Browse Source

Multiple Programs, discretize hatchline for height information

master
Jörg Kurlbaum 3 years ago
parent
commit
70b66c6719
  1. 74
      freecad/LaserCladdingWorkbench/commands.py
  2. 88
      freecad/LaserCladdingWorkbench/kuka.py
  3. 36
      freecad/LaserCladdingWorkbench/pad.py
  4. 4
      freecad/LaserCladdingWorkbench/program.py
  5. 7
      freecad/LaserCladdingWorkbench/templates/lasercladding.dat
  6. 48
      freecad/LaserCladdingWorkbench/templates/lasercladding.src
  7. 25
      freecad/LaserCladdingWorkbench/utils.py

74
freecad/LaserCladdingWorkbench/commands.py

@ -53,11 +53,11 @@ class LCSelectBaseReference():
class LCCreatePad(): class LCCreatePad():
def _create_laserpad(self, ref_to_face): def _create_laserpad(self, laserprogram, ref_to_face):
laserprogram = App.ActiveDocument.getObject('LaserProgram') #laserprogram = App.ActiveDocument.getObject('LaserProgram')
if laserprogram is None: #if laserprogram is None:
App.Console.PrintMessage('Create a LaserProgram first') # App.Console.PrintMessage('Create a LaserProgram first')
return # return
pad_obj = laserprogram.newObject("App::FeaturePython","LaserPad") pad_obj = laserprogram.newObject("App::FeaturePython","LaserPad")
LaserPad(pad_obj, ref_to_face) LaserPad(pad_obj, ref_to_face)
ViewProviderLaserPad(pad_obj.ViewObject) ViewProviderLaserPad(pad_obj.ViewObject)
@ -72,8 +72,29 @@ class LCCreatePad():
App.Console.PrintMessage('Select a Face') App.Console.PrintMessage('Select a Face')
return return
# check length # check length
ref_face = (Gui.Selection.getSelection()[0], selection = Gui.Selection.getSelectionEx()
Gui.Selection.getSelectionEx()[0].SubElementNames[0]) if len(selection) != 2:
App.Console.PrintMessage('Select a Face and a LaserProgram')
return
# find the Program
prog = None
face = None
if selection[0].Object.Name.startswith('LaserProgram'):
prog = selection[0].Object
ref_face = (selection[1].Object, Gui.Selection.getSelectionEx()[1].SubElementNames[0])
elif selection[1].Object.Name.startswith('LaserProgram'):
prog = selection[1].Object
ref_face = (selection[0].Object, Gui.Selection.getSelectionEx()[0].SubElementNames[0])
else:
App.Console.PrintMessage('Please select a LaserProgram')
return
#if program is None:
# App.Console.PrintMessage('Please select a LaserProgram')
# return
#ref_face = (Gui.Selection.getSelection()[0],
# Gui.Selection.getSelectionEx()[0].SubElementNames[0])
#selection = Gui.Selection.getSelectionEx() #selection = Gui.Selection.getSelectionEx()
# find first vertex # find first vertex
#for s in selection: #for s in selection:
@ -81,7 +102,7 @@ class LCCreatePad():
# for obj in s.SubObjects: # for obj in s.SubObjects:
# if isinstance(obj, Part.Face): # if isinstance(obj, Part.Face):
# face = obj.copy() # face = obj.copy()
self._create_laserpad(ref_face) self._create_laserpad(prog, ref_face)
App.ActiveDocument.recompute() App.ActiveDocument.recompute()
@ -118,7 +139,16 @@ class LCSaveProg():
def Activated(self): def Activated(self):
# Here your write what your ScriptCmd does... # Here your write what your ScriptCmd does...
App.Console.PrintMessage('Saving to KRL') App.Console.PrintMessage('Saving to KRL')
c = App.ActiveDocument.getObject("LaserProgram") if not Gui.Selection.hasSelection():
App.Console.PrintMessage('Select a Face')
return
selection = Gui.Selection.getSelectionEx()
c = None
if selection[0].Object.Name.startswith('LaserProgram'):
c = selection[0].Object
if c is None:
App.Console.PrintMessage('Selection is not a LaserProgram')
#c = App.ActiveDocument.getObject("LaserProgram")
pads = c.Group pads = c.Group
prog = Kuka_Prog() prog = Kuka_Prog()
prog.set_baseorigin(c.base_reference) prog.set_baseorigin(c.base_reference)
@ -128,7 +158,7 @@ class LCSaveProg():
prog.set_laser_power(c.laser_power) prog.set_laser_power(c.laser_power)
prog.set_laser_out(c.laser_real_out) prog.set_laser_out(c.laser_real_out)
prog.set_simulation(c.simulation) prog.set_simulation(c.simulation)
prog.set_label(c.Label)
for pad in pads: for pad in pads:
# one pad with contours and hatchlines # one pad with contours and hatchlines
prog.create_layer() prog.create_layer()
@ -151,18 +181,24 @@ class LCSaveProg():
prog.append_contour(poses, pathtype) prog.append_contour(poses, pathtype)
elif re.match('Hatch*', progpart.Name): elif re.match('Hatch*', progpart.Name):
face = pad.ref_body.getSubObject(pad.ref_surface) face = pad.ref_body.getSubObject(pad.ref_surface)
edges = progpart.Shape.Edges wires = progpart.Shape.Wires
for edge in edges: print("Number Hatchlines: ", len(wires))
p0 = edge.Vertexes[0].Point counter = 0
p1 = edge.Vertexes[1].Point for wire in wires:
line = [] line = []
for p in [p0, p1]: for edge in wire.Edges:
uv = face.Surface.parameter(p) p0 = edge.Vertexes[0].Point
normal = face.normalAt(uv[0], uv[1]) p1 = edge.Vertexes[1].Point
pose = Kuka_Pose.from_point_and_normal(p, normal) for p in [p0, p1]:
line.append(pose) uv = face.Surface.parameter(p)
normal = face.normalAt(uv[0], uv[1])
pose = Kuka_Pose.from_point_and_normal(p, normal)
line.append(pose)
print("append line: ", counter)
counter += 1
prog.append_hatchline(line, progpart.pathtype) prog.append_hatchline(line, progpart.pathtype)
#prog.save_prog(c.article, c.progpath) #prog.save_prog(c.article, c.progpath)
if c.templatename is None: if c.templatename is None:
templatename = "lasercladding" templatename = "lasercladding"

