admin管理员组

文章数量:1356959

From an OpenCascade TopoDS_CompSolid, I'm trying to

  • get a list of all external faces (the outer shell/envelope of the TopoDS_CompSolid)
  • get a list of all internal faces (in the case of the screenshot below, just the shared faces of the TopoDS_Solids in the TopoDS_CompSolid)

Screenshot of OpenCascade's topologic hierarchy from training PDF for reference:

Currently, following this BOPAlgo_CellsBuilder doc, I create the TopoDS_CompSolid from a list of TopoDS_Solids, remove internal boundaries, and then compare TopoDS_Faces of the external boundary solid and list of solids (if not in external, should be internal), but this does not find any internal boundaries.

void GetExternalBoundary(const TArray<TopoDS_Solid>& Solids, TopoDS_Solid& ExternalBoundary)
{
    // Get the Cells
    TopTools_ListOfShape BuilderArguments;
    for (const TopoDS_Solid& Solid : Solids)
    {
        BuilderArguments.Append(Solid);
    }

    // Build CompSolid
    BOPAlgo_CellsBuilder Builder;
    Builder.SetArguments(BuilderArguments);
    Builder.Perform();

    if (Builder.HasErrors())
    {
        UE_LOG(LogTemp, Error, TEXT("OCCT solids union failed."));
        return;
    }

    // Add results
    int32 Material = 1;
    bool bUpdate = false;
    Builder.AddAllToResult(Material, bUpdate);
    Builder.RemoveInternalBoundaries();

    // Return the first shape
    for (TopExp_Explorer ExternalBoundaryShapeExplorer(ExternalBoundaryShape, TopAbs_SOLID); ExternalBoundaryShapeExplorer.More(); ExternalBoundaryShapeExplorer.Next())
    {
        ExternalBoundary = TopoDS::Solid(ExternalBoundaryShapeExplorer.Current());
        return;
    }
}

void TestGetBoundaries(const TArray<TopoDS_Solid>& Solids)
{   
    // Compute the envelope Cell
    TopoDS_Solid ExternalBoundary;
    GetExternalBoundary(Solids, ExternalBoundary);

    // Get the envelope Faces
    TArray<TopoDS_Face> ExternalBoundaryFaces;
    for (TopExp_Explorer ExternalBoundaryExplorer(ExternalBoundary, TopAbs_FACE); ExternalBoundaryExplorer.More(); ExternalBoundaryExplorer.Next())
    {
        ExternalBoundaryFaces.Add(TopoDS::Face(ExternalBoundaryExplorer.Current()));
    }

    // Get the original Faces
    TArray<TopoDS_Face> Faces;
    for (const TopoDS_Solid& Solid : Solids)
    {
        for (TopExp_Explorer SolidExplorer(Solid, TopAbs_FACE); SolidExplorer.More(); SolidExplorer.Next())
        {
            Faces.Add(TopoDS::Face(SolidExplorer.Current()));
        }
    }

    // An internal Face can be found in the original Face list, but not in the envelope Face list.
    TArray<TopoDS_Face> InternalFaces;
    Handle(IntTools_Context) pOcctIntToolsContext = new IntTools_Context();
    for (const TopoDS_Face& Face : Faces)
    {
        bool isExternalFace = false;
        for (const TopoDS_Face& ExternalBoundaryFace : ExternalBoundaryFaces)
        {
            if (BOPTools_AlgoTools::AreFacesSameDomain(Face, ExternalBoundaryFace, pOcctIntToolsContext))
            {
                isExternalFace = true;
                break;
            }
        }

        if (!isExternalFace)
        {
            InternalFaces.Add(Face);
        }
    }

    UE_LOG(LogTemp, Warning, TEXT("Found %d exterior faces and %d interior faces."), ExternalBoundaryFaces.Num(), InternalFaces.Num());
}

From performing shape analysis,

ShapeAnalysis_ShapeContents ShapeAnalysis;
ShapeAnalysis.Perform(Shape);

and logging number TopoDS_Faces, it seems like RemoveInternalBoundaries() doesn't do anything/all faces are in the resulting external boundary.

本文标签: c17How to get external and internal faces from a TopoDSCompSolid in OpenCascade CStack Overflow