[Solved] Is there a simple way to get all Vertex coords from a sketch?

Need help, or want to share a macro? Post here!
Forum rules
Be nice to others! Respect the FreeCAD code of conduct!
freedman
Veteran
Posts: 3474
Joined: Thu Mar 22, 2018 3:02 am
Location: Washington State, USA

Re: Is there a simple way to get all Vertex from a sketch?

Post by freedman »

Thank you Chris_G, that works! :) :)
I don't understand the code as yet but a quick test confirms this working. And Yes! We are in Sketch edit mode.

Hopefully this will clear a path for what seemed to be a very complicated issue.

Trying to describe what goes on here, I'm not that good in Python:

Code: Select all

for so in sel:
    for sub in so.SubElementNames:
        if "Vertex" in sub:
            n = eval(sub.lstrip('Vertex'))
            geo, pos = so.Object.getGeoVertexIndex(n-1)
            p = so.Object.getPoint(geo, pos)
It looks like we search the object for Sub element names looking for vertex, then store the vertex without attribute, I'm lost after that............
I got this from a search:

Code: Select all

…returns tuple (geoId, posId) of vertex at that index in the sketch. usage example: (geoId, posId) = App.ActiveDocument.Sketch.getGeoVertexIndex(int(Gui.Selection.getSelectionEx()[0].SubElementNames[0][6:])-1)
OK! I can see the path for this, I don't understand some of that but I do see the path. :)

I will reference this in the other posts on this topic.
This is good stuff!
edwilliams16
Veteran
Posts: 3192
Joined: Thu Sep 24, 2020 10:31 pm
Location: Hawaii
Contact:

Re: Is there a simple way to get all Vertex from a sketch?

Post by edwilliams16 »

To get the local coordinates of a vertex, you apply the inverse of the global placement to the global position. You asked for this earlier.

Code: Select all

sel = Gui.Selection.getSelectionEx()[0]
vertexName = sel.SubElementNames[0]
if vertexName[0:6] == 'Vertex':
    vIndex = int(vertexName[6:])-1
    sk = App.ActiveDocument.getObject(sel.ObjectName)
    vGlobal = sk.Shape.Vertexes[vIndex].Point
    gpl = sk.getGlobalPlacement()
    vLocal = gpl.inverse().multVec(vGlobal)
    print(f'{sel.ObjectName} {vertexName} \nGlobal: {vGlobal} \nLocal: {vLocal}')
else:
    print('Select one vertex')
    
Select a vertex and run the macro.
freedman
Veteran
Posts: 3474
Joined: Thu Mar 22, 2018 3:02 am
Location: Washington State, USA

Re: Is there a simple way to get all Vertex from a sketch?

Post by freedman »

edwilliams16, I did ask for that but I didn't like the solution :) , what you show is all calculated and will have rounding errors. I had an idea the raw data was in the object somewhere and that's what I get from what Chris_G did.

Paullee, change axis or go off axis and the data has calculated errors.

I'm still testing so I could be wrong.

Thanks all
edwilliams16
Veteran
Posts: 3192
Joined: Thu Sep 24, 2020 10:31 pm
Location: Hawaii
Contact:

Re: Is there a simple way to get all Vertex from a sketch?

Post by edwilliams16 »

I may be making some brain-dead error, but @chrisb's method doesn't work consistently for me. If I select Vertex3 ofSketch, whose global coordinates are (10, -10, 5) and local coordinates (10, -10, 0) with the following Macro:

Code: Select all

sel = Gui.Selection.getSelectionEx()[0]
vertexName = sel.SubElementNames[0]
if vertexName[0:6] == 'Vertex':
    vIndex = int(vertexName[6:])-1
    sk = App.ActiveDocument.getObject(sel.ObjectName)
    vGlobal = sk.Shape.Vertexes[vIndex].Point
    gpl = sk.getGlobalPlacement()
    vLocal = gpl.inverse().multVec(vGlobal)
    print(f'{sel.ObjectName} {vertexName} \nGlobal: {vGlobal} \nLocal (calculated): {vLocal}')
    p = sel.Object.getPoint(*sel.Object.getGeoVertexIndex(vIndex))
    print(f'Local (from object) {p}')
    print (f'Equal? {p.isEqual(vLocal, 1E-7)}')
    for i in range(4):
        geo, pos = sel.Object.getGeoVertexIndex(i)
        print(f'geo {geo} pos {pos}')
        print(f' Vertex{i+1} {sel.Object.getPoint(geo, pos)}')
else:
    print('Select one vertex')
I get the correct coordinates, chrisb's method does not. OTOH, Vertex1 and Vertex2 are correct. Vertex4 is also incorrect

Here's the result, picking Vertex3 of Sketch

Code: Select all

