Browse Source

new style workbench with macros integrates

master
Jörg Kurlbaum 3 years ago
parent
commit
9b23de480d
  1. 1
      .gitignore
  2. 47
      InitGui.py
  3. 6
      Resources/LaserCladding.qrc
  4. 11
      freecad/LaserCladdingWorkbench/Resources/LaserCladding.qrc
  5. 325
      freecad/LaserCladdingWorkbench/Resources/icons/LaserCreatePad.svg
  6. 362
      freecad/LaserCladdingWorkbench/Resources/icons/LaserCreateProg.svg
  7. 362
      freecad/LaserCladdingWorkbench/Resources/icons/LaserRecomputePad.svg
  8. 357
      freecad/LaserCladdingWorkbench/Resources/icons/LaserSaveProg.svg
  9. 373
      freecad/LaserCladdingWorkbench/Resources/icons/LaserSelectBaseRef.svg
  10. 0
      freecad/LaserCladdingWorkbench/Resources/icons/Laser_Workbench.svg
  11. 0
      freecad/LaserCladdingWorkbench/__init__.py
  12. 170
      freecad/LaserCladdingWorkbench/commands.py
  13. 63
      freecad/LaserCladdingWorkbench/init_gui.py
  14. 265
      freecad/LaserCladdingWorkbench/kuka.py
  15. 1029
      freecad/LaserCladdingWorkbench/lc_resource.py
  16. 195
      freecad/LaserCladdingWorkbench/pad.py
  17. 17
      freecad/LaserCladdingWorkbench/path.py
  18. 74
      freecad/LaserCladdingWorkbench/program.py
  19. 160
      freecad/LaserCladdingWorkbench/utils.py
  20. 6
      lasercladding/__init__.py
  21. 77
      lasercladding/commands.py
  22. 170
      lasercladding/kuka.py
  23. 149
      lasercladding/pad.py
  24. 16
      lasercladding/path.py

1
.gitignore vendored

@ -0,0 +1 @@ @@ -0,0 +1 @@
/freecad/LaserCladdingWorkbench/__pycache__/

47
InitGui.py

@ -1,47 +0,0 @@ @@ -1,47 +0,0 @@
import FreeCAD as App
class LaserCladding (Workbench):
MenuText = "Laser Cladding"
ToolTip = "Create Simple Path on workpieces for Laser Cladding"
Icon = """"""
def __init__(self):
__dirname__ = os.path.join(FreeCAD.getUserAppDataDir(), "Mod", "LaserCladding")
_tooltip = "The LaserCladding Workbench can create Paths for Robots"
self.__class__.Icon = os.path.join(__dirname__,
"Resources", "icons",
"Laser_Workbench.svg")
def Initialize(self):
"""This function is executed when the workbench is first activated.
It is executed once in a FreeCAD session followed by the Activated function.
"""
import lasercladding
self.list = ["CreateCladdingJob", "SelectBaseReference", "CreatePad"] # A list of command names created in the line above
self.appendToolbar("My Commands",self.list) # creates a new toolbar with your commands
self.appendMenu("LaserCladding",self.list) # creates a new menu
self.appendMenu(["LaserCladding","My submenu"],self.list) # appends a submenu to an existing menu
def Activated(self):
"""This function is executed whenever the workbench is activated"""
#from importlib import reload
#reload(lccmd)
return
def Deactivated(self):
"""This function is executed whenever the workbench is deactivated"""
return
def ContextMenu(self, recipient):
"""This function is executed whenever the user right-clicks on screen"""
# "recipient" will be either "view" or "tree"
self.appendContextMenu("My commands",self.list) # add commands to the context menu
def GetClassName(self):
# This function is mandatory if this is a full Python workbench
# This is not a template, the returned string should be exactly "Gui::PythonWorkbench"
return "Gui::PythonWorkbench"
Gui.addWorkbench(LaserCladding())

6
Resources/LaserCladding.qrc

@ -1,6 +0,0 @@ @@ -1,6 +0,0 @@
<RCC>
<qresource>
<file>icons/Laser_Workbench.svg</file>
<!-- <file>ui/preferences-draft.ui</file> -->
</qresource>
</RCC>

11
freecad/LaserCladdingWorkbench/Resources/LaserCladding.qrc

@ -0,0 +1,11 @@ @@ -0,0 +1,11 @@
<RCC>
<qresource>
<file>icons/Laser_Workbench.svg</file>
<file>icons/LaserCreatePad.svg</file>
<file>icons/LaserCreateProg.svg</file>
<file>icons/LaserRecomputePad.svg</file>
<file>icons/LaserSaveProg.svg</file>
<file>icons/LaserSelectBaseRef.svg</file>
<!-- <file>uiLaser_Workbench.svg/preferences-draft.ui</file> -->
</qresource>
</RCC>

325
freecad/LaserCladdingWorkbench/Resources/icons/LaserCreatePad.svg

@ -0,0 +1,325 @@ @@ -0,0 +1,325 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.1"
id="svg2766"
height="64px"
width="64px"
sodipodi:docname="LaserCreatePad.svg"
inkscape:version="1.0.2 (e86c870879, 2021-01-15)">
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="2057"
inkscape:window-height="1417"
id="namedview975"
showgrid="false"
inkscape:zoom="8.5625"
inkscape:cx="32"
inkscape:cy="31.883212"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg2766"
inkscape:document-rotation="0" />
<defs
id="defs2768">
<linearGradient
id="linearGradient3787">
<stop
style="stop-color:#0619c0;stop-opacity:1;"
offset="0"
id="stop3789" />
<stop
style="stop-color:#379cfb;stop-opacity:1;"
offset="1"
id="stop3791" />
</linearGradient>
<linearGradient
id="linearGradient3864">
<stop
style="stop-color:#0619c0;stop-opacity:1;"
offset="0"
id="stop3866" />
<stop
style="stop-color:#379cfb;stop-opacity:1;"
offset="1"
id="stop3868" />
</linearGradient>
<linearGradient
gradientTransform="matrix(1.0614931,0,0,1,-540.96941,-73.37642)"
y2="100.10708"
x2="609.54919"
y1="126.79625"
x1="581.26331"
gradientUnits="userSpaceOnUse"
id="linearGradient3181"
xlink:href="#linearGradient3864" />
<linearGradient
y2="92.711899"
x2="626.31323"
y1="92.711899"
x1="605.94659"
gradientTransform="matrix(-0.72140579,0.77867919,-0.73356972,-0.67961421,545.35072,-389.46656)"
gradientUnits="userSpaceOnUse"
id="linearGradient3184"
xlink:href="#linearGradient3864" />
<linearGradient
id="linearGradient3864-0">
<stop
style="stop-color:#0619c0;stop-opacity:1;"
offset="0"
id="stop3866-6" />
<stop
style="stop-color:#379cfb;stop-opacity:1;"
offset="1"
id="stop3868-2" />
</linearGradient>
<linearGradient
xlink:href="#linearGradient3864-0"
id="linearGradient3217"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.0614931,0,0,1,-643.22843,-82.445766)"
x1="605.94659"
y1="92.711899"
x2="626.31323"
y2="92.711899" />
<linearGradient
y2="92.711899"
x2="626.31323"
y1="92.711899"
x1="605.94659"
gradientTransform="matrix(1.1915091,0,0,1,-772.13265,-84.532596)"
gradientUnits="userSpaceOnUse"
id="linearGradient3184-4-0"
xlink:href="#linearGradient3864-0-2" />
<linearGradient
id="linearGradient3864-0-2">
<stop
style="stop-color:#0619c0;stop-opacity:1;"
offset="0"
id="stop3866-6-8" />
<stop
style="stop-color:#379cfb;stop-opacity:1;"
offset="1"
id="stop3868-2-3" />
</linearGradient>
<linearGradient
y2="92.711899"
x2="626.31323"
y1="92.711899"
x1="605.94659"
gradientTransform="matrix(1.1915091,0,0,1,-772.13265,-84.532596)"
gradientUnits="userSpaceOnUse"
id="linearGradient3184-4-4"
xlink:href="#linearGradient3864-0-9" />
<linearGradient
id="linearGradient3864-0-9">
<stop
style="stop-color:#0619c0;stop-opacity:1;"
offset="0"
id="stop3866-6-9" />
<stop
style="stop-color:#379cfb;stop-opacity:1;"
offset="1"
id="stop3868-2-4" />
</linearGradient>
<linearGradient
xlink:href="#linearGradient3864-0-9-5"
id="linearGradient4054-6"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.0614931,0.54122665,0,1,-692.52246,-451.18305)"
x1="634.20868"
y1="91.597527"
x2="679.06909"
y2="102.88628" />
<linearGradient
id="linearGradient3864-0-9-5">
<stop
style="stop-color:#0619c0;stop-opacity:1;"
offset="0"
id="stop3866-6-9-0" />
<stop
style="stop-color:#379cfb;stop-opacity:1;"
offset="1"
id="stop3868-2-4-0" />
</linearGradient>
<linearGradient
xlink:href="#linearGradient3864-0-9-5"
id="linearGradient4090"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.0614931,0.54122665,0,1,-687.73118,-415.49631)"
x1="634.20868"
y1="91.597527"
x2="679.06909"
y2="102.88628" />
<linearGradient
xlink:href="#linearGradient3864-0-9-5-0"
id="linearGradient4090-6"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.0614931,0.54122665,0,1,-687.73118,-415.49631)"
x1="634.20868"
y1="91.597527"
x2="679.06909"
y2="102.88628" />
<linearGradient
id="linearGradient3864-0-9-5-0">
<stop
style="stop-color:#0619c0;stop-opacity:1;"
offset="0"
id="stop3866-6-9-0-2" />
<stop
style="stop-color:#379cfb;stop-opacity:1;"
offset="1"
id="stop3868-2-4-0-5" />
</linearGradient>
<linearGradient
xlink:href="#linearGradient3864-0-9-5-0"
id="linearGradient4124"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.80817481,0.4120665,0,0.76135663,-517.34974,-304.44262)"
x1="634.20868"
y1="91.597527"
x2="679.06909"
y2="102.88628" />
<linearGradient
xlink:href="#linearGradient3864-0-2-2"
id="linearGradient4018-2"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.5385683,-0.86055196,0,0.96535888,-879.38043,517.26249)"
x1="635.40765"
y1="100.79263"
x2="672.73157"
y2="100.2725" />
<linearGradient
id="linearGradient3864-0-2-2">
<stop
style="stop-color:#0619c0;stop-opacity:1;"
offset="0"
id="stop3866-6-8-9" />
<stop
style="stop-color:#379cfb;stop-opacity:1;"
offset="1"
id="stop3868-2-3-2" />
</linearGradient>
<linearGradient
y2="48.117603"
x2="709.04407"
y1="114.56509"
x1="663.32715"
gradientTransform="matrix(1.5385683,0.52247795,0,0.96535888,-912.7401,-396.04414)"
gradientUnits="userSpaceOnUse"
id="linearGradient4073-8"
xlink:href="#linearGradient3864-0-1" />
<linearGradient
id="linearGradient3864-0-1">
<stop
style="stop-color:#0619c0;stop-opacity:1;"
offset="0"
id="stop3866-6-2" />
<stop
style="stop-color:#379cfb;stop-opacity:1;"
offset="1"
id="stop3868-2-47" />
</linearGradient>
<linearGradient
xlink:href="#linearGradient3864-0-9-6"
id="linearGradient4054-8"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.5385683,0.52247795,0,0.96535888,-912.7628,-417.24568)"
x1="634.20868"
y1="91.597527"
x2="679.06909"
y2="102.88628" />
<linearGradient
id="linearGradient3864-0-9-6">
<stop
style="stop-color:#0619c0;stop-opacity:1;"
offset="0"
id="stop3866-6-9-3" />
<stop
style="stop-color:#379cfb;stop-opacity:1;"
offset="1"
id="stop3868-2-4-7" />
</linearGradient>
</defs>
<metadata
id="metadata57">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
<cc:license
rdf:resource="" />
<dc:date>Mon Oct 10 13:44:52 2011 +0000</dc:date>
<dc:creator>
<cc:Agent>
<dc:title>[wmayer]</dc:title>
</cc:Agent>
</dc:creator>
<dc:rights>
<cc:Agent>
<dc:title>FreeCAD LGPL2+</dc:title>
</cc:Agent>
</dc:rights>
<dc:publisher>
<cc:Agent>
<dc:title>FreeCAD</dc:title>
</cc:Agent>
</dc:publisher>
<dc:identifier>FreeCAD/src/Mod/Draft/Resources/icons/Draft_2DShapeView.svg</dc:identifier>
<dc:relation>http://www.freecadweb.org/wiki/index.php?title=Artwork</dc:relation>
<dc:contributor>
<cc:Agent>
<dc:title>[agryson] Alexander Gryson</dc:title>
</cc:Agent>
</dc:contributor>
<dc:subject>
<rdf:Bag>
<rdf:li>box</rdf:li>
<rdf:li>plane</rdf:li>
<rdf:li>rectangle</rdf:li>
</rdf:Bag>
</dc:subject>
<dc:description>A box floating above a projection of its lower face</dc:description>
</cc:Work>
</rdf:RDF>
</metadata>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:40px;line-height:1.25;font-family:sans-serif;fill:#ff0000;fill-opacity:1;stroke:none;"
x="33.156479"
y="28.303833"
id="text883"><tspan
sodipodi:role="line"
id="tspan881"
x="33.156479"
y="28.303833">+</tspan></text>
<rect
style="fill:#af2200;fill-opacity:1;stroke:#ff0000;stroke-width:13.4715"
id="rect904"
width="22.772932"
height="13.027493"
x="12.983288"
y="37.288033" />
<path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="M 11.226277,39.41104 18.116788,36.626369 10.963047,49.379106 25.682938,40.245894 24.294252,51.655566 38.255018,41.974909 32.018704,31.533303 21.932938,34.943431 9.5104927,33.191606 10.690693,39.623631"
id="path908" />
</svg>