88
freecad/LaserCladdingWorkbench/kuka.py

@ -41,6 +41,7 @@ class Kuka_Prog:
self.inert_gas_out = 9 self.inert_gas_out = 9
self.powder_out = 7 self.powder_out = 7
self.simulation = True self.simulation = True
self.label = "REPLACEME"
def set_baseorigin(self, vec): def set_baseorigin(self, vec):
self.baseorigin = (vec.x, vec.y, vec.z) self.baseorigin = (vec.x, vec.y, vec.z)
@ -71,6 +72,9 @@ class Kuka_Prog:
else: else:
self.use_laser_out = self.laser_pilot_out self.use_laser_out = self.laser_pilot_out
def set_label(self, label):
self.label = label
def create_layer(self): def create_layer(self):
self.layers.append(Kuka_Layer()) self.layers.append(Kuka_Layer())
self.current_layer += 1 self.current_layer += 1
@ -84,6 +88,7 @@ class Kuka_Prog:
layer = self.layers[self.current_layer] layer = self.layers[self.current_layer]
if not len(layer.hatchlines): if not len(layer.hatchlines):
layer.hatchlines.append((line, segmenttype)) layer.hatchlines.append((line, segmenttype))
return
# poses are sorted # poses are sorted
# but maybe we need to reverse # but maybe we need to reverse
# get the point distance from first and last pose # get the point distance from first and last pose
@ -110,12 +115,14 @@ class Kuka_Prog:
return [FreeCAD.Base.Vector(p.X, p.Y, p.Z) for p in poses for poses in self.contour_path_list ] return [FreeCAD.Base.Vector(p.X, p.Y, p.Z) for p in poses for poses in self.contour_path_list ]
def save_with_template(self, article, path, templatename): def save_with_template(self, article, path, templatename):
if article[0].isdigit():
article = "_"+article
if self.simulation: if self.simulation:
filename_src = "kvt_{}_sim.src".format(article) filename_src = "{}_sim.src".format(article)
filename_dat = "kvt_{}_sim.dat".format(article) filename_dat = "{}_sim.dat".format(article)
else: else:
filename_src = "kvt_{}.src".format(article) filename_src = "{}.src".format(article)
filename_dat = "kvt_{}.dat".format(article) filename_dat = "{}.dat".format(article)
user_dir = FreeCAD.getUserAppDataDir() user_dir = FreeCAD.getUserAppDataDir()
template_dir = os.path.join(user_dir, "Mod", "fc_lasercladding_wb", "freecad", "LaserCladdingWorkbench", "templates") template_dir = os.path.join(user_dir, "Mod", "fc_lasercladding_wb", "freecad", "LaserCladdingWorkbench", "templates")
@ -152,26 +159,40 @@ class Kuka_Prog:
# end of subroutine # end of subroutine
f.write(";- =============================\n") f.write(";- =============================\n")
f.write(";- Hatchlines\n") if len(layer.hatchlines):
f.write("$VEL.CP = TRAVELSPEED ; m/s ; m/s \n") print("Number Hatchlines: ", len(layer.hatchlines))
f.write("LIN_REL {Z 90.0} C_VEL; just move up \n") f.write(";- Hatchlines\n")
(line, seg_type) = layer.hatchlines[0] f.write("$VEL.CP = %f ; m/s ; m/s \n" % self.vmax)
f.write("LIN refpose:{}:{} C_VEL; move to first hatch point but with z_up\n".format(line[0].translate_with(self.baseorigin).to_string(), z_up_pose)) f.write("LIN_REL {Z 90.0} C_VEL; just move up \n")
for (line, seg_type) in layer.hatchlines: for (line, seg_type) in layer.hatchlines:
# start laser code # a line has many segments
f.write(";- Hatchline\n") # start laser at first segment
if seg_type == 'LIN': # stop with last
f.write("$VEL.CP = TRAVELSPEED ;m/s \n") f.write(";- Hatchline\n")
f.write("LIN refpose:{} C_VEL; GENERATED\n".format(line[0].translate_with(self.baseorigin).to_string())) segment = line[0]
f.write("TRIGGER WHEN DISTANCE=0 DELAY=0 DO $OUT[%d]=TRUE; Turn on Laser at point \n" % self.use_laser_out) f.write("$VEL.CP = %f ; m/s ; m/s \n" % self.vmax)
f.write("$VEL.CP = WELDSPEED ; m/s \n") f.write("LIN {}:{} C_VEL; move to first hatch point but with z_up\n".format(segment.translate_with(self.baseorigin).to_string(), z_up_pose))
f.write("LIN refpose:{} C_VEL; GENERATED\n".format(line[1].translate_with(self.baseorigin).to_string())) # One Hatchline
f.write(";- First Point in line \n")
f.write("LIN {} C_VEL; GENERATED\n".format(segment.translate_with(self.baseorigin).to_string()))
f.write("TRIGGER WHEN DISTANCE=0 DELAY=0 DO $OUT[%d]=True; Turn on Laser at point \n" % self.use_laser_out)
# each segment
for segment in line[1:-1]:
f.write("$VEL.CP = %f ; m/s ; m/s \n" % self.vproc)
f.write("LIN {} C_VEL; GENERATED\n".format(segment.translate_with(self.baseorigin).to_string()))
segment = line[-1]
f.write(";- Last Point in line \n")
f.write("LIN {} C_VEL; GENERATED\n".format(segment.translate_with(self.baseorigin).to_string()))
f.write("TRIGGER WHEN DISTANCE=0 DELAY=0 DO $OUT[%d]=FALSE; Turn off Laser at point\n" % self.use_laser_out) f.write("TRIGGER WHEN DISTANCE=0 DELAY=0 DO $OUT[%d]=FALSE; Turn off Laser at point\n" % self.use_laser_out)
f.write(";- End line \n")
f.write(";- ========= END LAYER =========\n") f.write(";- ========= END LAYER =========\n")
f.write(";- =============================\n") f.write(";- =============================\n")
# end of subroutine # end of subroutine
content = template_src.render( content = template_src.render(
simulation=self.simulation,
artikel=article, artikel=article,
tool=self.tool, tool=self.tool,
base=self.base, base=self.base,
@ -181,12 +202,14 @@ class Kuka_Prog:
laserpower=self.laser_power, laserpower=self.laser_power,
vproc=self.vproc, vproc=self.vproc,
vmax=self.vmax, vmax=self.vmax,
paths=f.getvalue() paths=f.getvalue(),
label=self.label
) )
# dat template # dat template
template_dat = environment.get_template(templatename+".dat") template_dat = environment.get_template(templatename+".dat")
datcontent = template_dat.render( datcontent = template_dat.render(
simulation=self.simulation,
artikel=article artikel=article
) )
@ -295,18 +318,25 @@ class Kuka_Prog:
srcfile.write(";- Hatchlines\n") srcfile.write(";- Hatchlines\n")
srcfile.write("$VEL.CP = %f ; m/s ; m/s \n" % self.vmax) srcfile.write("$VEL.CP = %f ; m/s ; m/s \n" % self.vmax)
srcfile.write("LIN_REL {Z 90.0} C_VEL; just move up \n") srcfile.write("LIN_REL {Z 90.0} C_VEL; just move up \n")
(line, seg_type) = layer.hatchlines[0]
srcfile.write("LIN {}:{} C_VEL; move to first hatch point but with z_up\n".format(line[0].translate_with(self.baseorigin).to_string(), z_up_pose))
for (line, seg_type) in layer.hatchlines: for (line, seg_type) in layer.hatchlines:
# start laser code # a line has many segments
# start laser at first segment
# stop with last
segment = line[0]
srcfile.write("$VEL.CP = %f ; m/s ; m/s \n" % self.vmax)
srcfile.write("LIN {}:{} C_VEL; move to first hatch point but with z_up\n".format(segment.translate_with(self.baseorigin).to_string(), z_up_pose))
# One Hatchline
srcfile.write(";- Hatchline\n") srcfile.write(";- Hatchline\n")
if seg_type == 'LIN': srcfile.write("LIN {} C_VEL; GENERATED\n".format(segment.translate_with(self.baseorigin).to_string()))
srcfile.write("$VEL.CP = %f ; m/s ; m/s \n" % self.vmax) srcfile.write("TRIGGER WHEN DISTANCE=0 DELAY=0 DO $OUT[%d]=True; Turn on Laser at point \n" % self.use_laser_out)
srcfile.write("LIN {} C_VEL; GENERATED\n".format(line[0].translate_with(self.baseorigin).to_string())) # each segment
srcfile.write("TRIGGER WHEN DISTANCE=0 DELAY=0 DO $OUT[%d]=True; Turn on Laser at point \n" % self.use_laser_out) for segment in line[1:-1]:
srcfile.write("$VEL.CP = %f ; m/s ; m/s \n" % self.vproc) srcfile.write("$VEL.CP = %f ; m/s ; m/s \n" % self.vproc)
srcfile.write("LIN {} C_VEL; GENERATED\n".format(line[1].translate_with(self.baseorigin).to_string())) srcfile.write("LIN {} C_VEL; GENERATED\n".format(segment.translate_with(self.baseorigin).to_string()))
srcfile.write("TRIGGER WHEN DISTANCE=0 DELAY=0 DO $OUT[%d]=FALSE; Turn off Laser at point\n" % self.use_laser_out) segment = line[-1]
srcfile.write("LIN {} C_VEL; GENERATED\n".format(segment.translate_with(self.baseorigin).to_string()))
srcfile.write("TRIGGER WHEN DISTANCE=0 DELAY=0 DO $OUT[%d]=FALSE; Turn off Laser at point\n" % self.use_laser_out)
srcfile.write(";- ========= END LAYER =========\n") srcfile.write(";- ========= END LAYER =========\n")
srcfile.write(";- =============================\n") srcfile.write(";- =============================\n")
# end of subroutine # end of subroutine

