def process(self):
        if not any(s.is_linked for s in self.outputs):
            return

        verts_out, edges_out, polys_out = [], [], []

        params = self.get_data()
        get_edges = self.outputs['Edges'].is_linked

        for p in zip(*params):
            p = match_long_repeat(p)
            for p2 in zip(*p):
                size, vTrunc, eTrunc = p2

                verts, faces = createSolid(self.source, vTrunc, eTrunc,
                                           self.dual, self.snub)

                # resize to normal size, or if keepSize, make sure all verts are of length 'size'
                if self.keepSize:
                    rad = size / verts[-1 if self.dual else 0].length
                else:
                    rad = size
                verts = [list(i * rad) for i in verts]

                verts_out.append(verts)
                polys_out.append(faces)
                if get_edges:
                    edges_out.append(pols_edges([faces], unique_edges=True)[0])

        if self.outputs['Vertices'].is_linked:
            self.outputs['Vertices'].sv_set(verts_out)
        if get_edges:
            self.outputs['Edges'].sv_set(edges_out)
        if self.outputs['Polygons'].is_linked:
            self.outputs['Polygons'].sv_set(polys_out)
def get_delaunay_triangulation(verts_in):
    pt_list = [Site(pt[0], pt[1]) for pt in verts_in]
    res = computeDelaunayTriangulation(pt_list)
    polys_in = [tri for tri in res if -1 not in tri]
    #all faces hase normals -Z, should be reversed
    polys_in = [pol[::-1] for pol in polys_in]
    edges_in = pols_edges([polys_in], unique_edges=True)[0]
    return edges_in, polys_in
示例#3
0
    def process(self):
        if not any(s.is_linked for s in self.outputs):
            return


        verts_out, edges_out, polys_out = [], [], []

        params = self.get_data()
        get_edges = self.outputs['Edges'].is_linked

        for p in zip(*params):
            p = match_long_repeat(p)
            for p2 in zip(*p):
                size, vTrunc, eTrunc = p2

                verts, faces = createSolid(self.source,
                                       vTrunc,
                                       eTrunc,
                                       self.dual,
                                       self.snub
                                       )

                # resize to normal size, or if keepSize, make sure all verts are of length 'size'
                if self.keepSize:
                    rad = size / verts[-1 if self.dual else 0].length
                else:
                    rad = size
                verts = [list(i * rad) for i in verts]

                verts_out.append(verts)
                polys_out.append(faces)
                if get_edges:
                    edges_out.append(pols_edges([faces], unique_edges=True)[0])


        if self.outputs['Vertices'].is_linked:
            self.outputs['Vertices'].sv_set(verts_out)
        if get_edges:
            self.outputs['Edges'].sv_set(edges_out)
        if self.outputs['Polygons'].is_linked:
            self.outputs['Polygons'].sv_set(polys_out)
def order(verts, edges, verts_o,k):
    for i in edges:
        if k in i:
            # this is awesome !!
            k = i[int(not i.index(k))]
            verts_o.append(verts[k])
            return k, i
    return False, False

if verts_A and verts_B and edges_A and edges_B:


    # pols2edges
    if len(edges_A[0][0]) > 2:
        edges_A = pols_edges(edges_A, unique_edges=True)
    if len(edges_B[0][0]) > 2:
        edges_B = pols_edges(edges_B, unique_edges=True)


    # ordering sort edges chain
    def ordering(in_verts, in_edges):
        ed = 1
        vout = []
        for edges, verts in zip(in_edges, in_verts):
            verts_o = []
            k = 0
            while True:
                k, ed = order(verts, edges, verts_o,k)
                if ed:
                    edges.remove(ed)
