Skip to content

Commit

Permalink
More or less working version.
Browse files Browse the repository at this point in the history
  • Loading branch information
portnov committed Aug 31, 2024
1 parent 948b8d4 commit 3cb3c32
Show file tree
Hide file tree
Showing 5 changed files with 97 additions and 15 deletions.
16 changes: 15 additions & 1 deletion nodes/surface/blend_surface.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,17 @@ 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',
update = updateNode)

def draw_buttons(self, context, layout):
layout.prop(self, 'tangency_mode')
box = layout.row(align=True)
Expand All @@ -115,6 +126,7 @@ def draw_buttons(self, context, layout):
box = layout.row(align=True)
box.prop(self, 'curve2_mode', text='')
box.prop(self, 'flip2', toggle=True, text='Flip')
layout.prop(self, 'ortho_mode')
layout.prop(self, 'use_nurbs')

def draw_buttons_ext(self, context, layout):
Expand Down Expand Up @@ -198,11 +210,13 @@ def process(self):
surface = nurbs_blend_surfaces(surface1, surface2, curve1, curve2, bulge1, bulge2, 3, samples,
absolute_bulge = self.absolute_bulge,
tangency = self.tangency_mode,
ortho_mode = self.ortho_mode,
logger = self.get_logger())
else:
surface = SvBlendSurface(surface1, surface2, curve1, curve2, bulge1, bulge2,
absolute_bulge = self.absolute_bulge,
tangency = self.tangency_mode)
tangency = self.tangency_mode,
ortho_mode = self.ortho_mode)
new_surfaces.append(surface)
surfaces_out.append(new_surfaces)

Expand Down
42 changes: 36 additions & 6 deletions utils/curve/algorithms.py
Original file line number Diff line number Diff line change
Expand Up @@ -750,25 +750,55 @@ def __init__(self, uv_curve, surface, ts, w_axis=2):
self.w_axis = w_axis
self.curve = SvCurveOnSurface(self.uv_curve, self.surface, axis=w_axis)
self._uv_points = None
self._uv_tangents = None
self._uv_normals = None
self._uv_normals_in_3d = None
self._tangents = None
self._unit_tangents = None
self._surface_calculator = None

def uv_axes(self):
if self.w_axis == 2:
U, V = 0, 1
elif self.w_axis == 1:
U, V = 0, 2
else:
U, V = 1, 2
return U, V

@property
def uv_points(self):
if self._uv_points is None:
self._uv_points = self.uv_curve.evaluate_array(self.ts)
return self._uv_points

@property
def uv_tangents(self):
if self._uv_tangents is None:
self._uv_tangents = self.uv_curve.tangent_array(self.ts)
return self._uv_tangents

@property
def uv_normals(self):
if self._uv_normals is None:
U, V = self.uv_axes()
tangents = self.uv_tangents
normals = np.zeros_like(tangents)
normals[:,U] = tangents[:,V]
normals[:,V] = -tangents[:,U]
self._uv_normals = normals
return self._uv_normals

@property
def uv_normals_in_3d(self):
if self._uv_normals_in_3d is None:
self._uv_normals_in_3d = self.surface_calculator.derivatives_data.tangents_in_direction(self.uv_normals, self.w_axis)
return self._uv_normals_in_3d

@property
def surface_calculator(self):
if self._surface_calculator is None:
if self.w_axis == 2:
U, V = 0, 1
elif self.w_axis == 1:
U, V = 0, 2
else:
U, V = 1, 2
U, V = self.uv_axes()
self._surface_calculator = self.surface.curvature_calculator(self.uv_points[:,U], self.uv_points[:,V])
return self._surface_calculator

Expand Down
10 changes: 9 additions & 1 deletion utils/surface/algorithms.py
Original file line number Diff line number Diff line change
Expand Up @@ -1040,7 +1040,10 @@ class SvBlendSurface(SvSurface):
G1 = 'G1'
G2 = 'G2'

def __init__(self, surface1, surface2, curve1, curve2, bulge1, bulge2, absolute_bulge = True, tangency = G1):
ORTHO_3D = '3D'
ORTHO_UV = 'UV'

