コード例 #1
0
ファイル: bezier_surface.py プロジェクト: trelau/pyNURBS
    def extract(self, u0=0., u1=1., v0=0., v1=1., domain='local'):
        """
        Extract Bezier surface bounded by parameters.

        :param float u0: Starting parameter in u-direction.
        :param float u1: Ending parameter in u-direction.
        :param float v0: Starting parameter in v-direction.
        :param float v1: Ending parameter in v-direction.
        :param str domain: Option to use local (0 <= u, v <= 1) or global
            (a <= u, v <= b) domain ('local', 'l', 'global', 'g').

        :return: Extracted Bezier surface.
        :rtype: :class:`.BezierSurface`
        """
        if not is_local_domain(domain):
            u0 = self.global_to_local_param('u', u0)
            u1 = self.global_to_local_param('u', u1)
            v0 = self.global_to_local_param('v', v0)
            v1 = self.global_to_local_param('v', v1)
        qw, ab = extract_bezier_surface(self._n, self._m, self._cpw, u0, u1,
                                        v0, v1, self._u0, self._u1, self._v0,
                                        self._v1)
        s = BezierSurface()
        s.set_cpw(qw)
        s.set_domain(ab[0, 0], ab[0, 1], ab[1, 0], ab[1, 1])
        return s
コード例 #2
0
ファイル: bezier_surface.py プロジェクト: trelau/pyNURBS
    def eval_params(self, ulist, vlist, rtype='Point', domain='local'):
        """
        Evaluate the surface at multiple parameters.

        :param array_like ulist: Parameters in u-direction.
        :param array_like vlist: Parameters in v-direction.
        :param str rtype: Option to return a NumPy array or Point instance
            (rtype = 'ndarray' or 'Point').
        :param str domain: Option to use local (0 <= u, v <= 1) or global
            (a <= u, v <= b) domain ('local', 'l', 'global', 'g').

        :return: Points on surface.
        :rtype: List :class:`.Point` instances or ndarray
        """
        if not is_array_like(ulist) or not is_array_like(vlist):
            return self.eval(ulist, vlist, rtype, domain)

        if not is_local_domain(domain):
            ulist = [self.global_to_local_param('u', ui) for ui in ulist]
            vlist = [self.global_to_local_param('v', vi) for vi in vlist]
        pnts = bezier_surface_points(self._n, self._m, self._cpw, ulist, vlist)
        if is_array_type(rtype):
            return pnts
        else:
            return [Point(pi) for pi in pnts]
コード例 #3
0
ファイル: nurbs_surface.py プロジェクト: trelau/pyNURBS
    def refine_knots(self, x, d, inplace=False, domain='local'):
        """
        Refine the knot vector by inserting the elements of *x* in specified
        direction.

        :param array_like x: Knot vector to insert.
        :param str d: Direction to refine knots ('u' or 'v').
        :param bool inplace: Option to return new surface or modify
            existing surface.
        :param str domain: Option to use local (0 <= u, v <= 1) or global
            (a <= u, v <= b) domain ('local', 'l', 'global', 'g').

        :return: New surface after knot refinement.
        :rtype: :class:`.NurbsSurface`
        """
        if is_local_domain(domain):
            x = self.local_to_global_param(d, *x)
        if isinstance(x, (tuple, list)):
            x = array(x, dtype=float64)
        elif isinstance(x, (int, float)):
            x = array([x], dtype=float64)
        uk, vk, cpw = refine_knot_vect_surface(self._n, self._p, self._uk,
                                               self._m, self._q, self._vk,
                                               self._cpw, x, d)
        if inplace:
            self.set_cpw(cpw)
            self.set_knots(uk, vk)
            return True
        else:
            s = NurbsSurface()
            s.set_cpw(cpw)
            s.set_knots(uk, vk)
            return s
コード例 #4
0
ファイル: nurbs_surface.py プロジェクト: trelau/pyNURBS
    def move_seam(self, uv, d, inplace=False, domain='local'):
        """
        Move the seam of a closed surface to a new parameter value.

        :param float uv: New seam parameter.
        :param str d: Direction for seam movement (surface must be closed in
            that direction).
        :param bool inplace: Option to return new surface or modify inpalce.
        :param str domain: Option to use local (0 <= u, v <= 1) or global
            (a <= u, v <= b) domain ('local', 'l', 'global', 'g').

        :return: New surface or *True* if successful.
        :rtype: :class:`.NurbsSurface` or bool
        """
        if not self.is_closed(d):
            return False
        if is_local_domain(domain):
            uv = self.local_to_global_param(d, uv)
        uq, vq, qw = move_nurbs_surface_seam(self._n, self._p, self._uk,
                                             self._m, self._q, self._vk,
                                             self._cpw, uv, d)

        if inplace:
            return self.set_cpw(qw) and self.set_knots(uq, vq)

        s = NurbsSurface()
        s.set_cpw(qw)
        s.set_knots(uq, vq)
        s.set_deg(self._p, self._q)
        return s
