def make_section(self, apex, cone_dir, alpha, cone_gen, count,
                     plane_center, plane_dir, maxd):
        apex = Vector(apex)
        cone_dir = Vector(cone_dir)
        plane_dir = Vector(plane_dir)
        cone_dir2 = cone_dir.orthogonal()

        if self.cone_mode == 'ANGLE':
            cone_vector = rotate_vector_around_vector(cone_dir, cone_dir2,
                                                      alpha)
        else:
            cone_vector = Vector(cone_gen)
        theta = 2 * pi / count
        angle = 0

        plane = PlaneEquation.from_normal_and_point(plane_dir, plane_center)
        cone_ort_plane = PlaneEquation.from_normal_and_point(cone_dir, apex)

        def get_branch(v):
            return cone_ort_plane.side_of_point(v) > 0

        if plane.side_of_point(apex) == 0 or (
                plane_dir.cross(cone_dir)).length < 1e-10:

            def get_side(v):
                return True
        else:
            apex_projection = plane.projection_of_point(apex)
            apex_ort = apex_projection - apex
            cone_sagital_plane = PlaneEquation.from_point_and_two_vectors(
                apex, apex_ort, cone_dir)

            def get_side(v):
                return cone_sagital_plane.side_of_point(v) > 0

        vertices = []
        branch_mask = []
        side_mask = []
        breaks = []
        i = 0
        while angle < 2 * pi:
            cone_line = LineEquation.from_direction_and_point(
                cone_vector, apex)
            vertex = plane.intersect_with_line(cone_line, min_det=1e-10)
            if vertex is not None and (vertex - apex).length <= maxd:
                vertices.append(tuple(vertex))
                branch = get_branch(vertex)
                side = get_side(vertex)
                branch_mask.append(branch)
                side_mask.append(side)
                i += 1
            else:
                breaks.append(i)

            cone_vector = rotate_vector_around_vector(cone_vector, cone_dir,
                                                      theta)
            angle += theta

        return SectionData(vertices, branch_mask, side_mask, get_branch,
                           get_side, breaks)
Exemplo n.º 2
0
        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 = []

            for curves, points, normals in zip_long_repeat(
                    curves_s, point_s, normal_s):
                new_points = []
                for curve, point, normal in zip_long_repeat(
                        curves, points, normals):
                    plane = PlaneEquation.from_normal_and_point(normal, point)
                    ps = intersect_curve_plane(curve,
                                               plane,
                                               init_samples=self.samples,
                                               ortho_samples=self.samples)
                    new_points.extend(ps)

                points_out.append(new_points)

            self.outputs['Point'].sv_set(points_out)
Exemplo n.º 3
0
 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
Exemplo n.º 4
0
    def _pre_calc(self):
        curve = self.curve
        t_min, t_max = curve.get_u_bounds()
        ts = np.linspace(t_min, t_max, num=self.resolution)

        points = curve.evaluate_array(ts)
        tangents, normals, binormals = curve.tangent_normal_binormal_array(ts)
        tangents /= np.linalg.norm(tangents, axis=1, keepdims=True)

        normal = normals[0]
        if np.linalg.norm(normal) > 1e-4:
            binormal = binormals[0]
            binormal /= np.linalg.norm(binormal)
        else:
            tangent = tangents[0]
            normal = Vector(tangent).orthogonal()
            normal = np.array(normal)
            binormal = np.cross(tangent, normal)
            binormal /= np.linalg.norm(binormal)

        out_normals = [normal]
        out_binormals = [binormal]

        for point, tangent in zip(points[1:], tangents[1:]):
            plane = PlaneEquation.from_normal_and_point(Vector(tangent), Vector(point))
            normal = plane.projection_of_vector(Vector(point), Vector(point + normal))
            normal = np.array(normal.normalized())
            binormal = np.cross(tangent, normal)
            binormal /= np.linalg.norm(binormal)
            out_normals.append(normal)
            out_binormals.append(binormal)

        self.quats = self._make_quats(points, tangents, np.array(out_normals), np.array(out_binormals))
        self.tknots = ts
Exemplo n.º 5
0
 def __init__(self, curve, point, normal, coefficient):
     self.curve = curve
     self.point = point
     self.normal = normal
     self.coefficient = coefficient
     self.plane = PlaneEquation.from_normal_and_point(normal, point)
     self.tangent_delta = 0.001
     self.__description__ = "{} casted to Plane".format(curve)
