Skip to content

Inconsistent Generated/Modified/IsDeleted implementations across BRepBuilderAPI classes Summary #1036

@Jojain

Description

@Jojain

Description

Several classes inheriting from BRepBuilderAPI_MakeShape have inconsistent or broken implementations of Generated(), Modified(), and IsDeleted() methods, making it difficult to reliably track shape history.

Affected Classes

  1. BRepFilletAPI_MakeFillet and BRepFilletAPI_MakeChamfer
    Problem: IsDeleted() only works reliably for faces, not for edges or vertices.

Root cause: In Build(), the internal map only stores faces from the result:

// BRepFilletAPI_MakeFillet.cxx, lines 382-386

TopExp_Explorer ex;
for (ex.Init(myShape, TopAbs_FACE); ex.More(); ex.Next())
{
  myMap.Add(ex.Current());
}
Then IsDeleted() checks this map:

// BRepFilletAPI_MakeFillet.cxx, lines 477-484

Standard_Boolean BRepFilletAPI_MakeFillet::IsDeleted(const TopoDS_Shape& F)
{
  if (myMap.Contains(F) || myBuilder.Builder()->IsSplit(F, TopAbs_OUT)
      || myBuilder.Builder()->IsSplit(F, TopAbs_IN) || myBuilder.Builder()->IsSplit(F, TopAbs_ON))
    return Standard_False;

  return Standard_True;
}

Since myMap only contains faces, calling IsDeleted() on an edge or vertex will always return true (deleted), even if the shape exists unchanged in the result.

Expected behavior: IsDeleted() should work for all shape types (faces, edges, vertices).

Reference implementation: BRepOffset_MakeOffset handles this correctly by mapping all shapes:

// BRepOffset_MakeOffset.cxx, lines 5220-5229

Standard_Boolean BRepOffset_MakeOffset::IsDeleted(const TopoDS_Shape& theS)
{
  if (myResMap.IsEmpty())
    TopExp::MapShapes(myOffsetShape, myResMap);  // Maps ALL shapes

  if (myResMap.Contains(theS))
    return Standard_False;

  return Generated(theS).IsEmpty() && Modified(theS).IsEmpty();
}

Suggested fix for BRepFilletAPI_MakeFillet:

Change myMap population in Build():


TopExp::MapShapes(myShape, myMap);
Update IsDeleted() to also check Generated() and Modified():

Standard_Boolean BRepFilletAPI_MakeFillet::IsDeleted(const TopoDS_Shape& F)
{
  if (myMap.Contains(F))
    return Standard_False;

  return Generated(F).IsEmpty() && Modified(F).IsEmpty();
}

The same fix applies to BRepFilletAPI_MakeChamfer, which has an identical implementation.

  1. BRepFeat_Form
    Problem: Generated() explicitly excludes faces, which is unexpected and undocumented.

// BRepFeat_Form.cxx

const TopTools_ListOfShape& BRepFeat_Form::Generated(const TopoDS_Shape& S)
{
  myGenerated.Clear();
  if (!IsDone()) return myGenerated;

  if (myMap.IsBound(S) && S.ShapeType() != TopAbs_FACE)  // Excludes faces
  {
    // ...
  }
  return myGenerated;
}

Impact
These inconsistencies make it difficult to write generic code that tracks shape modifications across different modeling operations. Users expect the BRepBuilderAPI_MakeShape interface to behave consistently across all derived classes.

Expected Behavior

If a face has generated shapes, Generated() should return them. The current behavior silently returns an empty list for faces, which can lead to incorrect assumptions about shape history.

Actual Behavior

Inconsistency in shape history tracking

Sample Code or DRAW Tcl Script

Source code provided above

Operating System

Windows

Compiler

MSVC

Bitness

64-bit

OCCT Version

7.9

Additional Files

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    0. NewThe issue was created, but not updated by maintainer. Waiting for updates labels and categories2. BugSomething isn't working2. EnhancementNew feature or request

    Type

    No type

    Projects

    Status

    Todo

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions