def build_surface(implementation, degree_u, degree_v, knotvector_u, knotvector_v, control_points, weights=None, normalize_knots=False): kv_error = sv_knotvector.check(degree_u, knotvector_u, len(control_points)) if kv_error is not None: raise Exception("U direction: " + kv_error) kv_error = sv_knotvector.check(degree_v, knotvector_v, len(control_points[0])) if kv_error is not None: raise Exception("V direction: " + kv_error) nurbs_class = SvNurbsMaths.surface_classes.get(implementation) if nurbs_class is None: raise Exception( f"Unsupported NURBS Surface implementation: {implementation}") else: return nurbs_class.build(implementation, degree_u, degree_v, knotvector_u, knotvector_v, control_points, weights)
def split_at(self, t): current_multiplicity = sv_knotvector.find_multiplicity(self.knotvector, t) to_add = self.degree - current_multiplicity # + 1 curve = self.insert_knot(t, count=to_add) knot_span = np.searchsorted(curve.knotvector, t) ts = np.full((self.degree+1,), t) knotvector1 = np.concatenate((curve.knotvector[:knot_span], ts)) knotvector2 = np.insert(curve.knotvector[knot_span:], 0, t) control_points_1 = curve.control_points[:knot_span] control_points_2 = curve.control_points[knot_span-1:] weights_1 = curve.weights[:knot_span] weights_2 = curve.weights[knot_span-1:] kv_error = sv_knotvector.check(curve.degree, knotvector1, len(control_points_1)) if kv_error is not None: raise Exception(kv_error) kv_error = sv_knotvector.check(curve.degree, knotvector2, len(control_points_2)) if kv_error is not None: raise Exception(kv_error) curve1 = SvNativeNurbsCurve(curve.degree, knotvector1, control_points_1, weights_1) curve2 = SvNativeNurbsCurve(curve.degree, knotvector2, control_points_2, weights_2) return curve1, curve2
def build(cls, implementation, degree_u, degree_v, knotvector_u, knotvector_v, control_points, weights=None, normalize_knots=False): kv_error = sv_knotvector.check(degree_u, knotvector_u, len(control_points)) if kv_error is not None: raise Exception("U direction: " + kv_error) kv_error = sv_knotvector.check(degree_v, knotvector_v, len(control_points[0])) if kv_error is not None: raise Exception("V direction: " + kv_error) if implementation == SvNurbsSurface.GEOMDL: return SvGeomdlSurface.build(degree_u, degree_v, knotvector_u, knotvector_v, control_points, weights, normalize_knots) elif implementation == SvNurbsSurface.NATIVE: if normalize_knots: knotvector_u = sv_knotvector.normalize(knotvector_u) knotvector_v = sv_knotvector.normalize(knotvector_v) return SvNativeNurbsSurface(degree_u, degree_v, knotvector_u, knotvector_v, control_points, weights) else: raise Exception( f"Unsupported NURBS Surface implementation: {implementation}")
def test_remove_2(self): points = np.array( [[0, 0, 0], [0, 1, 0], [1, 2, 0], [2, 2, 0], [3, 1, 0], [3, 0, 0]], dtype=np.float64) degree = 3 kv = np.array([0, 0, 0, 0, 0.25, 0.75, 1, 1, 1, 1]) weights = [1, 1, 1, 1, 1, 1] curve = SvNativeNurbsCurve(degree, kv, points, weights) kv_err = sv_knotvector.check(degree, kv, len(points)) if kv_err is not None: raise Exception(kv_err) knot = 0.1 inserted = curve.insert_knot(knot, 1) self.assertEquals(len(inserted.get_control_points()), len(points) + 1) expected_inserted_kv = np.array( [0, 0, 0, 0, 0.1, 0.25, 0.75, 1, 1, 1, 1]) self.assert_numpy_arrays_equal(inserted.get_knotvector(), expected_inserted_kv, precision=8) inserted_kv = inserted.get_knotvector() k = np.searchsorted(inserted_kv, knot, side='right') - 1 s = sv_knotvector.find_multiplicity(inserted_kv, knot) print("K:", k, "S:", s) removed = inserted.remove_knot(knot, 1) self.assert_numpy_arrays_equal(removed.get_knotvector(), kv, precision=8)
def test_remove_1(self): points = np.array([[0, 0, 0], [1, 1, 0], [2, 1, 0], [3, 0, 0]]) degree = 3 kv = np.array([0, 0, 0, 0, 1, 1, 1, 1], dtype=np.float64) weights = [1, 1, 1, 1] ts = np.linspace(0.0, 1.0, num=5) curve = SvNativeNurbsCurve(degree, kv, points, weights) orig_pts = curve.evaluate_array(ts) kv_err = sv_knotvector.check(degree, kv, len(points)) if kv_err is not None: raise Exception(kv_err) knot = 0.5 inserted = curve.insert_knot(knot, 2) self.assertEquals(len(inserted.get_control_points()), len(points) + 2) self.assert_numpy_arrays_equal(inserted.evaluate_array(ts), orig_pts, precision=8) expected_inserted_kv = np.array([0, 0, 0, 0, 0.5, 0.5, 1, 1, 1, 1]) inserted_kv = inserted.get_knotvector() self.assert_numpy_arrays_equal(inserted_kv, expected_inserted_kv, precision=8) removed = inserted.remove_knot(knot, 2) expected_removed_kv = kv self.assert_numpy_arrays_equal(removed.get_knotvector(), expected_removed_kv, precision=8) self.assert_numpy_arrays_equal(removed.evaluate_array(ts), orig_pts, precision=8)
def _split_at(self, t): # Split without building SvNurbsCurve objects: # Some implementations (geomdl in particular) # can check number of control points vs curve degree, # and that can be bad for very small segments; # on the other hand, we may not care about it # if we are throwing away that small segment and # going to use only the bigger one. t_min, t_max = self.get_u_bounds() # corner cases if t <= t_min: return None, (self.get_knotvector(), self.get_control_points(), self.get_weights()) if t >= t_max: return (self.get_knotvector(), self.get_control_points(), self.get_weights()), None current_multiplicity = sv_knotvector.find_multiplicity( self.get_knotvector(), t) to_add = self.get_degree() - current_multiplicity # + 1 curve = self.insert_knot(t, count=to_add) knot_span = np.searchsorted(curve.get_knotvector(), t) ts = np.full((self.get_degree() + 1, ), t) knotvector1 = np.concatenate((curve.get_knotvector()[:knot_span], ts)) knotvector2 = np.insert(curve.get_knotvector()[knot_span:], 0, t) control_points_1 = curve.get_control_points()[:knot_span] control_points_2 = curve.get_control_points()[knot_span - 1:] weights_1 = curve.get_weights()[:knot_span] weights_2 = curve.get_weights()[knot_span - 1:] #print(f"S: ctlpts1: {len(control_points_1)}, 2: {len(control_points_2)}") kv_error = sv_knotvector.check(curve.get_degree(), knotvector1, len(control_points_1)) if kv_error is not None: raise Exception(kv_error) kv_error = sv_knotvector.check(curve.get_degree(), knotvector2, len(control_points_2)) if kv_error is not None: raise Exception(kv_error) curve1 = (knotvector1, control_points_1, weights_1) curve2 = (knotvector2, control_points_2, weights_2) return curve1, curve2
def build(cls, implementation, degree, knotvector, control_points, weights=None, normalize_knots=False): kv_error = sv_knotvector.check(degree, knotvector, len(control_points)) if kv_error is not None: raise Exception(kv_error) if implementation == SvNurbsCurve.NATIVE: if normalize_knots: knotvector = sv_knotvector.normalize(knotvector) return SvNativeNurbsCurve(degree, knotvector, control_points, weights) elif implementation == SvNurbsCurve.GEOMDL and geomdl is not None: return SvGeomdlCurve.build(degree, knotvector, control_points, weights, normalize_knots) else: raise Exception(f"Unsupported NURBS Curve implementation: {implementation}")
def build_curve(implementation, degree, knotvector, control_points, weights=None, normalize_knots=False): kv_error = sv_knotvector.check(degree, knotvector, len(control_points)) if kv_error is not None: raise Exception(kv_error) nurbs_class = SvNurbsMaths.curve_classes.get(implementation) if nurbs_class is None: raise Exception( f"Unsupported NURBS Curve implementation: {implementation}") else: return nurbs_class.build(implementation, degree, knotvector, control_points, weights, normalize_knots)