Esempio n. 1
0
    def process(self):
        if not any(socket.is_linked for socket in self.outputs):
            return

        curve1_s = self.inputs['Curve1'].sv_get()
        curve2_s = self.inputs['Curve2'].sv_get()

        curve1_s = ensure_nesting_level(curve1_s, 2, data_types=(SvCurve, ))
        curve2_s = ensure_nesting_level(curve2_s, 2, data_types=(SvCurve, ))

        points_out = []
        t1_out = []
        t2_out = []

        for curve1s, curve2s in zip_long_repeat(curve1_s, curve2_s):
            new_points = []
            new_t1 = []
            new_t2 = []
            for curve1, curve2 in self.match(curve1s, curve2s):
                curve1 = SvNurbsCurve.to_nurbs(curve1)
                if curve1 is None:
                    raise Exception("Curve1 is not a NURBS")
                curve2 = SvNurbsCurve.to_nurbs(curve2)
                if curve2 is None:
                    raise Exception("Curve2 is not a NURBS")

                if self.implementation == 'SCIPY':
                    t1s, t2s, ps = self.process_native(curve1, curve2)
                else:
                    t1s, t2s, ps = self.process_freecad(curve1, curve2)

                if self.check_intersection:
                    if not ps:
                        raise Exception("Some curves do not intersect!")

                if self.single:
                    if len(ps) >= 1:
                        ps = ps[0]
                        t1s = t1s[0]
                        t2s = t2s[0]

                new_points.append(ps)
                new_t1.append(t1s)
                new_t2.append(t2s)

            if self.split:
                n = len(curve1s)
                new_points = split_by_count(new_points, n)
                new_t1 = split_by_count(new_t1, n)
                new_t1 = transpose_list(new_t1)
                new_t2 = split_by_count(new_t2, n)

            points_out.append(new_points)
            t1_out.append(new_t1)
            t2_out.append(new_t2)

        self.outputs['Intersections'].sv_set(points_out)
        self.outputs['T1'].sv_set(t1_out)
        self.outputs['T2'].sv_set(t2_out)
Esempio n. 2
0
    def process(self):
        if not any(socket.is_linked for socket in self.outputs):
            return

        u_curves_s = self.inputs['CurvesU'].sv_get()
        v_curves_s = self.inputs['CurvesV'].sv_get()
        intersections_s = self.inputs['Intersections'].sv_get()

        if self.explicit_t_values:
            t1_s = self.inputs['T1'].sv_get()
            t2_s = self.inputs['T2'].sv_get()
        else:
            t1_s = [[[]]]
            t2_s = [[[]]]

        u_curves_s = ensure_nesting_level(u_curves_s, 2, data_types=(SvCurve,))
        v_curves_s = ensure_nesting_level(v_curves_s, 2, data_types=(SvCurve,))
        t1_s = ensure_nesting_level(t1_s, 3)
        t2_s = ensure_nesting_level(t2_s, 3)
        intersections_s = ensure_nesting_level(intersections_s, 4)

        surface_out = []
        for u_curves, v_curves, t1s, t2s, intersections in zip_long_repeat(u_curves_s, v_curves_s, t1_s, t2_s, intersections_s):
            u_curves = [SvNurbsCurve.to_nurbs(c) for c in u_curves]
            if any(c is None for c in u_curves):
                raise Exception("Some of U curves are not NURBS!")
            v_curves = [SvNurbsCurve.to_nurbs(c) for c in v_curves]
            if any(c is None for c in v_curves):
                raise Exception("Some of V curves are not NURBS!")

            if self.explicit_t_values:
                if len(t1s) < len(u_curves):
                    t1s = repeat_last_for_length(t1s, len(u_curves))
                elif len(t1s) > len(u_curves):
                    raise Exception(f"Number of items in T1 input {len(t1s)} > number of U-curves {len(u_curves)}")

                if len(t1s[0]) != len(v_curves):
                    raise Exception(f"Length of items in T1 input {len(t1s[0])} != number of V-curves {len(v_curves)}")

                if len(t2s) < len(v_curves):
                    t2s = repeat_last_for_length(t2s, len(v_curves))
                elif len(t2s) > len(v_curves):
                    raise Exception(f"Number of items in T2 input {len(t2s)} > number of V-curves {len(v_curves)}")

                if len(t2s[0]) != len(u_curves):
                    raise Exception(f"Length of items in T2 input {len(t2s[0])} != number of U-curves {len(u_curves)}")

            if self.explicit_t_values:
                kwargs = {'u_knots': np.array(t1s), 'v_knots': np.array(t2s)}
            else:
                kwargs = dict()
            _, _, _, surface = gordon_surface(u_curves, v_curves, intersections, metric=self.metric, knotvector_accuracy = self.knotvector_accuracy, **kwargs)
            surface_out.append(surface)

        self.outputs['Surface'].sv_set(surface_out)