After

Width:  |  Height:  |  Size: 10 KiB

362
freecad/LaserCladdingWorkbench/Resources/icons/LaserCreateProg.svg

@ -0,0 +1,362 @@ @@ -0,0 +1,362 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.1"
id="svg2766"
height="64px"
width="64px"
sodipodi:docname="LaserCreateProg.svg"
inkscape:version="1.0.2 (e86c870879, 2021-01-15)">
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="2057"
inkscape:window-height="1417"
id="namedview975"
showgrid="false"
inkscape:zoom="8.5625"
inkscape:cx="32"
inkscape:cy="32"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg2766"
inkscape:document-rotation="0" />
<defs
id="defs2768">
<linearGradient
id="linearGradient3787">
<stop
style="stop-color:#0619c0;stop-opacity:1;"
offset="0"
id="stop3789" />
<stop
style="stop-color:#379cfb;stop-opacity:1;"
offset="1"
id="stop3791" />
</linearGradient>
<linearGradient
id="linearGradient3864">
<stop
style="stop-color:#0619c0;stop-opacity:1;"
offset="0"
id="stop3866" />
<stop
style="stop-color:#379cfb;stop-opacity:1;"
offset="1"
id="stop3868" />
</linearGradient>
<linearGradient
gradientTransform="matrix(1.0614931,0,0,1,-540.96941,-73.37642)"
y2="100.10708"
x2="609.54919"
y1="126.79625"
x1="581.26331"
gradientUnits="userSpaceOnUse"
id="linearGradient3181"
xlink:href="#linearGradient3864" />
<linearGradient
y2="92.711899"
x2="626.31323"
y1="92.711899"
x1="605.94659"
gradientTransform="matrix(-0.72140579,0.77867919,-0.73356972,-0.67961421,545.35072,-389.46656)"
gradientUnits="userSpaceOnUse"
id="linearGradient3184"
xlink:href="#linearGradient3864" />
<linearGradient
id="linearGradient3864-0">
<stop
style="stop-color:#0619c0;stop-opacity:1;"
offset="0"
id="stop3866-6" />
<stop
style="stop-color:#379cfb;stop-opacity:1;"
offset="1"
id="stop3868-2" />
</linearGradient>
<linearGradient
xlink:href="#linearGradient3864-0"
id="linearGradient3217"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.0614931,0,0,1,-643.22843,-82.445766)"
x1="605.94659"
y1="92.711899"
x2="626.31323"
y2="92.711899" />
<linearGradient
y2="92.711899"
x2="626.31323"
y1="92.711899"
x1="605.94659"
gradientTransform="matrix(1.1915091,0,0,1,-772.13265,-84.532596)"
gradientUnits="userSpaceOnUse"
id="linearGradient3184-4-0"
xlink:href="#linearGradient3864-0-2" />
<linearGradient
id="linearGradient3864-0-2">
<stop
style="stop-color:#0619c0;stop-opacity:1;"
offset="0"
id="stop3866-6-8" />
<stop
style="stop-color:#379cfb;stop-opacity:1;"
offset="1"
id="stop3868-2-3" />
</linearGradient>
<linearGradient
y2="92.711899"
x2="626.31323"
y1="92.711899"
x1="605.94659"
gradientTransform="matrix(1.1915091,0,0,1,-772.13265,-84.532596)"
gradientUnits="userSpaceOnUse"
id="linearGradient3184-4-4"
xlink:href="#linearGradient3864-0-9" />
<linearGradient
id="linearGradient3864-0-9">
<stop
style="stop-color:#0619c0;stop-opacity:1;"
offset="0"
id="stop3866-6-9" />
<stop
style="stop-color:#379cfb;stop-opacity:1;"
offset="1"
id="stop3868-2-4" />
</linearGradient>
<linearGradient
xlink:href="#linearGradient3864-0-9-5"
id="linearGradient4054-6"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.0614931,0.54122665,0,1,-692.52246,-451.18305)"
x1="634.20868"
y1="91.597527"
x2="679.06909"
y2="102.88628" />
<linearGradient
id="linearGradient3864-0-9-5">
<stop
style="stop-color:#0619c0;stop-opacity:1;"
offset="0"
id="stop3866-6-9-0" />
<stop
style="stop-color:#379cfb;stop-opacity:1;"
offset="1"
id="stop3868-2-4-0" />
</linearGradient>
<linearGradient
xlink:href="#linearGradient3864-0-9-5"
id="linearGradient4090"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.0614931,0.54122665,0,1,-687.73118,-415.49631)"
x1="634.20868"
y1="91.597527"
x2="679.06909"
y2="102.88628" />
<linearGradient
xlink:href="#linearGradient3864-0-9-5-0"
id="linearGradient4090-6"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.0614931,0.54122665,0,1,-687.73118,-415.49631)"
x1="634.20868"
y1="91.597527"
x2="679.06909"
y2="102.88628" />
<linearGradient
id="linearGradient3864-0-9-5-0">
<stop
style="stop-color:#0619c0;stop-opacity:1;"
offset="0"
id="stop3866-6-9-0-2" />
<stop
style="stop-color:#379cfb;stop-opacity:1;"
offset="1"
id="stop3868-2-4-0-5" />
</linearGradient>
<linearGradient
xlink:href="#linearGradient3864-0-9-5-0"
id="linearGradient4124"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.80817481,0.4120665,0,0.76135663,-517.34974,-304.44262)"
x1="634.20868"
y1="91.597527"
x2="679.06909"
y2="102.88628" />
<linearGradient
xlink:href="#linearGradient3864-0-2-2"
id="linearGradient4018-2"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.5385683,-0.86055196,0,0.96535888,-879.38043,517.26249)"
x1="635.40765"
y1="100.79263"
x2="672.73157"
y2="100.2725" />
<linearGradient
id="linearGradient3864-0-2-2">
<stop
style="stop-color:#0619c0;stop-opacity:1;"
offset="0"
id="stop3866-6-8-9" />
<stop
style="stop-color:#379cfb;stop-opacity:1;"
offset="1"
id="stop3868-2-3-2" />
</linearGradient>
<linearGradient
y2="48.117603"
x2="709.04407"
y1="114.56509"
x1="663.32715"
gradientTransform="matrix(1.5385683,0.52247795,0,0.96535888,-912.7401,-396.04414)"
gradientUnits="userSpaceOnUse"
id="linearGradient4073-8"
xlink:href="#linearGradient3864-0-1" />
<linearGradient
id="linearGradient3864-0-1">
<stop
style="stop-color:#0619c0;stop-opacity:1;"
offset="0"
id="stop3866-6-2" />
<stop
style="stop-color:#379cfb;stop-opacity:1;"
offset="1"
id="stop3868-2-47" />
</linearGradient>
<linearGradient
xlink:href="#linearGradient3864-0-9-6"
id="linearGradient4054-8"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.5385683,0.52247795,0,0.96535888,-912.7628,-417.24568)"
x1="634.20868"
y1="91.597527"
x2="679.06909"
y2="102.88628" />
<linearGradient
id="linearGradient3864-0-9-6">
<stop
style="stop-color:#0619c0;stop-opacity:1;"
offset="0"
id="stop3866-6-9-3" />
<stop
style="stop-color:#379cfb;stop-opacity:1;"
offset="1"
id="stop3868-2-4-7" />
</linearGradient>
</defs>
<g
id="layer1">
<path
id="rect3200-5-3"
d="M 33,35 5,49 33,59 59,45 z m 0,5 16,6 -16,8 -17,-6 z"
style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#0b1521;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
</g>
<metadata
id="metadata57">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
<cc:license
rdf:resource="" />
<dc:date>Mon Oct 10 13:44:52 2011 +0000</dc:date>
<dc:creator>
<cc:Agent>
<dc:title>[wmayer]</dc:title>
</cc:Agent>
</dc:creator>
<dc:rights>
<cc:Agent>
<dc:title>FreeCAD LGPL2+</dc:title>
</cc:Agent>
</dc:rights>
<dc:publisher>
<cc:Agent>
<dc:title>FreeCAD</dc:title>
</cc:Agent>
</dc:publisher>
<dc:identifier>FreeCAD/src/Mod/Draft/Resources/icons/Draft_2DShapeView.svg</dc:identifier>
<dc:relation>http://www.freecadweb.org/wiki/index.php?title=Artwork</dc:relation>
<dc:contributor>
<cc:Agent>
<dc:title>[agryson] Alexander Gryson</dc:title>
</cc:Agent>
</dc:contributor>
<dc:subject>
<rdf:Bag>
<rdf:li>box</rdf:li>
<rdf:li>plane</rdf:li>
<rdf:li>rectangle</rdf:li>
</rdf:Bag>
</dc:subject>
<dc:description>A box floating above a projection of its lower face</dc:description>
</cc:Work>
</rdf:RDF>
</metadata>
<path
style="fill:#ff0000;stroke:#ff0000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="M 33.119982,5.9005474 V 43.968066"
id="path1011" />
<ellipse
style="fill:#ff1a00;fill-opacity:1;stroke:none;stroke-width:9.49383"
id="path1020"
cx="33.058163"
cy="44.76939"
rx="1.6904655"
ry="1.6950274" />
<path
style="fill:none;stroke:#ff0000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="M 33.119982,43.968066 38.117245,40"
id="path1022" />
<path
style="fill:none;stroke:#ff0000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="M 33.119982,43.968066 29.151916,38.970803"
id="path1022-3" />
<path
style="fill:none;stroke:#ff0000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 33.119982,43.968066 -6.204197,-1.49202"
id="path1022-6"
inkscape:transform-center-x="2.4142336"
inkscape:transform-center-y="-0.3120438" />
<path
style="fill:none;stroke:#ff0000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 33.119982,43.968066 -5.853996,2.539469"
id="path1022-5"
inkscape:transform-center-x="-2.177793"
inkscape:transform-center-y="2.5275147" />
<path
style="fill:none;stroke:#ff0000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 33.316894,43.931615 5.935078,2.343723"
id="path1022-35"
inkscape:transform-center-x="-3.2044307"
inkscape:transform-center-y="1.9014819" />
<path
style="fill:none;stroke:#ff0000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 33.119982,43.968066 6.311789,-0.937814"
id="path1022-62" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:40px;line-height:1.25;font-family:sans-serif;fill:#00de00;fill-opacity:1;stroke:none;"
x="33.156479"
y="28.303833"
id="text883"><tspan
sodipodi:role="line"
id="tspan881"
x="33.156479"
y="28.303833">+</tspan></text>
</svg>

After

Width:  |  Height:  |  Size: 12 KiB

362
freecad/LaserCladdingWorkbench/Resources/icons/LaserRecomputePad.svg