Exemplo n.º 6
0
    def _faces_by_plane(self, topo, center, direction, radius):
        plane = PlaneEquation.from_normal_and_point(direction, center)

        def condition(points):
            distances = plane.distance_to_points(points)
            return distances < radius

        return topo.get_faces_by_location_mask(condition, self.include_partial)
Exemplo n.º 7
0
 def get_ridges_per_site(voronoi):
     result = defaultdict(list)
     for ridge_idx in range(len(voronoi.ridge_points)):
         site1_idx, site2_idx = tuple(voronoi.ridge_points[ridge_idx])
         site1 = voronoi.points[site1_idx]
         site2 = voronoi.points[site2_idx]
         middle = (site1 + site2) * 0.5
         normal = site2 - site1
         plane = PlaneEquation.from_normal_and_point(normal, middle)
         result[site1_idx].append(plane)
         result[site2_idx].append(plane)
     return result
Exemplo n.º 8
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)
Exemplo n.º 10
0
        def process(self):
            if not any(socket.is_linked for socket in self.outputs):
                return

            surfaces_s = self.inputs['Surface'].sv_get()
            point_s = self.inputs['Point'].sv_get()
            normal_s = self.inputs['Normal'].sv_get()
            samples_u_s = self.inputs['SamplesU'].sv_get()
            samples_v_s = self.inputs['SamplesV'].sv_get()

            surfaces_s = ensure_nesting_level(surfaces_s,
                                              2,
                                              data_types=(SvSurface, ))

            need_points = self.outputs['Points'].is_linked

            uv_out = []
            points_out = []
            for surfaces, points, normals, samples_u_i, samples_v_i in zip_long_repeat(
                    surfaces_s, point_s, normal_s, samples_u_s, samples_v_s):
                uv_new = []
                points_new = []
                for surface, point, normal, samples_u, samples_v in zip_long_repeat(
                        surfaces, points, normals, samples_u_i, samples_v_i):
                    plane = PlaneEquation.from_normal_and_point(normal, point)
                    if self.algorithm == 'skimage':
                        uv_new, points_new = intersect_surface_plane_msquares(
                            surface,
                            plane,
                            need_points=need_points,
                            samples_u=samples_u,
                            samples_v=samples_v)
                    else:
                        points_new = intersect_surface_plane_uv(
                            surface,
                            plane,
                            samples_u=samples_u,
                            samples_v=samples_v,
                            init_samples=self.init_samples,
                            ortho_samples=self.init_samples)
                        points_new = [points_new]

                uv_out.extend(uv_new)
                points_out.extend(points_new)

            self.outputs['Points'].sv_set(points_out)
            self.outputs['UVPoints'].sv_set(uv_out)
Exemplo n.º 11
0
    def cut_cell(verts, faces, planes, site):
        src_mesh = bmesh_from_pydata(verts, [], faces, normal_update=True)
        n_cuts = 0
        for plane in planes:
            if len(src_mesh.verts) == 0:
                break
            geom_in = src_mesh.verts[:] + src_mesh.edges[:] + src_mesh.faces[:]

            plane_co = plane.projection_of_point(site)
            plane_no = plane.normal.normalized()
            if plane.side_of_point(site) > 0:
                plane_no = -plane_no

            plane_co = plane_co - 0.5 * spacing * plane_no

            current_verts = np.array([tuple(v.co) for v in src_mesh.verts])
            signs = PlaneEquation.from_normal_and_point(
                plane_no, plane_co).side_of_points(current_verts)
            #print(f"Plane co {plane_co}, no {plane_no}, signs {signs}")
            if (signs <= 0).all():  # or (signs <= 0).all():
                continue

            res = bmesh.ops.bisect_plane(src_mesh,
                                         geom=geom_in,
                                         dist=precision,
                                         plane_co=plane_co,
                                         plane_no=plane_no,
                                         use_snap_center=False,
                                         clear_outer=True,
                                         clear_inner=False)
            n_cuts += 1

            if fill:
                surround = [
                    e for e in res['geom_cut']
                    if isinstance(e, bmesh.types.BMEdge)
                ]
                if surround:
                    fres = bmesh.ops.edgenet_prepare(src_mesh, edges=surround)
                    if fres['edges']:
                        bmesh.ops.edgeloop_fill(src_mesh, edges=fres['edges'])

        if n_cuts == 0:
            return None

        return pydata_from_bmesh(src_mesh)
Exemplo n.º 12
0
 def _verts_by_plane(self, topo, center, direction, radius):
     plane = PlaneEquation.from_normal_and_point(direction, center)
     condition = lambda v: plane.distance_to_point(v) < radius
     return topo.get_vertices_by_location_mask(condition)