コード例 #5
0
ファイル: nurbs_surface.py プロジェクト: trelau/pyNURBS
    def extract(self, u0=0., u1=1., v0=0., v1=1., domain='local'):
        """
        Extract NURBS surface bounded by parameters.

        :param float u0: Starting parameter in u-direction.
        :param float u1: Ending parameter in u-direction.
        :param float v0: Starting parameter in v-direction.
        :param float v1: Ending parameter in v-direction.
        :param str domain: Option to use local (0 <= u, v <= 1) or global
            (a <= u, v <= b) domain ('local', 'l', 'global', 'g').

        :return: Extracted NURBS surface.
        :rtype: :class:`.NurbsSurface`
        """
        if is_local_domain(domain):
            u0 = self.local_to_global_param('u', u0)
            u1 = self.local_to_global_param('u', u1)
            v0 = self.local_to_global_param('v', v0)
            v1 = self.local_to_global_param('v', v1)
        _, _, uq, vq, qw = extract_nurbs_surface(self._n, self._p, self._uk,
                                                 self._m, self._q, self._vk,
                                                 self._cpw, u0, u1, v0, v1)
        s = NurbsSurface()
        s.set_cpw(qw)
        s.set_knots(uq, vq)
        return s
コード例 #6
0
ファイル: nurbs_surface.py プロジェクト: trelau/pyNURBS
    def insert_knot(self, uv, d, r=1, inplace=False, domain='local'):
        """
        Insert knot in direction.

        :param float uv: Knot value to insert.
        :param str d: Direction to insert knot ('u1 or 'v').
        :param int r: Number of times to insert knot.
        :param bool inplace: Option to return new surface or modify
            existing surface.
        :param str domain: Option to use local (0 <= u, v <= 1) or global
            (a <= u, v <= b) domain ('local', 'l', 'global', 'g').

        :return: New surface after knot insertion.
        :rtype: :class:`.NurbsSurface`
        """
        if is_local_domain(domain):
            uv = self.local_to_global_param(d, uv)
        uk, vk, cpw = surface_knot_ins(self._n, self._p, self._uk,
                                       self._m, self._q, self._vk,
                                       self._cpw, d, uv, r)
        if inplace:
            self.set_cpw(cpw)
            self.set_knots(uk, vk)
            return True
        else:
            s = NurbsSurface()
            s.set_cpw(cpw)
            s.set_knots(uk, vk)
            return s
コード例 #7
0
ファイル: nurbs_curve.py プロジェクト: trelau/pyNURBS
    def insert_knot(self, u, r=1, inplace=False, domain='local'):
        """
        Insert knot.

        :param float u: Knot value to insert.
        :param int r: Number of times to insert knot (r + s <= p, where *s*
            is knot multiplicity).
        :param bool inplace: Option to return a new curve or modify the curve
            in place.
        :param str domain: Option to use local (0 <= u <= 1) or global
            (a <= u <= b) domain ('local', 'l', 'global', 'g').

        :return: New curve after knot insertion.
        :rtype: :class:`.NurbsCurve`
        """
        if is_local_domain(domain):
            u = self.local_to_global_param(u)
        uk, cpw = curve_knot_ins(self._n, self._p, self._uk, self._cpw, u, r)
        if inplace:
            self.set_cpw(cpw)
            self.set_knots(uk)
            return True
        else:
            c = NurbsCurve()
            c.set_cpw(cpw)
            c.set_knots(uk)
            c.set_deg(self._p)
            return c
コード例 #8
0
ファイル: nurbs_curve.py プロジェクト: trelau/pyNURBS
    def deriv(self, u, k, d=None, rtype='Vector', domain='local'):
        """
        Compute the *k* -th derivative at point *u*.

        :param float u: Parametric point.
        :param int k: Derivative to return (0 <= k <= d).
        :param int d: Highest derivative to compute. If *d* = *None*, then only
            the *k* th derivative will be computed.
        :param str rtype: Option to return a NumPy array or a Vector instance
            (rtype = 'Vector' or 'ndarray').
        :param str domain: Option to use local (0 <= u <= 1) or global
            (a <= u <= b) domain ('local', 'l', 'global', 'g').

        :return: Curve *k* -th derivative.
        :rtype: :class:`.Vector` or ndarray
        """
        if self._cp is None:
            return None
        if d is None:
            d = k
        if is_local_domain(domain):
            u = self.local_to_global_param(u)
        der = rat_curve_derivs(self._n, self._p, self._uk,
                               self._cpw, u, d)
        if is_array_type(rtype):
            return der[k]
        else:
            p0 = Point(der[0])
            return Vector(der[k], p0)
