Ejemplo n.º 1
0
    def process(self):
        if not any(socket.is_linked for socket in self.outputs):
            return
        if not self.inputs['Vertices'].is_linked:
            return

        vertices_s = self.inputs['Vertices'].sv_get()
        vertices_s = ensure_nesting_level(vertices_s, 4)
        surfaces = self.inputs['Surface'].sv_get()
        surfaces = ensure_nesting_level(surfaces, 4)

        objects = match_long_repeat([vertices_s, surfaces])

        result_vertices = []

        for vertices, surface in zip(*objects):
            if self.transpose:
                surface = transpose_list(surface)
            #print("Surface: {} of {} of {}".format(type(surface), type(surface[0]), type(surface[0][0])))
            spline = self.build_spline(surface)
            # uv_coords will be list[m] of lists[n] of 2-tuples of floats
            # number of "rows" and "columns" in uv_coords will match so of vertices.
            src_size_u, src_size_v, uv_coords = self.get_uv(vertices)
            if self.autoscale:
                u_index, v_index = self.get_other_axes()
                surface_flattened = [v for col in surface for v in col]
                scale_u = diameter(surface_flattened, u_index) / src_size_u
                scale_v = diameter(surface_flattened, v_index) / src_size_v
                scale_z = sqrt(scale_u * scale_v)
            else:
                scale_z = 1.0
            if self.flip:
                scale_z = -scale_z
            new_vertices = []
            for uv_row, vertices_row in zip(uv_coords, vertices):
                new_row = []
                for ((u, v), src_vertex) in zip(uv_row, vertices_row):
                    #print("UV: ({}, {}), SRC: {}".format(u, v, src_vertex))
                    spline_vertex = np.array(spline.eval(u, v))
                    spline_normal = np.array(
                        spline.normal(u, v, h=self.normal_precision))
                    #print("Spline: M {}, N {}".format(spline_vertex, spline_normal))
                    # Coordinate of source vertex corresponding to orientation axis
                    z = src_vertex[self.orient_axis]
                    new_vertex = tuple(spline_vertex +
                                       scale_z * z * spline_normal)
                    new_row.append(new_vertex)
                new_vertices.append(new_row)
            result_vertices.append(new_vertices)

        if not self.grouped:
            result_vertices = result_vertices[0]
        self.outputs['Vertices'].sv_set(result_vertices)
Ejemplo n.º 2
0
    def process(self):
        if not any(socket.is_linked for socket in self.outputs):
            return
        if not self.inputs['Vertices'].is_linked:
            return

        vertices_s = self.inputs['Vertices'].sv_get()
        vertices_s = ensure_nesting_level(vertices_s, 4)
        surfaces = self.inputs['Surface'].sv_get()
        surfaces = ensure_nesting_level(surfaces, 4)

        objects = match_long_repeat([vertices_s, surfaces])

        result_vertices = []

        for vertices, surface in zip(*objects):
            if self.transpose:
                surface = transpose_list(surface)
            #print("Surface: {} of {} of {}".format(type(surface), type(surface[0]), type(surface[0][0])))
            spline = self.build_spline(surface)
            # uv_coords will be list[m] of lists[n] of 2-tuples of floats
            # number of "rows" and "columns" in uv_coords will match so of vertices.
            src_size_u, src_size_v, uv_coords = self.get_uv(vertices)
            if self.autoscale:
                u_index, v_index = self.get_other_axes()
                surface_flattened = [v for col in surface for v in col]
                scale_u = diameter(surface_flattened, u_index) / src_size_u
                scale_v = diameter(surface_flattened, v_index) / src_size_v
                scale_z = sqrt(scale_u * scale_v)
            else:
                scale_z = 1.0
            if self.flip:
                scale_z = - scale_z
            new_vertices = []
            for uv_row, vertices_row in zip(uv_coords,vertices):
                new_row = []
                for ((u, v), src_vertex) in zip(uv_row, vertices_row):
                    #print("UV: ({}, {}), SRC: {}".format(u, v, src_vertex))
                    spline_vertex = np.array(spline.eval(u, v))
                    spline_normal = np.array(spline.normal(u, v, h=self.normal_precision))
                    #print("Spline: M {}, N {}".format(spline_vertex, spline_normal))
                    # Coordinate of source vertex corresponding to orientation axis
                    z = src_vertex[self.orient_axis]
                    new_vertex = tuple(spline_vertex + scale_z * z * spline_normal)
                    new_row.append(new_vertex)
                new_vertices.append(new_row)
            result_vertices.append(new_vertices)

        if not self.grouped:
            result_vertices = result_vertices[0]
        self.outputs['Vertices'].sv_set(result_vertices)
 def test_diameter_2(self):
     p1 = (0, 0, 0)
     p2 = (0, 1, 0)
     p3 = (1, 0, 0)
     diam = diameter([p1, p2, p3], None)
     expected = sqrt(2)
     self.assert_sverchok_data_equal(diam, expected, precision=8)
 def test_diameter_3(self):
     p1 = (0, 0, 0)
     p2 = (0, 1, 0)
     p3 = (1, 0, 0)
     direction = (1, 0, 0)
     diam = diameter([p1, p2, p3], direction)
     expected = 1
     self.assert_sverchok_data_equal(diam, expected, precision=8)
Ejemplo n.º 5
0
    def duplicate_vertices(self, v1, v2, vertices, edges, faces, count, p):
        direction = v2 - v1
        edge_length = (1.0 - 2 * p) * direction.length
        one_item_length = edge_length / count
        actual_length = diameter(vertices, self.orient_axis)
        if actual_length != 0.0:
            x_scale = one_item_length / actual_length
        else:
            x_scale = 1.0
        x = all_axes[self.orient_axis]
        # for actual_length = 1.0 and edge_length = 3.0, let origins be [0.5, 1.5, 2.5]
        u = direction.normalized()
        alphas = np.linspace(0.0, 1.0, count + 1)
        origins = [
            v1 + (1 - 2 * p) * direction * alpha + p * direction +
            0.5 * one_item_length * u for alpha in alphas
        ][:-1]
        assert len(origins) == count

        if self.scale_off:
            scale = None
        else:
            if self.scale_all:
                scale = Matrix.Scale(x_scale, 4)
            else:
                scale = Matrix.Scale(x_scale, 4, x)

        need_flip = False
        if self.algorithm == 'householder':
            rot = autorotate_householder(x, direction).inverted()
            # Since Householder transformation is reflection, we need to reflect things back
            need_flip = True
        elif self.algorithm == 'track':
            rot = autorotate_track(self.orient_axis_, direction, self.up_axis)
        elif self.algorithm == 'diff':
            rot = autorotate_diff(x, direction).inverted()
        else:
            raise Exception("Unsupported algorithm")

        if need_flip:
            flip = Matrix([[-1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0],
                           [0, 0, 0, 1]])
        else:
            flip = Matrix.Identity(4)
        if scale is None:
            matrices = [Matrix.Translation(o) * rot * flip for o in origins]
        else:
            matrices = [
                Matrix.Translation(o) * rot * scale * flip for o in origins
            ]

        if self.apply_matrices:
            result_vertices = [[m * vertex for vertex in vertices]
                               for m in matrices]
        else:
            result_vertices = [vertices] * count
        return matrices, result_vertices
Ejemplo n.º 6
0
    def duplicate_vertices(self, v1, v2, vertices, edges, faces, count, p):
        direction = v2 - v1
        edge_length = (1.0 - 2*p) * direction.length
        one_item_length = edge_length / count
        actual_length = diameter(vertices, self.orient_axis)
        if actual_length != 0.0:
            x_scale = one_item_length / actual_length
        else:
            x_scale = 1.0
        x = all_axes[self.orient_axis]
        # for actual_length = 1.0 and edge_length = 3.0, let origins be [0.5, 1.5, 2.5]
        u = direction.normalized()
        alphas = np.linspace(0.0, 1.0, count+1)
        origins = [v1 + (1-2*p)*direction*alpha + p*direction + 0.5*one_item_length*u for alpha in alphas][:-1]
        assert len(origins) == count

        if self.scale_off:
            scale = None
        else:
            if self.scale_all:
                scale = Matrix.Scale(x_scale, 4)
            else:
                scale = Matrix.Scale(x_scale, 4, x)

        need_flip = False
        if self.algorithm == 'householder':
            rot = autorotate_householder(x, direction).inverted()
            # Since Householder transformation is reflection, we need to reflect things back
            need_flip = True
        elif self.algorithm == 'track':
            rot = autorotate_track(self.orient_axis_, direction, self.up_axis)
        elif self.algorithm == 'diff':
            rot = autorotate_diff(x, direction).inverted()
        else:
            raise Exception("Unsupported algorithm")

        if need_flip:
            flip = Matrix([[-1,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,1]])
        else:
            flip = Matrix.Identity(4)
        if scale is None:
            matrices = [Matrix.Translation(o)*rot*flip for o in origins]
        else:
            matrices = [Matrix.Translation(o)*rot*scale*flip for o in origins]

        if self.apply_matrices:
            result_vertices = [[m * vertex for vertex in vertices] for m in matrices]
        else:
            result_vertices = [vertices] * count
        return matrices, result_vertices
