X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FGEOMImpl%2FGEOMImpl_GlueDriver.cxx;h=881fdab99d9cc38402bb5a87af68e3c7f7a7aac6;hb=d9b43f09413d444925291a882774de7893b0f2c4;hp=d9ed67437b8dd907d5296f93681de02e8044c942;hpb=e2dcf4323c7d7c36e8e1a4fda4dd6cf86c99be81;p=modules%2Fgeom.git diff --git a/src/GEOMImpl/GEOMImpl_GlueDriver.cxx b/src/GEOMImpl/GEOMImpl_GlueDriver.cxx index d9ed67437..881fdab99 100644 --- a/src/GEOMImpl/GEOMImpl_GlueDriver.cxx +++ b/src/GEOMImpl/GEOMImpl_GlueDriver.cxx @@ -1,3 +1,24 @@ +// Copyright (C) 2007-2011 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 @@ -8,7 +29,12 @@ #include #include -#include +//#include +//#include "GEOMAlgo_Gluer1.hxx" +#include "GEOMAlgo_Gluer2.hxx" +#include "GEOMAlgo_ListIteratorOfListOfCoupleOfShapes.hxx" +#include "GEOMAlgo_CoupleOfShapes.hxx" +#include "GEOMAlgo_ListOfCoupleOfShapes.hxx" #include "utilities.h" @@ -16,10 +42,13 @@ #include #include -#include +#include #include +#include #include +#include + #include #include @@ -48,8 +77,10 @@ const Standard_GUID& GEOMImpl_GlueDriver::GetID() //function : GlueFacesWithWarnings //purpose : //======================================================================= +/* TopoDS_Shape GEOMImpl_GlueDriver::GlueFacesWithWarnings (const TopoDS_Shape& theShape, const Standard_Real theTolerance, + const Standard_Boolean doKeepNonSolids, TCollection_AsciiString& theWarning) const { Standard_Integer iErr, iWrn; @@ -59,6 +90,7 @@ TopoDS_Shape GEOMImpl_GlueDriver::GlueFacesWithWarnings (const TopoDS_Shape& the aGluer.SetShape(theShape); aGluer.SetTolerance(theTolerance); aGluer.SetCheckGeometry(Standard_True); + aGluer.SetKeepNonSolids(doKeepNonSolids); aGluer.Perform(); @@ -120,6 +152,12 @@ TopoDS_Shape GEOMImpl_GlueDriver::GlueFacesWithWarnings (const TopoDS_Shape& the aRes = aGluer.Result(); + // SKL 18.01.2010 - patch for 20662 + Handle(ShapeFix_Shape) aSfs = new ShapeFix_Shape(aRes); + aSfs->SetPrecision(Precision::Confusion()); + aSfs->Perform(); + aRes = aSfs->Shape(); + // Fill history to be used by GetInPlace functionality TopTools_IndexedMapOfShape aResIndices; TopExp::MapShapes(aRes, aResIndices); @@ -173,19 +211,20 @@ TopoDS_Shape GEOMImpl_GlueDriver::GlueFacesWithWarnings (const TopoDS_Shape& the //purpose : //======================================================================= TopoDS_Shape GEOMImpl_GlueDriver::GlueFaces (const TopoDS_Shape& theShape, - const Standard_Real theTolerance) + const Standard_Real theTolerance, + const Standard_Boolean doKeepNonSolids) { - Standard_Integer iErr, iWrn; TopoDS_Shape aRes; GEOMAlgo_Gluer aGluer; aGluer.SetShape(theShape); aGluer.SetTolerance(theTolerance); aGluer.SetCheckGeometry(Standard_True); + aGluer.SetKeepNonSolids(doKeepNonSolids); aGluer.Perform(); - iErr = aGluer.ErrorStatus(); + Standard_Integer iErr = aGluer.ErrorStatus(); if (iErr) { switch (iErr) { case 2: @@ -212,7 +251,7 @@ TopoDS_Shape GEOMImpl_GlueDriver::GlueFaces (const TopoDS_Shape& theShape, return aRes; } - iWrn = aGluer.WarningStatus(); + Standard_Integer iWrn = aGluer.WarningStatus(); if (iWrn) { switch (iWrn) { case 1: @@ -230,6 +269,408 @@ TopoDS_Shape GEOMImpl_GlueDriver::GlueFaces (const TopoDS_Shape& theShape, return aRes; } +//======================================================================= +//function : GlueFacesByList +//purpose : +//======================================================================= +TopoDS_Shape GEOMImpl_GlueDriver::GlueFacesByList (const TopoDS_Shape& theShape, + const Standard_Real theTolerance, + const Standard_Boolean doKeepNonSolids, + const TopTools_MapOfShape& aFaces) +{ + TopoDS_Shape aRes; + + GEOMAlgo_Gluer1 aGluer; + GEOMAlgo_ListIteratorOfListOfCoupleOfShapes aItCS; + GEOMAlgo_CoupleOfShapes aCS; + GEOMAlgo_ListOfCoupleOfShapes aLCS; + + aGluer.SetShape(theShape); + aGluer.SetTolerance(theTolerance); + aGluer.SetKeepNonSolids(doKeepNonSolids); + aGluer.Perform(); + Standard_Integer iErr = aGluer.ErrorStatus(); + if (iErr) return aRes; + + TopTools_ListOfShape listShape; + const GEOMAlgo_ListOfCoupleOfShapes& aLCSG = aGluer.GluedFaces(); + // Access to faces + aItCS.Initialize(aLCSG); + for (; aItCS.More(); aItCS.Next()) { + const GEOMAlgo_CoupleOfShapes& aCSG = aItCS.Value(); + const TopoDS_Shape& aF1 = aCSG.Shape1(); + const TopoDS_Shape& aF2 = aCSG.Shape2(); + if (aFaces.Contains(aF1) || aFaces.Contains(aF2)) + continue; + aCS.SetShapes(aF1,aF2); + aLCS.Append(aCS); + } + + //cout<<"aLCS.Extent() = "<0) { + aGluer.SetFacesToUnglue(aLCS); + aGluer.UnglueFaces(); + iErr = aGluer.ErrorStatus(); + if (iErr) return aRes; + } + + aRes = aGluer.Result(); + + return aRes; +} +*/ + +//======================================================================= +//function : GlueFaces +//purpose : +//======================================================================= +TopoDS_Shape GEOMImpl_GlueDriver::GlueFaces (const TopoDS_Shape& theShape, + const Standard_Real theTolerance, + const Standard_Boolean doKeepNonSolids) +{ + TopoDS_Shape aRes; + + GEOMAlgo_Gluer2 aGA; + + // 1. Initialization + aGA.SetArgument(theShape); + aGA.SetTolerance(theTolerance); + aGA.SetKeepNonSolids(doKeepNonSolids); + + // 2. Detect interferred shapes + aGA.Detect(); + Standard_Integer iErr = aGA.ErrorStatus(); + if (iErr) { + switch (iErr) { + case 11: + Standard_Failure::Raise("GEOMAlgo_GlueDetector failed"); + break; + case 13: + case 14: + Standard_Failure::Raise("PerformImagesToWork failed"); + break; + default: + { + // description of all errors see in GEOMAlgo_Gluer2.cxx + TCollection_AsciiString aMsg ("Error in GEOMAlgo_Gluer2 with code "); + aMsg += TCollection_AsciiString(iErr); + Standard_Failure::Raise(aMsg.ToCString()); + break; + } + } + return aRes; + } + + // 3. Set shapes to glue. If the operator is absent, the whole gluing will be done + //aGA.SetShapesToGlue(aMSG); + + // 4. Gluing + aGA.Perform(); + iErr = aGA.ErrorStatus(); + if (iErr) { + switch (iErr) { + case 11: + Standard_Failure::Raise("GEOMAlgo_GlueDetector failed"); + break; + case 13: + case 14: + Standard_Failure::Raise("PerformImagesToWork failed"); + break; + default: + { + // description of all errors see in GEOMAlgo_Gluer2.cxx + TCollection_AsciiString aMsg ("Error in GEOMAlgo_Gluer2 with code "); + aMsg += TCollection_AsciiString(iErr); + Standard_Failure::Raise(aMsg.ToCString()); + break; + } + } + return aRes; + } + + Standard_Integer iWrn = aGA.WarningStatus(); + if (iWrn) { + switch (iWrn) { + case 1: + MESSAGE("No shapes to glue"); + break; + default: + // description of all warnings see in GEOMAlgo_Gluer2.cxx + MESSAGE("Warning in GEOMAlgo_Gluer2 with code " << iWrn); + break; + } + } + + // 5. Result + aRes = aGA.Shape(); + + return aRes; +} + +//======================================================================= +//function : GlueWithWarnings +//purpose : +//======================================================================= +TopoDS_Shape GEOMImpl_GlueDriver::GlueWithWarnings (const TopoDS_Shape& theShape, + const Standard_Real theTolerance, + const TopAbs_ShapeEnum theShapeType, + const Standard_Boolean doKeepNonSolids, + TCollection_AsciiString& theWarning) const +{ + TopoDS_Shape aRes; + + GEOMAlgo_Gluer2 aGA; + + // 1. Initialization + aGA.SetArgument(theShape); + aGA.SetTolerance(theTolerance); + aGA.SetKeepNonSolids(doKeepNonSolids); + + // 2. Detect interferred shapes + aGA.Detect(); + Standard_Integer iErr = aGA.ErrorStatus(); + if (iErr) { + switch (iErr) { + case 11: + Standard_Failure::Raise("GEOMAlgo_GlueDetector failed"); + break; + case 13: + case 14: + Standard_Failure::Raise("PerformImagesToWork failed"); + break; + default: + { + // description of all errors see in GEOMAlgo_Gluer2.cxx + TCollection_AsciiString aMsg ("Error in GEOMAlgo_Gluer2 with code "); + aMsg += TCollection_AsciiString(iErr); + Standard_Failure::Raise(aMsg.ToCString()); + break; + } + } + return aRes; + } + + if (theShapeType != TopAbs_FACE) { + // 3. Fill shapes to glue aMSG + TopTools_DataMapOfShapeListOfShape aMSG; + const TopTools_DataMapOfShapeListOfShape& aMSD = aGA.ShapesDetected(); + TopTools_DataMapIteratorOfDataMapOfShapeListOfShape aItMSD; + aItMSD.Initialize(aMSD); + for (; aItMSD.More(); aItMSD.Next()) { + const TopoDS_Shape& aSx = aItMSD.Key(); + const TopTools_ListOfShape& aLSD = aItMSD.Value(); + if (aSx.ShapeType() == theShapeType) { + aMSG.Bind(aSx, aLSD); + } + } + + // 4. Set shapes to glue. If the operator is absent, the whole gluing will be done + aGA.SetShapesToGlue(aMSG); + } + + // 5. Gluing + aGA.Perform(); + iErr = aGA.ErrorStatus(); + if (iErr) { + switch (iErr) { + case 11: + Standard_Failure::Raise("GEOMAlgo_GlueDetector failed"); + break; + case 13: + case 14: + Standard_Failure::Raise("PerformImagesToWork failed"); + break; + default: + { + // description of all errors see in GEOMAlgo_Gluer2.cxx + TCollection_AsciiString aMsg ("Error in GEOMAlgo_Gluer2 with code "); + aMsg += TCollection_AsciiString(iErr); + Standard_Failure::Raise(aMsg.ToCString()); + break; + } + } + return aRes; + } + + Standard_Integer iWrn = aGA.WarningStatus(); + if (iWrn) { + switch (iWrn) { + case 1: + theWarning = "No shapes to glue"; + break; + default: + // description of all warnings see in GEOMAlgo_Gluer2.cxx + theWarning = "Warning in GEOMAlgo_Gluer2 with code "; + theWarning += TCollection_AsciiString(iWrn); + break; + } + } + + // 6. Result + aRes = aGA.Shape(); + + // 7. Fill history to be used by GetInPlace functionality + TopTools_IndexedMapOfShape aResIndices; + TopExp::MapShapes(aRes, aResIndices); + + Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label()); + + // history for all argument shapes + TDF_LabelSequence aLabelSeq; + aFunction->GetDependency(aLabelSeq); + Standard_Integer nbArg = aLabelSeq.Length(); + + for (Standard_Integer iarg = 1; iarg <= nbArg; iarg++) { + + TDF_Label anArgumentRefLabel = aLabelSeq.Value(iarg); + + Handle(GEOM_Object) anArgumentObject = GEOM_Object::GetReferencedObject(anArgumentRefLabel); + TopoDS_Shape anArgumentShape = anArgumentObject->GetValue(); + + TopTools_IndexedMapOfShape anArgumentIndices; + TopExp::MapShapes(anArgumentShape, anArgumentIndices); + Standard_Integer nbArgumentEntities = anArgumentIndices.Extent(); + + // Find corresponding label in history + TDF_Label anArgumentHistoryLabel = + aFunction->GetArgumentHistoryEntry(anArgumentRefLabel, Standard_True); + + for (Standard_Integer ie = 1; ie <= nbArgumentEntities; ie++) { + TopoDS_Shape anEntity = anArgumentIndices.FindKey(ie); + const TopTools_ListOfShape& aModified = aGA.Modified(anEntity); + Standard_Integer nbModified = aModified.Extent(); + + if (nbModified > 0) { + TDF_Label aWhatHistoryLabel = anArgumentHistoryLabel.FindChild(ie, Standard_True); + Handle(TDataStd_IntegerArray) anAttr = + TDataStd_IntegerArray::Set(aWhatHistoryLabel, 1, nbModified); + + TopTools_ListIteratorOfListOfShape itM (aModified); + for (int im = 1; itM.More(); itM.Next(), ++im) { + int id = aResIndices.FindIndex(itM.Value()); + anAttr->SetValue(im, id); + } + } + } + } + + return aRes; +} + +//======================================================================= +//function : GlueByList +//purpose : +//======================================================================= +TopoDS_Shape GEOMImpl_GlueDriver::GlueByList (const TopoDS_Shape& theShape, + const Standard_Real theTolerance, + const Standard_Boolean doKeepNonSolids, + const TopTools_MapOfShape& theShapesList, + const Standard_Boolean doGlueAllEdges) +{ + TopoDS_Shape aRes; + + GEOMAlgo_Gluer2 aGA; + + // 1. Initialization + aGA.SetArgument(theShape); + aGA.SetTolerance(theTolerance); + aGA.SetKeepNonSolids(doKeepNonSolids); + + // 2. Detect interferred shapes + aGA.Detect(); + Standard_Integer iErr = aGA.ErrorStatus(); + if (iErr) { + switch (iErr) { + case 11: + Standard_Failure::Raise("GEOMAlgo_GlueDetector failed"); + break; + case 13: + case 14: + Standard_Failure::Raise("PerformImagesToWork failed"); + break; + default: + { + // description of all errors see in GEOMAlgo_Gluer2.cxx + TCollection_AsciiString aMsg ("Error in GEOMAlgo_Gluer2 with code "); + aMsg += TCollection_AsciiString(iErr); + Standard_Failure::Raise(aMsg.ToCString()); + break; + } + } + return aRes; + } + + // 3. Fill shapes to glue aMSG + TopTools_DataMapOfShapeListOfShape aMSG; + const TopTools_DataMapOfShapeListOfShape& aMSD = aGA.ShapesDetected(); + TopTools_DataMapIteratorOfDataMapOfShapeListOfShape aItMSD; + aItMSD.Initialize(aMSD); + for (; aItMSD.More(); aItMSD.Next()) { + const TopoDS_Shape& aSx = aItMSD.Key(); + const TopTools_ListOfShape& aLSD = aItMSD.Value(); + TopTools_ListIteratorOfListOfShape anItLSD (aLSD); + bool isToGlue = false; + if (doGlueAllEdges && aSx.ShapeType() == TopAbs_EDGE) { + isToGlue = true; + } + else { + for (; anItLSD.More() && !isToGlue; anItLSD.Next()) { + if (theShapesList.Contains(anItLSD.Value())) { + isToGlue = true; + } + } + } + if (isToGlue) { + aMSG.Bind(aSx, aLSD); + } + } + + // 4. Set shapes to glue. If the operator is absent, the whole gluing will be done + aGA.SetShapesToGlue(aMSG); + + // 5. Gluing + aGA.Perform(); + iErr = aGA.ErrorStatus(); + if (iErr) { + switch (iErr) { + case 11: + Standard_Failure::Raise("GEOMAlgo_GlueDetector failed"); + break; + case 13: + case 14: + Standard_Failure::Raise("PerformImagesToWork failed"); + break; + default: + { + // description of all errors see in GEOMAlgo_Gluer2.cxx + TCollection_AsciiString aMsg ("Error in GEOMAlgo_Gluer2 with code "); + aMsg += TCollection_AsciiString(iErr); + Standard_Failure::Raise(aMsg.ToCString()); + break; + } + } + return aRes; + } + + Standard_Integer iWrn = aGA.WarningStatus(); + if (iWrn) { + switch (iWrn) { + case 1: + MESSAGE("No shapes to glue"); + break; + default: + // description of all warnings see in GEOMAlgo_Gluer2.cxx + MESSAGE("Warning in GEOMAlgo_Gluer2 with code " << iWrn); + break; + } + } + + // 6. Result + aRes = aGA.Shape(); + + return aRes; +} + //======================================================================= //function : Execute //purpose : @@ -245,16 +686,47 @@ Standard_Integer GEOMImpl_GlueDriver::Execute(TFunction_Logbook& log) const TopoDS_Shape aShape; TCollection_AsciiString aWrn; + Handle(GEOM_Function) aRefBase = aCI.GetBase(); + TopoDS_Shape aShapeBase = aRefBase->GetValue(); + if (aShapeBase.IsNull()) { + Standard_NullObject::Raise("Shape for gluing is null"); + } + + Standard_Real tol3d = aCI.GetTolerance(); + + Standard_Boolean aKeepNonSolids = aCI.GetKeepNonSolids(); + if (aType == GLUE_FACES) { - Handle(GEOM_Function) aRefBase = aCI.GetBase(); - TopoDS_Shape aShapeBase = aRefBase->GetValue(); - if (aShapeBase.IsNull()) { - Standard_NullObject::Raise("Shape for gluing is null"); + //aShape = GlueFacesWithWarnings(aShapeBase, tol3d, aKeepNonSolids, aWrn); + aShape = GlueWithWarnings(aShapeBase, tol3d, TopAbs_FACE, aKeepNonSolids, aWrn); + } + else if (aType == GLUE_EDGES) { + aShape = GlueWithWarnings(aShapeBase, tol3d, TopAbs_EDGE, aKeepNonSolids, aWrn); + } + else if (aType == GLUE_FACES_BY_LIST || aType == GLUE_EDGES_BY_LIST) { + Handle(TColStd_HSequenceOfTransient) SF = aCI.GetFaces(); + TopTools_MapOfShape aFaces; + int i = 1; + for (; i <= SF->Length(); i++) { + Handle(Standard_Transient) anItem = SF->Value(i); + if (anItem.IsNull()) + continue; + Handle(GEOM_Function) aRefSh = Handle(GEOM_Function)::DownCast(anItem); + if (aRefSh.IsNull()) + continue; + TopoDS_Shape aFace = aRefSh->GetValue(); + if (aFace.IsNull()) + continue; + if (!aFaces.Contains(aFace)) + aFaces.Add(aFace); } - Standard_Real tol3d = aCI.GetTolerance(); - aShape = GlueFacesWithWarnings(aShapeBase, tol3d, aWrn); - } else { + Standard_Boolean aGlueAllEdges = Standard_False; + if (aType == GLUE_FACES_BY_LIST) + aGlueAllEdges = aCI.GetGlueAllEdges(); + + //aShape = GlueFacesByList(aShapeBase, tol3d, aKeepNonSolids, aFaces); + aShape = GlueByList(aShapeBase, tol3d, aKeepNonSolids, aFaces, aGlueAllEdges); } if (aShape.IsNull()) return 0; @@ -278,19 +750,19 @@ Standard_EXPORT Handle_Standard_Type& GEOMImpl_GlueDriver_Type_() { static Handle_Standard_Type aType1 = STANDARD_TYPE(TFunction_Driver); - if ( aType1.IsNull()) aType1 = STANDARD_TYPE(TFunction_Driver); + if (aType1.IsNull()) aType1 = STANDARD_TYPE(TFunction_Driver); static Handle_Standard_Type aType2 = STANDARD_TYPE(MMgt_TShared); - if ( aType2.IsNull()) aType2 = STANDARD_TYPE(MMgt_TShared); + if (aType2.IsNull()) aType2 = STANDARD_TYPE(MMgt_TShared); static Handle_Standard_Type aType3 = STANDARD_TYPE(Standard_Transient); - if ( aType3.IsNull()) aType3 = STANDARD_TYPE(Standard_Transient); + if (aType3.IsNull()) aType3 = STANDARD_TYPE(Standard_Transient); static Handle_Standard_Transient _Ancestors[]= {aType1,aType2,aType3,NULL}; static Handle_Standard_Type _aType = new Standard_Type("GEOMImpl_GlueDriver", - sizeof(GEOMImpl_GlueDriver), - 1, - (Standard_Address)_Ancestors, - (Standard_Address)NULL); + sizeof(GEOMImpl_GlueDriver), + 1, + (Standard_Address)_Ancestors, + (Standard_Address)NULL); return _aType; } @@ -309,5 +781,5 @@ const Handle(GEOMImpl_GlueDriver) Handle(GEOMImpl_GlueDriver)::DownCast(const Ha } } - return _anOtherObject ; + return _anOtherObject; }