X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FGEOMImpl%2FGEOMImpl_BlockDriver.cxx;h=d80125d3582d5042a62d1f4ef1f525728cec0e56;hb=3059f9d5521dd7c91c35c50afbd6beb18b8826fd;hp=27073e43919bcdc6ba5e59d1556022bbefb329a9;hpb=d3dd282390888d7dc091ba2c2ffe7923bd7458e6;p=modules%2Fgeom.git diff --git a/src/GEOMImpl/GEOMImpl_BlockDriver.cxx b/src/GEOMImpl/GEOMImpl_BlockDriver.cxx index 27073e439..d80125d35 100644 --- a/src/GEOMImpl/GEOMImpl_BlockDriver.cxx +++ b/src/GEOMImpl/GEOMImpl_BlockDriver.cxx @@ -1,22 +1,50 @@ - -using namespace std; +// Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 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 "GEOMImpl_BlockDriver.hxx" -#include "GEOMImpl_IBlocks.hxx" -#include "GEOMImpl_IBlockTrsf.hxx" -#include "GEOMImpl_GlueDriver.hxx" -#include "GEOMImpl_Types.hxx" -#include "GEOMImpl_ILocalOperations.hxx" -#include "GEOMImpl_Block6Explorer.hxx" -#include "GEOM_Function.hxx" +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include -#include "ShHealOper_Sewing.hxx" -#include "NMTAlgo_Splitter1.hxx" +#include "utilities.h" #include +#include #include #include #include @@ -28,6 +56,7 @@ using namespace std; #include #include #include +#include #include #include #include @@ -55,6 +84,9 @@ using namespace std; #include +#include +#include + #include #include #include @@ -196,17 +228,25 @@ Standard_Integer GEOMImpl_BlockDriver::Execute(TFunction_Logbook& log) const } // build wire in right order, corresponding to edges connexity - BRepBuilderAPI_MakeWire MW; + BRepBuilderAPI_MakeWire* MW; if (isConnected12) - MW = BRepBuilderAPI_MakeWire(anEdge1, anEdge2, anEdge3, anEdge4); + MW = new BRepBuilderAPI_MakeWire(anEdge1, anEdge2, anEdge3, anEdge4); else - MW = BRepBuilderAPI_MakeWire(anEdge1, anEdge3, anEdge2, anEdge4); + MW = new BRepBuilderAPI_MakeWire(anEdge1, anEdge3, anEdge2, anEdge4); - if (!MW.IsDone()) { + if (!MW->IsDone()) { Standard_ConstructionError::Raise ("Impossible to build a connected wire from the given edges"); } - TopoDS_Wire aWire = MW; + TopoDS_Wire aWire = *MW; + delete MW; + + // check the wire closure + TopoDS_Vertex aV1, aV2; + TopExp::Vertices(aWire, aV1, aV2); + if ( !aV1.IsNull() && !aV2.IsNull() && aV1.IsSame(aV2) ) + aWire.Closed( true ); + if (!aWire.Closed()) { Standard_ConstructionError::Raise ("Impossible to build a closed wire from the given edges"); @@ -235,16 +275,26 @@ Standard_Integer GEOMImpl_BlockDriver::Execute(TFunction_Logbook& log) const // create two edges, linking ends of the given edges TopoDS_Vertex V11, V12, V21, V22; - TopExp::Vertices(anEdge1, V11, V12, Standard_True); - TopExp::Vertices(anEdge2, V21, V22, Standard_True); + TopExp::Vertices(anEdge1, V11, V12, Standard_False); + TopExp::Vertices(anEdge2, V21, V22, Standard_False); if (V11.IsNull() || V12.IsNull() || V21.IsNull() || V22.IsNull()) { Standard_NullObject::Raise("Bad edge for face construction: vertex is not defined"); } - gp_Pnt P11 = BRep_Tool::Pnt(V11); - gp_Pnt P12 = BRep_Tool::Pnt(V12); - gp_Pnt P21 = BRep_Tool::Pnt(V21); - gp_Pnt P22 = BRep_Tool::Pnt(V22); + + BRepAdaptor_Curve C1 (anEdge1); + BRepAdaptor_Curve C2 (anEdge2); + gp_Pnt P11, P12, P21, P22; + + // Mantis issue 0020599: Creation of a quadrangle face from 2 edges: SIGSEGV + P11 = C1.Value(C1.FirstParameter()); + P12 = C1.Value(C1.LastParameter()); + P21 = C2.Value(C2.FirstParameter()); + P22 = C2.Value(C2.LastParameter()); + //gp_Pnt P11 = BRep_Tool::Pnt(V11); + //gp_Pnt P12 = BRep_Tool::Pnt(V12); + //gp_Pnt P21 = BRep_Tool::Pnt(V21); + //gp_Pnt P22 = BRep_Tool::Pnt(V22); if (P11.Distance(P21) < prec || P12.Distance(P22) < prec || P11.Distance(P22) < prec || P12.Distance(P21) < prec) { @@ -254,24 +304,70 @@ Standard_Integer GEOMImpl_BlockDriver::Execute(TFunction_Logbook& log) const Standard_Real per11 = P11.Distance(P21) + P12.Distance(P22); Standard_Real per12 = P11.Distance(P22) + P12.Distance(P21); + BRep_Builder BB; + TopoDS_Edge anEdge3; TopoDS_Edge anEdge4; + + // Mantis issue 0020599: Creation of a quadrangle face from 2 edges: SIGSEGV if (per11 < per12) { - anEdge3 = BRepBuilderAPI_MakeEdge(V11, V21); - anEdge4 = BRepBuilderAPI_MakeEdge(V12, V22); - } else { - anEdge3 = BRepBuilderAPI_MakeEdge(V11, V22); - anEdge4 = BRepBuilderAPI_MakeEdge(V12, V21); + Handle(Geom_Line) Line1 = GC_MakeLine(P11, P21).Value(); + Handle(Geom_Line) Line2 = GC_MakeLine(P12, P22).Value(); + + BB.MakeEdge(anEdge3, Line1, Precision::Confusion()); + BB.Range(anEdge3, 0., P11.Distance(P21)); + BB.Add(anEdge3, V11.Oriented(TopAbs_FORWARD)); + BB.Add(anEdge3, V21.Oriented(TopAbs_REVERSED)); + + BB.MakeEdge(anEdge4, Line2, Precision::Confusion()); + BB.Range(anEdge4, 0., P12.Distance(P22)); + BB.Add(anEdge4, V12.Oriented(TopAbs_FORWARD)); + BB.Add(anEdge4, V22.Oriented(TopAbs_REVERSED)); + } + else { + Handle(Geom_Line) Line1 = GC_MakeLine(P11, P22).Value(); + Handle(Geom_Line) Line2 = GC_MakeLine(P12, P21).Value(); + + BB.MakeEdge(anEdge3, Line1, Precision::Confusion()); + BB.Range(anEdge3, 0., P11.Distance(P22)); + BB.Add(anEdge3, V11.Oriented(TopAbs_FORWARD)); + BB.Add(anEdge3, V22.Oriented(TopAbs_REVERSED)); + + BB.MakeEdge(anEdge4, Line2, Precision::Confusion()); + BB.Range(anEdge4, 0., P12.Distance(P21)); + BB.Add(anEdge4, V12.Oriented(TopAbs_FORWARD)); + BB.Add(anEdge4, V21.Oriented(TopAbs_REVERSED)); } + //if (per11 < per12) { + // anEdge3 = BRepBuilderAPI_MakeEdge(V11, V21); + // anEdge4 = BRepBuilderAPI_MakeEdge(V12, V22); + //} else { + // anEdge3 = BRepBuilderAPI_MakeEdge(V11, V22); + // anEdge4 = BRepBuilderAPI_MakeEdge(V12, V21); + //} // build a wire - BRepBuilderAPI_MakeWire MW (anEdge1, anEdge3, anEdge2, anEdge4); - if (!MW.IsDone()) { + BRepBuilderAPI_MakeWire* MW; + MW = new BRepBuilderAPI_MakeWire(anEdge1, anEdge3, anEdge2, anEdge4); + if (!MW->IsDone()) { Standard_ConstructionError::Raise("Wire construction failed"); } + TopoDS_Wire aWire = *MW; + delete MW; + + TopoDS_Vertex aV1, aV2; + TopExp::Vertices(aWire, aV1, aV2); + if ( !aV1.IsNull() && !aV2.IsNull() && aV1.IsSame(aV2) ) + aWire.Closed( true ); + + if (!aWire.Closed()) { + Standard_ConstructionError::Raise + ("Impossible to build a closed wire from the given edges"); + } + // try to build face on the wire - GEOMImpl_Block6Explorer::MakeFace(MW, Standard_False, aShape); + GEOMImpl_Block6Explorer::MakeFace(aWire, Standard_False, aShape); if (aShape.IsNull()) { Standard_ConstructionError::Raise("Face construction failed"); } @@ -329,6 +425,7 @@ Standard_Integer GEOMImpl_BlockDriver::Execute(TFunction_Logbook& log) const } // try to build face on the wire + aMkPoly.Close(); GEOMImpl_Block6Explorer::MakeFace(aMkPoly, Standard_False, aShape); if (aShape.IsNull()) { Standard_ConstructionError::Raise("Face construction failed"); @@ -445,124 +542,203 @@ Standard_Integer GEOMImpl_BlockDriver::Execute(TFunction_Logbook& log) const TopoDS_Shape aCompound = anArgs(1); // Glue coincident faces and edges (with Partition algorithm). - NMTAlgo_Splitter1 PS; - PS.AddShape(aCompound); - PS.Compute(); - PS.SetRemoveWebs(Standard_False); -// PS.Build(aCompound.ShapeType()); - PS.Build(TopAbs_SOLID); - - aShape = PS.Shape(); - } else { - } + //NMTAlgo_Splitter1 PS; + //PS.AddShape(aCompound); + //PS.Compute(); + //PS.SetRemoveWebs(Standard_False); + // PS.Build(aCompound.ShapeType()); + //PS.Build(TopAbs_SOLID); + //aShape = PS.Shape(); + + GEOMAlgo_Gluer aGluer; + aGluer.SetShape(aCompound); + aGluer.SetCheckGeometry(Standard_True); + aGluer.Perform(); + aShape = aGluer.Result(); - } else { // Multi-transformations - TopoDS_Shape aMulti; - GEOMImpl_IBlockTrsf aCI (aFunction); - Handle(GEOM_Function) aRefShape = aCI.GetOriginal(); - TopoDS_Shape aBlockIni = aRefShape->GetValue(); - if (aBlockIni.IsNull()) { - Standard_NullObject::Raise("Null Block"); + } else { } - // Copy block to avoid problems (PAL6706) - TColStd_IndexedDataMapOfTransientTransient aMap; - TopoDS_Shape aBlock; - TNaming_CopyShape::CopyTool(aBlockIni, aMap, aBlock); + } else { // Multi-transformations and compound improving - // Block tolerance in vertices - Standard_Real aTol = prec; - TopExp_Explorer expV (aBlock, TopAbs_VERTEX); - TopTools_MapOfShape mapShape; - for (; expV.More(); expV.Next()) { - if (mapShape.Add(expV.Current())) { - TopoDS_Vertex aV = TopoDS::Vertex(expV.Current()); - aTol = Max(BRep_Tool::Tolerance(aV), aTol); - } - } + if (aType == BLOCK_REMOVE_EXTRA || + aType == BLOCK_COMPOUND_IMPROVE) { - if (aType == BLOCK_MULTI_TRANSFORM_1D) { - // Retrieve a faces by Ids - Standard_Integer aFace1Id = aCI.GetFace1U(); - Standard_Integer aFace2Id = aCI.GetFace2U(); - TopoDS_Shape aFace1, aFace2; - if (!GEOMImpl_ILocalOperations::GetSubShape(aBlock, aFace1Id, aFace1)) { - Standard_NullObject::Raise("Can not retrieve a sub-shape with given Id"); + GEOMImpl_IBlockTrsf aCI (aFunction); + Handle(GEOM_Function) aRefShape = aCI.GetOriginal(); + TopoDS_Shape aBlockOrComp = aRefShape->GetValue(); + if (aBlockOrComp.IsNull()) { + Standard_NullObject::Raise("Null Shape given"); } - if (aFace1.ShapeType() != TopAbs_FACE) { - Standard_TypeMismatch::Raise("Sub-shape with given Id is not a face"); + + // 1. Improve solids with seam and/or degenerated edges + BlockFix_BlockFixAPI aTool; + //aTool.Tolerance() = toler; + aTool.OptimumNbFaces() = aCI.GetOptimumNbFaces(); + aTool.SetShape(aBlockOrComp); + aTool.Perform(); + + TopoDS_Shape aFixedExtra = aTool.Shape(); + + // Repair result + BRepCheck_Analyzer ana (aFixedExtra, false); + if (!ana.IsValid()) { + TopoDS_Shape aFixed; + ShHealOper_ShapeProcess aHealer; + aHealer.Perform(aFixedExtra, aFixed); + if (aHealer.isDone()) + aFixedExtra = aFixed; } - if (aFace2Id > 0) { - if (!GEOMImpl_ILocalOperations::GetSubShape(aBlock, aFace2Id, aFace2)) { - Standard_NullObject::Raise("Can not retrieve a sub-shape with given Id"); - } - if (aFace2.ShapeType() != TopAbs_FACE) { - Standard_TypeMismatch::Raise("Sub-shape with given Id is not a face"); + if (aType == BLOCK_REMOVE_EXTRA) + { + aShape = aFixedExtra; + + if (aShape == aBlockOrComp) { + MESSAGE("No modifications have been done"); } } + else // aType == BLOCK_COMPOUND_IMPROVE + { + // 2. Separate non-blocks + TopTools_ListOfShape BLO; // All blocks from the given compound + TopTools_ListOfShape NOT; // Not blocks + TopTools_ListOfShape EXT; // Hexahedral solids, having degenerated and/or seam edges + GEOMImpl_IBlocksOperations::AddBlocksFrom(aFixedExtra, BLO, NOT, EXT); + + if (NOT.Extent() > 0) { + MESSAGE("Some non-blocks have been removed"); + } - Standard_Integer aNbIter = aCI.GetNbIterU(); + // 3. Warn about staying extra-edges + if (EXT.Extent() > 0) { + MESSAGE("Warning: Not all seam or degenerated edges was removed"); + } - MultiTransformate1D(aBlock, aFace1, aFace2, aNbIter, aMulti); + // ??? Throw away standalone blocks ??? - } else if (aType == BLOCK_MULTI_TRANSFORM_2D) { - // Retrieve a faces by Ids - Standard_Integer aFace1UId = aCI.GetFace1U(); - Standard_Integer aFace2UId = aCI.GetFace2U(); - Standard_Integer aFace1VId = aCI.GetFace1V(); - Standard_Integer aFace2VId = aCI.GetFace2V(); + // 4. Create compound of all blocks + TopoDS_Compound aComp; + BRep_Builder BB; + BB.MakeCompound(aComp); + TopTools_ListIteratorOfListOfShape BLOit (BLO); + for (; BLOit.More(); BLOit.Next()) { + BB.Add(aComp, BLOit.Value()); + } - TopoDS_Shape aFace1U, aFace2U, aFace1V, aFace2V; - if (!GEOMImpl_ILocalOperations::GetSubShape(aBlock, aFace1UId, aFace1U) || - !GEOMImpl_ILocalOperations::GetSubShape(aBlock, aFace1VId, aFace1V)) { - Standard_NullObject::Raise("Can not retrieve a sub-shape with given Id"); + // 5. Glue Faces + aShape = GEOMImpl_GlueDriver::GlueFaces(aComp, Precision::Confusion(), Standard_False); } - if (aFace1U.ShapeType() != TopAbs_FACE || - aFace1V.ShapeType() != TopAbs_FACE) { - Standard_TypeMismatch::Raise("Sub-shape with given Id is not a face"); + } else if (aType == BLOCK_MULTI_TRANSFORM_1D || + aType == BLOCK_MULTI_TRANSFORM_2D) { + + TopoDS_Shape aMulti; + GEOMImpl_IBlockTrsf aCI (aFunction); + Handle(GEOM_Function) aRefShape = aCI.GetOriginal(); + TopoDS_Shape aBlockIni = aRefShape->GetValue(); + if (aBlockIni.IsNull()) { + Standard_NullObject::Raise("Null Block"); } - if (aFace2UId > 0) { - if (!GEOMImpl_ILocalOperations::GetSubShape(aBlock, aFace2UId, aFace2U)) { - Standard_NullObject::Raise("Can not retrieve a sub-shape with given Id"); + // Copy block to avoid problems (PAL6706) + TColStd_IndexedDataMapOfTransientTransient aMap; + TopoDS_Shape aBlock; + TNaming_CopyShape::CopyTool(aBlockIni, aMap, aBlock); + + // Block tolerance in vertices + Standard_Real aTol = prec; + TopExp_Explorer expV (aBlock, TopAbs_VERTEX); + TopTools_MapOfShape mapShape; + for (; expV.More(); expV.Next()) { + if (mapShape.Add(expV.Current())) { + TopoDS_Vertex aV = TopoDS::Vertex(expV.Current()); + aTol = Max(BRep_Tool::Tolerance(aV), aTol); } + } - if (aFace2U.ShapeType() != TopAbs_FACE) { + if (aType == BLOCK_MULTI_TRANSFORM_1D) { + // Retrieve a faces by Ids + Standard_Integer aFace1Id = aCI.GetFace1U(); + Standard_Integer aFace2Id = aCI.GetFace2U(); + TopoDS_Shape aFace1, aFace2; + if (!GEOMImpl_ILocalOperations::GetSubShape(aBlock, aFace1Id, aFace1)) { + Standard_NullObject::Raise("Can not retrieve a sub-shape with given Id"); + } + if (aFace1.ShapeType() != TopAbs_FACE) { Standard_TypeMismatch::Raise("Sub-shape with given Id is not a face"); } - } - if (aFace2VId > 0) { - if (!GEOMImpl_ILocalOperations::GetSubShape(aBlock, aFace2VId, aFace2V)) { + if (aFace2Id > 0) { + if (!GEOMImpl_ILocalOperations::GetSubShape(aBlock, aFace2Id, aFace2)) { + Standard_NullObject::Raise("Can not retrieve a sub-shape with given Id"); + } + if (aFace2.ShapeType() != TopAbs_FACE) { + Standard_TypeMismatch::Raise("Sub-shape with given Id is not a face"); + } + } + + Standard_Integer aNbIter = aCI.GetNbIterU(); + + MultiTransformate1D(aBlock, aFace1, aFace2, aNbIter, aMulti); + + } else { // aType == BLOCK_MULTI_TRANSFORM_2D + // Retrieve a faces by Ids + Standard_Integer aFace1UId = aCI.GetFace1U(); + Standard_Integer aFace2UId = aCI.GetFace2U(); + Standard_Integer aFace1VId = aCI.GetFace1V(); + Standard_Integer aFace2VId = aCI.GetFace2V(); + + TopoDS_Shape aFace1U, aFace2U, aFace1V, aFace2V; + if (!GEOMImpl_ILocalOperations::GetSubShape(aBlock, aFace1UId, aFace1U) || + !GEOMImpl_ILocalOperations::GetSubShape(aBlock, aFace1VId, aFace1V)) { Standard_NullObject::Raise("Can not retrieve a sub-shape with given Id"); } - if (aFace2V.ShapeType() != TopAbs_FACE) { + if (aFace1U.ShapeType() != TopAbs_FACE || + aFace1V.ShapeType() != TopAbs_FACE) { Standard_TypeMismatch::Raise("Sub-shape with given Id is not a face"); } - } - Standard_Integer aNbIterU = aCI.GetNbIterU(); - Standard_Integer aNbIterV = aCI.GetNbIterV(); + if (aFace2UId > 0) { + if (!GEOMImpl_ILocalOperations::GetSubShape(aBlock, aFace2UId, aFace2U)) { + Standard_NullObject::Raise("Can not retrieve a sub-shape with given Id"); + } - MultiTransformate2D(aBlock, - aFace1U, aFace2U, aNbIterU, - aFace1V, aFace2V, aNbIterV, aMulti); + if (aFace2U.ShapeType() != TopAbs_FACE) { + Standard_TypeMismatch::Raise("Sub-shape with given Id is not a face"); + } + } - } else { - return 0; - } + if (aFace2VId > 0) { + if (!GEOMImpl_ILocalOperations::GetSubShape(aBlock, aFace2VId, aFace2V)) { + Standard_NullObject::Raise("Can not retrieve a sub-shape with given Id"); + } - if (aMulti.IsNull()) { - StdFail_NotDone::Raise("Multi-transformation failed"); + if (aFace2V.ShapeType() != TopAbs_FACE) { + Standard_TypeMismatch::Raise("Sub-shape with given Id is not a face"); + } + } + + Standard_Integer aNbIterU = aCI.GetNbIterU(); + Standard_Integer aNbIterV = aCI.GetNbIterV(); + + MultiTransformate2D(aBlock, + aFace1U, aFace2U, aNbIterU, + aFace1V, aFace2V, aNbIterV, aMulti); + } + + if (aMulti.IsNull()) { + StdFail_NotDone::Raise("Multi-transformation failed"); + } + + // Glue faces of the multi-block + aShape = GEOMImpl_GlueDriver::GlueFaces(aMulti, aTol, Standard_False); + + } else { // unknown function type return 0; } - - // Glue faces of the multi-block - aShape = GEOMImpl_GlueDriver::GlueFaces(aMulti, aTol); } if (aShape.IsNull()) return 0; @@ -906,7 +1082,8 @@ Standard_EXPORT Handle_Standard_Type& GEOMImpl_BlockDriver_Type_() //function : DownCast //purpose : //======================================================================= -const Handle(GEOMImpl_BlockDriver) Handle(GEOMImpl_BlockDriver)::DownCast(const Handle(Standard_Transient)& AnObject) +const Handle(GEOMImpl_BlockDriver) Handle(GEOMImpl_BlockDriver)::DownCast + (const Handle(Standard_Transient)& AnObject) { Handle(GEOMImpl_BlockDriver) _anOtherObject; @@ -916,5 +1093,5 @@ const Handle(GEOMImpl_BlockDriver) Handle(GEOMImpl_BlockDriver)::DownCast(const } } - return _anOtherObject ; + return _anOtherObject; }