3D Solid Face Recognition

3D Solid Face Recognition

doaiena
Collaborator Collaborator
8,844 Views
70 Replies
Message 1 of 71

3D Solid Face Recognition

doaiena
Collaborator
Collaborator

Hello all,


I'm quite new to .NET programming in AutoCAD and most of the API is foreign to me. I want to be able to uniquely identify each face of a 3d solid object regardless of the solid's position or rotation and have the ability to change the faces' color, material, offset, etc.
At the moment i am able to loop through the solid's components using Brep and add all of the faces' SubentityIds to a list.

The problems i'm facing are: 
After a boolean operation all of the SubentityIds are reordered and my list of ids is useless. I tried another approach to recognize the solid's faces. Changing the color/material of a face and checking for the face's color during the Brep loop sort of works, until i change the solid's color/material and all the information is lost.
Is there a way to get a unique id for each face, or add some xdata or something similar to the face in order to recognize it?

 

Either my approach is totally wrong, or my lack of knoledge is the problem. I would be very grateful if the .NET experts can lend me a hand.

Thank you in advance.

0 Likes
8,845 Views
70 Replies
Replies (70)
Message 2 of 71

ActivistInvestor
Mentor
Mentor

I very much doubt there is any way to identify a face, that can persist across boolean operations, or other operations that modify the topology of a solid.

 

Solid faces are represented by a numerical index with the SubEntityId class, which is what AutoCAD APIs used as a way of referencing specific faces, and so indexes would become invalid after any change to the solid's topology that results in a change in the number of faces the solid is comprised of.

 


@doaienawrote:

Hello all,


I'm quite new to .NET programming in AutoCAD and most of the API is foreign to me. I want to be able to uniquely identify each face of a 3d solid object regardless of the solid's position or rotation and have the ability to change the faces' color, material, offset, etc.
At the moment i am able to loop through the solid's components using Brep and add all of the faces' SubentityIds to a list.

The problems i'm facing are: 
After a boolean operation all of the SubentityIds are reordered and my list of ids is useless. I tried another approach to recognize the solid's faces. Changing the color/material of a face and checking for the face's color during the Brep loop sort of works, until i change the solid's color/material and all the information is lost.
Is there a way to get a unique id for each face, or add some xdata or something similar to the face in order to recognize it?

 

Either my approach is totally wrong, or my lack of knoledge is the problem. I would be very grateful if the .NET experts can lend me a hand.

Thank you in advance.


 

0 Likes
Message 3 of 71

dgorsman
Consultant
Consultant

