fetching geometry/Toolpath for svg paths
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
Hi there,
I am struggling to find a generic script to extract the outer and inner (holes, pockets, etc) geometry from the up & down faces of my 3D models.
So, the starting point is to identify the parts of my model that are sheet-goods and identify the up & down faces, so the shortest distance between these faces determines the thickness of the part. With the faces identified, I get the face.loops and iterate them through the edges. If edges.count == 1 -> circle or ellipse. If edges.count > 1, then it's a mix between lines and arcs, and here is where I'm struggling.
the process goes: Iterate through the loops on faces, identify the coEdges and egdes and determine if the edge is isOpposedToEdge or isParamReversed plus check the edge.evaluator.getEndPoints() (start and end points) makes sense respective the previous edge: (see snippet of code below)
path = ""
start = None
end = None
c = 0
for coEdge in loop.coEdges:
reversed = False
edge = coEdge.edge
curve_type = edge.geometry.curveType
# determine if edge is reversed
isOpposedToEdge = coEdge.isOpposedToEdge
isParamReversed = coEdge.isParamReversed
(returnBool, startPoint, endPoint) = edge.evaluator.getEndPoints()
if self.getTwoD(u, v, endPoint) == end:
reversed = True
if self.getTwoD(u, v, startPoint) == start:
print('this is wrong')
start = self.getTwoD(u, v, startPoint)
end = self.getTwoD(u, v, endPoint)
if c == 0:
if coEdge.isOpposedToEdge and coEdge.isParamReversed:
path = f"M {end[0]} {end[1]} "
path += self.getLineArcPath(start, edge, face, isParamReversed, isOpposedToEdge)
else:
path = f'M {start[0]} {start[1]} '
path += self.getLineArcPath(end, edge, face, isParamReversed, isOpposedToEdge)
c += 1
print(path)
else:
if coEdge.isOpposedToEdge and coEdge.isParamReversed or reversed:
path += self.getLineArcPath(start, edge, face, isParamReversed, isOpposedToEdge)
start,end = end,start
else:
path += self.getLineArcPath(end, edge, face, isParamReversed, isOpposedToEdge)
c += 1
path += "Z"
identify if edge is either Line or Arc:
def getLineArcPath(self, end, edge, face, isParamReversed, isOpposedToEdge):
curve_type = edge.geometry.curveType
# line segment:
if curve_type == 0:
path = f"L {end[0]} {end[1]} "
print(path)
# arc:
elif curve_type == 1:
face_normal = face.geometry.normal
arc_normal = edge.geometry.normal
opp_or_equal = self.check_vectors(face_normal,arc_normal)
arc = edge.geometry
rx = str(arc.radius)
ry = str(arc.radius)
rotation = "0"
large_arc_flag = "0"
sweep_flag = "0"
angle = abs(arc.endAngle - arc.startAngle)
if angle >= 3.141592653589793 :
large_arc_flag = "1"
if isParamReversed == True and isOpposedToEdge == True and opp_or_equal == 'opposite':
sweep_flag = "1"
if isParamReversed == False and isOpposedToEdge == False and opp_or_equal == 'equal':
sweep_flag = "1"
x = str(end[0])
y = str(end[1])
path =f"A {rx} {ry} {rotation} {large_arc_flag} {sweep_flag} {x} {y} "
print(path)
return path
To determine the sweep_flag and the large_arc_flag of the arcs, I use this function:
def check_vectors(self,face_normal,arc_normal):
"""Checks face normal vector and arc normal vector angle.
They can be opposites or parallels.
Args:
face_normal ([3D vector]): fusion builtin type
arc_normal ([3D vector]): fusion builtin type
Returns:
[string]: whether are equal or opposites
"""
if arc_normal.angleTo(face_normal) == math.pi:
# print('opposite')
return 'opposite'
elif arc_normal.angleTo(face_normal) == 0:
# print('equal')
return 'equal'
else:
return 'error'
This works fine for some models, but for some others won't and I'm not sure why..
(some examples attached in this post. Same code used in both cases, but geometry is wrong on the table file for some arcs.)
The main questions are regarding how to make sure the arcs are defined properly and also which property should I use to check if segment is reversed and so flip them accordingly. But if someone knows how to get a consistent geometry loops, then I would really appreciate it!
Thank you!