コード例 #1
0
ファイル: nurbs.py プロジェクト: ppaawweeuu/sverchok
    def insert_knot(self, direction, parameter, count=1):
        if direction == SvNurbsSurface.U:
            new_points = []
            new_weights = []
            new_u_degree = None
            for i in range(self.get_control_points().shape[1]):
                fixed_v_points = self.get_control_points()[:, i]
                fixed_v_weights = self.get_weights()[:, i]
                fixed_v_curve = SvNurbsMaths.build_curve(
                    SvNurbsMaths.NATIVE, self.degree_u, self.knotvector_u,
                    fixed_v_points, fixed_v_weights)
                fixed_v_curve = fixed_v_curve.insert_knot(parameter, count)
                fixed_v_knotvector = fixed_v_curve.get_knotvector()
                new_u_degree = fixed_v_curve.get_degree()
                fixed_v_points = fixed_v_curve.get_control_points()
                fixed_v_weights = fixed_v_curve.get_weights()
                new_points.append(fixed_v_points)
                new_weights.append(fixed_v_weights)

            new_points = np.transpose(np.array(new_points), axes=(1, 0, 2))
            new_weights = np.array(new_weights).T

            return SvNativeNurbsSurface(new_u_degree, self.degree_v,
                                        fixed_v_knotvector, self.knotvector_v,
                                        new_points, new_weights)

        elif direction == SvNurbsSurface.V:
            new_points = []
            new_weights = []
            new_v_degree = None
            for i in range(self.get_control_points().shape[0]):
                fixed_u_points = self.get_control_points()[i, :]
                fixed_u_weights = self.get_weights()[i, :]
                fixed_u_curve = SvNurbsMaths.build_curve(
                    SvNurbsMaths.NATIVE, self.degree_v, self.knotvector_v,
                    fixed_u_points, fixed_u_weights)
                fixed_u_curve = fixed_u_curve.insert_knot(parameter, count)
                fixed_u_knotvector = fixed_u_curve.get_knotvector()
                new_v_degree = fixed_u_curve.get_degree()
                fixed_u_points = fixed_u_curve.get_control_points()
                fixed_u_weights = fixed_u_curve.get_weights()
                new_points.append(fixed_u_points)
                new_weights.append(fixed_u_weights)

            new_points = np.array(new_points)
            new_weights = np.array(new_weights)

            return SvNativeNurbsSurface(self.degree_u, new_v_degree,
                                        self.knotvector_u, fixed_u_knotvector,
                                        new_points, new_weights)
        else:
            raise Exception("Unsupported direction")
コード例 #2
0
    def _arc_to_nurbs(self, t_min, t_max, implementation=SvNurbsMaths.NATIVE):
        alpha = t_max - t_min
        p0_x = cos(t_min)
        p0_y = sin(t_min)
        p2_x = cos(t_max)
        p2_y = sin(t_max)
        t_mid = 0.5 * (t_max + t_min)
        theta = 0.5 * alpha
        p1_r = 1.0 / cos(theta)
        p1_x = p1_r * cos(t_mid)
        p1_y = p1_r * sin(t_mid)

        control_points = np.array([[p0_x, p0_y, 0], [p1_x, p1_y, 0],
                                   [p2_x, p2_y, 0]])
        control_points = self.radius * control_points
        control_points = np.apply_along_axis(lambda v: self.matrix @ v, 1,
                                             control_points)
        control_points = self.center + control_points

        w1 = cos(theta)
        weights = np.array([1, w1, 1])
        degree = 2
        knotvector = sv_knotvector.generate(degree, 3)
        knotvector = sv_knotvector.rescale(knotvector, t_min, t_max)

        nurbs = SvNurbsMaths.build_curve(implementation, degree, knotvector,
                                         control_points, weights)

        if alpha > 2 * pi / 3:
            nurbs = nurbs.insert_knot(t_mid)

        return nurbs
コード例 #3
0
 def to_nurbs(self, implementation=SvNurbsMaths.NATIVE):
     knotvector = sv_knotvector.generate(3, 4)
     control_points = np.array([self.p0, self.p1, self.p2, self.p3])
     return SvNurbsMaths.build_curve(implementation,
                                     degree=3,
                                     knotvector=knotvector,
                                     control_points=control_points)