36
freecad/LaserCladdingWorkbench/pad.py

@ -37,6 +37,9 @@ class LaserPad:
obj.addProperty("App::PropertyFloat", "hatch_contour_offset", "Parameters", "Contour Offset") obj.addProperty("App::PropertyFloat", "hatch_contour_offset", "Parameters", "Contour Offset")
obj.hatch_contour_offset = 2.3 obj.hatch_contour_offset = 2.3
obj.addProperty("App::PropertyBool", "hatching_enabled", "Parameters", "Hatch inner Region")
obj.hatching_enabled = True
obj.addProperty("App::PropertyFloat", "z_offset", "Parameters", "Height (Z) Offset") obj.addProperty("App::PropertyFloat", "z_offset", "Parameters", "Height (Z) Offset")
obj.z_offset = 0 obj.z_offset = 0
@ -46,6 +49,17 @@ class LaserPad:
obj.addProperty("App::PropertyString","ref_surface","Reference","face") obj.addProperty("App::PropertyString","ref_surface","Reference","face")
obj.ref_surface = face[1] obj.ref_surface = face[1]
obj.addProperty("App::PropertyBool","debug_polygons","Debugging","Show Polygons from shapely")
obj.debug_polygons = False
obj.addProperty("App::PropertyBool","debug_rdp","Debugging","Simplify polygons")
obj.debug_rdp = False
obj.addProperty("App::PropertyFloat","debug_rdp_epsilon","Debugging","Epsilon")
obj.debug_rdp_epsilon = 0.2
obj.addProperty("App::PropertyFloat","debug_discretization","Debugging","Discretization")
obj.debug_discretization = 2.3
obj.addExtension("App::GroupExtensionPython") obj.addExtension("App::GroupExtensionPython")
obj.Proxy = self obj.Proxy = self
self._create_path(obj) self._create_path(obj)
@ -57,6 +71,7 @@ class LaserPad:
# obj.removeObjectsFromDocument() # obj.removeObjectsFromDocument()
face = obj.ref_body.getSubObject(obj.ref_surface) face = obj.ref_body.getSubObject(obj.ref_surface)
myHatcher = hatching.Hatcher() myHatcher = hatching.Hatcher()
myHatcher.hatchingEnabled = obj.hatching_enabled
myHatcher.hatchDistance = obj.tool_width myHatcher.hatchDistance = obj.tool_width
myHatcher.hatchAngle = obj.hatch_angle myHatcher.hatchAngle = obj.hatch_angle
myHatcher.volumeOffsetHatch = obj.hatch_volume_offset myHatcher.volumeOffsetHatch = obj.hatch_volume_offset
@ -66,17 +81,18 @@ class LaserPad:
myHatcher.contourOffset = obj.hatch_contour_offset myHatcher.contourOffset = obj.hatch_contour_offset
myHatcher.hatchSortMethod = hatching.AlternateSort() myHatcher.hatchSortMethod = hatching.AlternateSort()
polygon_coords = get_coords_from_shape(face) polygon_coords = get_coords_from_shape(face, obj.debug_rdp_epsilon, obj.debug_discretization)
print("===== coords from shape ======") print("===== coords from shape ======")
print("{}", polygon_coords) print("{}", polygon_coords)
print("===== ======") print("===== ======")
## debug ## debug
# for poly in polygon_coords: if obj.debug_polygons:
# c = Part.makeCompound([]) for poly in polygon_coords:
# vertex_list = [App.Vector(x,y,0) for x,y in poly] c = Part.makeCompound([])
# c.add(Part.makePolygon(vertex_list)) vertex_list = [App.Vector(x,y,0) for x,y in poly]
# Part.show(c) c.add(Part.makePolygon(vertex_list))
Part.show(c)
layer = myHatcher.hatch(polygon_coords) layer = myHatcher.hatch(polygon_coords)
@ -102,8 +118,12 @@ class LaserPad:
print("Creating Hatch Part") print("Creating Hatch Part")
hatches_comp = obj.newObject("Part::Feature", "Hatchlines") hatches_comp = obj.newObject("Part::Feature", "Hatchlines")
p = Part.makeCompound([]) p = Part.makeCompound([])
for pc in proj_hatchlines: for hatchline in proj_hatchlines:
p.add(Part.makeCompound(pc)) # discretize by length
for line in hatchline:
wire_sections = line.Wires[0].discretize(Distance=3.0)
wire = Part.makePolygon(wire_sections)
p.add(wire)
LaserPath(hatches_comp) LaserPath(hatches_comp)
hatches_comp.Shape = p hatches_comp.Shape = p

