kopia lustrzana https://github.com/vilemduha/blendercam
362 wiersze
12 KiB
Python
362 wiersze
12 KiB
Python
"""Fabex 'movement.py'
|
|
|
|
'CAM Movement' properties and panel in Properties > Render
|
|
"""
|
|
|
|
from math import pi
|
|
|
|
import bpy
|
|
from bpy.props import (
|
|
BoolProperty,
|
|
EnumProperty,
|
|
FloatProperty,
|
|
)
|
|
from bpy.types import Panel, PropertyGroup
|
|
|
|
from .buttons_panel import CAMButtonsPanel
|
|
from ...utils import update_operation
|
|
from ...constants import (
|
|
PRECISION,
|
|
G64_INCOMPATIBLE_MACHINES,
|
|
)
|
|
|
|
|
|
class CAM_MOVEMENT_Properties(PropertyGroup):
|
|
# movement parallel_step_back
|
|
type: EnumProperty(
|
|
name="Movement Type",
|
|
items=(
|
|
(
|
|
"CONVENTIONAL",
|
|
"Conventional (Up)",
|
|
"Cutter rotates against the direction of the feed",
|
|
),
|
|
(
|
|
"CLIMB",
|
|
"Climb (Down)",
|
|
"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=update_operation,
|
|
)
|
|
|
|
insideout: EnumProperty(
|
|
name="Direction",
|
|
items=(
|
|
("INSIDEOUT", "Inside out", "a"),
|
|
("OUTSIDEIN", "Outside in", "a"),
|
|
),
|
|
description="Approach to the piece",
|
|
default="INSIDEOUT",
|
|
update=update_operation,
|
|
)
|
|
|
|
spindle_rotation: EnumProperty(
|
|
name="Spindle Rotation",
|
|
items=(
|
|
("CW", "Clockwise", "a"),
|
|
("CCW", "Counter clockwise", "a"),
|
|
),
|
|
description="Spindle rotation direction",
|
|
default="CW",
|
|
update=update_operation,
|
|
)
|
|
|
|
free_height: FloatProperty(
|
|
name="Safe Height",
|
|
description="Height where the machine can freely move without hitting the workpiece",
|
|
default=0.01,
|
|
min=0.0000,
|
|
max=32,
|
|
precision=PRECISION,
|
|
unit="LENGTH",
|
|
update=update_operation,
|
|
)
|
|
|
|
useG64: BoolProperty(
|
|
name="G64 Trajectory",
|
|
description="Use only if your machine supports G64 code. LinuxCNC and Mach3 do",
|
|
default=False,
|
|
update=update_operation,
|
|
)
|
|
|
|
G64: FloatProperty(
|
|
name="Path Control Mode with Optional Tolerance",
|
|
default=0.0001,
|
|
min=0.0000,
|
|
max=0.005,
|
|
precision=PRECISION,
|
|
unit="LENGTH",
|
|
update=update_operation,
|
|
)
|
|
|
|
parallel_step_back: BoolProperty(
|
|
name="Parallel Step Back",
|
|
description="For roughing and finishing in one pass: mills "
|
|
"material in climb mode, then steps back and goes "
|
|
"between 2 last chunks back",
|
|
default=False,
|
|
update=update_operation,
|
|
)
|
|
|
|
helix_enter: BoolProperty(
|
|
name="Helix Enter - EXPERIMENTAL",
|
|
description="Enter material in helix",
|
|
default=False,
|
|
update=update_operation,
|
|
)
|
|
|
|
ramp_in_angle: FloatProperty(
|
|
name="Ramp-in Angle",
|
|
default=pi / 6,
|
|
min=0,
|
|
max=pi * 0.4999,
|
|
precision=1,
|
|
subtype="ANGLE",
|
|
unit="ROTATION",
|
|
update=update_operation,
|
|
)
|
|
|
|
helix_diameter: FloatProperty(
|
|
name="Helix Diameter - % of Cutter Diameter",
|
|
default=90,
|
|
min=10,
|
|
max=100,
|
|
precision=1,
|
|
subtype="PERCENTAGE",
|
|
update=update_operation,
|
|
)
|
|
|
|
ramp: BoolProperty(
|
|
name="Ramp-in - EXPERIMENTAL",
|
|
description="Ramps down the whole contour, so the cutline looks " "like helix",
|
|
default=False,
|
|
update=update_operation,
|
|
)
|
|
|
|
ramp_out: BoolProperty(
|
|
name="Ramp-out - EXPERIMENTAL",
|
|
description="Ramp out to not leave mark on surface",
|
|
default=False,
|
|
update=update_operation,
|
|
)
|
|
|
|
ramp_out_angle: FloatProperty(
|
|
name="Ramp-out Angle",
|
|
default=pi / 6,
|
|
min=0,
|
|
max=pi * 0.4999,
|
|
precision=1,
|
|
subtype="ANGLE",
|
|
unit="ROTATION",
|
|
update=update_operation,
|
|
)
|
|
|
|
retract_tangential: BoolProperty(
|
|
name="Retract Tangential - EXPERIMENTAL",
|
|
description="Retract from material in circular motion",
|
|
default=False,
|
|
update=update_operation,
|
|
)
|
|
|
|
retract_radius: FloatProperty(
|
|
name="Retract Arc Radius",
|
|
default=0.001,
|
|
min=0.000001,
|
|
max=100,
|
|
precision=PRECISION,
|
|
unit="LENGTH",
|
|
update=update_operation,
|
|
)
|
|
|
|
retract_height: FloatProperty(
|
|
name="Retract Arc Height",
|
|
default=0.001,
|
|
min=0.00000,
|
|
max=100,
|
|
precision=PRECISION,
|
|
unit="LENGTH",
|
|
update=update_operation,
|
|
)
|
|
|
|
stay_low: BoolProperty(
|
|
name="Stay Low if Possible",
|
|
default=True,
|
|
update=update_operation,
|
|
)
|
|
|
|
merge_dist: FloatProperty(
|
|
name="Merge Distance - EXPERIMENTAL",
|
|
default=0.0,
|
|
min=0.0000,
|
|
max=0.1,
|
|
precision=PRECISION,
|
|
unit="LENGTH",
|
|
update=update_operation,
|
|
)
|
|
|
|
protect_vertical: BoolProperty(
|
|
name="Protect Vertical",
|
|
description="The path goes only vertically next to steep areas",
|
|
default=True,
|
|
update=update_operation,
|
|
)
|
|
|
|
protect_vertical_limit: FloatProperty(
|
|
name="Verticality Limit",
|
|
description="What angle is already considered vertical",
|
|
default=pi / 45,
|
|
min=0,
|
|
max=pi * 0.5,
|
|
precision=0,
|
|
subtype="ANGLE",
|
|
unit="ROTATION",
|
|
update=update_operation,
|
|
)
|
|
|
|
|
|
class CAM_MOVEMENT_Panel(CAMButtonsPanel, Panel):
|
|
"""CAM Movement Panel"""
|
|
|
|
bl_space_type = "VIEW_3D"
|
|
bl_region_type = "UI"
|
|
bl_category = "CNC"
|
|
|
|
bl_label = "[ Movement ]"
|
|
bl_idname = "WORLD_PT_CAM_MOVEMENT"
|
|
panel_interface_level = 0
|
|
|
|
def draw(self, context):
|
|
layout = self.layout
|
|
layout.use_property_split = True
|
|
layout.use_property_decorate = False
|
|
|
|
# Milling Type
|
|
if self.level >= 1:
|
|
col = layout.column()
|
|
col.scale_y = 1.2
|
|
movement = self.op.movement.type
|
|
if movement == "MEANDER":
|
|
icon = "ANIM"
|
|
elif movement == "CLIMB":
|
|
icon = "SORT_ASC"
|
|
else:
|
|
icon = "SORT_DESC"
|
|
col.prop(self.op.movement, "type", text="Milling Type", icon=icon)
|
|
if self.op.movement.type in ["BLOCK", "SPIRAL", "CIRCLES"]:
|
|
col.prop(self.op.movement, "insideout")
|
|
|
|
# Spindle Rotation
|
|
if self.level >= 2:
|
|
rotation = self.op.movement.spindle_rotation
|
|
icon = "LOOP_FORWARDS" if rotation == "CW" else "LOOP_BACK"
|
|
col.prop(self.op.movement, "spindle_rotation", text="Cutter Spin", icon=icon)
|
|
|
|
# Free Height
|
|
box = layout.box()
|
|
boxcol = box.column(align=True)
|
|
boxcol.label(text="Z Clearance", icon="CON_FLOOR")
|
|
boxcol.prop(self.op.movement, "free_height")
|
|
if self.op.max_z > self.op.movement.free_height:
|
|
box = boxcol.box()
|
|
subcol = box.column(align=True)
|
|
subcol.alert = True
|
|
subcol.label(text="! POSSIBLE COLLISION !", icon="ERROR")
|
|
subcol.label(text="Depth Start > Free Movement")
|
|
|
|
# Stay Low
|
|
row = layout.row()
|
|
row.use_property_split = False
|
|
row.prop(self.op.movement, "stay_low", text="Stay Low (if possible)")
|
|
|
|
# Parallel Stepback
|
|
if self.level >= 1:
|
|
if self.op.strategy in ["PARALLEL", "CROSS"]:
|
|
if not self.op.movement.ramp:
|
|
row = layout.row()
|
|
row.use_property_split = False
|
|
row.prop(self.op.movement, "parallel_step_back")
|
|
|
|
if self.level >= 2:
|
|
# Use G64
|
|
if context.scene.cam_machine.post_processor not in G64_INCOMPATIBLE_MACHINES:
|
|
layout.use_property_split = False
|
|
header, panel = layout.panel("g64", default_closed=True)
|
|
header.prop(self.op.movement, "useG64", text="G64 Trajectory")
|
|
if panel:
|
|
panel.enabled = self.op.movement.useG64
|
|
col = panel.column(align=True)
|
|
col.use_property_split = True
|
|
col.prop(self.op.movement, "G64", text="Tolerance")
|
|
|
|
# Retract Tangential
|
|
if self.op.strategy in ["POCKET"]:
|
|
layout.use_property_split = False
|
|
header, panel = layout.panel("tengential", default_closed=True)
|
|
header.prop(self.op.movement, "retract_tangential", text="Retract Tangential")
|
|
if panel:
|
|
panel.enabled = self.op.movement.retract_tangential
|
|
col = panel.column(align=True)
|
|
col.use_property_split = True
|
|
col.prop(self.op.movement, "retract_radius", text="Arc Radius")
|
|
col.prop(self.op.movement, "retract_height", text="Arc Height")
|
|
|
|
# Protect Vertical
|
|
if self.level >= 1:
|
|
if self.op.cutter_type not in ["BALLCONE"]:
|
|
layout.use_property_split = False
|
|
header, panel = layout.panel("vertical", default_closed=False)
|
|
header.prop(self.op.movement, "protect_vertical", text="Protect Vertical")
|
|
if panel:
|
|
panel.enabled = self.op.movement.protect_vertical
|
|
col = panel.column(align=True)
|
|
col.use_property_split = True
|
|
col.prop(self.op.movement, "protect_vertical_limit", text="Angle Limit")
|
|
|
|
if self.level >= 3:
|
|
header, parent_panel = layout.panel("experiment", default_closed=True)
|
|
header.label(text="╼ EXPERIMENTAL ╾", icon="EXPERIMENTAL")
|
|
if parent_panel:
|
|
col = parent_panel.column(align=True)
|
|
|
|
# Merge Distance
|
|
if self.op.movement.stay_low:
|
|
row = col.row()
|
|
row.use_property_split = True
|
|
row.prop(self.op.movement, "merge_dist", text="Merge Distance")
|
|
|
|
# Helix Enter
|
|
if self.op.strategy in ["POCKET"]:
|
|
header, panel = col.panel("helix", default_closed=True)
|
|
header.prop(self.op.movement, "helix_enter", text="Helix Enter")
|
|
if panel:
|
|
subcol = panel.column(align=True)
|
|
subcol.use_property_split = True
|
|
subcol.enabled = self.op.movement.helix_enter
|
|
subcol.prop(self.op.movement, "ramp_in_angle")
|
|
subcol.prop(self.op.movement, "helix_diameter")
|
|
|
|
# Ramp
|
|
header, panel = col.panel("ramps", default_closed=True)
|
|
header.prop(self.op.movement, "ramp", text="Ramp")
|
|
if panel:
|
|
subcol = panel.column(align=True)
|
|
subcol.enabled = self.op.movement.ramp
|
|
row = subcol.row()
|
|
row.use_property_split = True
|
|
row.prop(self.op.movement, "ramp_in_angle", text="In Angle")
|
|
subheader, subpanel = subcol.panel("ramps_o", default_closed=True)
|
|
subheader.prop(self.op.movement, "ramp_out", text="Ramp Out")
|
|
if subpanel:
|
|
row = subcol.row()
|
|
row.use_property_split = True
|
|
row.enabled = self.op.movement.ramp_out
|
|
row.prop(self.op.movement, "ramp_out_angle", text="Out Angle")
|