kopia lustrzana https://github.com/vilemduha/blendercam
254 wiersze
6.6 KiB
Python
254 wiersze
6.6 KiB
Python
#very simple slicing for 3d meshes, usefull for plywood cutting.
|
|
from cam import chunk, polygon_utils_cam
|
|
import bpy
|
|
|
|
def getSlices(ob,slice_distance):
|
|
'''function for slicing a mesh. It is now not used, but can be used for e.g. lasercutting from sheets a 3d model in the future.'''
|
|
|
|
layer_thickness=slice_distance
|
|
edges=[]
|
|
verts = []
|
|
i=0
|
|
slices=[]#slice format is [length, minx,miny, maxx, maxy,verts,z]
|
|
firstslice=None
|
|
lastslice=None
|
|
maxzt = -100000000000000000000000000
|
|
minzt = 1000000000000000000000000000
|
|
#progress('slicing object')
|
|
m=ob.to_mesh(scene=bpy.context.scene, apply_modifiers=True, settings='PREVIEW')
|
|
#d={}#!
|
|
for p in m.polygons:
|
|
#a=i*50+12
|
|
|
|
v1=m.vertices[p.vertices[0]].co
|
|
v2=m.vertices[p.vertices[1]].co
|
|
v3=m.vertices[p.vertices[2]].co
|
|
if len(p.vertices)==3:
|
|
tris=[[v1,v2,v3]]
|
|
else:
|
|
v4=m.vertices[p.vertices[3]].co
|
|
tris=[[v1,v2,v3],[v3,v4,v1]]
|
|
|
|
for v in tris:
|
|
#print(v)
|
|
minz=min(v[0].z,v[1].z,v[2].z)
|
|
maxz=max(v[0].z,v[1].z,v[2].z)
|
|
|
|
|
|
t=layer_thickness
|
|
|
|
start=int(minz // t)
|
|
end=int(maxz // t +2)
|
|
if firstslice==None:
|
|
firstslice = start
|
|
lastslice = end
|
|
#print start, end
|
|
for s in range(firstslice,lastslice):
|
|
sz= s*t
|
|
slices.append([0.0,100000000000.0,100000000000.0,-100000000000.0,-100000000000.0,[],sz])
|
|
|
|
if start<firstslice:
|
|
ns=[]
|
|
ind=0
|
|
for s in range(start, firstslice):
|
|
sz=s*t
|
|
slices.insert(ind,[0.0,100000000000.0,100000000000.0,-100000000000.0,-100000000000.0,[],sz])
|
|
ind+=1
|
|
firstslice=start
|
|
if end>lastslice:
|
|
for s in range(lastslice,end):
|
|
sz=s*t
|
|
slices.append([0.0,100000000000.0,100000000000.0,-100000000000.0,-100000000000.0,[],sz])
|
|
#i+=1
|
|
lastslice=end
|
|
|
|
|
|
for s in range(start,end):
|
|
si=s-firstslice
|
|
sc=slices[si]
|
|
sz = sc[6]#s * t
|
|
|
|
over=[]
|
|
under=[]
|
|
onslice=[]
|
|
iv=[]
|
|
for vert in v:
|
|
if vert[2]>sz:
|
|
over.append(vert)
|
|
elif vert[2]<sz:
|
|
under.append(vert)
|
|
elif vert[2]==sz:
|
|
onslice.append(vert)
|
|
if len(onslice)==1:
|
|
#pass
|
|
iv.append((onslice[0][0],onslice[0][1],sz))
|
|
#iv[-1]=(int(1000000000*iv[-1][0])/1000000000,int(1000000000*iv[-1][1])/1000000000,int(1000000000*iv[-1][2])/1000000000)
|
|
elif len(onslice)==2:
|
|
#if p.normal.z<1.0:
|
|
#iv.extend([onslice[0],onslice[1]])
|
|
iv.append((onslice[0][0],onslice[0][1],sz))
|
|
iv.append((onslice[1][0],onslice[1][1],sz))
|
|
#iv[-2]=(int(1000000000*iv[-2][0])/1000000000,int(1000000000*iv[-2][1])/1000000000,int(1000000000*iv[-2][2])/1000000000)
|
|
#iv[-1]=(int(1000000000*iv[-1][0])/1000000000,int(1000000000*iv[-1][1])/1000000000,int(1000000000*iv[-1][2])/1000000000)
|
|
elif len(onslice)==3:
|
|
print('flat face')#,v)
|
|
for v1 in under:
|
|
for v2 in over:
|
|
coef=(sz-v1[2])/(v2[2]-v1[2])
|
|
x=v1[0]+(v2[0]-v1[0])*coef
|
|
y=v1[1]+(v2[1]-v1[1])*coef
|
|
z=sz#!
|
|
#iv.append((int(100000000*x)/100000000,int(100000000*y)/100000000,int(100000000*z)/100000000))#! z not needed!
|
|
iv.append((x,y,sz))
|
|
if len(iv)==2:
|
|
#d{iv[0]}
|
|
#sc=slices[si]
|
|
#print(iv)
|
|
sc[5].append(iv[0])
|
|
sc[5].append(iv[1])
|
|
|
|
else:
|
|
pass
|
|
# print('strange count of layer faces',iv)
|
|
|
|
|
|
|
|
|
|
if i % 10000 == 0:
|
|
print ('parsed faces', i, firstslice, lastslice, len(slices))
|
|
i+=1
|
|
#sliceobs=[]
|
|
print('sorting slices')
|
|
slicechunks=[]
|
|
obs=[]
|
|
for sc in slices:
|
|
if len(sc[5])>0:
|
|
i=0
|
|
chi=0
|
|
|
|
edges=[]
|
|
z=sc[5][0][2]
|
|
|
|
slicechunks.append([])
|
|
|
|
|
|
d={}
|
|
for i in range(0,len(sc[5])):
|
|
d[sc[5][i]]=[]
|
|
for i in range(0,int(len(sc[5])/2)):
|
|
verts1=d[sc[5][i*2]]
|
|
verts2=d[sc[5][i*2+1]]
|
|
|
|
if len(verts1)==2:
|
|
if verts1[0]==verts1[1]:
|
|
verts1.pop()
|
|
if len(verts1)<2:
|
|
verts1.append(sc[5][i*2+1])
|
|
|
|
if len(verts2)==2:
|
|
if verts2[0]==verts2[1]:
|
|
verts2.pop()
|
|
|
|
if len(verts2)<2:
|
|
verts2.append(sc[5][i*2])
|
|
|
|
|
|
|
|
ch=[sc[5][0],sc[5][1]]#first and his reference
|
|
|
|
d.pop(ch[0])
|
|
|
|
i=0
|
|
verts=[123]
|
|
|
|
while len(d)>0 and i<200000:# and verts!=[]:
|
|
verts=d.get(ch[-1],[])
|
|
if len(verts)<=1:
|
|
if len(ch)>2:
|
|
slicechunks[-1].append(ch)
|
|
v1=d.popitem()
|
|
ch=[v1[0],v1[1][0]]
|
|
|
|
elif len(verts)>2:
|
|
pass;
|
|
i+=1
|
|
|
|
|
|
else:
|
|
done=False
|
|
for v in verts:
|
|
|
|
if not done:
|
|
if v[0]==ch[-2][0] and v[1]==ch[-2][1]:# and v[2]==ch[-2][2]:
|
|
pass
|
|
else:
|
|
#print(v,ch[-2])
|
|
ch.append(v)
|
|
|
|
d.pop(ch[-2])
|
|
done=True
|
|
if v[0]==ch[0][0] and v[1]==ch[0][1]:# and v[2]==ch[0][2]:
|
|
slicechunks[-1].append(ch)
|
|
print('closed')
|
|
#d.pop(ch[-1])
|
|
if len(d)>0:
|
|
v1=d.popitem()
|
|
ch=[v1[0],v1[1][0]]
|
|
i+=1
|
|
|
|
slicechunks[-1].append(ch)################3this might be a bug!!!!
|
|
#print(len(slicechunks))
|
|
return slicechunks
|
|
|
|
|
|
|
|
def sliceObject(ob):
|
|
settings=bpy.context.scene.cam_slice
|
|
|
|
layers = getSlices(ob, settings.slice_distance)
|
|
#print(layers)
|
|
sliceobjects=[]
|
|
i=1
|
|
for layer in layers:
|
|
pi=1
|
|
layerpolys=[]
|
|
for slicechunk in layer:
|
|
#these functions here are totally useless conversions, could generate slices more directly, just lazy to write new functions
|
|
#print (slicechunk)
|
|
nchp=[]
|
|
for p in slicechunk:
|
|
nchp.append((p[0],p[1]))
|
|
#print(slicechunk)
|
|
ch = chunk.camPathChunk(nchp)
|
|
|
|
#print(ch)
|
|
pslices=chunk.chunksToShapely([ch])
|
|
#print(pslices)
|
|
for pslice in pslices:
|
|
p = pslice#-p1
|
|
#print(p)
|
|
text = '%i - %i' % (i,pi)
|
|
bpy.ops.object.text_add()
|
|
textob = bpy.context.active_object
|
|
textob.data.size = 0.0035
|
|
textob.data.body = text
|
|
textob.data.align = 'CENTER'
|
|
|
|
#print(len(ch.points))
|
|
sliceobject = polygon_utils_cam.shapelyToCurve('slice',p,slicechunk[0][2])
|
|
textob.location=(0,0,0)
|
|
|
|
textob.parent=sliceobject
|
|
|
|
sliceobject.data.extrude = settings.slice_distance/2
|
|
sliceobject.data.dimensions = '2D'
|
|
sliceobjects.append(sliceobject)
|
|
pi+=1
|
|
#FIXME: the polys on same layer which are hollow are not joined by now, this prevents doing hollow surfaces :(
|
|
#for p in layerpolys:
|
|
#for p1 in layerpolys:
|
|
|
|
i+=1
|
|
for o in sliceobjects:
|
|
o.select=True
|
|
bpy.ops.group.create(name='slices') |