kopia lustrzana https://github.com/vilemduha/blendercam
Revert "- little bug fixes and some code refactoring"
rodzic
a22ebc3094
commit
f8154f3386
|
@ -16,4 +16,4 @@ config/bookmarks.txt
|
|||
*.py
|
||||
config/recent-files.txt
|
||||
scripts/addons_contrib/add_mesh_rocks/add_mesh_rocks.xml
|
||||
scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/wood/rough_pine.bcm
|
||||
scripts/addons_contrib/online_mat_lib/material-library/bundled/cycles/wood/rough_pine.bcm
|
|
@ -31,7 +31,7 @@ from bpy.types import Menu, Operator, UIList, AddonPreferences
|
|||
|
||||
#from . import patterns
|
||||
#from . import chunk_operations
|
||||
from cam import ui, ops, utils, simple, polygon_utils_cam#, post_processors
|
||||
from cam import ui, ops,utils, simple,polygon_utils_cam#, post_processors
|
||||
import numpy
|
||||
import Polygon
|
||||
from bpy.app.handlers import persistent
|
||||
|
@ -85,7 +85,7 @@ class machineSettings(bpy.types.PropertyGroup):
|
|||
'''stores all data for machines'''
|
||||
#name = bpy.props.StringProperty(name="Machine Name", default="Machine")
|
||||
post_processor = EnumProperty(name='Post processor',
|
||||
items=(('ISO','Iso','this should export a standardized gcode'),('MACH3','Mach3','default mach3'),('EMC','EMC - LinuxCNC','default emc'),('GRBL','grbl','grbl on Arduino cnc shield'),('HEIDENHAIN','Heidenhain','heidenhain'),('TNC151','Heidenhain TNC151','Post Processor for the Heidenhain TNC151 machine'),('SIEGKX1','Sieg KX1','Sieg KX1'),('HM50','Hafco HM-50','Hafco HM-50'),('CENTROID','Centroid M40','Centroid M40'),('ANILAM','Anilam Crusader M','Anilam Crusader M'),('GRAVOS','Gravos','Gravos'),('WIN-PC','Win-PC','German CNC'),('SHOPBOT MTC','ShopBot MTC','ShopBot MTC'),('LYNX_OTTER_O','Lynx Otter o','Lynx Otter o')),
|
||||
items=(('ISO','Iso','this should export a standardized gcode'),('MACH3','Mach3','default mach3'),('EMC','EMC - LinuxCNC','default emc'),('HEIDENHAIN','Heidenhain','heidenhain'),('TNC151','Heidenhain TNC151','Post Processor for the Heidenhain TNC151 machine'),('SIEGKX1','Sieg KX1','Sieg KX1'),('HM50','Hafco HM-50','Hafco HM-50'),('CENTROID','Centroid M40','Centroid M40'),('ANILAM','Anilam Crusader M','Anilam Crusader M'),('GRAVOS','Gravos','Gravos'),('WIN-PC','Win-PC','German CNC'),('SHOPBOT MTC','ShopBot MTC','ShopBot MTC'),('LYNX_OTTER_O','Lynx Otter o','Lynx Otter o')),
|
||||
description='Post processor',
|
||||
default='MACH3')
|
||||
#units = EnumProperty(name='Units', items = (('IMPERIAL', ''))
|
||||
|
@ -447,7 +447,7 @@ class camOperation(bpy.types.PropertyGroup):
|
|||
plunge_angle = bpy.props.FloatProperty(name="Plunge angle", description="What angle is allready considered to plunge", default=math.pi/6, min=0, max=math.pi*0.5 , precision=0, subtype="ANGLE" , unit="ROTATION" , update = updateRest)
|
||||
spindle_rpm = FloatProperty(name="Spindle rpm", description="Spindle speed ", min=1000, max=60000, default=12000, update = updateChipload)
|
||||
#movement parallel_step_back
|
||||
movement_type = EnumProperty(name='Movement type',items=(('CONVENTIONAL','Conventional / Up milling', 'cutter rotates against the direction of the feed'),('CLIMB', 'Climb / Down milling', 'cutter rotates with the direction of the feed'),('MEANDER', 'Meander / Zig Zag' , 'cutting is done both with and against the rotation of the spindle') ),description='movement type', default='CLIMB', update = updateRest)
|
||||
movement_type = EnumProperty(name='Movement type',items=(('CONVENTIONAL','Conventional', 'a'),('CLIMB', 'Climb', 'a'),('MEANDER', 'Meander' , 'a') ),description='movement type', default='CLIMB', update = updateRest)
|
||||
spindle_rotation_direction = EnumProperty(name='Spindle rotation', items=(('CW','Clock wise', 'a'),('CCW', 'Counter clock wise', 'a')),description='Spindle rotation direction',default='CW', update = updateRest)
|
||||
free_movement_height = bpy.props.FloatProperty(name="Free movement height", default=0.01, min=0.0000, max=32,precision=PRECISION, unit="LENGTH", update = updateRest)
|
||||
movement_insideout = EnumProperty(name='Direction', items=(('INSIDEOUT','Inside out', 'a'),('OUTSIDEIN', 'Outside in', 'a')),description='approach to the piece',default='INSIDEOUT', update = updateRest)
|
||||
|
|
|
@ -1,287 +0,0 @@
|
|||
from . import nc
|
||||
from . import iso_modal
|
||||
import math
|
||||
import datetime
|
||||
import time
|
||||
|
||||
now = datetime.datetime.now()
|
||||
|
||||
class Creator(iso_modal.Creator):
|
||||
def __init__(self):
|
||||
iso_modal.Creator.__init__(self)
|
||||
self.absolute_flag = True
|
||||
self.prev_g91 = ''
|
||||
self.useCrc = False
|
||||
self.start_of_line = True
|
||||
|
||||
def write_blocknum(self):
|
||||
self.start_of_line = True
|
||||
|
||||
def SPACE(self):
|
||||
if self.start_of_line == True:
|
||||
self.start_of_line = False
|
||||
return ''
|
||||
else:
|
||||
return ' '
|
||||
|
||||
def PROGRAM_END(self): return ' '
|
||||
|
||||
############################################################################
|
||||
## Begin Program
|
||||
|
||||
|
||||
def program_begin(self, id, comment):
|
||||
if (self.useCrc == False):
|
||||
self.write( ('(Created with grbl post processor ' + str(now.strftime("%Y/%m/%d %H:%M")) + ')' + '\n') )
|
||||
else:
|
||||
self.write( ('(Created with grbl Cutter Radius Compensation post processor ' + str(now.strftime("%Y/%m/%d %H:%M")) + ')' + '\n') )
|
||||
|
||||
|
||||
|
||||
|
||||
############################################################################
|
||||
## Settings
|
||||
|
||||
def tool_defn(self, id, name='', radius=None, length=None, gradient=None):
|
||||
pass
|
||||
|
||||
def tool_change(self, id):
|
||||
pass
|
||||
|
||||
def comment(self, text):
|
||||
self.write_blocknum()
|
||||
self.write((self.COMMENT(text) + '\n'))
|
||||
|
||||
# This is the coordinate system we're using. G54->G59, G59.1, G59.2, G59.3
|
||||
# These are selected by values from 1 to 9 inclusive.
|
||||
def workplane(self, id):
|
||||
if ((id >= 1) and (id <= 6)):
|
||||
self.write_blocknum()
|
||||
self.write( (self.WORKPLANE() % (id + self.WORKPLANE_BASE())) + '\t (Select Relative Coordinate System)\n')
|
||||
if ((id >= 7) and (id <= 9)):
|
||||
self.write_blocknum()
|
||||
self.write( ((self.WORKPLANE() % (6 + self.WORKPLANE_BASE())) + ('.%i' % (id - 6))) + '\t (Select Relative Coordinate System)\n')
|
||||
|
||||
|
||||
############################################################################
|
||||
## Moves
|
||||
|
||||
|
||||
############################################################################
|
||||
## Probe routines
|
||||
def report_probe_results(self, x1=None, y1=None, z1=None, x2=None, y2=None, z2=None, x3=None, y3=None, z3=None, x4=None, y4=None, z4=None, x5=None, y5=None, z5=None, x6=None, y6=None, z6=None, xml_file_name=None ):
|
||||
if (xml_file_name != None):
|
||||
self.comment('Generate an XML document describing the probed coordinates found');
|
||||
self.write_blocknum()
|
||||
self.write('(LOGOPEN,')
|
||||
self.write(xml_file_name)
|
||||
self.write(')\n')
|
||||
|
||||
self.write_blocknum()
|
||||
self.write('(LOG,<POINTS>)\n')
|
||||
|
||||
if ((x1 != None) or (y1 != None) or (z1 != None)):
|
||||
self.write_blocknum()
|
||||
self.write('(LOG,<POINT>)\n')
|
||||
|
||||
if (x1 != None):
|
||||
self.write_blocknum()
|
||||
self.write('#<_value>=[' + x1 + ']\n')
|
||||
self.write_blocknum()
|
||||
self.write('(LOG,<X>#<_value></X>)\n')
|
||||
|
||||
if (y1 != None):
|
||||
self.write_blocknum()
|
||||
self.write('#<_value>=[' + y1 + ']\n')
|
||||
self.write_blocknum()
|
||||
self.write('(LOG,<Y>#<_value></Y>)\n')
|
||||
|
||||
if (z1 != None):
|
||||
self.write_blocknum()
|
||||
self.write('#<_value>=[' + z1 + ']\n')
|
||||
self.write_blocknum()
|
||||
self.write('(LOG,<Z>#<_value></Z>)\n')
|
||||
|
||||
if ((x1 != None) or (y1 != None) or (z1 != None)):
|
||||
self.write_blocknum()
|
||||
self.write('(LOG,</POINT>)\n')
|
||||
|
||||
if ((x2 != None) or (y2 != None) or (z2 != None)):
|
||||
self.write_blocknum()
|
||||
self.write('(LOG,<POINT>)\n')
|
||||
|
||||
if (x2 != None):
|
||||
self.write_blocknum()
|
||||
self.write('#<_value>=[' + x2 + ']\n')
|
||||
self.write_blocknum()
|
||||
self.write('(LOG,<X>#<_value></X>)\n')
|
||||
|
||||
if (y2 != None):
|
||||
self.write_blocknum()
|
||||
self.write('#<_value>=[' + y2 + ']\n')
|
||||
self.write_blocknum()
|
||||
self.write('(LOG,<Y>#<_value></Y>)\n')
|
||||
|
||||
if (z2 != None):
|
||||
self.write_blocknum()
|
||||
self.write('#<_value>=[' + z2 + ']\n')
|
||||
self.write_blocknum()
|
||||
self.write('(LOG,<Z>#<_value></Z>)\n')
|
||||
|
||||
if ((x2 != None) or (y2 != None) or (z2 != None)):
|
||||
self.write_blocknum()
|
||||
self.write('(LOG,</POINT>)\n')
|
||||
|
||||
if ((x3 != None) or (y3 != None) or (z3 != None)):
|
||||
self.write_blocknum()
|
||||
self.write('(LOG,<POINT>)\n')
|
||||
|
||||
if (x3 != None):
|
||||
self.write_blocknum()
|
||||
self.write('#<_value>=[' + x3 + ']\n')
|
||||
self.write_blocknum()
|
||||
self.write('(LOG,<X>#<_value></X>)\n')
|
||||
|
||||
if (y3 != None):
|
||||
self.write_blocknum()
|
||||
self.write('#<_value>=[' + y3 + ']\n')
|
||||
self.write_blocknum()
|
||||
self.write('(LOG,<Y>#<_value></Y>)\n')
|
||||
|
||||
if (z3 != None):
|
||||
self.write_blocknum()
|
||||
self.write('#<_value>=[' + z3 + ']\n')
|
||||
self.write_blocknum()
|
||||
self.write('(LOG,<Z>#<_value></Z>)\n')
|
||||
|
||||
if ((x3 != None) or (y3 != None) or (z3 != None)):
|
||||
self.write_blocknum()
|
||||
self.write('(LOG,</POINT>)\n')
|
||||
|
||||
if ((x4 != None) or (y4 != None) or (z4 != None)):
|
||||
self.write_blocknum()
|
||||
self.write('(LOG,<POINT>)\n')
|
||||
|
||||
if (x4 != None):
|
||||
self.write_blocknum()
|
||||
self.write('#<_value>=[' + x4 + ']\n')
|
||||
self.write_blocknum()
|
||||
self.write('(LOG,<X>#<_value></X>)\n')
|
||||
|
||||
if (y4 != None):
|
||||
self.write_blocknum()
|
||||
self.write('#<_value>=[' + y4 + ']\n')
|
||||
self.write_blocknum()
|
||||
self.write('(LOG,<Y>#<_value></Y>)\n')
|
||||
|
||||
if (z4 != None):
|
||||
self.write_blocknum()
|
||||
self.write('#<_value>=[' + z4 + ']\n')
|
||||
self.write_blocknum()
|
||||
self.write('(LOG,<Z>#<_value></Z>)\n')
|
||||
|
||||
if ((x4 != None) or (y4 != None) or (z4 != None)):
|
||||
self.write_blocknum()
|
||||
self.write('(LOG,</POINT>)\n')
|
||||
|
||||
if ((x5 != None) or (y5 != None) or (z5 != None)):
|
||||
self.write_blocknum()
|
||||
self.write('(LOG,<POINT>)\n')
|
||||
|
||||
if (x5 != None):
|
||||
self.write_blocknum()
|
||||
self.write('#<_value>=[' + x5 + ']\n')
|
||||
self.write_blocknum()
|
||||
self.write('(LOG,<X>#<_value></X>)\n')
|
||||
|
||||
if (y5 != None):
|
||||
self.write_blocknum()
|
||||
self.write('#<_value>=[' + y5 + ']\n')
|
||||
self.write_blocknum()
|
||||
self.write('(LOG,<Y>#<_value></Y>)\n')
|
||||
|
||||
if (z5 != None):
|
||||
self.write_blocknum()
|
||||
self.write('#<_value>=[' + z5 + ']\n')
|
||||
self.write_blocknum()
|
||||
self.write('(LOG,<Z>#<_value></Z>)\n')
|
||||
|
||||
if ((x5 != None) or (y5 != None) or (z5 != None)):
|
||||
self.write_blocknum()
|
||||
self.write('(LOG,</POINT>)\n')
|
||||
|
||||
if ((x6 != None) or (y6 != None) or (z6 != None)):
|
||||
self.write_blocknum()
|
||||
self.write('(LOG,<POINT>)\n')
|
||||
|
||||
if (x6 != None):
|
||||
self.write_blocknum()
|
||||
self.write('#<_value>=[' + x6 + ']\n')
|
||||
self.write_blocknum()
|
||||
self.write('(LOG,<X>#<_value></X>)\n')
|
||||
|
||||
if (y6 != None):
|
||||
self.write_blocknum()
|
||||
self.write('#<_value>=[' + y6 + ']\n')
|
||||
self.write_blocknum()
|
||||
self.write('(LOG,<Y>#<_value></Y>)\n')
|
||||
|
||||
if (z6 != None):
|
||||
self.write_blocknum()
|
||||
self.write('#<_value>=[' + z6 + ']\n')
|
||||
self.write_blocknum()
|
||||
self.write('(LOG,<Z>#<_value></Z>)\n')
|
||||
|
||||
if ((x6 != None) or (y6 != None) or (z6 != None)):
|
||||
self.write_blocknum()
|
||||
self.write('(LOG,</POINT>)\n')
|
||||
|
||||
self.write_blocknum()
|
||||
self.write('(LOG,</POINTS>)\n')
|
||||
|
||||
if (xml_file_name != None):
|
||||
self.write_blocknum()
|
||||
self.write('(LOGCLOSE)\n')
|
||||
|
||||
def open_log_file(self, xml_file_name=None ):
|
||||
self.write_blocknum()
|
||||
self.write('(LOGOPEN,')
|
||||
self.write(xml_file_name)
|
||||
self.write(')\n')
|
||||
|
||||
def close_log_file(self):
|
||||
self.write_blocknum()
|
||||
self.write('(LOGCLOSE)\n')
|
||||
|
||||
def log_coordinate(self, x=None, y=None, z=None):
|
||||
if ((x != None) or (y != None) or (z != None)):
|
||||
self.write_blocknum()
|
||||
self.write('(LOG,<POINT>)\n')
|
||||
|
||||
if (x != None):
|
||||
self.write_blocknum()
|
||||
self.write('#<_value>=[' + x + ']\n')
|
||||
self.write_blocknum()
|
||||
self.write('(LOG,<X>#<_value></X>)\n')
|
||||
|
||||
if (y != None):
|
||||
self.write_blocknum()
|
||||
self.write('#<_value>=[' + y + ']\n')
|
||||
self.write_blocknum()
|
||||
self.write('(LOG,<Y>#<_value></Y>)\n')
|
||||
|
||||
if (z != None):
|
||||
self.write_blocknum()
|
||||
self.write('#<_value>=[' + z + ']\n')
|
||||
self.write_blocknum()
|
||||
self.write('(LOG,<Z>#<_value></Z>)\n')
|
||||
|
||||
if ((x != None) or (y != None) or (z != None)):
|
||||
self.write_blocknum()
|
||||
self.write('(LOG,</POINT>)\n')
|
||||
|
||||
def log_message(self, message=None ):
|
||||
self.write_blocknum()
|
||||
self.write('(LOG,' + message + ')\n')
|
||||
|
||||
nc.creator = Creator()
|
|
@ -381,7 +381,6 @@ class CAM_OPERATION_PROPERTIES_Panel(CAMButtonsPanel, bpy.types.Panel):
|
|||
layout.prop(ao,'strategy')
|
||||
layout.prop(ao,'rotary_axis_1')
|
||||
layout.prop(ao,'rotary_axis_2')
|
||||
|
||||
if ao.strategy=='BLOCK' or ao.strategy=='SPIRAL' or ao.strategy=='CIRCLES' or ao.strategy=='OUTLINEFILL':
|
||||
layout.prop(ao,'movement_insideout')
|
||||
|
||||
|
@ -424,6 +423,7 @@ class CAM_OPERATION_PROPERTIES_Panel(CAMButtonsPanel, bpy.types.Panel):
|
|||
if ao.waterline_fill:
|
||||
layout.prop(ao,'dist_between_paths')
|
||||
layout.prop(ao,'waterline_project')
|
||||
layout.prop(ao,'skin')
|
||||
layout.prop(ao,'inverse')
|
||||
elif ao.strategy=='CARVE':
|
||||
layout.prop(ao,'carve_depth')
|
||||
|
@ -449,7 +449,9 @@ class CAM_OPERATION_PROPERTIES_Panel(CAMButtonsPanel, bpy.types.Panel):
|
|||
layout.prop(ao,'dist_along_paths')
|
||||
if ao.strategy=='PARALLEL' or ao.strategy=='CROSS':
|
||||
layout.prop(ao,'parallel_angle')
|
||||
|
||||
|
||||
|
||||
layout.prop(ao,'skin')
|
||||
layout.prop(ao,'inverse')
|
||||
#elif ao.strategy=='SLICES':
|
||||
# layout.prop(ao,'slice_detail')
|
||||
|
@ -457,8 +459,6 @@ class CAM_OPERATION_PROPERTIES_Panel(CAMButtonsPanel, bpy.types.Panel):
|
|||
#layout.operator("object.cam_pack_objects")
|
||||
#layout.operator("scene.cam_orientation_add")
|
||||
#gname=ao.name+'_orientations'
|
||||
|
||||
layout.prop(ao,'skin')
|
||||
|
||||
#if gname in bpy.data.groups:
|
||||
# layout.label('orientations')
|
||||
|
@ -576,7 +576,7 @@ class CAM_OPTIMISATION_Panel(CAMButtonsPanel, bpy.types.Panel):
|
|||
if ao.optimize:
|
||||
layout.prop(ao,'optimize_threshold')
|
||||
if ao.geometry_source=='OBJECT' or ao.geometry_source=='GROUP':
|
||||
exclude_exact= ao.strategy=='WATERLINE' or ao.strategy=='POCKET' or ao.strategy=='CUTOUT' or ao.strategy=='DRILL' or ao.strategy=='PENCIL'
|
||||
exclude_exact= ao.strategy=='CUTOUT' or ao.strategy=='DRILL' or ao.strategy=='PENCIL'
|
||||
if not exclude_exact:
|
||||
layout.prop(ao,'use_exact')
|
||||
if ao.use_exact:
|
||||
|
|
|
@ -1060,9 +1060,6 @@ def exportGcodePath(filename,vertslist,operations):
|
|||
elif m.post_processor=='EMC':
|
||||
extension = '.ngc'
|
||||
from .nc import emc2b as postprocessor
|
||||
elif m.post_processor=='GRBL':
|
||||
extension = '.ngc'
|
||||
from .nc import grbl as postprocessor
|
||||
elif m.post_processor=='HM50':
|
||||
from .nc import hm50 as postprocessor
|
||||
elif m.post_processor=='HEIDENHAIN':
|
||||
|
@ -1564,28 +1561,15 @@ def sortChunks(chunks,o):
|
|||
ch = getClosest(o,pos,chunks)
|
||||
# break
|
||||
#pass;
|
||||
if ch is not None:#found next chunk, append it to list
|
||||
ch.sorted = True
|
||||
ch.adaptdist(pos, o)
|
||||
if ch!=None:#found next chunk, append it to list
|
||||
ch.sorted=True
|
||||
ch.adaptdist(pos,o)
|
||||
print(ch)
|
||||
chunks.remove(ch)
|
||||
sortedchunks.append(ch)
|
||||
lastch = ch
|
||||
pos = lastch.points[-1]
|
||||
# experimental fix for infinite loop problem
|
||||
#else:
|
||||
# can't find chunks close enough and still some chunks left
|
||||
# to be sorted. For now just move the remaining chunks over to
|
||||
# the sorted list.
|
||||
# This fixes an infinite loop condition that occurs sometimes.
|
||||
# This is a bandaid fix: need to find the root cause of this problem
|
||||
# suspect it has to do with the sorted flag?
|
||||
#print("no chunks found closest. Chunks not sorted: ", len(chunks))
|
||||
#sortedchunks.extend(chunks)
|
||||
#chunks[:] = []
|
||||
|
||||
i -= 1
|
||||
|
||||
lastch=ch
|
||||
pos=lastch.points[-1]
|
||||
i-=1
|
||||
'''
|
||||
if i<-200:
|
||||
for ch in chunks:
|
||||
|
@ -2300,239 +2284,236 @@ def addBridges(ch,o):
|
|||
ch.points[p[0]]=p[1]
|
||||
for pi in range(len(insertpoints)-1,-1,-1):
|
||||
ch.points.insert(insertpoints[pi][0],insertpoints[pi][1])
|
||||
|
||||
'''
|
||||
|
||||
###########cutout strategy is completely here:
|
||||
def strategy_cutout( o ):
|
||||
#ob=bpy.context.active_object
|
||||
print('operation: cutout')
|
||||
offset=True
|
||||
if o.cut_type=='ONLINE' and o.onlycurves==True:#is separate to allow open curves :)
|
||||
print('separate')
|
||||
chunksFromCurve=[]
|
||||
for ob in o.objects:
|
||||
chunksFromCurve.extend(curveToChunks(ob))
|
||||
#p=Polygon.Polygon()
|
||||
for ch in chunksFromCurve:
|
||||
#print(ch.points)
|
||||
|
||||
if len(ch.points)>2:
|
||||
ch.poly=chunkToShapely(ch)
|
||||
#p.addContour(ch.poly)
|
||||
else:
|
||||
chunksFromCurve=[]
|
||||
if o.cut_type=='ONLINE':
|
||||
p=getObjectOutline(0,o,True)
|
||||
|
||||
else:
|
||||
offset=True
|
||||
if o.cut_type=='INSIDE':
|
||||
offset=False
|
||||
|
||||
p=getObjectOutline(o.cutter_diameter/2,o,offset)
|
||||
if o.outlines_count>1:
|
||||
for i in range(1,o.outlines_count):
|
||||
chunksFromCurve.extend(shapelyToChunks(p,-1))
|
||||
p = p.buffer(distance = o.dist_between_paths * offset, resolution = o.circle_detail)
|
||||
|
||||
|
||||
chunksFromCurve.extend(shapelyToChunks(p,-1))
|
||||
if o.outlines_count>1 and o.movement_insideout=='OUTSIDEIN':
|
||||
chunksFromCurve.reverse()
|
||||
|
||||
#parentChildPoly(chunksFromCurve,chunksFromCurve,o)
|
||||
chunksFromCurve=limitChunks(chunksFromCurve,o)
|
||||
parentChildPoly(chunksFromCurve,chunksFromCurve,o)
|
||||
if o.outlines_count==1:
|
||||
chunksFromCurve=sortChunks(chunksFromCurve,o)
|
||||
|
||||
#if o.outlines_count>0 and o.cut_type!='ONLINE' and o.movement_insideout=='OUTSIDEIN':#reversing just with more outlines
|
||||
# chunksFromCurve.reverse()
|
||||
|
||||
if (o.movement_type=='CLIMB' and o.spindle_rotation_direction=='CCW') or (o.movement_type=='CONVENTIONAL' and o.spindle_rotation_direction=='CW'):
|
||||
for ch in chunksFromCurve:
|
||||
ch.points.reverse()
|
||||
|
||||
if o.cut_type=='INSIDE':#there would bee too many conditions above, so for now it gets reversed once again when inside cutting.
|
||||
for ch in chunksFromCurve:
|
||||
ch.points.reverse()
|
||||
|
||||
|
||||
if o.use_layers:
|
||||
layers=[]
|
||||
n=math.ceil((o.maxz-o.min.z)/o.stepdown)
|
||||
layerstart=o.maxz
|
||||
for x in range(0,n):
|
||||
layerend=max(o.maxz-((x+1)*o.stepdown),o.min.z)
|
||||
if int(layerstart*10**8)!=int(layerend*10**8):#it was possible that with precise same end of operation, last layer was done 2x on exactly same level...
|
||||
layers.append([layerstart,layerend])
|
||||
layerstart=layerend
|
||||
else:
|
||||
layers=[[o.maxz,o.min.z]]
|
||||
|
||||
print(layers)
|
||||
|
||||
extendorder=[]
|
||||
if o.first_down:#each shape gets either cut all the way to bottom, or every shape gets cut 1 layer, then all again. has to create copies, because same chunks are worked with on more layers usually
|
||||
for chunk in chunksFromCurve:
|
||||
for layer in layers:
|
||||
extendorder.append([chunk.copy(),layer])
|
||||
else:
|
||||
for layer in layers:
|
||||
for chunk in chunksFromCurve:
|
||||
extendorder.append([chunk.copy(),layer])
|
||||
|
||||
for chl in extendorder:#Set Z for all chunks
|
||||
chunk=chl[0]
|
||||
layer=chl[1]
|
||||
print(layer[1])
|
||||
chunk.setZ(layer[1])
|
||||
|
||||
chunks=[]
|
||||
|
||||
if o.ramp:#add ramps or simply add chunks
|
||||
for chl in extendorder:
|
||||
chunk=chl[0]
|
||||
layer=chl[1]
|
||||
if chunk.closed:
|
||||
chunks.append(chunk.rampContour(layer[0],layer[1],o))
|
||||
else:
|
||||
chunks.append(chunk.rampZigZag(layer[0],layer[1],o))
|
||||
|
||||
if o.use_bridges:#add bridges to chunks
|
||||
#bridges=getBridges(p,o)
|
||||
bridgeheight=min(0,o.min.z+o.bridges_height)
|
||||
for chl in extendorder:
|
||||
chunk=chl[0]
|
||||
layer=chl[1]
|
||||
if layer[1]<bridgeheight:
|
||||
addBridges(chunk,o)
|
||||
|
||||
for chl in extendorder:
|
||||
chunks.append(chl[0])
|
||||
|
||||
|
||||
chunksToMesh(chunks,o)
|
||||
|
||||
def strategy_curve( o ):
|
||||
print('operation: curve')
|
||||
pathSamples=[]
|
||||
getOperationSources(o)
|
||||
if not o.onlycurves:
|
||||
o.warnings+= 'at least one of assigned objects is not a curve'
|
||||
#ob=bpy.data.objects[o.object_name]
|
||||
for ob in o.objects:
|
||||
pathSamples.extend(curveToChunks(ob))
|
||||
pathSamples=sortChunks(pathSamples,o)#sort before sampling
|
||||
pathSamples=chunksRefine(pathSamples,o)
|
||||
|
||||
if o.ramp:
|
||||
for ch in pathSamples:
|
||||
nchunk = ch.rampZigZag(ch.zstart, ch.points[0][2],o)
|
||||
ch.points=nchunk.points
|
||||
|
||||
chunksToMesh(pathSamples,o)
|
||||
|
||||
def strategy_proj_curve( s, o ):
|
||||
print('operation: projected curve')
|
||||
pathSamples = []
|
||||
chunks = []
|
||||
ob = bpy.data.objects[o.curve_object]
|
||||
pathSamples.extend(curveToChunks(ob))
|
||||
|
||||
targetCurve = s.objects[o.curve_object1]
|
||||
|
||||
from cam import chunk
|
||||
if targetCurve.type != 'CURVE':
|
||||
o.warnings = o.warnings+'Projection target and source have to be curve objects!\n '
|
||||
return
|
||||
''' #mesh method is highly unstable, I don't like itwould be there at all.... better to use curves.
|
||||
if targetCurve.type=='MESH':
|
||||
|
||||
c=targetCurve
|
||||
for ch in pathSamples:
|
||||
ch.depth=0
|
||||
for i,s in enumerate(ch.points):
|
||||
np=c.closest_point_on_mesh(s)
|
||||
ch.startpoints.append(Vector(s))
|
||||
ch.endpoints.append(np[0])
|
||||
ch.rotations.append((0,0,0))
|
||||
vect = np[0]-Vector(s)
|
||||
|
||||
ch.depth=min(ch.depth,-vect.length)
|
||||
else:
|
||||
'''
|
||||
if 1:
|
||||
extend_up = 0.1
|
||||
extend_down = 0.04
|
||||
tsamples = curveToChunks(targetCurve)
|
||||
for chi,ch in enumerate(pathSamples):
|
||||
cht = tsamples[chi].points
|
||||
ch.depth = 0
|
||||
for i,s in enumerate(ch.points):
|
||||
#move the points a bit
|
||||
ep = Vector(cht[i])
|
||||
sp = Vector(ch.points[i])
|
||||
#extend startpoint
|
||||
vecs = sp-ep
|
||||
vecs.normalize()
|
||||
vecs *= extend_up
|
||||
sp += vecs
|
||||
ch.startpoints.append(sp)
|
||||
|
||||
#extend endpoint
|
||||
vece = sp - ep
|
||||
vece.normalize()
|
||||
vece *= extend_down
|
||||
ep -= vece
|
||||
ch.endpoints.append(ep)
|
||||
|
||||
ch.rotations.append((0,0,0))
|
||||
|
||||
vec = sp - ep
|
||||
ch.depth = min(ch.depth,-vec.length)
|
||||
ch.points[i] = sp.copy()
|
||||
|
||||
|
||||
if o.use_layers:
|
||||
n = math.ceil(-(ch.depth/o.stepdown))
|
||||
layers = []
|
||||
for x in range(0,n):
|
||||
|
||||
layerstart = -(x*o.stepdown)
|
||||
layerend = max(-((x+1)*o.stepdown),ch.depth)
|
||||
layers.append([layerstart,layerend])
|
||||
else:
|
||||
layerstart = 0#
|
||||
layerend = ch.depth#
|
||||
layers = [[layerstart,layerend]]
|
||||
|
||||
chunks.extend(sampleChunksNAxis(o,pathSamples,layers))
|
||||
#for ch in pathSamples:
|
||||
# ch.points=ch.endpoints
|
||||
chunksToMesh(chunks,o)
|
||||
|
||||
|
||||
#this is the main function.
|
||||
#FIXME: split strategies into separate file!
|
||||
#def cutoutStrategy(o):
|
||||
def getPath3axis(context, operation):
|
||||
'''
|
||||
#this is the main function.
|
||||
#FIXME: split strategies into separate file!
|
||||
#def cutoutStrategy(o):
|
||||
def getPath3axis(context,operation):
|
||||
s=bpy.context.scene
|
||||
o=operation
|
||||
getBounds(o)
|
||||
|
||||
|
||||
###########cutout strategy is completely here:
|
||||
if o.strategy=='CUTOUT':
|
||||
strategy_cutout( o )
|
||||
|
||||
elif o.strategy=='CURVE':
|
||||
strategy_curve( o )
|
||||
#ob=bpy.context.active_object
|
||||
offset=True
|
||||
if o.cut_type=='ONLINE' and o.onlycurves==True:#is separate to allow open curves :)
|
||||
print('separe')
|
||||
chunksFromCurve=[]
|
||||
for ob in o.objects:
|
||||
chunksFromCurve.extend(curveToChunks(ob))
|
||||
p=Polygon.Polygon()
|
||||
for ch in chunksFromCurve:
|
||||
#print(ch.points)
|
||||
|
||||
elif o.strategy=='PROJECTED_CURVE':
|
||||
strategy_proj_curve(s, o)
|
||||
if len(ch.points)>2:
|
||||
ch.poly=chunkToShapely(ch)
|
||||
#p.addContour(ch.poly)
|
||||
else:
|
||||
chunksFromCurve=[]
|
||||
if o.cut_type=='ONLINE':
|
||||
p=getObjectOutline(0,o,True)
|
||||
|
||||
else:
|
||||
offset=True
|
||||
if o.cut_type=='INSIDE':
|
||||
offset=False
|
||||
|
||||
p=getObjectOutline(o.cutter_diameter/2,o,offset)
|
||||
if o.outlines_count>1:
|
||||
for i in range(1,o.outlines_count):
|
||||
chunksFromCurve.extend(shapelyToChunks(p,-1))
|
||||
p = p.buffer(distance = o.dist_between_paths * offset, resolution = o.circle_detail)
|
||||
|
||||
|
||||
chunksFromCurve.extend(shapelyToChunks(p,-1))
|
||||
if o.outlines_count>1 and o.movement_insideout=='OUTSIDEIN':
|
||||
chunksFromCurve.reverse()
|
||||
#parentChildPoly(chunksFromCurve,chunksFromCurve,o)
|
||||
chunksFromCurve=limitChunks(chunksFromCurve,o)
|
||||
parentChildPoly(chunksFromCurve,chunksFromCurve,o)
|
||||
if o.outlines_count==1:
|
||||
chunksFromCurve=sortChunks(chunksFromCurve,o)
|
||||
|
||||
elif o.strategy=='POCKET':
|
||||
#if o.outlines_count>0 and o.cut_type!='ONLINE' and o.movement_insideout=='OUTSIDEIN':#reversing just with more outlines
|
||||
# chunksFromCurve.reverse()
|
||||
|
||||
if (o.movement_type=='CLIMB' and o.spindle_rotation_direction=='CCW') or (o.movement_type=='CONVENTIONAL' and o.spindle_rotation_direction=='CW'):
|
||||
for ch in chunksFromCurve:
|
||||
ch.points.reverse()
|
||||
|
||||
if o.cut_type=='INSIDE':#there would bee too many conditions above, so for now it gets reversed once again when inside cutting.
|
||||
for ch in chunksFromCurve:
|
||||
ch.points.reverse()
|
||||
|
||||
|
||||
if o.use_layers:
|
||||
layers=[]
|
||||
n=math.ceil((o.maxz-o.min.z)/o.stepdown)
|
||||
layerstart=o.maxz
|
||||
for x in range(0,n):
|
||||
layerend=max(o.maxz-((x+1)*o.stepdown),o.min.z)
|
||||
if int(layerstart*10**8)!=int(layerend*10**8):#it was possible that with precise same end of operation, last layer was done 2x on exactly same level...
|
||||
layers.append([layerstart,layerend])
|
||||
layerstart=layerend
|
||||
else:
|
||||
layers=[[o.maxz,o.min.z]]
|
||||
|
||||
print(layers)
|
||||
extendorder=[]
|
||||
if o.first_down:#each shape gets either cut all the way to bottom, or every shape gets cut 1 layer, then all again. has to create copies, because same chunks are worked with on more layers usually
|
||||
for chunk in chunksFromCurve:
|
||||
for layer in layers:
|
||||
extendorder.append([chunk.copy(),layer])
|
||||
else:
|
||||
for layer in layers:
|
||||
for chunk in chunksFromCurve:
|
||||
extendorder.append([chunk.copy(),layer])
|
||||
|
||||
for chl in extendorder:#Set Z for all chunks
|
||||
chunk=chl[0]
|
||||
layer=chl[1]
|
||||
print(layer[1])
|
||||
chunk.setZ(layer[1])
|
||||
|
||||
chunks=[]
|
||||
|
||||
if o.ramp:#add ramps or simply add chunks
|
||||
for chl in extendorder:
|
||||
chunk=chl[0]
|
||||
layer=chl[1]
|
||||
if chunk.closed:
|
||||
chunk.rampContour(layer[0],layer[1],o)
|
||||
else:
|
||||
chunk.rampZigZag(layer[0],layer[1],o)
|
||||
|
||||
|
||||
|
||||
if o.use_bridges:#add bridges to chunks
|
||||
#bridges=getBridges(p,o)
|
||||
bridgeheight=min(0,o.min.z+o.bridges_height)
|
||||
for chl in extendorder:
|
||||
chunk=chl[0]
|
||||
layer=chl[1]
|
||||
if layer[1]<bridgeheight:
|
||||
addBridges(chunk,o)
|
||||
|
||||
|
||||
|
||||
for chl in extendorder:
|
||||
chunks.append(chl[0])
|
||||
|
||||
|
||||
|
||||
|
||||
chunksToMesh(chunks,o)
|
||||
|
||||
elif o.strategy=='CURVE':
|
||||
pathSamples=[]
|
||||
getOperationSources(o)
|
||||
if not o.onlycurves:
|
||||
o.warnings+= 'at least one of assigned objects is not a curve'
|
||||
#ob=bpy.data.objects[o.object_name]
|
||||
for ob in o.objects:
|
||||
pathSamples.extend(curveToChunks(ob))
|
||||
pathSamples=sortChunks(pathSamples,o)#sort before sampling
|
||||
pathSamples=chunksRefine(pathSamples,o)
|
||||
|
||||
if o.ramp:
|
||||
for ch in pathSamples:
|
||||
nchunk = ch.rampZigZag(ch.zstart, ch.points[0][2],o)
|
||||
ch.points=nchunk.points
|
||||
|
||||
chunksToMesh(pathSamples,o)
|
||||
|
||||
|
||||
|
||||
if o.strategy=='PROJECTED_CURVE':
|
||||
pathSamples=[]
|
||||
chunks=[]
|
||||
ob=bpy.data.objects[o.curve_object]
|
||||
pathSamples.extend(curveToChunks(ob))
|
||||
|
||||
targetCurve=s.objects[o.curve_object1]
|
||||
|
||||
from cam import chunk
|
||||
if targetCurve.type!='CURVE':
|
||||
o.warnings=o.warnings+'Projection target and source have to be curve objects!\n '
|
||||
return
|
||||
''' #mesh method is highly unstable, I don't like itwould be there at all.... better to use curves.
|
||||
if targetCurve.type=='MESH':
|
||||
|
||||
c=targetCurve
|
||||
for ch in pathSamples:
|
||||
ch.depth=0
|
||||
for i,s in enumerate(ch.points):
|
||||
np=c.closest_point_on_mesh(s)
|
||||
ch.startpoints.append(Vector(s))
|
||||
ch.endpoints.append(np[0])
|
||||
ch.rotations.append((0,0,0))
|
||||
vect = np[0]-Vector(s)
|
||||
|
||||
ch.depth=min(ch.depth,-vect.length)
|
||||
else:
|
||||
'''
|
||||
if 1:
|
||||
extend_up=0.1
|
||||
extend_down=0.04
|
||||
tsamples = curveToChunks(targetCurve)
|
||||
for chi,ch in enumerate(pathSamples):
|
||||
cht=tsamples[chi].points
|
||||
ch.depth=0
|
||||
for i,s in enumerate(ch.points):
|
||||
#move the points a bit
|
||||
ep=Vector(cht[i])
|
||||
sp=Vector(ch.points[i])
|
||||
#extend startpoint
|
||||
vecs=sp-ep
|
||||
vecs.normalize()
|
||||
vecs*=extend_up
|
||||
sp+=vecs
|
||||
ch.startpoints.append(sp)
|
||||
|
||||
#extend endpoint
|
||||
vece=sp-ep
|
||||
vece.normalize()
|
||||
vece*=extend_down
|
||||
ep-=vece
|
||||
ch.endpoints.append(ep)
|
||||
|
||||
|
||||
ch.rotations.append((0,0,0))
|
||||
|
||||
vec=sp-ep
|
||||
ch.depth=min(ch.depth,-vec.length)
|
||||
ch.points[i]=sp.copy()
|
||||
|
||||
|
||||
|
||||
if o.use_layers:
|
||||
n=math.ceil(-(ch.depth/o.stepdown))
|
||||
layers=[]
|
||||
for x in range(0,n):
|
||||
|
||||
layerstart=-(x*o.stepdown)
|
||||
layerend=max(-((x+1)*o.stepdown),ch.depth)
|
||||
layers.append([layerstart,layerend])
|
||||
else:
|
||||
layerstart=0#
|
||||
layerend=ch.depth#
|
||||
layers=[[layerstart,layerend]]
|
||||
|
||||
chunks.extend(sampleChunksNAxis(o,pathSamples,layers))
|
||||
#for ch in pathSamples:
|
||||
# ch.points=ch.endpoints
|
||||
chunksToMesh(chunks,o)
|
||||
|
||||
|
||||
if o.strategy=='POCKET':
|
||||
p=getObjectOutline(o.cutter_diameter/2,o,False)
|
||||
#all=Polygon.Polygon(p)
|
||||
approxn=(min(o.max.x-o.min.x,o.max.y-o.min.y)/o.dist_between_paths)/2
|
||||
|
@ -3052,7 +3033,6 @@ def getPath3axis(context, operation):
|
|||
chunks=sortChunks(chunks,o)
|
||||
print(chunks)
|
||||
chunksToMesh(chunks,o)
|
||||
|
||||
elif o.strategy=='MEDIAL_AXIS':
|
||||
print('doing highly experimental stuff')
|
||||
|
||||
|
@ -3493,3 +3473,5 @@ def reload_paths(o):
|
|||
|
||||
if old_pathmesh != None:
|
||||
bpy.data.meshes.remove(old_pathmesh)
|
||||
|
||||
|
||||
|
|
Ładowanie…
Reference in New Issue