Ejemplo n.º 7
0
 def scale_cells(self, verts, sites, insets, precision):
     if all(i == 0.0 for i in insets):
         return verts
     verts_out = []
     for vs, site, inset in zip(verts, sites, insets):
         if inset >= 1.0:
             continue
         if self.scale_center == 'SITE':
             c = site
         else:
             c = center(vs)
         vs1 = scale_relative(vs, c, 1.0 - inset)
         if diameter(vs1, axis=None) <= precision:
             continue
         verts_out.append(vs1)
     return verts_out
Ejemplo n.º 8
0
    def process(self):
        if not self.inputs['Vertices'].is_linked:
            return
        if not any(s.is_linked for s in self.outputs):
            return

        any_direction = not self.inputs['Direction'].is_linked

        out_results = []

        vertices_s = self.inputs['Vertices'].sv_get(default=[[]])
        directions_s = self.inputs['Direction'].sv_get(default=[[]])
        objects = match_long_repeat([vertices_s, directions_s])

        for vertices, directions in zip(*objects):
            if any_direction:
                direction = None
            else:
                direction = directions[0]
            diam = diameter(vertices, direction)
            out_results.append([diam])

        self.outputs['Diameter'].sv_set(out_results)
Ejemplo n.º 9
0
 def count_down(self, edge_length, vertices, count):
     donor_size = diameter(vertices, self.orient_axis)
     if donor_size == 0.0:
         return 1
     return ceil(edge_length / donor_size)