コード例 #4
0
ファイル: nurbs.py プロジェクト: Moult/sverchok
    def extrude_to_point(self, point):
        my_control_points = self.get_control_points()
        n = len(my_control_points)
        other_control_points = np.empty((n, 3))
        other_control_points[:] = point

        control_points = np.stack((my_control_points, other_control_points))
        control_points = np.transpose(control_points, axes=(1, 0, 2))

        my_weights = self.get_weights()
        other_weights = my_weights
        #other_weights = np.ones((n,))
        weights = np.stack((my_weights, other_weights)).T

        knotvector_u = self.get_knotvector()
        knotvector_v = sv_knotvector.generate(1, 2, clamped=True)

        degree_u = self.get_degree()
        degree_v = 1

        surface = SvNurbsMaths.build_surface(self.get_nurbs_implementation(),
                                             degree_u, degree_v, knotvector_u,
                                             knotvector_v, control_points,
                                             weights)
        return surface
コード例 #5
0
ファイル: nurbs_algorithms.py プロジェクト: Durman/sverchok
def interpolate_nurbs_curve(cls,
                            degree,
                            points,
                            metric='DISTANCE',
                            tknots=None):
    n = len(points)
    if points.ndim != 2:
        raise Exception(
            f"Array of points was expected, but got {points.shape}: {points}")
    ndim = points.shape[1]  # 3 or 4
    if ndim not in {3, 4}:
        raise Exception(
            f"Only 3D and 4D points are supported, but ndim={ndim}")
    #points3d = points[:,:3]
    #print("pts:", points)
    if tknots is None:
        tknots = Spline.create_knots(
            points, metric=metric)  # In 3D or in 4D, in general?
    knotvector = sv_knotvector.from_tknots(degree, tknots)
    functions = SvNurbsBasisFunctions(knotvector)
    coeffs_by_row = [
        functions.function(idx, degree)(tknots) for idx in range(n)
    ]
    A = np.zeros((ndim * n, ndim * n))
    for equation_idx, t in enumerate(tknots):
        for unknown_idx in range(n):
            coeff = coeffs_by_row[unknown_idx][equation_idx]
            row = ndim * equation_idx
            col = ndim * unknown_idx
            for d in range(ndim):
                A[row + d, col + d] = coeff
    B = np.zeros((ndim * n, 1))
    for point_idx, point in enumerate(points):
        row = ndim * point_idx
        B[row:row + ndim] = point[:, np.newaxis]

    x = np.linalg.solve(A, B)

    control_points = []
    for i in range(n):
        row = i * ndim
        control = x[row:row + ndim, 0].T
        control_points.append(control)
    control_points = np.array(control_points)
    if ndim == 3:
        weights = np.ones((n, ))
    else:  # 4
        control_points, weights = from_homogenous(control_points)

    if type(cls) == type:
        return cls.build(cls.get_nurbs_implementation(), degree, knotvector,
                         control_points, weights)
    elif isinstance(cls, str):
        return SvNurbsMaths.build_curve(cls, degree, knotvector,
                                        control_points, weights)
    else:
        raise TypeError(f"Unsupported type of `cls` parameter: {type(cls)}")
コード例 #6
0
 def to_nurbs(self, implementation=SvNurbsMaths.NATIVE):
     control_points = self.get_control_points()
     degree = self.get_degree()
     knotvector = sv_knotvector.generate(degree, len(control_points))
     nurbs = SvNurbsMaths.build_curve(implementation,
                                      degree=degree,
                                      knotvector=knotvector,
                                      control_points=control_points)
     return nurbs.cut_segment(*self.u_bounds)