4
freecad/LaserCladdingWorkbench/program.py

@ -23,10 +23,10 @@ class LaserProgram:
obj.laser_real_out = 3 obj.laser_real_out = 3
obj.addProperty("App::PropertyInteger", "laser_gas_out", "Laser Parameter", "Laser inert gas") obj.addProperty("App::PropertyInteger", "laser_gas_out", "Laser Parameter", "Laser inert gas")
obj.laser_gas_out = 9 obj.laser_gas_out = 7
obj.addProperty("App::PropertyInteger", "laser_powder_out", "Laser Parameter", "Laser Powder Bucket") obj.addProperty("App::PropertyInteger", "laser_powder_out", "Laser Parameter", "Laser Powder Bucket")
obj.laser_powder_out = 7 obj.laser_powder_out = 8
obj.addProperty("App::PropertyFloat", "laser_feedrate", "Laser Parameter", "Process Velocity (Feedrate m/s)") obj.addProperty("App::PropertyFloat", "laser_feedrate", "Laser Parameter", "Process Velocity (Feedrate m/s)")
obj.laser_feedrate = 0.022500 obj.laser_feedrate = 0.022500

7
freecad/LaserCladdingWorkbench/templates/lasercladding.dat

@ -2,7 +2,12 @@
&REL 47 &REL 47
&PARAM TEMPLATE = C:\KRC\Roboter\Template\ExpertVorgabe &PARAM TEMPLATE = C:\KRC\Roboter\Template\ExpertVorgabe
&PARAM EDITMASK = * &PARAM EDITMASK = *
DEFDAT kvt_{{artikel}} PUBLIC {%- if simulation %}
DEFDAT k{{artikel}}_sim PUBLIC
{%- else %}
DEFDAT k{{artikel}} PUBLIC
{%- endif %}
;FOLD EXTERNAL DECLARATIONS;%{PE}%MKUKATPBASIS,%CEXT,%VCOMMON,%P ;FOLD EXTERNAL DECLARATIONS;%{PE}%MKUKATPBASIS,%CEXT,%VCOMMON,%P
;FOLD BASISTECH EXT;%{PE}%MKUKATPBASIS,%CEXT,%VEXT,%P ;FOLD BASISTECH EXT;%{PE}%MKUKATPBASIS,%CEXT,%VEXT,%P
DECL INT SUCCESS DECL INT SUCCESS

