Browse Source

new path2D function from pySLM

master
Jörg Kurlbaum 3 years ago
parent
commit
cc25701e4c
  1. 2
      freecad/LaserCladdingWorkbench/Resources/LaserCladding.qrc
  2. 351
      freecad/LaserCladdingWorkbench/Resources/icons/Laser_Workbench.svg
  3. 5
      freecad/LaserCladdingWorkbench/init_gui.py
  4. 9
      freecad/LaserCladdingWorkbench/pad.py
  5. 3
      freecad/LaserCladdingWorkbench/path.py
  6. 6
      freecad/LaserCladdingWorkbench/program.py
  7. 19
      freecad/LaserCladdingWorkbench/utils.py

2
freecad/LaserCladdingWorkbench/Resources/LaserCladding.qrc

@ -1,6 +1,6 @@ @@ -1,6 +1,6 @@
<RCC>
<qresource>
<file>icons/Laser_Workbench.svg</file>
<file>icons/LaserWorkbench.svg</file>
<file>icons/LaserCreatePad.svg</file>
<file>icons/LaserCreateProg.svg</file>
<file>icons/LaserRecomputePad.svg</file>

351
freecad/LaserCladdingWorkbench/Resources/icons/Laser_Workbench.svg

@ -1,351 +0,0 @@ @@ -1,351 +0,0 @@
<?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="Laser_Workbench.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="1278"
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" />
<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" />
</svg>

Before

Width:  |  Height:  |  Size: 11 KiB

5
freecad/LaserCladdingWorkbench/init_gui.py

@ -9,8 +9,9 @@ import os @@ -9,8 +9,9 @@ import os
class LaserCladding (Gui.Workbench):
MenuText = "Laser Cladding"
ToolTip = "Create Simple Paths on workpieces for Laser Cladding"
Icon = ":/icons/Laser_Workbench.svg"
Icon = os.path.join(App.getUserAppDataDir(),
"Mod", "fc_lasercladding_wb","freecad", "LaserCladdingWorkbench",
"Resources", "icons", "LaserWorkbench.svg")
def __init__(self):
pass

9
freecad/LaserCladdingWorkbench/pad.py

@ -64,6 +64,9 @@ class LaserPad: @@ -64,6 +64,9 @@ class LaserPad:
myHatcher.hatchSortMethod = hatching.AlternateSort()
polygon_coords = get_coords_from_shape(face)
print("===== coords from shape ======")
print("{}", polygon_coords)
print("===== ======")
layer = myHatcher.hatch(polygon_coords)
contours_geoms = layer.getContourGeometry()
@ -97,7 +100,8 @@ class LaserPad: @@ -97,7 +100,8 @@ class LaserPad:
def onChanged(self, fp, prop):
'''Do something when a property has changed'''
App.Console.PrintMessage("Change property: " + str(prop) + "\n")
# App.Console.PrintMessage("Change property: " + str(prop) + "\n")
pass
def execute(self, fp):
App.Console.PrintMessage("Recompute LaserPad\n")
@ -149,10 +153,11 @@ class ViewProviderLaserPad: @@ -149,10 +153,11 @@ class ViewProviderLaserPad:
def onChanged(self, vp, prop):
'''Here we can do something when a single property got changed'''
App.Console.PrintMessage("Change property: " + str(prop) + "\n")
# 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])
pass
def getIcon(self):
'''Return the icon in XPM format which will appear in the tree view. This method is\

3
freecad/LaserCladdingWorkbench/path.py

@ -11,7 +11,8 @@ class LaserPath: @@ -11,7 +11,8 @@ class LaserPath:
def onChanged(self, fp, prop):
'''Do something when a property has changed'''
App.Console.PrintMessage("Change property: " + str(prop) + "\n")
#App.Console.PrintMessage("Change property: " + str(prop) + "\n")
pass
def execute(self, fp):
App.Console.PrintMessage("Recompute LaserPath\n")

6
freecad/LaserCladdingWorkbench/program.py

@ -54,7 +54,8 @@ class LaserProgram: @@ -54,7 +54,8 @@ class LaserProgram:
def onChanged(self, fp, prop):
'''Do something when a property has changed'''
App.Console.PrintMessage("Change property: " + str(prop) + "\n")
#App.Console.PrintMessage("Change property: " + str(prop) + "\n")
pass
def execute(self, fp):
'''Do something when doing a recomputation, this method is mandatory'''
@ -95,10 +96,11 @@ class ViewProviderLaserProgram: @@ -95,10 +96,11 @@ class ViewProviderLaserProgram:
def onChanged(self, vp, prop):
'''Here we can do something when a single property got changed'''
App.Console.PrintMessage("Change property: " + str(prop) + "\n")
# 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])
pass
def getIcon(self):
'''Return the icon in XPM format which will appear in the tree view. This method is\

19
freecad/LaserCladdingWorkbench/utils.py

@ -4,6 +4,7 @@ import FreeCADGui as Gui @@ -4,6 +4,7 @@ import FreeCADGui as Gui
import numpy as np
import math
import Part
import shapely
from shapely.geometry import Polygon, Point
from pyslm import hatching as hatching
from pyslm.geometry.geometry import LayerGeometryType
@ -33,14 +34,17 @@ def map_wire(wire, surface): @@ -33,14 +34,17 @@ def map_wire(wire, surface):
return Part.Wire(mapped_edges)
def path2DToPathList(shapes: List[Polygon]) -> List[np.ndarray]:
def path2DToPathList(shapes: List[shapely.geometry.polygon.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
Returns the list of paths and coordinates from a cross-section (i.e. :class:`Trimesh.path.Path2D` objects).
This is required to be done for performing boolean operations and offsetting with the internal PyClipper package.
:param shapes: A list of Shapely Polygons 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:
@ -100,7 +104,7 @@ def tuple_is_equal(t1, t2): @@ -100,7 +104,7 @@ def tuple_is_equal(t1, t2):
def get_polygon_from_subshape(subshape):
# print("START NEW POLYGON")
polygon = []
for edge in Part.__sortEdges__(subshape.Edges):
for edge in subshape.Edges: # Part.__sortEdges__(subshape.Edges):
poly_points = []
if type(edge.Curve) in [Part.Ellipse, Part.BSplineCurve, Part.Circle]:
n = math.floor(edge.Length/2.3)
@ -131,6 +135,7 @@ def get_coords_from_shape(face): @@ -131,6 +135,7 @@ def get_coords_from_shape(face):
tmp = get_polygon_from_subshape(inner_wire)
inner_polys.append(tmp)
poly = Polygon(outerpoly, holes=inner_polys)
print("Polygon: ", poly)
return path2DToPathList([poly])
@ -153,8 +158,8 @@ def create_contour_lines(geoms): @@ -153,8 +158,8 @@ def create_contour_lines(geoms):
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)
#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])
pp = Part.makePolygon([App.Vector(x,y,0) for (x,y) in geom.coords])
contours.append(pp)
return contours

Loading…
Cancel
Save