[Feature Request] Sketch - Identify Geometry Index (inside and outside Edit Mode)

Need help, or want to share a macro? Post here!
paullee
Posts: 1842
Joined: Wed May 04, 2016 3:58 pm

[Feature Request] Sketch - Identify Geometry Index (inside and outside Edit Mode)

Postby paullee » Fri Mar 02, 2018 12:15 am

Hi, I remember there was a similar post but no one provide a feedback and I can't find it at the moment.

Problem is:-

Gui.SelectionEx()[0].SubElementNames would provide different Edges 'name' Inside and Outside Sketch Edit mode
See screencaptures
  1. Say a rectangle inside sketch, Edges index report are, Anti-Clockwise, 1-2-3-4 [EDIT] ('1' being the edge at the 'bottom')
  2. Edge 2 is construction
  3. Exiting Edit mode, same code seem report the Wire edge number created, INSTEAD of the Geometry inside edit mode
  4. So, only 3 edges form a wire Outside edit mode
  5. Edges nos. BECOME (report here as it is in same direction) 1-(none)-3-2 [EDIT] 3-none-1-2 (same edge by edge)
  6. Or ClockWire as 1-2-3 [EDIT] Top Edge is '1' now
  7. Using the latter 'index' in sketch.geometry[index] would report wrong edge (following Geometry Index) information
So, Solution I haven't found:-
  • Outside Edit Mode, how can I without enter edit mode, a script to identify the selected edge's (the wire shape I guess) internal Edge geometry Index?
Thanks for any hints.
Screenshot from 2018-03-02 07-42-21.png
Screenshot from 2018-03-02 07-42-21.png (166.35 KiB) Viewed 1827 times
Screenshot from 2018-03-02 07-48-24.png
Screenshot from 2018-03-02 07-48-24.png (180.81 KiB) Viewed 1827 times
Screenshot from 2018-03-02 07-49-25.png
Screenshot from 2018-03-02 07-49-25.png (144.17 KiB) Viewed 1827 times
Screenshot from 2018-03-02 07-51-20.png
Screenshot from 2018-03-02 07-51-20.png (131.98 KiB) Viewed 1827 times
Attachments
Test_ Sketch_ Identify Geometry Index.fcstd
(3.33 KiB) Downloaded 12 times
Last edited by paullee on Wed Mar 14, 2018 7:04 pm, edited 2 times in total.
User avatar
Joel_graff
Posts: 1584
Joined: Fri Apr 28, 2017 4:23 pm
Contact:

Re: Sketch - Identify Geometry Index (inside and outside Edit Mode)

Postby Joel_graff » Fri Mar 02, 2018 3:14 am

I haven't tried manipulating sketches outside of edit mode, and i know that the fact that construction geometry is absent changes the selection mechanism because of the separation between the coin geometry and the sketch GUI representations. @wmayer, I think, would be the person who might provide some insight.
Last edited by Joel_graff on Fri Mar 02, 2018 3:29 am, edited 3 times in total.
FreeCAD Trails workbench for transportation engineering: https://www.github.com/joelgraff/freecad.trails

pivy_trackers 2D coin3D library: https://www.github.com/joelgraff/pivy_trackers
User avatar
Joel_graff
Posts: 1584
Joined: Fri Apr 28, 2017 4:23 pm
Contact:

Re: Sketch - Identify Geometry Index (inside and outside Edit Mode)

Postby Joel_graff » Fri Mar 02, 2018 3:20 am

As a followup, here's the link to the thread I posted about this a few weeks back:

https://forum.freecadweb.org/viewtopic. ... es#p211551
FreeCAD Trails workbench for transportation engineering: https://www.github.com/joelgraff/freecad.trails

pivy_trackers 2D coin3D library: https://www.github.com/joelgraff/pivy_trackers
paullee
Posts: 1842
Joined: Wed May 04, 2016 3:58 pm

Re: Sketch - Identify Geometry Index (inside and outside Edit Mode)

Postby paullee » Fri Mar 02, 2018 9:47 am

Joel_graff wrote:
Fri Mar 02, 2018 3:20 am
As a followup, here's the link to the thread I posted about this a few weeks back:

https://forum.freecadweb.org/viewtopic. ... es#p211551
Thanks! I miss this thread, I think you should have another post related.

