Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement G2 continuity for some nodes #4847

Merged
merged 18 commits into from
Aug 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 14 additions & 6 deletions docs/nodes/curve/blend_curves.rst
Original file line number Diff line number Diff line change
Expand Up @@ -66,29 +66,29 @@ This node has the following parameters:
* **Continuity**. This defines how smooth the connection between initial curves
and generated blending curves should be. The available options are:

* **0 - Position**. Blending curve starts at the end of first curve and ends
* **C0 - Position**. Blending curve starts at the end of first curve and ends
at the beginning of the second curve, but no attempts are made to make
these connections smooth. As a result, the blending curve is always a
segment of a straight line.

.. image:: https://user-images.githubusercontent.com/14288520/211332041-419c7002-28bb-45ca-b507-238ff4f13dcd.png
:target: https://user-images.githubusercontent.com/14288520/211332041-419c7002-28bb-45ca-b507-238ff4f13dcd.png

* **1 - Tangency**. The blending curves are generated so that the tangent
* **G1 - Tangency**. The blending curves are generated so that the tangent
vectors of the curves are equal at their meeting points. The generated
curves are cubic Bezier curves.

.. image:: https://user-images.githubusercontent.com/14288520/211333493-3dfe0a3f-1143-429f-bd1c-7a9c04ce45bf.png
:target: https://user-images.githubusercontent.com/14288520/211333493-3dfe0a3f-1143-429f-bd1c-7a9c04ce45bf.png

* **1b - Bi Arc**. The blending curves are generated as biarc_ curves, i.e.
* **G1 - Bi Arc**. The blending curves are generated as biarc_ curves, i.e.
pairs of circular arcs; they are generated so that the tanent vectors of
the curves are equal at their meeting points.

.. image:: https://user-images.githubusercontent.com/14288520/211338021-ae8c68d9-bc02-4323-8cc5-8888c0c8ad33.png
:target: https://user-images.githubusercontent.com/14288520/211338021-ae8c68d9-bc02-4323-8cc5-8888c0c8ad33.png

* **2 - Normals**. The blending curves are generated so that 1) tangent
* **C2 - Smooth Normals**. The blending curves are generated so that 1) tangent
vectors of the curves are equal at the meeting points; 2) second
derivatives of the curves are also equal at the meeting points. Thus,
normal and binormal vectors of the curves are equal at their meeting
Expand All @@ -97,7 +97,7 @@ This node has the following parameters:
.. image:: https://user-images.githubusercontent.com/14288520/211343223-f0c9bc79-bf16-4833-a3cd-6b651d52d099.png
:target: https://user-images.githubusercontent.com/14288520/211343223-f0c9bc79-bf16-4833-a3cd-6b651d52d099.png

* **3 - Curvature**. The blending curves are generated so that 1) tangent
* **C3 - Smooth Curvature**. The blending curves are generated so that 1) tangent
vectors of the curves are equal at the meeting points; 2) second and third
derivatives of the curves are also equal at the meeting points. Thus,
normal and binormal vectors of the curves, as well as curvatures of the
Expand All @@ -107,6 +107,14 @@ This node has the following parameters:
.. image:: https://user-images.githubusercontent.com/14288520/211344080-1146e033-7296-4f92-9bd5-f36348d7ebd7.png
:target: https://user-images.githubusercontent.com/14288520/211344080-1146e033-7296-4f92-9bd5-f36348d7ebd7.png

* **G2 - Curvature**. This means continuous curvature. Curvature comb rim
line is continuous, but not smooth. In this sense, this mode is similar to
"C2 - Smooth Normals" mode. But with G2 mode, the blending curve does not
go so far from touching points as in C2 or C3 mode.

.. image:: https://user-images.githubusercontent.com/284644/210864882-de4a8a95-f73a-42d3-b30f-1f01ad7a6c33.png
:target: https://user-images.githubusercontent.com/284644/210864882-de4a8a95-f73a-42d3-b30f-1f01ad7a6c33.png