Esempio n. 3
0
    def process(self):
        if not any(socket.is_linked for socket in self.outputs):
            return

        curve_s = self.inputs['Curve'].sv_get()
        knot_s = self.inputs['Knot'].sv_get()
        count_s = self.inputs['Count'].sv_get()

        input_level = get_data_nesting_level(curve_s, data_types=(SvCurve, ))
        flat_output = input_level < 2
        curve_s = ensure_nesting_level(curve_s, 2, data_types=(SvCurve, ))
        knot_s = ensure_nesting_level(knot_s, 3)
        count_s = ensure_nesting_level(count_s, 3)

        curves_out = []
        for curves, knots_i, counts_i in zip_long_repeat(
                curve_s, knot_s, count_s):
            new_curves = []
            for curve, knots, counts in zip_long_repeat(
                    curves, knots_i, counts_i):
                curve = SvNurbsCurve.to_nurbs(curve)
                if curve is None:
                    raise Exception("One of curves is not NURBS")
                for knot, count in zip_long_repeat(knots, counts):
                    curve = curve.insert_knot(knot,
                                              count,
                                              if_possible=self.if_possible)
                new_curves.append(curve)
            if flat_output:
                curves_out.extend(new_curves)
            else:
                curves_out.append(new_curves)

        self.outputs['Curve'].sv_set(curves_out)
Esempio n. 4
0
    def deconstruct(self, curve):
        nurbs = SvNurbsCurve.to_nurbs(curve)
        if nurbs is None:
            nurbs = curve

        try:
            degree = nurbs.get_degree()
        except:
            degree = None

        if hasattr(nurbs, 'get_knotvector'):
            knots = nurbs.get_knotvector().tolist()
        else:
            knots = []

        try:
            points = nurbs.get_control_points().tolist()
        except Exception as e:
            points = []

        if hasattr(nurbs, 'get_weights'):
            weights = nurbs.get_weights().tolist()
        else:
            weights = []

        return degree, knots, points, weights
Esempio n. 5
0
    def process(self):
        if not any(socket.is_linked for socket in self.outputs):
            return

        curve_s = self.inputs['Curve'].sv_get()

        input_level = get_data_nesting_level(curve_s, data_types=(SvCurve,))
        flat_output = input_level < 2
        curve_s = ensure_nesting_level(curve_s, 2, data_types=(SvCurve,))

        tolerance = self.tolerance

        curves_out = []
        for curves in curve_s:
            new_curves = []
            for curve in curves:
                curve = SvNurbsCurve.to_nurbs(curve)
                if curve is None:
                    raise Exception("One of curves is not NURBS")
                curve = remove_excessive_knots(curve, tolerance=tolerance)
                new_curves.append(curve)
            if flat_output:
                curves_out.extend(new_curves)
            else:
                curves_out.append(new_curves)

        self.outputs['Curve'].sv_set(curves_out)
Esempio n. 6
0
 def to_nurbs(self, curves):
     result = []
     for i,c in enumerate(curves):
         nurbs = SvNurbsCurve.to_nurbs(c)
         if nurbs is None:
             raise Exception(f"Curve #{i} - {c} - can not be converted to NURBS!")
         result.append(nurbs)
     return result
Esempio n. 7
0
    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)
Esempio n. 8
0
    def cut(self, face_surface, sv_curves, point, vector):
        # face_surface : SvFreeCadNurbsSurface
        nurbs = [SvNurbsCurve.to_nurbs(curve) for curve in sv_curves]
        if any(c is None for c in nurbs):
            raise Exception("One of curves is not a NURBS!")
        fc_nurbs_curves = [SvFreeCadNurbsCurve.from_any_nurbs(c) for c in nurbs]
        fc_nurbs = [c.curve for c in fc_nurbs_curves]
        if self.projection_type in {'PARALLEL', 'PERSPECTIVE', 'ORTHO'}:
            try:
                fc_edges = [Part.Edge(c) for c in fc_nurbs]
            except Exception as e:
                raise Exception(f"Can't build edges from {fc_nurbs}: {e}")
        fc_face = Part.Face(face_surface.surface)

        if self.projection_type == 'PARALLEL':
            vector = Base.Vector(*vector)
            projections = [fc_face.makeParallelProjection(edge, vector) for edge in fc_edges]
            projections = [p.Edges for p in projections]
        elif self.projection_type == 'PERSPECTIVE':
            point = Base.Vector(*point)
            projections = [fc_face.makePerspectiveProjection(edge, point).Edges for edge in fc_edges]
        elif self.projection_type == 'ORTHO':
            projections = [fc_face.project(fc_edges).Edges]
        else: # UV
            uv_curves = [c.to_2d() for c in fc_nurbs_curves]
            fc_nurbs_2d = [c.curve for c in uv_curves]
            projections = [[c.toShape(face_surface.surface) for c in fc_nurbs_2d]]

        projections = sum(projections, [])
        if not projections:
            words = f"along {vector}" if self.projection_type == 'PARALLEL' else f"from {point}"
            raise Exception(f"Projection {words} of {sv_curves} onto {face_surface} is empty for some reason")
        try:
            wire = Part.Wire(projections)
        except Exception as e:
            ps = [SvFreeCadNurbsCurve(p.Curve) for p in projections]
            raise Exception(f"Can't make a valid Wire out of curves {sv_curves} projected onto {face_surface}:\n{e}\nProjections are: {ps}")

        cut_fc_face = Part.Face(face_surface.surface, wire)
        cut_face_surface = SvFreeCadNurbsSurface(face_surface.surface, face=cut_fc_face) 

        if self.projection_type != 'UV':
            uv_curves = []
            for edge in cut_fc_face.OuterWire.Edges:
                trim,m,M = cut_fc_face.curveOnSurface(edge)
                trim = SvFreeCadCurve(trim, (m,M), ndim=2)
                uv_curves.append(trim)

        projections = [SvSolidEdgeCurve(p) for p in projections]
        return uv_curves, projections, cut_face_surface