コード例 #9
0
ファイル: nurbs_surface.py プロジェクト: trelau/pyNURBS
    def eval(self, u, v, rtype='Point', domain='local'):
        """
        Evaluate surface at parametric points.

        :param float u: Parametric point in u-direction.
        :param float v: Parametric point in v-direction.
        :param str rtype: Option to return a NumPy array or Point instance
            (rtype = 'ndarray' or 'Point').
        :param str domain: Option to use local (0 <= u, v <= 1) or global
            (a <= u, v <= b) domain ('local', 'l', 'global', 'g').

        :return: Point on surface.
        :rtype: :class:`.Point` or ndarray
        """
        if is_array_like(u) and is_array_like(v):
            return self.eval_params(u, v, rtype, domain)

        if is_local_domain(domain):
            u = self.local_to_global_param('u', u)
            v = self.local_to_global_param('v', v)
        pnt = surface_point(self._n, self._p, self._uk,
                            self._m, self._q, self._vk,
                            self._cpw, u, v)
        if is_array_type(rtype):
            return pnt
        else:
            return Point(pnt)
コード例 #10
0
ファイル: nurbs_curve.py プロジェクト: trelau/pyNURBS
    def refine_knots(self, x, inplace=False, domain='local'):
        """
        Refine the knot vector by inserting the elements of *x*.

        :param array_like x: Knot vector to insert.
        :param bool inplace: Option to return new curve or modify
            existing curve.
        :param str domain: Option to use local (0 <= u <= 1) or global
            (a <= u <= b) domain ('local', 'l', 'global', 'g').

        :return: New curve after knot refinement.
        :rtype: :class:`.NurbsCurve`
        """
        if is_local_domain(domain):
            x = self.local_to_global_param(*x)
        if isinstance(x, (tuple, list, ndarray)):
            x = array(x, dtype=float64)
        elif isinstance(x, (int, float)):
            x = array([x], dtype=float64)
        uq, qw = refine_knot_vect_curve(self._n, self._p, self._uk,
                                        self._cpw, x)
        if inplace:
            self.set_cpw(qw)
            self.set_knots(uq)
            return True
        else:
            c = NurbsCurve()
            c.set_cpw(qw)
            c.set_knots(uq)
            c.set_deg(self._p)
            return c
コード例 #11
0
ファイル: bezier_surface.py プロジェクト: trelau/pyNURBS
    def deriv(self, u, v, k, l, rtype='Vector', domain='local'):
        """
        Compute the surface derivative.

        :param float u: Parametric point.
        :param float v: Parametric point.
        :param int k: Derivative to return in u-direction (0 <= k <= d).
        :param int l: Derivative to return in v-direction (0 <= l <= d).
        :param str rtype: Option to return a NumPy array or a Vector instance
            (rtype = 'Vector' or 'ndarray').
        :param str domain: Option to use local (0 <= u, v <= 1) or global
            (a <= u, v <= b) domain ('local', 'l', 'global', 'g').

        :return: Surface derivative.
        :rtype: :class:`.Vector` or ndarray
        """
        if self._cp is None:
            return None
        # Use NURBS rational curve derivative to compute Bezier derivative.
        # Convert to global since using a NURBS method.
        if is_local_domain(domain):
            u = self.local_to_global_param('u', u)
            v = self.local_to_global_param('v', v)
        d = k + l
        der = rat_surface_derivs(self._n, self._p, self._uk, self._m, self._q,
                                 self._vk, self._cpw, u, v, d)
        if is_array_type(rtype):
            return der[k, l]
        else:
            p0 = Point(der[0, 0])
            return Vector(der[k, l], p0)
コード例 #12
0
ファイル: nurbs_curve.py プロジェクト: trelau/pyNURBS
    def reverse_param(self, u, domain='local'):
        """
        Reverse the parameter.

        :param float u: Original parameter.
        :param str domain: Option to use local (0 <= u <= 1) or global
            (a <= u <= b) domain ('local', 'l', 'global', 'g').

        :return: Reversed parameter.
        :rtype: float
        """
        if is_local_domain(domain):
            u = self.local_to_global_param(u)
        u = -u + self._a + self._b
        if not is_local_domain(domain):
            return u
        return self.global_to_local_param(u)