12:24:26  Sketch Vertex3 
Global: Vector (10.0, -10.0, 5.0) 
Local (calculated from gpl): Vector (10.0, -10.0, 0.0)
12:24:26  Local (from object) Vector (10.0, 10.0, 0.0)
12:24:26  Equal? False
12:24:26  geo 0 pos 1
12:24:26   Vertex1 Vector (-10.0, 10.0, 0.0)
12:24:26  geo 0 pos 2
12:24:26   Vertex2 Vector (10.0, 10.0, 0.0)
12:24:26  geo 1 pos 1
12:24:26   Vertex3 Vector (10.0, 10.0, 0.0)
12:24:26  geo 1 pos 2
12:24:26   Vertex4 Vector (10.0, -10.0, 0.0)
Attachments
vertexLCS.FCStd
(11.46 KiB) Downloaded 36 times
paullee
Veteran
Posts: 5135
Joined: Wed May 04, 2016 3:58 pm

Re: Is there a simple way to get all Vertex from a sketch?

Post by paullee »

Note :

The Edge or Vertex 'index' returned when Sketch is in Edit or Not will be different.

In Edit mode, the index return is exactly what you see in the edit panel ('basic Part Geometry').

Outside Edit mode, it refer to the Wires created (Part Topology)

See https://wiki.freecadweb.org/Topological_data_scripting
paullee
Veteran
Posts: 5135
Joined: Wed May 04, 2016 3:58 pm

Re: Is there a simple way to get all Vertex from a sketch?

Post by paullee »

freedman wrote: Sat Sep 11, 2021 6:29 pm Paullee, change axis or go off axis and the data has calculated errors.
Not sure I get your meaning :)

May approach is similar to @Chris_G's, just my approach use Selection Observer.

So, the coordinate return is 'local'.
edwilliams16
Veteran
Posts: 3192
Joined: Thu Sep 24, 2020 10:31 pm
Location: Hawaii
Contact:

Re: Is there a simple way to get all Vertex from a sketch?

Post by edwilliams16 »

paullee wrote: Sat Sep 11, 2021 11:18 pm Note :

The Edge or Vertex 'index' returned when Sketch is in Edit or Not will be different.
If I run my macro, I get identical results in or out of edit mode.
paullee
Veteran
Posts: 5135
Joined: Wed May 04, 2016 3:58 pm

Re: Is there a simple way to get all Vertex from a sketch?

Post by paullee »

Probably we are talking about different things :) See below 2 screencaptures-


1. In Edit Mode, the highlighted Vertex is 8
- It is about the Part Geometry
- Every straight has 2 vertexes
- It is the End Vertex of the 4th Edges, so 8

2. Outside Edit Mode, the highlighted Vertex is 5
- It is the Wire (topological shape)
- It is the last Vertex of the Wire with 4 Edges, so 5


Test_ Observer_ 2.FCStd
(6.21 KiB) Downloaded 32 times
Screenshot from 2021-09-12 11-31-07.png
Screenshot from 2021-09-12 11-31-07.png (254.66 KiB) Viewed 1886 times
Screenshot from 2021-09-12 11-31-24.png
Screenshot from 2021-09-12 11-31-24.png (258.14 KiB) Viewed 1886 times
freedman
Veteran
Posts: 3474
Joined: Thu Mar 22, 2018 3:02 am
Location: Washington State, USA

Re: Is there a simple way to get all Vertex from a sketch?

Post by freedman »

To test this there are two variables. 1) We need to be in sketch edit mode and 2) We need to attach the sketch to an off axis face.

Paullee, whenever I see the Z coord (see pic) as anything but 0.00 then I presume it's not local geometry of Sketcher X,Y,Z. When I see Z coords that are close to zero but not zero then I feel the results are global, they just appear as local because the sketch was created on the XY plane. If the sketch was created off axis then Z will be big time non-zero.
Attachments
pic33.PNG
pic33.PNG (56.05 KiB) Viewed 1835 times
Last edited by freedman on Sun Sep 12, 2021 5:10 am, edited 1 time in total.
paullee
Veteran
Posts: 5135
Joined: Wed May 04, 2016 3:58 pm

Re: Is there a simple way to get all Vertex from a sketch?

Post by paullee »

Copied the original sketch, translated and rotated it.

Now below steps:-

Code: Select all

# Select 'original' sketch
>>> s=Gui.Selection.getSelection()[0]

# Select the translated and rotated sketch
>>> ss=Gui.Selection.getSelection()[0]

# Print the (random) 3rd Geometry, 1st Vertex (StartPoint) coordinate ('local')
>>> s.Geometry[3].StartPoint
Vector (-35.999249, 36.64522212474619, 0.0)

# This is for the translated and rotated sketch
# Print the 3rd Geometry, 1st Vertex (StartPoint) coordinate ('local')
>>> ss.Geometry[3].StartPoint
Vector (-35.999249, 36.64522212474619, 0.0)
>>> 
Both return identical 'local coordinates'. May try attachment.


Test_ Observer_ 3.FCStd
(8.02 KiB) Downloaded 33 times
Screenshot from 2021-09-12 13-00-17.png
Screenshot from 2021-09-12 13-00-17.png (264.22 KiB) Viewed 1837 times
Post Reply