kopia lustrzana https://github.com/vilemduha/blendercam
156 wiersze
4.1 KiB
Python
156 wiersze
4.1 KiB
Python
import bpy
|
|
from cam import utils, simple,polygon_utils_cam
|
|
import Polygon
|
|
import random
|
|
#this algorithm takes all selected curves,
|
|
#converts them to polygons,
|
|
# offsets them by the pre-set margin
|
|
#then chooses a starting location possibly inside the allready occupied area and moves and rotates the polygon out of the occupied area
|
|
#if one or more positions are found where the poly doesn't overlap, it is placed and added to the occupied area - allpoly
|
|
#this algorithm is very slow and STUPID, a collision algorithm would be much much faster...
|
|
|
|
def packCurves():
|
|
packsettings=bpy.context.scene.cam_pack
|
|
|
|
sheetsizex=packsettings.sheet_x
|
|
sheetsizey=packsettings.sheet_y
|
|
direction=packsettings.sheet_fill_direction
|
|
distance=packsettings.distance
|
|
rotate = packsettings.rotate
|
|
|
|
polyfield=[]#in this, position, rotation, and actual poly will be stored.
|
|
for ob in bpy.context.selected_objects:
|
|
allchunks=[]
|
|
simple.activate(ob)
|
|
bpy.ops.object.make_single_user(type='SELECTED_OBJECTS')
|
|
bpy.ops.object.origin_set(type='ORIGIN_GEOMETRY')
|
|
z=ob.location.z
|
|
bpy.ops.object.location_clear()
|
|
bpy.ops.object.rotation_clear()
|
|
|
|
chunks=utils.curveToChunks(ob)
|
|
npolys=utils.chunksToPolys(chunks)
|
|
#add all polys in silh to one poly
|
|
poly=Polygon.Polygon()
|
|
for p in npolys:
|
|
poly+=p
|
|
poly.simplify()
|
|
poly=polygon_utils_cam.outlinePoly(poly,distance/1.5,8,True,.003,offset = True)
|
|
polyfield.append([[0,0],0.0,poly,ob,z])
|
|
random.shuffle(polyfield)
|
|
#primitive layout here:
|
|
allpoly=Polygon.Polygon()#main collision poly.
|
|
|
|
|
|
shift=0.0015#one milimeter by now.
|
|
rotchange=.3123456#in radians
|
|
|
|
xmin,xmax,ymin,ymax=polyfield[0][2].boundingBox()
|
|
if direction=='X':
|
|
mindist=-xmin
|
|
else:
|
|
mindist=-ymin
|
|
i=0
|
|
for pf in polyfield:
|
|
print(i)
|
|
rot=0
|
|
porig=pf[2]
|
|
placed=False
|
|
xmin,xmax,ymin,ymax=p.boundingBox()
|
|
#p.shift(-xmin,-ymin)
|
|
if direction=='X':
|
|
x=mindist
|
|
y=-ymin
|
|
if direction=='Y':
|
|
x=-xmin
|
|
y=mindist
|
|
|
|
iter=0
|
|
best=None
|
|
hits=0
|
|
besthit=None
|
|
while not placed:
|
|
|
|
#swap x and y, and add to x
|
|
#print(x,y)
|
|
#p=Polygon.Polygon(porig)
|
|
p=porig
|
|
p.rotate(rot,0,0)
|
|
p.shift(x,y)
|
|
|
|
xmin,xmax,ymin,ymax=p.boundingBox()
|
|
if xmin>0 and ymin>0 and ((direction=='Y' and xmax<sheetsizex) or (direction=='X' and ymax<sheetsizey)) and not p.overlaps(allpoly):
|
|
#we do more good solutions, choose best out of them:
|
|
hits+=1
|
|
if best==None:
|
|
best=[x,y,rot,xmax,ymax]
|
|
besthit=hits
|
|
if direction=='X':
|
|
if xmax<best[3]:
|
|
best=[x,y,rot,xmax,ymax]
|
|
besthit=hits
|
|
elif ymax<best[4]:
|
|
best=[x,y,rot,xmax,ymax]
|
|
besthit=hits
|
|
|
|
|
|
|
|
|
|
p.shift(-x,-y)
|
|
p.rotate(-rot,0,0)
|
|
|
|
if hits>=1 or (iter>10000 and hits>0):#here was originally more, but 90% of best solutions are still 1
|
|
placed=True
|
|
pf[3].location.x=best[0]
|
|
pf[3].location.y=best[1]
|
|
pf[3].location.z=pf[4]
|
|
pf[3].rotation_euler.z=best[2]
|
|
|
|
|
|
pf[3].select=True
|
|
|
|
#print(mindist)
|
|
mindist=mindist-0.5*(xmax-xmin)
|
|
#print(mindist)
|
|
#print(iter)
|
|
|
|
#reset polygon to best position here:
|
|
p.rotate(best[2],0,0)
|
|
p.shift(best[0],best[1])
|
|
|
|
#polygon_utils_cam.polyToMesh(p,0.1)#debug visualisation
|
|
keep=[]
|
|
|
|
npoly=Polygon.Polygon()
|
|
for ci in range(0,len(allpoly)):
|
|
cminx,cmaxx,cminy,cmaxy=allpoly.boundingBox(ci)
|
|
if direction=='X' and cmaxx>mindist-.1:
|
|
npoly.addContour(allpoly[ci])
|
|
if direction=='Y' and cmaxy>mindist-.1:
|
|
npoly.addContour(allpoly[ci])
|
|
|
|
allpoly=npoly
|
|
#polygon_utils_cam.polyToMesh(allpoly,0.1)#debug visualisation
|
|
|
|
for c in p:
|
|
allpoly.addContour(c)
|
|
#cleanup allpoly
|
|
print(iter,hits,besthit)
|
|
if not placed:
|
|
if direction=='Y':
|
|
x+=shift
|
|
mindist=y
|
|
if (xmax+shift>sheetsizex):
|
|
x=x-xmin
|
|
y+=shift
|
|
if direction=='X':
|
|
y+=shift
|
|
mindist=x
|
|
if (ymax+shift>sheetsizey):
|
|
y=y-ymin
|
|
x+=shift
|
|
if rotate: rot+=rotchange
|
|
iter+=1
|
|
i+=1
|
|
|