コード例 #13
0
    def eval2d(self, u, rtype='Point', domain='local', tol=None, sref=None):
        """
        Evaluate the intersection curve in 2-D space for each surface.

        :param float u: Parametric point.
        :param str rtype: Option to return a NumPy array or Point2D instance
            (rtype = 'Point' or 'ndarray').
        :param str domain: Option to use local (0 <= u <= 1) or global
            (a <= u <= b) domain ('local', 'l', 'global', 'g').
        :param float tol: Tolerance for point refinement.
        :param surface_like sref: Option to provide one of the two surfaces
            used in the intersection curve. If present, the method will
            only return the 2-D parameters associated to that surface.

        :return: Point on curve. Will return *None* if *sref* is not in the
            intersection.
        :rtype: :class:`.Point2D` or ndarray
        """
        if is_local_domain(domain):
            u = self.local_to_global_param(u)

        # Evaluate 2-D curves.
        s1, s2 = self._s1, self._s2
        u1, v1 = self._crv2d_s1.eval(u, rtype='ndarray', domain='global')[:-1]
        u2, v2 = self._crv2d_s2.eval(u, rtype='ndarray', domain='global')[:-1]

        # Project 3-D point to surfaces to get initial parameters.
        # s1, s2 = self._s1, self._s2
        # p3d = self._crv3d.eval(u, domain='global')
        # u1, v1 = invert_point_on_surface(p3d, s1)
        # if self.is_spi:
        #     u2, v2 = invert_point_on_plane(p3d, s2)
        # else:
        #     u2, v2 = invert_point_on_surface(p3d, s2)

        # Refine parameters.
        if tol is None:
            tol = Settings.gtol / 100.
        if self.is_spi:
            u1, v1, u2, v2 = refine_spi_point(s1, s2, u1, v1, tol)[:-1]
        else:
            u1, v1, u2, v2 = refine_ssi_point(s1, s2, u1, v1, u2, v2, tol)[:-1]

        if is_array_type(rtype):
            if sref is s1:
                return array([u1, v1], dtype=float64)
            if sref is s2:
                return array([u2, v2], dtype=float64)
            return (array([u1, v1],
                          dtype=float64), array([u2, v2], dtype=float64))
        else:
            if sref is s1:
                return Point2D((u1, v1))
            if sref is s2:
                return Point2D((u2, v2))
            return Point2D((u1, v1)), Point2D((u2, v2))
コード例 #14
0
ファイル: nurbs_curve.py プロジェクト: trelau/pyNURBS
    def arc_length(self, u0=0., u1=1., domain='local'):
        """
        Estimate the arc length between curve parameters.

        :param float u0: Starting parameter.
        :param float u1: Ending parameter.
        :param str domain: Option to use local or global domain.

        :return: Arc length of curve between *u0* and *u1*.
        :rtype: float
        """
        if is_local_domain(domain):
            u0, u1 = self.local_to_global_param(u0, u1)
        return arc_length_nurbs(self.n, self.p, self.uk, self.cpw, u0, u1,
                                self.a, self.b)
コード例 #15
0
ファイル: bezier_curve.py プロジェクト: trelau/pyNURBS
    def extract(self, u0=0., u1=1., domain='local'):
        """
        Extract a curve.

        :param float u0: Starting parameter.
        :param float u1: Ending parameter.
        :param str domain: Option to use local (0 <= u <= 1) or global
            (a <= u <= b) domain ('local', 'l', 'global', 'g').

        :return: Curve between *u0* and *u1*.
        :rtype: :class:`.BezierCurve`
        """
        if not is_local_domain(domain):
            u0, u1 = self.global_to_local_param(u0, u1)
        qw, a, b = extract_bezier_curve(self._cpw, self._n, u0, u1, self._u0,
                                        self._u1)
        c = BezierCurve()
        c.set_cpw(qw)
        c.set_domain(a, b)
        return c
コード例 #16
0
def points_at_kinks(curve, angle=30., u0=0., u1=1., domain='local'):
    """
    Create points at kinks of a curve.
    """
    if is_local_domain(domain):
        u0, u1 = curve.local_to_global_param(u0, u1)

    # Get knots and multiplicities.
    nu, um, uq = curve.get_mult_and_knots()

    kinks = []
    # If p > 1, create a point wherever the knot multiplicity equals the
    # degree, excluding the endpoints.
    if curve.p > 1:
        for mult, ui in zip(um, uq)[1:-1]:
            if ui <= u0 or ui >= u1:
                continue
            if mult == curve.p:
                pi = curve.eval(ui, domain='global')
                kinks.append((ui, pi))
        return kinks

    # If p = 1, then use the angle criteria and the control points.
    angle_tol = abs(angle)
    n, cp = curve.n, curve.cp
    for i in range(1, n):
        ui = uq[i]
        if ui <= u0 or ui >= u1:
            continue
        # Get previous, current, and next points.
        p0 = cp[i - 1]
        pi = cp[i]
        p1 = cp[i + 1]
        # Calculate angle.
        v1 = pi - p0
        v2 = p1 - pi
        angle = angle_between_vecs(v1, v2)
        if angle > angle_tol:
            pi = curve.eval(ui, domain='global')
            kinks.append((ui, pi))
    return kinks
