Back to index

salome-geom  6.5.0
GEOMImpl_HealingDriver.cxx
Go to the documentation of this file.
00001 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
00002 //
00003 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
00004 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
00005 //
00006 // This library is free software; you can redistribute it and/or
00007 // modify it under the terms of the GNU Lesser General Public
00008 // License as published by the Free Software Foundation; either
00009 // version 2.1 of the License.
00010 //
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014 // Lesser General Public License for more details.
00015 //
00016 // You should have received a copy of the GNU Lesser General Public
00017 // License along with this library; if not, write to the Free Software
00018 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00019 //
00020 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00021 //
00022 
00023 #include <Standard_Stream.hxx>
00024 
00025 #include <GEOMImpl_HealingDriver.hxx>
00026 #include <GEOMImpl_Types.hxx>
00027 #include <GEOMImpl_IHealing.hxx>
00028 #include <GEOM_Function.hxx>
00029 
00030 #include <GEOMImpl_GlueDriver.hxx>
00031 
00032 #include <ShHealOper_ShapeProcess.hxx>
00033 #include <ShHealOper_RemoveFace.hxx>
00034 #include <ShHealOper_CloseContour.hxx>
00035 #include <ShHealOper_RemoveInternalWires.hxx>
00036 #include <ShHealOper_FillHoles.hxx>
00037 #include <ShHealOper_Sewing.hxx>
00038 #include <ShHealOper_EdgeDivide.hxx>
00039 #include <ShHealOper_ChangeOrientation.hxx>
00040 
00041 #include <BRep_Builder.hxx>
00042 
00043 #include <TopExp.hxx>
00044 #include <TopoDS.hxx>
00045 #include <TopoDS_Iterator.hxx>
00046 #include <TopTools_IndexedMapOfShape.hxx>
00047 
00048 #include <TColStd_IndexedDataMapOfTransientTransient.hxx>
00049 #include <TNaming_CopyShape.hxx>
00050 #include <ShapeFix_ShapeTolerance.hxx>
00051 #include <ShapeFix_Shape.hxx>
00052 #include <BRepCheck_Analyzer.hxx>
00053 
00054 #include <Precision.hxx>
00055 
00056 #include <StdFail_NotDone.hxx>
00057 
00058 //=======================================================================
00059 //function :  raiseNotDoneExeption
00060 //purpose  :  global function: forms error message and raises exeption
00061 //=======================================================================
00062 void raiseNotDoneExeption( const int theErrorStatus )
00063 {
00064   switch ( theErrorStatus )
00065   {
00066   case ShHealOper_NotError:           StdFail_NotDone::Raise( "ShHealOper_NotError_msg" );
00067   case ShHealOper_InvalidParameters:  StdFail_NotDone::Raise( "ShHealOper_InvalidParameters_msg" );
00068   case ShHealOper_ErrorExecution:
00069   default:                            StdFail_NotDone::Raise( "ShHealOper_ErrorExecution_msg" );
00070   }
00071 }
00072 
00073 //=======================================================================
00074 //function : GetID
00075 //purpose  :
00076 //=======================================================================
00077 const Standard_GUID& GEOMImpl_HealingDriver::GetID()
00078 {
00079   static Standard_GUID aHealingDriver("FF1BBB61-5D14-4df2-980B-3A668264EA16");
00080   return aHealingDriver;
00081 }
00082 
00083 //=======================================================================
00084 //function : GEOMImpl_HealingDriver
00085 //purpose  :
00086 //=======================================================================
00087 GEOMImpl_HealingDriver::GEOMImpl_HealingDriver()
00088 {
00089 }
00090 
00091 //=======================================================================
00092 //function : Execute
00093 //purpose  :
00094 //=======================================================================
00095 Standard_Integer GEOMImpl_HealingDriver::Execute(TFunction_Logbook& log) const
00096 {
00097   if (Label().IsNull()) return 0;
00098   Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());
00099 
00100   if (aFunction.IsNull()) return 0;
00101 
00102   GEOMImpl_IHealing HI (aFunction);
00103   Standard_Integer aType = aFunction->GetType();
00104   Handle(GEOM_Function) anOriginalFunction = HI.GetOriginal();
00105   if (anOriginalFunction.IsNull()) return 0;
00106   TopoDS_Shape aShape, anOriginalShape = anOriginalFunction->GetValue();
00107   if (anOriginalShape.IsNull()) return 0;
00108 
00109   switch (aType)
00110   {
00111   case SHAPE_PROCESS:
00112     ShapeProcess(&HI, anOriginalShape, aShape);
00113     break;
00114   case SUPPRESS_FACES:
00115     SuppressFaces(&HI, anOriginalShape, aShape);
00116     break;
00117   case CLOSE_CONTOUR:
00118     CloseContour(&HI, anOriginalShape, aShape);
00119     break;
00120   case REMOVE_INT_WIRES:
00121     RemoveIntWires(&HI, anOriginalShape, aShape);
00122     break;
00123   case FILL_HOLES:
00124     RemoveHoles(&HI, anOriginalShape, aShape);
00125     break;
00126   case SEWING:
00127     Sew(&HI, anOriginalShape, aShape);
00128     break;
00129   case DIVIDE_EDGE:
00130     AddPointOnEdge(&HI, anOriginalShape, aShape);
00131     break;
00132   case CHANGE_ORIENTATION:
00133     ChangeOrientation(&HI, anOriginalShape, aShape);
00134     break;
00135   case LIMIT_TOLERANCE:
00136     LimitTolerance(&HI, anOriginalShape, aShape);
00137     break;
00138   default:
00139     return 0;
00140   }
00141 
00142   if (aShape.IsNull())
00143     raiseNotDoneExeption( ShHealOper_ErrorExecution );
00144 
00145   aFunction->SetValue(aShape);
00146 
00147   log.SetTouched(Label());
00148   return 1;
00149 }
00150 
00151 //=======================================================================
00152 //function :  ShapeProcess
00153 //purpose  :
00154 //=======================================================================
00155 Standard_Boolean GEOMImpl_HealingDriver::ShapeProcess (GEOMImpl_IHealing* theHI,
00156                                                        const TopoDS_Shape& theOriginalShape,
00157                                                        TopoDS_Shape& theOutShape) const
00158 {
00159   Handle(TColStd_HArray1OfExtendedString) anOperators = theHI->GetOperators();
00160   Handle(TColStd_HArray1OfExtendedString) aParams = theHI->GetParameters();
00161   Handle(TColStd_HArray1OfExtendedString) aValues = theHI->GetValues();
00162 
00163   if (anOperators.IsNull() || anOperators->Length() <= 0)
00164     return Standard_False;
00165 
00166   Standard_Integer nbParams = 0, nbValues = 0;
00167   if (!aParams.IsNull()) {
00168     nbParams = aParams->Length();
00169   }
00170   if (!aValues.IsNull()) {
00171     nbValues = aValues->Length();
00172   }
00173   if (nbParams != nbValues)
00174     return Standard_False;
00175 
00176   ShHealOper_ShapeProcess aHealer;
00177   TColStd_SequenceOfAsciiString anOperatorsAS, aParamsAS, aValuesAS;
00178   int i;
00179   for (i = 1; i <= anOperators->Length(); i++)
00180     anOperatorsAS.Append(TCollection_AsciiString(anOperators->Value(i)));
00181 
00182   aHealer.SetOperators(anOperatorsAS);
00183 
00184   for (i = 1; i <= nbParams; i++) {
00185     aHealer.SetParameter(TCollection_AsciiString(aParams->Value(i)),
00186                          TCollection_AsciiString(aValues->Value(i)));
00187   }
00188 
00189   aHealer.Perform(theOriginalShape, theOutShape);
00190 
00191   if (!aHealer.isDone())
00192     raiseNotDoneExeption( ShHealOper_NotError );
00193 
00194   return Standard_True;
00195 }
00196 
00197 //=======================================================================
00198 //function :  SupressFaces
00199 //purpose  :
00200 //=======================================================================
00201 void SuppressFacesRec (const TopTools_SequenceOfShape& theShapesFaces,
00202                        const TopoDS_Shape&             theOriginalShape,
00203                        TopoDS_Shape&                   theOutShape)
00204 {
00205   if ((theOriginalShape.ShapeType() != TopAbs_COMPOUND &&
00206        theOriginalShape.ShapeType() != TopAbs_COMPSOLID))
00207   {
00208     ShHealOper_RemoveFace aHealer (theOriginalShape);
00209     Standard_Boolean aResult = aHealer.Perform(theShapesFaces);
00210 
00211     if (aResult)
00212       theOutShape = aHealer.GetResultShape();
00213     else
00214       raiseNotDoneExeption(aHealer.GetErrorStatus());
00215   }
00216   else
00217   {
00218     BRep_Builder BB;
00219     TopoDS_Compound CC;
00220     BB.MakeCompound(CC);
00221 
00222     TopTools_MapOfShape mapShape;
00223     TopoDS_Iterator It (theOriginalShape, Standard_True, Standard_True);
00224 
00225     for (; It.More(); It.Next()) {
00226       TopoDS_Shape aShape_i = It.Value();
00227       if (mapShape.Add(aShape_i)) {
00228         // check, if current shape contains at least one of faces to be removed
00229         bool isFound = false;
00230         TopTools_IndexedMapOfShape aShapes_i;
00231         TopExp::MapShapes(aShape_i, aShapes_i);
00232         for (int i = 1; i <= theShapesFaces.Length() && !isFound; i++) {
00233           const TopoDS_Shape& aFace_i = theShapesFaces.Value(i);
00234           if (aShapes_i.Contains(aFace_i)) isFound = true;
00235         }
00236         if (isFound) {
00237           TopoDS_Shape anOutSh_i;
00238           SuppressFacesRec(theShapesFaces, aShape_i, anOutSh_i);
00239           if ( !anOutSh_i.IsNull() )
00240             BB.Add(CC, anOutSh_i);
00241         }
00242         else {
00243           // nothing to do
00244           BB.Add(CC, aShape_i);
00245         }
00246       }
00247     }
00248     theOutShape = CC;
00249   }
00250 }
00251 
00252 Standard_Boolean GEOMImpl_HealingDriver::SuppressFaces (GEOMImpl_IHealing* theHI,
00253                                                         const TopoDS_Shape& theOriginalShape,
00254                                                         TopoDS_Shape& theOutShape) const
00255 {
00256   Handle(TColStd_HArray1OfInteger) aFaces = theHI->GetFaces();
00257 
00258   Standard_Boolean aResult = Standard_False;
00259 
00260   if (aFaces.IsNull()) {
00261     ShHealOper_RemoveFace aHealer (theOriginalShape);
00262     aResult = aHealer.Perform();
00263 
00264     if (aResult)
00265       theOutShape = aHealer.GetResultShape();
00266     else
00267       raiseNotDoneExeption(aHealer.GetErrorStatus());
00268   }
00269   else {
00270     TopTools_SequenceOfShape aShapesFaces;
00271     TopTools_IndexedMapOfShape aShapes;
00272     TopExp::MapShapes(theOriginalShape, aShapes);
00273     for (int i = 1; i <= aFaces->Length(); i++) {
00274       int indexOfFace = aFaces->Value(i);
00275       TopoDS_Shape aFace = aShapes.FindKey(indexOfFace);
00276       aShapesFaces.Append(aFace);
00277     }
00278     SuppressFacesRec(aShapesFaces, theOriginalShape, theOutShape);
00279     if ((theOriginalShape.ShapeType() == TopAbs_COMPOUND ||
00280          theOriginalShape.ShapeType() == TopAbs_COMPSOLID)) {
00281       TopoDS_Shape aSh = theOutShape;
00282       theOutShape = GEOMImpl_GlueDriver::GlueFaces(aSh, Precision::Confusion(), Standard_True);
00283     }
00284   }
00285 
00286   return Standard_True;
00287 }
00288 
00289 //=======================================================================
00290 //function :  CloseContour
00291 //purpose  :
00292 //=======================================================================
00293 Standard_Boolean GEOMImpl_HealingDriver::CloseContour (GEOMImpl_IHealing* theHI,
00294                                                        const TopoDS_Shape& theOriginalShape,
00295                                                        TopoDS_Shape& theOutShape) const
00296 {
00297   Standard_Boolean isByVertex = theHI->GetIsCommonVertex();
00298   Handle(TColStd_HArray1OfInteger) aWires = theHI->GetWires();
00299 
00300   ShHealOper_CloseContour aHealer (theOriginalShape);
00301 
00302   Standard_Boolean aResult = Standard_False;
00303   if ( aWires.IsNull() ) {
00304     if ( theOriginalShape.ShapeType() == TopAbs_WIRE )
00305       aResult = aHealer.Perform(TopoDS::Wire(theOriginalShape), isByVertex, !isByVertex);
00306   }
00307   else {
00308     TopTools_SequenceOfShape aShapesWires;
00309     TopTools_IndexedMapOfShape aShapes;
00310     TopExp::MapShapes(theOriginalShape, aShapes);
00311     for (int i = 1; i <= aWires->Length(); i++) {
00312       int indexOfWire = aWires->Value(i);
00313       TopoDS_Shape aWire = aShapes.FindKey(indexOfWire);
00314       aShapesWires.Append(aWire);
00315     }
00316 
00317     aResult = aHealer.Perform( aShapesWires, isByVertex, !isByVertex );
00318   }
00319 
00320   if (aResult)
00321     theOutShape = aHealer.GetResultShape();
00322   else
00323     raiseNotDoneExeption( aHealer.GetErrorStatus() );
00324 
00325   return aResult;
00326 }
00327 
00328 //=======================================================================
00329 //function :  RemoveIntWires
00330 //purpose  :
00331 //=======================================================================
00332 Standard_Boolean GEOMImpl_HealingDriver::RemoveIntWires (GEOMImpl_IHealing* theHI,
00333                                                          const TopoDS_Shape& theOriginalShape,
00334                                                          TopoDS_Shape& theOutShape) const
00335 {
00336   Handle(TColStd_HArray1OfInteger) aWires = theHI->GetWires();
00337 
00338   ShHealOper_RemoveInternalWires aHealer(theOriginalShape);
00339 
00340   Standard_Boolean aResult = Standard_False;
00341   if (aWires.IsNull()) { // remove all faces
00342     aResult = aHealer.Remove();
00343   } else {
00344     TopTools_SequenceOfShape aShapesWires;
00345     TopTools_IndexedMapOfShape aShapes;
00346     TopExp::MapShapes(theOriginalShape, aShapes);
00347     for (int i = 1; i <= aWires->Length(); i++) {
00348       int indexOfWire = aWires->Value(i);
00349       TopoDS_Shape aWire = aShapes.FindKey(indexOfWire);
00350       aShapesWires.Append(aWire);
00351     }
00352 
00353     aResult = aHealer.Remove(aShapesWires);
00354   }
00355 
00356   if (aResult)
00357     theOutShape = aHealer.GetResultShape();
00358   else
00359     raiseNotDoneExeption( aHealer.GetErrorStatus() );
00360 
00361   return aResult;
00362 }
00363 
00364 //=======================================================================
00365 //function :  RemoveHoles
00366 //purpose  :
00367 //=======================================================================
00368 Standard_Boolean GEOMImpl_HealingDriver::RemoveHoles (GEOMImpl_IHealing* theHI,
00369                                                       const TopoDS_Shape& theOriginalShape,
00370                                                       TopoDS_Shape& theOutShape) const
00371 {
00372   Handle(TColStd_HArray1OfInteger) aWires = theHI->GetWires();
00373 
00374   ShHealOper_FillHoles aHealer (theOriginalShape);
00375 
00376   Standard_Boolean aResult = Standard_False;
00377   if (aWires.IsNull()) { // remove all faces
00378     aResult = aHealer.Fill();
00379   } else {
00380     TopTools_SequenceOfShape aShapesWires;
00381     TopTools_IndexedMapOfShape aShapes;
00382     TopExp::MapShapes(theOriginalShape, aShapes);
00383     for (int i = 1; i <= aWires->Length(); i++) {
00384       int indexOfWire = aWires->Value(i);
00385       TopoDS_Shape aWire = aShapes.FindKey(indexOfWire);
00386       aShapesWires.Append(aWire);
00387     }
00388 
00389     aResult = aHealer.Fill(aShapesWires);
00390   }
00391 
00392   if (aResult)
00393     theOutShape = aHealer.GetResultShape();
00394   else
00395     raiseNotDoneExeption( aHealer.GetErrorStatus() );
00396 
00397   return aResult;
00398 }
00399 
00400 //=======================================================================
00401 //function :  Sew
00402 //purpose  :
00403 //=======================================================================
00404 Standard_Boolean GEOMImpl_HealingDriver::Sew (GEOMImpl_IHealing* theHI,
00405                                               const TopoDS_Shape& theOriginalShape,
00406                                               TopoDS_Shape& theOutShape) const
00407 {
00408   Standard_Real aTol = theHI->GetTolerance();
00409 
00410   ShHealOper_Sewing aHealer (theOriginalShape, aTol);
00411 
00412   Standard_Boolean aResult = aHealer.Perform();
00413 
00414   if (aResult)
00415     theOutShape = aHealer.GetResultShape();
00416   else
00417     raiseNotDoneExeption( aHealer.GetErrorStatus() );
00418 
00419   return aResult;
00420 }
00421 
00422 //=======================================================================
00423 //function :  AddPointOnEdge
00424 //purpose  :
00425 //=======================================================================
00426 Standard_Boolean GEOMImpl_HealingDriver::AddPointOnEdge (GEOMImpl_IHealing* theHI,
00427                                                          const TopoDS_Shape& theOriginalShape,
00428                                                          TopoDS_Shape& theOutShape) const
00429 {
00430   Standard_Boolean isByParameter = theHI->GetIsByParameter();
00431   Standard_Integer anIndex = theHI->GetIndex();
00432   Standard_Real aValue = theHI->GetDevideEdgeValue();
00433 
00434   ShHealOper_EdgeDivide aHealer (theOriginalShape);
00435 
00436   Standard_Boolean aResult = Standard_False;
00437   if (anIndex == -1) { // apply algorythm for the whole shape which is EDGE
00438     if (theOriginalShape.ShapeType() == TopAbs_EDGE)
00439       aResult = aHealer.Perform(TopoDS::Edge(theOriginalShape), aValue, isByParameter);
00440   } else {
00441     TopTools_IndexedMapOfShape aShapes;
00442     TopExp::MapShapes(theOriginalShape, aShapes);
00443     TopoDS_Shape aEdgeShape = aShapes.FindKey(anIndex);
00444     if (aEdgeShape.ShapeType() == TopAbs_EDGE)
00445       aResult = aHealer.Perform(TopoDS::Edge(aEdgeShape), aValue, isByParameter);
00446   }
00447 
00448   if (aResult)
00449     theOutShape = aHealer.GetResultShape();
00450   else
00451     raiseNotDoneExeption( aHealer.GetErrorStatus() );
00452 
00453   return aResult;
00454 }
00455 
00456 
00457 //=======================================================================
00458 //function :  ChangeOrientation
00459 //purpose  :
00460 //=======================================================================
00461 Standard_Boolean GEOMImpl_HealingDriver::ChangeOrientation (GEOMImpl_IHealing* theHI,
00462                                                             const TopoDS_Shape& theOriginalShape,
00463                                                             TopoDS_Shape& theOutShape) const
00464 {
00465   ShHealOper_ChangeOrientation aHealer (theOriginalShape);
00466 
00467   Standard_Boolean aResult = aHealer.Perform();
00468 
00469   if (aResult)
00470     theOutShape = aHealer.GetResultShape();
00471   else
00472     raiseNotDoneExeption( aHealer.GetErrorStatus() );
00473 
00474   return aResult;
00475 }
00476 
00477 //=======================================================================
00478 //function : LimitTolerance
00479 //purpose  :
00480 //=======================================================================
00481 void GEOMImpl_HealingDriver::LimitTolerance (GEOMImpl_IHealing* theHI,
00482                                              const TopoDS_Shape& theOriginalShape,
00483                                              TopoDS_Shape& theOutShape) const
00484 {
00485   Standard_Real aTol = theHI->GetTolerance();
00486   if (aTol < Precision::Confusion())
00487     aTol = Precision::Confusion();
00488 
00489   // 1. Make a copy to prevent the original shape changes.
00490   TopoDS_Shape aShapeCopy;
00491   TColStd_IndexedDataMapOfTransientTransient aMapTShapes;
00492   TNaming_CopyShape::CopyTool(theOriginalShape, aMapTShapes, aShapeCopy);
00493 
00494   // 2. Limit tolerance.
00495   ShapeFix_ShapeTolerance aSFT;
00496   aSFT.LimitTolerance(aShapeCopy, aTol, aTol, TopAbs_SHAPE);
00497 
00498   // 3. Fix obtained shape.
00499   Handle(ShapeFix_Shape) aSfs = new ShapeFix_Shape (aShapeCopy);
00500   aSfs->Perform();
00501   theOutShape = aSfs->Shape();
00502 
00503   BRepCheck_Analyzer ana (theOutShape, Standard_True);
00504   if (!ana.IsValid())
00505     StdFail_NotDone::Raise("Non valid shape result");
00506 }
00507 
00508 //=======================================================================
00509 //function :  GEOMImpl_HealingDriver_Type_
00510 //purpose  :
00511 //=======================================================================
00512 Standard_EXPORT Handle_Standard_Type& GEOMImpl_HealingDriver_Type_()
00513 {
00514 
00515   static Handle_Standard_Type aType1 = STANDARD_TYPE(TFunction_Driver);
00516   if ( aType1.IsNull()) aType1 = STANDARD_TYPE(TFunction_Driver);
00517   static Handle_Standard_Type aType2 = STANDARD_TYPE(MMgt_TShared);
00518   if ( aType2.IsNull()) aType2 = STANDARD_TYPE(MMgt_TShared);
00519   static Handle_Standard_Type aType3 = STANDARD_TYPE(Standard_Transient);
00520   if ( aType3.IsNull()) aType3 = STANDARD_TYPE(Standard_Transient);
00521 
00522 
00523   static Handle_Standard_Transient _Ancestors[]= {aType1,aType2,aType3,NULL};
00524   static Handle_Standard_Type _aType = new Standard_Type("GEOMImpl_HealingDriver",
00525                                                          sizeof(GEOMImpl_HealingDriver),
00526                                                          1,
00527                                                          (Standard_Address)_Ancestors,
00528                                                          (Standard_Address)NULL);
00529 
00530   return _aType;
00531 }
00532 
00533 //=======================================================================
00534 //function : DownCast
00535 //purpose  :
00536 //=======================================================================
00537 
00538 const Handle(GEOMImpl_HealingDriver) Handle(GEOMImpl_HealingDriver)::DownCast(const Handle(Standard_Transient)& AnObject)
00539 {
00540   Handle(GEOMImpl_HealingDriver) _anOtherObject;
00541 
00542   if (!AnObject.IsNull()) {
00543      if (AnObject->IsKind(STANDARD_TYPE(GEOMImpl_HealingDriver))) {
00544        _anOtherObject = Handle(GEOMImpl_HealingDriver)((Handle(GEOMImpl_HealingDriver)&)AnObject);
00545      }
00546   }
00547 
00548   return _anOtherObject;
00549 }