Anyway, if (so far) there is no way to identify the edge selected (shape) outside Edit Mode in the Edit Mode, then need to let the user to enter in edit mode to do the selection...

Wonder any similar code example done that?

BTW, there is a section explaining Identifying the numbering of the vertices of a line for sketch hidden in wiki on Constraint PointOnPoint https://www.freecadweb.org/wiki/Constraint_PointOnPoint - spent lot of time kind of 'reverse-engineer' the edge index with sketch.geometry, .subelements... .subobject etc.....!
User avatar
Joel_graff
Posts: 1584
Joined: Fri Apr 28, 2017 4:23 pm
Contact:

Re: Sketch - Identify Geometry Index (inside and outside Edit Mode)

Postby Joel_graff » Fri Mar 02, 2018 10:50 am

paullee wrote:
Fri Mar 02, 2018 9:47 am
Anyway, if (so far) there is no way to identify the edge selected (shape) outside Edit Mode in the Edit Mode, then need to let the user to enter in edit mode to do the selection...
Yeah, I wrote that functionality into my workbench, but if all you're doing is entering edit mode just to get references to selected geometry, it's definitely undesirable...

Regarding your original post:
paullee wrote:
Fri Mar 02, 2018 12:15 am
Edges nos. BECOME (report here as it is in same direction) 1-(none)-3-2.
Or ClockWire as 1-2-3
So what appears to be happening is elements at the end of the list appear to be getting reordered to fill in the spots for the "missing" construction geometry higher up. I don't know if that's consistently how it works, but even if it does, trying to anticipate that reordering would be prohibitively difficult.

I have one idea that should work, but it's not pretty.

The SelectionObject.PickedPoints attribute returns a vector list of selected vertices. If you have no vertices selected, but only edges, then PickedPoints returns a point on that selected edge (how it's computed, I'm not sure). You *could* iterate through the geometry list and compute the equation of the line for each Part.LineSegment, then test to see if the PickedPoints vector falls on that line. If so, then that's your selection.

The same is true for arcs. The solution is a bit more involved, though, as it would mean doing two things: First, calculate the arc paramter() value using the PickedPoints vector, then check to ensure it falls between the arc's FirstParameter and LastParameter attributes. Second, compute the distance between the PickedPoints vector and the arc's center, and test to see if it matches the radius. If both conditions are met, that's your selection. Note that floating point error applies, here - your tests for equality will have to allow for a small tolerance.

It's a really ugly, brute-force solution, but that's the only way i can see how you could correlate the Shape geometry with the underlying Coin3D geometry outside edit mode.

Also, I've developed my own Python classes to handle stuff like this. It's a bit complicated, but in the end, it makes the problem much easier to manage. I'm not doing what you're doing, but I know what I've written would adapt well to solving this problem. If you're interested, I can post something later about that. Otherwise, you'll have to auto-enter Edit mode and manage selection that way.

I might also suggest putting in a feature request with the devs for a more consistent coupling between the Coin3D geometry and the Shape geometry so we can more reliably correlate selections in Sketcher. I don't know if it's a reasonable thing to ask for, but it can't hurt to try. :)
FreeCAD Trails workbench for transportation engineering: https://www.github.com/joelgraff/freecad.trails

pivy_trackers 2D coin3D library: https://www.github.com/joelgraff/pivy_trackers
paullee
Posts: 1842
Joined: Wed May 04, 2016 3:58 pm

Re: Sketch - Identify Geometry Index (inside and outside Edit Mode)

Postby paullee » Fri Mar 02, 2018 11:51 pm

Joel_graff wrote:
Fri Mar 02, 2018 10:50 am
...
The SelectionObject.PickedPoints attribute returns a vector list of selected vertices. If you have no vertices selected, but only edges, then PickedPoints returns a point on that selected edge (how it's computed, I'm not sure). You *could* iterate through the geometry list and compute the equation of the line for each Part.LineSegment, then test to see if the PickedPoints vector falls on that line. If so, then that's your selection...
...

Also, I've developed my own Python classes to handle stuff like this. It's a bit complicated, but in the end, it makes the problem much easier to manage. I'm not doing what you're doing, but I know what I've written would adapt well to solving this problem. If you're interested, I can post something later about that. Otherwise, you'll have to auto-enter Edit mode and manage selection that way.