@ -0,0 +1,362 @@ @@ -0,0 +1,362 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.1"
id="svg2766"
height="64px"
width="64px"
sodipodi:docname="LaserRecomputePad.svg"
inkscape:version="1.0.2 (e86c870879, 2021-01-15)">
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="2057"
inkscape:window-height="1417"
id="namedview975"
showgrid="false"
inkscape:zoom="8.5625"
inkscape:cx="32"
inkscape:cy="32"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg2766"
inkscape:document-rotation="0" />
<defs
id="defs2768">
<linearGradient
id="linearGradient3787">
<stop
style="stop-color:#0619c0;stop-opacity:1;"
offset="0"
id="stop3789" />
<stop
style="stop-color:#379cfb;stop-opacity:1;"
offset="1"
id="stop3791" />
</linearGradient>
<linearGradient
id="linearGradient3864">
<stop
style="stop-color:#0619c0;stop-opacity:1;"
offset="0"
id="stop3866" />
<stop
style="stop-color:#379cfb;stop-opacity:1;"
offset="1"
id="stop3868" />
</linearGradient>
<linearGradient
gradientTransform="matrix(1.0614931,0,0,1,-540.96941,-73.37642)"
y2="100.10708"
x2="609.54919"
y1="126.79625"
x1="581.26331"
gradientUnits="userSpaceOnUse"
id="linearGradient3181"
xlink:href="#linearGradient3864" />
<linearGradient
y2="92.711899"
x2="626.31323"
y1="92.711899"
x1="605.94659"
gradientTransform="matrix(-0.72140579,0.77867919,-0.73356972,-0.67961421,545.35072,-389.46656)"
gradientUnits="userSpaceOnUse"
id="linearGradient3184"
xlink:href="#linearGradient3864" />
<linearGradient
id="linearGradient3864-0">
<stop
style="stop-color:#0619c0;stop-opacity:1;"
offset="0"
id="stop3866-6" />
<stop
style="stop-color:#379cfb;stop-opacity:1;"
offset="1"
id="stop3868-2" />
</linearGradient>
<linearGradient
xlink:href="#linearGradient3864-0"
id="linearGradient3217"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.0614931,0,0,1,-643.22843,-82.445766)"
x1="605.94659"
y1="92.711899"
x2="626.31323"
y2="92.711899" />
<linearGradient
y2="92.711899"
x2="626.31323"
y1="92.711899"
x1="605.94659"
gradientTransform="matrix(1.1915091,0,0,1,-772.13265,-84.532596)"
gradientUnits="userSpaceOnUse"
id="linearGradient3184-4-0"
xlink:href="#linearGradient3864-0-2" />
<linearGradient
id="linearGradient3864-0-2">
<stop
style="stop-color:#0619c0;stop-opacity:1;"
offset="0"
id="stop3866-6-8" />
<stop
style="stop-color:#379cfb;stop-opacity:1;"
offset="1"
id="stop3868-2-3" />
</linearGradient>
<linearGradient
y2="92.711899"
x2="626.31323"
y1="92.711899"
x1="605.94659"
gradientTransform="matrix(1.1915091,0,0,1,-772.13265,-84.532596)"
gradientUnits="userSpaceOnUse"
id="linearGradient3184-4-4"
xlink:href="#linearGradient3864-0-9" />
<linearGradient
id="linearGradient3864-0-9">
<stop
style="stop-color:#0619c0;stop-opacity:1;"
offset="0"
id="stop3866-6-9" />
<stop
style="stop-color:#379cfb;stop-opacity:1;"
offset="1"
id="stop3868-2-4" />
</linearGradient>
<linearGradient
xlink:href="#linearGradient3864-0-9-5"
id="linearGradient4054-6"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.0614931,0.54122665,0,1,-692.52246,-451.18305)"
x1="634.20868"
y1="91.597527"
x2="679.06909"
y2="102.88628" />
<linearGradient
id="linearGradient3864-0-9-5">
<stop
style="stop-color:#0619c0;stop-opacity:1;"
offset="0"
id="stop3866-6-9-0" />
<stop
style="stop-color:#379cfb;stop-opacity:1;"
offset="1"
id="stop3868-2-4-0" />
</linearGradient>
<linearGradient
xlink:href="#linearGradient3864-0-9-5"
id="linearGradient4090"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.0614931,0.54122665,0,1,-687.73118,-415.49631)"
x1="634.20868"
y1="91.597527"
x2="679.06909"
y2="102.88628" />
<linearGradient
xlink:href="#linearGradient3864-0-9-5-0"
id="linearGradient4090-6"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.0614931,0.54122665,0,1,-687.73118,-415.49631)"
x1="634.20868"
y1="91.597527"
x2="679.06909"
y2="102.88628" />
<linearGradient
id="linearGradient3864-0-9-5-0">
<stop
style="stop-color:#0619c0;stop-opacity:1;"
offset="0"
id="stop3866-6-9-0-2" />
<stop
style="stop-color:#379cfb;stop-opacity:1;"
offset="1"
id="stop3868-2-4-0-5" />
</linearGradient>
<linearGradient
xlink:href="#linearGradient3864-0-9-5-0"
id="linearGradient4124"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.80817481,0.4120665,0,0.76135663,-517.34974,-304.44262)"
x1="634.20868"
y1="91.597527"
x2="679.06909"
y2="102.88628" />
<linearGradient
xlink:href="#linearGradient3864-0-2-2"
id="linearGradient4018-2"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.5385683,-0.86055196,0,0.96535888,-879.38043,517.26249)"
x1="635.40765"
y1="100.79263"
x2="672.73157"
y2="100.2725" />
<linearGradient
id="linearGradient3864-0-2-2">
<stop
style="stop-color:#0619c0;stop-opacity:1;"
offset="0"
id="stop3866-6-8-9" />
<stop
style="stop-color:#379cfb;stop-opacity:1;"
offset="1"
id="stop3868-2-3-2" />
</linearGradient>
<linearGradient
y2="48.117603"
x2="709.04407"
y1="114.56509"
x1="663.32715"
gradientTransform="matrix(1.5385683,0.52247795,0,0.96535888,-912.7401,-396.04414)"
gradientUnits="userSpaceOnUse"
id="linearGradient4073-8"
xlink:href="#linearGradient3864-0-1" />
<linearGradient
id="linearGradient3864-0-1">
<stop
style="stop-color:#0619c0;stop-opacity:1;"
offset="0"
id="stop3866-6-2" />
<stop
style="stop-color:#379cfb;stop-opacity:1;"
offset="1"
id="stop3868-2-47" />
</linearGradient>
<linearGradient
xlink:href="#linearGradient3864-0-9-6"
id="linearGradient4054-8"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.5385683,0.52247795,0,0.96535888,-912.7628,-417.24568)"
x1="634.20868"
y1="91.597527"
x2="679.06909"
y2="102.88628" />
<linearGradient
id="linearGradient3864-0-9-6">
<stop
style="stop-color:#0619c0;stop-opacity:1;"
offset="0"
id="stop3866-6-9-3" />
<stop
style="stop-color:#379cfb;stop-opacity:1;"
offset="1"
id="stop3868-2-4-7" />
</linearGradient>
</defs>
<g
id="layer1">
<path
id="rect3200-5-3"
d="M 33,35 5,49 33,59 59,45 z m 0,5 16,6 -16,8 -17,-6 z"
style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#0b1521;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
</g>
<metadata
id="metadata57">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
<cc:license
rdf:resource="" />
<dc:date>Mon Oct 10 13:44:52 2011 +0000</dc:date>
<dc:creator>
<cc:Agent>
<dc:title>[wmayer]</dc:title>
</cc:Agent>
</dc:creator>
<dc:rights>
<cc:Agent>
<dc:title>FreeCAD LGPL2+</dc:title>
</cc:Agent>
</dc:rights>
<dc:publisher>
<cc:Agent>
<dc:title>FreeCAD</dc:title>
</cc:Agent>
</dc:publisher>
<dc:identifier>FreeCAD/src/Mod/Draft/Resources/icons/Draft_2DShapeView.svg</dc:identifier>
<dc:relation>http://www.freecadweb.org/wiki/index.php?title=Artwork</dc:relation>
<dc:contributor>
<cc:Agent>
<dc:title>[agryson] Alexander Gryson</dc:title>
</cc:Agent>
</dc:contributor>
<dc:subject>
<rdf:Bag>
<rdf:li>box</rdf:li>
<rdf:li>plane</rdf:li>
<rdf:li>rectangle</rdf:li>
</rdf:Bag>
</dc:subject>
<dc:description>A box floating above a projection of its lower face</dc:description>
</cc:Work>
</rdf:RDF>
</metadata>
<path
style="fill:#ff0000;stroke:#ff0000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="M 33.119982,5.9005474 V 43.968066"
id="path1011" />
<ellipse
style="fill:#ff1a00;fill-opacity:1;stroke:none;stroke-width:9.49383"
id="path1020"
cx="33.058163"
cy="44.76939"
rx="1.6904655"
ry="1.6950274" />
<path
style="fill:none;stroke:#ff0000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="M 33.119982,43.968066 38.117245,40"
id="path1022" />
<path
style="fill:none;stroke:#ff0000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="M 33.119982,43.968066 29.151916,38.970803"
id="path1022-3" />
<path
style="fill:none;stroke:#ff0000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 33.119982,43.968066 -6.204197,-1.49202"
id="path1022-6"
inkscape:transform-center-x="2.4142336"
inkscape:transform-center-y="-0.3120438" />
<path
style="fill:none;stroke:#ff0000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 33.119982,43.968066 -5.853996,2.539469"
id="path1022-5"
inkscape:transform-center-x="-2.177793"
inkscape:transform-center-y="2.5275147" />
<path
style="fill:none;stroke:#ff0000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 33.316894,43.931615 5.935078,2.343723"
id="path1022-35"
inkscape:transform-center-x="-3.2044307"
inkscape:transform-center-y="1.9014819" />
<path
style="fill:none;stroke:#ff0000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 33.119982,43.968066 6.311789,-0.937814"
id="path1022-62" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:40px;line-height:1.25;font-family:sans-serif;fill:#000000;fill-opacity:1;stroke:none"
x="35.75502"
y="31.866331"
id="text1569"><tspan
sodipodi:role="line"
id="tspan1567"
x="35.75502"
y="31.866331">R</tspan></text>
</svg>

After

Width:  |  Height:  |  Size: 12 KiB

357
freecad/LaserCladdingWorkbench/Resources/icons/LaserSaveProg.svg

@ -0,0 +1,357 @@ @@ -0,0 +1,357 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.1"
id="svg2766"
height="64px"
width="64px"
sodipodi:docname="LaserSaveProg.svg"
inkscape:version="1.0.2 (e86c870879, 2021-01-15)">
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="2057"
inkscape:window-height="1417"
id="namedview975"
showgrid="false"
inkscape:zoom="8.5625"
inkscape:cx="32"
inkscape:cy="32"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg2766"
inkscape:document-rotation="0" />
<defs
id="defs2768">
<marker
style="overflow:visible;"
id="Arrow2Send"
refX="0.0"
refY="0.0"
orient="auto"
inkscape:stockid="Arrow2Send"
inkscape:isstock="true">
<path
transform="scale(0.3) rotate(180) translate(-2.3,0)"
d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round;stroke:#00ff00;stroke-opacity:1;fill:#00ff00;fill-opacity:1"
id="path1684" />
</marker>
<marker
style="overflow:visible;"
id="Arrow1Send"
refX="0.0"
refY="0.0"
orient="auto"
inkscape:stockid="Arrow1Send"
inkscape:isstock="true">
<path
transform="scale(0.2) rotate(180) translate(6,0)"
style="fill-rule:evenodd;stroke:#00ff00;stroke-width:1pt;stroke-opacity:1;fill:#00ff00;fill-opacity:1"
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
id="path1666" />
</marker>
<marker
style="overflow:visible;"
id="Arrow2Lend"
refX="0.0"
refY="0.0"
orient="auto"
inkscape:stockid="Arrow2Lend"
inkscape:isstock="true">
<path
transform="scale(1.1) rotate(180) translate(1,0)"
d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round;stroke:#00ff00;stroke-opacity:1;fill:#00ff00;fill-opacity:1"
id="path1672" />
</marker>
<linearGradient
id="linearGradient3787">
<stop
style="stop-color:#0619c0;stop-opacity:1;"
offset="0"
id="stop3789" />
<stop
style="stop-color:#379cfb;stop-opacity:1;"
offset="1"
id="stop3791" />
</linearGradient>
<linearGradient
id="linearGradient3864">
<stop
style="stop-color:#0619c0;stop-opacity:1;"
offset="0"
id="stop3866" />
<stop
style="stop-color:#379cfb;stop-opacity:1;"
offset="1"
id="stop3868" />
</linearGradient>
<linearGradient
gradientTransform="matrix(1.0614931,0,0,1,-540.96941,-73.37642)"
y2="100.10708"
x2="609.54919"
y1="126.79625"
x1="581.26331"
gradientUnits="userSpaceOnUse"
id="linearGradient3181"
xlink:href="#linearGradient3864" />
<linearGradient
y2="92.711899"
x2="626.31323"
y1="92.711899"
x1="605.94659"
gradientTransform="matrix(-0.72140579,0.77867919,-0.73356972,-0.67961421,545.35072,-389.46656)"
gradientUnits="userSpaceOnUse"
id="linearGradient3184"
xlink:href="#linearGradient3864" />
<linearGradient
id="linearGradient3864-0">
<stop
style="stop-color:#0619c0;stop-opacity:1;"
offset="0"
id="stop3866-6" />
<stop
style="stop-color:#379cfb;stop-opacity:1;"
offset="1"
id="stop3868-2" />
</linearGradient>
<linearGradient
xlink:href="#linearGradient3864-0"
id="linearGradient3217"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.0614931,0,0,1,-643.22843,-82.445766)"
x1="605.94659"
y1="92.711899"
x2="626.31323"
y2="92.711899" />
<linearGradient
y2="92.711899"
x2="626.31323"
y1="92.711899"
x1="605.94659"
gradientTransform="matrix(1.1915091,0,0,1,-772.13265,-84.532596)"
gradientUnits="userSpaceOnUse"
id="linearGradient3184-4-0"
xlink:href="#linearGradient3864-0-2" />
<linearGradient
id="linearGradient3864-0-2">
<stop
style="stop-color:#0619c0;stop-opacity:1;"
offset="0"
id="stop3866-6-8" />
<stop
style="stop-color:#379cfb;stop-opacity:1;"
offset="1"
id="stop3868-2-3" />
</linearGradient>
<linearGradient
y2="92.711899"
x2="626.31323"
y1="92.711899"
x1="605.94659"
gradientTransform="matrix(1.1915091,0,0,1,-772.13265,-84.532596)"
gradientUnits="userSpaceOnUse"
id="linearGradient3184-4-4"
xlink:href="#linearGradient3864-0-9" />
<linearGradient
id="linearGradient3864-0-9">
<stop
style="stop-color:#0619c0;stop-opacity:1;"
offset="0"
id="stop3866-6-9" />
<stop
style="stop-color:#379cfb;stop-opacity:1;"
offset="1"
id="stop3868-2-4" />
</linearGradient>
<linearGradient
xlink:href="#linearGradient3864-0-9-5"
id="linearGradient4054-6"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.0614931,0.54122665,0,1,-692.52246,-451.18305)"
x1="634.20868"
y1="91.597527"
x2="679.06909"
y2="102.88628" />
<linearGradient
id="linearGradient3864-0-9-5">
<stop
style="stop-color:#0619c0;stop-opacity:1;"
offset="0"
id="stop3866-6-9-0" />
<stop
style="stop-color:#379cfb;stop-opacity:1;"
offset="1"
id="stop3868-2-4-0" />
</linearGradient>
<linearGradient
xlink:href="#linearGradient3864-0-9-5"
id="linearGradient4090"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.0614931,0.54122665,0,1,-687.73118,-415.49631)"
x1="634.20868"
y1="91.597527"
x2="679.06909"
y2="102.88628" />
<linearGradient
xlink:href="#linearGradient3864-0-9-5-0"
id="linearGradient4090-6"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.0614931,0.54122665,0,1,-687.73118,-415.49631)"
x1="634.20868"
y1="91.597527"
x2="679.06909"
y2="102.88628" />
<linearGradient
id="linearGradient3864-0-9-5-0">
<stop
style="stop-color:#0619c0;stop-opacity:1;"
offset="0"
id="stop3866-6-9-0-2" />
<stop
style="stop-color:#379cfb;stop-opacity:1;"
offset="1"
id="stop3868-2-4-0-5" />
</linearGradient>
<linearGradient
xlink:href="#linearGradient3864-0-9-5-0"
id="linearGradient4124"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.80817481,0.4120665,0,0.76135663,-517.34974,-304.44262)"
x1="634.20868"
y1="91.597527"
x2="679.06909"
y2="102.88628" />
<linearGradient
xlink:href="#linearGradient3864-0-2-2"
id="linearGradient4018-2"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.5385683,-0.86055196,0,0.96535888,-879.38043,517.26249)"
x1="635.40765"
y1="100.79263"
x2="672.73157"
y2="100.2725" />
<linearGradient
id="linearGradient3864-0-2-2">
<stop
style="stop-color:#0619c0;stop-opacity:1;"
offset="0"
id="stop3866-6-8-9" />
<stop
style="stop-color:#379cfb;stop-opacity:1;"
offset="1"
id="stop3868-2-3-2" />
</linearGradient>
<linearGradient
y2="48.117603"
x2="709.04407"
y1="114.56509"
x1="663.32715"
gradientTransform="matrix(1.5385683,0.52247795,0,0.96535888,-912.7401,-396.04414)"
gradientUnits="userSpaceOnUse"
id="linearGradient4073-8"
xlink:href="#linearGradient3864-0-1" />
<linearGradient
id="linearGradient3864-0-1">
<stop
style="stop-color:#0619c0;stop-opacity:1;"
offset="0"
id="stop3866-6-2" />
<stop
style="stop-color:#379cfb;stop-opacity:1;"
offset="1"
id="stop3868-2-47" />
</linearGradient>
<linearGradient
xlink:href="#linearGradient3864-0-9-6"
id="linearGradient4054-8"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.5385683,0.52247795,0,0.96535888,-912.7628,-417.24568)"
x1="634.20868"
y1="91.597527"
x2="679.06909"
y2="102.88628" />
<linearGradient
id="linearGradient3864-0-9-6">
<stop
style="stop-color:#0619c0;stop-opacity:1;"
offset="0"
id="stop3866-6-9-3" />
<stop
style="stop-color:#379cfb;stop-opacity:1;"
offset="1"
id="stop3868-2-4-7" />
</linearGradient>
</defs>
<g
id="layer1">
<path
id="rect3200-5-3"
d="M 33,35 5,49 33,59 59,45 z m 0,5 16,6 -16,8 -17,-6 z"
style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#0b1521;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
</g>
<metadata
id="metadata57">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
<cc:license
rdf:resource="" />
<dc:date>Mon Oct 10 13:44:52 2011 +0000</dc:date>
<dc:creator>
<cc:Agent>
<dc:title>[wmayer]</dc:title>
</cc:Agent>
</dc:creator>
<dc:rights>
<cc:Agent>
<dc:title>FreeCAD LGPL2+</dc:title>
</cc:Agent>
</dc:rights>
<dc:publisher>
<cc:Agent>
<dc:title>FreeCAD</dc:title>
</cc:Agent>
</dc:publisher>
<dc:identifier>FreeCAD/src/Mod/Draft/Resources/icons/Draft_2DShapeView.svg</dc:identifier>
<dc:relation>http://www.freecadweb.org/wiki/index.php?title=Artwork</dc:relation>
<dc:contributor>
<cc:Agent>
<dc:title>[agryson] Alexander Gryson</dc:title>
</cc:Agent>
</dc:contributor>
<dc:subject>
<rdf:Bag>
<rdf:li>box</rdf:li>
<rdf:li>plane</rdf:li>
<rdf:li>rectangle</rdf:li>
</rdf:Bag>
</dc:subject>
<dc:description>A box floating above a projection of its lower face</dc:description>
</cc:Work>
</rdf:RDF>
</metadata>
<path
style="fill:#00ff00;fill-opacity:1;stroke:#00ff00;stroke-width:4.3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow2Send)"
d="M 33,0.1368616 V 40"
id="path1649" />
</svg>