示例#5
0
    def process(self):

        if 'vecLine' in self.inputs and \
                'vecPlane' in self.inputs and \
                'edgPlane' in self.inputs:
            print(self.name, 'is starting')
            if self.inputs['vecLine'].links and \
                    self.inputs['vecPlane'].links and \
                    self.inputs['edgPlane'].links:
                if self.bindCircle:
                    circle = [ (Vector((sin(radians(i)),cos(radians(i)),0))*self.circle_rad)/4 \
                              for i in range(0,360,30) ]
                vec = self.inputs['vecLine'].sv_get()
                vecplan = self.inputs['vecPlane'].sv_get()
                edgplan = self.inputs['edgPlane'].sv_get()
                if len(edgplan[0][0]) > 2:
                    edgplan = pols_edges(edgplan)
                thick = self.inputs['thick'].sv_get()[0][0]
                threshold_coplanar = 0.005
                sinuso60 = 0.8660254037844386
                sinuso60_minus = 0.133974596
                sinuso30 = 0.5
                sinuso45 = 0.7071067811865475
                thick_2 = thick / 2
                thick_3 = thick / 3
                thick_6 = thick / 6
                threshold = self.threshold
                if 'vecContr' in self.inputs and self.inputs['vecContr'].links:
                    vecont = self.inputs['vecContr'].sv_get()
                    #edgcont = self.inputs['edgContr'].sv_get()
                    vec_cont = Vector_generate(vecont)
                    loc_cont = [[i[0]] for i in vec_cont]
                    norm_cont = [[NM(i[0], i[len(i) // 2], i[-1])]
                                 for i in vec_cont]  # довести до ума
                else:
                    vec_cont = []
                if 'vecTube' in self.inputs and self.inputs['vecTube'].links:
                    vectube = self.inputs['vecTube'].sv_get()
                    vec_tube = Vector_generate(vectube)
                    tube_radius = self.inputs['radTube'].sv_get()[0][0]
                    circle_tube = [ (Vector((sin(radians(i)),cos(radians(i)),0))*tube_radius) \
                              for i in range(0,360,15) ]
                else:
                    vec_tube = []
                outeup = []
                outelo = []
                vupper = []
                vlower = []
                centers = []
                vec_ = Vector_generate(vec)
                vecplan_ = Vector_generate(vecplan)
                for centersver, vecp, edgp in zip(vecplan, vecplan_, edgplan):
                    tubes_flag_bed_solution_i_know = False
                    newinds1 = [list(e) for e in edgp]
                    newinds2 = newinds1.copy()
                    vupperob = vecp.copy()
                    vlowerob = vecp.copy()
                    deledges1 = []
                    deledges2 = []
                    # to define bounds
                    x = [i[0] for i in vecp]
                    y = [i[1] for i in vecp]
                    z = [i[2] for i in vecp]
                    m1x, m2x, m1y, m2y, m1z, m2z = max(x), min(x), max(y), min(
                        y), max(z), min(z)
                    l = Vector(
                        (sum(x) / len(x), sum(y) / len(y), sum(z) / len(z)))
                    n_select = [vecp[0], vecp[len(vecp) // 2],
                                vecp[-1]]  # довести до ума
                    n_select.sort(key=lambda x: sum(x[:]), reverse=False)
                    n_ = NM(n_select[0], n_select[1], n_select[2])
                    n_.normalize()
                    # а виновта ли нормаль?
                    if n_[0] < 0:
                        n = n_ * -1
                    else:
                        n = n_
                    cen = [sum(i) for i in zip(*centersver)]
                    centers.append(Vector(cen) / len(centersver))
                    k = 0
                    lenvep = len(vecp)
                    # KDtree collections closest to join edges to sockets
                    tree = KDT.KDTree(lenvep)
                    for i, v in enumerate(vecp):
                        tree.insert(v, i)
                    tree.balance()
                    # vertical edges iterations
                    # every edge is object - two points, one edge
                    for v in vec_:
                        if not v: continue
                        # sort vertices by Z value
                        # find two vertices - one lower, two upper
                        vlist = [v[0], v[1]]
                        vlist.sort(key=lambda x: x[2], reverse=False)
                        # flip if coplanar to enemy plane
                        # flip plane coplanar
                        if vec_cont:
                            fliped = self.get_coplanar(v[0], loc_cont,
                                                       norm_cont, vec_cont)
                        else:
                            fliped = False
                        shortedge = (vlist[1] - vlist[0]).length
                        if fliped:
                            two, one = vlist
                        else:
                            one, two = vlist
                        # coplanar to owner
                        cop = abs(D2P(one, l, n))
                        # defining bounds
                        inside = one[0]<m1x and one[0]>m2x and one[1]<m1y and one[1]>m2y \
                                 and one[2]<=m1z and one[2]>=m2z
                        # if in bounds and coplanar do:
                        #print(self.name,l, cop, inside)
                        if cop < threshold_coplanar and inside and shortedge > thick * threshold:
                            '''
                            huge calculations. if we can reduce...
                            '''
                            # find shift for thickness in sockets
                            diry = two - one
                            diry.normalize()
                            # solution for vertical wafel - cool but not in diagonal case
                            # angle = radians(degrees(atan(n.y/n.x))+90)
                            dirx_ = self.rotation_on_axis(diry, n, radians(90))
                            dirx = dirx_ * thick_2
                            # вектор, индекс, расстояние
                            # запоминаем порядок находим какие удалить рёбра
                            # делаем выборку левая-правая точка
                            nearv_1, near_1 = tree.find(one)[:2]
                            nearv_2, near_2 = tree.find(two)[:2]
                            # indexes of two nearest points
                            # удалить рёбра что мешают спать заодно
                            en_0, en_1, de1 = self.calc_indexes(edgp, near_1)
                            deledges1.extend(de1)
                            en_2, en_3, de2 = self.calc_indexes(edgp, near_2)
                            deledges2.extend(de2)
                            # print(vecp, one, dirx, en_0, en_1)
                            # left-right indexes and vectors
                            # с учётом интерполяций по высоте
                            l1, r1, lz1, rz1 = \
                                    self.calc_leftright(vecp, one, dirx, en_0, en_1, thick_2, diry)
                            l2, r2, lz2, rz2 = \
                                    self.calc_leftright(vecp, two, dirx, en_2, en_3, thick_2, diry)
                            # print(left2, right2, l2, r2, lz2, rz2)
                            # средняя точка и её смещение по толщине материала
                            three = (one - two) / 2 + two

                            # rounded section
                            if self.rounded:
                                '''рёбра'''
                                # пазы формируем независимо от верх низ

                                outeob1 = [[lenvep + k + 8, lenvep + k],
                                           [lenvep + k + 1, lenvep + k + 2],
                                           [lenvep + k + 2, lenvep + k + 3],
                                           [lenvep + k + 3, lenvep + k + 4],
                                           [lenvep + k + 4, lenvep + k + 5],
                                           [lenvep + k + 5, lenvep + k + 6],
                                           [lenvep + k + 6, lenvep + k + 7],
                                           [lenvep + k + 7, lenvep + k + 8],
                                           [lenvep + k + 9, lenvep + k + 1]]

                                outeob2 = [[lenvep + k, lenvep + k + 1],
                                           [lenvep + k + 1, lenvep + k + 2],
                                           [lenvep + k + 2, lenvep + k + 3],
                                           [lenvep + k + 3, lenvep + k + 4],
                                           [lenvep + k + 4, lenvep + k + 5],
                                           [lenvep + k + 5, lenvep + k + 6],
                                           [lenvep + k + 6, lenvep + k + 7],
                                           [lenvep + k + 7, lenvep + k + 8],
                                           [lenvep + k + 8, lenvep + k + 9]]
                                # наполнение списков lenvep = length(vecp)
                                newinds1.extend([[l1, lenvep + k],
                                                 [lenvep + k + 9, r1]])
                                newinds2.extend([[l2, lenvep + k + 9],
                                                 [lenvep + k, r2]])
                                '''Вектора'''
                                round1 = diry * thick_3
                                round2 = diry * thick_3 * sinuso30
                                round2_ = dirx / 3 + dirx * (2 * sinuso60 / 3)
                                round3 = diry * thick_3 * sinuso60_minus
                                round3_ = dirx / 3 + dirx * (2 * sinuso30 / 3)
                                round4 = dirx / 3
                                vupperob.extend([
                                    lz2, three + round1 - dirx,
                                    three + round2 - round2_,
                                    three + round3 - round3_, three - round4,
                                    three + round4, three + round3 + round3_,
                                    three + round2 + round2_,
                                    three + round1 + dirx, rz2
                                ])
                                vlowerob.extend([
                                    rz1, three - round1 - dirx,
                                    three - round2 - round2_,
                                    three - round3 - round3_, three - round4,
                                    three + round4, three - round3 + round3_,
                                    three - round2 + round2_,
                                    three - round1 + dirx, lz1
                                ])
                                k += 10

                            # streight section
                            else:
                                '''рёбра'''
                                # пазы формируем независимо от верх низ
                                outeob1 = [[lenvep + k, lenvep + k + 1],
                                           [lenvep + k + 1, lenvep + k + 2],
                                           [lenvep + k + 2, lenvep + k + 3]]
                                outeob2 = [[lenvep + k, lenvep + k + 1],
                                           [lenvep + k + 1, lenvep + k + 2],
                                           [lenvep + k + 2, lenvep + k + 3]]
                                # наполнение списков lenvep = length(vecp)
                                newinds1.extend([[l1, lenvep + k],
                                                 [lenvep + k + 3, r1]])
                                newinds2.extend([[l2, lenvep + k + 3],
                                                 [lenvep + k, r2]])
                                '''Вектора'''
                                vupperob.extend(
                                    [lz2, three - dirx, three + dirx, rz2])
                                vlowerob.extend(
                                    [rz1, three + dirx, three - dirx, lz1])
                                k += 4
                            newinds1.extend(outeob1)
                            newinds2.extend(outeob2)

                            # circles to bing panels section
                            if self.bindCircle:
                                CP = self.circl_place
                                if CP == 'Midl':
                                    crcl_cntr = IL2P(one, two, Vector(
                                        (0, 0, 0)), Vector((0, 0, -1)))
                                elif CP == 'Up' and not fliped:
                                    crcl_cntr = two - diry * self.circle_rad * 2
                                elif CP == 'Down' and not fliped:
                                    crcl_cntr = one + diry * self.circle_rad * 2
                                elif CP == 'Up' and fliped:
                                    crcl_cntr = one + diry * self.circle_rad * 2
                                elif CP == 'Down' and fliped:
                                    crcl_cntr = two - diry * self.circle_rad * 2
                                # forgot howto 'else' in line iteration?
                                outeob1 = [[
                                    lenvep + k + i, lenvep + k + i + 1
                                ] for i in range(0, 11)]
                                outeob1.append([lenvep + k, lenvep + k + 11])
                                outeob2 = [[
                                    lenvep + k + i, lenvep + k + i + 1
                                ] for i in range(12, 23)]
                                outeob2.append(
                                    [lenvep + k + 12, lenvep + k + 23])
                                newinds1.extend(outeob1 + outeob2)
                                newinds2.extend(outeob1 + outeob2)
                                mat_rot_cir = n.rotation_difference(
                                    Vector((0, 0, 1))).to_matrix().to_4x4()
                                circle_to_add_1 = [vecir*mat_rot_cir+crcl_cntr+ \
                                        dirx_*self.circle_rad for vecir in circle ]
                                circle_to_add_2 = [vecir*mat_rot_cir+crcl_cntr- \
                                        dirx_*self.circle_rad for vecir in circle ]
                                vupperob.extend(circle_to_add_1 +
                                                circle_to_add_2)
                                vlowerob.extend(circle_to_add_1 +
                                                circle_to_add_2)
                                k += 24

                            # TUBE section
                            if vec_tube and not tubes_flag_bed_solution_i_know:
                                for v in vec_tube:
                                    tubeverlength = len(v)
                                    if tubeverlength == 2:
                                        crcl_cntr = IL2P(v[0], v[1], l, n)
                                        if crcl_cntr:
                                            inside = crcl_cntr[0]<m1x and crcl_cntr[0]>m2x and crcl_cntr[1]<m1y \
                                                 and crcl_cntr[1]>m2y and crcl_cntr[2]<=m1z and crcl_cntr[2]>=m2z
                                            if inside:
                                                outeob = [[
                                                    lenvep + k + i,
                                                    lenvep + k + i + 1
                                                ] for i in range(0, 23)]
                                                outeob.append([
                                                    lenvep + k, lenvep + k + 23
                                                ])
                                                newinds1.extend(outeob)
                                                newinds2.extend(outeob)
                                                mat_rot_cir = n.rotation_difference(
                                                    Vector(
                                                        (0, 0, 1))).to_matrix(
                                                        ).to_4x4()
                                                circle_to_add = [
                                                    vecir * mat_rot_cir +
                                                    crcl_cntr
                                                    for vecir in circle_tube
                                                ]
                                                vupperob.extend(circle_to_add)
                                                vlowerob.extend(circle_to_add)
                                                k += 24
                                    else:
                                        tubeshift = tubeverlength // 2
                                        crcl_cntr = IL2P(
                                            v[0], v[tubeshift], l, n)
                                        if crcl_cntr:
                                            inside = crcl_cntr[0]<m1x and crcl_cntr[0]>m2x and crcl_cntr[1]<m1y \
                                                 and crcl_cntr[1]>m2y and crcl_cntr[2]<=m1z and crcl_cntr[2]>=m2z
                                            if inside:
                                                outeob = [[
                                                    lenvep + k + i,
                                                    lenvep + k + i + 1
                                                ] for i in range(tubeshift - 1)
                                                          ]
                                                outeob.append([
                                                    lenvep + k,
                                                    lenvep + k + tubeshift - 1
                                                ])
                                                newinds1.extend(outeob)
                                                newinds2.extend(outeob)
                                                for tubevert in range(
                                                        tubeshift):
                                                    tubevert_out = IL2P(
                                                        v[tubevert],
                                                        v[tubevert +
                                                          tubeshift], l, n)
                                                    vupperob.append(
                                                        tubevert_out)
                                                    vlowerob.append(
                                                        tubevert_out)
                                                k += tubeshift

                                tubes_flag_bed_solution_i_know = True
                        elif cop < threshold_coplanar and inside and shortedge <= thick * threshold:
                            vupperob.extend([one, two])
                            vlowerob.extend([one, two])
                            newinds1.append([lenvep + k, lenvep + k + 1])
                            newinds2.append([lenvep + k, lenvep + k + 1])
                            k += 2
                    del tree
                    for e in deledges1:
                        if e in newinds1:
                            newinds1.remove(e)
                    for e in deledges2:
                        if e in newinds2:
                            newinds2.remove(e)
                    if vupperob or vlowerob:
                        outeup.append(newinds2)
                        outelo.append(newinds1)
                        vupper.append(vupperob)
                        vlower.append(vlowerob)
                vupper = Vector_degenerate(vupper)
                vlower = Vector_degenerate(vlower)
                centers = Vector_degenerate([centers])

                if 'vert' in self.outputs:
                    if self.out_up_down == 'Up':
                        out = dataCorrect(vupper)
                    else:
                        out = dataCorrect(vlower)
                    self.outputs['vert'].sv_set(out)
                if 'edge' in self.outputs and self.outputs['edge'].links:
                    if self.out_up_down == 'Up':
                        self.outputs['edge'].sv_set(outeup)
                    else:
                        self.outputs['edge'].sv_set(outelo)
                if 'centers' in self.outputs and self.outputs['centers'].links:
                    self.outputs['centers'].sv_set(centers)
                print(self.name, 'is finishing')
示例#6
0
    def make_bevel(self, curve, bevel_verts, bevel_edges, bevel_faces, taper, steps):
        spline = self.build_spline(curve, self.bevel_mode, self.is_cyclic)

        t_values = np.linspace(0.0, 1.0, num = steps)
        if self.is_cyclic:
            t_values = t_values[:-1]
        if self.flip_curve:
            t_for_curve = 1.0 - t_values
        else:
            t_for_curve = t_values
        if self.flip_taper:
            t_for_taper = 1.0 - t_values
        else:
            t_for_taper = t_values

        spline_vertices = [Vector(v) for v in spline.eval(t_for_curve).tolist()]
        spline_tangents = [Vector(v) for v in spline.tangent(t_for_curve, h=self.tangent_precision).tolist()]
        taper_values = [self.get_taper_scale(v) for v in taper.eval(t_for_taper).tolist()]

        if bevel_faces:
            bevel_faces = ensure_nesting_level(bevel_faces, 2)
        if not bevel_edges and bevel_faces:
            bevel_edges = pols_edges([bevel_faces], True)[0]

        mesh = bmesh.new()
        prev_level_vertices = None
        first_level_vertices = None
        for spline_vertex, spline_tangent, taper_value in zip(spline_vertices, spline_tangents, taper_values):
            # Scaling and rotation matrix
            scale_x, scale_y = taper_value
            matrix = self.get_matrix(spline_tangent, scale_x, scale_y)
            level_vertices = []
            for bevel_vertex in bevel_verts:
                new_vertex = matrix @ Vector(bevel_vertex) + spline_vertex
                level_vertices.append(mesh.verts.new(new_vertex))
            if prev_level_vertices is not None:
                for i,j in bevel_edges:
                    v1 = prev_level_vertices[i]
                    v2 = level_vertices[i]
                    v3 = level_vertices[j]
                    v4 = prev_level_vertices[j]
                    mesh.faces.new([v4, v3, v2, v1])

            if first_level_vertices is None:
                first_level_vertices = level_vertices
            prev_level_vertices = level_vertices

        if not self.is_cyclic:
            if self.cap_start:
                if not bevel_faces:
                    mesh.faces.new(list(reversed(first_level_vertices)))
                else:
                    for face in bevel_faces:
                        cap = [first_level_vertices[i] for i in reversed(face)]
                        mesh.faces.new(cap)
            if self.cap_end and prev_level_vertices is not None:
                if not bevel_faces:
                    mesh.faces.new(prev_level_vertices)
                else:
                    for face in bevel_faces:
                        cap = [prev_level_vertices[i] for i in face]
                        mesh.faces.new(cap)
        else:
            for i,j in bevel_edges:
                v1 = first_level_vertices[i]
                v2 = prev_level_vertices[i]
                v3 = prev_level_vertices[j]
                v4 = first_level_vertices[j]
                mesh.faces.new([v1, v2, v3, v4])

        mesh.verts.index_update()
        mesh.verts.ensure_lookup_table()
        mesh.faces.index_update()
        mesh.edges.index_update()

        return mesh
示例#7
0
    def process(self):

        if 'vecLine' in self.inputs and \
                'vecPlane' in self.inputs and \
                'edgPlane' in self.inputs:
            print(self.name, 'is starting')
            if self.inputs['vecLine'].links and \
                    self.inputs['vecPlane'].links and \
                    self.inputs['edgPlane'].links:
                if self.bindCircle:
                    circle = [ (Vector((sin(radians(i)),cos(radians(i)),0))*self.circle_rad)/4 \
                              for i in range(0,360,30) ]
                vec = self.inputs['vecLine'].sv_get()
                vecplan = self.inputs['vecPlane'].sv_get()
                edgplan = self.inputs['edgPlane'].sv_get()
                if len(edgplan[0][0]) > 2:
                    edgplan = pols_edges(edgplan)
                thick = self.inputs['thick'].sv_get()[0][0]
                threshold_coplanar = 0.005
                sinuso60 = 0.8660254037844386
                sinuso60_minus = 0.133974596
                sinuso30 = 0.5
                sinuso45 = 0.7071067811865475
                thick_2 = thick/2
                thick_3 = thick/3
                thick_6 = thick/6
                threshold = self.threshold
                if 'vecContr' in self.inputs and self.inputs['vecContr'].links:
                    vecont = self.inputs['vecContr'].sv_get()
                    #edgcont = self.inputs['edgContr'].sv_get()
                    vec_cont = Vector_generate(vecont)
                    loc_cont = [ [ i[0] ] for i in vec_cont ]
                    norm_cont = [ [ NM(i[0],i[len(i)//2], i[-1]) ] for i in vec_cont ] # довести до ума
                else:
                    vec_cont = []
                if 'vecTube' in self.inputs and self.inputs['vecTube'].links:
                    vectube = self.inputs['vecTube'].sv_get()
                    vec_tube = Vector_generate(vectube)
                    tube_radius = self.inputs['radTube'].sv_get()[0][0]
                    circle_tube = [ (Vector((sin(radians(i)),cos(radians(i)),0))*tube_radius) \
                              for i in range(0,360,15) ]
                else:
                    vec_tube = []
                outeup = []
                outelo = []
                vupper = []
                vlower = []
                centers = []
                vec_ = Vector_generate(vec)
                vecplan_ = Vector_generate(vecplan)
                for centersver, vecp, edgp in zip(vecplan,vecplan_,edgplan):
                    tubes_flag_bed_solution_i_know = False
                    newinds1 = edgp.copy()
                    newinds2 = edgp.copy()
                    vupperob = vecp.copy()
                    vlowerob = vecp.copy()
                    deledges1 = []
                    deledges2 = []
                    # to define bounds
                    x = [i[0] for i in vecp]
                    y = [i[1] for i in vecp]
                    z = [i[2] for i in vecp]
                    m1x,m2x,m1y,m2y,m1z,m2z = max(x), min(x), max(y), min(y), max(z), min(z)
                    l = Vector((sum(x)/len(x),sum(y)/len(y),sum(z)/len(z)))
                    n_select = [vecp[0],vecp[len(vecp)//2], vecp[-1]] # довести до ума
                    n_select.sort(key=lambda x: sum(x[:]), reverse=False)
                    n_ = NM(n_select[0],n_select[1],n_select[2])
                    n_.normalize()
                    # а виновта ли нормаль?
                    if n_[0] < 0:
                        n = n_ * -1
                    else:
                        n = n_
                    cen = [sum(i) for i in zip(*centersver)]
                    centers.append(Vector(cen)/len(centersver))
                    k = 0
                    lenvep = len(vecp)
                    # KDtree collections closest to join edges to sockets
                    tree = KDT.KDTree(lenvep)
                    for i,v in enumerate(vecp):
                        tree.insert(v,i)
                    tree.balance()
                    # vertical edges iterations
                    # every edge is object - two points, one edge
                    for v in vec_:
                        if not v: continue
                        # sort vertices by Z value
                        # find two vertices - one lower, two upper
                        vlist = [v[0],v[1]]
                        vlist.sort(key=lambda x: x[2], reverse=False)
                        # flip if coplanar to enemy plane
                        # flip plane coplanar
                        if vec_cont:
                            fliped = self.get_coplanar(v[0], loc_cont,norm_cont, vec_cont)
                        else:
                            fliped = False
                        shortedge = (vlist[1]-vlist[0]).length
                        if fliped:
                            two, one = vlist
                        else:
                            one, two = vlist
                        # coplanar to owner
                        cop = abs(D2P(one,l,n))
                        # defining bounds
                        inside = one[0]<m1x and one[0]>m2x and one[1]<m1y and one[1]>m2y \
                                 and one[2]<=m1z and one[2]>=m2z
                        # if in bounds and coplanar do:
                        #print(self.name,l, cop, inside)
                        if cop < threshold_coplanar and inside and shortedge > thick*threshold:
                            '''
                            huge calculations. if we can reduce...
                            '''
                            # find shift for thickness in sockets
                            diry = two - one
                            diry.normalize()
                            # solution for vertical wafel - cool but not in diagonal case
                            # angle = radians(degrees(atan(n.y/n.x))+90)
                            dirx_ = self.rotation_on_axis(diry, n, radians(90))
                            dirx = dirx_*thick_2
                            # вектор, индекс, расстояние
                            # запоминаем порядок находим какие удалить рёбра
                            # делаем выборку левая-правая точка
                            nearv_1, near_1 = tree.find(one)[:2]
                            nearv_2, near_2 = tree.find(two)[:2]
                            # indexes of two nearest points
                            # удалить рёбра что мешают спать заодно
                            en_0, en_1, de1 = self.calc_indexes(edgp, near_1)
                            deledges1.extend(de1)
                            en_2, en_3, de2 = self.calc_indexes(edgp, near_2)
                            deledges2.extend(de2)
                            # print(vecp, one, dirx, en_0, en_1)
                            # left-right indexes and vectors
                            # с учётом интерполяций по высоте
                            l1, r1, lz1, rz1 = \
                                    self.calc_leftright(vecp, one, dirx, en_0, en_1, thick_2, diry)
                            l2, r2, lz2, rz2 = \
                                    self.calc_leftright(vecp, two, dirx, en_2, en_3, thick_2, diry)
                            # print(left2, right2, l2, r2, lz2, rz2)
                            # средняя точка и её смещение по толщине материала
                            three = (one-two)/2 + two

                            # rounded section
                            if self.rounded:
                                '''рёбра'''
                                # пазы формируем независимо от верх низ

                                outeob1 = [[lenvep+k+8,lenvep+k],[lenvep+k+1,lenvep+k+2],
                                          [lenvep+k+2,lenvep+k+3],[lenvep+k+3,lenvep+k+4],
                                          [lenvep+k+4,lenvep+k+5],[lenvep+k+5,lenvep+k+6],
                                          [lenvep+k+6,lenvep+k+7],[lenvep+k+7,lenvep+k+8],
                                          [lenvep+k+9,lenvep+k+1]]

                                outeob2 = [[lenvep+k,lenvep+k+1],[lenvep+k+1,lenvep+k+2],
                                          [lenvep+k+2,lenvep+k+3],[lenvep+k+3,lenvep+k+4],
                                          [lenvep+k+4,lenvep+k+5],[lenvep+k+5,lenvep+k+6],
                                          [lenvep+k+6,lenvep+k+7],[lenvep+k+7,lenvep+k+8],
                                          [lenvep+k+8,lenvep+k+9]]
                                # наполнение списков lenvep = length(vecp)
                                newinds1.extend([[l1, lenvep+k], [lenvep+k+9, r1]])
                                newinds2.extend([[l2, lenvep+k+9], [lenvep+k, r2]])
                                '''Вектора'''
                                round1 = diry*thick_3
                                round2 = diry*thick_3*sinuso30
                                round2_= dirx/3 + dirx*(2*sinuso60/3)
                                round3 = diry*thick_3*sinuso60_minus
                                round3_= dirx/3 + dirx*(2*sinuso30/3)
                                round4 = dirx/3
                                vupperob.extend([lz2,
                                                 three+round1-dirx, three+round2-round2_,
                                                 three+round3-round3_, three-round4,
                                                 three+round4, three+round3+round3_,
                                                 three+round2+round2_, three+round1+dirx,
                                                 rz2])
                                vlowerob.extend([rz1,
                                                 three-round1-dirx, three-round2-round2_,
                                                 three-round3-round3_, three-round4,
                                                 three+round4, three-round3+round3_,
                                                 three-round2+round2_, three-round1+dirx,
                                                 lz1])
                                k += 10

                            # streight section
                            else:
                                '''рёбра'''
                                # пазы формируем независимо от верх низ
                                outeob1 = [[lenvep+k,lenvep+k+1],[lenvep+k+1,lenvep+k+2],[lenvep+k+2,lenvep+k+3]]
                                outeob2 = [[lenvep+k,lenvep+k+1],[lenvep+k+1,lenvep+k+2],[lenvep+k+2,lenvep+k+3]]
                                # наполнение списков lenvep = length(vecp)
                                newinds1.extend([[l1, lenvep+k], [lenvep+k+3, r1]])
                                newinds2.extend([[l2, lenvep+k+3], [lenvep+k, r2]])
                                '''Вектора'''
                                vupperob.extend([lz2, three-dirx,
                                                 three+dirx, rz2])
                                vlowerob.extend([rz1, three+dirx,
                                                 three-dirx, lz1])
                                k += 4
                            newinds1.extend(outeob1)
                            newinds2.extend(outeob2)

                            # circles to bing panels section
                            if self.bindCircle:
                                CP = self.circl_place
                                if CP == 'Midl':
                                    crcl_cntr = IL2P(one, two, Vector((0,0,0)), Vector((0,0,-1)))
                                elif CP == 'Up' and not fliped:
                                    crcl_cntr = two - diry*self.circle_rad*2
                                elif CP == 'Down' and not fliped:
                                    crcl_cntr = one + diry*self.circle_rad*2
                                elif CP == 'Up' and fliped:
                                    crcl_cntr = one + diry*self.circle_rad*2
                                elif CP == 'Down' and fliped:
                                    crcl_cntr = two - diry*self.circle_rad*2
                                # forgot howto 'else' in line iteration?
                                outeob1 = [ [lenvep+k+i,lenvep+k+i+1] for i in range(0,11) ]
                                outeob1.append([lenvep+k,lenvep+k+11])
                                outeob2 = [ [lenvep+k+i,lenvep+k+i+1] for i in range(12,23) ]
                                outeob2.append([lenvep+k+12,lenvep+k+23])
                                newinds1.extend(outeob1+outeob2)
                                newinds2.extend(outeob1+outeob2)
                                mat_rot_cir = n.rotation_difference(Vector((0,0,1))).to_matrix().to_4x4()
                                circle_to_add_1 = [vecir*mat_rot_cir+crcl_cntr+ \
                                        dirx_*self.circle_rad for vecir in circle ]
                                circle_to_add_2 = [vecir*mat_rot_cir+crcl_cntr- \
                                        dirx_*self.circle_rad for vecir in circle ]
                                vupperob.extend(circle_to_add_1+circle_to_add_2)
                                vlowerob.extend(circle_to_add_1+circle_to_add_2)
                                k += 24

                            # TUBE section
                            if vec_tube and not tubes_flag_bed_solution_i_know:
                                for v in vec_tube:
                                    tubeverlength = len(v)
                                    if tubeverlength == 2:
                                        crcl_cntr = IL2P(v[0], v[1], l, n)
                                        if crcl_cntr:
                                            inside = crcl_cntr[0]<m1x and crcl_cntr[0]>m2x and crcl_cntr[1]<m1y \
                                                 and crcl_cntr[1]>m2y and crcl_cntr[2]<=m1z and crcl_cntr[2]>=m2z
                                            if inside:
                                                outeob = [ [lenvep+k+i,lenvep+k+i+1] for i in range(0,23) ]
                                                outeob.append([lenvep+k,lenvep+k+23])
                                                newinds1.extend(outeob)
                                                newinds2.extend(outeob)
                                                mat_rot_cir = n.rotation_difference(Vector((0,0,1))).to_matrix().to_4x4()
                                                circle_to_add = [ vecir*mat_rot_cir+crcl_cntr for vecir in circle_tube ]
                                                vupperob.extend(circle_to_add)
                                                vlowerob.extend(circle_to_add)
                                                k += 24
                                    else:
                                        tubeshift = tubeverlength//2
                                        crcl_cntr = IL2P(v[0], v[tubeshift], l, n)
                                        if crcl_cntr:
                                            inside = crcl_cntr[0]<m1x and crcl_cntr[0]>m2x and crcl_cntr[1]<m1y \
                                                 and crcl_cntr[1]>m2y and crcl_cntr[2]<=m1z and crcl_cntr[2]>=m2z
                                            if inside:
                                                outeob = [ [lenvep+k+i,lenvep+k+i+1] for i in range(tubeshift-1) ]
                                                outeob.append([lenvep+k,lenvep+k+tubeshift-1])
                                                newinds1.extend(outeob)
                                                newinds2.extend(outeob)
                                                for tubevert in range(tubeshift):
                                                    tubevert_out = IL2P(v[tubevert], v[tubevert+tubeshift], l, n)
                                                    vupperob.append(tubevert_out)
                                                    vlowerob.append(tubevert_out)
                                                k += tubeshift

                                tubes_flag_bed_solution_i_know = True
                        elif cop < threshold_coplanar and inside and shortedge <= thick*threshold:
                            vupperob.extend([one,two])
                            vlowerob.extend([one,two])
                            newinds1.append([lenvep+k,lenvep+k+1])
                            newinds2.append([lenvep+k,lenvep+k+1])
                            k += 2
                    del tree
                    for e in deledges1:
                        if e in newinds1:
                            newinds1.remove(e)
                    for e in deledges2:
                        if e in newinds2:
                            newinds2.remove(e)
                    if vupperob or vlowerob:
                        outeup.append(newinds2)
                        outelo.append(newinds1)
                        vupper.append(vupperob)
                        vlower.append(vlowerob)
                vupper = Vector_degenerate(vupper)
                vlower = Vector_degenerate(vlower)
                centers = Vector_degenerate([centers])

                if 'vert' in self.outputs:
                    if self.out_up_down == 'Up':
                        out = dataCorrect(vupper)
                    else:
                        out = dataCorrect(vlower)
                    self.outputs['vert'].sv_set(out)
                if 'edge' in self.outputs and self.outputs['edge'].links:
                    if self.out_up_down == 'Up':
                        self.outputs['edge'].sv_set(outeup)
                    else:
                        self.outputs['edge'].sv_set(outelo)
                if 'centers' in self.outputs and self.outputs['centers'].links:
                    self.outputs['centers'].sv_set(centers)
                print(self.name, 'is finishing')