Esempio n. 9
0
        def _cast_nurbs(self, curve, center, direction, radius, coeff):
            curve = SvNurbsCurve.to_nurbs(curve)
            if curve is None:
                raise Exception("Provided curve is not a NURBS")
            if self.form == 'PLANE':
                target = PlaneEquation.from_normal_and_point(direction, center)
            elif self.form == 'SPHERE':
                target = SphereEquation(center, radius)
            elif self.form == 'CYLINDER':
                target = CylinderEquation.from_point_direction_radius(center, direction, radius)
            else:
                raise Exception("Unsupported target form")

            return cast_nurbs_curve(curve, target, coeff=coeff)
        def process(self):
            if not any(socket.is_linked for socket in self.outputs):
                return

            curves_s = self.inputs['Curve'].sv_get()
            point_s = self.inputs['Point'].sv_get()
            normal_s = self.inputs['Normal'].sv_get()
            curves_s = ensure_nesting_level(curves_s,
                                            2,
                                            data_types=(SvCurve, ))

            points_out = []
            t_out = []

            tolerance = 10**(-self.accuracy)

            for curves, points, normals in zip_long_repeat(
                    curves_s, point_s, normal_s):
                new_points = []
                new_ts = []
                for curve, point, normal in zip_long_repeat(
                        curves, points, normals):
                    method = EQUATION
                    if self.use_nurbs:
                        c = SvNurbsCurve.to_nurbs(curve)
                        if c is not None:
                            curve = c
                            method = NURBS

                    plane = PlaneEquation.from_normal_and_point(normal, point)
                    ps = intersect_curve_plane(curve,
                                               plane,
                                               method=method,
                                               init_samples=self.samples,
                                               tolerance=tolerance)
                    ts = [p[0] for p in ps]
                    points = [p[1].tolist() for p in ps]

                    if self.join:
                        new_points.extend(points)
                        new_ts.extend(ts)
                    else:
                        new_points.append(points)
                        new_ts.append(ts)

                points_out.append(new_points)
                t_out.append(new_ts)

            self.outputs['Point'].sv_set(points_out)
            self.outputs['T'].sv_set(t_out)
Esempio n. 11
0
    def process(self):
        if not any(socket.is_linked for socket in self.outputs):
            return

        curve_s = self.inputs['Curve'].sv_get()
        init_cuts_s = self.inputs['InitCuts'].sv_get()
        tolerance_s = self.inputs['Tolerance'].sv_get()

        curve_s = ensure_nesting_level(curve_s, 2, data_types=(SvCurve, ))
        init_cuts_s = ensure_nesting_level(init_cuts_s, 2)
        tolerance_s = ensure_nesting_level(tolerance_s, 2)

        need_verts = self.outputs['Vertices'].is_linked

        verts_out = []
        edges_out = []
        ts_out = []

        for params in zip_long_repeat(curve_s, init_cuts_s, tolerance_s):
            new_verts = []
            new_edges = []
            new_ts = []
            for curve, init_cuts, tolerance in zip_long_repeat(*params):
                curve = SvNurbsCurve.to_nurbs(curve)
                if curve is None:
                    raise Exception("Curve is not NURBS")
                ts = curve.calc_linear_segment_knots(splits=init_cuts,
                                                     tolerance=tolerance)
                new_ts.append(ts.tolist())
                if need_verts:
                    verts = curve.evaluate_array(ts)
                    new_verts.append(verts.tolist())
                n = len(ts)
                edges = [(i, i + 1) for i in range(n - 1)]
                new_edges.append(edges)

            if self.join:
                verts_out.extend(new_verts)
                edges_out.extend(new_edges)
                ts_out.extend(new_ts)
            else:
                verts_out.append(new_verts)
                edges_out.append(new_edges)
                ts_out.append(new_ts)

        self.outputs['Vertices'].sv_set(verts_out)
        self.outputs['Edges'].sv_set(edges_out)
        self.outputs['T'].sv_set(ts_out)