コード例 #17
0
ファイル: nurbs_curve.py プロジェクト: trelau/pyNURBS
    def extract(self, u0, u1, domain='local'):
        """
        Extract a curve.

        :param float u0: Starting parameter.
        :param float u1: Ending parameter.
        :param str domain: Option to use local (0 <= u <= 1) or global
            (a <= u <= b) domain ('local', 'l', 'global', 'g').

        :return: Curve between *u0* and *u1*.
        :rtype: :class:`.NurbsCurve`
        """
        if is_local_domain(domain):
            u0, u1 = self.local_to_global_param(u0, u1)
        uq, qw = extract_nurbs_curve(self._n, self._p, self._uk, self._cpw, u0,
                                     u1)
        c = NurbsCurve()
        c.set_cpw(qw)
        c.set_knots(uq)
        c.set_deg(self._p)
        return c
コード例 #18
0
ファイル: bezier_curve.py プロジェクト: trelau/pyNURBS
    def split(self, u=0.5, domain='local'):
        """
        Split the curve.

        :param float u: Parametric point to split curve at.
        :param str domain: Option to use local (0 <= u <= 1) or global
            (a <= u <= b) domain ('local', 'l', 'global', 'g').

        :return: Two new Bezier curves *(c1, c2)*.
        :rtype: tuple
        """
        if not is_local_domain(domain):
            u = self.global_to_local_param(u)
        qw1, a1, b1, qw2, a2, b2 = split_bezier_curve(self._cpw, self._n, u,
                                                      self._u0, self._u1)
        c1, c2 = BezierCurve(), BezierCurve()
        c1.set_cpw(qw1)
        c2.set_cpw(qw2)
        c1.set_domain(a1, b1)
        c2.set_domain(a2, b2)
        return c1, c2
コード例 #19
0
ファイル: nurbs_surface.py プロジェクト: trelau/pyNURBS
    def isocurve(self, u=None, v=None, domain='local'):
        """
        Extract iso-curve from NURBS surface.

        :param float u: Parameter *u* to extract curve at (in v-direction).
        :param float v: Parameter *v* to extract curve at (in u-direction).
        :param str domain: Option to use local (0 <= u, v <= 1) or global
            (a <= u, v <= b) domain ('local', 'l', 'global', 'g').

        :return: NURBS curve along parameter.
        :rtype: :class:`.NurbsCurve`
        """
        if is_local_domain(domain):
            u = self.local_to_global_param('u', u)
            v = self.local_to_global_param('v', v)
        uq, qw = extract_nurbs_isocurve(self._n, self._p, self._uk,
                                        self._m, self._q, self._vk,
                                        self._cpw, u, v)
        c = NurbsCurve()
        c.set_cpw(qw)
        c.set_knots(uq)
        return c
コード例 #20
0
    def eval(self, u, rtype='Point', domain='local', tol=None):
        """
        Evaluate curve at parametric point.

        :param float u: Parametric point.
        :param str rtype: Option to return a NumPy array or Point instance
            (rtype = 'Point' or 'ndarray').
        :param str domain: Option to use local (0 <= u <= 1) or global
            (a <= u <= b) domain ('local', 'l', 'global', 'g').
        :param float tol: Tolerance for point refinement.

        :return: Point on curve.
        :rtype: :class:`.Point` or ndarray
        """
        if is_local_domain(domain):
            u = self.local_to_global_param(u)
        uv1, uv2 = self.eval2d(u, rtype='ndarray', domain='global', tol=tol)
        p3d = self._s1.eval(uv1[0], uv1[1], rtype='ndarray', domain='global')
        if is_array_type(rtype):
            return p3d
        else:
            return Point(p3d)
