CadQuery / CadQuery/cadquery

Get wire/edge position by absolute distance. (Convert Face to GeoJson)

Open
#855 2 comments 0 reactions 0 assignees View on GitHub
question
Dominant language
Python
Stars
5.8k
Forks
541
Avg merge
3d 2h
Merged PRs (30d)
5

Description

I found that if I export faces to dxf, the end points wouldn't be conneted.
Such like following :
![image](https://user-images.githubusercontent.com/65506932/130372677-b802d414-f527-4804-bbbd-f42d47c9d198.png)

So I try to convert the face element to GeoJson.
```PYTHON
import shapely
from shapely.geometry import *

import cadquery as cq
from cadquery.selectors import*

def wire_to_Polygon(wire, interval_distance):
wire_length = wire.Length()
if interval_distance<10e-6:
interval_distance=10e-6
elif interval_distance > wire_length/100:
interval_distance = wire_length/100
div = wire_length/interval_distance
linspace = [ i/div for i in range(int(div))]+[1]
vector_list = wire.positions(linspace,mode='length')
linestring = LineString([ (vector.x,vector.y) for vector in vector_list])
linestring_boundarys = linestring.buffer(interval_distance).buffer(-1*interval_distance*(0.99)).boundary
if isinstance( linestring_boundarys,type(LineString()) ):
if interval_distance == 10e-6:
print('In wire_to_Polygon : Have the aspect ratio is too large. '+'Change interval_distance = '+str(interval_distance))
linestring = linestring_boundarys
else:
print('In wire_to_Polygon : Have the aspect ratio is too large. '+'Change interval_distance = '+str(interval_distance/2))
linestring = wire_to_Polygon(wire, interval_distance/2).boundary
else:
linestring = linestring_boundarys[0]
return Polygon(linestring)

def face_to_polygon(face, interval_distance):
# Only read X and Y coordinate.
outerWire = face.outerWire()
innerWires = face.innerWires()
polygon = Polygon(wire_to_Polygon(outerWire, interval_distance))
for innerWire in innerWires:
polygon = polygon.difference(wire_to_Polygon(innerWire, interval_distance))
return polygon

def cut_section_to_geojson(result, Plane, interval_distance):
result_plane = cq.Workplane(Plane)
result_plane.objects = result.vals()
result_section = result_plane.section()
section_faces = [result_section.plane.toLocalCoords(face_) for object_ in result_section.objects for face_ in object_.Faces()]
polygons = [ face_to_polygon(face,interval_distance) for face in section_faces]
return polygons
```
But I have a problem about the function `wire.positions()`. It use `wire.paramAt()` to get parameter value, and the `param d` in `wire.paramAt()` is normalized distance `[0, 1]` not absolute distance.
I think it should add absolute distance to get position. Like this:
```python
Mixin1D.positions([0, 0.2, 0.9, 1.2], mode = "absolute distance")
```
Besides this, you can try my function to get the closed and connected polygon with GeoJson.
```python
result0 = cq.Workplane("XY")
result0 = result0.moveTo(3,4).circle(1).extrude(10,both=True)
result0 = result0.spline([(0,0),(1,0),(1,1),(0,1)]).close().extrude(1,both=True).translate((-3,-4,0))
result0 = result0.moveTo(4,3).circle(1).extrude(1,both=True)
result0 = result0.union( cq.Workplane("XY").
spline([(0,0),(-1,0),(-0.1,-0.5),(-1,-1),(0,-1)]).
close().
extrude(1,both=True).
translate((3,-4,0.5)).
rotate((0,0,0),(1,0,0),(5))
)
result0.plane = cq.Plane(origin=(0,0.1,0.5), normal=(0.05,0.05,1))
#result0 = result0.section()

polygons = cut_section_to_geojson(result0,result0.plane,0.1)
MultiPolygon(polygons)
```
![image](https://user-images.githubusercontent.com/65506932/130372926-13e58356-e1b4-4c86-a905-725b9a29eb34.png)

And it would be easy to use ezdxf to convet GeoJson to dxf.

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.