def __init__(self, surface1, surface2, curve1, curve2, bulge1, bulge2, absolute_bulge = True, tangency = G1, ortho_mode = ORTHO_3D):
self.surface1 = surface1
self.surface2 = surface2
self.curve1 = curve1
Expand All @@ -1049,6 +1052,7 @@ def __init__(self, surface1, surface2, curve1, curve2, bulge1, bulge2, absolute_
self.bulge2 = bulge2
self.absolute_bulge = absolute_bulge
self.tangency = tangency
self.ortho_mode = ortho_mode
self.u_bounds = (0.0, 1.0)
self.v_bounds = (0.0, 1.0)

Expand Down Expand Up @@ -1080,6 +1084,10 @@ def evaluate_array(self, us, vs):
t1dir = c1_binormals / np.linalg.norm(c1_binormals, axis=1, keepdims=True)
t2dir = c2_binormals / np.linalg.norm(c2_binormals, axis=1, keepdims=True)

if self.ortho_mode == SvBlendSurface.ORTHO_UV:
c1_binormals = calc1.uv_normals_in_3d
c2_binormals = calc2.uv_normals_in_3d

if self.absolute_bulge:
c1_binormals = self.bulge1 * t1dir
c2_binormals = self.bulge2 * t2dir
Expand Down
20 changes: 20 additions & 0 deletions utils/surface/data.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,17 @@ def matrices(self, as_mathutils = False):
else:
return matrices_np

def tangents_in_direction(self, uv_directions, w_axis=2):
if w_axis == 2:
U, V = 0, 1
elif w_axis == 1:
U, V = 0, 2
else:
U, V = 1, 2
d_u = uv_directions[:,U][np.newaxis].T
d_v = uv_directions[:,V][np.newaxis].T
return self.du * d_u + self.dv * d_v

class SurfaceCurvatureCalculator(object):
"""
This class contains pre-calculated first and second surface derivatives,
Expand All @@ -87,6 +98,7 @@ def __init__(self, us, vs, order=True):
self.nuu = self.nvv = self.nuv = None
self.points = None
self.normals = None
self._derivatives_data = None

def set(self, points, normals, fu, fv, duu, dvv, duv, nuu, nvv, nuv):
"""Set derivatives information"""
Expand All @@ -101,6 +113,14 @@ def set(self, points, normals, fu, fv, duu, dvv, duv, nuu, nvv, nuv):
self.nvv = nvv # (fvv, normal), a.k.a n
self.nuv = nuv # (fuv, normal), a.k.a m

@property
def derivatives_data(self):
if self._derivatives_data is None:
if self.points is None or self.fu is None or self.fv is None:
raise Exception("SurfaceCurvatureCalculator.set() was not called before call to SurfaceCurvatureCalculator.derivatives_data")
self._derivatives_data = SurfaceDerivativesData(self.points, self.fu, self.fv)
return self._derivatives_data

def mean(self):
"""
Calculate mean curvature.
Expand Down
24 changes: 17 additions & 7 deletions utils/surface/gordon.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,10 @@ def gordon_surface(u_curves, v_curves, intersections, metric='POINTS', u_knots=N
TANGENCY_G1 = 'G1'
TANGENCY_G2 = 'G2'

def nurbs_blend_surfaces(surface1, surface2, curve1, curve2, bulge1, bulge2, u_degree, u_samples, absolute_bulge = True, tangency = TANGENCY_G1, logger=None):
ORTHO_3D = '3D'
ORTHO_UV = 'UV'

def nurbs_blend_surfaces(surface1, surface2, curve1, curve2, bulge1, bulge2, u_degree, u_samples, absolute_bulge = True, tangency = TANGENCY_G1, ortho_mode = ORTHO_UV, logger=None):
t_min, t_max = curve1.get_u_bounds()
ts1 = np.linspace(t_min, t_max, num=u_samples)

Expand All @@ -146,6 +149,11 @@ def nurbs_blend_surfaces(surface1, surface2, curve1, curve2, bulge1, bulge2, u_d
calc2 = SvCurveOnSurfaceCurvaturesCalculator(curve2, surface2, ts2)
_, c1_points, c1_tangents, c1_normals, c1_binormals = calc1.curve_frame_on_surface_array(normalize=False)
_, c2_points, c2_tangents, c2_normals, c2_binormals = calc2.curve_frame_on_surface_array(normalize=False)

if ortho_mode == ORTHO_UV:
c1_binormals = calc1.uv_normals_in_3d
c2_binormals = calc2.uv_normals_in_3d

if absolute_bulge:
c1_binormals = bulge1 * c1_binormals / np.linalg.norm(c1_binormals, axis=1, keepdims=True)
c2_binormals = bulge2 * c2_binormals / np.linalg.norm(c2_binormals, axis=1, keepdims=True)
Expand All @@ -155,15 +163,17 @@ def nurbs_blend_surfaces(surface1, surface2, curve1, curve2, bulge1, bulge2, u_d

c1_across = calc1.calc_curvatures_across_curve()
c2_across = calc2.calc_curvatures_across_curve()
c1_along = calc1.calc_curvatures_along_curve()
c2_along = calc2.calc_curvatures_along_curve()
#c1_along = calc1.calc_curvatures_along_curve()
#c2_along = calc2.calc_curvatures_along_curve()
#print(f"C1: {list(zip(ts1, c1_across, c1_along))}")
#print(f"C2: {list(zip(ts2, c2_across, c1_along))}")

bad1 = (c1_across * c1_along) > 0
bad2 = (c2_across * c2_along) > 0
c1_normals[bad1] = - c1_normals[bad1]
c2_normals[bad2] = - c2_normals[bad2]
#bad1 = (c1_across * c1_along) < 0
#bad2 = (c2_across * c2_along) < 0
#print(f"Bad1: {bad1}")
#print(f"Bad2: {bad2}")
#c1_normals[bad1] = - c1_normals[bad1]
#c2_normals[bad2] = - c2_normals[bad2]

#curve1 = interpolate_nurbs_curve_with_tangents(u_degree, c1_points, c1_tangents, tknots=ts1, logger=logger)
#curve2 = interpolate_nurbs_curve_with_tangents(u_degree, c2_points, c2_tangents, tknots=ts2, logger=logger)
Expand Down

0 comments on commit 3cb3c32

Please sign in to comment.