X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FGEOMImpl%2FGEOMImpl_ShapeDriver.cxx;h=349b59f09a25e0e321d5c60e29051a1d16c275a2;hb=ae90785412a3a7038313c4d5f0e8df6449741607;hp=418ecbc3a2fef49036e41b4863eecf2e2feb866a;hpb=10781d15d3ddb4627492197b1bdb3b3042cdef28;p=modules%2Fgeom.git diff --git a/src/GEOMImpl/GEOMImpl_ShapeDriver.cxx b/src/GEOMImpl/GEOMImpl_ShapeDriver.cxx index 418ecbc3a..349b59f09 100644 --- a/src/GEOMImpl/GEOMImpl_ShapeDriver.cxx +++ b/src/GEOMImpl/GEOMImpl_ShapeDriver.cxx @@ -1,9 +1,26 @@ - -#include +// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// #include + #include -#include #include #include @@ -17,25 +34,30 @@ #include #include #include -#include #include #include #include #include #include +#include + +#include #include #include #include #include #include +#include #include #include #include #include + #include -#include -#include +#include + +#include #include #include @@ -82,6 +104,8 @@ Standard_Integer GEOMImpl_ShapeDriver::Execute(TFunction_Logbook& log) const TopoDS_Wire aWire; B.MakeWire(aWire); + BRepBuilderAPI_MakeWire MW; + bool isMWDone = true; // add edges for (ind = 1; ind <= nbshapes; ind++) { @@ -90,99 +114,156 @@ Standard_Integer GEOMImpl_ShapeDriver::Execute(TFunction_Logbook& log) const if (aShape_i.IsNull()) { Standard_NullObject::Raise("Shape for wire construction is null"); } - if (aShape_i.ShapeType() == TopAbs_EDGE) - B.Add(aWire, TopoDS::Edge(aShape_i)); - else if (aShape_i.ShapeType() == TopAbs_WIRE) - B.Add(aWire, TopoDS::Wire(aShape_i)); - else + if (aShape_i.ShapeType() == TopAbs_EDGE) { + B.Add(aWire, TopoDS::Edge(aShape_i)); + MW.Add(TopoDS::Edge(aShape_i)); + if (!MW.IsDone()) { + // check status after each edge/wire addition, because the final status + // can be OK even in case, when some edges/wires was not accepted. + isMWDone = false; + } + } else if (aShape_i.ShapeType() == TopAbs_WIRE) { + TopExp_Explorer exp (aShape_i, TopAbs_EDGE); + for (; exp.More(); exp.Next()) { + B.Add(aWire, TopoDS::Edge(exp.Current())); + MW.Add(TopoDS::Edge(exp.Current())); + if (!MW.IsDone()) { + // check status after each edge/wire addition, because the final status + // can be OK even in case, when some edges/wires was not accepted. + isMWDone = false; + } + } + } else { Standard_TypeMismatch::Raise ("Shape for wire construction is neither an edge nor a wire"); + } } - // fix edges order - Handle(ShapeFix_Wire) aFW = new ShapeFix_Wire; - aFW->Load(aWire); - aFW->FixReorder(); - - 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"); - } else if (aFW->StatusReorder(ShapeExtend_DONE2)) { - Standard_ConstructionError::Raise("Wire construction failed: some gaps detected"); + if (isMWDone) { + aShape = MW; } else { - } - aShape = aFW->WireAPIMake(); - if (aShape.IsNull()) - Standard_ConstructionError::Raise("Wire construction failed"); + // fix edges order + Handle(ShapeFix_Wire) aFW = new ShapeFix_Wire; + aFW->Load(aWire); + aFW->FixReorder(); + + 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"); + } else if (aFW->StatusReorder(ShapeExtend_DONE2)) { + Standard_ConstructionError::Raise("Wire construction failed: some gaps detected"); + } else { + } - } else if (aType == FACE_WIRE) { + 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; - } else if (aType == FACE_WIRES) { 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 - 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"); + // 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()); + } + } } - 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"); + + // 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)); } - if (nbshapes == 1) { - aShape = FFace; + if (aSeqClosedWires->Length() < 1) { + Standard_ConstructionError::Raise + ("There is no closed contour can be built from the given arguments"); + } - } else { + // 4. Build a face / list of faces from all the obtained closed wires + + // 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(); @@ -202,7 +283,28 @@ Standard_Integer GEOMImpl_ShapeDriver::Execute(TFunction_Logbook& log) const } } } - } else if (aType == SHELL_FACES) { + + // 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(); unsigned int ind, nbshapes = aShapes->Length(); @@ -219,17 +321,29 @@ Standard_Integer GEOMImpl_ShapeDriver::Execute(TFunction_Logbook& log) const aSewing.Perform(); - TopExp_Explorer exp (aSewing.SewedShape(), TopAbs_SHELL); - Standard_Integer ish = 0; - for (; exp.More(); exp.Next()) { - aShape = exp.Current(); - ish++; + TopoDS_Shape sh = aSewing.SewedShape(); + if( sh.ShapeType()==TopAbs_FACE && nbshapes==1 ) { + // case for creation of shell from one face - PAL12722 (skl 26.06.2006) + TopoDS_Shell ss; + B.MakeShell(ss); + B.Add(ss,sh); + aShape = ss; } + else { + //TopExp_Explorer exp (aSewing.SewedShape(), TopAbs_SHELL); + TopExp_Explorer exp (sh, TopAbs_SHELL); + Standard_Integer ish = 0; + for (; exp.More(); exp.Next()) { + aShape = exp.Current(); + ish++; + } - if (ish != 1) - aShape = aSewing.SewedShape(); + if (ish != 1) + aShape = aSewing.SewedShape(); + } - } else if (aType == SOLID_SHELL) { + } + else if (aType == SOLID_SHELL) { Handle(GEOM_Function) aRefShell = aCI.GetBase(); TopoDS_Shape aShapeShell = aRefShell->GetValue(); if (aShapeShell.IsNull() || aShapeShell.ShapeType() != TopAbs_SHELL) { @@ -251,7 +365,8 @@ Standard_Integer GEOMImpl_ShapeDriver::Execute(TFunction_Logbook& log) const aShape = Sol; - } else if (aType == SOLID_SHELLS) { + } + else if (aType == SOLID_SHELLS) { Handle(TColStd_HSequenceOfTransient) aShapes = aCI.GetShapes(); unsigned int ind, nbshapes = aShapes->Length(); Standard_Integer ish = 0; @@ -282,7 +397,8 @@ Standard_Integer GEOMImpl_ShapeDriver::Execute(TFunction_Logbook& log) const return 0; } - } else if (aType == COMPOUND_SHAPES) { + } + else if (aType == COMPOUND_SHAPES) { Handle(TColStd_HSequenceOfTransient) aShapes = aCI.GetShapes(); unsigned int ind, nbshapes = aShapes->Length(); @@ -300,27 +416,28 @@ Standard_Integer GEOMImpl_ShapeDriver::Execute(TFunction_Logbook& log) const aShape = C; - } else if (aType == REVERSE_ORIENTATION) { + } + else if (aType == REVERSE_ORIENTATION) { Handle(GEOM_Function) aRefShape = aCI.GetBase(); TopoDS_Shape aShape_i = aRefShape->GetValue(); if (aShape_i.IsNull()) { Standard_NullObject::Raise("Shape for reverse is null"); } - + BRepBuilderAPI_Copy Copy(aShape_i); 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; - } + } } if (aShape.IsNull()) return 0; @@ -378,5 +495,5 @@ const Handle(GEOMImpl_ShapeDriver) Handle(GEOMImpl_ShapeDriver)::DownCast(const } } - return _anOtherObject ; + return _anOtherObject; }