コード例 #7
0
ファイル: nurbs.py プロジェクト: ppaawweeuu/sverchok
 def iso_curve(self, fixed_direction, param, flip=False):
     controls = self.get_control_points()
     weights = self.get_weights()
     k_u, k_v = weights.shape
     if fixed_direction == SvNurbsSurface.U:
         q_curves = [
             SvNurbsMaths.build_curve(self.get_nurbs_implementation(),
                                      self.get_degree_u(),
                                      self.get_knotvector_u(),
                                      controls[:, j], weights[:, j])
             for j in range(k_v)
         ]
         q_controls = [q_curve.evaluate(param) for q_curve in q_curves]
         q_weights = [
             q_curve.fraction_single(0, param)[1] for q_curve in q_curves
         ]
         curve = SvNurbsMaths.build_curve(self.get_nurbs_implementation(),
                                          self.get_degree_v(),
                                          self.get_knotvector_v(),
                                          q_controls, q_weights)
         if flip:
             return curve.reverse()
         else:
             return curve
     elif fixed_direction == SvNurbsSurface.V:
         q_curves = [
             SvNurbsMaths.build_curve(self.get_nurbs_implementation(),
                                      self.get_degree_v(),
                                      self.get_knotvector_v(),
                                      controls[i, :], weights[i, :])
             for i in range(k_u)
         ]
         q_controls = [q_curve.evaluate(param) for q_curve in q_curves]
         q_weights = [
             q_curve.fraction_single(0, param)[1] for q_curve in q_curves
         ]
         curve = SvNurbsMaths.build_curve(self.get_nurbs_implementation(),
                                          self.get_degree_u(),
                                          self.get_knotvector_u(),
                                          q_controls, q_weights)
         if flip:
             return curve.reverse()
         else:
             return curve
コード例 #8
0
ファイル: nurbs.py プロジェクト: ppaawweeuu/sverchok
 def iso_curve(self, fixed_direction, param, flip=False):
     if self.surface.rational:
         raise UnsupportedSurfaceTypeException(
             "iso_curve() is not supported for rational Geomdl surfaces yet"
         )
     controls = self.get_control_points()
     weights = self.get_weights()
     k_u, k_v = weights.shape
     if fixed_direction == SvNurbsSurface.U:
         q_curves = [
             SvNurbsMaths.build_curve(self.get_nurbs_implementation(),
                                      self.get_degree_u(),
                                      self.get_knotvector_u(),
                                      controls[:, j], weights[:, j])
             for j in range(k_v)
         ]
         q_controls = [q_curve.evaluate(param) for q_curve in q_curves]
         q_weights = np.ones((k_v, ))
         curve = SvNurbsMaths.build_curve(self.get_nurbs_implementation(),
                                          self.get_degree_v(),
                                          self.get_knotvector_v(),
                                          q_controls, q_weights)
         if flip:
             return curve.reverse()
         else:
             return curve
     elif fixed_direction == SvNurbsSurface.V:
         q_curves = [
             SvNurbsMaths.build_curve(self.get_nurbs_implementation(),
                                      self.get_degree_v(),
                                      self.get_knotvector_v(),
                                      controls[i, :], weights[i, :])
             for i in range(k_u)
         ]
         q_controls = [q_curve.evaluate(param) for q_curve in q_curves]
         q_weights = np.ones((k_u, ))
         curve = SvNurbsMaths.build_curve(self.get_nurbs_implementation(),
                                          self.get_degree_u(),
                                          self.get_knotvector_u(),
                                          q_controls, q_weights)
         if flip:
             return curve.reverse()
         else:
             return curve