After

Width:  |  Height:  |  Size: 12 KiB

373
freecad/LaserCladdingWorkbench/Resources/icons/LaserSelectBaseRef.svg

@ -0,0 +1,373 @@ @@ -0,0 +1,373 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.1"
id="svg2766"
height="64px"
width="64px"
sodipodi:docname="LaserSelectBaseRef.svg"
inkscape:version="1.0.2 (e86c870879, 2021-01-15)">
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="2057"
inkscape:window-height="1417"
id="namedview975"
showgrid="false"
inkscape:zoom="6.0546018"
inkscape:cx="41.158453"
inkscape:cy="17.061775"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg2766"
inkscape:document-rotation="0" />
<defs
id="defs2768">
<marker
style="overflow:visible;"
id="Arrow2Send"
refX="0.0"
refY="0.0"
orient="auto"
inkscape:stockid="Arrow2Send"
inkscape:isstock="true">
<path
transform="scale(0.3) rotate(180) translate(-2.3,0)"
d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round;stroke:#00ff00;stroke-opacity:1;fill:#00ff00;fill-opacity:1"
id="path1684" />
</marker>
<marker
style="overflow:visible;"
id="Arrow1Send"
refX="0.0"
refY="0.0"
orient="auto"
inkscape:stockid="Arrow1Send"
inkscape:isstock="true">
<path
transform="scale(0.2) rotate(180) translate(6,0)"
style="fill-rule:evenodd;stroke:#00ff00;stroke-width:1pt;stroke-opacity:1;fill:#00ff00;fill-opacity:1"
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
id="path1666" />
</marker>
<marker
style="overflow:visible;"
id="Arrow2Lend"
refX="0.0"
refY="0.0"
orient="auto"
inkscape:stockid="Arrow2Lend"
inkscape:isstock="true">
<path
transform="scale(1.1) rotate(180) translate(1,0)"
d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
style="fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round;stroke:#00ff00;stroke-opacity:1;fill:#00ff00;fill-opacity:1"
id="path1672" />
</marker>
<linearGradient
id="linearGradient3787">
<stop
style="stop-color:#0619c0;stop-opacity:1;"
offset="0"
id="stop3789" />
<stop
style="stop-color:#379cfb;stop-opacity:1;"
offset="1"
id="stop3791" />
</linearGradient>
<linearGradient
id="linearGradient3864">
<stop
style="stop-color:#0619c0;stop-opacity:1;"
offset="0"
id="stop3866" />
<stop
style="stop-color:#379cfb;stop-opacity:1;"
offset="1"
id="stop3868" />
</linearGradient>
<linearGradient
gradientTransform="matrix(1.0614931,0,0,1,-540.96941,-73.37642)"
y2="100.10708"
x2="609.54919"
y1="126.79625"
x1="581.26331"
gradientUnits="userSpaceOnUse"
id="linearGradient3181"
xlink:href="#linearGradient3864" />
<linearGradient
y2="92.711899"
x2="626.31323"
y1="92.711899"
x1="605.94659"
gradientTransform="matrix(-0.72140579,0.77867919,-0.73356972,-0.67961421,545.35072,-389.46656)"
gradientUnits="userSpaceOnUse"
id="linearGradient3184"
xlink:href="#linearGradient3864" />
<linearGradient
id="linearGradient3864-0">
<stop
style="stop-color:#0619c0;stop-opacity:1;"
offset="0"
id="stop3866-6" />
<stop
style="stop-color:#379cfb;stop-opacity:1;"
offset="1"
id="stop3868-2" />
</linearGradient>
<linearGradient
xlink:href="#linearGradient3864-0"
id="linearGradient3217"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.0614931,0,0,1,-643.22843,-82.445766)"
x1="605.94659"
y1="92.711899"
x2="626.31323"
y2="92.711899" />
<linearGradient
y2="92.711899"
x2="626.31323"
y1="92.711899"
x1="605.94659"
gradientTransform="matrix(1.1915091,0,0,1,-772.13265,-84.532596)"
gradientUnits="userSpaceOnUse"
id="linearGradient3184-4-0"
xlink:href="#linearGradient3864-0-2" />
<linearGradient
id="linearGradient3864-0-2">
<stop
style="stop-color:#0619c0;stop-opacity:1;"
offset="0"
id="stop3866-6-8" />
<stop
style="stop-color:#379cfb;stop-opacity:1;"
offset="1"
id="stop3868-2-3" />
</linearGradient>
<linearGradient
y2="92.711899"
x2="626.31323"
y1="92.711899"
x1="605.94659"
gradientTransform="matrix(1.1915091,0,0,1,-772.13265,-84.532596)"
gradientUnits="userSpaceOnUse"
id="linearGradient3184-4-4"
xlink:href="#linearGradient3864-0-9" />
<linearGradient
id="linearGradient3864-0-9">
<stop
style="stop-color:#0619c0;stop-opacity:1;"
offset="0"
id="stop3866-6-9" />
<stop
style="stop-color:#379cfb;stop-opacity:1;"
offset="1"
id="stop3868-2-4" />
</linearGradient>
<linearGradient
xlink:href="#linearGradient3864-0-9-5"
id="linearGradient4054-6"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.0614931,0.54122665,0,1,-692.52246,-451.18305)"
x1="634.20868"
y1="91.597527"
x2="679.06909"
y2="102.88628" />
<linearGradient
id="linearGradient3864-0-9-5">
<stop
style="stop-color:#0619c0;stop-opacity:1;"
offset="0"
id="stop3866-6-9-0" />
<stop
style="stop-color:#379cfb;stop-opacity:1;"
offset="1"
id="stop3868-2-4-0" />
</linearGradient>
<linearGradient
xlink:href="#linearGradient3864-0-9-5"
id="linearGradient4090"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.0614931,0.54122665,0,1,-687.73118,-415.49631)"
x1="634.20868"
y1="91.597527"
x2="679.06909"
y2="102.88628" />
<linearGradient
xlink:href="#linearGradient3864-0-9-5-0"
id="linearGradient4090-6"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.0614931,0.54122665,0,1,-687.73118,-415.49631)"
x1="634.20868"
y1="91.597527"
x2="679.06909"
y2="102.88628" />
<linearGradient
id="linearGradient3864-0-9-5-0">
<stop
style="stop-color:#0619c0;stop-opacity:1;"
offset="0"
id="stop3866-6-9-0-2" />
<stop
style="stop-color:#379cfb;stop-opacity:1;"
offset="1"
id="stop3868-2-4-0-5" />
</linearGradient>
<linearGradient
xlink:href="#linearGradient3864-0-9-5-0"
id="linearGradient4124"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(0.80817481,0.4120665,0,0.76135663,-517.34974,-304.44262)"
x1="634.20868"
y1="91.597527"
x2="679.06909"
y2="102.88628" />
<linearGradient
xlink:href="#linearGradient3864-0-2-2"
id="linearGradient4018-2"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.5385683,-0.86055196,0,0.96535888,-879.38043,517.26249)"
x1="635.40765"
y1="100.79263"
x2="672.73157"
y2="100.2725" />
<linearGradient
id="linearGradient3864-0-2-2">
<stop
style="stop-color:#0619c0;stop-opacity:1;"
offset="0"
id="stop3866-6-8-9" />
<stop
style="stop-color:#379cfb;stop-opacity:1;"
offset="1"
id="stop3868-2-3-2" />
</linearGradient>
<linearGradient
y2="48.117603"
x2="709.04407"
y1="114.56509"
x1="663.32715"
gradientTransform="matrix(1.5385683,0.52247795,0,0.96535888,-912.7401,-396.04414)"
gradientUnits="userSpaceOnUse"
id="linearGradient4073-8"
xlink:href="#linearGradient3864-0-1" />
<linearGradient
id="linearGradient3864-0-1">
<stop
style="stop-color:#0619c0;stop-opacity:1;"
offset="0"
id="stop3866-6-2" />
<stop
style="stop-color:#379cfb;stop-opacity:1;"
offset="1"
id="stop3868-2-47" />
</linearGradient>
<linearGradient
xlink:href="#linearGradient3864-0-9-6"
id="linearGradient4054-8"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.5385683,0.52247795,0,0.96535888,-912.7628,-417.24568)"
x1="634.20868"
y1="91.597527"
x2="679.06909"
y2="102.88628" />
<linearGradient
id="linearGradient3864-0-9-6">
<stop
style="stop-color:#0619c0;stop-opacity:1;"
offset="0"
id="stop3866-6-9-3" />
<stop
style="stop-color:#379cfb;stop-opacity:1;"
offset="1"
id="stop3868-2-4-7" />
</linearGradient>
</defs>
<g
id="layer1"
transform="translate(0,-20)">
<path
id="rect3200-5-3"
d="M 33,35 5,49 33,59 59,45 Z m 0,5 16,6 -16,8 -17,-6 z"
style="color:#000000;display:inline;overflow:visible;visibility:visible;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#0b1521;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker:none;enable-background:accumulate" />
</g>
<metadata
id="metadata57">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
<cc:license
rdf:resource="" />
<dc:date>Mon Oct 10 13:44:52 2011 +0000</dc:date>
<dc:creator>
<cc:Agent>
<dc:title>[wmayer]</dc:title>
</cc:Agent>
</dc:creator>
<dc:rights>
<cc:Agent>
<dc:title>FreeCAD LGPL2+</dc:title>
</cc:Agent>
</dc:rights>
<dc:publisher>
<cc:Agent>
<dc:title>FreeCAD</dc:title>
</cc:Agent>
</dc:publisher>
<dc:identifier>FreeCAD/src/Mod/Draft/Resources/icons/Draft_2DShapeView.svg</dc:identifier>
<dc:relation>http://www.freecadweb.org/wiki/index.php?title=Artwork</dc:relation>
<dc:contributor>
<cc:Agent>
<dc:title>[agryson] Alexander Gryson</dc:title>
</cc:Agent>
</dc:contributor>
<dc:subject>
<rdf:Bag>
<rdf:li>box</rdf:li>
<rdf:li>plane</rdf:li>
<rdf:li>rectangle</rdf:li>
</rdf:Bag>
</dc:subject>
<dc:description>A box floating above a projection of its lower face</dc:description>
</cc:Work>
</rdf:RDF>
</metadata>
<path
style="fill:none;stroke:#00ffff;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="M 31.630474,10.979015 V 40.312044 L 53.135645,27.896028"
id="path2023" />
<path
style="fill:none;stroke:#00ffff;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="M 31.630474,40.312044 7.2673358,31.301551"
id="path2027" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:12px;line-height:1.25;font-family:sans-serif;fill:#000000;fill-opacity:1;stroke:none"
x="13.311802"
y="54.823357"
id="text2031"><tspan
sodipodi:role="line"
id="tspan2029"
x="13.311802"
y="54.823357"
style="font-size:12px">(1,3,0)</tspan></text>
</svg>