48
freecad/LaserCladdingWorkbench/templates/lasercladding.src

@ -2,9 +2,15 @@
&REL 1 &REL 1
&PARAM TEMPLATE = C:\KRC\Roboter\Template\ExpertVorgabe &PARAM TEMPLATE = C:\KRC\Roboter\Template\ExpertVorgabe
&PARAM EDITMASK = * &PARAM EDITMASK = *
DEF kvt_{{artikel}}( ) {%- if simulation %}
DEF k{{artikel}}_sim( )
{%- else %}
DEF k{{artikel}}( )
{%- endif %}
;- Kuka src file, generated by FreeCAD LaserCladding WorkBench (by KVT) ;- Kuka src file, generated by FreeCAD LaserCladding WorkBench (by KVT)
;- Artikelnummer: {{artikel}}
;- Programm: {{label}}
;- Anweisungen ..
E6POS refpose E6POS refpose
E6POS pulverstart E6POS pulverstart
@ -12,6 +18,9 @@ REAL WELDSPEED
REAL TRAVELSPEED REAL TRAVELSPEED
REAL LASERPOWER REAL LASERPOWER
INT POWDEROUT INT POWDEROUT
REAL OFFSET_X
REAL OFFSET_Y
REAL OFFSET_Z
;------------- definitions ------------ ;------------- definitions ------------
EXT BAS (BAS_COMMAND :IN,REAL :IN ) ;set base to World EXT BAS (BAS_COMMAND :IN,REAL :IN ) ;set base to World
@ -40,6 +49,12 @@ WELDSPEED = {{vproc}}; m/s
LASERPOWER = {{laserpower}} ; Set laser power LASERPOWER = {{laserpower}} ; Set laser power
POWDEROUT = {{powder_out}} POWDEROUT = {{powder_out}}
;- Offset for tweaking (in mm)
;- Only experts!
OFFSET_X = 0.0 ; mm
OFFSET_Y = 0.0 ; mm
OFFSET_Z = 0.0 ; mm
;- Movement parameters ;- Movement parameters
$VEL.CP = TRAVELSPEED ; m/s ; m/s $VEL.CP = TRAVELSPEED ; m/s ; m/s
$APO.CDIS = 2.300000 ; mm $APO.CDIS = 2.300000 ; mm
@ -49,32 +64,47 @@ $APO.CVEL = 95.000000 ; percent
$ANOUT[1] = LASERPOWER ; Set laser power $ANOUT[1] = LASERPOWER ; Set laser power
$OUT[{{laser_out}}] = FALSE ; Set Laser off $OUT[{{laser_out}}] = FALSE ; Set Laser off
$OUT[2] = TRUE ; Set Laser activation on $OUT[2] = TRUE ; Set Laser activation on
$OUT[POWDER_OUT] = FALSE ; Set powder on $OUT[POWDEROUT] = FALSE ; Set powder off
$OUT[{{inert_gas_out}}] = FALSE ; Set inert gas on $OUT[{{inert_gas_out}}] = FALSE ; Set inert gas off
;- Ab hier nicht mehr aendern! ;- Ab hier nicht mehr aendern!
;- Starting point ;- Starting point
refpose=$POS_ACT refpose=$POS_ACT
pulverstart = {X -110.0, Y 0.0, Z 0.0, A 0.0000, B 0.0000, C 0.0000, E1 0.0000, E2 0.0000} ; zero out rotations
; because the base is already rectangular
refpose.A=0
refpose.B=0
refpose.C=0
; Offset draufrechnen (fummelfaktor)
refpose.X=refpose.X+OFFSET_X
refpose.Y=refpose.Y+OFFSET_Y
refpose.Z=refpose.Z+OFFSET_Z
pulverstart = {X 130.0, Y 0.0, Z 0.0, A 0.0000, B 0.0000, C 0.0000, E1 0.0000, E2 0.0000}
pulverstart.S = refpose.S pulverstart.S = refpose.S
pulverstart.T = refpose.T pulverstart.T = refpose.T
LIN refpose:pulverstart C_VEL; GENERATED LIN refpose:pulverstart C_VEL; GENERATED
WAIT SEC 7.0
$OUT[2] = TRUE ; Set Laser activation on $OUT[2] = TRUE ; Set Laser activation on
{% if simulation %}
$OUT[POWDEROUT] = FALSE ; OFF: SIMULATION Mode
$OUT[{{inert_gas_out}}] = FALSE ; OFF: SIMULATION Mode
{% else %}
$OUT[POWDEROUT] = TRUE ; Set powder on $OUT[POWDEROUT] = TRUE ; Set powder on
$OUT[{{inert_gas_out}}] = TRUE ; Set inert gas on $OUT[{{inert_gas_out}}] = TRUE ; Set inert gas on
{% endif %}
WAIT SEC 7.0
;- ============================= ;- =============================
;- == generated poses == ;- == generated poses ==
{{paths}} {{paths}}
;- ============================= ;- =============================
$OUT[{{laser_out}}] = FALSE ; Set Laser off $OUT[{{laser_out}}] = FALSE ; Set Laser off
$OUT[2] = FALSE ; Set Laser activation on $OUT[2] = FALSE ; Set Laser activation on
$OUT[POWDEROUT] = FALSE ; Set powder on $OUT[POWDEROUT] = FALSE ; Set powder on
$OUT[{{inert_gas_out}}] = FALSE ; Set inert gas on $OUT[{{inert_gas_out}}] = FALSE ; Set inert gas on
$VEL.CP = 0.100000 ; m/s ; m/s $VEL.CP = TRAVELSPEED ; m/s ; m/s
;- Move to HOME position ;- Move to HOME position
PTP {A1 -33.31, A2 -104.71, A3 114.60, A4 282.66, A5 -39.21, A6 -104.87, E1 -90, E2 1.0} PTP {A1 -33.31, A2 -104.71, A3 114.60, A4 282.66, A5 -39.21, A6 -104.87, E1 -90, E2 1.0}

