From 8e483143ae8f0d44b125d2eae84ff0a4629366c2 Mon Sep 17 00:00:00 2001 From: jfa Date: Fri, 12 Oct 2007 08:28:53 +0000 Subject: [PATCH] NPAL13902: Create face from edges. --- src/GEOMImpl/GEOMImpl_ShapeDriver.cxx | 146 +++++++++++++++----------- 1 file changed, 86 insertions(+), 60 deletions(-) diff --git a/src/GEOMImpl/GEOMImpl_ShapeDriver.cxx b/src/GEOMImpl/GEOMImpl_ShapeDriver.cxx index dc199ffee..4343903d5 100644 --- a/src/GEOMImpl/GEOMImpl_ShapeDriver.cxx +++ b/src/GEOMImpl/GEOMImpl_ShapeDriver.cxx @@ -18,11 +18,9 @@ // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -#include - #include + #include -#include #include #include @@ -36,12 +34,14 @@ #include #include #include -#include #include #include #include #include #include +#include + +#include #include #include @@ -53,9 +53,11 @@ #include #include #include + #include -#include -#include +#include + +#include #include #include @@ -182,75 +184,79 @@ Standard_Integer GEOMImpl_ShapeDriver::Execute(TFunction_Logbook& log) const } } else if (aType == FACE_WIRES) { + // Try to build a face from a set of wires and edges + int ind; + Handle(TColStd_HSequenceOfTransient) aShapes = aCI.GetShapes(); int nbshapes = aShapes->Length(); if (nbshapes < 1) { - Standard_ConstructionError::Raise("No wires given"); + Standard_ConstructionError::Raise("No wires or edges given"); } - // first wire or edge - Handle(GEOM_Function) aRefWire = Handle(GEOM_Function)::DownCast(aShapes->Value(1)); - TopoDS_Shape aWire = aRefWire->GetValue(); - if (aWire.IsNull()) Standard_NullObject::Raise("Argument Shape is null"); - TopoDS_Wire W1; - if(aWire.ShapeType() == TopAbs_WIRE) { - W1 = TopoDS::Wire(aWire); - } - else if(aWire.ShapeType() == TopAbs_EDGE && aWire.Closed()) { - BRepBuilderAPI_MakeWire MW; - MW.Add(TopoDS::Edge(aWire)); - if (!MW.IsDone()) { - Standard_ConstructionError::Raise("Wire construction failed"); + // 1. Extract all edges from the given arguments + TopTools_MapOfShape aMapEdges; + Handle(TopTools_HSequenceOfShape) aSeqEdgesIn = new TopTools_HSequenceOfShape; + + BRep_Builder B; + for (ind = 1; ind <= nbshapes; ind++) { + Handle(GEOM_Function) aRefSh_i = Handle(GEOM_Function)::DownCast(aShapes->Value(ind)); + TopoDS_Shape aSh_i = aRefSh_i->GetValue(); + + TopExp_Explorer anExpE_i (aSh_i, TopAbs_EDGE); + for (; anExpE_i.More(); anExpE_i.Next()) { + if (aMapEdges.Add(anExpE_i.Current())) { + aSeqEdgesIn->Append(anExpE_i.Current()); + } } - W1 = MW; } - else { - Standard_NullObject::Raise - ("Shape for face construction is neither a wire nor closed edge"); + + // 2. Connect edges to wires of maximum length + Handle(TopTools_HSequenceOfShape) aSeqWiresOut; + ShapeAnalysis_FreeBounds::ConnectEdgesToWires(aSeqEdgesIn, Precision::Confusion(), + /*shared*/Standard_False, aSeqWiresOut); + + // 3. Separate closed wires + Handle(TopTools_HSequenceOfShape) aSeqClosedWires = new TopTools_HSequenceOfShape; + Handle(TopTools_HSequenceOfShape) aSeqOpenWires = new TopTools_HSequenceOfShape; + for (ind = 1; ind <= aSeqWiresOut->Length(); ind++) { + if (aSeqWiresOut->Value(ind).Closed()) + aSeqClosedWires->Append(aSeqWiresOut->Value(ind)); + else + aSeqOpenWires->Append(aSeqWiresOut->Value(ind)); } - // basic face - TopoDS_Shape FFace; - GEOMImpl_Block6Explorer::MakeFace(W1, aCI.GetIsPlanar(), FFace); - if (FFace.IsNull()) { - Standard_ConstructionError::Raise("Face construction failed"); + if (aSeqClosedWires->Length() < 1) { + Standard_ConstructionError::Raise + ("There is no closed contour can be built from the given arguments"); } - if (nbshapes == 1) { - aShape = FFace; + // 4. Build a face / list of faces from all the obtained closed wires - } else { + // 4.a. Basic face + TopoDS_Shape aFFace; + TopoDS_Wire aW1 = TopoDS::Wire(aSeqClosedWires->Value(1)); + GEOMImpl_Block6Explorer::MakeFace(aW1, aCI.GetIsPlanar(), aFFace); + if (aFFace.IsNull()) { + Standard_ConstructionError::Raise("Face construction failed"); + } + + // 4.b. Add other wires + if (aSeqClosedWires->Length() == 1) { + aShape = aFFace; + } + else { TopoDS_Compound C; BRep_Builder aBuilder; aBuilder.MakeCompound(C); BRepAlgo_FaceRestrictor FR; - TopAbs_Orientation OriF = FFace.Orientation(); - TopoDS_Shape aLocalS = FFace.Oriented(TopAbs_FORWARD); + TopAbs_Orientation OriF = aFFace.Orientation(); + TopoDS_Shape aLocalS = aFFace.Oriented(TopAbs_FORWARD); FR.Init(TopoDS::Face(aLocalS), Standard_False, Standard_True); - for (int ind = 1; ind <= nbshapes; ind++) { - Handle(GEOM_Function) aRefWire_i = - Handle(GEOM_Function)::DownCast(aShapes->Value(ind)); - TopoDS_Shape aWire_i = aRefWire_i->GetValue(); - if (aWire_i.IsNull()) Standard_NullObject::Raise("Argument Shape is null"); - TopoDS_Wire W_i; - if(aWire_i.ShapeType() == TopAbs_WIRE) { - W_i = TopoDS::Wire(aWire_i); - } - else if(aWire_i.ShapeType() == TopAbs_EDGE && aWire_i.Closed()) { - BRepBuilderAPI_MakeWire MW1; - MW1.Add(TopoDS::Edge(aWire_i)); - if (!MW1.IsDone()) { - Standard_ConstructionError::Raise("Wire construction failed"); - } - W_i = MW1; - } - else { - Standard_NullObject::Raise - ("Shape for face construction is neither a wire nor closed edges"); - } - FR.Add(W_i); + for (ind = 1; ind <= aSeqClosedWires->Length(); ind++) { + TopoDS_Wire aW = TopoDS::Wire(aSeqClosedWires->Value(ind)); + FR.Add(aW); } FR.Perform(); @@ -270,6 +276,26 @@ Standard_Integer GEOMImpl_ShapeDriver::Execute(TFunction_Logbook& log) const } } } + + // 5. Add all open wires to the result + if (aSeqOpenWires->Length() > 0) { + //Standard_ConstructionError::Raise("There are some open wires"); + TopoDS_Compound C; + BRep_Builder aBuilder; + if (aSeqClosedWires->Length() == 1) { + aBuilder.MakeCompound(C); + aBuilder.Add(C, aShape); + } + else { + C = TopoDS::Compound(aShape); + } + + for (ind = 1; ind <= aSeqOpenWires->Length(); ind++) { + aBuilder.Add(C, aSeqOpenWires->Value(ind)); + } + + aShape = C; + } } else if (aType == SHELL_FACES) { Handle(TColStd_HSequenceOfTransient) aShapes = aCI.GetShapes(); @@ -395,13 +421,13 @@ Standard_Integer GEOMImpl_ShapeDriver::Execute(TFunction_Logbook& log) const if( Copy.IsDone() ) { TopoDS_Shape tds = Copy.Shape(); if( tds.IsNull() ) { - Standard_ConstructionError::Raise("Orientation aborted : Can not reverse the shape"); + Standard_ConstructionError::Raise("Orientation aborted : Can not reverse the shape"); } if( tds.Orientation() == TopAbs_FORWARD) - tds.Orientation(TopAbs_REVERSED) ; + tds.Orientation(TopAbs_REVERSED); else - tds.Orientation(TopAbs_FORWARD) ; + tds.Orientation(TopAbs_FORWARD); aShape = tds; } @@ -462,5 +488,5 @@ const Handle(GEOMImpl_ShapeDriver) Handle(GEOMImpl_ShapeDriver)::DownCast(const } } - return _anOtherObject ; + return _anOtherObject; } -- 2.39.2