def test_curve_3436(self): points = [(0.0, 0.0, 0.0), (0.5, 0.0, 0.5), (1.0, 0.0, 0.0)] ts = np.array([0, 0.5, 1, 1.61803397]) #ts = self.ts degree = 2 knotvector = [0, 0, 0, 1, 1, 1] weights = [1, 1, 1] geomdl_curve = SvNurbsCurve.build('GEOMDL', degree, knotvector, points, weights) native_curve = SvNurbsCurve.build('NATIVE', degree, knotvector, points, weights) p1s = geomdl_curve.evaluate_array(ts) p2s = native_curve.evaluate_array(ts) #print("NATIVE:", p2s) self.assert_numpy_arrays_equal(p1s, p2s, precision=8)
def to_nurbs(self, implementation=SvNurbsCurve.NATIVE): knotvector = sv_knotvector.generate(3, 4) control_points = np.array([self.p0, self.p1, self.p2, self.p3]) return SvNurbsCurve.build(implementation, degree=3, knotvector=knotvector, control_points=control_points)
def process(self): if not any(socket.is_linked for socket in self.outputs): return vertices_s = self.inputs['ControlPoints'].sv_get() has_weights = self.inputs['Weights'].is_linked weights_s = self.inputs['Weights'].sv_get(default = [[1.0]]) knots_s = self.inputs['Knots'].sv_get(default = [[]]) degree_s = self.inputs['Degree'].sv_get() curves_out = [] knots_out = [] for vertices, weights, knots, degree in zip_long_repeat(vertices_s, weights_s, knots_s, degree_s): if isinstance(degree, (tuple, list)): degree = degree[0] n_source = len(vertices) fullList(weights, n_source) if self.knot_mode == 'AUTO' and self.is_cyclic: vertices = vertices + vertices[:degree] weights = weights + weights[:degree] n_total = len(vertices) # Set degree curve_degree = degree if has_weights and self.surface_mode == 'NURBS': curve_weights = weights else: curve_weights = None # Set knot vector if self.knot_mode == 'AUTO': if self.is_cyclic: self.debug("N: %s, degree: %s", n_total, degree) knots = list(range(n_total + degree + 1)) else: knots = sv_knotvector.generate(curve_degree, n_total) self.debug('Auto knots: %s', knots) curve_knotvector = knots else: self.debug('Manual knots: %s', knots) curve_knotvector = knots new_curve = SvNurbsCurve.build(self.implementation, degree, curve_knotvector, vertices, curve_weights, normalize_knots = self.normalize_knots) curve_knotvector = new_curve.get_knotvector().tolist() if self.knot_mode == 'AUTO' and self.is_cyclic: u_min = curve_knotvector[degree] u_max = curve_knotvector[-degree-1] new_curve.u_bounds = u_min, u_max else: u_min = min(curve_knotvector) u_max = max(curve_knotvector) new_curve.u_bounds = (u_min, u_max) curves_out.append(new_curve) knots_out.append(curve_knotvector) self.outputs['Curve'].sv_set(curves_out) self.outputs['Knots'].sv_set(knots_out)
def process(self): if not any(socket.is_linked for socket in self.outputs): return curve_s = self.inputs['Curve'].sv_get() field_s = self.inputs['Field'].sv_get() coeff_s = self.inputs['Coefficient'].sv_get() curve_s = ensure_nesting_level(curve_s, 2, data_types=(SvCurve, )) field_s = ensure_nesting_level(field_s, 2, data_types=(SvVectorField, )) coeff_s = ensure_nesting_level(coeff_s, 2) curve_out = [] for curve_i, field_i, coeff_i in zip_long_repeat( curve_s, field_s, coeff_s): new_curves = [] for curve, field, coeff in zip_long_repeat(curve_i, field_i, coeff_i): if self.use_control_points: nurbs = SvNurbsCurve.to_nurbs(curve) if nurbs is not None: control_points = nurbs.get_control_points() else: raise Exception("Curve is not a NURBS!") cpt_xs = control_points[:, 0] cpt_ys = control_points[:, 1] cpt_zs = control_points[:, 2] cpt_dxs, cpt_dys, cpt_dzs = field.evaluate_grid( cpt_xs, cpt_ys, cpt_zs) xs = cpt_xs + coeff * cpt_dxs ys = cpt_ys + coeff * cpt_dys zs = cpt_zs + coeff * cpt_dzs control_points = np.stack((xs, ys, zs)).T knotvector = nurbs.get_knotvector() #old_t_min, old_t_max = curve.get_u_bounds() #knotvector = sv_knotvector.rescale(knotvector, old_t_min, old_t_max) new_curve = SvNurbsCurve.build( nurbs.get_nurbs_implementation(), nurbs.get_degree(), knotvector, control_points, nurbs.get_weights()) new_curve.u_bounds = nurbs.u_bounds else: new_curve = SvDeformedByFieldCurve(curve, field, coeff) new_curves.append(new_curve) if self.join: curve_out.extend(new_curves) else: curve_out.append(new_curves) self.outputs['Curve'].sv_set(curve_out)
def test_outside_sphere_3(self): cpts = np.array([[-2, 5, 0], [2, 5, 0]]) degree = 1 knotvector = sv_knotvector.generate(degree, len(cpts)) curve = SvNurbsCurve.build(SvNurbsCurve.NATIVE, degree, knotvector, cpts) result = curve.is_strongly_outside_sphere(np.array([0, 0, 0]), 1) expected_result = True self.assertEquals(result, expected_result)
def to_nurbs(self, implementation=SvNurbsCurve.NATIVE): knotvector = sv_knotvector.generate(1, 2) u_min, u_max = self.get_u_bounds() p1 = self.evaluate(u_min) p2 = self.evaluate(u_max) control_points = np.array([p1, p2]) return SvNurbsCurve.build(implementation, degree=1, knotvector=knotvector, control_points=control_points)
def to_nurbs(self, implementation=SvNurbsCurve.NATIVE): control_points = self.spline.get_control_points() degree = self.spline.get_degree() n_points = degree + 1 knotvector = sv_knotvector.generate(degree, n_points) t_segments = self.spline.get_t_segments() segments = [SvNurbsCurve.build(implementation, degree, knotvector, points) for points in control_points] segments = [reparametrize_curve(segment, t_min, t_max) for segment, (t_min, t_max) in zip(segments, t_segments)] # pairs = [f"#{i}: {t_min}-{t_max}: {segment.evaluate(t_min)} -- {segment.evaluate(t_max)}" for i, (segment, (t_min, t_max)) in enumerate(zip(segments, t_segments))] # pairs = ", ".join(pairs) # print(f"S: {pairs}") return concatenate_nurbs_curves(segments)
def scipy_nurbs_approximate(points, weights=None, metric='DISTANCE', degree=3, filter_doubles=None, smoothing=None, is_cyclic=False): points = np.asarray(points) if weights is not None and len(points) != len(weights): raise Exception("Number of weights must be equal to number of points") if filter_doubles is not None: good = np.where( np.linalg.norm(np.diff(points, axis=0), axis=1) > filter_doubles) points = np.r_[points[good], points[-1][np.newaxis]] if weights is not None: weights = np.r_[weights[good], weights[-1]] if is_cyclic: if (points[0] != points[-1]).any(): points = np.vstack((points, points[0])) if weights is not None: weights = np.insert(weights, -1, weights[0]) points_orig = points points = points.T kwargs = dict() if weights is not None: kwargs['w'] = np.asarray(weights) if metric is not None: tknots = Spline.create_knots(points.T, metric) if len(tknots) != len(points.T): raise Exception( f"Number of T knots ({len(tknots)}) is not equal to number of points ({len(points.T)})" ) kwargs['u'] = tknots if degree is not None: kwargs['k'] = degree if smoothing is not None: kwargs['s'] = smoothing if is_cyclic: kwargs['per'] = 1 tck, u = interpolate.splprep(points, **kwargs) knotvector = tck[0] control_points = np.stack(tck[1]).T degree = tck[2] curve = SvNurbsCurve.build(SvNurbsCurve.NATIVE, degree, knotvector, control_points) if is_cyclic: curve = curve.cut_segment(0.0, 1.00) #curve.u_bounds = (0.0, 1.0) return curve
def test_bezier_to_taylor_2(self): cpts = np.array([[0, 0, 0], [1, 0, 0], [1, 1, 0], [2, 1, 0]], dtype=np.float64) degree = 3 knotvector = sv_knotvector.generate(degree, len(cpts)) knotvector += 1.0 curve = SvNurbsCurve.build(SvNurbsCurve.NATIVE, degree, knotvector, cpts) taylor = curve.bezier_to_taylor() nurbs = taylor.to_nurbs() self.assert_numpy_arrays_equal(nurbs.get_control_points(), cpts, precision=8)
def get_curve(self, spline, matrix): curve_degree = spline.order_u - 1 if self.apply_matrix: vertices = [ tuple(matrix @ Vector(p.co[:3])) for p in spline.points ] else: vertices = [tuple(p.co)[:3] for p in spline.points] weights = [tuple(p.co)[3] for p in spline.points] if spline.use_cyclic_u: vertices = vertices + vertices[:curve_degree + 1] weights = weights + weights[:curve_degree + 1] n_total = len(vertices) curve_ctrlpts = vertices curve_weights = weights if spline.use_cyclic_u: knots = list(range(n_total + curve_degree + 1)) else: knots = sv_knotvector.generate(curve_degree, n_total, clamped=spline.use_endpoint_u) self.debug('Auto knots: %s', knots) curve_knotvector = knots new_curve = SvNurbsCurve.build(self.implementation, curve_degree, curve_knotvector, curve_ctrlpts, curve_weights) if spline.use_cyclic_u: u_min = curve_knotvector[curve_degree] u_max = curve_knotvector[-curve_degree - 2] new_curve = new_curve.cut_segment(u_min, u_max) #new_curve.u_bounds = u_min, u_max else: if spline.use_endpoint_u: u_min = min(curve_knotvector) u_max = max(curve_knotvector) else: u_min = curve_knotvector[curve_degree] u_max = curve_knotvector[-curve_degree - 1] new_curve.u_bounds = (u_min, u_max) return new_curve
def test_bezier_to_taylor_1(self): cpts = np.array([[0, 0, 0], [1, 0, 0], [1, 1, 0], [2, 1, 0]], dtype=np.float64) degree = 3 knotvector = sv_knotvector.generate(degree, len(cpts)) curve = SvNurbsCurve.build(SvNurbsCurve.NATIVE, degree, knotvector, cpts) taylor = curve.bezier_to_taylor() coeffs = taylor.get_coefficients() self.assert_numpy_arrays_equal(coeffs[0], np.array([0, 0, 0, 1]), precision=8) self.assert_numpy_arrays_equal(coeffs[1], np.array([3, 0, 0, 0]), precision=8) self.assert_numpy_arrays_equal(coeffs[2], np.array([-3, 3, 0, 0]), precision=8) self.assert_numpy_arrays_equal(coeffs[3], np.array([2, -2, 0, 0]), precision=8)
def to_nurbs(self, implementation=SvNurbsCurve.NATIVE): t_min, t_max = self.get_u_bounds() if t_min < 0 or t_max > 2 * pi: raise UnsupportedCurveTypeException( f"Can't transform a circle arc out of 0-2pi bound ({t_min} - {t_max}) to NURBS" ) control_points = np.array([[1, 0, 0], [1, 1, 0], [0, 1, 0], [-1, 1, 0], [-1, 0, 0], [-1, -1, 0], [0, -1, 0], [1, -1, 0], [1, 0, 0]]) control_points = self.radius * control_points control_points = np.apply_along_axis(lambda v: self.matrix @ v, 1, control_points) sqrt22 = sqrt(2.0) / 2.0 weights = np.array([1, sqrt22, 1, sqrt22, 1, sqrt22, 1, sqrt22, 1]) pi2 = pi / 2.0 pi32 = 3 * pi / 2.0 knotvector = np.array( [0, 0, 0, pi2, pi2, pi, pi, pi32, pi32, 2 * pi, 2 * pi, 2 * pi]) degree = 2 curve = SvNurbsCurve.build(implementation, degree, knotvector, control_points, weights) if t_min != 0 or t_max != 2 * pi: curve = curve_segment(curve, t_min, t_max) return curve
def to_nurbs(self, implementation=SvNurbsCurve.NATIVE): knotvector = sv_knotvector.generate(self.degree, len(self.points)) return SvNurbsCurve.build(implementation, degree=self.degree, knotvector=knotvector, control_points=self.points)