PR #4752 Topological Naming

Post here if you have re-based and finalised code to integrate into master, which was discussed, agreed to and tested in other forums. You can also submit your PR directly on github.
realthunder
Posts: 1960
Joined: Tue Jan 03, 2017 10:55 am

PR #4752 Topological Naming

Postby realthunder » Thu Apr 22, 2021 5:46 am

PR link: https://github.com/FreeCAD/FreeCAD/pull/4752

This is the first batch of patches for the new Topological Naming. It introduces a few new classes, and some new APIs for existing classes (mostly in ComplexGeoData, TopoShape, and various Property links with sub names). There is also some new features introduced in Base::Reader and Writer, for more efficient embedding of arbitrary binary and unicode text inside XML file, which is required for topo naming persistence. These Reader and Writer changes are also the precursor for supporting saving FreeCAD document as an uncompressed directory. I'll submit a separate PR for that later.

For an overview of new APIs (excluding TopoShape), please check out the wiki article here. These APIs are for storing, retrieving, and updating user defined text based topological names for index based geometry elements. The actual implementation is changed a bit since the article is written, but the basic idea still remains. The current implementation makes considerable effort to reuse existing topological names for speed and compact storage.

For the actual topological naming algorithm, i.e. how the text based names are generated, please check out the article here. Again, due to the aforementioned changes, the actual text of topo names is different. The algorithm largely remains the same.

There is one important factor that is not mentioned in either of the articles is the fact that the new topo naming is rather sensitive to the modeling algorithm, e.g. whether to cut first and then fuse, or the other way round. It also depends on how OCCT reports the generated and modified shapes. This means potential problems on name stability with each OCCT version and FC modeling code changes. This problem was eventually solved by using geometrical search. A new API, Part::Geometry::isSame() is added for comparing two geometries, either surface or curve, and another API TopoShape::searchSubShape() to look for an unrelated sub shape among sub shapes of a given OCC shape that has the exact same location and geometry. Before a recompute happens for any geometrical object, it will store all referenced geometry elements (i.e. sub shapes referenced by various property links), and perform a search after recompute for each missing elements (due to topo naming changes). This is based on the assumption that the changes in OCCT and FC modeling code will try best to make sure to produce the exact same shape.

The current PR only introduced the framework. No actual modeling code uses the framework yet. So there isn't much you can test. There will be at least three more follow up PRs, one for Sketcher, one for Part (i.e. make use of the framework in various Part features), and finally PartDesign. I have already prepare the branch TopoNamingSketch, and TopoNamingPart, which contain the future PR for Sketcher and Part. These two PRs can be applied independently with each other. I have made a merged branch TopoNamingSketchPart for those who want to test it before hand. All features in Part workbench should be working there.

The final PartDesign changes contains quite a few other changes in visual and modeling. I may split it further if necessary.
Try Assembly3 (latest version 0.11) along with my custom build of FreeCAD at here.
And if you'd like to show your support, you can donate through patreon, liberapay, or paypal
User avatar
Petert
Posts: 75
Joined: Tue Dec 01, 2015 9:27 pm

Re: PR #4752 Topological Naming

Postby Petert » Thu Apr 22, 2021 8:13 am

Thanks for all your hard work. I haven been using your branch exclusively for the last couple of months and can confirm that the topo problem is fixed for the most part.

Thanks once again and thanks too for all the other great stuff you implemented in your branch and thus making FC a joy to work with.
I am a refugee from Fusion 360, have been using Fusion for almost 5 years now and after the latest debacle with the licensing stuff I had enough of AutoDesk.
Switched over to FreeCAD and am spreading the word.
User avatar
yorik
Site Admin
Posts: 12222
Joined: Tue Feb 17, 2009 9:16 pm
Location: Brussels, Belgium
Contact:

Re: PR #4752 Topological Naming

Postby yorik » Thu Apr 22, 2021 9:38 am

Impressive work... Thanks also for the effort to condensate the PR into an as manageable as possible structure.
ickby
Posts: 3054
Joined: Wed Oct 05, 2011 7:36 am

Re: PR #4752 Topological Naming

Postby ickby » Thu Apr 22, 2021 10:06 am

Hello realthunder,

looks like some very good work! I looked at the changes with my personal bias towards my work on collaborative editing (see here) and have some questions / remarks. Note that I did not fully get all your changes, so my findings may be wrong.