As a thought... you could attach XDATA in one of the vector formats that tracks position and rotation (I can't remember the precise DXF code though - sorry).  When you construct the original object, set the XDATA with a vector that is normal to the surface and within it's bounds.  Later, after the 3D solid is repositioned the normal vector position and direction can be checked against each face.  You still need to iterate over the faces which might be a problem for a very complex object but should be OK for most uses.

----------------------------------
If you are going to fly by the seat of your pants, expect friction burns.
"I don't know" is the beginning of knowledge, not the end.


0 Likes
Message 4 of 71

ActivistInvestor
Mentor
Mentor

@dgorsmanwrote:

 

        ...the normal vector position and direction...


A vector defines only a direction, not a position and direction, so it can't be 'within the bounds' of a face.  

 

0 Likes
Message 5 of 71

doaiena
Collaborator
Collaborator

Thank you for your suggestion 

0 Likes
Message 6 of 71

JamesMaeding
Advisor
Advisor

Not sure if its getting rediculous, but you could tract the centroid (and maybe area) of the face.

That could be too intensive if calcing the centroids of new solid is too slow.

A normal is not enough, many would be the same. Similar idea though.

You could store the list as xrecords as xdata is limited in size.


internal protected virtual unsafe Human() : mostlyHarmless
I'm just here for the Shelties

0 Likes
Message 7 of 71

ActivistInvestor
Mentor
Mentor

@JamesMaedingwrote:

Not sure if its getting rediculous, but you could tract the centroid (and maybe area) of the face.

That could be too intensive if calcing the centroids of new solid is too slow.

A normal is not enough, many would be the same. Similar idea though.

You could store the list as xrecords as xdata is limited in size.


That (and the previous suggestion of using vector normals) doesn't help associate new faces created by dividing an existing one, with the existing faces.

 

Neither the centroid and/or area can tell what existing face was divided to create any given new face(s) after an edit.

 

 

0 Likes
Message 8 of 71

ActivistInvestor
Mentor
Mentor

@doaienawrote:


There's no public API for accessing solid information at that level. AutoCAD stores the SAT file record in the entity, but reverse-engineering it is not trivial

0 Likes
Message 9 of 71

doaiena
Collaborator
Collaborator

A few years ago i made an effort to understand the acis model using as a starting point ACIS-REGION.LSP by Reini Urban, 12/1/98. As a proof of concept i wrote a function that could read the data from 3d solids and reconstruct that geometry in autolisp. There was still much work to be done in order to read all of the properties of the solid and reconstruct it as a copy. The next step was to make it work using "entmake" and "entmod" but it was too involved and i didnt have enough free time to work that out so i set my eyes on .NET, thinking there must be a more elegant way to handle that task.

0 Likes
Message 10 of 71

SEANT61
Advisor
Advisor

Is there a more robust definition for face recognition?  Here are a couple of fairly basic face modifications on a simple cube: Would  'Face recognition' need to retrieve everything I have highlighted - even if more than one face matched, or if the initial face had none of the original Vertex/Edge/Loop remaining?


************************************************************
May your cursor always snap to the location intended.
0 Likes
Message 11 of 71

doaiena
Collaborator
Collaborator

Your 4-th example is pretty overkill SEANT61. I wouldn't need to track such complexity (1 face split into 4 and track them all). It's getting too complicated if i have to keep track of such complex changes. What i'm looking for is a way to mark a face in on a solid and if the solid is modified in some way (stretch, chamfer, fillet, boolean operation), i want to know what the initial face that i've marked is, if it still exists (if the face is removed because of a boolean operation, i don't care about it). Once i know the original face that i have selected i can measure its dimensions, change its color/material, offset etc. I don't need to keep track of all of the faces in a solid.

0 Likes
Message 12 of 71

SEANT61
Advisor
Advisor

From what I currently know about the BREP api, I’m inclined to believe that all my examples could possibly be tracked, even with a solid’s subsequent translation and rotation.  As mentioned, the appropriate XDATA could coordinate Brep Face’s Plane.PointOnPlane and Normal. 

 

Other surface types, a cylinder, for example may also allow tracking via AxisOfSymetry and ReferenceAxis, coordinated with the cylinder’s Height interval. 

 

Your hope to accommodate chamfer, Fillet, and, maybe, Boolean would leave a Face's geometry intact for tracking.  Stretch, which I take to mean SolidEdit(Move, Rotate, Offset) would likely be a problem.  


************************************************************
May your cursor always snap to the location intended.
0 Likes
Message 13 of 71

doaiena
Collaborator
Collaborator

In stretch i meant if you have a box 10x10x10, move one of its faces along its normal and have a resulting solid 20x10x10. So that the starting dimensions of the marked face were 10x10 and after the stretch - 20x10. And by offset i meant just moving the face along its normal, without changing its dimensions or rotation, i won't twist marked faces. Most of the editing will be done prior to marking faces, so that minimal changes occur to the faces i'm tracking.

0 Likes
Message 14 of 71

SEANT61
Advisor
Advisor

@doaienawrote:

In stretch i meant if you have a box 10x10x10, move one of its faces along its normal and have a resulting solid 20x10x10. So that the starting dimensions of the marked face were 10x10 and after the stretch - 20x10. . . .


 

That may be trackable in that the underlying 'Plane', retrievable by It's PointOnPlane and Normal properties, can be coordinated via recorded XDATA.

@doaienawrote:

. . . And by offset i meant just moving the face along its normal, . . . .


 

This may require additional qualifiers. The sub-entity move/displacement for a solid probably does not (needs confirmation) modify the 1011,1021,1031 stored with the entity.

************************************************************
May your cursor always snap to the location intended.
0 Likes
Message 15 of 71

ActivistInvestor
Mentor
Mentor

XData is only transformed when an operation invokes TransformBy() on the object (e.g, move, rotate, mirror, scale).

 

Stretching, or any other type of face-level editing doesn't transform any Xdata.

 

@SEANT6's example represents the simplest of possible cases, notably that a cube doesn't have multiple, coplanar faces.

 

To solve a problem you have to identify the worst-case scenario, not the simplest one.

 


@doaienawrote:

In stretch i meant if you have a box 10x10x10, move one of its faces along its normal and have a resulting solid 20x10x10. So that the starting dimensions of the marked face were 10x10 and after the stretch - 20x10. And by offset i meant just moving the face along its normal, without changing its dimensions or rotation, i won't twist marked faces. Most of the editing will be done prior to marking faces, so that minimal changes occur to the faces i'm tracking.


 

 

 

 

 

 

0 Likes
Message 16 of 71

SEANT61
Advisor
Advisor

 Generally speaking, I agree with everything you've said @ActivistInvestor.  I will make a few observations, however:

 

I tend to believe that 'Stretching', as applied to 3dSolids, would not modify any 1011,1021,1031 based XDATA.  If I can believe this reference page, though, it will work for 2D related geometry:

https://www.autodesk.com/techpubs/autocad/acadr14/dxf/extended_data_al_u05_c.htm

The AutoCAD editor does allow 3dSolid "Stretch" (not necessarily with the Stretch command) via window selection with the Vertex filter engaged.  I doubt it does but we may need to confirm that the 3dSolid XDATA point does not behave similar.  

 

With regard to Simplest vs Worst case scenarios - if the process can't handle the simplest, no sense proceeding to the worst. Smiley Happy

 

 

 


************************************************************
May your cursor always snap to the location intended.
0 Likes
Message 17 of 71

ActivistInvestor
Mentor
Mentor

IMO, the question of what does/doesn't cause xdata to be transformed is really moot here, since there's numerous ways to edit solids that wouldn't transform xdata at all, so I don't think that sort of approach would be of use without imposing unreasonable restrictions on how users can edit solids.

 

The reason I suggested identifying and trying to address the worst-case scenario first, is because if that can't be solved, then a determination can be made without much wasted effort. Starting from the simplest-case and progressing to more complicated ones, only to hit a wall that can't be breached usually leads to the same outcome, but with more wasted effort.

 


@SEANT61wrote:

 Generally speaking, I agree with everything you've said @ActivistInvestor.  I will make a few observations, however:

 

I tend to believe that 'Stretching', as applied to 3dSolids, would not modify any 1011,1021,1031 based XDATA.  If I can believe this reference page, though, it will work for 2D related geometry:

https://www.autodesk.com/techpubs/autocad/acadr14/dxf/extended_data_al_u05_c.htm

The AutoCAD editor does allow 3dSolid "Stretch" (not necessarily with the Stretch command) via window selection with the Vertex filter engaged.  I doubt it does but we may need to confirm that the 3dSolid XDATA point does not behave similar.  

 

With regard to Simplest vs Worst case scenarios - if the process can't handle the simplest, no sense proceeding to the worst. Smiley Happy

 

 

 


 

 

0 Likes
Message 18 of 71

SEANT61
Advisor
Advisor

Interesting point.  We're both suggesting opposite direction to achieve the same goal; minimizing wasted effort.  I can't say that my recommendation is better or worse - I suppose it depends on the end goal of the OP.  I think I tend towards the 'simple to complex' methodology based on an assumption that I would learn more and more along the way.  


************************************************************
May your cursor always snap to the location intended.
0 Likes
Message 19 of 71

doaiena
Collaborator
Collaborator

I wouldn't want to go for an overly complicated solution that will cover all cases, if i can manage with a simpler one and work around its limitations. I still think about my initial approach of coloring the faces and searching for that color. It just seems the simplest thing to implement with the least ammount of code. It will work with all the possible ways i could edit a 3d solid and i won't have to worry about calculations, transformations, xdata and so on. The only drawback, i can't find a way around is that, changing the color of the solid entity will remove all of my "marked" faces. Is there some kind of reactor that could activate "on color change", or something else that would allow me to preserve the faces i've marked already and just color the rest. Besides i'm not confident that my .NET coding skills would allow me to implement one of the more sophisticated solutions.

0 Likes
Message 20 of 71

ActivistInvestor
Mentor
Mentor

I'm not aware of any notification or API that can tell you what happened to a solid when it was edited.  But, if you use color (or material perhaps?) to implement tracking, you could use an ObjectOverrule to capture the face attributes when the object is opened, and compare that to the attributes captured when the object is subsequently closed, but that presumes that the object is being opened and closed to change face attributes, but not also to change the solid's topology. IOW, that isn't trivial either, but might allow you to identify color or material changes.

 


@doaienawrote:

I wouldn't want to go for an overly complicated solution that will cover all cases, if i can manage with a simpler one and work around its limitations. I still think about my initial approach of coloring the faces and searching for that color. It just seems the simplest thing to implement with the least ammount of code. It will work with all the possible ways i could edit a 3d solid and i won't have to worry about calculations, transformations, xdata and so on. The only drawback, i can't find a way around is that, changing the color of the solid entity will remove all of my "marked" faces. Is there some kind of reactor that could activate "on color change", or something else that would allow me to preserve the faces i've marked already and just color the rest. Besides i'm not confident that my .NET coding skills would allow me to implement one of the more sophisticated solutions.