The default value is **1 - Tangency**.

* **Blend**. These defines how the curves to be joined are provided. The available options are:
Expand Down Expand Up @@ -190,4 +198,4 @@ Cycle one curve
:target: https://user-images.githubusercontent.com/14288520/211379616-f43aac03-c3a5-4023-8f51-e243990c74e4.png

* Scene-> :doc:`Bezier Input </nodes/exchange/bezier_in>`
* Viz-> :doc:`Viewer Draw Curve </nodes/viz/viewer_draw_curve>`
* Viz-> :doc:`Viewer Draw Curve </nodes/viz/viewer_draw_curve>`
17 changes: 16 additions & 1 deletion docs/nodes/surface/blend_surface.rst
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,21 @@ Parameters

This node has the following parameters:

* **Smoothness**. This defines how smooth the connection between initial
surfaces and generated blending surface should be. The available options are:

* **G1 - Tangency**. Exact matching of tangents is guaranteed.

.. image:: https://user-images.githubusercontent.com/284644/210866314-f05d511e-8ae9-46aa-88b1-feb030c67ce1.png
:target: https://user-images.githubusercontent.com/284644/210866314-f05d511e-8ae9-46aa-88b1-feb030c67ce1.png

* **G2 - Curvature**. Matching of geometric curvature is guaranteed.

.. image:: https://user-images.githubusercontent.com/284644/210866466-2a0d5628-0d00-48ad-a28b-5c037d84b7fd.png
:target: https://user-images.githubusercontent.com/284644/210866466-2a0d5628-0d00-48ad-a28b-5c037d84b7fd.png

The default option is **G1 - Tangency**.

* **Curve1**. This defines where the blending surface should touch the first surface. The available options are:

* **Min U**. Use the edge of the surface with the minimum value of U parameter.
Expand Down Expand Up @@ -133,4 +148,4 @@ An example of NURBS mode:
* Surfaces-> :doc:`Plane (Surface) </nodes/surface/plane>`
* Surfaces-> :doc:`Apply Field to Surface </nodes/surface/apply_field_to_surface>`
* Matrix-> :doc:`Matrix In </nodes/matrix/matrix_in_mk4>`
* Viz-> :doc:`Viewer Draw Surface </nodes/viz/viewer_draw_surface>`
* Viz-> :doc:`Viewer Draw Surface </nodes/viz/viewer_draw_surface>`
34 changes: 25 additions & 9 deletions nodes/curve/blend_curves.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ def update_sockets(self, context):
self.inputs['Curve1'].hide_safe = self.mode != 'TWO'
self.inputs['Curve2'].hide_safe = self.mode != 'TWO'
self.inputs['Curves'].hide_safe = self.mode != 'N'
self.inputs['Factor1'].hide_safe = self.smooth_mode != '1'
self.inputs['Factor2'].hide_safe = self.smooth_mode != '1'
self.inputs['Factor1'].hide_safe = self.smooth_mode not in ['1', 'G2']
self.inputs['Factor2'].hide_safe = self.smooth_mode not in ['1', 'G2']
self.inputs['Parameter'].hide_safe = self.smooth_mode != '1b'
updateNode(self, context)

Expand All @@ -60,11 +60,12 @@ def update_sockets(self, context):
update = update_sockets)