After

Width:  |  Height:  |  Size: 12 KiB

0
Resources/icons/Laser_Workbench.svg → freecad/LaserCladdingWorkbench/Resources/icons/Laser_Workbench.svg

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

0
Init.py → freecad/LaserCladdingWorkbench/__init__.py

170
freecad/LaserCladdingWorkbench/commands.py

@ -0,0 +1,170 @@ @@ -0,0 +1,170 @@
import FreeCAD as App
import FreeCADGui as Gui
import Part
import os
import re
import copy
from .program import LaserProgram, ViewProviderLaserProgram
from .pad import LaserPad, ViewProviderLaserPad
from .kuka import Kuka_Prog, Kuka_Pose, get_list_of_poses
class LCCreateProgram():
def Activated(self):
# Here your write what your ScriptCmd does...
App.Console.PrintMessage('Create Lasser Cladding Program')
a=App.ActiveDocument.addObject("App::FeaturePython","LaserProgram")
LaserProgram(a)
ViewProviderLaserProgram(a.ViewObject)
def GetResources(self):
return {'Pixmap' : ":icons/LaserCreateProg.svg", 'MenuText': 'Create Laser Program', 'ToolTip': 'Add a Laser Program to your Document'}
class LCSelectBaseReference():
def Activated(self):
# Here your write what your ScriptCmd does...
App.Console.PrintMessage('Select Base reference!')
if not Gui.Selection.hasSelection():
App.Console.PrintMessage('Select a Vertex')
return
# check length
selection = Gui.Selection.getSelectionEx()
# find first vertex
for s in selection:
if s.HasSubObjects:
for obj in s.SubObjects:
if isinstance(obj, Part.Vertex):
vertex = obj.copy()
laserjob_entry = App.ActiveDocument.getObject('LaserProgram')
if laserjob_entry is None:
App.Console.PrintMessage('Create a LaserJob first')
return
laserjob_entry.base_reference = App.Vector((vertex.X, vertex.Y, vertex.Z))
App.ActiveDocument.recompute()
def GetResources(self):
return {'Pixmap' : ":icons/LaserSelectBaseRef.svg",
'MenuText': 'Select Base reference',
'ToolTip': 'Add a Job to your Document'}
class LCCreatePad():
def _create_laserpad(self, ref_to_face):
laserprogram = App.ActiveDocument.getObject('LaserProgram')
if laserprogram is None:
App.Console.PrintMessage('Create a LaserProgram first')
return
pad_obj = laserprogram.newObject("App::FeaturePython","LaserPad")
LaserPad(pad_obj, ref_to_face)
ViewProviderLaserPad(pad_obj.ViewObject)
return pad_obj
def Activated(self):
# Here your write what your ScriptCmd does...
App.Console.PrintMessage('Select some Face as reference')
if not Gui.Selection.hasSelection():
App.Console.PrintMessage('Select a Face')
return
# check length
ref_face = (Gui.Selection.getSelection()[0],
Gui.Selection.getSelectionEx()[0].SubElementNames[0])
#selection = Gui.Selection.getSelectionEx()
# find first vertex
#for s in selection:
# if s.HasSubObjects:
# for obj in s.SubObjects:
# if isinstance(obj, Part.Face):
# face = obj.copy()
self._create_laserpad(ref_face)
App.ActiveDocument.recompute()
def GetResources(self):
return {'Pixmap' : ":icons/LaserCreatePad.svg", 'MenuText': 'Create Pad', 'ToolTip': 'Create a Pad on selected face'}
class LCRecompute():
def Activated(self):
# Here your write what your ScriptCmd does...
App.Console.PrintMessage('Recomputer Pads')
if not Gui.Selection.hasSelection():
App.Console.PrintMessage('Select a Pad')
return
if Gui.Selection.hasSelection():
laser_path_obj = Gui.Selection.getSelection()[0]
if len(laser_path_obj.Group):
laser_path_obj.removeObjectsFromDocument()
laser_path_obj.Proxy._create_path(laser_path_obj)
App.ActiveDocument.recompute()
def GetResources(self):
return {'Pixmap' : ":icons/LaserRecomputePad.svg",
'MenuText': 'Recompute',
'ToolTip': 'Recompute selected Pads'}
class LCSaveProg():
def Activated(self):
# Here your write what your ScriptCmd does...
App.Console.PrintMessage('Saving to KRL')
c = App.ActiveDocument.getObject("LaserProgram")
pads = c.Group
prog = Kuka_Prog()
for pad in pads:
# one pad with contours and hatchlines
for progpart in pad.Group:
## jedes Contour oder Hatchline Feature
if re.match('Contour*', progpart.Name):
# do Conoutes
face = pad.ref_body.getSubObject(pad.ref_surface)
edges = Part.__sortEdges__(progpart.Shape.Edges)
vlist = []
for edge in edges:
vlist.extend([v.Point for v in edge.Vertexes])
poly = Part.makePolygon(vlist)
#Part.show(poly, "ContourPath")
poses = get_list_of_poses(face, poly.Edges)
prog.append_contour(poses, progpart.pathtype)
elif re.match('Hatch*', progpart.Name):
face = pad.ref_body.getSubObject(pad.ref_surface)
edges = progpart.Shape.Edges
for edge in edges:
p0 = edge.Vertexes[0].Point
p1 = edge.Vertexes[1].Point
line = []
for p in [p0, p1]:
uv = face.Surface.parameter(p)
normal = face.normalAt(uv[0], uv[1])
pose = Kuka_Pose.from_point_and_normal(p, normal)
line.append(pose)
prog.append_hatchline(line, progpart.pathtype)
prog.set_base(c.base_reference)
prog.save_prog(c.progpath)
App.ActiveDocument.recompute()
def GetResources(self):
return {'Pixmap' : ":icons/LaserSaveProg.svg",
'MenuText': 'Save Program',
'ToolTip': 'Save the Program as KRL'}
Gui.addCommand('LCCreateProgram', LCCreateProgram())
Gui.addCommand('LCSelectBaseReference', LCSelectBaseReference())
Gui.addCommand('LCCreatePad', LCCreatePad())
Gui.addCommand('LCRecompute', LCRecompute())
Gui.addCommand('LCSaveProg', LCSaveProg())

63
freecad/LaserCladdingWorkbench/init_gui.py

@ -0,0 +1,63 @@ @@ -0,0 +1,63 @@
import FreeCAD as App
import FreeCADGui as Gui
from freecad.LaserCladdingWorkbench import lc_resource
from freecad.LaserCladdingWorkbench import commands
import os
class LaserCladding (Gui.Workbench):
MenuText = "Laser Cladding"
ToolTip = "Create Simple Paths on workpieces for Laser Cladding"
Icon = ":/icons/Laser_Workbench.svg"
def __init__(self):
pass
def Initialize(self):
"""This function is executed when the workbench is first activated.
It is executed once in a FreeCAD session followed by the Activated function.
"""
import freecad.LaserCladdingWorkbench
self.appendMenu("LaserCladding",
["LCCreateProgram",
"LCSelectBaseReference",
"LCCreatePad",
"LCRecompute",
"LCSaveProg"
]
) # creates a new menu
self.appendToolbar("LaserCladding",
["LCCreateProgram",
"LCSelectBaseReference",
"LCCreatePad",
"LCRecompute",
"LCSaveProg"
]
) # creates a new toolbar
def Activated(self):
"""This function is executed whenever the workbench is activated"""
import freecad.LaserCladdingWorkbench
from importlib import reload
reload(freecad.LaserCladdingWorkbench)
return
def Deactivated(self):
"""This function is executed whenever the workbench is deactivated"""
return
def ContextMenu(self, recipient):
"""This function is executed whenever the user right-clicks on screen"""
# "recipient" will be either "view" or "tree"
self.appendContextMenu("Laser Cladding",[]) # add commands to the context menu
def GetClassName(self):
# This function is mandatory if this is a full Python workbench
# This is not a template, the returned string should be exactly "Gui::PythonWorkbench"
return "Gui::PythonWorkbench"
Gui.addWorkbench(LaserCladding())

265
freecad/LaserCladdingWorkbench/kuka.py