コード例 #21
0
ファイル: nurbs_curve.py プロジェクト: trelau/pyNURBS
    def split(self, u=0.5, domain='local'):
        """
        Split the curve into two segments at *u*.

        :param float u: Parametric point to split curve at.
        :param str domain: Option to use local (0 <= u <= 1) or global
            (a <= u <= b) domain ('local', 'l', 'global', 'g').

        :return: Two new NURBS curves *(c1, c2)*.
        :rtype: tuple
        """
        if is_local_domain(domain):
            u = self.local_to_global_param(u)
        uk1, qw1, uk2, qw2 = split_nurbs_curve(self._n, self._p, self._uk,
                                               self._cpw, u)
        c1, c2 = NurbsCurve(), NurbsCurve()
        c1.set_cpw(qw1)
        c1.set_knots(uk1)
        c1.set_deg(self._p)
        c2.set_cpw(qw2)
        c2.set_knots(uk2)
        c2.set_deg(self._p)
        return c1, c2
コード例 #22
0
ファイル: nurbs_curve.py プロジェクト: trelau/pyNURBS
    def eval_params(self, ulist, rtype='Point', domain='local'):
        """
        Evaluate the curve at multiple parameters.

        :param array_like ulist: Curve parameters.
        :param str rtype: Option to return a NumPy array or list of Point
            instances (rtype = 'Point' or 'ndarray').
        :param str domain: Option to use local (0 <= u <= 1) or global
            (a <= u <= b) domain ('local', 'l', 'global', 'g').

        :return: Points at parameters.
        :rtype: List of :class:`.Point` instances or NumPy array
        """
        if not is_array_like(ulist):
            return self.eval(ulist, rtype, domain)

        if is_local_domain(domain):
            ulist = map(self.global_to_local_param, ulist)
        pnts = curve_points(self._n, self._p, self._uk, self._cpw, ulist)
        if is_array_type(rtype):
            return pnts
        else:
            return [Point(pi) for pi in pnts]
コード例 #23
0
ファイル: nurbs_curve.py プロジェクト: trelau/pyNURBS
    def eval(self, u, rtype='Point', domain='local'):
        """
        Evaluate curve at parametric point.

        :param float u: Parametric point.
        :param str rtype: Option to return a NumPy array or Point instance
            (rtype = 'Point' or 'ndarray').
        :param str domain: Option to use local (0 <= u <= 1) or global
            (a <= u <= b) domain ('local', 'l', 'global', 'g').

        :return: Point on curve.
        :rtype: :class:`.Point` or ndarray
        """
        if is_array_like(u):
            return self.eval_params(u, rtype, domain)

        if is_local_domain(domain):
            u = self.local_to_global_param(u)
        pnt = curve_point(self._n, self._p, self._uk, self._cpw, u)
        if is_array_type(rtype):
            return pnt
        else:
            return Point(pnt)
コード例 #24
0
ファイル: bezier_surface.py プロジェクト: trelau/pyNURBS
    def eval(self, u, v, rtype='Point', domain='local'):
        """
        Evaluate surface at parametric points.

        :param float u: Parametric point in u-direction.
        :param float v: Parametric point in v-direction.
        :param str rtype: Option to return a NumPy array or Point instance
            (rtype = 'Point' or 'ndarray').
        :param str domain: Option to use local (0 <= u, v <= 1) or global
            (a <= u, v <= b) domain ('local', 'l', 'global', 'g').

        :return: Point on surface.
        :rtype: :class:`.Point` or ndarray
        """
        if not is_local_domain(domain):
            u = self.global_to_local_param('u', u)
            v = self.global_to_local_param('v', v)
        pw = deCasteljau2(self._cpw, self._n, self._m, u, v)
        pnt = pw[:-1] / pw[-1]
        if is_array_type(rtype):
            return pnt
        else:
            return Point(pnt)
コード例 #25
0
ファイル: bezier_surface.py プロジェクト: trelau/pyNURBS
    def isocurve(self, u=None, v=None, domain='local'):
        """
        Extract iso-curve from Bezier surface.

        :param float u: Parameter *u* to extract curve at (in v-direction).
        :param float v: Parameter *v* to extract curve at (in u-direction).
        :param str domain: Option to use local (0 <= u, v <= 1) or global
            (a <= u, v <= b) domain ('local', 'l', 'global', 'g').

        :return: Bezier curve along parameter.
        :rtype: :class:`.BezierCurve`
        """
        if not is_local_domain(domain):
            u = self.global_to_local_param('u', u)
            v = self.global_to_local_param('v', v)
        qw = extract_bezier_isocurve(self._n, self._m, self._cpw, u, v)
        c = BezierCurve()
        c.set_cpw(qw)
        if u is not None:
            c.set_domain(self._v0, self._v1)
        if v is not None:
            c.set_domain(self._u0, self._u1)
        return c