I might also suggest putting in a feature request with the devs for a more consistent coupling between the Coin3D geometry and the Shape geometry so we can more reliably correlate selections in Sketcher. I don't know if it's a reasonable thing to ask for, but it can't hurt to try. :)
Thanks for the detailed information about this matter!

Just begin 'studying' python, and not found PickedPoints, FirstParameter attributes usage in my 'trial and errors' experiment of the sketch object! :) So if you don't mind sharing so there is more reference to learn! Yes I believe the concept to compare the geometry between the selected edge with the internal geometry should work!

Though I guess sketcher developer should be able to easily provide a method if there is a feature request: I have another test and my guess how sketcher vs resultant shape/Wire works below ... [btw, some of my information last time is found incorrect (or 'topologically' renamed upon reopening of the same file?) ]
  • My guess is the geometries/edges within a sketch are analysed: any individual or connect 'internal edges' are turned into a shape/Wire; a Wire (of multi-edges) is constructed by its 1st edge (edge 1 in 'external shape/Wire'), then find the next consecutive geometry with a matching end point (edge 2 in 'external shape/Wire'), if none is consecutive just another edge then try to find any consecutive edge with matching endpoint.
  • Then a Wire with multiple edge outside Edit Mode would have consecutive 'edge index' for consecutive edges (rather it is the 'definition' of a Wire so Sketcher needs to follow in anther words). So in the attached files, 2 sets of Wire have consecutive edges with consecutive 'edge index'.
  • So, it sound easy that the original algorithm should be able to 'remember' which 'internal edge' is mapped to which 'external Wire edge' - at least that's my hope so a method to tell should be easy :)
Information corrected
  1. Say a rectangle inside sketch, Edges index report are, Anti-Clockwise, 1-2-3-4 [EDIT] ('1' being the edge at the 'bottom')
  2. Edge 2 is construction
  3. Exiting Edit mode, same code seem report the Wire edge number created, INSTEAD of the Geometry inside edit mode
  4. So, only 3 edges form a wire Outside edit mode
  5. Edges nos. BECOME (report here as it is in same direction) 1-(none)-3-2 [EDIT] 3-none-1-2 (same edge by edge)
  6. Or ClockWire as 1-2-3 [EDIT] Top Edge is '1' now
(I am not sure if the 'external' edge index will survive upon recompute - seem yes after a few trial)
User avatar
Joel_graff
Posts: 1584
Joined: Fri Apr 28, 2017 4:23 pm
Contact:

Re: Sketch - Identify Geometry Index (inside and outside Edit Mode)

Postby Joel_graff » Sat Mar 03, 2018 2:11 am

paullee wrote:
Fri Mar 02, 2018 11:51 pm
Thanks for the detailed information about this matter!
You may be right about what's going on behind the scenes - I really don't know, but it makes some sense.

As for the code, see attached for the files. I've also included a link to my github repo which shows how I've used them in my workbench.

The important class is the SketchElement class. It stores a reference to the actual Sketcher geometry, along with a reference to the containing sketch and the geometry index. I added several static members to the class that can be called without first instancing an object. Those methods are deisnged to find geometry / constraints that are attached to another piece of geometry.

I also created two subclasses which inherit from SketchElement: SketchGeometry and SketchConstraint. They provide convenience functions that are specific to geometry and constraints and also make use of the static functions.

For example:

Code: Select all

import SketchElement as skel

def createSketchGeometry (geo_index):

	#create a SketchGeometry based on an existing line segment
	var my_line = skel.SketchGeometry(App.ActiveDocument.Sketch, geo_index)

	#access the original geometry
	print (str(my_line.element))

	#access the geometry index
	print (str(my_line.index))

	#access the class type
	print (str(my_line.type))

Finally, I added line and curve classes which provide mathematical functions that allow for more complex operations (like computing the intersection between two lines):

Code: Select all

import GeometryObjects as GeoObj

def getIntersection (line_segment_1, line_segment_2):

	#get mathematical models of existing Part.LineSegment objects
	line_1 = GeoObj.Line2d.from_line_segment(line_segment_1)
	line_2 = GeoObj.Line2d.from_line_segment(line_segment_2)
	
	#return the App.Vector representing the point of intersection
	return line_1.interesection(line_2)

Then, I extended the SketchElement classes to use the Line2d / Arc2d classes directly.