コード例 #9
0
 def to_nurbs(self, implementation=SvNurbsMaths.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 SvNurbsMaths.build_curve(implementation,
                                     degree=1,
                                     knotvector=knotvector,
                                     control_points=control_points)
コード例 #10
0
ファイル: freecad.py プロジェクト: DolphinDream/sverchok
 def to_nurbs(self, implementation=SvNurbsMaths.FREECAD):
     curve = self.curve.toBSpline(*self.u_bounds)
     #curve.transform(self.edge.Matrix)
     control_points = np.array(curve.getPoles())
     weights = np.array(curve.getWeights())
     knotvector = np.array(curve.KnotSequence)
     curve = SvNurbsMaths.build_curve(implementation, curve.Degree,
                                      knotvector, control_points, weights)
     #curve.u_bounds = self.u_bounds
     return curve
コード例 #11
0
ファイル: nurbs.py プロジェクト: Moult/sverchok
 def build(cls,
           implementation,
           degree,
           knotvector,
           control_points,
           weights=None,
           normalize_knots=False):
     return SvNurbsMaths.build_curve(implementation, degree, knotvector,
                                     control_points, weights,
                                     normalize_knots)
コード例 #12
0
ファイル: nurbs.py プロジェクト: ppaawweeuu/sverchok
 def build(cls,
           implementation,
           degree_u,
           degree_v,
           knotvector_u,
           knotvector_v,
           control_points,
           weights=None,
           normalize_knots=False):
     return SvNurbsMaths.build_surface(implementation, degree_u, degree_v,
                                       knotvector_u, knotvector_v,
                                       control_points, weights,
                                       normalize_knots)
コード例 #13
0
    def to_nurbs(self, implementation=SvNurbsMaths.NATIVE):
        t_min, t_max = self.get_u_bounds()
        epsilon = 1e-6

        if -2 * pi < t_min < 0 and 0 < t_max < 2 * pi:
            arc1 = self.copy()
            arc1.u_bounds = (2 * pi + t_min, 2 * pi)
            arc1 = arc1.to_nurbs()
            arc2 = self.copy()
            arc2.u_bounds = (0, t_max)
            arc2 = arc2.to_nurbs()
            return arc1.concatenate(arc2)

        if t_min < 0 or t_max > 2 * pi + epsilon:
            raise UnsupportedCurveTypeException(
                f"Can't transform a circle arc out of 0-2pi bound ({t_min} - {t_max}) to NURBS"
            )

        #print(f"T {t_min},{t_max}, 2pi {2*pi}")
        if t_max - t_min < pi:
            return self._arc_to_nurbs(t_min, t_max, implementation)
        elif t_max - t_min < 2 * pi + epsilon:
            half = self._half_circle_nurbs(t_min, implementation)
            if abs(t_max - t_min - pi) < epsilon:
                return half
            arc = self._arc_to_nurbs(t_min + pi, t_max, implementation)
            return half.concatenate(arc)

        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)
        control_points = self.center + 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 = SvNurbsMaths.build_curve(implementation, degree, knotvector,
                                         control_points, weights)

        #if t_min != 0 or t_max != 2*pi:
        #print(f"Cut {t_min} - {t_max}")
        #curve = curve_segment(curve, t_min, t_max)
        return curve
コード例 #14
0
ファイル: core.py プロジェクト: DolphinDream/sverchok
 def to_nurbs(self, implementation=SvNurbsMaths.NATIVE):
     control_points = self.get_control_points()
     if control_points.shape[1] == 4:
         control_points, weights = from_homogenous(control_points)
     else:
         weights = None
     degree = self.get_degree()
     knotvector = sv_knotvector.generate(degree, len(control_points))
     u1, u2 = self.get_u_bounds()
     knotvector = (u2 - u1) * knotvector + u1
     nurbs = SvNurbsMaths.build_curve(implementation,
                                      degree=degree,
                                      knotvector=knotvector,
                                      control_points=control_points,
                                      weights=weights)
     #return nurbs.reparametrize(*self.get_u_bounds())
     return nurbs
コード例 #15
0
ファイル: freecad.py プロジェクト: 615120036/sverchok
def curve_to_freecad_nurbs(sv_curve):
    """
    Convert SvCurve to FreeCAD's NURBS curve.
    Raise an exception if it is not possible.

    input: SvCurve
    output: SvFreeCadNurbsCurve
    """
    nurbs = SvNurbsCurve.to_nurbs(sv_curve)
    if nurbs is None:
        raise TypeError(f"{sv_curve} is not a NURBS curve")
    fc_curve = SvNurbsMaths.build_curve(SvNurbsMaths.FREECAD,
                nurbs.get_degree(),
                nurbs.get_knotvector(),
                nurbs.get_control_points(),
                nurbs.get_weights())
    return fc_curve
コード例 #16
0
    def to_nurbs(self, implementation = SvNurbsMaths.NATIVE):
        u_min, u_max = self.u_bounds
        v_min, v_max = self.v_bounds
        pt1 = self.evaluate(u_min, v_min)
        pt2 = self.evaluate(u_min, v_max)
        pt3 = self.evaluate(u_max, v_min)
        pt4 = self.evaluate(u_max, v_max)

        control_points = np.array([[pt1, pt2], [pt3, pt4]])
        weights = np.array([[1,1], [1, 1]])
        degree_u = degree_v = 1
        knotvector_u = knotvector_v = sv_knotvector.generate(1, 2)

        return SvNurbsMaths.build_surface(implementation,
                degree_u, degree_v,
                knotvector_u, knotvector_v,
                control_points, weights)