Esempio n. 12
0
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
Esempio n. 13
0
    def process(self):
        if not any(socket.is_linked for socket in self.outputs):
            return

        curves_s = self.inputs['Curves'].sv_get()
        degrees_s = self.inputs['DegreeV'].sv_get()

        curves_s = ensure_nesting_level(curves_s, 3, data_types=(SvCurve, ))
        degrees_s = ensure_nesting_level(degrees_s, 2)

        surface_out = []
        curves_out = []
        v_curves_out = []
        for curves_i, degrees in zip_long_repeat(curves_s, degrees_s):
            new_surfaces = []
            new_curves = []
            new_v_curves = []
            for curves, degree_v in zip_long_repeat(curves_i, degrees):
                curves = [SvNurbsCurve.to_nurbs(c) for c in curves]
                if any(c is None for c in curves):
                    raise Exception("Some of curves are not NURBS!")
                unified_curves, v_curves, new_surface = simple_loft(
                    curves,
                    degree_v=degree_v,
                    knots_u=self.u_knots_mode,
                    metric=self.metric,
                    implementation=self.nurbs_implementation)
                new_surfaces.append(new_surface)
                new_curves.extend(unified_curves)
                new_v_curves.extend(v_curves)
            surface_out.append(new_surfaces)
            curves_out.append(new_curves)
            v_curves_out.append(new_v_curves)

        self.outputs['Surface'].sv_set(surface_out)
        self.outputs['UnifiedCurves'].sv_set(curves_out)
        self.outputs['VCurves'].sv_set(v_curves_out)
Esempio n. 14
0
def coons_surface(curve1, curve2, curve3, curve4):
    curves = [curve1, curve2, curve3, curve4]
    nurbs_curves = [SvNurbsCurve.to_nurbs(c) for c in curves]
    if any(c is None for c in nurbs_curves):
        return SvCoonsSurface(*curves)
    try:
        nurbs_curves = [c.reparametrize(0, 1) for c in nurbs_curves]
        degrees = [c.get_degree() for c in nurbs_curves]
        implementation = nurbs_curves[0].get_nurbs_implementation()

        if degrees[0] > degrees[2]:
            nurbs_curves[2] = nurbs_curves[2].elevate_degree(delta=degrees[0] -
                                                             degrees[2])
        if degrees[2] > degrees[0]:
            nurbs_curves[0] = nurbs_curves[0].elevate_degree(delta=degrees[2] -
                                                             degrees[0])
        if degrees[1] > degrees[3]:
            nurbs_curves[3] = nurbs_curves[3].elevate_degree(delta=degrees[1] -
                                                             degrees[3])
        if degrees[3] > degrees[1]:
            nurbs_curves[1] = nurbs_curves[1].elevate_degree(delta=degrees[3] -
                                                             degrees[1])

        degree_u = nurbs_curves[0].get_degree()
        degree_v = nurbs_curves[1].get_degree()

        knotvectors = [c.get_knotvector() for c in nurbs_curves]
        if not sv_knotvector.equal(knotvectors[0], knotvectors[2]):
            nurbs_curves[0], nurbs_curves[2] = unify_two_curves(
                nurbs_curves[0], nurbs_curves[2])
        if not sv_knotvector.equal(knotvectors[1], knotvectors[3]):
            nurbs_curves[1], nurbs_curves[3] = unify_two_curves(
                nurbs_curves[1], nurbs_curves[3])

        nurbs_curves[0] = reverse_curve(nurbs_curves[0])
        nurbs_curves[3] = reverse_curve(nurbs_curves[3])

        ruled1 = nurbs_curves[0].make_ruled_surface(nurbs_curves[2], 0, 1)
        ruled2 = nurbs_curves[1].make_ruled_surface(nurbs_curves[3], 0,
                                                    1).swap_uv()
        ruled1 = ruled1.elevate_degree(SvNurbsSurface.V, target=degree_v)
        ruled2 = ruled2.elevate_degree(SvNurbsSurface.U, target=degree_u)

        diff_1to2 = sv_knotvector.difference(ruled1.get_knotvector_v(),
                                             ruled2.get_knotvector_v())
        diff_2to1 = sv_knotvector.difference(ruled2.get_knotvector_u(),
                                             ruled1.get_knotvector_u())

        for v, count in diff_1to2:
            #print(f"R1: insert V={v} {count} times")
            ruled1 = ruled1.insert_knot(SvNurbsSurface.V, v, count)
        for u, count in diff_2to1:
            #print(f"R2: insert U={u} {count} times")
            ruled2 = ruled2.insert_knot(SvNurbsSurface.U, u, count)
        #print(f"R1: {ruled1.get_control_points().shape}, R2: {ruled2.get_control_points().shape}")

        linear_kv = sv_knotvector.generate(1, 2)

        c1_t_min, c1_t_max = nurbs_curves[0].get_u_bounds()
        c3_t_min, c3_t_max = nurbs_curves[2].get_u_bounds()

        pt1 = nurbs_curves[0].evaluate(c1_t_min)
        pt2 = nurbs_curves[0].evaluate(c1_t_max)
        pt3 = nurbs_curves[2].evaluate(c3_t_min)
        pt4 = nurbs_curves[2].evaluate(c3_t_max)

        w1 = nurbs_curves[0].get_weights()[0]
        w2 = nurbs_curves[0].get_weights()[-1]
        w3 = nurbs_curves[2].get_weights()[0]
        w4 = nurbs_curves[2].get_weights()[-1]

        linear_pts = np.array([[pt1, pt3], [pt2, pt4]])
        linear_weights = np.array([[w1, w3], [w2, w4]])
        #linear_weights = np.array([[1,1], [1,1]])
        bilinear = SvNurbsSurface.build(implementation, 1, 1, linear_kv,
                                        linear_kv, linear_pts, linear_weights)

        bilinear = bilinear.elevate_degree(SvNurbsSurface.U, target=degree_u)
        bilinear = bilinear.elevate_degree(SvNurbsSurface.V, target=degree_v)

        knotvector_u = ruled1.get_knotvector_u()
        knotvector_v = ruled2.get_knotvector_v()
        for u, count in sv_knotvector.get_internal_knots(
                knotvector_u, output_multiplicity=True):
            #print(f"B: insert U={u} {count} times")
            bilinear = bilinear.insert_knot(SvNurbsSurface.U, u, count)
        for v, count in sv_knotvector.get_internal_knots(
                knotvector_v, output_multiplicity=True):
            #print(f"B: insert V={v} {count} times")
            bilinear = bilinear.insert_knot(SvNurbsSurface.V, v, count)

        control_points = ruled1.get_control_points(
        ) + ruled2.get_control_points() - bilinear.get_control_points()
        weights = ruled1.get_weights() + ruled2.get_weights(
        ) - bilinear.get_weights()
        result = SvNurbsSurface.build(implementation, degree_u, degree_v,
                                      knotvector_u, knotvector_v,
                                      control_points, weights)
        return result
    except UnsupportedCurveTypeException as e:
        info("Can't create a native Coons surface from curves %s: %s", curves,
             e)
        return SvCoonsSurface(*curves)
