Realthunder recently posted a potential solution
for the Topological Naming problem. It is very impressive and, in my opinion, shows a lot of potential. I have posted previously a a potential solution (mostly a proof of concept) in python
(though upon further inspection, there are some bugs in that code that I should fix...), as well as an approach (attempting to) utilizing OCC's built-in TNaming functionality
This post is to showcase a c++ implementation (and improvement) of the python topo namer that I linked above. without further ado, here's a (very crude) gif showing it in action!
And here's a (equally crude) gif showing the current FreeCAD behaviour:
(If anyone can tell me how to resize these on the forum I can make them a bit smaller)
I'm very excited to show this! I originally wanted to also post a gif of the current behaviour (i.e. the fillet moves when the cylinder is made shorter) but my 'vanilla' version of FreeCAD isn't done compiling yet.
(it finished) I also wanted to do a fancy screencast gif, but I wasn't able to make the screencast thing work, so I just took some screenshots and used gimp to make the gif.
Anyway, let me explain (briefly, and at a high level) how this works. I've created a library that (for now) I'm calling TopoManagers
which describes a Topological Manager interface (ISolidManager) as well as two concrete implementations of this interface: PrimitiveSolidManager and CompoundSolidManager. This line
in a test for the PrimitiveSolidManager shows how the manager can be used to obtain a "constant reference" to a topological edge. Note that this reference is a simple integer, but it is guaranteed to always return the same edge.
I have a TopoManager branch of FreeCAD
that shows these managers in action (I have not rebased against master in a week or two, please excuse my excitement to post this as soon as possible.) In particular, notice that I've added a new member variable
to Part::PropertyPartShape, as well as a getter and setter for that variable.
The use of this variable (a unique_ptr to an ISolidManager) is easiest shown in Part::Box
. You can see that we retreive the ISolidManager, then either initialize it or update it as appropriate. The update is done using a helper class "Occ::ModifiedSolid" which carries information needed to keep track of which faces have changed (or been deleted or generated).
It's that simple! You can also look at Part::Cylinder
for another (almost identical) use-case, as well as Part::Boolean
for a more complicated use-case (this one uses CompoundSolidManager).
I don't want to get too deep into the technical details of how this works on this post for two reasons: one, my wife is hungry and I need to cook dinner
And two...actually, that's the only reason. I will give a little bit of detail though.
The way this works is essentially by using <will insert link later> the method whereby each Edge is described by the two faces that make it up. As such, as long as we know how each Face changes, we can consistently refer to a given edge as "the common edge between FaceX and FaceY". It's that simple! My library simply provides facilities for (more) easily keeping track of these face changes.
I will also briefly mention that the TopoManagers library uses another small (and incomplete) library that I've named OccWrapper
. This library provides a set of wrapper classes to Opencascade, namely (currently) TopoDS_Shape and it's derived classes, as well as some helper classes. The helper classes fall in two categories: specialized Occ::Solids (Occ::Box, Occ::Cylinder, Occ::BooleanSolid) that provide facilities for (more) easily keeping track of faces. And then factory classes: Occ::SolidMaker and Occ::SolidModifier (I'm considering merging these into one).
I wrote this wrapper library because I didn't want to keep using BRep_Explorer all the time. The library is imperfect, and wasteful (it makes tons of copies of TopoDS_Shape's). I mostly wrote it to make the writing of TopoManagers easier, but I also feel that it can be improved and extended for more general use in FreeCAD. That's a separate topic though.
So, please, let me know your thoughts, comments, (constructive) critiques and anything else! I can post instructions on how to build the two libraries as well as my FreeCAD branch if anyone is interested.