コード例 #17
0
ファイル: nurbs.py プロジェクト: Moult/sverchok
    def make_ruled_surface(self, curve2, vmin, vmax):
        curve = self
        curve2 = SvNurbsCurve.to_nurbs(curve2)
        if curve2 is None:
            raise UnsupportedCurveTypeException("second curve is not NURBS")
        curve, curve2 = unify_curves_degree([curve, curve2])
        if curve.get_degree() != curve2.get_degree():
            raise UnsupportedCurveTypeException(
                f"curves have different degrees: {curve.get_degree()} != {curve2.get_degree()}"
            )

        #print(f"kv1: {curve.get_knotvector().shape}, kv2: {curve2.get_knotvector().shape}")
        kv1, kv2 = curve.get_knotvector(), curve2.get_knotvector()
        if kv1.shape != kv2.shape or (kv1 != kv2).any():
            curve, curve2 = unify_two_curves(curve, curve2)
            #raise UnsupportedCurveTypeException("curves have different knot vectors")

        my_control_points = curve.get_control_points()
        other_control_points = curve2.get_control_points()
        if len(my_control_points) != len(other_control_points):
            raise UnsupportedCurveTypeException(
                "curves have different number of control points")

        if vmin != 0:
            my_control_points = (
                1 - vmin) * my_control_points + vmin * other_control_points
        if vmax != 0:
            other_control_points = (
                1 - vmax) * my_control_points + vmax * other_control_points

        control_points = np.stack((my_control_points, other_control_points))
        control_points = np.transpose(control_points, axes=(1, 0, 2))

        weights = np.stack((curve.get_weights(), curve2.get_weights())).T
        knotvector_v = sv_knotvector.generate(1, 2, clamped=True)

        surface = SvNurbsMaths.build_surface(
            self.get_nurbs_implementation(),
            degree_u=curve.get_degree(),
            degree_v=1,
            knotvector_u=curve.get_knotvector(),
            knotvector_v=knotvector_v,
            control_points=control_points,
            weights=weights)
        return surface
コード例 #18
0
ファイル: freecad.py プロジェクト: DolphinDream/sverchok
    def to_nurbs(self, implementation=SvNurbsMaths.FREECAD):
        curve = self.curve.toBSpline(*self.u_bounds)

        if implementation == SvNurbsMaths.FREECAD:
            return SvFreeCadNurbsCurve(curve, self.ndim)

        #curve.transform(self.edge.Matrix)
        if self.ndim == 2:
            control_points = [(p.x, p.y, 0) for p in curve.getPoles()]
        else:
            control_points = [(p.x, p.y, p.z) for p in curve.getPoles()]
        control_points = np.array(control_points)
        weights = np.array(curve.getWeights())
        knotvector = np.array(curve.KnotSequence)

        curve = SvNurbsMaths.build_curve(implementation, curve.Degree,
                                         knotvector, control_points, weights)
        #curve.u_bounds = self.u_bounds
        return curve
コード例 #19
0
ファイル: nurbs.py プロジェクト: Moult/sverchok
 def transform(self, frame, vector):
     """
     Apply transformation matrix to the curve.
     Inputs:
     * frame: np.array of shape (3,3) - transformation matrix
     * vector: np.array of shape (3,) - translation vector
     Output: new NURBS curve of the same implementation.
     """
     if frame is None and vector is None:
         return self
     elif frame is None and vector is not None:
         fn = lambda p: p + vector
     elif frame is not None and vector is None:
         fn = lambda p: frame @ p
     else:
         fn = lambda p: frame @ p + vector
     new_controls = np.apply_along_axis(fn, 1, self.get_control_points())
     return SvNurbsMaths.build_curve(self.get_nurbs_implementation(),
                                     self.get_degree(),
                                     self.get_knotvector(), new_controls,
                                     self.get_weights())