Esempio n. 15
0
def coons_surface(curve1, curve2, curve3, curve4, use_nurbs=NURBS_IF_POSSIBLE):
    curves = [curve1, curve2, curve3, curve4]
    nurbs_curves = [SvNurbsCurve.to_nurbs(c) for c in curves]
    if use_nurbs == GENERIC:
        return SvCoonsSurface(*curves)
    if any(c is None for c in nurbs_curves):
        if use_nurbs == NURBS_ONLY:
            raise UnsupportedCurveTypeException("Some of curves are not NURBS")
        else:
            return SvCoonsSurface(*curves)
    try:
        nurbs_curves = [c.reparametrize(0, 1) for c in nurbs_curves]
        degrees = [c.get_degree() for c in nurbs_curves]
        implementation = nurbs_curves[0].get_nurbs_implementation()

        nurbs_curves[0], nurbs_curves[2] = unify_curves(
            [nurbs_curves[0], nurbs_curves[2]])
        nurbs_curves[1], nurbs_curves[3] = unify_curves(
            [nurbs_curves[1], nurbs_curves[3]])

        degree_u = nurbs_curves[0].get_degree()
        degree_v = nurbs_curves[1].get_degree()

        nurbs_curves[0] = reverse_curve(nurbs_curves[0])
        nurbs_curves[3] = reverse_curve(nurbs_curves[3])

        ruled1 = nurbs_curves[0].make_ruled_surface(nurbs_curves[2], 0, 1)
        ruled2 = nurbs_curves[1].make_ruled_surface(nurbs_curves[3], 0,
                                                    1).swap_uv()

        linear_kv = sv_knotvector.generate(1, 2)

        c1_t_min, c1_t_max = nurbs_curves[0].get_u_bounds()
        c3_t_min, c3_t_max = nurbs_curves[2].get_u_bounds()

        pt1 = nurbs_curves[0].evaluate(c1_t_min)
        pt2 = nurbs_curves[0].evaluate(c1_t_max)
        pt3 = nurbs_curves[2].evaluate(c3_t_min)
        pt4 = nurbs_curves[2].evaluate(c3_t_max)

        w1 = nurbs_curves[0].get_weights()[0]
        w2 = nurbs_curves[0].get_weights()[-1]
        w3 = nurbs_curves[2].get_weights()[0]
        w4 = nurbs_curves[2].get_weights()[-1]

        linear_pts = np.array([[pt1, pt3], [pt2, pt4]])
        linear_weights = np.array([[w1, w3], [w2, w4]])
        #linear_weights = np.array([[1,1], [1,1]])
        bilinear = SvNurbsSurface.build(implementation, 1, 1, linear_kv,
                                        linear_kv, linear_pts, linear_weights)

        ruled1, ruled2, bilinear = unify_nurbs_surfaces(
            [ruled1, ruled2, bilinear])
        knotvector_u = ruled1.get_knotvector_u()
        knotvector_v = ruled1.get_knotvector_v()

        control_points = ruled1.get_control_points(
        ) + ruled2.get_control_points() - bilinear.get_control_points()
        weights = ruled1.get_weights() + ruled2.get_weights(
        ) - bilinear.get_weights()
        result = SvNurbsSurface.build(implementation, degree_u, degree_v,
                                      knotvector_u, knotvector_v,
                                      control_points, weights)
        return result
    except UnsupportedCurveTypeException as e:
        if use_nurbs == NURBS_ONLY:
            raise
        else:
            info("Can't create a native Coons surface from curves %s: %s",
                 curves, e)
            return SvCoonsSurface(*curves)