1. The ID of document objects are used in naming now as the first real use-case. As far as I can see they are an integral part of the element mapping and hence names. The problem for me arises, that those IDs are not controllable. Hence in my effort to recreate a document fully from python I ran into trouble: I can cannot create objects with a certain ID, but some properties use those IDs to refer to this element in the new naming. Hence It breaks the recreation if e.g. the order of object creation changes.

2. It looks like the element maps of geometries are updated automatically for dependent objects. However, I did not find any code that makes this observable. I fear that it could happen that a Geometry inside e.g. PropertyComplexGeoData is changed without me noticing it. I think the "propertyChanged" should be emitted than, or maybe another document-observer call, so that I can react on this change. Actually thinking about it, a separate one makes most sense, as most likely in 99% of times the change in ElementMap will be followed up by a recompute and hence property update anyway.

Any thoughts about that?
realthunder
Posts: 1960
Joined: Tue Jan 03, 2017 10:55 am

Re: PR #4752 Topological Naming

Postby realthunder » Fri Apr 23, 2021 4:03 am

ickby wrote:
Thu Apr 22, 2021 10:06 am
1. The ID of document objects are used in naming now as the first real use-case. As far as I can see they are an integral part of the element mapping and hence names. The problem for me arises, that those IDs are not controllable. Hence in my effort to recreate a document fully from python I ran into trouble: I can cannot create objects with a certain ID, but some properties use those IDs to refer to this element in the new naming. Hence It breaks the recreation if e.g. the order of object creation changes.
When copy and paste object into another document, the object will be marked for recompute anyway, so the element map will be regenerated as well. The same principle applies to your use case. If there are objects coming from multiple documents, then it is possible to have ID conflict, hence, a recompute (of those imported objects along its dependencies) is required. For concurrent editing, I think you'll likely run into similar problem of object name conflict, if user is adding objects at the same time. How do you plan to solve that problem? We can of course extend the addObject() API to accept a user supplied ID number just like the name. So whatever your solution is, it should also be applicable to ID just the same.

2. It looks like the element maps of geometries are updated automatically for dependent objects. However, I did not find any code that makes this observable. I fear that it could happen that a Geometry inside e.g. PropertyComplexGeoData is changed without me noticing it. I think the "propertyChanged" should be emitted than, or maybe another document-observer call, so that I can react on this change. Actually thinking about it, a separate one makes most sense, as most likely in 99% of times the change in ElementMap will be followed up by a recompute and hence property update anyway.
The element map is designed to be largely 'invisible' to normal user. The new name is stored alongside the indexed based element reference in those property links in something called shadow. The tracking of element update is mostly implemented in PropertyLinks.cpp using static tables. The logic flows like this. Property link setValues() will call PropertyLinkBase::_updateElementReference() to obtain shadow names, and also register itself in a static table _ElementRefMap that maps the geometry owner object to this property link. When the geometry owner object updates, it will call static method PropertyLinkBase::updateElementReferences(), which will consult _ElementRefMap and update each property that references the relevant geometry. If there is any geometry element index changes, the property will be updated with the standard aboutToSetValue/hasSetValue() API, so the user code can catch that through the usual onChanged() interface.
Try Assembly3 (latest version 0.11) along with my custom build of FreeCAD at here.
And if you'd like to show your support, you can donate through patreon, liberapay, or paypal
ickby
Posts: 3054
Joined: Wed Oct 05, 2011 7:36 am

Re: PR #4752 Topological Naming

Postby ickby » Sat Apr 24, 2021 8:49 am

realthunder wrote:
Fri Apr 23, 2021 4:03 am
2. ... If there is any geometry element index changes, the property will be updated with the standard aboutToSetValue/hasSetValue() API, so the user code can catch that through the usual onChanged() interface.
Thats perfect and works well for me. My second point is done with this info.

realthunder wrote:
Fri Apr 23, 2021 4:03 am
When copy and paste object into another document, the object will be marked for recompute anyway...
I need to avoid recomputes. They take potentially a noticeable time, which ruins the user experience if synchronization happens in the background. Hence I rely on data load only of individual properties and prevent any recomputes.

Naming conflicts are resolved in my code as following: I have logic in place to determine who has registered a certain name first and that user is the one defining the object. If any other user creates a object with same name in almost the same time his object will be removed again, and replaced with the one that came first. He will be informed than and can simply redo his action. This is the only way to do it as objects cannot be renamed, but at least I can make it work. This does not work for ID as once the internal doc counter is increased, the user with a deleted object will create all new objects with different IDs than the other user in his document. Hence I would like to have a chance to provide an ID to "addObject".
User avatar
onekk
Posts: 788
Joined: Sat Jan 17, 2015 7:48 am
Contact:

