IS this situation a bug of TopoDS_Shape.IsNull() ?

jianbaoxia

CAD master
Hey Bros, I meet a confusing situation today.
I build two faces: aFace and bFace, and the aFace can cover bFace.
Then I use the BRepAlgoAPI_Cut get a TopoDS_Shape which is named bCuta,
and as expected the bCuta has nothing, I had output it as step file to verify it.

And what make me confused is, when I call bCuta.IsNull(), the result is false.
I hace no idea why it's false???
There is my code:
C++:
    gp_Pnt p1(0, 0, 0);
    gp_Pnt p2(10, 0, 0);
    gp_Pnt p3(10, 10, 0);
    gp_Pnt p4(0, 10, 0);
    TopoDS_Edge e1 = BRepBuilderAPI_MakeEdge(p1, p2);
    TopoDS_Edge e2 = BRepBuilderAPI_MakeEdge(p2, p3);
    TopoDS_Edge e3 = BRepBuilderAPI_MakeEdge(p3, p4);
    TopoDS_Edge e4 = BRepBuilderAPI_MakeEdge(p4, p1);
    TopoDS_Wire aWire = BRepBuilderAPI_MakeWire(e1, e2, e3, e4);
    TopoDS_Face aFace = BRepBuilderAPI_MakeFace(aWire);

    gp_Pnt p5(10, 5, 0);
    gp_Pnt p6(0, 5, 0);
    TopoDS_Edge e01 = BRepBuilderAPI_MakeEdge(p1, p2);
    TopoDS_Edge e02 = BRepBuilderAPI_MakeEdge(p2, p5);
    TopoDS_Edge e03 = BRepBuilderAPI_MakeEdge(p5, p6);
    TopoDS_Edge e04 = BRepBuilderAPI_MakeEdge(p6, p1);
    TopoDS_Wire bWire = BRepBuilderAPI_MakeWire(e01, e02, e03, e04);
    TopoDS_Face bFace = BRepBuilderAPI_MakeFace(bWire);

    TopoDS_Shape bCuta = BRepAlgoAPI_Cut(bFace, aFace);
    if (bCuta.IsNull()) std::cout << "bCuta is null!" << std::endl;
 

Quaoar

Administrator
Staff member
Null shape would mean that no memory is allocated to store its B-rep. A shape can be empty but not-null. That's exactly your case:

1654873167545.png

bCuta is an allocated compound which is simply empty:

1654873205132.png

You would need some different method to check if a shape is empty or not. Something like that:

Code:
bool IsEmptyShape(const TopoDS_Shape& shape)
{
  if ( shape.IsNull() )
    return true;

  if ( shape.ShapeType() >= TopAbs_FACE )
    return false;

  // If a shape contains just nested compounds, it's still empty. If there's at least
  // something of non-compound type, the shape is considered as non-empty.
  TopTools_IndexedMapOfShape map;
  TopExp::MapShapes(shape, map);
  //
  for ( TopTools_IndexedMapOfShape::const_iterator it = map.cbegin(); it != map.cend(); it++ )
  {
    if ( (*it).ShapeType() != TopAbs_COMPOUND )
      return false;
  }

  return true;
}

As you can see, it's slightly more than plain null check ;)
 
Top