smooth_modes = [
('0', "0 - Position", "Connect ends of curves with straight line segment", 0),
('1', "1 - Tangency", "Connect curves such that their tangents are smoothly joined", 1),
('1b', "1b - Bi Arc", "Connect curves with Bi Arc, such that tangents are smoothly joined", 2),
('2', "2 - Normals", "Connect curves such that their normals (second derivatives) are smoothly joined", 3),
('3', "3 - Curvature", "Connect curves such that their curvatures (third derivatives) are smoothly joined", 4)
('0', "C0 - Position", "Connect ends of curves with straight line segment", 0),
('1', "G1 - Tangency", "Connect curves such that their tangents are continuosly joined", 1),
('1b', "G1 - Bi Arc", "Connect curves with Bi Arc, such that tangents are continuosly joined", 2),
('2', "C2 - Smooth Normals", "Connect curves such that their second derivatives are continuosly joined", 3),
('3', "C3 - Smooth Curvature", "Connect curves such that their third derivatives are continuosly joined", 4),
('G2', "G2 - Curvature", "Connect curves such that their tangents, normals and curvatures are continuosly joined", 5)
]

smooth_mode : EnumProperty(
Expand Down Expand Up @@ -245,8 +246,23 @@ def process(self):
curve1_end, tangent_1_end, second_1_end, third_1_end,
curve2_begin, tangent_2_begin, second_2_begin, third_2_begin)
controls = [p.tolist() for p in new_curve.points]
else:
raise Exception("Unsupported smooth level")
elif smooth == 'G2':
tangent_1_end = curve1.tangent(t_max_1)
tangent_2_begin = curve2.tangent(t_min_2)
tangent1 = factor1 * tangent_1_end
tangent2 = factor2 * tangent_2_begin
normal_1_end = curve1.main_normal(t_max_1)
normal_2_begin = curve2.main_normal(t_min_2)
curvature_1_end = curve1.curvature(t_max_1)
curvature_2_begin = curve2.curvature(t_min_2)

#print(f"Bz: P1 {curve1_end}, P2 {curve2_begin}, T1 {tangent1}, T2 {tangent2}, n1 {normal_1_end}, n2 {normal_2_begin}, c1 {curvature_1_end}, c2 {curvature_2_begin}")
new_curve = SvBezierCurve.from_tangents_normals_curvatures(
curve1_end, curve2_begin,
tangent1, tangent2,
normal_1_end, normal_2_begin,
curvature_1_end, curvature_2_begin)
controls = new_curve.get_control_points().tolist()

# There is two templates of result:
# 1. curve1 new_curve1 curve2 new_curve2 curve3 [new_curve3 curve4]/cyclic->curve1
Expand Down
2 changes: 2 additions & 0 deletions nodes/curve/fillet_curve.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
from sverchok.utils.curve.nurbs import SvNurbsCurve
from sverchok.utils.curve.fillet import (
SMOOTH_POSITION, SMOOTH_TANGENT, SMOOTH_ARC, SMOOTH_BIARC, SMOOTH_QUAD, SMOOTH_NORMAL, SMOOTH_CURVATURE,
SMOOTH_G2,
fillet_polyline_from_curve, fillet_nurbs_curve
)
from sverchok.utils.handle_blender_data import keep_enum_reference
Expand Down Expand Up @@ -69,6 +70,7 @@ def get_smooth_modes(self, context):
items.append((SMOOTH_BIARC, "1 - Bi Arc", "Connect segments with Bi Arc, such that tangents are smoothly joined", 2))
#items.append((SMOOTH_NORMAL, "2 - Normals", "Connect segments such that their normals (second derivatives) are smoothly joined", 3))
#items.append((SMOOTH_CURVATURE, "3 - Curvature", "Connect segments such that their curvatures (third derivatives) are smoothly joined", 4))
#items.append((SMOOTH_G2, "G2 - Curvature", "Connect curves such that their tangents, normals and curvatures are continuosly joined", 6))
else:
items.append((SMOOTH_ARC, "1 - Circular Arc", "Connect segments with circular arcs", 5))
return items
Expand Down
48 changes: 46 additions & 2 deletions nodes/surface/blend_surface.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,23 @@ def update_sockets(self, context):
default = 'UMIN',
update = update_sockets)