Exemplo n.º 13
0
        def process(self):
            if not any(socket.is_linked for socket in self.outputs):
                return

            vertices_s = self.inputs['Vertices'].sv_get()
            edges_s = self.inputs['Edges'].sv_get()
            faces_s = self.inputs['Faces'].sv_get()
            vertex_weight_s = self.inputs['VertexWeight'].sv_get()
            edge_weight_s = self.inputs['EdgeWeight'].sv_get()
            face_weight_s = self.inputs['FaceWeight'].sv_get()
            tangent_weight_s = self.inputs['TangentWeight'].sv_get()
            degree_u_s = self.inputs['DegreeU'].sv_get()
            degree_v_s = self.inputs['DegreeV'].sv_get()

            surface_out = []
            control_points_out = []
            weights_out = []
            inputs = zip_long_repeat(vertices_s, edges_s, faces_s, degree_u_s,
                                     degree_v_s, vertex_weight_s,
                                     edge_weight_s, face_weight_s,
                                     tangent_weight_s)
            for vertices, edges, faces, degree_u, degree_v, vertex_weights, edge_weights, face_weights, tangent_weights in inputs:
                fullList(degree_u, len(faces))
                fullList(degree_v, len(faces))

                if not edges:
                    edges = polygons_to_edges([faces], True)[0]

                fullList(vertex_weights, len(vertices))
                fullList(tangent_weights, len(vertices))
                fullList(edge_weights, len(edges))
                fullList(face_weights, len(faces))

                bm = bmesh_from_pydata(vertices,
                                       edges,
                                       faces,
                                       normal_update=True,
                                       markup_edge_data=True)
                normals = [vertex.normal for vertex in bm.verts]
                edge_planes_dict = dict()
                for edge in bm.edges:
                    edge_v = edge.verts[1].co - edge.verts[0].co
                    edge_c = (edge.verts[0].co + edge.verts[1].co) / 2.0
                    edge_ort_plane = PlaneEquation.from_normal_and_point(
                        edge_v, edge_c)
                    face_normals = [face.normal for face in edge.link_faces]
                    faces_normal = sum(face_normals, Vector())
                    projected_faces_normal = edge_ort_plane.projection_of_point(
                        faces_normal)
                    #print("EV: %s, No.sum: %s, Pr.N: %s" % (edge_v, faces_normal, projected_faces_normal))
                    edge_plane = PlaneEquation.from_normal_and_point(
                        projected_faces_normal, edge_c)
                    edge_planes_dict[(edge.verts[0].index,
                                      edge.verts[1].index)] = edge_plane
                    edge_planes_dict[(edge.verts[1].index,
                                      edge.verts[0].index)] = edge_plane
                bm.free()

                vert_planes = [
                    PlaneEquation.from_normal_and_point(normal, point)
                    for normal, point in zip(normals, vertices)
                ]

                edge_weights_dict = dict()
                #edge_planes_dict = dict()
                for (i, j), edge_weight in zip(edges, edge_weights):
                    edge_weights_dict[(i, j)] = edge_weight
                    edge_weights_dict[(j, i)] = edge_weight
                    #edge_planes_dict[(i, j)] = edge_plane
                    #edge_planes_dict[(j, i)] = edge_plane

                for i, (face, degree_u, degree_v, face_weight) in enumerate(
                        zip(faces, degree_u, degree_v, face_weights)):
                    if len(face) != 4:
                        self.info("Face #%s is not a Quad, skip it", i)
                        continue
                    face_verts = [vertices[i] for i in face]
                    face_planes = [vert_planes[i] for i in face]
                    face_vert_weights = [vertex_weights[i] for i in face]
                    face_tangent_weights = [tangent_weights[i] for i in face]
                    #face_edges = list(zip(face, face[1:])) + [(face[-1], face[0])]
                    #face_edge_weights = [edge_weights_dict[edge] for edge in face_edges]
                    surface, ctrlpts, weights = self.make_surface(
                        face, degree_u, degree_v, face_verts, face_planes,
                        face_vert_weights, face_tangent_weights, face_weight,
                        edge_weights_dict, edge_planes_dict)
                    surface_out.append(surface)
                    control_points_out.append(list(map(tuple, ctrlpts)))
                    weights_out.append(weights)

            self.outputs['Surfaces'].sv_set(surface_out)
            self.outputs['ControlPoints'].sv_set(control_points_out)
            self.outputs['Weights'].sv_set(weights_out)