コード例 #26
0
    def deriv(self, u, k=1, d=1, rtype='Vector', domain='local', tol=None):
        """
        Compute the derivative of the intersection curve. Only supports
        first derivates.

        :param float u: Parametric point.
        :param int k: Derivative to return (0 <= k <= 1).
        :param int d: Highest derivative to compute. Currently only supports
            first derivative.
        :param str rtype: Option to return a NumPy array or a Vector instance
            (rtype = 'Vector' or 'ndarray').
        :param str domain: Option to use local (0 <= u <= 1) or global
            (a <= u <= b) domain ('local', 'l', 'global', 'g').
        :param float tol: Tolerance for point refinement.

        :return: First derivative or intersection curve.
        :rtype: :class:`.Vector` or ndarray
        """
        if is_local_domain(domain):
            u = self.local_to_global_param(u)
        # Evaluate 2-D points.
        s1, s2 = self._s1, self._s2
        uv1, uv2 = self.eval2d(u, rtype='ndarray', domain='global', tol=tol)
        # Evaluate surface normals.
        vn1 = s1.norm(uv1[0], uv1[1], rtype='ndarray', domain='global')
        if self.is_spi:
            vn2 = s2.vn.ijk
        else:
            vn2 = s2.norm(uv2[0], uv2[1], rtype='ndarray', domain='global')
        # First derivative is cross product
        du = cross(vn1, vn2)
        if is_array_type(rtype):
            return du
        else:
            p0 = self.eval(u, domain='global')
            return Vector(du, p0)
コード例 #27
0
    def extract(self, u0, u1, domain='local'):
        """
        Extract a curve.

        :param float u0: Starting parameter.
        :param float u1: Ending parameter.
        :param str domain: Option to use local (0 <= u <= 1) or global
            (a <= u <= b) domain ('local', 'l', 'global', 'g').

        :return: Curve between *u0* and *u1*.
        :rtype: :class:`.ICurve`
        """
        if is_local_domain(domain):
            u0, u1 = self.local_to_global_param(u0, u1)
        if u0 > u1:
            u0, u1 = u1, u0

        # Evaluate points on intersection curve.
        p3d_0 = self.eval(u0, rtype='ndarray', domain='global')
        p3d_1 = self.eval(u1, rtype='ndarray', domain='global')
        uv0_s1_0, uv0_s2_0 = self.eval2d(u0, rtype='ndarray', domain='global')
        uv0_s1_1, uv0_s2_1 = self.eval2d(u1, rtype='ndarray', domain='global')
        # Extract curves
        crv3d = self._crv3d.extract(u0, u1, domain='global')
        crv2d_s1 = self._crv2d_s1.extract(u0, u1, domain='global')
        crv2d_s2 = self._crv2d_s2.extract(u0, u1, domain='global')
        # Force endpoints of curves to match original points by adjusting
        # first and last control points.
        crv3d.modify_cp(0, p3d_0)
        crv3d.modify_cp(-1, p3d_1)
        crv2d_s1.modify_cp(0, uv0_s1_0)
        crv2d_s1.modify_cp(-1, uv0_s1_1)
        crv2d_s2.modify_cp(0, uv0_s2_0)
        crv2d_s2.modify_cp(-1, uv0_s2_1)
        return ICurve(self._s1, self._s2, crv3d, crv2d_s1, crv2d_s2,
                      self._ftol)