Esempio n. 16
0
    def process(self):
        if not any(socket.is_linked for socket in self.outputs):
            return

        path1_s = self.inputs['Path1'].sv_get()
        path2_s = self.inputs['Path2'].sv_get()
        profile_s = self.inputs['Profile'].sv_get()
        if self.explicit_v:
            v1_s = self.inputs['V1'].sv_get()
            v1_s = ensure_nesting_level(v1_s, 3)
            v2_s = self.inputs['V2'].sv_get()
            v2_s = ensure_nesting_level(v2_s, 3)
        else:
            v1_s = [[[]]]
            v2_s = [[[]]]
        profiles_count_s = self.inputs['VSections'].sv_get()
        degree_v_s = self.inputs['DegreeV'].sv_get()

        path1_s = ensure_nesting_level(path1_s, 2, data_types=(SvCurve, ))
        path2_s = ensure_nesting_level(path2_s, 2, data_types=(SvCurve, ))
        profile_s = ensure_nesting_level(profile_s, 3, data_types=(SvCurve, ))
        profiles_count_s = ensure_nesting_level(profiles_count_s, 2)
        degree_v_s = ensure_nesting_level(degree_v_s, 2)

        surfaces_out = []
        curves_out = []
        v_curves_out = []
        for params in zip_long_repeat(path1_s, path2_s, profile_s, v1_s, v2_s,
                                      profiles_count_s, degree_v_s):
            new_surfaces = []
            new_curves = []
            new_v_curves = []
            new_profiles = []
            for path1, path2, profiles, vs1, vs2, profiles_count, degree_v in zip_long_repeat(
                    *params):
                path1 = SvNurbsCurve.to_nurbs(path1)
                if path1 is None:
                    raise Exception("Path #1 is not a NURBS curve!")
                path2 = SvNurbsCurve.to_nurbs(path2)
                if path2 is None:
                    raise Exception("Path #2 is not a NURBS curve!")
                profiles = [
                    SvNurbsCurve.to_nurbs(profile) for profile in profiles
                ]
                if any(p is None for p in profiles):
                    raise Exception("Some of profiles are not NURBS curves!")
                if self.explicit_v:
                    ts1 = np.array(vs1)
                    ts2 = np.array(vs2)
                else:
                    ts1 = None
                    ts2 = None
                _, unified_curves, v_curves, surface = nurbs_birail(
                    path1,
                    path2,
                    profiles,
                    ts1=ts1,
                    ts2=ts2,
                    min_profiles=profiles_count,
                    knots_u=self.u_knots_mode,
                    degree_v=degree_v,
                    metric=self.metric,
                    scale_uniform=self.scale_uniform,
                    implementation=self.nurbs_implementation)
                new_surfaces.append(surface)
                new_curves.extend(unified_curves)
                new_v_curves.extend(v_curves)
            surfaces_out.append(new_surfaces)
            curves_out.append(new_curves)
            v_curves_out.append(new_v_curves)

        self.outputs['Surface'].sv_set(surfaces_out)
        self.outputs['AllProfiles'].sv_set(curves_out)
        self.outputs['VCurves'].sv_set(v_curves_out)
