def process(self): if not any(socket.is_linked for socket in self.outputs): return verts_s = self.inputs['Vertices'].sv_get() tangent_s = self.inputs['Tangent'].sv_get(default = [[[]]]) have_tangent = self.inputs['Tangent'].is_linked verts_s = ensure_nesting_level(verts_s, 3) tangent_s = ensure_nesting_level(tangent_s, 3) tangent_s = tangent_s[0] # We can use only one tangent per curve, but let's support a spare pair of [] curve_out = [] center_out = [] radius_out = [] angle_out = [] for verts, tangent in zip_long_repeat(verts_s, tangent_s): new_curves = [] new_centers = [] new_radius = [] new_angles = [] if not have_tangent: tangent = self.calc_tangent(verts) elif not isinstance(tangent, Vector): tangent = Vector(tangent) if self.is_cyclic: verts = verts + [verts[0]] for start, end in zip(verts, verts[1:]): start = Vector(start) end = Vector(end) diff = end - start if diff.angle(tangent) < 1e-8: curve = SvLine.from_two_points(start, end) else: eq = circle_by_start_end_tangent(start, end, tangent) curve = SvCircle.from_equation(eq) _, angle = curve.get_u_bounds() tangent = Vector(curve.tangent(angle)) new_centers.append(curve.matrix) new_radius.append(curve.radius) new_angles.append(angle) new_curves.append(curve) if self.make_nurbs: new_curves = [c.to_nurbs() for c in new_curves] if self.concat: new_curves = [concatenate_curves(new_curves)] curve_out.append(new_curves) center_out.append(new_centers) radius_out.append(new_radius) angle_out.append(new_angles) self.outputs['Curve'].sv_set(curve_out) self.outputs['Center'].sv_set(center_out) self.outputs['Radius'].sv_set(radius_out) self.outputs['Angle'].sv_set(angle_out)
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 process(self): if not any(socket.is_linked for socket in self.outputs): return point1_s = self.inputs['Point1'].sv_get() point2_s = self.inputs['Point2'].sv_get() point3_s = self.inputs['Point3'].sv_get() point1_s = ensure_nesting_level(point1_s, 3) point2_s = ensure_nesting_level(point2_s, 3) point3_s = ensure_nesting_level(point3_s, 3) arcs_out = [] circles_out = [] centers_out = [] radius_out = [] angle_out = [] for point1s, point2s, point3s in zip_long_repeat( point1_s, point2_s, point3_s): arcs_new = [] circles_new = [] centers_new = [] radius_new = [] angle_new = [] for point1, point2, point3 in zip_long_repeat( point1s, point2s, point3s): circle_data = circle_by_three_points(point1, point2, point3) if circle_data is None: raise Exception( "Can't build a circle by these points: {}, {}, {}". format(point1, point2, point3)) matrix = circle_data.get_matrix() circle = SvCircle(matrix, circle_data.radius) # arc = SvCircle(radius=circle_data.radius, # center=np.array(circle_data.center), # normal=np.array(circle_data.normal), # vectorx = np.array(circle_data.point1) - np.array(circle_data.center)) #arc.u_bounds = (0.0, circle_data.arc_angle) arc = SvCircle.from_equation(circle_data) arcs_new.append(arc) circles_new.append(circle) centers_new.append(matrix) radius_new.append(circle_data.radius) angle_new.append(circle_data.arc_angle) if self.join: arcs_out.extend(arcs_new) circles_out.extend(circles_new) centers_out.extend(centers_new) radius_out.extend(radius_new) angle_out.extend(angle_new) else: arcs_out.append(arcs_new) circles_out.append(circles_new) centers_out.append(centers_new) radius_out.append(radius_new) angle_out.append(angle_new) self.outputs['Arc'].sv_set(arcs_out) self.outputs['Circle'].sv_set(circles_out) self.outputs['Center'].sv_set(centers_out) self.outputs['Radius'].sv_set(radius_out) self.outputs['Angle'].sv_set(angle_out)