tangency_modes = [
(SvBlendSurface.G1, "G1 - Tangency", "G1 tangency: match tangent vectors", 0),
(SvBlendSurface.G2, "G2 - Curvature", "G2 tangency: match tangent vectors, normal vectors and curvature values", 1)
]

tangency_mode : EnumProperty(
name = "Smoothness",
description = "How smooth the tangency should be",
items = tangency_modes,
update = updateNode)

absolute_bulge : BoolProperty(
name = "Absolute bulge",
description = "If checked, then bulge values specified are actual required tangent vector lengths; otherwise, bulge values are specified as multipliers of surface's tangent vectors",
default = True,
update = updateNode)

bulge1 : FloatProperty(
name = "Bulge1",
description = "Bulge factor for the first surface; set to negative value to bulge in another direction",
Expand Down Expand Up @@ -90,7 +107,19 @@ def update_sockets(self, context):
min = 3,
update = updateNode)

ortho_modes = [
('3D', "3D space", "Make V isolines of the surface orthogonal to touching curves in 3D space", 0),
('UV', "UV space", "Make V isolines of the surface continue isolines in original surfaces UV space", 1)
]

ortho_mode : EnumProperty(
name = "Ortho mode",
items = ortho_modes,
default = '3D', # default for pre-existing nodes
update = updateNode)

def draw_buttons(self, context, layout):
layout.prop(self, 'tangency_mode')
box = layout.row(align=True)
box.prop(self, 'curve1_mode', text='')
box.prop(self, 'flip1', toggle=True, text='Flip')
Expand All @@ -99,6 +128,11 @@ def draw_buttons(self, context, layout):
box.prop(self, 'flip2', toggle=True, text='Flip')
layout.prop(self, 'use_nurbs')

def draw_buttons_ext(self, context, layout):
self.draw_buttons(context, layout)
layout.prop(self, 'ortho_mode')
#layout.prop(self, 'absolute_bulge')

def sv_init(self, context):
self.inputs.new('SvSurfaceSocket', 'Surface1')
self.inputs.new('SvCurveSocket', 'UVCurve1')
Expand All @@ -108,6 +142,7 @@ def sv_init(self, context):
self.inputs.new('SvStringsSocket', 'Bulge2').prop_name = 'bulge2'
self.inputs.new('SvStringsSocket', 'Samples').prop_name = 'samples'
self.outputs.new('SvSurfaceSocket', 'Surface')
self.ortho_mode = 'UV' # default for new nodes
self.update_sockets(context)

def make_uv_curve(self, surface, mode, flip):
Expand Down Expand Up @@ -159,6 +194,8 @@ def process(self):
bulge2_s = ensure_nesting_level(bulge2_s, 2)
samples_s = ensure_nesting_level(samples_s, 2)

absolute_bulge = (self.tangency_mode == SvBlendSurface.G1)

surfaces_out = []
for params in zip_long_repeat(surface1_s, uv_curve1_s, bulge1_s, surface2_s, uv_curve2_s, bulge2_s, samples_s):
new_surfaces = []
Expand All @@ -173,9 +210,16 @@ def process(self):
curve2 = reverse_curve(curve2)

if self.use_nurbs:
surface = nurbs_blend_surfaces(surface1, surface2, curve1, curve2, bulge1, bulge2, 3, samples)
surface = nurbs_blend_surfaces(surface1, surface2, curve1, curve2, bulge1, bulge2, 3, samples,
absolute_bulge = absolute_bulge,
tangency = self.tangency_mode,
ortho_mode = self.ortho_mode,
logger = self.sv_logger)
else:
surface = SvBlendSurface(surface1, surface2, curve1, curve2, bulge1, bulge2)
surface = SvBlendSurface(surface1, surface2, curve1, curve2, bulge1, bulge2,
absolute_bulge = absolute_bulge,
tangency = self.tangency_mode,
ortho_mode = self.ortho_mode)
new_surfaces.append(surface)
surfaces_out.append(new_surfaces)

Expand Down
Loading