Esempio n. 17
0
def intersect_curve_surface(curve,
                            surface,
                            init_samples=10,
                            raycast_samples=10,
                            tolerance=1e-3,
                            maxiter=50,
                            raycast_method='hybr',
                            support_nurbs=False):
    """
    Intersect a curve with a surface.
    dependencies: scipy
    """
    u_min, u_max = curve.get_u_bounds()
    is_nurbs = False
    c = SvNurbsCurve.to_nurbs(curve)
    if c is not None:
        curve = c
        is_nurbs = True

    raycaster = SurfaceRaycaster(surface)
    raycaster.init_bvh(raycast_samples)

    def do_raycast(point, tangent, sign=1):
        good_sign = sign
        raycast = raycaster.raycast([point], [sign * tangent],
                                    method=raycast_method,
                                    on_init_fail=RETURN_NONE)
        if raycast is None:
            good_sign = -sign
            raycast = raycaster.raycast([point], [-sign * tangent],
                                        method=raycast_method,
                                        on_init_fail=RETURN_NONE)
        return good_sign, raycast

    good_ranges = []
    u_range = np.linspace(u_min, u_max, num=init_samples)
    points = curve.evaluate_array(u_range)
    tangents = curve.tangent_array(u_range)
    for u1, u2, p1, p2, tangent1, tangent2 in zip(u_range, u_range[1:], points,
                                                  points[1:], tangents,
                                                  tangents[1:]):
        raycast = raycaster.raycast([p1, p2], [tangent1, -tangent2],
                                    precise=False,
                                    calc_points=False,
                                    on_init_fail=RETURN_NONE)
        if raycast is None:
            continue
        good_ranges.append((u1, u2, raycast.points[0], raycast.points[1]))

    def to_curve(point, curve, u1, u2, raycast=None):
        if support_nurbs and is_nurbs and raycast is not None:
            segment = curve.cut_segment(u1, u2)
            surface_u, surface_v = raycast.us[0], raycast.vs[0]
            point_on_surface = raycast.points[0]
            surface_normal = surface.normal(surface_u, surface_v)
            plane = PlaneEquation.from_normal_and_point(
                surface_normal, point_on_surface)
            r = intersect_curve_plane_nurbs(segment,
                                            plane,
                                            init_samples=2,
                                            tolerance=tolerance,
                                            maxiter=maxiter)
            if not r:
                return None
            else:
                return r[0]
        else:
            ortho = ortho_project_curve(point,
                                        curve,
                                        subdomain=(u1, u2),
                                        init_samples=2,
                                        on_fail=RETURN_NONE)
            if ortho is None:
                return None
            else:
                return ortho.nearest_u, ortho.nearest

    result = []
    for u1, u2, init_p1, init_p2 in good_ranges:

        tangent = curve.tangent(u1)
        point = curve.evaluate(u1)

        i = 0
        sign = 1
        prev_prev_point = None
        prev_point = init_p1
        u_root = None
        point_found = False
        raycast = None
        while True:
            i += 1
            if i > maxiter:
                raise Exception(
                    "Maximum number of iterations is exceeded; last step {} - {} = {}"
                    .format(prev_prev_point, point, step))

            on_curve = to_curve(prev_point, curve, u1, u2, raycast=raycast)
            if on_curve is None:
                break
            u_root, point = on_curve
            if u_root < u1 or u_root > u2:
                break
            step = np.linalg.norm(point - prev_point)
            if step < tolerance and i > 1:
                debug("After ortho: Point {}, prev {}, iter {}".format(
                    point, prev_point, i))
                point_found = True
                break

            prev_point = point
            tangent = curve.tangent(u_root)
            sign, raycast = do_raycast(point, tangent, sign)
            if raycast is None:
                raise Exception(
                    "Iteration #{}: Can't do a raycast with point {}, direction {} onto surface {}"
                    .format(i, point, tangent, surface))
            point = raycast.points[0]
            step = np.linalg.norm(point - prev_point)
            prev_prev_point = prev_point
            prev_point = point

        if point_found:
            result.append((u_root, point))

    return result
Esempio n. 18
0
    def process(self):
        if not any(socket.is_linked for socket in self.outputs):
            return

        path_s = self.inputs['Path'].sv_get()
        profile_s = self.inputs['Profile'].sv_get()
        if self.explicit_v:
            v_s = self.inputs['V'].sv_get()
            v_s = ensure_nesting_level(v_s, 3)
        else:
            v_s = [[[]]]
        profiles_count_s = self.inputs['VSections'].sv_get()
        resolution_s = self.inputs['Resolution'].sv_get()
        normal_s = self.inputs['Normal'].sv_get()

        path_s = ensure_nesting_level(path_s, 2, data_types=(SvCurve,))
        profile_s = ensure_nesting_level(profile_s, 3, data_types=(SvCurve,))
        resolution_s = ensure_nesting_level(resolution_s, 2)
        normal_s = ensure_nesting_level(normal_s, 3)
        profiles_count_s = ensure_nesting_level(profiles_count_s, 2)

        surfaces_out = []
        curves_out = []
        v_curves_out = []
        for params in zip_long_repeat(path_s, profile_s, v_s, profiles_count_s, resolution_s, normal_s):
            new_surfaces = []
            new_curves = []
            new_v_curves = []
            new_profiles = []
            for path, profiles, vs, profiles_count, resolution, normal in zip_long_repeat(*params):
                path = SvNurbsCurve.to_nurbs(path)
                if path is None:
                    raise Exception("Path is not a NURBS curve!")
                profiles = [SvNurbsCurve.to_nurbs(profile) for profile in profiles]
                if any(p is None for p in profiles):
                    raise Exception("Some of profiles are not NURBS curves!")
                if self.explicit_v:
                    ts = np.array(vs)
                else:
                    ts = None
                _, unified_curves, v_curves, surface = nurbs_sweep(path, profiles,
                                    ts = ts,
                                    min_profiles = profiles_count,
                                    algorithm = self.algorithm,
                                    knots_u = self.u_knots_mode,
                                    metric = self.metric,
                                    implementation = self.nurbs_implementation,
                                    resolution = resolution,
                                    normal = np.array(normal))
                new_surfaces.append(surface)
                new_curves.extend(unified_curves)
                new_v_curves.extend(v_curves)
            surfaces_out.append(new_surfaces)
            curves_out.append(new_curves)
            v_curves_out.append(new_v_curves)

        self.outputs['Surface'].sv_set(surfaces_out)
        if 'AllProfiles' in self.outputs:
            self.outputs['AllProfiles'].sv_set(curves_out)
        if 'VCurves' in self.outputs:
            self.outputs['VCurves'].sv_set(v_curves_out)