@ -0,0 +1,265 @@ @@ -0,0 +1,265 @@
import FreeCAD
import numpy as np
import math
import time
import Part
import re
import copy
TeachPointFold = """
;FOLD LIN P4 Vel= 0.2 m/s CPDAT1 Tool[1] Base[0];%{PE}%R 5.4.27,%MKUKATPBASIS,%CMOVE,%VLIN,%P 1:LIN, 2:P4, 3:, 5:0.2, 7:CPDAT1
$BWDSTART = FALSE
LDAT_ACT=LCPDAT1
FDAT_ACT=FP4
BAS(#CP_PARAMS,0.2)
LIN XP4
;ENDFOLD
"""
TeachPointDat = """
DECL E6POS XP4={X -25.1844196,Y 1122.42603,Z 1158.07996,A -14.3267002,B 0.537901878,C 179.028305,S 6,T 59,E1 0.0,E2 0.0,E3 0.0,E4 0.0,E5 0.0,E6 0.0}
DECL FDAT FP4={TOOL_NO 1,BASE_NO 0,IPO_FRAME #BASE,POINT2[] " "}
DECL LDAT LCPDAT1={VEL 2.0,ACC 100.0,APO_DIST 100.0,APO_FAC 50.0,ORI_TYP #VAR}
"""
header_src = """&ACCESS RVP
&REL 1
&PARAM TEMPLATE = C:\KRC\Roboter\Template\ExpertVorgabe
&PARAM EDITMASK = *
"""
ptp_fold = """;FOLD PTP xp1 Vel=100 % PDAT1 Tool[6]:laser6 Base[2]:Laser;%{PE}%R 8.2.24,%MKUKATPBASIS,%CMOVE,%VPTP,%P 1:PTP, 2:xp1, 3:, 5:100, 7:PDAT1
$BWDSTART=FALSE
PDAT_ACT=PPDAT1
FDAT_ACT=Fxp1
BAS(#PTP_PARAMS,100)
PTP Xxp1
;ENDFOLD"""
class Kuka_Prog:
def __init__(self):
self.contour_path_list = []
self.hatchlines_list = []
self.base = (0,0,0)
def set_base(self, vec):
self.base = (vec.x, vec.y, vec.z)
def append_contour(self, poses, segmenttype = 'LIN'):
self.contour_path_list.append((poses, segmenttype))
def append_hatchline(self, line, segmenttype = 'LIN'):
if not len(self.hatchlines_list):
self.hatchlines_list.append((line, segmenttype))
# poses are sorted
# but maybe we need to reverse
#get the point distance from first and last pose
last, _ = self.hatchlines_list[-1]
nfirst = line[0]
nlast = line[-1]
last = FreeCAD.Base.Vector(last[1].X, last[1].Y, last[1].Z)
nlast = FreeCAD.Base.Vector(nlast.X, nlast.Y, nlast.Z)
nfirst = FreeCAD.Base.Vector(nfirst.X, nfirst.Y, nfirst.Z)
dnl = last.distanceToPoint(nlast)
dnf = last.distanceToPoint(nfirst)
if dnl < dnf:
line.reverse()
self.hatchlines_list.append((line, segmenttype))
def append_poses(self, poses):
if not len(self.pose_list):
self.pose_list.extend(poses)
# poses are sorted
# but maybe we need to reverse
#get the point distance from first and last pose
last = self.pose_list[-1]
nfirst = poses[0]
nlast = poses[-1]
last = FreeCAD.Base.Vector(last.X, last.Y, last.Z)
nlast = FreeCAD.Base.Vector(nlast.X, nlast.Y, nlast.Z)
nfirst = FreeCAD.Base.Vector(nfirst.X, nfirst.Y, nfirst.Z)
dnl = last.distanceToPoint(nlast)
dnf = last.distanceToPoint(nfirst)
if dnl < dnf:
poses.reverse()
self.pose_list.extend(poses)
def draw_wire(self, obj):
path = Part.makePolygon([FreeCAD.Base.Vector(p.X, p.Y, p.Z) for p in self.pose_list ])
#s = Part.show(path)
obj.addObject(s)
s.ViewObject.LineColor=(1.0,0.5,0.0)
s.ViewObject.LineWidth=(2.5)
def get_vectors(self):
return [FreeCAD.Base.Vector(p.X, p.Y, p.Z) for p in poses for poses in self.contour_path_list ]
def save_prog(self, filename):
if not filename.endswith('.src'):
filename = filename +'.src'
srcfile = open(filename, 'w')
srcfile.write(header_src)
# subroutine definition
srcfile.write("DEF "+filename+"( )\n\n")
srcfile.write(";- Kuka src file, generated by KVT\n")
srcfile.write(";- "+ time.asctime()+"\n\n")
# defining world and base
srcfile.write("E6POS startp\n")
# srcfile.write("DECL E6AXIS xp1={A1 -1.9, A2 -105.76, A3 79.97, A4 178.83, A5 -20.3, A6 -4.37, E1 -90, E2 0}\n")
srcfile.write(";------------- definitions ------------\n")
srcfile.write("EXT BAS (BAS_COMMAND :IN,REAL :IN ) ;set base to World\n")
srcfile.write("BAS (#INITMOV,0 ) ;Initialicing the defaults for Vel and so on \n\n")
srcfile.write("BAS (#TOOL,6) ;Initialicing the defaults for Vel and so on \n\n")
srcfile.write("BAS (#BASE,2) ;Initialicing the defaults for Vel and so on \n\n")
#srcfile.write(ptp_fold)
srcfile.write("PTP {A1 -33.31, A2 -104.71, A3 114.60, A4 282.66, A5 -39.21, A6 -104.87, E1 -90, E2 1.0}\n")
srcfile.write("\n;------------- main part ------------\n")
srcfile.write("startp=$POS_ACT\n")
#V = w.Velocity / 1000.0 # from mm/s to m/s
V_prozess = 0.0225
V_max = 0.15
CDIS = 2.3
CVEL = 95.0
LASERPOWER = 0.4
srcfile.write("$VEL.CP = %f ; m/s ; m/s \n"%V_max)
srcfile.write("$APO.CDIS = %f ; mm \n"%CDIS)
srcfile.write("$APO.CVEL = %f ; percent \n"%CVEL)
srcfile.write("$ANOUT[1] = %f ; \n"%LASERPOWER)
srcfile.write("$OUT[7] = TRUE ; \n")
srcfile.write("$OUT[9] = TRUE ; \n")
srcfile.write("LIN startp:{X -100.0, Y 0.0, Z 0.0, A 0.0000, B 0.0000, C 0.0000, E1 0.0000, E2 0.0000} C_VEL; GENERATED\n")
srcfile.write("WAIT SEC 10.0\n")
srcfile.write(";- Contourpaths\n")
for (poses, seg_type) in self.contour_path_list:
# start laser code
srcfile.write("$VEL.CP = %f ; m/s ; m/s \n"%V_prozess)
srcfile.write(";- Turn on Laser\n")
if seg_type == 'LIN':
srcfile.write("LIN startp:{} C_VEL; GENERATED\n".format(poses[0].translate_with(self.base).to_string()))
srcfile.write("TRIGGER WHEN DISTANCE=0 DELAY=0 DO $OUT[3]=True\n" ) ## Einschalten
for pose in poses[1:]:
srcfile.write("LIN startp:{} C_VEL; GENERATED\n".format(pose.translate_with(self.base).to_string()))
if seg_type == 'SPLINE':
srcfile.write("SPLINE\n")
for pose in poses:
srcfile.write(" SPL startp:{} ; GENERATED\n".format(pose.translate_with(self.base).to_string()))
srcfile.write("ENDSPLINE\n")
srcfile.write(";- Turn off Laser\n")
srcfile.write("$OUT[3] = FALSE\n")
# end of subroutine
srcfile.write(";- Hatchlines\n")
for (line, seg_type) in self.hatchlines_list:
# start laser code
srcfile.write(";- Hatchline\n")
if seg_type == 'LIN':
srcfile.write("$VEL.CP = %f ; m/s ; m/s \n"%V_max)
srcfile.write("LIN startp:{} C_VEL; GENERATED\n".format(line[0].translate_with(self.base).to_string()))
srcfile.write("TRIGGER WHEN DISTANCE=0 DELAY=0 DO $OUT[3]=True\n" ) ## Einschalten
srcfile.write("$VEL.CP = %f ; m/s ; m/s \n"%V_prozess)
srcfile.write("LIN startp:{} C_VEL; GENERATED\n".format(line[1].translate_with(self.base).to_string()))
srcfile.write("TRIGGER WHEN DISTANCE=0 DELAY=0 DO $OUT[3]=FALSE\n") ## Ausschalten
# end of subroutine
srcfile.write("$OUT[3] = FALSE\n")
srcfile.write("$OUT[7] = FALSE ; \n")
srcfile.write("$OUT[9] = FALSE ; \n")
srcfile.write("\n;------------- end ------------\n")
srcfile.write("END \n\n")
srcfile.close()
class Kuka_Pose:
def __init__(self):
self.X = 0.0
self.Y = 0.0
self.Z = 0.0
self.A = 0.0
self.B = 0.0
self.C = 0.0
self.S = 0
self.T = 0
self.E1 = 0.0
self.E2 = 0.0
def set_from_point_and_normal(self, point, normal):
self.X = point.x
self.Y = point.y
self.Z = point.z
r = FreeCAD.Base.Rotation(FreeCAD.Base.Vector(0,0,1), normal)
ABC_in_deg = r.toEulerAngles('ZYX')
self.A = math.radians(ABC_in_deg[0])
self.B = math.radians(ABC_in_deg[1])
self.C = math.radians(ABC_in_deg[2])
#print("Rotation:", self.A, self.B, self.C)
def from_point_and_normal(point, normal):
pose = Kuka_Pose()
pose.X = point.x
pose.Y = point.y
pose.Z = point.z
r = FreeCAD.Base.Rotation(FreeCAD.Base.Vector(0,0,1), normal)
ABC_in_deg = r.toEulerAngles('ZYX')
pose.A = math.radians(ABC_in_deg[0])
pose.B = math.radians(ABC_in_deg[1])
pose.C = math.radians(ABC_in_deg[2])
#print("Rotation:", self.A, self.B, self.C)
return pose
def to_string(self, rot=False):
if rot:
pose_string="X {:.3f}, Y {:.3f}, Z {:.3f}, A {:.4f}, B {:.4f}, C {:.4f}, E1 {:.4f}, E2 {:.4f}"
return "{" + pose_string.format(self.X, self.Y, self.Z, self.A, self.B, self.C, self.E1, self.E2) + "}"
else:
pose_string="X {:.3f}, Y {:.3f}, Z {:.3f}, A {:.4f}, B {:.4f}, C {:.4f}, E1 {:.4f}, E2 {:.4f}"
return "{" + pose_string.format(self.X, self.Y, self.Z, 0,0,0,0,0) + "}"
def translate_with(self, vector):
pose = copy.copy(self)
pose.X = pose.X - vector[0]
pose.Y = pose.Y - vector[1]
pose.Z = pose.Z - vector[2]
return pose
def draw_pose(self):
#line=Part.makeLine(point, point+3*normal)
#lines.append(line)
# from euler to some line
# create upfacing vector then rotate around each axis?
up = FreeCAD.Base.Vector(0,0,1)
rotx = FreeCAD.Base.Rotation(FreeCAD.Base.Vector(1,0,0), math.degrees(self.C))
roty = FreeCAD.Base.Rotation(FreeCAD.Base.Vector(0,1,0), math.degrees(self.B))
rotz = FreeCAD.Base.Rotation(FreeCAD.Base.Vector(0,0,1), math.degrees(self.A))
rot = rotz.multiply(roty.multiply(rotx))
up_rotated = rot.multVec(up)
basepoint = FreeCAD.Base.Vector(self.X, self.Y, self.Z)
line = Part.makeLine(basepoint, basepoint+5*up_rotated)
#line.Placement.Rotation = rot
s = Part.show(line)
s.ViewObject.LineColor=(1.0,0.0,0.0)
def get_list_of_poses(face, edges):
poses = []
for edge in edges:
p0 = edge.Vertexes[0].Point
p1 = edge.Vertexes[1].Point
for p in [p0, p1]:
uv = face.Surface.parameter(p)
normal = face.normalAt(uv[0], uv[1])
pose = Kuka_Pose.from_point_and_normal(p, normal)
poses.append(pose)
return poses

1029
freecad/LaserCladdingWorkbench/lc_resource.py

File diff suppressed because it is too large Load Diff

195
freecad/LaserCladdingWorkbench/pad.py

@ -0,0 +1,195 @@ @@ -0,0 +1,195 @@
import FreeCAD
import FreeCAD as App
import FreeCADGui as Gui
import numpy as np
import math
import Part
from shapely.geometry import Polygon, Point
from pyslm import hatching as hatching
from pyslm.geometry.geometry import LayerGeometryType
from typing import List
import rdp
from .utils import *
from freecad.LaserCladdingWorkbench.path import LaserPath
class LaserPad:
def __init__(self, obj, face):
obj.addProperty("App::PropertyFloatConstraint", "tool_width", "Parameters", "Width of the circular effect area of Laser in mm")
obj.tool_width = (2.3, 0.01, 20.0, 0.1)
obj.addProperty("App::PropertyFloatConstraint", "hatch_angle", "Hatching Parameters", "Hatch Angle")
obj.hatch_angle = (0.0, 0.0, 180.0, 1.0)
obj.addProperty("App::PropertyFloat", "hatch_volume_offset", "Parameters", "Offset between internal and external boundary")
obj.hatch_volume_offset = 2.3*0.5
obj.addProperty("App::PropertyFloat", "hatch_spot_compensation", "Parameters", "Additional offset to account for laser spot size")
obj.hatch_spot_compensation = 2.3*0.5
obj.addProperty("App::PropertyInteger", "hatch_inner_contours", "Parameters", "Inner Contours")
obj.hatch_inner_contours = 1
obj.addProperty("App::PropertyInteger", "hatch_outer_contours", "Parameters", "Outer Contours")
obj.hatch_outer_contours = 0
obj.addProperty("App::PropertyFloat", "hatch_contour_offset", "Parameters", "Contour Offset")
obj.hatch_contour_offset = 2.3
obj.addProperty("App::PropertyLinkGlobal","ref_body","Reference","body")
obj.ref_body = face[0]
obj.addProperty("App::PropertyString","ref_surface","Reference","face")
obj.ref_surface = face[1]
obj.addExtension("App::GroupExtensionPython")
obj.Proxy = self
self._create_path(obj)
def _create_path(self, obj):
print("Create_path")
print("obj.ref_surface", obj.ref_surface)
# if len(obj.Group):
# obj.removeObjectsFromDocument()
face = obj.ref_body.getSubObject(obj.ref_surface)
myHatcher = hatching.Hatcher()
myHatcher.hatchDistance = obj.tool_width
myHatcher.hatchAngle = obj.hatch_angle
myHatcher.volumeOffsetHatch = obj.hatch_volume_offset
myHatcher.spotCompensation = obj.hatch_spot_compensation
myHatcher.numInnerContours = obj.hatch_inner_contours
myHatcher.numOuterContours = obj.hatch_outer_contours
myHatcher.contourOffset = obj.hatch_contour_offset
myHatcher.hatchSortMethod = hatching.AlternateSort()
polygon_coords = get_coords_from_shape(face)
layer = myHatcher.hatch(polygon_coords)
contours_geoms = layer.getContourGeometry()
hatch_geoms = layer.getHatchGeometry()
contours = create_contour_lines(contours_geoms)
hatchlines = create_hatch_lines(hatch_geoms)
proj_contours = project_to_face(contours, face)
proj_hatchlines = project_to_face(hatchlines, face)
# DEBUG Part.show(Part.makeCompound(hatchlines))
obj.purgeTouched()
for pc in proj_contours:
p = Part.makeCompound(pc)
contours_comp = obj.newObject("Part::Feature", "Contours")
LaserPath(contours_comp)
contours_comp.Shape = p
contours_comp.ViewObject.LineColor = (0.5, 0.8, 0.9)
print("Creating Hatch Part")
hatches_comp = obj.newObject("Part::Feature", "Hatchlines")
p = Part.makeCompound([])
for pc in proj_hatchlines:
p.add(Part.makeCompound(pc))
LaserPath(hatches_comp)
hatches_comp.Shape = p
hatches_comp.ViewObject.LineColor = (0.9, 0.2, 0.2)
print("Group: ", obj.Group)
def onChanged(self, fp, prop):
'''Do something when a property has changed'''
App.Console.PrintMessage("Change property: " + str(prop) + "\n")
def execute(self, fp):
App.Console.PrintMessage("Recompute LaserPad\n")
# self._create_path(fp)
class ViewProviderLaserPad:
def __init__(self, obj):
'''Set this object to the proxy object of the actual view provider'''
obj.addProperty("App::PropertyColor", "Color", "Box", "Color of the box").Color=(1.0, 0.0, 0.0)
obj.addExtension("Gui::ViewProviderGroupExtensionPython")
self.Object = obj.Object
obj.Proxy = self
def claimChildren(self):
"""Return objects that will be placed under it in the tree view."""
App.Console.PrintMessage("Reclaim children\n")
claimed = []
App.Console.PrintMessage(self.__dict__)
for o in self.Object.OutList:
if o.TypeId == 'Part::Feature':
claimed.append(o)
return claimed
def attach(self, vobj):
self.Object = vobj.Object
self.ViewObject = vobj
def getDisplayModes(self, obj):
"'''Return a list of display modes.'''"
return ["Standard"]
def getDefaultDisplayMode(self):
"'''Return the name of the default display mode. It must be defined in getDisplayModes.'''"
return "Standard"
def updateData(self, fp, prop):
'''If a property of the handled feature has changed we have the chance to handle this here'''
# fp is the handled feature, prop is the name of the property that has changed
pass
def setDisplayMode(self, mode):
'''Map the display mode defined in attach with those defined in getDisplayModes.\
Since they have the same names nothing needs to be done. This method is optional'''
return mode
def onChanged(self, vp, prop):
'''Here we can do something when a single property got changed'''
App.Console.PrintMessage("Change property: " + str(prop) + "\n")
# if prop == "Color":
# c = vp.getPropertyByName("Color")
# self.color.rgb.setValue(c[0],c[1],c[2])
def getIcon(self):
'''Return the icon in XPM format which will appear in the tree view. This method is\
optional and if not defined a default icon is shown.'''
return """
/* XPM */
static const char * ViewProviderBox_xpm[] = {
"16 16 6 1",
" c None",
". c #141010",
"+ c #615BD2",
"@ c #C39D55",
"# c #000000",
"$ c #57C355",
" ........",
" ......++..+..",
" .@@@@.++..++.",
" .@@@@.++..++.",
" .@@ .++++++.",
" ..@@ .++..++.",
"###@@@@ .++..++.",
"##$.@@$#.++++++.",
"#$#$.$$$........",
"#$$####### ",
"#$$#$$$$$# ",
"#$$#$$$$$# ",
"#$$#$$$$$# ",
" #$#$$$$$# ",
" ##$$$$$# ",
" ####### "};
"""
def __getstate__(self):
'''When saving the document this object gets stored using Python's json module.\
Since we have some un-serializable parts here -- the Coin stuff -- we must define this method\
to return a tuple of all serializable objects or None.'''
return None
def __setstate__(self, state):
'''When restoring the serialized object from document we have the chance to set some internals here.\
Since no data were serialized nothing needs to be done here.'''
return None