25
freecad/LaserCladdingWorkbench/utils.py

@ -4,8 +4,10 @@ import FreeCADGui as Gui
import numpy as np import numpy as np
import math import math
import Part import Part
import Draft
import shapely import shapely
from shapely.geometry import Polygon, Point from shapely.geometry import Polygon, Point
from shapely.validation import make_valid, explain_validity
from pyslm import hatching as hatching from pyslm import hatching as hatching
from pyslm.geometry.geometry import LayerGeometryType from pyslm.geometry.geometry import LayerGeometryType
from typing import List from typing import List
@ -129,23 +131,28 @@ def get_polygon_from_subshape(subshape):
return polygon return polygon
def get_polygon_from_wire(wire): def get_polygon_from_wire(wire, discretization_factor):
polygon = [] polygon = []
n = math.floor(wire.Length/2.3) n = math.floor(wire.Length/discretization_factor)
for v in wire.discretize(Number=n): for v in wire.discretize(Number=n)[:-1]:
polygon.append((v.x, v.y)) polygon.append((v.x, v.y))
return polygon return polygon
def get_coords_from_shape(face): def get_coords_from_shape(face, rdp_epsilon, discretization_factor):
#outerpoly = get_polygon_from_subshape(face.OuterWire) #outerpoly = get_polygon_from_subshape(face.OuterWire)
outerpoly = get_polygon_from_wire(face.OuterWire) #sv0 = Draft.make_shape2dview(face.OuterWire, FreeCAD.Vector(0.0, 0.0, 1.0))
outerpoly = get_polygon_from_wire(face.OuterWire, discretization_factor)
inner_polys = [] inner_polys = []
for inner_wire in face.SubShapes[1:]: subshapes = [x for x in face.SubShapes if not x.isEqual(face.OuterWire)]
tmp = get_polygon_from_wire(inner_wire) for inner_wire in subshapes:
tmp = get_polygon_from_wire(inner_wire, discretization_factor)
inner_polys.append(tmp) inner_polys.append(tmp)
poly = Polygon(shell=outerpoly, holes=inner_polys) poly = Polygon(shell=outerpoly, holes=inner_polys)
print("Polygon: ", poly) print("Polygon: ", poly)
valid_poly = make_valid(poly)
print("Validated Polygon:", explain_validity(valid_poly))
return path2DToPathList([poly]) return path2DToPathList([poly])
@ -163,12 +170,12 @@ def create_hatch_lines(geoms):
return hatchlines return hatchlines
def create_contour_lines(geoms): def create_contour_lines(geoms, epsilon=0.2):
contours = [] contours = []
for geom in geoms: for geom in geoms:
if geom.type() == LayerGeometryType.Polygon: if geom.type() == LayerGeometryType.Polygon:
# print("Contour with {} coords".format(len(geom.coords))) # print("Contour with {} coords".format(len(geom.coords)))
coords = rdp.rdp(geom.coords, epsilon=0.2, algo="iter", return_mask=False) coords = rdp.rdp(geom.coords, epsilon=epsilon, algo="iter", return_mask=False)
#print("Simplfied Poly:", len(coords)) #print("Simplfied Poly:", len(coords))
pp = Part.makePolygon([App.Vector(x,y,0) for (x,y) in coords]) pp = Part.makePolygon([App.Vector(x,y,0) for (x,y) in coords])
contours.append(pp) contours.append(pp)

Loading…
Cancel
Save