pyslm
pyslm copied to clipboard
Using the pyslm.hatching.*Hatcher with shapely object as input
Hi, i'm trying to use some of the pySLM methods to do some basic hatching for robot tool path generation (there are not so many hatching implementation out there).
The idea is to create a shapely.Polygon oder shapely.LineString from a set of arbitrary points (x,y). Then i like to feed this polygon into one of the Hatchers from pySLM.
The examples use getVectorSlice() for generating input for the .hatch() method.
Can i generate the input for hatching from shapely Objects? Or would it be possible to generate input directly based on some list of points that describe a polygon?
The whole point is to generate paths for some laser cladding application, where the surface boundaries are extracted from some CAD document via FreeCAD.
HI,
Sounds an interesting application.
That is fine and definitely possible. As you suggested you can directly export the path segments as a series of coordinates from the shapely objects. There's an internal function for extracting segment/path coordinates from shapely polygons into a format (list of coordinates) used internally by the clipper library in PySLM. This function iterates through the paths within a Shapely polygon list and extracts the coordinates into a compatible list of coordinates.
def path2DToPathList shapes) -> List[np.ndarray]:
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
coordList = path2DToPathList(shapelyPaths)
From here you create a Hatcher object (or sub-class) and use the hatching functionality directly.
myHatcher = hatching.Hatcher()
layer = myHatcher.hatch(coordList)
That actually works so far. Thanks a lot!
But now i'm actually struggling with interpreting the result of this hatching.
The resulting Layer has LaserGeometry objects. I have a very basic shape (rectangle with circular/rect hole).
Depending on parameters for the hatcher:
myHatcher.numInnerContours = 0
myHatcher.numOuterContours = 1
myHatcher.hatchSortMethod = hatching.AlternateSort()
i get some HatchGeometry and some ContourGeometry via getGeometry()
When setting the parameters for contours to zero, the hole is ignored completly. When setting inner or outer contours to 1, i get a ContourGeometry, which kind of has the holes in it, but i don't really know how to interpret these, because they are just arrays of x,y coordinates.
I doing something along these lines in my FreeCAD-Macro, where Draft.make_wire does what you would think. With two coordinates it generates a line.
poly = Polygon(outerpoly, holes=inner_polys)
coordList = path2DToPathList([poly])
layer = myHatcher.hatch(coordList)
for geom in layer.getGeometry():
if geom.type() == LayerGeometryType.Hatch:
hatches = np.vstack([geom.coords.reshape(-1, 2, 2)])
for line in hatches:
p0 = line[0]
p1 = line[1]
wire = Draft.make_wire([App.Vector(p0[0], p0[1],0), App.Vector(p1[0],p1[1],0)], closed=False, face=False)
elif geom.type() == LayerGeometryType.Polygon:
wire = Draft.make_wire([ App.Vector(x,y,0) for (x,y) in geom.coords], closed=True, face=False)
else:
print("Unhandled Geometry")
It looks to me, that the Hatcher does not actually clip the hatching lines. From looking at the code i cannot figure out, what makes the difference, since all examples e.g. from the blog obviously have holes and the hatching works. I attached some figures to show the result i get in FreeCAD.
The model with some rect as hole. The green highlighted lines are the result from the hatching process. The code is basically from above.
Here is another interesting detail of the hole
The Shapely Polygon extracted from the FreeCAD Selection is correct as plotted with matplot:
With some contours the clipping works, somewhat....
There is something i'm missing i guess. Could you give a hint?
Sorry, but the problem is probably not with the hatching code from PySLM but somewhere in my code. With certain geometries everything looks actually quite nice.
The tool path is projected to the XY-Plane for now. Therefore is looks a bit off.
I think i need to dig a bit further.
That looks a nice result already within FreeCAD and integrating it with PySLM.
Likely, you have to be careful with the projection of coordinates into the OpenCascade wire (path) structure used in FreeCAD and ensure that they full connected and in the correct orientation (winding order, for the contour paths. If in doubt, extract the polygons, hatch and plot with pyslm.visualise.plotPolygon
, or pyslm.visualise.plot()
The default Hatcher assumes that there is one offset for the outer contour, but this behavior can be changed in the future, if there are occurance of issues.
Let me know if you find any further issues.
No further questions, so marked as resolved.