Duplicate points found when iterating points of a face

I'm trying to iterate the points of each selected planar face in a viewer. A crude example of what I'm doing is shown in the code below:

for (aisContext->InitSelected(); aisContext->MoreSelected(); aisContext->NextSelected())
{
    Handle(StdSelect_BRepOwner) owner = Handle(StdSelect_BRepOwner)::DownCast(aisContext->SelectedOwner());
    if (!owner.IsNull())
    {
        TopoDS_Shape shape = owner->Shape();
        if (shape.ShapeType() == TopAbs_ShapeEnum::TopAbs_FACE)
        {
            TopExp_Explorer vertexExplorer(shape, TopAbs_ShapeEnum::TopAbs_VERTEX);
            while (vertexExplorer.More())
            {
                TopoDS_Vertex v = TopoDS::Vertex(vertexExplorer.Current());
                gp_Pnt p = BRep_Tool::Pnt(v);

                // Do stuff with the point ...
                
                vertexExplorer.Next();
            }
        }
    }
}

The TopExp_Explorer iterates through each vertex twice. For example, if a single quad face is selected, the while loop above loops 8 times before exiting. Why would this be happening?

Also, I'm not sure if the code above is the "canonical" way of iterating sub-geometry of selectable entities. If there's a better solution to this, I'd love to know it.

Thanks!

 

Kirill Gavrilov's picture

The TopExp_Explorer iterates through each vertex twice.

TopExp_Explorer doesn't de-duplicate shapes for you - it just recursively iterates over all sub-shapes and return the ones that match required type.
TopoDS_Vertex entities are not direct children of TopoDS_Face, instead Face contains bounding Wire(s), Wire contains Edges, Edge contains Vertex, and Edges within Wire are connected via shared Vertexes. Take a look onto topology definition:
https://dev.opencascade.org/doc/overview/html/occt_user_guides__modeling...

Thus, indeed, duplicated vertexes in your code sample are expected.
You can use a map to filter results of TopExp_Explorer, or use tools like TopExp::MapShapes() which will do this for you.

Ajith Subramanian's picture

Thanks for your reply and the documentation. That makes perfect sense.

I was able to get the information I needed by using TopExp::MapShapes and then iterating the map of vertices.