Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The referenced faces problem #98

Open
dzervas opened this issue Jun 7, 2024 · 2 comments
Open

The referenced faces problem #98

dzervas opened this issue Jun 7, 2024 · 2 comments
Labels
b-rep kernel help wanted Extra attention is needed

Comments

@dzervas
Copy link
Collaborator

dzervas commented Jun 7, 2024

This is a discussion about how to solve the "referenced faces problem", both for 2D and 3D faces. 2D faces are enclosed, "colored" areas of a sketch that one can extrude, 3D faces are the flat surfaces that 3D objects are comprised of (a 3D cube has 6 faces).

The problem is simple: How do you refer to a selected face, e.g. during an extrusion?

Just ID

This is the simplest solution and what we've done till now, but it has a huge deal breaker: we're calculating faces and they're not static.

This simplest way to break this is approach is to create a sketch with 2 rectangles that share a line, do an extrusion on the second rectangle and then edit the sketch and remove the shared line. Now there's only 1 face and the face ID 2 does not exist

Centroid anchor

A very interesting idea @MattFerraro introduced with the document is to use anchors to refer to faces.

Every time a face is generated its centroid is also calculated and thus during extrusion the face centroid is referenced, not the face or its ID

After a sketch edit the face with centroid closest to the saved centroid is selected.

This approach though is also problematic:

  • There's no way to "fail". For example if a sketch defines 3 faces and 3 extrusions are done and then edited to have only 1 extrusion all 3 extrusions will extrude the same face without producing any errors or warnings (as the closest centroid will be the single centroid of the new single face)
  • Co-eccentricity introduces uncertainty. Since the centroid of 2 co-eccentric polygons is the same, the selection of the face is only based on the order of face generation
  • Movement introduces uncertainty. If we have 2 rectangles that have the same size, select 1 of the two, extrude and then edit the sketch to move the selected rectangle more enough (more than width/2 for example) the other rectangle will now be selected

Some possible fixes for the second problem is:

  • More robust face generation ordering - e.g. from the center to edge or vice versa and the introduction of an "index" along with the centroid so that a faces with the same centroid can be "favored" depending on that index
  • Inclusion of the area along with the centroid so the face with the closest area can be used

About the failing problem I can't think of a good enough solution. Maybe we can store the amount of "independant" (they share no features) faces and if that drops we fail?
Do we just throw a warning when more than 1 extrusion with different centroids end up referring to the same face?


I think the correct approach is to introduce some kind of hashing to the faces that is able to produce a "hash distance" or "not found". the face with the closest hash distance (if any) is selected.

But what do we include the hash and how do we hash it so that a "distance" can be found?

@dzervas dzervas added help wanted Extra attention is needed b-rep kernel labels Jun 7, 2024
@dzervas dzervas mentioned this issue Jun 7, 2024
@dumblob
Copy link

dumblob commented Jun 12, 2024

Just a bit crazy brainstroming here.

What if we saw the whole problem even more holistically than just focusing on the one operation right after the one which creates this "ref. faces problem"?

What if we somehow "split" the part into two (conceptually something like booleans but kind of "generalized") right at that point and try to "visually" preserve the "concept" (intent) the user has done. The AI hype all around can give you a sense of what the "visual concept" (intent, essence) might mean. Note, I would not want to use any kind of AI (even if it would be just its purest form - i.e. fuzzy logic) but it can help us develop a holistic answer to the "reference faces problem".

E.g. let us have a cube 3x3x3 [op1]. On one face we will draw a circle and subtract its 360deg rotation from the cube [op2]. Then we will select the half-cylindric face and somewhere close to its centroid we will create a touching sketch with a triangle [op3] which we will extrude outwards from the cube [op4].

Then we will change op2 to "draw and rotate a triange forming a cone which we will add to the cube" [op2b].

My proposal would be then to separate visually the whole initial creation right at the place where the change started. That means we take the status after op2 and then subtract it from state at op4 resulting in a temporary shape [tmp1]. This difference [dif1] will then be the guidance for the intent. Then we will just take op1, apply op2b and then try to find a way how to apply op3, etc. to mimic tmp1 (i.e. the original "look & feel"). In this case we can take a look at tmp1 center of gravity, tmp1 vector along its longest dimension, tmp1 "rotation" relative to the shape after op1, we can try to translate tmp1 a little bit for validation of different options (sounds like another gradient descent algo...), IDK, just try to fit it in somehow 😃.

Yeah, it is on the verge of dreaming. But why not to dream at this stage 🤣

@gabrielgrant
Copy link

IIUC what is being discussed here is the notorious "topological naming problem" - identifying geometric features in a consistent way that persists as the operations that created that geometry are modified. As has been mentioned, there is no strictly 100% correct solution to these problems, just a variety of heuristics, some far better, and some (like just using static IDs) more fragile.

The "topo naming problem" has plagued FreeCAD since its inception, and is often cited as the Number One reason FreeCAD can't compete with commercial CAD packages, and is the reason probably half the FreeCAD community uses a 3rd party fork -- a development branch maintained by a single author (RealThunder) -- rather than the FreeCAD project's official releases.

Finally, after many years of discussion and development, there are finally some big changes slated to arrive in the upcoming FreeCAD v0.22 that should largely mitigate the problem. The main steps of the project are largely complete. But there are still a bunch of issues related to it that will likely not be fully fixed for quite a while yet

All that to say, this is a difficult problem to get right, but, because it is so central to the models' internal representation, it is incredibly painful to get wrong. I'm really hopeful about the potential of what you are building here, so really hope CADmium can learn from FreeCAD's mistakes to figure out this issue early on.

In particular, it seems worth reading through/understanding the description of the new algorithm being incorporated (and that has been tested and refined for several years in RealThunder's development branch): https://github.com/realthunder/FreeCAD_assembly3/wiki/Topological-Naming-Algorithm

Other resources:

Some more background about the issue in FreeCAD: https://ondsel.com/blog/freecad-topological-naming/
The master GitHub issue: FreeCAD/FreeCAD#8432

One of countless related discussions: https://www.reddit.com/r/FreeCAD/comments/vpxxcb/is_the_topological_naming_problem_unique_to/

Demo of an early version of the fix: https://www.reddit.com/r/FreeCAD/comments/1cpi0v4/i_have_it_freecad_exclusive_first_look_at_022/

Special considerations needed to be taken when modelling to avoid triggering the issues: https://wiki.freecad.org/Feature_editing#Advice_for_creating_stable_models

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
b-rep kernel help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

3 participants