Code: Select all

import SketchElement as skel

def getSketchGeoIntersection (sketch_geo_1, sketch_geo_2):

	#return the intersection of two lines as an App.Vector
	return sketch_geo_1.as_line2d().intersection(sketch_geo_2.as_line2d())

You can modify the SketchElement, SketchGeometry, and Line2d / Arc2d classes to provide additional functionality for the testing you're doing.

Anyway, this is new code I've written in the last week. I use these classes everywhere I need to access Part objects - in other words, I don't ever use Part objects directly - they're always encapsulated in a SketchElement class. It makes it much easier knowing that at any time I can access the geometry, it's index, and whatever convenience functions I may need directly through the SketchElement class.

I've pushed it to my repo (currently in the 'sketch_curve_generator' branch, so you can view how I've used it in my code here:

https://github.com/joelgraff/freecad-transportation-wb

Take a look at it and let me know if you have questions. I can certainly help with the implementation.
GeometryUtilities.py
(6.04 KiB) Downloaded 17 times
GeometryObjects.py
(6.3 KiB) Downloaded 20 times
SketchElement.py
(8.07 KiB) Downloaded 16 times
FreeCAD Trails workbench for transportation engineering: https://www.github.com/joelgraff/freecad.trails

pivy_trackers 2D coin3D library: https://www.github.com/joelgraff/pivy_trackers
paullee
Posts: 1842
Joined: Wed May 04, 2016 3:58 pm

Re: Sketch - Identify Geometry Index (inside and outside Edit Mode)

Postby paullee » Sat Mar 03, 2018 7:45 am

Joel_graff wrote:
Sat Mar 03, 2018 2:11 am

The important class is the SketchElement class. It stores a reference to the actual Sketcher geometry, along with a reference to the containing sketch and the geometry index. I added several static members to the class that can be called without first instancing an object. Those methods are deisnged to find geometry / constraints that are attached to another piece of geometry.
That might need me a few weeks to read through and hopefully understand !!! Thanks! (I just start to learn what is a class and sub-class in Python - I am not a programmer! )

BTW, I start to realise the discussion you and Microelly in Civil engineering feature implementation (Transportation Engineering) would be useful in Arch also!
User avatar
Joel_graff
Posts: 1584
Joined: Fri Apr 28, 2017 4:23 pm
Contact:

Re: Sketch - Identify Geometry Index (inside and outside Edit Mode)

Postby Joel_graff » Sat Mar 03, 2018 12:33 pm

paullee wrote:
Sat Mar 03, 2018 7:45 am
That might need me a few weeks to read through and hopefully understand !!! Thanks! (I just start to learn what is a class and sub-class in Python - I am not a programmer! )
I'm not much of a Python programmer - mostly C++. So my implementation may be rough around the edges. It's certainly more complex than needed to solve your problem...

To start, I'd just look at the Line2d and Arc2d classes in GeometryObjects. That's where the code that you really need is. You can use those classes and just forget about the SketchElement classes. I gave an example of that in my last post in the second code snippet.

I think most of the functions you need to do your work are already there in the Line2d / Arc2d classes. Anyway, if you get stuck or have questions, let me know. What you're trying to do doesn't seem particularly difficult to implement.
paullee wrote:
Sat Mar 03, 2018 7:45 am
BTW, I start to realise the discussion you and Microelly in Civil engineering feature implementation (Transportation Engineering) would be useful in Arch also!
I'm curious to know what purposes that work might serve in Arch...
FreeCAD Trails workbench for transportation engineering: https://www.github.com/joelgraff/freecad.trails

pivy_trackers 2D coin3D library: https://www.github.com/joelgraff/pivy_trackers
paullee
Posts: 1842
Joined: Wed May 04, 2016 3:58 pm

Re: Sketch - Identify Geometry Index (inside and outside Edit Mode)

Postby paullee » Thu Mar 08, 2018 1:18 pm

Joel_graff wrote:
Sat Mar 03, 2018 12:33 pm

I'm curious to know what purposes that work might serve in Arch...
Busy digging into Python lessonsssss....

Added a post in Civil engineering feature implementation (Transportation Engineering) - attempt to build some Site Context with Street and Roads!!!

Also had long time ago a building project needs to have a vehicular bridge!

Hope there will be more handy tool for these usages!