def process(self): if not any(socket.is_linked for socket in self.outputs): return surface1_s = self.inputs['Surface1'].sv_get() surface2_s = self.inputs['Surface2'].sv_get() uv_curve1_s = self.inputs['UVCurve1'].sv_get(default=[[None]]) uv_curve2_s = self.inputs['UVCurve2'].sv_get(default=[[None]]) bulge1_s = self.inputs['Bulge1'].sv_get() bulge2_s = self.inputs['Bulge2'].sv_get() surface1_s = ensure_nesting_level(surface1_s, 2, data_types=(SvSurface, )) if self.inputs['UVCurve1'].is_linked: uv_curve1_s = ensure_nesting_level(uv_curve1_s, 2, data_types=(SvCurve, )) surface2_s = ensure_nesting_level(surface2_s, 2, data_types=(SvSurface, )) if self.inputs['UVCurve2'].is_linked: uv_curve2_s = ensure_nesting_level(uv_curve2_s, 2, data_types=(SvCurve, )) bulge1_s = ensure_nesting_level(bulge1_s, 2) bulge2_s = ensure_nesting_level(bulge2_s, 2) surfaces_out = [] for surface1_i, curve1_i, bulge1_i, surface2_i, curve2_i, bulge2_i in zip_long_repeat( surface1_s, uv_curve1_s, bulge1_s, surface2_s, uv_curve2_s, bulge2_s): new_surfaces = [] for surface1, curve1, bulge1, surface2, curve2, bulge2 in zip_long_repeat( surface1_i, curve1_i, bulge1_i, surface2_i, curve2_i, bulge2_i): if self.curve1_mode != 'USER': curve1 = self.make_uv_curve(surface1, self.curve1_mode, self.flip1) elif self.flip1: curve1 = reverse_curve(curve1) if self.curve2_mode != 'USER': curve2 = self.make_uv_curve(surface2, self.curve2_mode, self.flip2) elif self.flip2: curve2 = reverse_curve(curve2) surface = SvBlendSurface(surface1, surface2, curve1, curve2, bulge1, bulge2) new_surfaces.append(surface) surfaces_out.append(new_surfaces) self.outputs['Surface'].sv_set(surfaces_out)
def __init__(self, curve1, curve2, curve3, curve4): curve1 = reparametrize_curve(curve1) curve2 = reparametrize_curve(curve2) curve3 = reparametrize_curve(curve3) curve4 = reparametrize_curve(curve4) self.curve1 = curve1 self.curve2 = curve2 self.curve3 = curve3 self.curve4 = curve4 self.linear1 = SvCurveLerpSurface.build(curve1, reverse_curve(curve3)) self.linear2 = SvCurveLerpSurface.build(curve2, reverse_curve(curve4)) self.c1_t_min, self.c1_t_max = curve1.get_u_bounds() self.c3_t_min, self.c3_t_max = curve3.get_u_bounds() self.corner1 = self.curve1.evaluate(self.c1_t_min) self.corner2 = self.curve1.evaluate(self.c1_t_max) self.corner3 = self.curve3.evaluate(self.c3_t_max) self.corner4 = self.curve3.evaluate(self.c3_t_min) self.normal_delta = 0.001
def process(self): if not any(socket.is_linked for socket in self.outputs): return curve_s = self.inputs['Curve'].sv_get() if isinstance(curve_s[0], SvCurve): out_level = 1 curve_s = [curve_s] else: out_level = 2 curves_out = [] for curves in curve_s: new_curves = [] for curve in curves: new_curve = reverse_curve(curve) new_curves.append(new_curve) if out_level == 1: curves_out.extend(new_curves) else: curves_out.append(new_curves) self.outputs['Curve'].sv_set(curves_out)
def coons_surface(curve1, curve2, curve3, curve4): curves = [curve1, curve2, curve3, curve4] nurbs_curves = [SvNurbsCurve.to_nurbs(c) for c in curves] if any(c is None for c in nurbs_curves): return SvCoonsSurface(*curves) try: nurbs_curves = [c.reparametrize(0, 1) for c in nurbs_curves] degrees = [c.get_degree() for c in nurbs_curves] implementation = nurbs_curves[0].get_nurbs_implementation() if degrees[0] > degrees[2]: nurbs_curves[2] = nurbs_curves[2].elevate_degree(delta=degrees[0] - degrees[2]) if degrees[2] > degrees[0]: nurbs_curves[0] = nurbs_curves[0].elevate_degree(delta=degrees[2] - degrees[0]) if degrees[1] > degrees[3]: nurbs_curves[3] = nurbs_curves[3].elevate_degree(delta=degrees[1] - degrees[3]) if degrees[3] > degrees[1]: nurbs_curves[1] = nurbs_curves[1].elevate_degree(delta=degrees[3] - degrees[1]) degree_u = nurbs_curves[0].get_degree() degree_v = nurbs_curves[1].get_degree() knotvectors = [c.get_knotvector() for c in nurbs_curves] if not sv_knotvector.equal(knotvectors[0], knotvectors[2]): nurbs_curves[0], nurbs_curves[2] = unify_two_curves( nurbs_curves[0], nurbs_curves[2]) if not sv_knotvector.equal(knotvectors[1], knotvectors[3]): nurbs_curves[1], nurbs_curves[3] = unify_two_curves( nurbs_curves[1], nurbs_curves[3]) nurbs_curves[0] = reverse_curve(nurbs_curves[0]) nurbs_curves[3] = reverse_curve(nurbs_curves[3]) ruled1 = nurbs_curves[0].make_ruled_surface(nurbs_curves[2], 0, 1) ruled2 = nurbs_curves[1].make_ruled_surface(nurbs_curves[3], 0, 1).swap_uv() ruled1 = ruled1.elevate_degree(SvNurbsSurface.V, target=degree_v) ruled2 = ruled2.elevate_degree(SvNurbsSurface.U, target=degree_u) diff_1to2 = sv_knotvector.difference(ruled1.get_knotvector_v(), ruled2.get_knotvector_v()) diff_2to1 = sv_knotvector.difference(ruled2.get_knotvector_u(), ruled1.get_knotvector_u()) for v, count in diff_1to2: #print(f"R1: insert V={v} {count} times") ruled1 = ruled1.insert_knot(SvNurbsSurface.V, v, count) for u, count in diff_2to1: #print(f"R2: insert U={u} {count} times") ruled2 = ruled2.insert_knot(SvNurbsSurface.U, u, count) #print(f"R1: {ruled1.get_control_points().shape}, R2: {ruled2.get_control_points().shape}") linear_kv = sv_knotvector.generate(1, 2) c1_t_min, c1_t_max = nurbs_curves[0].get_u_bounds() c3_t_min, c3_t_max = nurbs_curves[2].get_u_bounds() pt1 = nurbs_curves[0].evaluate(c1_t_min) pt2 = nurbs_curves[0].evaluate(c1_t_max) pt3 = nurbs_curves[2].evaluate(c3_t_min) pt4 = nurbs_curves[2].evaluate(c3_t_max) w1 = nurbs_curves[0].get_weights()[0] w2 = nurbs_curves[0].get_weights()[-1] w3 = nurbs_curves[2].get_weights()[0] w4 = nurbs_curves[2].get_weights()[-1] linear_pts = np.array([[pt1, pt3], [pt2, pt4]]) linear_weights = np.array([[w1, w3], [w2, w4]]) #linear_weights = np.array([[1,1], [1,1]]) bilinear = SvNurbsSurface.build(implementation, 1, 1, linear_kv, linear_kv, linear_pts, linear_weights) bilinear = bilinear.elevate_degree(SvNurbsSurface.U, target=degree_u) bilinear = bilinear.elevate_degree(SvNurbsSurface.V, target=degree_v) knotvector_u = ruled1.get_knotvector_u() knotvector_v = ruled2.get_knotvector_v() for u, count in sv_knotvector.get_internal_knots( knotvector_u, output_multiplicity=True): #print(f"B: insert U={u} {count} times") bilinear = bilinear.insert_knot(SvNurbsSurface.U, u, count) for v, count in sv_knotvector.get_internal_knots( knotvector_v, output_multiplicity=True): #print(f"B: insert V={v} {count} times") bilinear = bilinear.insert_knot(SvNurbsSurface.V, v, count) control_points = ruled1.get_control_points( ) + ruled2.get_control_points() - bilinear.get_control_points() weights = ruled1.get_weights() + ruled2.get_weights( ) - bilinear.get_weights() result = SvNurbsSurface.build(implementation, degree_u, degree_v, knotvector_u, knotvector_v, control_points, weights) return result except UnsupportedCurveTypeException as e: info("Can't create a native Coons surface from curves %s: %s", curves, e) return SvCoonsSurface(*curves)
def extend_curve(self, curve, t_before, t_after): u_min, u_max = curve.get_u_bounds() start, end = curve.evaluate(u_min), curve.evaluate(u_max) start_extent, end_extent = None, None is_nurbs = isinstance(curve, SvNurbsCurve) if self.mode == 'LINE': tangent_start = curve.tangent(u_min) tangent_end = curve.tangent(u_max) if t_before > 0: start_extent = self.make_line(start, tangent_start, t_before, -1) start_extent = self.set_length(curve, start_extent, t_before, -1) if t_after > 0: end_extent = self.make_line(end, tangent_end, t_after, +1) end_extent = self.set_length(curve, end_extent, t_after, +1) elif self.mode == 'ARC': tangent_start = curve.tangent(u_min) tangent_end = curve.tangent(u_max) second_start = curve.second_derivative(u_min) second_end = curve.second_derivative(u_max) if t_before > 0: if np.linalg.norm(second_start) > 1e-6: eq1 = circle_by_two_derivatives(start, -tangent_start, second_start) start_extent = SvCircle.from_equation(eq1) start_extent = self.set_length(curve, start_extent, t_before, -1) if is_nurbs: start_extent = start_extent.to_nurbs() start_extent = reverse_curve(start_extent) else: start_extent = self.make_line(start, tangent_start, t_before, -1) start_extent = self.set_length(curve, start_extent, t_before, -1) if t_after > 0: if np.linalg.norm(second_end) > 1e-6: eq2 = circle_by_two_derivatives(end, tangent_end, second_end) end_extent = SvCircle.from_equation(eq2) else: end_extent = self.make_line(end, tangent_end, t_after, +1) end_extent = self.set_length(curve, end_extent, t_after, +1) elif self.mode == 'QUAD': tangent_start = curve.tangent(u_min) tangent_end = curve.tangent(u_max) second_start = curve.second_derivative(u_min) second_end = curve.second_derivative(u_max) if t_before > 0: start_extent = SvTaylorCurve(start, [-tangent_start, second_start]) start_extent = self.set_length(curve, start_extent, t_before) if is_nurbs: start_extent = start_extent.to_nurbs() start_extent = reverse_curve(start_extent) if t_after > 0: end_extent = SvTaylorCurve(end, [tangent_end, second_end]) end_extent = self.set_length(curve, end_extent, t_after) elif self.mode == 'CUBIC': tangent_start = curve.tangent(u_min) tangent_end = curve.tangent(u_max) second_start = curve.second_derivative(u_min) second_end = curve.second_derivative(u_max) third_start, third_end = curve.third_derivative_array( np.array([u_min, u_max])) if t_before > 0: start_extent = SvTaylorCurve( start, [-tangent_start, second_start, -third_start]) start_extent = self.set_length(curve, start_extent, t_before) if is_nurbs: start_extent = start_extent.to_nurbs() start_extent = reverse_curve(start_extent) if t_after > 0: end_extent = SvTaylorCurve( end, [tangent_end, second_end, third_end]) end_extent = self.set_length(curve, end_extent, t_after) else: raise Exception("Unsupported mode") if is_nurbs: if start_extent is not None and not isinstance( start_extent, SvNurbsCurve): start_extent = start_extent.to_nurbs( implementation=curve.get_nurbs_implementation()) if end_extent is not None and not isinstance( end_extent, SvNurbsCurve): end_extent = end_extent.to_nurbs( implementation=curve.get_nurbs_implementation()) return start_extent, end_extent
def extend_curve(curve, t_before, t_after, mode='LINE', len_mode='T', len_resolution=50): def make_line(point, tangent, t_ext, sign): if sign < 0: before_start = point - t_ext * tangent # / np.linalg.norm(tangent_start) return SvLine.from_two_points(before_start, point) else: after_end = point + t_ext * tangent # / np.linalg.norm(tangent_end) return SvLine.from_two_points(point, after_end) u_min, u_max = curve.get_u_bounds() start, end = curve.evaluate(u_min), curve.evaluate(u_max) start_extent, end_extent = None, None is_nurbs = isinstance(curve, SvNurbsCurve) if mode == 'LINE': tangent_start = curve.tangent(u_min) tangent_end = curve.tangent(u_max) if t_before > 0: start_extent = make_line(start, tangent_start, t_before, -1) start_extent = set_length(curve, start_extent, t_before, -1, len_mode=len_mode, len_resolution=len_resolution) if t_after > 0: end_extent = make_line(end, tangent_end, t_after, +1) end_extent = set_length(curve, end_extent, t_after, +1, len_mode=len_mode, len_resolution=len_resolution) elif mode == 'ARC': tangent_start = curve.tangent(u_min) tangent_end = curve.tangent(u_max) second_start = curve.second_derivative(u_min) second_end = curve.second_derivative(u_max) if t_before > 0: if np.linalg.norm(second_start) > 1e-6: eq1 = circle_by_two_derivatives(start, -tangent_start, second_start) start_extent = SvCircle.from_equation(eq1) start_extent = set_length(curve, start_extent, t_before, -1, len_mode=len_mode, len_resolution=len_resolution) if is_nurbs: start_extent = start_extent.to_nurbs() start_extent = reverse_curve(start_extent) else: start_extent = make_line(start, tangent_start, t_before, -1) start_extent = set_length(curve, start_extent, t_before, -1, len_mode=len_mode, len_resolution=len_resolution) if t_after > 0: if np.linalg.norm(second_end) > 1e-6: eq2 = circle_by_two_derivatives(end, tangent_end, second_end) end_extent = SvCircle.from_equation(eq2) else: end_extent = make_line(end, tangent_end, t_after, +1) end_extent = set_length(curve, end_extent, t_after, +1, len_mode=len_mode, len_resolution=len_resolution) elif mode == 'QUAD': tangent_start = curve.tangent(u_min) tangent_end = curve.tangent(u_max) second_start = curve.second_derivative(u_min) second_end = curve.second_derivative(u_max) if t_before > 0: start_extent = SvTaylorCurve(start, [-tangent_start, second_start]) start_extent = set_length(curve, start_extent, t_before, len_mode=len_mode, len_resolution=len_resolution) if is_nurbs: start_extent = start_extent.to_nurbs() start_extent = reverse_curve(start_extent) if t_after > 0: end_extent = SvTaylorCurve(end, [tangent_end, second_end]) end_extent = set_length(curve, end_extent, t_after, len_mode=len_mode, len_resolution=len_resolution) elif mode == 'CUBIC': tangent_start = curve.tangent(u_min) tangent_end = curve.tangent(u_max) second_start = curve.second_derivative(u_min) second_end = curve.second_derivative(u_max) third_start, third_end = curve.third_derivative_array( np.array([u_min, u_max])) if t_before > 0: start_extent = SvTaylorCurve( start, [-tangent_start, second_start, -third_start]) start_extent = set_length(curve, start_extent, t_before, len_mode=len_mode, len_resolution=len_resolution) if is_nurbs: start_extent = start_extent.to_nurbs() start_extent = reverse_curve(start_extent) if t_after > 0: end_extent = SvTaylorCurve(end, [tangent_end, second_end, third_end]) end_extent = set_length(curve, end_extent, t_after, len_mode=len_mode, len_resolution=len_resolution) else: raise Exception("Unsupported mode") if is_nurbs: if start_extent is not None and not isinstance(start_extent, SvNurbsCurve): start_extent = start_extent.to_nurbs( implementation=curve.get_nurbs_implementation()) if end_extent is not None and not isinstance(end_extent, SvNurbsCurve): end_extent = end_extent.to_nurbs( implementation=curve.get_nurbs_implementation()) return start_extent, end_extent
def coons_surface(curve1, curve2, curve3, curve4, use_nurbs=NURBS_IF_POSSIBLE): curves = [curve1, curve2, curve3, curve4] nurbs_curves = [SvNurbsCurve.to_nurbs(c) for c in curves] if use_nurbs == GENERIC: return SvCoonsSurface(*curves) if any(c is None for c in nurbs_curves): if use_nurbs == NURBS_ONLY: raise UnsupportedCurveTypeException("Some of curves are not NURBS") else: return SvCoonsSurface(*curves) try: nurbs_curves = [c.reparametrize(0, 1) for c in nurbs_curves] degrees = [c.get_degree() for c in nurbs_curves] implementation = nurbs_curves[0].get_nurbs_implementation() nurbs_curves[0], nurbs_curves[2] = unify_curves( [nurbs_curves[0], nurbs_curves[2]]) nurbs_curves[1], nurbs_curves[3] = unify_curves( [nurbs_curves[1], nurbs_curves[3]]) degree_u = nurbs_curves[0].get_degree() degree_v = nurbs_curves[1].get_degree() nurbs_curves[0] = reverse_curve(nurbs_curves[0]) nurbs_curves[3] = reverse_curve(nurbs_curves[3]) ruled1 = nurbs_curves[0].make_ruled_surface(nurbs_curves[2], 0, 1) ruled2 = nurbs_curves[1].make_ruled_surface(nurbs_curves[3], 0, 1).swap_uv() linear_kv = sv_knotvector.generate(1, 2) c1_t_min, c1_t_max = nurbs_curves[0].get_u_bounds() c3_t_min, c3_t_max = nurbs_curves[2].get_u_bounds() pt1 = nurbs_curves[0].evaluate(c1_t_min) pt2 = nurbs_curves[0].evaluate(c1_t_max) pt3 = nurbs_curves[2].evaluate(c3_t_min) pt4 = nurbs_curves[2].evaluate(c3_t_max) w1 = nurbs_curves[0].get_weights()[0] w2 = nurbs_curves[0].get_weights()[-1] w3 = nurbs_curves[2].get_weights()[0] w4 = nurbs_curves[2].get_weights()[-1] linear_pts = np.array([[pt1, pt3], [pt2, pt4]]) linear_weights = np.array([[w1, w3], [w2, w4]]) #linear_weights = np.array([[1,1], [1,1]]) bilinear = SvNurbsSurface.build(implementation, 1, 1, linear_kv, linear_kv, linear_pts, linear_weights) ruled1, ruled2, bilinear = unify_nurbs_surfaces( [ruled1, ruled2, bilinear]) knotvector_u = ruled1.get_knotvector_u() knotvector_v = ruled1.get_knotvector_v() control_points = ruled1.get_control_points( ) + ruled2.get_control_points() - bilinear.get_control_points() weights = ruled1.get_weights() + ruled2.get_weights( ) - bilinear.get_weights() result = SvNurbsSurface.build(implementation, degree_u, degree_v, knotvector_u, knotvector_v, control_points, weights) return result except UnsupportedCurveTypeException as e: if use_nurbs == NURBS_ONLY: raise else: info("Can't create a native Coons surface from curves %s: %s", curves, e) return SvCoonsSurface(*curves)