I’ll take a look at your example of the “pillow thingy”. Regarding this last example, I see two seam edges (one from a cylindrical surface, one from a toroidal surface). As explained in my last post, I’m simply ignoring seam edges in my TopoManager for now, but to add support would be trivial. It begs the question though: for what reason would you need a constant reference for a seam edge? Are there any geometric manipulations you could perform on a seam edge? My understanding was that seam edges were used solely for the construction of the solid’s topology, and as such I decided not to concern myself with them.
Other than the seam edges, I see two other edges. These are at the intersection of the cylindrical surface and the toroidal surface, and as such should work well with my algorithm.
Edit:
Took a look at the pillow thing. It seems there is an axis through the center, I guess this was somehow made as revolved surface? I tried performing a boolean union on the two surfaces (since the top and bottom were two separate surface in the file) and received an error that they could not create a solid. As such, it seems to support my earlier assumption that any case in which you have an edge that is not formed by two surfaces, it would be either a seam edge or an invalid solid.
In fact, based on my research regarding BRep and the data models used to represent solids as BRep, each edge must necessarily have precisely two faces associated with it in order to be a valid, two-manifold solid. You can read a bit more on winged edge representation at this link. This is a common data structure used in BRep.
I remember having to select a seam edge’s vertex to attach a datum plane on a cylinder, might have been a cone (using Part Attachment). Sorry I don’t recall exactly what attachment mode I used, nor why…
Ah hah, now the lightbulb has gone off. This would indeed pose a problem, and it is something I will have to put some more thought into. I’ll have to consider, likely, how these solids are made: in other words, for this example, is it only possible to make this solid via revolving a 2d sketch? If so, this may give us sufficient information to distinguish the two edges from each other.
I’m familiar with the ‘Shapebuilder’ concept in opencascade (in passing), but not within freecad. I am much obliged to you for having created the solid for me. That being said, given the lightbulb moment you gave me earlier, I can see how this solid would also pose the same issue. Again, it’s something I’d have to put more thought into, and again, I’m wondering if the manner in which the solid is created may not give us enough additional information to distinguish the various edges.
How was this solid created? I get that you eventually "Shapebuilder"d two surfaces together. But where did the two surfaces come from?
On task panel, click “Add edges”, then select the edges that make up the square sketch, one by one. They should appear in the list on task panel.
On task panel, expand “Vertexes” tab, and pick a vertex from another sketch.
Accept task dialog, now you have one of the faces.
Repeat 2-5 to make the second face.
Go to Part → Shapebuilder.
…Make a shell from the two faces.
…Make a solid from the shell. Done.
It’s not parametric, because shapebuilder is not parametric. Hopefully, shapebuilder will be made parametric some day, a lot of people are waiting for it.
You rock! Based on your description, as well as the following tool-tip description from the Surface workbench – “Fills a series of boundary curves, constraint curves and vertexes with a surface” – I think that this case can also be handled with, perhaps, a “ParametricSurfaceSolidManager” or some such.
What I mean by this is that this surface has been explicitly defined and constructed by the user. As such, its definition inherently includes the edges in question. When these two surfaces are used to create a solid (via, say, MakeSolidFromParametricSurfaces or some such) we can be sure that the parameters to this factory method contain enough information to uniquely identify these edges.
What I mean by that is that I’d probably add another helper class to my OccWrapper library (similar to BooleanSolid). I could call this helper class ParametricSurfaceSolid, and this can be used as the parameters for the MakeSolidFromParametricSurfaces factory method.
Hrm, hopefully that’s not too technical. Or too abstract. Suffice to say, I feel pretty good that we can figure out a way to handle this.
There is one use case of which I know which uses the seam: Helix-Controlled thread tend to fail if the align with the seam. So we like turn it a few degrees against it. As this is usually done on th ePlacement level it should not be a problem.
If FreeCAD is able to handle everything but the seams it would be already a giant’s leap forward. If a fallback solution for seams exists, e.g. they behave like they do now, even better.
I have seen some videos about the big boys CAD systems and they can’t handle every possible problem either.
You have a remarkable combination of FC knowledge and brain capability. But what I really admire most is your ability to show counterexamples. In that you are not awesome or great, what comes after that is still to be named. DeepSOIC-ic, DeepSOIC-nic ?
Posted a brief readme on the OccWrapper repository. I hope to add more info to the TopoManager repository too, to hopefully make my code a bit easier to understand.
I had not seen those, thanks for posting. I think taking Roman’s example and expanding it (or utilizing it straight up) would probably be a good idea for a better long-term OccWrapper solution.
As it stands, a planned improvement is to do away with, say, Occ::Solid::myFaces (which is a local std::vector of all of Occ::Solid’s TopoDS_Face’s), and move the getFaces method up to Occ::Shape.
The return type of getFaces will have to change from a constant reference to a plain copied vector. The Occ::Shape::getFaces method would then utilize TopExp::Map (or w/e) to construct a new vector each time it is called and return that vector.
This would result in more processing each time getFaces is called (since we’d had to loop through each face each time to create the vector), but would also mean that any TopoDS_Face’s that are stored in a vector would essentially be transient. They’d be gone as soon as they go out of scope. This could effectively minimize the issue that Roman mentions in his blog post. That doesn’t mean that we’d want to completely ignore his suggestion, though, as what I’m proposing would merely make things “a bit better” but not really “solve” them the way that OpenCasCade has done so internally.
Ah, that’s because you need to download and compile OccWrapper and TopoManagers libraries, and then update CmakeLosts.txt to point to the right location. I can write a step by step when I’m back at my comp, sorry for the confusion.
I’ve updated the second post on this thread that gives a step-by-step on how to compile my TopoManagers branch of FreeCAD. I realize it may seem a bit convoluted, but I wanted to keep OccWrapper and TopoManagers as separate, distinct libraries from FreeCAD in order to allow me to more easily (and quickly) develop them.