コード例 #20
0
ファイル: freecad.py プロジェクト: Durman/sverchok
def surface_to_freecad(sv_surface, make_face=False):
    """
    Convert SvSurface into FreeCAD's Surface.
    The surface must be presentable as NURBS.

    input:
      * sv_surface: SvSurface
      * make_face: if True, create a Part.Face out of the surface and assign it
        to the `face` property of the resulting surface
    output: SvFreeCadNurbsSurface
    """
    nurbs = SvNurbsSurface.get(sv_surface)
    if nurbs is None:
        raise TypeError(f"{sv_surface} is not a NURBS surface")
    sv_fc_nurbs = SvNurbsMaths.build_surface(SvNurbsMaths.FREECAD,
                                             nurbs.get_degree_u(),
                                             nurbs.get_degree_v(),
                                             nurbs.get_knotvector_u(),
                                             nurbs.get_knotvector_v(),
                                             nurbs.get_control_points(),
                                             nurbs.get_weights())
    if make_face:
        sv_fc_nurbs.face = Part.Face(sv_fc_nurbs.surface)
    return sv_fc_nurbs
コード例 #21
0
    def _half_circle_nurbs(self, t_min, implementation=SvNurbsMaths.NATIVE):
        control_points = np.array([[1, 0, 0], [1, 1, 0], [0, 1, 0], [-1, 1, 0],
                                   [-1, 0, 0]])

        ct, st = cos(t_min), sin(t_min)
        rotate = np.array([[ct, -st, 0], [st, ct, 0], [0, 0, 1]])
        control_points = np.apply_along_axis(lambda v: rotate @ v, 1,
                                             control_points)

        control_points = self.radius * control_points
        control_points = np.apply_along_axis(lambda v: self.matrix @ v, 1,
                                             control_points)
        control_points = self.center + control_points

        sqrt22 = sqrt(2.0) / 2.0
        weights = np.array([1, sqrt22, 1, sqrt22, 1])
        pi2 = pi / 2.0
        knotvector = np.array([0, 0, 0, pi2, pi2, pi, pi, pi])
        knotvector += t_min

        degree = 2
        nurbs = SvNurbsMaths.build_curve(implementation, degree, knotvector,
                                         control_points, weights)
        return nurbs
コード例 #22
0
ファイル: nurbs.py プロジェクト: ppaawweeuu/sverchok
    def elevate_degree(self, direction, delta=None, target=None):
        if delta is None and target is None:
            delta = 1
        if delta is not None and target is not None:
            raise Exception(
                "Of delta and target, only one parameter can be specified")
        if direction == SvNurbsSurface.U:
            degree = self.get_degree_u()
        else:
            degree = self.get_degree_v()
        if delta is None:
            delta = target - degree
            if delta < 0:
                raise Exception(
                    f"Surface already has degree {degree}, which is greater than target {target}"
                )
        if delta == 0:
            return self

        implementation = self.get_nurbs_implementation()

        if direction == SvNurbsSurface.U:
            new_points = []
            new_weights = []
            new_u_degree = None
            for i in range(self.get_control_points().shape[1]):
                fixed_v_points = self.get_control_points()[:, i]
                fixed_v_weights = self.get_weights()[:, i]
                fixed_v_curve = SvNurbsMaths.build_curve(
                    implementation, self.get_degree_u(),
                    self.get_knotvector_u(), fixed_v_points, fixed_v_weights)
                fixed_v_curve = fixed_v_curve.elevate_degree(delta)
                fixed_v_knotvector = fixed_v_curve.get_knotvector()
                new_u_degree = fixed_v_curve.get_degree()
                fixed_v_points = fixed_v_curve.get_control_points()
                fixed_v_weights = fixed_v_curve.get_weights()
                new_points.append(fixed_v_points)
                new_weights.append(fixed_v_weights)

            new_points = np.transpose(np.array(new_points), axes=(1, 0, 2))
            new_weights = np.array(new_weights).T

            return SvNurbsSurface.build(self.get_nurbs_implementation(),
                                        new_u_degree, self.get_degree_v(),
                                        fixed_v_knotvector,
                                        self.get_knotvector_v(), new_points,
                                        new_weights)

        elif direction == SvNurbsSurface.V:
            new_points = []
            new_weights = []
            new_v_degree = None
            for i in range(self.get_control_points().shape[0]):
                fixed_u_points = self.get_control_points()[i, :]
                fixed_u_weights = self.get_weights()[i, :]
                fixed_u_curve = SvNurbsMaths.build_curve(
                    implementation, self.get_degree_v(),
                    self.get_knotvector_v(), fixed_u_points, fixed_u_weights)
                fixed_u_curve = fixed_u_curve.elevate_degree(delta)
                fixed_u_knotvector = fixed_u_curve.get_knotvector()
                new_v_degree = fixed_u_curve.get_degree()
                fixed_u_points = fixed_u_curve.get_control_points()
                fixed_u_weights = fixed_u_curve.get_weights()
                new_points.append(fixed_u_points)
                new_weights.append(fixed_u_weights)

            new_points = np.array(new_points)
            new_weights = np.array(new_weights)

            return SvNurbsSurface.build(implementation, self.get_degree_u(),
                                        new_v_degree, self.get_knotvector_u(),
                                        fixed_u_knotvector, new_points,
                                        new_weights)
