X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FGEOMImpl%2FGEOMImpl_ShapeDriver.cxx;h=349b59f09a25e0e321d5c60e29051a1d16c275a2;hb=ae90785412a3a7038313c4d5f0e8df6449741607;hp=b533e7bff126f49fe0dcc4b363bfe118b82a4a09;hpb=670be7193918b4f9b65d5db19209f76744bbe43b;p=modules%2Fgeom.git diff --git a/src/GEOMImpl/GEOMImpl_ShapeDriver.cxx b/src/GEOMImpl/GEOMImpl_ShapeDriver.cxx index b533e7bff..349b59f09 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 @@ -145,7 +147,7 @@ Standard_Integer GEOMImpl_ShapeDriver::Execute(TFunction_Logbook& log) const aFW->Load(aWire); aFW->FixReorder(); - if (aFW->StatusReorder(ShapeExtend_FAIL1)) { + if (aFW->StatusReorder(ShapeExtend_FAIL1)) { Standard_ConstructionError::Raise("Wire construction failed: several loops detected"); } else if (aFW->StatusReorder(ShapeExtend_FAIL)) { Standard_ConstructionError::Raise("Wire construction failed"); @@ -153,78 +155,115 @@ Standard_Integer GEOMImpl_ShapeDriver::Execute(TFunction_Logbook& log) const Standard_ConstructionError::Raise("Wire construction failed: some gaps detected"); } else { } + + aFW->ClosedWireMode() = Standard_False; + aFW->FixConnected(); + if (aFW->StatusConnected(ShapeExtend_FAIL)) { + Standard_ConstructionError::Raise("Wire construction failed: cannot build connected wire"); + } + aShape = aFW->WireAPIMake(); } - } else if (aType == FACE_WIRE) { Handle(GEOM_Function) aRefBase = aCI.GetBase(); TopoDS_Shape aShapeBase = aRefBase->GetValue(); - if (aShapeBase.IsNull() || aShapeBase.ShapeType() != TopAbs_WIRE) { + if (aShapeBase.IsNull()) Standard_NullObject::Raise("Argument Shape is null"); + TopoDS_Wire W; + if (aShapeBase.ShapeType() == TopAbs_WIRE) { + W = TopoDS::Wire(aShapeBase); + } + else if (aShapeBase.ShapeType() == TopAbs_EDGE && aShapeBase.Closed()) { + BRepBuilderAPI_MakeWire MW; + MW.Add(TopoDS::Edge(aShapeBase)); + if (!MW.IsDone()) { + Standard_ConstructionError::Raise("Wire construction failed"); + } + W = MW; + } + else { Standard_NullObject::Raise - ("Shape for face construction is null or not a wire"); + ("Shape for face construction is neither a wire nor a closed edge"); } - TopoDS_Wire W = TopoDS::Wire(aShapeBase); - //BRepBuilderAPI_MakeFace MF (W, aCI.GetIsPlanar()); - //if (!MF.IsDone()) { - // Standard_ConstructionError::Raise("Face construction failed"); - //} - //aShape = MF.Shape(); GEOMImpl_Block6Explorer::MakeFace(W, aCI.GetIsPlanar(), aShape); if (aShape.IsNull()) { Standard_ConstructionError::Raise("Face construction failed"); } - } 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"); + } + + // 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()); + } + } } - // first wire - Handle(GEOM_Function) aRefWire = Handle(GEOM_Function)::DownCast(aShapes->Value(1)); - TopoDS_Shape aWire = aRefWire->GetValue(); - if (aWire.IsNull() || aWire.ShapeType() != TopAbs_WIRE) { - Standard_NullObject::Raise("Shape for face construction is null or not a wire"); + // 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)); } - TopoDS_Wire W = TopoDS::Wire(aWire); - - // basic face - //BRepBuilderAPI_MakeFace MF (W, aCI.GetIsPlanar()); - //if (!MF.IsDone()) { - // Standard_ConstructionError::Raise("Face construction failed"); - //} - //TopoDS_Shape FFace = MF.Shape(); - TopoDS_Shape FFace; - GEOMImpl_Block6Explorer::MakeFace(W, 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() || aWire_i.ShapeType() != TopAbs_WIRE) { - Standard_NullObject::Raise("Shape for face construction is null or not a wire"); - } - - FR.Add(TopoDS::Wire(aWire_i)); + for (ind = 1; ind <= aSeqClosedWires->Length(); ind++) { + TopoDS_Wire aW = TopoDS::Wire(aSeqClosedWires->Value(ind)); + FR.Add(aW); } FR.Perform(); @@ -244,6 +283,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(); @@ -369,13 +428,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; } @@ -436,5 +495,5 @@ const Handle(GEOMImpl_ShapeDriver) Handle(GEOMImpl_ShapeDriver)::DownCast(const } } - return _anOtherObject ; + return _anOtherObject; }