17
freecad/LaserCladdingWorkbench/path.py

@ -0,0 +1,17 @@ @@ -0,0 +1,17 @@
import FreeCAD as App
import FreeCADGui as Gui
class LaserPath:
def __init__(self, obj):
obj.addProperty("App::PropertyEnumeration", "pathtype", "Parameter", "How this path is converted to robot")
obj.pathtype = ["LIN", "CIRC", "SPLINE"]
# obj.addExtension("App::GroupExtensionPython")
# obj.Proxy = self
def onChanged(self, fp, prop):
'''Do something when a property has changed'''
App.Console.PrintMessage("Change property: " + str(prop) + "\n")
def execute(self, fp):
App.Console.PrintMessage("Recompute LaserPath\n")

74
lasercladding/job.py → freecad/LaserCladdingWorkbench/program.py

@ -1,18 +1,44 @@ @@ -1,18 +1,44 @@
import FreeCAD
import FreeCAD as App
import numpy as np
import math
import time
import Part
import Draft
class LaserJob:
class LaserProgram:
def __init__(self, obj):
'''Add some custom properties to our box feature'''
obj.addProperty("App::PropertyVector", "base_reference", "Reference", "Reference Point (teached)")
obj.base_reference = App.Vector(0,0,0)
## to make addObject() available
obj.addExtension("App::GroupExtensionPython", None)
obj.Proxy = self
def addObject(self, obj):
self.pads = [obj]
obj.addProperty("App::PropertyFloat", "laser_power", "Laser Parameter", "Laser Power output (0.4 means 4 Volts)")
obj.laser_power = 0.4
obj.addProperty("App::PropertyInteger", "laser_pilot_out", "Laser Parameter", "Pilot Laser output")
obj.laser_pilot_out = 4
obj.addProperty("App::PropertyInteger", "laser_real_out", "Laser Parameter", "Laser output")
obj.laser_real_out = 3
obj.addProperty("App::PropertyInteger", "laser_gas_out", "Laser Parameter", "Laser inert gas")
obj.laser_gas_out = 7
obj.addProperty("App::PropertyInteger", "laser_powder_out", "Laser Parameter", "Laser Powder Bucket")
obj.laser_powder_out = 9
obj.addProperty("App::PropertyFloat", "laser_feedrate", "Laser Parameter", "Process Velocity (Feedrate m/s)")
obj.laser_feedrate = 0.022500
obj.addProperty("App::PropertyFloat", "laser_speed", "Laser Parameter", "Velocity reaching (m/s)")
obj.laser_speed = 0.15
obj.addProperty("App::PropertyFile", "progpath", "Export Parameters", "Where to store the Program")
obj.progpath = "/home/jk/test_export_workbench.src"
obj.addExtension("App::GroupExtensionPython")
obj.Proxy = self
def onChanged(self, fp, prop):
'''Do something when a property has changed'''
@ -20,41 +46,33 @@ class LaserJob: @@ -20,41 +46,33 @@ class LaserJob:
def execute(self, fp):
'''Do something when doing a recomputation, this method is mandatory'''
App.Console.PrintMessage("Recompute Python Box feature\n")
App.Console.PrintMessage("Recompute LaserPad\n")
class ViewProviderLaserJob:
class ViewProviderLaserProgram:
def __init__(self, obj):
'''Set this object to the proxy object of the actual view provider'''
obj.addProperty("App::PropertyColor","Color","Box","Color of the box").Color=(1.0,0.0,0.0)
obj.addExtension("Gui::ViewProviderGroupExtensionPython")
obj.Proxy = self
obj.addExtension("Gui::ViewProviderGroupExtensionPython", None)
def attach(self, vobj):
obj = vobj.Object
obj.Proxy = self
def getDisplayModes(self,obj):
"'''Return a list of display modes.'''"
return ["Standard"]
def getDefaultDisplayMode(self):
"'''Return the name of the default display mode. It must be defined in getDisplayModes.'''"
return "Standard"
def attach(self, obj):
'''Setup the scene sub-graph of the view provider, this method is mandatory'''
self.onChanged(obj,"Color")
def updateData(self, fp, prop):
'''If a property of the handled feature has changed we have the chance to handle this here'''
# fp is the handled feature, prop is the name of the property that has changed
pass
def getDisplayModes(self,obj):
'''Return a list of display modes.'''
modes=[]
modes.append("Shaded")
modes.append("Wireframe")
return modes
def getDefaultDisplayMode(self):
'''Return the name of the default display mode. It must be defined in getDisplayModes.'''
return "Shaded"
def setDisplayMode(self,mode):
'''Map the display mode defined in attach with those defined in getDisplayModes.\
Since they have the same names nothing needs to be done. This method is optional'''

160
freecad/LaserCladdingWorkbench/utils.py

@ -0,0 +1,160 @@ @@ -0,0 +1,160 @@
import FreeCAD
import FreeCAD as App
import FreeCADGui as Gui
import numpy as np
import math
import Part
from shapely.geometry import Polygon, Point
from pyslm import hatching as hatching
from pyslm.geometry.geometry import LayerGeometryType
from typing import List
import rdp
def project_to_face(compounds, face):
# proj = Part.makeCompound([])
proj = []
for c in compounds:
projection_result = []
for e in c.Edges:
projection_result.append(face.makeParallelProjection(e, App.Vector(0, 0, 1)))
# proj.add(Part.makeCompound(projection_result))
proj.append(projection_result)
return proj
def map_wire(wire, surface):
"""Map wire on target surface
Input wire must be on XY plane"""
plane = Part.Plane().toShape()
mapped_edges = []
for e in wire.Edges:
c, fp, lp = plane.curveOnSurface(e)
mapped_edges.append(c.toShape(surface, fp, lp))
return Part.Wire(mapped_edges)
def path2DToPathList(shapes: List[Polygon]) -> List[np.ndarray]:
"""
Returns the list of paths and coordinates from a cross-section (i.e. Trimesh Path2D). This is required to be
done for performing boolean operations and offsetting with the internal PyClipper package.
:param shapes: A list of :class:`shapely.geometry.Polygon` representing a cross-section or container of
closed polygons
:return: A list of paths (Numpy Coordinate Arrays) describing fully closed and oriented paths.
"""
paths = []
for poly in shapes:
coords = np.array(poly.exterior.coords)
paths.append(coords)
for path in poly.interiors:
coords = np.array(path.coords)
paths.append(coords)
return paths
def get_polypoints_from_edges(edges):
# print("START NEW POLYGON")
poly_points = []
# print("edges:", len(edges))
for edge in Part.__sortEdges__(edges):
if type(edge.Curve) is Part.Circle and edge.Closed:
# print("Edge is Circle")
c = edge.Curve
center = Point(c.Center.x, c.Center.y)
radius = c.Radius
circle = center.buffer(radius)
poly_points = circle.exterior.coords
elif type(edge.Curve) in [Part.Ellipse, Part.BSplineCurve, Part.Circle]:
# print("Edge is Ellipse, BSpline or unclosed Circle")
n = math.floor(edge.Length/2.3)
if n > 200:
n = 200
if edge.Closed:
# print("Edge is closed Ellipse or BSpline")
for v in edge.discretize(Number=n):
poly_points.append((v.x, v.y))
else:
# print("Edge is unclosed Circle")
# for Circles at least 64 steps for full circle
for v in edge.discretize(Number=n, First=edge.FirstParameter, Last=edge.LastParameter):
poly_points.append((v.x, v.y))
else:
# print("Line Vertexes:", len(edge.Vertexes))
# print("Line Vertexes:", [(v.Point.x, v.Point.y) for v in edge.Vertexes])
for v in edge.Vertexes:
poly_points.append((v.Point.x, v.Point.y))
u = np.unique(poly_points, axis=0)
# print("UNIQUE:", u)
# print("END NEW POLYGON")
return poly_points
def tuple_is_equal(t1, t2):
if math.isclose(t1[0], t2[0]) and math.isclose(t1[1], t2[1]):
return True
return False
def get_polygon_from_subshape(subshape):
# print("START NEW POLYGON")
polygon = []
for edge in Part.__sortEdges__(subshape.Edges):
poly_points = []
if type(edge.Curve) in [Part.Ellipse, Part.BSplineCurve, Part.Circle]:
n = math.floor(edge.Length/2.3)
for v in edge.discretize(Number=n, First=edge.FirstParameter, Last=edge.LastParameter):
poly_points.append((v.x, v.y))
else:
# print("Line Vertexes:", len(edge.Vertexes))
# print("Line Vertexes:", [(v.Point.x, v.Point.y) for v in edge.Vertexes])
for v in edge.Vertexes:
poly_points.append((v.Point.x, v.Point.y))
if len(polygon):
if tuple_is_equal(poly_points[0], polygon[-1]):
polygon.extend(poly_points[1:])
else:
polygon.extend(poly_points)
else:
polygon.extend(poly_points)
# print("END NEW POLYGON")
# return LinearRing(polygon)
return polygon
def get_coords_from_shape(face):
outerpoly = get_polygon_from_subshape(face.OuterWire)
inner_polys = []
for inner_wire in face.SubShapes[1:]:
tmp = get_polygon_from_subshape(inner_wire)
inner_polys.append(tmp)
poly = Polygon(outerpoly, holes=inner_polys)
return path2DToPathList([poly])
def create_hatch_lines(geoms):
hatchlines = []
for geom in geoms:
if geom.type() == LayerGeometryType.Hatch:
# print("Hatch with {} coords".format(len(geom.coords)))
hatches = np.vstack([geom.coords.reshape(-1, 2, 2)])
for line in hatches:
p0 = line[0]
p1 = line[1]
pp = Part.makeLine(App.Vector(p0[0], p0[1],0), App.Vector(p1[0],p1[1],0))
hatchlines.append(pp)
return hatchlines
def create_contour_lines(geoms):
contours = []
for geom in geoms:
if geom.type() == LayerGeometryType.Polygon:
# print("Contour with {} coords".format(len(geom.coords)))
coords = rdp.rdp(geom.coords, epsilon=0.3, algo="iter", return_mask=False)
# print("Simplfied Poly:", len(coords))
pp = Part.makePolygon([App.Vector(x,y,0) for (x,y) in coords])
contours.append(pp)
return contours

6
lasercladding/__init__.py

@ -1,6 +0,0 @@ @@ -1,6 +0,0 @@
# module lasercladding
from .commands import *
from .path import *
from .job import *
from .kuka import *

77
lasercladding/commands.py

@ -1,77 +0,0 @@ @@ -1,77 +0,0 @@
import FreeCAD as App
import FreeCADGui as Gui
import Part
from .job import LaserJob, ViewProviderLaserJob
from .pad import LaserPad, create_laserpad
class CreateCladdingJob():
def Activated(self):
# Here your write what your ScriptCmd does...
App.Console.PrintMessage('Create Lasser Cladding Job')
a=App.ActiveDocument.addObject("App::FeaturePython","LaserJob")
LaserJob(a)
ViewProviderLaserJob(a.ViewObject)
def GetResources(self):
return {'Pixmap' : 'path_to_an_icon/myicon.png', 'MenuText': 'Create Cladding Job', 'ToolTip': 'Add a Job to your Document'}
class SelectBaseReference():
def Activated(self):
# Here your write what your ScriptCmd does...
App.Console.PrintMessage('Select Base reference!')
if not Gui.Selection.hasSelection():
App.Console.PrintMessage('Select a Vertex')
return
# check length
selection = Gui.Selection.getSelectionEx()
# find first vertex
for s in selection:
if s.HasSubObjects:
for obj in s.SubObjects:
if isinstance(obj, Part.Vertex):
vertex = obj.copy()
laserjob_entry = App.ActiveDocument.getObject('LaserJob')
if laserjob_entry is None:
App.Console.PrintMessage('Create a LaserJob first')
return
laserjob_entry.base_reference = App.Vector((vertex.X, vertex.Y, vertex.Z))
App.ActiveDocument.recompute()
def GetResources(self):
return {'Pixmap' : 'path_to_an_icon/myicon.png', 'MenuText': 'Select Base reference', 'ToolTip': 'Add a Job to your Document'}
class CreatePad():
def Activated(self):
# Here your write what your ScriptCmd does...
App.Console.PrintMessage('Select some Face as reference')
if not Gui.Selection.hasSelection():
App.Console.PrintMessage('Select a Face')
return
# check length
ref_face = (Gui.Selection.getSelection()[0],
Gui.Selection.getSelectionEx()[0].SubElementNames[0])
#selection = Gui.Selection.getSelectionEx()
# find first vertex
#for s in selection:
# if s.HasSubObjects:
# for obj in s.SubObjects:
# if isinstance(obj, Part.Face):
# face = obj.copy()
create_laserpad(ref_face)
App.ActiveDocument.recompute()
def GetResources(self):
return {'Pixmap' : 'path_to_an_icon/myicon.png', 'MenuText': 'Select Base reference', 'ToolTip': 'Add a Job to your Document'}
Gui.addCommand('CreateCladdingJob', CreateCladdingJob())
Gui.addCommand('SelectBaseReference', SelectBaseReference())
Gui.addCommand('CreatePad', CreatePad())

