If a surface is set, how to know which solid in this context the face belongs to.
Roman Lygin Fri, 01/21/2005 - 20:31
Hi TengDX,
This question is often posted, maybe you already found an answer. Just in case you did not, here it is.
Assume aShape is a shape that contains your solid - btw, this can only be compound of (compound of ...) solid(s). Or of compsolids, what is unlikely. aFace is a face you know (note a "face" term, not a surface which is a geometric entity underlying a face).
TopoDS_Solid aResSolid;
TopTools_IndexedDataMapOfShapeListOfShape anAncestorsMap;
TopExp::MapShapesAndAncestors (aShape, TopAbs_FACE, TopAbs_SOLID, anAncestorMap);
if (anAncestorsMap.Contains (aFace)) {
const TopTools_ListOfShape& aSolidList = anAncestorsMap.FindFromKey (aFace);
aResSolid = aSolidList.First();
//or search another solid if there are severals
}
Hi Roman. Thank you for your answer. There is some difference in my application. When to operate an solid in the AIS_InteractiveContext, I want to get the solid from the selected face. So I implement this function with the following code:
If I understand correctly, you have several solids in InteractiveContext (at neutral point) and you want to find the one the selected face belongs to, right ?
I would expect your code should work but I'd just optimize it as follows. I'd write:
...
else
{
TopTools_IndexedMapOfShape aChildrenMap;
TopExp::MapShapes( shape, TopAbs_FACE, aChildrenMap); //stores all faces of the shape
if (aChildrenMap.Contains (face->Shape())
{
...//solid is found
}
}
I even would write my own function and use it instead of TopExp::Map() as follows:
Probably you already got the difference. Just in case if not, or for other reviewers - here it is.
- TopExp::Map() iterates and stores ALL children in the map
- own IsChild() iterates until THE FIRST matching subshape is found, i.e. it should be time saving in average.
Fri, 01/21/2005 - 20:31
Hi TengDX,
This question is often posted, maybe you already found an answer. Just in case you did not, here it is.
Assume aShape is a shape that contains your solid - btw, this can only be compound of (compound of ...) solid(s). Or of compsolids, what is unlikely. aFace is a face you know (note a "face" term, not a surface which is a geometric entity underlying a face).
TopoDS_Solid aResSolid;
TopTools_IndexedDataMapOfShapeListOfShape anAncestorsMap;
TopExp::MapShapesAndAncestors (aShape, TopAbs_FACE, TopAbs_SOLID, anAncestorMap);
if (anAncestorsMap.Contains (aFace)) {
const TopTools_ListOfShape& aSolidList = anAncestorsMap.FindFromKey (aFace);
aResSolid = aSolidList.First();
//or search another solid if there are severals
}
Hope this helps.
Roman
Fri, 01/21/2005 - 20:55
Correction to the above:
aResSolid = TopoDS::Solid (aSolidList.First());
Sun, 01/23/2005 - 17:13
Hi Roman. Thank you for your answer. There is some difference in my application. When to operate an solid in the AIS_InteractiveContext, I want to get the solid from the selected face. So I implement this function with the following code:
Handle(AIS_Shape) CSketchDesignDoc::GetShapeFromFace( Handle(AIS_Shape) face)
{
AIS_ListOfInteractive aList;
myAISContext->DisplayedObjects(aList);
AIS_ListIteratorOfListOfInteractive aListIterator; for(aListIterator.Initialize(aList);aListIterator.More();aListIterator.Next())
{
Handle_AIS_InteractiveObject curItem = aListIterator.Value();
Handle_AIS_Shape pShape = Handle_AIS_Shape::DownCast (curItem);
TopoDS_Shape shape = pShape->Shape();
TopAbs_ShapeEnum typeEnum = shape.ShapeType();
if ( typeEnum != TopAbs_SOLID)
continue;
else
{
TopTools_IndexedDataMapOfShapeListOfShape anAncestorMap;
TopExp::MapShapesAndAncestors (shape, TopAbs_FACE,
TopAbs_SOLID, anAncestorMap);
if ( anAncestorMap.Contains( TopoDS::Face(face->Shape())))
{
AfxMessageBox("Face is found");
return pShape;
}
}
}
}
return NULL;
}
Would you help me check these code, and I debug for many times and failed. Thank you for your kindness again.
Sun, 01/23/2005 - 22:14
Hi TengDX,
If I understand correctly, you have several solids in InteractiveContext (at neutral point) and you want to find the one the selected face belongs to, right ?
I would expect your code should work but I'd just optimize it as follows. I'd write:
...
else
{
TopTools_IndexedMapOfShape aChildrenMap;
TopExp::MapShapes( shape, TopAbs_FACE, aChildrenMap); //stores all faces of the shape
if (aChildrenMap.Contains (face->Shape())
{
...//solid is found
}
}
I even would write my own function and use it instead of TopExp::Map() as follows:
Standard_Boolan IsChild (const TopoDS_Shape& theParent, const TopoDS_Shape& theChild)
{
for (TopExp_Explorer anExp (theParent, theChild.ShapeType()); anExp.More(); anExp.Next()) {
if (anExp.CurrentValue() == theChild)
return Standard_True;
}
return Standard_False;
}
...
else
{
if (IsChild (shape, face->Shape()))
{
... //solid is found
}
}
Hope this helps.
Roman
Mon, 01/24/2005 - 05:48
Hi, Roman,
Thank you very much. I adopt your advice and it works!!! Can you tell me what difference between the two methods. I really want to know the reason.
Thank you again.
TengDX
Wed, 02/23/2005 - 00:39
Hi TengDX,
Probably you already got the difference. Just in case if not, or for other reviewers - here it is.
- TopExp::Map() iterates and stores ALL children in the map
- own IsChild() iterates until THE FIRST matching subshape is found, i.e. it should be time saving in average.
Roman