forked from nortikin/sverchok
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathnode_Bisect.py
135 lines (102 loc) · 4.86 KB
/
node_Bisect.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
import bmesh, mathutils
from mathutils import Vector, Matrix
from node_s import *
from util import *
from math import *
import copy
# based on CrossSectionNode
# but using python bmesh code for driving
# by Linus Yng
def bisect(cut_me_vertices, cut_me_edges, pp, pno, outer, inner,fill):
if not cut_me_edges or not cut_me_vertices:
return False
cut_me_polygons=[]
if len(cut_me_edges[0])>2:
cut_me_polygons = cut_me_edges.copy()
cut_me_edges=[]
bm=bmesh.new()
bm_verts =[ bm.verts.new(v) for v in cut_me_vertices]
if cut_me_edges:
for edge in cut_me_edges:
bm.edges.new((bm_verts[edge[0]],bm_verts[edge[1]]))
else:
for face in cut_me_polygons:
bm.faces.new([bm_verts[i] for i in face])
geom_in = bm.verts[:] +bm.edges[:]+bm.faces[:]
res=bmesh.ops.bisect_plane(bm,geom=geom_in, dist=0.00001,
plane_co = pp, plane_no = pno, use_snap_center = False,
clear_outer= outer, clear_inner = inner)
# this needs work function with solid gemometry
if fill:
fres = bmesh.ops.edgenet_prepare(bm, edges=[e for e in res['geom_cut'] if isinstance(e,bmesh.types.BMEdge)])
bmesh.ops.edgeloop_fill(bm, edges = fres['edges'])
edges = []
faces = []
bm.verts.index_update()
bm.edges.index_update()
bm.faces.index_update()
for edge in bm.edges[:]:
edges.append([v.index for v in edge.verts[:]])
verts = [vert.co[:] for vert in bm.verts[:]]
for face in bm.faces:
faces.append([v.index for v in face.verts[:]])
bm.clear()
bm.free()
return (verts,edges,faces)
class SvBisectNode(Node, SverchCustomTreeNode):
bl_idname = 'SvBisectNode'
bl_label = 'Bisect'
bl_icon = 'OUTLINER_OB_EMPTY'
inner = bpy.props.BoolProperty(name='inner', description='clear inner', default=False, update=updateNode)
outer = bpy.props.BoolProperty(name='outer', description='clear outer', default=False, update=updateNode)
fill = bpy.props.BoolProperty(name='fill', description='Fill cuts', default=False, update=updateNode)
def init(self, context):
self.inputs.new('VerticesSocket', 'vertices', 'vertices')
self.inputs.new('StringsSocket', 'edg_pol', 'edg_pol')
self.inputs.new('MatrixSocket', 'cut_matrix', 'cut_matrix')
self.outputs.new('VerticesSocket', 'vertices', 'vertices')
self.outputs.new('StringsSocket', 'edges', 'edges')
self.outputs.new('StringsSocket', 'polygons', 'polygons')
def draw_buttons(self, context, layout):
layout.prop(self,'inner',text="Clear Inner")
layout.prop(self,'outer',text="Clear Outer")
layout.prop(self,'fill',text="Fill cuts")
def update(self):
if not ('vertices' in self.outputs and self.outputs['vertices'].links or \
'edges' in self.outputs and self.outputs['edges'].links and\
'polygons' in self.outputs and self.outputs['polygons'].links):
return
if 'vertices' in self.inputs and self.inputs['vertices'].links and \
'edg_pol' in self.inputs and self.inputs['edg_pol'].links and\
'cut_matrix' in self.inputs and self.inputs['cut_matrix'].links:
verts_ob = Vector_generate(SvGetSocketAnyType(self,self.inputs['vertices']))
edg_pols = SvGetSocketAnyType(self,self.inputs['edg_pol'])
cut_mats_ = SvGetSocketAnyType(self,self.inputs['cut_matrix'])
cut_mats = Matrix_generate(cut_mats_)
verts_out = []
edges_out = []
polys_out = []
for cut_mat in cut_mats:
pp = cut_mat.to_translation()
pno = Vector((0.0, 0.0, 1.0)) * cut_mat.to_3x3().transposed()
for obj in zip(verts_ob,edg_pols):
res = bisect(obj[0], obj[1], pp, pno, self.outer, self.inner,self.fill)
if not res:
return
verts_out.append(res[0])
edges_out.append(res[1])
polys_out.append(res[2])
if 'vertices' in self.outputs and self.outputs['vertices'].links:
SvSetSocketAnyType(self, 'vertices',verts_out)
if 'edges' in self.outputs and self.outputs['edges'].links:
SvSetSocketAnyType(self, 'edges',edges_out)
if 'polygons' in self.outputs and self.outputs['polygons'].links:
SvSetSocketAnyType(self, 'polygons', polys_out)
def update_socket(self, context):
self.update()
def register():
bpy.utils.register_class(SvBisectNode)
def unregister():
bpy.utils.unregister_class(SvBisectNode)
if __name__ == "__main__":
register()