コード例 #28
0
ファイル: bezier_surface.py プロジェクト: trelau/pyNURBS
    def split(self, u=None, v=None, domain='local'):
        """
        Split Bezier surface.

        :param float u: Location of split (in v-direction).
        :param float v: Location of split (in u-direction).
        :param str domain: Option to use local (0 <= u, v <= 1) or global
            (a <= u, v <= b) domain ('local', 'l', 'global', 'g').

        :return: Tuple of Bezier surfaces after splitting.
        :rtype: tuple

        .. note::
            If only one parameter is provided, then two surfaces are
            created and the length of the tuple is two (s1, s2). If both
            parameters are provided, four surfaces are created and the length
            of tuple is four (s1, s2, s3, s4).
        """
        if not is_local_domain(domain):
            u = self.global_to_local_param('u', u)
            v = self.global_to_local_param('v', v)
        if u is None or v is None:
            # Split in one direction only.
            qw1, qw2, ab1, ab2 = split_bezier_surface(self._cpw, self._n,
                                                      self._m, u, v, self._u0,
                                                      self._u1, self._v0,
                                                      self._v1)
            s1, s2 = BezierSurface(), BezierSurface()
            s1.set_cpw(qw1)
            s2.set_cpw(qw2)
            s1.set_domain(ab1[0, 0], ab1[0, 1], ab1[1, 0], ab1[1, 1])
            s2.set_domain(ab2[0, 0], ab2[0, 1], ab2[1, 0], ab2[1, 1])
            return s1, s2
        elif u is not None and v is not None:
            # Split in both directions, starting  at u (in v-direction).
            qw1, qw2, ab1, ab2 = split_bezier_surface(self._cpw, self._n,
                                                      self._m, u, None,
                                                      self._u0, self._u1,
                                                      self._v0, self._v1)
            # Split first surface at v (in u-direction).
            qw3, qw4, ab3, ab4 = split_bezier_surface(qw1, self._n, self._m,
                                                      None, v, ab1[0,
                                                                   0], ab1[0,
                                                                           1],
                                                      ab1[1, 0], ab1[1, 1])
            # Split second surface at v (in u-direction).
            qw5, qw6, ab5, ab6 = split_bezier_surface(qw2, self._n, self._m,
                                                      None, v, ab2[0,
                                                                   0], ab2[0,
                                                                           1],
                                                      ab2[1, 0], ab2[1, 1])
            # Create surfaces
            s3, s4, s5, s6 = (BezierSurface(), BezierSurface(),
                              BezierSurface(), BezierSurface())
            s3.set_cpw(qw3)
            s4.set_cpw(qw4)
            s5.set_cpw(qw5)
            s6.set_cpw(qw6)
            s3.set_domain(ab3[0, 0], ab3[0, 1], ab3[1, 0], ab3[1, 1])
            s4.set_domain(ab4[0, 0], ab4[0, 1], ab4[1, 0], ab4[1, 1])
            s5.set_domain(ab5[0, 0], ab5[0, 1], ab5[1, 0], ab5[1, 1])
            s6.set_domain(ab6[0, 0], ab6[0, 1], ab6[1, 0], ab6[1, 1])
            return s3, s4, s5, s6
コード例 #29
0
ファイル: nurbs_surface.py プロジェクト: trelau/pyNURBS
    def split(self, u=None, v=None, domain='local'):
        """
        Split NURBS surface.

        :param float u: Location of split (in v-direction).
        :param float v: Location of split (in u-direction).
        :param str domain: Option to use local (0 <= u, v <= 1) or global
            (a <= u, v <= b) domain ('local', 'l', 'global', 'g').

        :return: Tuple of NURBS surfaces after splitting.
        :rtype: tuple

        .. note::
            If only one parameter is provided, then two surfaces are
            created and the length of the tuple is two (s1, s2). If both
            parameters are provided, four surfaces are created and the length
            of tuple is four (s1, s2, s3, s4).
        """
        if is_local_domain(domain):
            u = self.local_to_global_param('u', u)
            v = self.local_to_global_param('v', v)
        if u is None or v is None:
            # Split in one direction only.
            uk1, vk1, qw1, uk2, vk2, qw2 = split_nurbs_surface(self._n,
                                                               self._p,
                                                               self._uk,
                                                               self._m,
                                                               self._q,
                                                               self._vk,
                                                               self._cpw, u, v)
            s1, s2 = NurbsSurface(), NurbsSurface()
            s1.set_cpw(qw1)
            s1.set_knots(uk1, vk1)
            s2.set_cpw(qw2)
            s2.set_knots(uk2, vk2)
            return s1, s2
        elif u is not None and v is not None:
            # Split in both directions, starting at u (in v-direction).
            uk1, vk1, qw1, uk2, vk2, qw2 = split_nurbs_surface(self._n,
                                                               self._p,
                                                               self._uk,
                                                               self._m,
                                                               self._q,
                                                               self._vk,
                                                               self._cpw, u,
                                                               None)
            # Split first surface at v (in u-direction).
            nm1, nm2 = qw1.shape[:-1], qw2.shape[:-1]
            n1, m1 = nm1[0] - 1, nm1[1] - 1
            uk3, vk3, qw3, uk4, vk4, qw4 = split_nurbs_surface(n1, self._p,
                                                               uk1, m1,
                                                               self._q, vk1,
                                                               qw1, None, v)
            # Split second surface at v (in u-direction).
            n2, m2 = nm2[0] - 1, nm2[1] - 1
            uk5, vk5, qw5, uk6, vk6, qw6 = split_nurbs_surface(n2, self._p,
                                                               uk2, m2,
                                                               self._q, vk2,
                                                               qw2, None, v)
            # Create surfaces.
            s3, s4, s5, s6 = (NurbsSurface(), NurbsSurface(),
                              NurbsSurface(), NurbsSurface())
            s3.set_cpw(qw3)
            s3.set_knots(uk3, vk3)
            s4.set_cpw(qw4)
            s4.set_knots(uk4, vk4)
            s5.set_cpw(qw5)
            s5.set_knots(uk5, vk5)
            s6.set_cpw(qw6)
            s6.set_knots(uk6, vk6)
            return s3, s4, s5, s6