コード例 #23
0
 def concatenate(self, curve2):
     curve2 = SvNurbsMaths.to_nurbs_curve(curve2)
     if curve2 is None:
         raise UnsupportedCurveTypeException("Second curve is not a NURBS")
     return self.to_nurbs().concatenate(curve2)
コード例 #24
0
ファイル: primitives.py プロジェクト: DolphinDream/sverchok
    def to_nurbs_arc(self,
                     n=4,
                     t_min=None,
                     t_max=None,
                     implementation=SvNurbsMaths.NATIVE):
        if t_min is None:
            t_min = 0.0
        if t_max is None:
            t_max = 2 * pi

        if t_max < t_min:
            return self.to_nurbs_arc(n=n,
                                     t_max=t_min,
                                     t_min=t_max,
                                     implementation=implementation).reverse()

        omega = t_max - t_min
        alpha = pi / n
        n_full_arcs = round(omega // (2 * alpha))
        small_arc_angle = omega % (2 * alpha)

        idxs_full = np.array(range(2 * n_full_arcs + 1), dtype=np.float64)
        ts_full = pi * idxs_full / n + t_min
        rs_full = np.where(idxs_full % 2 == 0, 1.0, 1.0 / cos(alpha))

        xs_full = rs_full * np.cos(ts_full)
        ys_full = rs_full * np.sin(ts_full)
        zs_full = np.zeros_like(xs_full)

        weights_full = np.where(idxs_full % 2 == 0, 1.0, cos(alpha))

        knots_full = np.array(range(n_full_arcs + 1), dtype=np.float64)
        knots_full = 2 * pi * knots_full / n + t_min
        knots_full = np.repeat(knots_full, 2)

        if small_arc_angle > 1e-6:
            t_mid_small_arc = ts_full[-1] + small_arc_angle / 2.0
            r_mid_small_arc = 1.0 / cos(small_arc_angle / 2.0)
            x_mid_small_arc = r_mid_small_arc * cos(t_mid_small_arc)
            y_mid_small_arc = r_mid_small_arc * sin(t_mid_small_arc)
            z_mid_small_arc = 0.0

            x_end = cos(t_max)
            y_end = sin(t_max)
            z_end = 0.0

            xs = np.concatenate((xs_full, [x_mid_small_arc, x_end]))
            ys = np.concatenate((ys_full, [y_mid_small_arc, y_end]))
            zs = np.concatenate((zs_full, [z_mid_small_arc, z_end]))

            weight_mid_small_arc = cos(small_arc_angle / 2.0)
            weight_end = 1.0
            weights = np.concatenate(
                (weights_full, [weight_mid_small_arc, weight_end]))

            knots = np.concatenate((knots_full, [t_max, t_max]))
        else:
            xs = xs_full
            ys = ys_full
            zs = zs_full

            weights = weights_full
            knots = knots_full

        knots = np.concatenate(([knots[0]], knots, [knots[-1]]))

        control_points = np.stack((xs, ys, zs)).T
        control_points = self.radius * control_points
        control_points = np.apply_along_axis(lambda v: self.matrix @ v, 1,
                                             control_points)
        control_points = self.center + control_points

        degree = 2
        curve = SvNurbsMaths.build_curve(implementation, degree, knots,
                                         control_points, weights)
        return curve
コード例 #25
0
 def to_nurbs(self, implementation=SvNurbsMaths.NATIVE):
     knotvector = sv_knotvector.generate(self.degree, len(self.points))
     return SvNurbsMaths.build_curve(implementation,
                                     degree=self.degree,
                                     knotvector=knotvector,
                                     control_points=self.points)