Esempio n. 19
0
    def process(self):
        if not any(socket.is_linked for socket in self.outputs):
            return

        path_s = self.inputs['Path'].sv_get()
        profile_s = self.inputs['Profile'].sv_get()
        if self.inputs['Taper'].is_linked:
            scale_base = 'TAPER'
            taper_s = self.inputs['Taper'].sv_get()
            taper_s = ensure_nesting_level(taper_s, 2, data_types=(SvCurve, ))
        else:
            scale_base = 'PROFILE'
            taper_s = [[None]]

        resolution_s = self.inputs['Resolution'].sv_get()
        taper_samples_s = self.inputs['ProfileCopies'].sv_get()
        taper_refine_s = self.inputs['TaperRefine'].sv_get()
        profile_samples_s = self.inputs['TaperCopies'].sv_get()

        input_level = get_data_nesting_level(path_s, data_types=(SvCurve, ))

        path_s = ensure_nesting_level(path_s, 2, data_types=(SvCurve, ))
        profile_s = ensure_nesting_level(profile_s, 2, data_types=(SvCurve, ))

        orient_axis = self._get_orient_axis_idx()

        surface_out = []
        cap_start_out = []
        cap_end_out = []
        for params in zip_long_repeat(path_s, profile_s, taper_s, resolution_s,
                                      taper_samples_s, taper_refine_s,
                                      profile_samples_s):
            new_surfaces = []
            new_cap_start = []
            new_cap_end = []
            for path, profile, taper, resolution, taper_samples, taper_refine, profile_samples in zip_long_repeat(
                    *params):
                if taper is None:
                    taper = self._make_unit_taper(path, profile)
                if self.curve_mode == 'GENERIC':
                    surface = generic_bevel_curve(
                        path,
                        profile,
                        taper,
                        algorithm=self.algorithm,
                        path_axis=orient_axis,
                        path_length_resolution=resolution,
                        up_axis=self.up_axis,
                        scale_base=scale_base)
                else:
                    path = SvNurbsCurve.to_nurbs(path)
                    profile = SvNurbsCurve.to_nurbs(profile)
                    taper = SvNurbsCurve.to_nurbs(taper)
                    if path is None:
                        raise Exception("One of paths is not a NURBS curve")
                    if profile is None:
                        raise Exception("One of profiles is not a NURBS curve")
                    if taper is None:
                        raise Exception("One of tapers is not a NURBS curve")

                    surface = nurbs_bevel_curve(
                        path,
                        profile,
                        taper,
                        algorithm=self.algorithm,
                        path_axis='XYZ'.index(self.orient_axis),
                        path_length_resolution=resolution,
                        up_axis=self.up_axis,
                        precision_method=self.precision_method,
                        taper_samples=taper_samples,
                        taper_refine=taper_refine,
                        profile_samples=profile_samples)

                v_min, v_max = surface.get_v_min(), surface.get_v_max()
                cap_start = SvIsoUvCurve.take(surface, 'V', v_min)
                cap_end = SvIsoUvCurve.take(surface, 'V', v_max)

                new_surfaces.append(surface)
                new_cap_start.append(cap_start)
                new_cap_end.append(cap_end)

            if input_level < 2:
                surface_out.extend(new_surfaces)
                cap_start_out.extend(new_cap_start)
                cap_end_out.extend(new_cap_end)
            else:
                surface_out.append(new_surfaces)
                cap_start_out.append(new_cap_start)
                cap_end_out.append(new_cap_end)

        self.outputs['Surface'].sv_set(surface_out)
        if 'CapStart' in self.outputs:
            self.outputs['CapStart'].sv_set(cap_start_out)
        if 'CapEnd' in self.outputs:
            self.outputs['CapEnd'].sv_set(cap_end_out)
Esempio n. 20
0
 def check_nurbs(*curves):
     return [SvNurbsCurve.to_nurbs(c) for c in curves]