kopia lustrzana https://github.com/vilemduha/blendercam
Merge branch 'master' of https://github.com/vilemnovak/blendercam into edge
commit
dd4140cdcb
|
@ -26,7 +26,7 @@ from cam import simple
|
|||
from cam.simple import *
|
||||
|
||||
BULLET_SCALE=10000 # this is a constant for scaling the rigidbody collision world for higher precision from bullet library
|
||||
|
||||
CUTTER_OFFSET = (-5*BULLET_SCALE,-5*BULLET_SCALE,-5*BULLET_SCALE)# the cutter object has to be present in the scene , so we need to put it aside for sweep collisions, otherwise it collides itself.
|
||||
|
||||
#
|
||||
def getCutterBullet(o):
|
||||
|
@ -39,19 +39,19 @@ def getCutterBullet(o):
|
|||
|
||||
type=o.cutter_type
|
||||
if type=='END':
|
||||
bpy.ops.mesh.primitive_cylinder_add(vertices=32, radius=BULLET_SCALE*o.cutter_diameter/2, depth=BULLET_SCALE*o.cutter_diameter, end_fill_type='NGON', view_align=False, enter_editmode=False, location=(-100,-100, -100), rotation=(0, 0, 0))
|
||||
bpy.ops.mesh.primitive_cylinder_add(vertices=32, radius=BULLET_SCALE*o.cutter_diameter/2, depth=BULLET_SCALE*o.cutter_diameter, end_fill_type='NGON', view_align=False, enter_editmode=False, location=CUTTER_OFFSET, rotation=(0, 0, 0))
|
||||
bpy.ops.rigidbody.object_add(type='ACTIVE')
|
||||
cutter=bpy.context.active_object
|
||||
cutter.rigid_body.collision_shape = 'CYLINDER'
|
||||
elif type=='BALL' or type=='BALLNOSE':
|
||||
if o.strategy!='PROJECTED_CURVE' or type=='BALL':#only sphere, good for 3 axis and real ball cutters for undercuts and projected curve
|
||||
|
||||
bpy.ops.mesh.primitive_ico_sphere_add(subdivisions=2, size=BULLET_SCALE*o.cutter_diameter/2, view_align=False, enter_editmode=False, location=(-100,-100, -100), rotation=(0, 0, 0))
|
||||
bpy.ops.mesh.primitive_ico_sphere_add(subdivisions=2, size=BULLET_SCALE*o.cutter_diameter/2, view_align=False, enter_editmode=False, location=CUTTER_OFFSET, rotation=(0, 0, 0))
|
||||
bpy.ops.rigidbody.object_add(type='ACTIVE')
|
||||
cutter=bpy.context.active_object
|
||||
cutter.rigid_body.collision_shape = 'SPHERE'
|
||||
else:#ballnose ending used mainly when projecting from sides. the actual collision shape is capsule in this case.
|
||||
bpy.ops.mesh.primitive_ico_sphere_add(subdivisions=2, size=BULLET_SCALE*o.cutter_diameter/2, view_align=False, enter_editmode=False, location=(-100,-100, -100), rotation=(0, 0, 0))
|
||||
bpy.ops.mesh.primitive_ico_sphere_add(subdivisions=2, size=BULLET_SCALE*o.cutter_diameter/2, view_align=False, enter_editmode=False, location=CUTTER_OFFSET, rotation=(0, 0, 0))
|
||||
bpy.ops.rigidbody.object_add(type='ACTIVE')
|
||||
cutter=bpy.context.active_object
|
||||
cutter.dimensions.z=0.2*BULLET_SCALE#should be sufficient for now... 20 cm.
|
||||
|
@ -62,7 +62,7 @@ def getCutterBullet(o):
|
|||
|
||||
angle=o.cutter_tip_angle
|
||||
s=math.tan(math.pi*(90-angle/2)/180)/2
|
||||
bpy.ops.mesh.primitive_cone_add(vertices=32, radius1=BULLET_SCALE*o.cutter_diameter/2, radius2=0, depth = BULLET_SCALE*o.cutter_diameter*s, end_fill_type='NGON', view_align=False, enter_editmode=False, location=(-100,-100, -100), rotation=(math.pi, 0, 0))
|
||||
bpy.ops.mesh.primitive_cone_add(vertices=32, radius1=BULLET_SCALE*o.cutter_diameter/2, radius2=0, depth = BULLET_SCALE*o.cutter_diameter*s, end_fill_type='NGON', view_align=False, enter_editmode=False, location=CUTTER_OFFSET, rotation=(math.pi, 0, 0))
|
||||
bpy.ops.rigidbody.object_add(type='ACTIVE')
|
||||
cutter=bpy.context.active_object
|
||||
cutter.rigid_body.collision_shape = 'CONE'
|
||||
|
@ -80,7 +80,7 @@ def getCutterBullet(o):
|
|||
#print(cutter.dimensions,scale)
|
||||
bpy.ops.rigidbody.object_add(type='ACTIVE')
|
||||
cutter.rigid_body.collision_shape = 'CONVEX_HULL'
|
||||
cutter.location=(-100,-100,-100)
|
||||
cutter.location=CUTTER_OFFSET
|
||||
|
||||
cutter.name='cam_cutter'
|
||||
o.cutter_shape=cutter
|
||||
|
|
|
@ -38,7 +38,7 @@ class Creator(iso.Creator):
|
|||
#print(self.SPACE())
|
||||
#print(self.TOOL())
|
||||
self.write(self.SPACE() + (self.TOOL() % id) + '\n')
|
||||
self.write('\n')
|
||||
#self.write('\n')
|
||||
self.flush_nc()
|
||||
self.t = id
|
||||
|
||||
|
|
|
@ -67,22 +67,22 @@ class CAM_CUTTER_Panel(CAMButtonsPanel, bpy.types.Panel):
|
|||
layout.prop(ao,'cutter_id')
|
||||
layout.prop(ao,'cutter_type')
|
||||
if ao.cutter_type=='VCARVE':
|
||||
layout.prop(ao,'cutter_tip_angle')
|
||||
layout.prop(ao,'cutter_tip_angle')
|
||||
if ao.cutter_type=='CUSTOM':
|
||||
if ao.use_exact:
|
||||
layout.label(text='Warning - only convex shapes are supported. ', icon='COLOR_RED')
|
||||
layout.label(text='If your custom cutter is concave,')
|
||||
layout.label(text='switch exact mode off.')
|
||||
|
||||
layout.prop_search(ao, "cutter_object_name", bpy.data, "objects")
|
||||
|
||||
layout.prop_search(ao, "cutter_object_name", bpy.data, "objects")
|
||||
|
||||
layout.prop(ao,'cutter_diameter')
|
||||
#layout.prop(ao,'cutter_length')
|
||||
layout.prop(ao,'cutter_flutes')
|
||||
layout.prop(ao, 'cutter_description')
|
||||
|
||||
|
||||
class CAM_MACHINE_Panel(CAMButtonsPanel, bpy.types.Panel):
|
||||
layout.prop(ao, 'cutter_description')
|
||||
|
||||
|
||||
class CAM_MACHINE_Panel(CAMButtonsPanel, bpy.types.Panel):
|
||||
"""CAM machine panel"""
|
||||
bl_label = " "
|
||||
bl_idname = "WORLD_PT_CAM_MACHINE"
|
||||
|
@ -109,18 +109,18 @@ class CAM_MACHINE_Panel(CAMButtonsPanel, bpy.types.Panel):
|
|||
layout.prop(ao,'post_processor')
|
||||
layout.prop(ao,'eval_splitting')
|
||||
if ao.eval_splitting:
|
||||
layout.prop(ao,'split_limit')
|
||||
|
||||
layout.prop(ao,'split_limit')
|
||||
|
||||
layout.prop(us,'system')
|
||||
|
||||
|
||||
layout.prop(ao, 'use_position_definitions')
|
||||
if ao.use_position_definitions:
|
||||
layout.prop(ao, 'starting_position')
|
||||
layout.prop(ao, 'mtc_position')
|
||||
layout.prop(ao, 'ending_position')
|
||||
layout.prop(ao,'working_area')
|
||||
layout.prop(ao,'feedrate_min')
|
||||
layout.prop(ao,'feedrate_max')
|
||||
layout.prop(ao, 'starting_position')
|
||||
layout.prop(ao, 'mtc_position')
|
||||
layout.prop(ao, 'ending_position')
|
||||
layout.prop(ao,'working_area')
|
||||
layout.prop(ao,'feedrate_min')
|
||||
layout.prop(ao,'feedrate_max')
|
||||
layout.prop(ao,'feedrate_default')#TODO: spindle default and feedrate default should become part of the cutter definition...
|
||||
layout.prop(ao,'spindle_min')
|
||||
layout.prop(ao,'spindle_max')
|
||||
|
@ -369,7 +369,7 @@ class CAM_INFO_Panel(CAMButtonsPanel, bpy.types.Panel):
|
|||
layout.label(text=l, icon='COLOR_RED')
|
||||
if ao.valid:
|
||||
if ao.duration>0:
|
||||
layout.label('operation time: '+str(int(ao.duration*100)/100.0)+' min')
|
||||
layout.label('operation time: '+str(int(ao.duration*100)//3600.0)+' hour, '+str((int(ao.duration*100)//60.0)%60)+' min, '+str((int(ao.duration*100)%60.0)//1)+' sec.')
|
||||
layout.label( 'chipload: '+ strInUnits(ao.chipload,4) + ' / tooth')
|
||||
|
||||
|
||||
|
@ -470,15 +470,15 @@ class CAM_OPERATION_PROPERTIES_Panel(CAMButtonsPanel, bpy.types.Panel):
|
|||
layout.prop(ao,'crazy_threshold3')
|
||||
layout.prop(ao,'crazy_threshold4')
|
||||
layout.prop(ao,'dist_between_paths')
|
||||
layout.prop(ao,'dist_along_paths')
|
||||
elif ao.strategy=='DRILL':
|
||||
layout.prop(ao,'drill_type')
|
||||
elif ao.strategy=='POCKET':
|
||||
layout.prop(ao,'pocket_option')
|
||||
layout.prop(ao,'dist_between_paths')
|
||||
else:
|
||||
layout.prop(ao,'dist_between_paths')
|
||||
layout.prop(ao,'dist_along_paths')
|
||||
layout.prop(ao,'dist_along_paths')
|
||||
elif ao.strategy=='DRILL':
|
||||
layout.prop(ao,'drill_type')
|
||||
elif ao.strategy=='POCKET':
|
||||
layout.prop(ao,'pocket_option')
|
||||
layout.prop(ao,'dist_between_paths')
|
||||
else:
|
||||
layout.prop(ao,'dist_between_paths')
|
||||
layout.prop(ao,'dist_along_paths')
|
||||
if ao.strategy=='PARALLEL' or ao.strategy=='CROSS':
|
||||
layout.prop(ao,'parallel_angle')
|
||||
|
||||
|
@ -626,7 +626,7 @@ class CAM_OPTIMISATION_Panel(CAMButtonsPanel, bpy.types.Panel):
|
|||
|
||||
layout.prop(ao,'simulation_detail')
|
||||
layout.prop(ao,'circle_detail')
|
||||
layout.prop(ao,'use_opencamlib')
|
||||
layout.prop(ao,'use_opencamlib')
|
||||
#if not ao.use_exact:#this will be replaced with groups of objects.
|
||||
#layout.prop(ao,'render_all')# replaced with groups support
|
||||
|
||||
|
@ -748,7 +748,7 @@ class CAM_SLICE_Panel(CAMButtonsPanel, bpy.types.Panel):
|
|||
layout.operator("object.cam_slice_objects")
|
||||
layout.prop(settings,'slice_distance')
|
||||
layout.prop(settings,'indexes')
|
||||
|
||||
|
||||
#panel containing all tools
|
||||
class VIEW3D_PT_tools_curvetools(bpy.types.Panel):
|
||||
bl_space_type = 'VIEW_3D'
|
||||
|
|
|
@ -1973,13 +1973,14 @@ def addAutoBridges(o):
|
|||
'''attempt to add auto bridges as set of curves'''
|
||||
getOperationSources(o)
|
||||
if not o.onlycurves:
|
||||
o.warnings.append('not curves')
|
||||
o.warnings+=('not curves')
|
||||
return;
|
||||
bridgegroupname=o.bridges_group_name
|
||||
if bridgegroupname == '' or bpy.data.groups.get(bridgegroupname) == None:
|
||||
bridgegroupname = 'bridges_'+o.name
|
||||
bpy.data.groups.new(bridgegroupname)
|
||||
g= bpy.data.groups[bridgegroupname]
|
||||
o.bridges_group_name = bridgegroupname
|
||||
for ob in o.objects:
|
||||
|
||||
if ob.type=='CURVE':
|
||||
|
@ -2002,7 +2003,7 @@ def addAutoBridges(o):
|
|||
g.objects.link( addBridge(p.x,p.y,pi,o.bridges_width, o.cutter_diameter*1))
|
||||
|
||||
mw=ob.matrix_world
|
||||
|
||||
|
||||
def getBridgesPoly(o):
|
||||
if not hasattr(o, 'bridgespolyorig'):
|
||||
bridgegroupname=o.bridges_group_name
|
||||
|
|
Ładowanie…
Reference in New Issue