Ejemplo n.º 10
0
    def _process(self, verts_recpt, faces_recpt, verts_donor, faces_donor, face_data_donor, frame_widths, zcoefs, zoffsets, zrotations, wcoefs, facerots, mask):
        bm = bmesh_from_pydata(verts_recpt, [], faces_recpt, normal_update=True)
        bm.verts.ensure_lookup_table()
        single_donor = self.matching_mode == 'LONG'
        frame_level = get_data_nesting_level(frame_widths)
        if single_donor:
            # Original (unrotated) donor vertices
            donor_verts_o = [Vector(v) for v in verts_donor]

            verts_donor = [verts_donor]
            faces_donor = [faces_donor]
            face_data_donor = [face_data_donor]
            if frame_level == 0:
                frame_widths = [frame_widths]

        n_faces_recpt = len(faces_recpt)
        fullList(verts_donor, n_faces_recpt)
        fullList(faces_donor, n_faces_recpt)
        fullList(face_data_donor, n_faces_recpt)
        fullList(frame_widths, n_faces_recpt)

        X, Y = self.get_other_axes()
        Z = self.normal_axis_idx()

        donor = DonorData()

        # Vertices of the unit triangle.
        # In case xy_mode != BOUNDS, we will never
        # have to recalculate these.
        if self.tri_bound_mode == 'EQUILATERAL':
            donor.tri_vert_1 = self.from2d(-0.5, -sqrt_3_6)
            donor.tri_vert_2 = self.from2d(0.5, -sqrt_3_6)
            donor.tri_vert_3 = self.from2d(0, sqrt_3_3)
        else:
            donor.tri_vert_1 = self.from2d(-1, 0)
            donor.tri_vert_2 = self.from2d(1, 0)
            donor.tri_vert_3 = self.from2d(0, 1)

        if single_donor:
            # We will be rotating the donor object around Z axis,
            # so it's size along Z is not going to change.
            z_size = diameter(donor_verts_o, Z)

        output = OutputData()

        prev_angle = None
        face_data = zip(faces_recpt, bm.faces, frame_widths, verts_donor, faces_donor, face_data_donor, zcoefs, zoffsets, zrotations, wcoefs, facerots, mask)
        recpt_face_idx = 0
        for recpt_face, recpt_face_bm, frame_width, donor_verts_i, donor_faces_i, donor_face_data_i, zcoef, zoffset, angle, wcoef, facerot, m in face_data:

            recpt_face_data = RecptFaceData()
            recpt_face_data.index = recpt_face_idx
            recpt_face_data.normal = recpt_face_bm.normal
            recpt_face_data.center = recpt_face_bm.calc_center_median()
            recpt_face_data.vertices_co = [bm.verts[i].co for i in recpt_face]
            if self.use_shell_factor:
                recpt_face_data.vertices_normal = [bm.verts[i].normal * bm.verts[i].calc_shell_factor() for i in recpt_face]
            else:
                recpt_face_data.vertices_normal = [bm.verts[i].normal for i in recpt_face]
            recpt_face_data.vertices_idxs = recpt_face[:]
            if not isinstance(frame_width, (int, float)):
                raise Exception(f"Unexpected data type for frame_width: {frame_width}")
            recpt_face_data.frame_width = frame_width

            donor.faces_i = donor_faces_i
            donor.face_data_i = donor_face_data_i

            if not single_donor:
                # Original (unrotated) donor vertices
                donor_verts_o = [Vector(v) for v in donor_verts_i]
                z_size = diameter(donor_verts_o, Z)

            # We have to recalculate rotated vertices only if
            # the rotation angle have changed.
            if prev_angle is None or angle != prev_angle or not single_donor:
                donor.verts_v = self.rotate_z(donor_verts_o, angle)

                if self.xy_mode == 'BOUNDS' or self.z_scale == 'AUTO' :
                    donor.max_x = max(v[X] for v in donor.verts_v)
                    donor.min_x = min(v[X] for v in donor.verts_v)
                    donor.max_y = max(v[Y] for v in donor.verts_v)
                    donor.min_y = min(v[Y] for v in donor.verts_v)

                if self.xy_mode == 'BOUNDS':
                    donor.tri_vert_1, donor.tri_vert_2, donor.tri_vert_3 = self.bounding_triangle(donor.verts_v)

            prev_angle = angle

            if self.z_scale == 'CONST':
                if abs(z_size) < 1e-6:
                    zcoef = 0
                else:
                    zcoef = zcoef / z_size

            # Define TRI/QUAD mode based on node settings.
            n = len(recpt_face)
            if not m:
                map_mode = self.mask_mode
            else:
                if n == 3:
                    if self.frame_mode == 'ALWAYS':
                        map_mode = 'FRAME'
                    else:
                        if self.map_mode == 'QUADTRI':
                            map_mode = 'TRI'
                        else: # self.map_mode == 'QUADS':
                            map_mode = 'QUAD'
                elif n == 4:
                    if self.frame_mode in ['ALWAYS', 'NGONQUAD']:
                        map_mode = 'FRAME'
                    else:
                        map_mode = 'QUAD'
                else:
                    if self.frame_mode in ['ALWAYS', 'NGONQUAD', 'NGONS']:
                        map_mode = 'FRAME'
                    else:
                        if self.ngon_mode == 'QUADS':
                            map_mode = 'QUAD'
                        elif self.ngon_mode == 'ASIS':
                            map_mode = 'ASIS'
                        else:
                            map_mode = 'SKIP'

            if map_mode == 'SKIP':
                # Skip this recipient's face - do not produce any vertices/faces for it
                continue

            self._process_face(map_mode, output, recpt_face_data, donor, zcoef, zoffset, angle, wcoef, facerot)
            recpt_face_idx += 1

        bm.free()

        return output
Ejemplo n.º 11
0
 def count_down(self, edge_length, vertices, count):
     donor_size = diameter(vertices, self.orient_axis)
     if donor_size == 0.0:
         return 1
     return ceil( edge_length / donor_size )
 def test_diameter_1(self):
     p1 = (0, 0, 0)
     p2 = (0, 1, 0)
     diam = diameter([p1, p2], None)
     expected = 1.0
     self.assert_sverchok_data_equal(diam, expected, precision=8)