170
lasercladding/kuka.py

@ -1,170 +0,0 @@ @@ -1,170 +0,0 @@
import FreeCAD
import numpy as np
import math
import time
import Part
TeachPointFold = """
;FOLD LIN P4 Vel= 0.2 m/s CPDAT1 Tool[1] Base[0];%{PE}%R 5.4.27,%MKUKATPBASIS,%CMOVE,%VLIN,%P 1:LIN, 2:P4, 3:, 5:0.2, 7:CPDAT1
$BWDSTART = FALSE
LDAT_ACT=LCPDAT1
FDAT_ACT=FP4
BAS(#CP_PARAMS,0.2)
LIN XP4
;ENDFOLD
"""
TeachPointDat = """
DECL E6POS XP4={X -25.1844196,Y 1122.42603,Z 1158.07996,A -14.3267002,B 0.537901878,C 179.028305,S 6,T 59,E1 0.0,E2 0.0,E3 0.0,E4 0.0,E5 0.0,E6 0.0}
DECL FDAT FP4={TOOL_NO 1,BASE_NO 0,IPO_FRAME #BASE,POINT2[] " "}
DECL LDAT LCPDAT1={VEL 2.0,ACC 100.0,APO_DIST 100.0,APO_FAC 50.0,ORI_TYP #VAR}
"""
header_src = """&ACCESS RVP
&REL 1
&PARAM TEMPLATE = C:\KRC\Roboter\Template\ExpertVorgabe
&PARAM EDITMASK = *
"""
class Kuka_Prog:
def __init__(self):
self.pose_list = []
self.base = (0,0,0)
def append_pose(self, pose):
self.pose_list.append(pose)
def append_poses(self, poses):
if not len(self.pose_list):
self.pose_list.extend(poses)
# poses are sorted
# but maybe we need to reverse
#get the point distance from first and last pose
last = self.pose_list[-1]
nfirst = poses[0]
nlast = poses[-1]
last = FreeCAD.Base.Vector(last.X, last.Y, last.Z)
nlast = FreeCAD.Base.Vector(nlast.X, nlast.Y, nlast.Z)
nfirst = FreeCAD.Base.Vector(nfirst.X, nfirst.Y, nfirst.Z)
dnl = last.distanceToPoint(nlast)
dnf = last.distanceToPoint(nfirst)
if dnl < dnf:
poses.reverse()
self.pose_list.extend(poses)
def draw_wire(self):
path = Part.makePolygon([FreeCAD.Base.Vector(p.X, p.Y, p.Z) for p in self.pose_list ])
s = Part.show(path)
s.ViewObject.LineColor=(1.0,0.5,0.0)
s.ViewObject.LineWidth=(2.5)
def save_prog(self, filename):
srcfile = open(filename+'.src','w')
srcfile.write(header_src)
# subroutine definition
srcfile.write("DEF "+filename+"( )\n\n")
srcfile.write(";- Kuka src file, generated by KVT\n")
srcfile.write(";- "+ time.asctime()+"\n\n")
# defining world and base
srcfile.write("E6POS startp\n")
srcfile.write(";------------- definitions ------------\n")
srcfile.write("EXT BAS (BAS_COMMAND :IN,REAL :IN ) ;set base to World\n")
srcfile.write("BAS (#INITMOV,0 ) ;Initialicing the defaults for Vel and so on \n\n")
srcfile.write("BAS (#TOOL,6) ;Initialicing the defaults for Vel and so on \n\n")
srcfile.write("BAS (#BASE,2) ;Initialicing the defaults for Vel and so on \n\n")
srcfile.write("PTP {A1 -1.9, A2 -105.76, A3 79.97, A4 178.83, A5 -20.3, A6 -4.37, E1 -90, E2 0}\n")
srcfile.write(";------------- main part ------------\n")
srcfile.write("startp=$POS_ACT\n")
#V = w.Velocity / 1000.0 # from mm/s to m/s
V = 0.05
srcfile.write("$VEL.CP = %f ; m/s ; m/s \n"%V)
for pose in self.pose_list:
srcfile.write("LIN startp:{} C_VEL; GENERATED\n".format(pose.to_string()))
# end of subroutine
srcfile.write("\n;------------- end ------------\n")
srcfile.write("END \n\n")
srcfile.close()
class Kuka_Pose:
def __init__(self):
self.X = 0.0
self.Y = 0.0
self.Z = 0.0
self.A = 0.0
self.B = 0.0
self.C = 0.0
self.S = 0
self.T = 0
self.E1 = 0.0
self.E2 = 0.0
def set_from_point_and_normal(self, point, normal):
self.X = point.x
self.Y = point.y
self.Z = point.z
r = FreeCAD.Base.Rotation(FreeCAD.Base.Vector(0,0,1), normal)
ABC_in_deg = r.toEulerAngles('ZYX')
self.A = math.radians(ABC_in_deg[0])
self.B = math.radians(ABC_in_deg[1])
self.C = math.radians(ABC_in_deg[2])
#print("Rotation:", self.A, self.B, self.C)
def from_point_and_normal(point, normal):
pose = Kuka_Pose()
pose.X = point.x
pose.Y = point.y
pose.Z = point.z
r = FreeCAD.Base.Rotation(FreeCAD.Base.Vector(0,0,1), normal)
ABC_in_deg = r.toEulerAngles('ZYX')
pose.A = math.radians(ABC_in_deg[0])
pose.B = math.radians(ABC_in_deg[1])
pose.C = math.radians(ABC_in_deg[2])
#print("Rotation:", self.A, self.B, self.C)
return pose
def to_string(self):
pose_string="X {:.3f}, Y {:.3f}, Z {:.3f}, A {:.4f}, B {:.4f}, C {:.4f}, E1 {:.4f}, E2 {:.4f}"
return "{" + pose_string.format(self.X, self.Y, self.Z, self.A, self.B, self.C, self.E1, self.E2) + "}"
def draw_pose(self):
#line=Part.makeLine(point, point+3*normal)
#lines.append(line)
# from euler to some line
# create upfacing vector then rotate around each axis?
up = FreeCAD.Base.Vector(0,0,1)
rotx = FreeCAD.Base.Rotation(FreeCAD.Base.Vector(1,0,0), math.degrees(self.C))
roty = FreeCAD.Base.Rotation(FreeCAD.Base.Vector(0,1,0), math.degrees(self.B))
rotz = FreeCAD.Base.Rotation(FreeCAD.Base.Vector(0,0,1), math.degrees(self.A))
rot = rotz.multiply(roty.multiply(rotx))
up_rotated = rot.multVec(up)
basepoint = FreeCAD.Base.Vector(self.X, self.Y, self.Z)
line = Part.makeLine(basepoint, basepoint+5*up_rotated)
#line.Placement.Rotation = rot
s = Part.show(line)
s.ViewObject.LineColor=(1.0,0.0,0.0)
def get_list_of_poses(face, edge, n):
poses = []
points = edge.discretize(n)
lines = []
for point in points:
uv = face.Surface.parameter(point)
normal = face.normalAt(uv[0], uv[1])
line=Part.makeLine(point, point+3*normal)
lines.append(line)
# create pose
pose = Kuka_Pose.from_point_and_normal(point, normal)
poses.append(pose)
return poses

149
lasercladding/pad.py

@ -1,149 +0,0 @@ @@ -1,149 +0,0 @@
import FreeCAD as App
import numpy as np
from . import kuka
class LaserPad:
def __init__(self, obj, face):
'''Add some custom properties to our box feature'''
obj.addProperty("App::PropertyEnumeration", "pathtype", "SlicingParameters", "Type of Path generation (slice, etc)")
obj.pathtype = ["sliced", "auto", "wire"]
obj.addProperty("App::PropertyEnumeration", "slicedirection", "SlicingParameters", "When Slicing, which direction to use")
obj.slicedirection = ["xaxis", "yaxis", "zaxis", "custom"]
obj.addProperty("App::PropertyLinkSub","ref_surface","SlicingParameters","reference_1")
obj.ref_surface = face
obj.Proxy = self
def onChanged(self, fp, prop):
'''Do something when a property has changed'''
App.Console.PrintMessage("Change property: " + str(prop) + "\n")
def execute(self, fp):
'''Do something when doing a recomputation, this method is mandatory'''
App.Console.PrintMessage("Recompute LaserPad\n")
face = fp.ref_surface[0].getSubObject(fp.ref_surface[1])[0]
print(face)
if fp.pathtype == "sliced":
xmin = face.BoundBox.XMin
xmax = face.BoundBox.XMax
ymin = face.BoundBox.YMin
ymax = face.BoundBox.YMax
slice_direction = App.Vector(0,0,0)
if fp.slicedirection == "xaxis":
slice_direction = App.Vector(1,0,0)
pmin, pmax = xmin, xmax
if fp.slicedirection == "yaxis":
slice_direction = App.Vector(0,1,0)
pmin, pmax = ymin, ymax
if fp.slicedirection == "zaxis":
slice_direction = App.Vector(0,0,1)
pmin, pmax = zmin, zmax
slices = face.slices(slice_direction, [x for x in np.arange(pmin, pmax, 2)])
prog = kuka.Kuka_Prog()
for edge in slices.Edges:
poses = kuka.get_list_of_poses(face, edge, 10)
prog.append_poses(poses)
prog.draw_wire()
prog.save_prog("/home/jk/test_export_workbench")
### helper to create some object
def create_laserpad(face):
laserjob_entry = App.ActiveDocument.getObject('LaserJob')
if laserjob_entry is None:
App.Console.PrintMessage('Create a LaserJob first')
return
pad_obj = App.ActiveDocument.addObject("App::FeaturePython","LaserPad")
pad = LaserPad(pad_obj, face)
#a=laserjob_entry.addObbject(pad)
ViewProviderLaserPad(pad.ViewProvider)
return pad
class ViewProviderLaserPad:
def __init__(self, obj):
'''Set this object to the proxy object of the actual view provider'''
obj.addProperty("App::PropertyColor","Color","Box","Color of the box").Color=(1.0,0.0,0.0)
obj.Proxy = self
def attach(self, obj):
'''Setup the scene sub-graph of the view provider, this method is mandatory'''
self.onChanged(obj,"Color")
def updateData(self, fp, prop):
'''If a property of the handled feature has changed we have the chance to handle this here'''
# fp is the handled feature, prop is the name of the property that has changed
pass
def getDisplayModes(self,obj):
'''Return a list of display modes.'''
modes=[]
modes.append("Shaded")
modes.append("Wireframe")
return modes
def getDefaultDisplayMode(self):
'''Return the name of the default display mode. It must be defined in getDisplayModes.'''
return "Shaded"
def setDisplayMode(self,mode):
'''Map the display mode defined in attach with those defined in getDisplayModes.\
Since they have the same names nothing needs to be done. This method is optional'''
return mode
def onChanged(self, vp, prop):
'''Here we can do something when a single property got changed'''
App.Console.PrintMessage("Change property: " + str(prop) + "\n")
#if prop == "Color":
# c = vp.getPropertyByName("Color")
# self.color.rgb.setValue(c[0],c[1],c[2])
def getIcon(self):
'''Return the icon in XPM format which will appear in the tree view. This method is\
optional and if not defined a default icon is shown.'''
return """
/* XPM */
static const char * ViewProviderBox_xpm[] = {
"16 16 6 1",
" c None",
". c #141010",
"+ c #615BD2",
"@ c #C39D55",
"# c #000000",
"$ c #57C355",
" ........",
" ......++..+..",
" .@@@@.++..++.",
" .@@@@.++..++.",
" .@@ .++++++.",
" ..@@ .++..++.",
"###@@@@ .++..++.",
"##$.@@$#.++++++.",
"#$#$.$$$........",
"#$$####### ",
"#$$#$$$$$# ",
"#$$#$$$$$# ",
"#$$#$$$$$# ",
" #$#$$$$$# ",
" ##$$$$$# ",
" ####### "};
"""
def __getstate__(self):
'''When saving the document this object gets stored using Python's json module.\
Since we have some un-serializable parts here -- the Coin stuff -- we must define this method\
to return a tuple of all serializable objects or None.'''
return None
def __setstate__(self,state):
'''When restoring the serialized object from document we have the chance to set some internals here.\
Since no data were serialized nothing needs to be done here.'''
return None

16
lasercladding/path.py

@ -1,16 +0,0 @@ @@ -1,16 +0,0 @@
import FreeCAD as App
class LaserPath:
def __init__(self, obj):
'''Add some custom properties to our box feature'''
obj.addProperty("App::Property", "base_reference", "Reference", "Reference Point (teached)")
obj.base_reference = App.Vector(0,0,0)
obj.Proxy = self
def onChanged(self, fp, prop):
'''Do something when a property has changed'''
App.Console.PrintMessage("Change property: " + str(prop) + "\n")
def execute(self, fp):
'''Do something when doing a recomputation, this method is mandatory'''
App.Console.PrintMessage("Recompute Python Box feature\n")
Loading…
Cancel
Save