Re: PR #4752 Topological Naming

Postby onekk » Mon Apr 26, 2021 4:40 pm

Sorry for the intrusion.

I also vote for a search by ID and a way to add ID to create object, or maybe that the ID properties coudl be searched and assigned.

but if you are merging different objects between different document, the way FreeCAD stores thing, make a recompute a "minimal requirement", how to cope with "not unique name" or other conflicts, without a "recompute", the treeview has to be updated and many other things are to be done.

Other pieces of software mantain an "internal database" that is managed with SQL queries, and could dump this database in a "human readable text file".

But the "internal naming" is always a problem, a "unique name" would involve to have a mean to generate a "unique name or ID" but what is the overload of this, an ID says of 128 digits, an UUID and even some sort of hash could not be made "duplicate proof".

Better to have a "nae consistency", If I create objectA and then I will modify it in a sort of way.

Say I'm creating a technical "drawing" of a complex part, suppose an engine made by 10.000 pieces, i want the the piston1 is named "12345678" and piston2 is named "12345679" when i modify the assembly "piston1" will always be paired with the "Hole1" in the "engine block", so if I modify the shape of "piston1" all the related parts, rod and other thing attached to "piston1" have to retain the "reference" if this will be "piston1" or "12345678" i don't care so much.

In a complex model, is my "care" to create the appropriate "connector" to place things in placement relative to others, so if "piston1" were modified I "HAVE" to take care of diameter and other things to match with the already present components, maybe it will be handy to have some indication that there are some mismatch, but I don't want to modify all the relation between part.

how such thing is achieved is not a "user problem", but have to be managed in "some way" whichever way is good provided that in a complex assembly a coherence is retained.

Other CAD/CAM gave the concept of Tag similar but not overlapping with FreeCAD "Label" property.

Suppose that this engine has to be made and that some spare parts has to be managed, "piston1" would have a "PN of 12347621a" say so if I change the "design" of the piston in the "schematic diagram" the part has the ID "12345678" that is used to "connect" to other parts in the model, but I want that those "PN" will correctly go in the "spare part list" with his "PN of 12347621a" correctly assigned.

A similar behaviour could be achieved as something have to be modified in the "naming scheme"?

Hope to have not bothered, but "topoNaming" issue is not very clear to me but above problems seems a "common" use case that maybe could be addressed during this "big modification"

Best Regards to All

Carlo D.
Introduzione a FreeCAD in Italiano: https://github.com/onekk/freecad-doc
realthunder
Posts: 1960
Joined: Tue Jan 03, 2017 10:55 am

Re: PR #4752 Topological Naming

Postby realthunder » Sun May 02, 2021 11:30 pm

onekk wrote:
Mon Apr 26, 2021 4:40 pm
but if you are merging different objects between different document, the way FreeCAD stores thing, make a recompute a "minimal requirement", how to cope with "not unique name" or other conflicts, without a "recompute", the treeview has to be updated and many other things are to be done.
FreeCAD actually takes care of this internal renaming when merging/pasting objects, which is a very complex and error prone process. It will have to modify all involved property link and expression references as well.

In a complex model, is my "care" to create the appropriate "connector" to place things in placement relative to others, so if "piston1" were modified I "HAVE" to take care of diameter and other things to match with the already present components, maybe it will be handy to have some indication that there are some mismatch, but I don't want to modify all the relation between part.

how such thing is achieved is not a "user problem", but have to be managed in "some way" whichever way is good provided that in a complex assembly a coherence is retained.


Other CAD/CAM gave the concept of Tag similar but not overlapping with FreeCAD "Label" property.
I have thought about this 'connector' problem before my work on topo naming. This is actually a 'user problem' that is beyond the scope of the topo naming problem addressed here, but the software should also provide a way for the user to manage those 'connectors'. I introduce the 'Element' concept in my Assembly3 workbench to do exactly that. You can read the description here for more details. In short, it allows user to create common interface (using the Element object label) for various interchangeable parts/sub-assemblies. See the replacing part demo here.
Try Assembly3 (latest version 0.11) along with my custom build of FreeCAD at here.
And if you'd like to show your support, you can donate through patreon, liberapay, or paypal