Back to index

salome-geom  6.5.0
GEOMImpl_IShapesOperations.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 //  File      : GEOMImpl_IShapesOperations.cxx
00024 //  Created   :
00025 //  Author    : modified by Lioka RAZAFINDRAZAKA (CEA) 22/06/2007
00026 //  Project   : SALOME
00027 
00028 #include <Standard_Stream.hxx>
00029 
00030 #include "GEOMImpl_IShapesOperations.hxx"
00031 
00032 #include "GEOMImpl_Types.hxx"
00033 
00034 #include "GEOMImpl_VectorDriver.hxx"
00035 #include "GEOMImpl_ShapeDriver.hxx"
00036 #include "GEOMImpl_CopyDriver.hxx"
00037 #include "GEOMImpl_GlueDriver.hxx"
00038 
00039 #include "GEOMImpl_IVector.hxx"
00040 #include "GEOMImpl_IShapes.hxx"
00041 #include "GEOMImpl_IGlue.hxx"
00042 
00043 #include "GEOMImpl_Block6Explorer.hxx"
00044 #include "GEOMImpl_IHealingOperations.hxx"
00045 
00046 #include <GEOMImpl_Gen.hxx>
00047 
00048 #include "GEOM_Function.hxx"
00049 #include "GEOM_ISubShape.hxx"
00050 #include "GEOM_PythonDump.hxx"
00051 
00052 #include "GEOMAlgo_ClsfBox.hxx"
00053 #include "GEOMAlgo_ClsfSolid.hxx"
00054 #include "GEOMAlgo_CoupleOfShapes.hxx"
00055 #include "GEOMAlgo_FinderShapeOn1.hxx"
00056 #include "GEOMAlgo_FinderShapeOnQuad.hxx"
00057 #include "GEOMAlgo_FinderShapeOn2.hxx"
00058 #include "GEOMAlgo_GetInPlace.hxx"
00059 #include "GEOMAlgo_GlueDetector.hxx"
00060 #include "GEOMAlgo_ListIteratorOfListOfCoupleOfShapes.hxx"
00061 #include "GEOMAlgo_ListOfCoupleOfShapes.hxx"
00062 
00063 #include <Basics_OCCTVersion.hxx>
00064 
00065 #include "utilities.h"
00066 #include "OpUtil.hxx"
00067 #include "Utils_ExceptHandlers.hxx"
00068 
00069 #include <TFunction_DriverTable.hxx>
00070 #include <TFunction_Driver.hxx>
00071 #include <TFunction_Logbook.hxx>
00072 #include <TDataStd_Integer.hxx>
00073 #include <TDataStd_IntegerArray.hxx>
00074 #include <TDataStd_ListIteratorOfListOfExtendedString.hxx>
00075 #include <TDF_Tool.hxx>
00076 
00077 #include <BRepExtrema_ExtCF.hxx>
00078 #include <BRepExtrema_DistShapeShape.hxx>
00079 
00080 #include <BRep_Tool.hxx>
00081 #include <BRep_Builder.hxx>
00082 #include <BRepTools.hxx>
00083 #include <BRepGProp.hxx>
00084 #include <BRepAdaptor_Curve.hxx>
00085 #include <BRepAdaptor_Surface.hxx>
00086 #include <BRepBndLib.hxx>
00087 #include <BRepMesh_IncrementalMesh.hxx>
00088 
00089 #include <TopAbs.hxx>
00090 #include <TopExp.hxx>
00091 #include <TopExp_Explorer.hxx>
00092 #include <TopLoc_Location.hxx>
00093 #include <TopoDS.hxx>
00094 #include <TopoDS_Shape.hxx>
00095 #include <TopoDS_Solid.hxx>
00096 #include <TopoDS_Face.hxx>
00097 #include <TopoDS_Edge.hxx>
00098 #include <TopoDS_Vertex.hxx>
00099 #include <TopoDS_Compound.hxx>
00100 #include <TopoDS_Iterator.hxx>
00101 #include <TopTools_Array1OfShape.hxx>
00102 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
00103 #include <TopTools_IndexedMapOfShape.hxx>
00104 #include <TopTools_ListIteratorOfListOfShape.hxx>
00105 #include <TopTools_MapOfShape.hxx>
00106 #include <TopTools_MapOfOrientedShape.hxx>
00107 
00108 #include <Geom_Surface.hxx>
00109 #include <Geom_Plane.hxx>
00110 #include <Geom_SphericalSurface.hxx>
00111 #include <Geom_CylindricalSurface.hxx>
00112 #include <GeomAdaptor_Surface.hxx>
00113 
00114 #include <GeomLib_Tool.hxx>
00115 #include <Geom2d_Curve.hxx>
00116 
00117 #include <Bnd_Box.hxx>
00118 #include <GProp_GProps.hxx>
00119 #include <TColStd_Array1OfReal.hxx>
00120 #include <TColStd_HArray1OfInteger.hxx>
00121 #include <TColStd_ListIteratorOfListOfInteger.hxx>
00122 #include <TColStd_ListOfInteger.hxx>
00123 #include <gp_Cylinder.hxx>
00124 #include <gp_Lin.hxx>
00125 #include <gp_Pnt.hxx>
00126 
00127 #include <vector>
00128 #include <algorithm>
00129 #include <functional>
00130 
00131 #include <Standard_NullObject.hxx>
00132 #include <Standard_Failure.hxx>
00133 #include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
00134 
00135 // Includes added for GetInPlace algorithm improvement
00136 
00137 #include <GEOMImpl_MeasureDriver.hxx>
00138 #include <GEOMImpl_IMeasure.hxx>
00139 #include <BRepBuilderAPI_MakeVertex.hxx>
00140 
00141 #include <BRepClass_FaceClassifier.hxx>
00142 #include <BRepClass3d_SolidClassifier.hxx>
00143 #include <Precision.hxx>
00144 
00145 #define STD_SORT_ALGO 1
00146 
00147 //=============================================================================
00151 //=============================================================================
00152 GEOMImpl_IShapesOperations::GEOMImpl_IShapesOperations (GEOM_Engine* theEngine, int theDocID)
00153 : GEOM_IOperations(theEngine, theDocID)
00154 {
00155   MESSAGE("GEOMImpl_IShapesOperations::GEOMImpl_IShapesOperations");
00156 }
00157 
00158 //=============================================================================
00162 //=============================================================================
00163 GEOMImpl_IShapesOperations::~GEOMImpl_IShapesOperations()
00164 {
00165   MESSAGE("GEOMImpl_IShapesOperations::~GEOMImpl_IShapesOperations");
00166 }
00167 
00168 //=============================================================================
00172 //=============================================================================
00173 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeEdge
00174                      (Handle(GEOM_Object) thePnt1, Handle(GEOM_Object) thePnt2)
00175 {
00176   SetErrorCode(KO);
00177 
00178   if (thePnt1.IsNull() || thePnt2.IsNull()) return NULL;
00179 
00180   //Add a new Edge object
00181   Handle(GEOM_Object) anEdge = GetEngine()->AddObject(GetDocID(), GEOM_EDGE);
00182 
00183   //Add a new Vector function
00184   Handle(GEOM_Function) aFunction =
00185     anEdge->AddFunction(GEOMImpl_VectorDriver::GetID(), VECTOR_TWO_PNT);
00186 
00187   //Check if the function is set correctly
00188   if (aFunction->GetDriverGUID() != GEOMImpl_VectorDriver::GetID()) return NULL;
00189 
00190   GEOMImpl_IVector aPI (aFunction);
00191 
00192   Handle(GEOM_Function) aRef1 = thePnt1->GetLastFunction();
00193   Handle(GEOM_Function) aRef2 = thePnt2->GetLastFunction();
00194   if (aRef1.IsNull() || aRef2.IsNull()) return NULL;
00195 
00196   aPI.SetPoint1(aRef1);
00197   aPI.SetPoint2(aRef2);
00198 
00199   //Compute the Edge value
00200   try {
00201 #if OCC_VERSION_LARGE > 0x06010000
00202     OCC_CATCH_SIGNALS;
00203 #endif
00204     if (!GetSolver()->ComputeFunction(aFunction)) {
00205       SetErrorCode("Vector driver failed");
00206       return NULL;
00207     }
00208   }
00209   catch (Standard_Failure) {
00210     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
00211     SetErrorCode(aFail->GetMessageString());
00212     return NULL;
00213   }
00214 
00215   //Make a Python command
00216   GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdge("
00217                                << thePnt1 << ", " << thePnt2 << ")";
00218 
00219   SetErrorCode(OK);
00220   return anEdge;
00221 }
00222 
00223 //=============================================================================
00227 //=============================================================================
00228 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeEdgeOnCurveByLength
00229                      (Handle(GEOM_Object) theRefCurve,
00230                       const Standard_Real theLength,
00231                       Handle(GEOM_Object) theStartPoint)
00232 {
00233   SetErrorCode(KO);
00234 
00235   if (theRefCurve.IsNull()) return NULL;
00236 
00237   //Add a new Edge object
00238   Handle(GEOM_Object) anEdge = GetEngine()->AddObject(GetDocID(), GEOM_EDGE);
00239 
00240   //Add a new Vector function
00241   Handle(GEOM_Function) aFunction =
00242     anEdge->AddFunction(GEOMImpl_ShapeDriver::GetID(), EDGE_CURVE_LENGTH);
00243 
00244   //Check if the function is set correctly
00245   if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
00246 
00247   GEOMImpl_IVector aPI (aFunction);
00248 
00249   Handle(GEOM_Function) aRef1 = theRefCurve->GetLastFunction();
00250   if (aRef1.IsNull()) return NULL;
00251   aPI.SetPoint1(aRef1);
00252 
00253   if (!theStartPoint.IsNull()) {
00254     Handle(GEOM_Function) aRef2 = theStartPoint->GetLastFunction();
00255     aPI.SetPoint2(aRef2);
00256   }
00257 
00258   aPI.SetParameter(theLength);
00259 
00260   //Compute the Edge value
00261   try {
00262 #if OCC_VERSION_LARGE > 0x06010000
00263     OCC_CATCH_SIGNALS;
00264 #endif
00265     if (!GetSolver()->ComputeFunction(aFunction)) {
00266       SetErrorCode("Vector driver failed");
00267       return NULL;
00268     }
00269   }
00270   catch (Standard_Failure) {
00271     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
00272     SetErrorCode(aFail->GetMessageString());
00273     return NULL;
00274   }
00275 
00276   //Make a Python command
00277   GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdgeOnCurveByLength("
00278                                << theRefCurve << ", " << theLength << ", " << theStartPoint << ")";
00279 
00280   SetErrorCode(OK);
00281   return anEdge;
00282 }
00283 
00284 //=============================================================================
00288 //=============================================================================
00289 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeEdgeWire
00290                     (Handle(GEOM_Object) theWire,
00291                      const Standard_Real theLinearTolerance,
00292                      const Standard_Real theAngularTolerance)
00293 {
00294   SetErrorCode(KO);
00295 
00296   if (theWire.IsNull()) return NULL;
00297 
00298   //Add a new Edge object
00299   Handle(GEOM_Object) anEdge = GetEngine()->AddObject(GetDocID(), GEOM_EDGE);
00300 
00301   //Add a new Vector function
00302   Handle(GEOM_Function) aFunction =
00303     anEdge->AddFunction(GEOMImpl_ShapeDriver::GetID(), EDGE_WIRE);
00304 
00305   //Check if the function is set correctly
00306   if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
00307 
00308   GEOMImpl_IShapes aCI (aFunction);
00309 
00310   Handle(GEOM_Function) aWire = theWire->GetLastFunction();
00311 
00312   if (aWire.IsNull()) return NULL;
00313 
00314   aCI.SetBase(aWire);
00315   aCI.SetTolerance(theLinearTolerance);
00316   aCI.SetAngularTolerance(theAngularTolerance);
00317 
00318   //Compute the Edge value
00319   try {
00320 #if OCC_VERSION_LARGE > 0x06010000
00321     OCC_CATCH_SIGNALS;
00322 #endif
00323     if (!GetSolver()->ComputeFunction(aFunction)) {
00324       SetErrorCode("Shape driver failed");
00325       return NULL;
00326     }
00327   }
00328   catch (Standard_Failure) {
00329     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
00330     SetErrorCode(aFail->GetMessageString());
00331     return NULL;
00332   }
00333 
00334   const double DEF_LIN_TOL = Precision::Confusion();
00335   const double DEF_ANG_TOL = Precision::Angular();
00336   //Make a Python command
00337   if ( theAngularTolerance == DEF_ANG_TOL ) {
00338     if ( theLinearTolerance == DEF_LIN_TOL )
00339       GEOM::TPythonDump(aFunction) << anEdge  << " = geompy.MakeEdgeWire("
00340                                    << theWire << ")";
00341     else
00342       GEOM::TPythonDump(aFunction) << anEdge  << " = geompy.MakeEdgeWire("
00343                                    << theWire << ", " << theLinearTolerance << ")";
00344   }
00345   else {
00346     GEOM::TPythonDump(aFunction) << anEdge  << " = geompy.MakeEdgeWire("
00347                                  << theWire << ", " << theLinearTolerance << ", "
00348                                  << theAngularTolerance << ")";
00349   }
00350 
00351   SetErrorCode(OK);
00352   return anEdge;
00353 }
00354 
00355 //=============================================================================
00359 //=============================================================================
00360 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeWire
00361                              (std::list<Handle(GEOM_Object)> theShapes,
00362                               const Standard_Real            theTolerance)
00363 {
00364   SetErrorCode(KO);
00365 
00366   //Add a new object
00367   Handle(GEOM_Object) aWire = GetEngine()->AddObject(GetDocID(), GEOM_WIRE);
00368 
00369   //Add a new function
00370   Handle(GEOM_Function) aFunction =
00371     aWire->AddFunction(GEOMImpl_ShapeDriver::GetID(), WIRE_EDGES);
00372   if (aFunction.IsNull()) return NULL;
00373 
00374   //Check if the function is set correctly
00375   if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
00376 
00377   GEOMImpl_IShapes aCI (aFunction);
00378   aCI.SetTolerance(theTolerance);
00379 
00380   Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
00381 
00382   // Shapes
00383   std::list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
00384   for (; it != theShapes.end(); it++) {
00385     Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
00386     if (aRefSh.IsNull()) {
00387       SetErrorCode("NULL argument shape for the shape construction");
00388       return NULL;
00389     }
00390     aShapesSeq->Append(aRefSh);
00391   }
00392   aCI.SetShapes(aShapesSeq);
00393 
00394   //Compute the shape
00395   try {
00396 #if OCC_VERSION_LARGE > 0x06010000
00397     OCC_CATCH_SIGNALS;
00398 #endif
00399     if (!GetSolver()->ComputeFunction(aFunction)) {
00400       SetErrorCode("Shape driver failed");
00401       return NULL;
00402     }
00403   }
00404   catch (Standard_Failure) {
00405     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
00406     SetErrorCode(aFail->GetMessageString());
00407     return NULL;
00408   }
00409 
00410   //Make a Python command
00411   GEOM::TPythonDump pd (aFunction);
00412   pd << aWire << " = geompy.MakeWire([";
00413 
00414   // Shapes
00415   it = theShapes.begin();
00416   if (it != theShapes.end()) {
00417     pd << (*it++);
00418     while (it != theShapes.end()) {
00419       pd << ", " << (*it++);
00420     }
00421   }
00422   pd << "], " << theTolerance << ")";
00423 
00424   SetErrorCode(OK);
00425   return aWire;
00426 }
00427 
00428 //=============================================================================
00432 //=============================================================================
00433 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFace (Handle(GEOM_Object) theWire,
00434                                                           const bool isPlanarWanted)
00435 {
00436   SetErrorCode(KO);
00437 
00438   if (theWire.IsNull()) return NULL;
00439 
00440   //Add a new Face object
00441   Handle(GEOM_Object) aFace = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
00442 
00443   //Add a new Shape function for creation of a face from a wire
00444   Handle(GEOM_Function) aFunction =
00445     aFace->AddFunction(GEOMImpl_ShapeDriver::GetID(), FACE_WIRE);
00446   if (aFunction.IsNull()) return NULL;
00447 
00448   //Check if the function is set correctly
00449   if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
00450 
00451   GEOMImpl_IShapes aCI (aFunction);
00452 
00453   Handle(GEOM_Function) aRefWire = theWire->GetLastFunction();
00454 
00455   if (aRefWire.IsNull()) return NULL;
00456 
00457   aCI.SetBase(aRefWire);
00458   aCI.SetIsPlanar(isPlanarWanted);
00459 
00460   //Compute the Face value
00461   Standard_Boolean isWarning = Standard_False;
00462   try {
00463 #if OCC_VERSION_LARGE > 0x06010000
00464     OCC_CATCH_SIGNALS;
00465 #endif
00466     if (!GetSolver()->ComputeFunction(aFunction)) {
00467       SetErrorCode("Shape driver failed to compute a face");
00468       return NULL;
00469     }
00470   }
00471   catch (Standard_Failure) {
00472     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
00473     SetErrorCode(aFail->GetMessageString());
00474     // to provide warning
00475     if (!aFunction->GetValue().IsNull()) {
00476       isWarning = Standard_True;
00477     } else {
00478       return NULL;
00479     }
00480   }
00481 
00482   //Make a Python command
00483   GEOM::TPythonDump(aFunction) << aFace << " = geompy.MakeFace("
00484     << theWire << ", " << (int)isPlanarWanted << ")";
00485 
00486   // to provide warning
00487   if (!isWarning) SetErrorCode(OK);
00488   return aFace;
00489 }
00490 
00491 //=============================================================================
00495 //=============================================================================
00496 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFaceWires
00497                              (std::list<Handle(GEOM_Object)> theShapes,
00498                               const bool isPlanarWanted)
00499 {
00500   SetErrorCode(KO);
00501 
00502   //Add a new object
00503   Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
00504 
00505   //Add a new function
00506   Handle(GEOM_Function) aFunction =
00507     aShape->AddFunction(GEOMImpl_ShapeDriver::GetID(), FACE_WIRES);
00508   if (aFunction.IsNull()) return NULL;
00509 
00510   //Check if the function is set correctly
00511   if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
00512 
00513   GEOMImpl_IShapes aCI (aFunction);
00514 
00515   Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
00516 
00517   // Shapes
00518   std::list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
00519   for (; it != theShapes.end(); it++) {
00520     Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
00521     if (aRefSh.IsNull()) {
00522       SetErrorCode("NULL argument shape for the face construction");
00523       return NULL;
00524     }
00525     aShapesSeq->Append(aRefSh);
00526   }
00527   aCI.SetShapes(aShapesSeq);
00528 
00529   aCI.SetIsPlanar(isPlanarWanted);
00530 
00531   //Compute the shape
00532   Standard_Boolean isWarning = Standard_False;
00533   try {
00534 #if OCC_VERSION_LARGE > 0x06010000
00535     OCC_CATCH_SIGNALS;
00536 #endif
00537     if (!GetSolver()->ComputeFunction(aFunction)) {
00538       SetErrorCode("Shape driver failed");
00539       return NULL;
00540     }
00541   }
00542   catch (Standard_Failure) {
00543     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
00544     SetErrorCode(aFail->GetMessageString());
00545     // to provide warning
00546     if (!aFunction->GetValue().IsNull()) {
00547       isWarning = Standard_True;
00548     } else {
00549       return NULL;
00550     }
00551   }
00552 
00553   //Make a Python command
00554   GEOM::TPythonDump pd (aFunction);
00555   pd << aShape << " = geompy.MakeFaceWires([";
00556 
00557   // Shapes
00558   it = theShapes.begin();
00559   if (it != theShapes.end()) {
00560     pd << (*it++);
00561     while (it != theShapes.end()) {
00562       pd << ", " << (*it++);
00563     }
00564   }
00565   pd << "], " << (int)isPlanarWanted << ")";
00566 
00567   // to provide warning
00568   if (!isWarning) SetErrorCode(OK);
00569   return aShape;
00570 }
00571 
00572 //=============================================================================
00576 //=============================================================================
00577 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeShell
00578                              (std::list<Handle(GEOM_Object)> theShapes)
00579 {
00580   return MakeShape(theShapes, GEOM_SHELL, SHELL_FACES, "MakeShell");
00581 }
00582 
00583 //=============================================================================
00587 //=============================================================================
00588 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeSolidShells
00589                              (std::list<Handle(GEOM_Object)> theShapes)
00590 {
00591   return MakeShape(theShapes, GEOM_SOLID, SOLID_SHELLS, "MakeSolid");
00592 }
00593 
00594 //=============================================================================
00598 //=============================================================================
00599 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeCompound
00600                              (std::list<Handle(GEOM_Object)> theShapes)
00601 {
00602   return MakeShape(theShapes, GEOM_COMPOUND, COMPOUND_SHAPES, "MakeCompound");
00603 }
00604 
00605 //=============================================================================
00609 //=============================================================================
00610 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeShape
00611                              (std::list<Handle(GEOM_Object)> theShapes,
00612                               const Standard_Integer         theObjectType,
00613                               const Standard_Integer         theFunctionType,
00614                               const TCollection_AsciiString& theMethodName)
00615 {
00616   SetErrorCode(KO);
00617 
00618   //Add a new object
00619   Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), theObjectType);
00620 
00621   //Add a new function
00622   Handle(GEOM_Function) aFunction =
00623     aShape->AddFunction(GEOMImpl_ShapeDriver::GetID(), theFunctionType);
00624   if (aFunction.IsNull()) return NULL;
00625 
00626   //Check if the function is set correctly
00627   if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
00628 
00629   GEOMImpl_IShapes aCI (aFunction);
00630 
00631   Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
00632 
00633   // Shapes
00634   std::list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
00635   for (; it != theShapes.end(); it++) {
00636     Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
00637     if (aRefSh.IsNull()) {
00638       SetErrorCode("NULL argument shape for the shape construction");
00639       return NULL;
00640     }
00641     aShapesSeq->Append(aRefSh);
00642   }
00643   aCI.SetShapes(aShapesSeq);
00644 
00645   //Compute the shape
00646   try {
00647 #if OCC_VERSION_LARGE > 0x06010000
00648     OCC_CATCH_SIGNALS;
00649 #endif
00650     if (!GetSolver()->ComputeFunction(aFunction)) {
00651       SetErrorCode("Shape driver failed");
00652       return NULL;
00653     }
00654   }
00655   catch (Standard_Failure) {
00656     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
00657     SetErrorCode(aFail->GetMessageString());
00658     return NULL;
00659   }
00660 
00661   //Make a Python command
00662   GEOM::TPythonDump pd (aFunction);
00663   pd << aShape << " = geompy." << theMethodName.ToCString() << "([";
00664 
00665   // Shapes
00666   it = theShapes.begin();
00667   if (it != theShapes.end()) {
00668     pd << (*it++);
00669     while (it != theShapes.end()) {
00670       pd << ", " << (*it++);
00671     }
00672   }
00673   pd << "])";
00674 
00675   SetErrorCode(OK);
00676   return aShape;
00677 }
00678 
00679 //=============================================================================
00683 //=============================================================================
00684 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeGlueFaces
00685                                                 (Handle(GEOM_Object) theShape,
00686                                                  const Standard_Real theTolerance,
00687                                                  const Standard_Boolean doKeepNonSolids)
00688 {
00689   SetErrorCode(KO);
00690 
00691   if (theShape.IsNull()) return NULL;
00692 
00693   //Add a new Glued object
00694   Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
00695 
00696   //Add a new Glue function
00697   Handle(GEOM_Function) aFunction;
00698   aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_FACES);
00699   if (aFunction.IsNull()) return NULL;
00700 
00701   //Check if the function is set correctly
00702   if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
00703 
00704   GEOMImpl_IGlue aCI (aFunction);
00705 
00706   Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
00707   if (aRefShape.IsNull()) return NULL;
00708 
00709   aCI.SetBase(aRefShape);
00710   aCI.SetTolerance(theTolerance);
00711   aCI.SetKeepNonSolids(doKeepNonSolids);
00712 
00713   //Compute the sub-shape value
00714   Standard_Boolean isWarning = Standard_False;
00715   try {
00716 #if OCC_VERSION_LARGE > 0x06010000
00717     OCC_CATCH_SIGNALS;
00718 #endif
00719     if (!GetSolver()->ComputeFunction(aFunction)) {
00720       SetErrorCode("Shape driver failed to glue faces");
00721       return NULL;
00722     }
00723   }
00724   catch (Standard_Failure) {
00725     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
00726     SetErrorCode(aFail->GetMessageString());
00727     // to provide warning
00728     if (!aFunction->GetValue().IsNull()) {
00729       isWarning = Standard_True;
00730     } else {
00731       return NULL;
00732     }
00733   }
00734 
00735   //Make a Python command
00736   GEOM::TPythonDump(aFunction) << aGlued << " = geompy.MakeGlueFaces("
00737     << theShape << ", " << theTolerance << ")";
00738 
00739   // to provide warning
00740   if (!isWarning) SetErrorCode(OK);
00741   return aGlued;
00742 }
00743 
00744 //=============================================================================
00748 //=============================================================================
00749 /*
00750 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetGlueFaces
00751                                                 (Handle(GEOM_Object) theShape,
00752                                                  const Standard_Real theTolerance)
00753 {
00754   SetErrorCode(KO);
00755 
00756   if (theShape.IsNull()) return NULL;
00757   TopoDS_Shape aShape = theShape->GetValue();
00758   if (aShape.IsNull()) return NULL;
00759 
00760   Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
00761 
00762   Standard_Integer iErr;
00763   TopoDS_Shape aS;
00764   GEOMAlgo_Gluer1 aGluer;
00765   GEOMAlgo_ListIteratorOfListOfCoupleOfShapes aItCS;
00766   GEOMAlgo_CoupleOfShapes aCS;
00767   GEOMAlgo_ListOfCoupleOfShapes aLCS;
00768 
00769   //aGluer = new GEOMAlgo_Gluer1;
00770   aGluer.SetShape(aShape);
00771   aGluer.SetTolerance(theTolerance);
00772   aGluer.Perform();
00773   iErr = aGluer.ErrorStatus();
00774   if (iErr) return NULL;
00775 
00776   TopTools_ListOfShape listShape;
00777   const GEOMAlgo_ListOfCoupleOfShapes& aLCSG = aGluer.GluedFaces();
00778   // Access to faces
00779   aItCS.Initialize(aLCSG);
00780   for (; aItCS.More(); aItCS.Next()) {
00781     const GEOMAlgo_CoupleOfShapes& aCSG = aItCS.Value();
00782     listShape.Append(aCSG.Shape1());
00783   }
00784 
00785   TopTools_ListIteratorOfListOfShape itSub (listShape);
00786   TCollection_AsciiString anAsciiList, anEntry;
00787   TopTools_IndexedMapOfShape anIndices;
00788   TopExp::MapShapes(aShape, anIndices);
00789   Handle(TColStd_HArray1OfInteger) anArray;
00790   Handle(GEOM_Object) anObj;
00791   for (int index = 1; itSub.More(); itSub.Next(), ++index) {
00792     TopoDS_Shape aValue = itSub.Value();
00793     anArray = new TColStd_HArray1OfInteger(1,1);
00794     anArray->SetValue(1, anIndices.FindIndex(aValue));
00795     anObj = GetEngine()->AddSubShape(theShape, anArray);
00796     if (!anObj.IsNull()) {
00797       aSeq->Append(anObj);
00798 
00799       // for python command
00800       TDF_Tool::Entry(anObj->GetEntry(), anEntry);
00801       anAsciiList += anEntry;
00802       anAsciiList += ",";
00803     }
00804   }
00805 
00806   //Make a Python command
00807   if( anAsciiList.Length() > 0 ) {
00808     anAsciiList.Trunc(anAsciiList.Length() - 1);
00809     Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
00810     GEOM::TPythonDump pd (aFunction, true);
00811     pd << "[" << anAsciiList.ToCString();
00812     pd << "] = geompy.GetGlueFaces(" << theShape << ", " << theTolerance << ")";
00813   }
00814 
00815   SetErrorCode(OK);
00816 
00817   return aSeq;
00818 }
00819 */
00820 
00821 //=============================================================================
00825 //=============================================================================
00826 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeGlueFacesByList
00827                                                 (Handle(GEOM_Object) theShape,
00828                                                  const Standard_Real theTolerance,
00829                                                  std::list<Handle(GEOM_Object)> theFaces,
00830                                                  const Standard_Boolean doKeepNonSolids,
00831                                                  const Standard_Boolean doGlueAllEdges)
00832 {
00833   SetErrorCode(KO);
00834 
00835   if (theShape.IsNull()) return NULL;
00836 
00837   //Add a new Glued object
00838   Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
00839 
00840   //Add a new Glue function
00841   Handle(GEOM_Function) aFunction;
00842   aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_FACES_BY_LIST);
00843   if (aFunction.IsNull()) return NULL;
00844 
00845   //Check if the function is set correctly
00846   if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
00847 
00848   GEOMImpl_IGlue aCI (aFunction);
00849 
00850   Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
00851   if (aRefShape.IsNull()) return NULL;
00852 
00853   aCI.SetBase(aRefShape);
00854   aCI.SetTolerance(theTolerance);
00855   aCI.SetKeepNonSolids(doKeepNonSolids);
00856   aCI.SetGlueAllEdges(doGlueAllEdges);
00857 
00858   Handle(TColStd_HSequenceOfTransient) aFaces = new TColStd_HSequenceOfTransient;
00859   std::list<Handle(GEOM_Object)>::iterator it = theFaces.begin();
00860   for (; it != theFaces.end(); it++) {
00861     Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
00862     if (aRefSh.IsNull()) {
00863       SetErrorCode("NULL argument shape for the shape construction");
00864       return NULL;
00865     }
00866     aFaces->Append(aRefSh);
00867   }
00868   aCI.SetFaces(aFaces);
00869 
00870   //Compute the sub-shape value
00871   Standard_Boolean isWarning = Standard_False;
00872   try {
00873 #if OCC_VERSION_LARGE > 0x06010000
00874     OCC_CATCH_SIGNALS;
00875 #endif
00876     if (!GetSolver()->ComputeFunction(aFunction)) {
00877       SetErrorCode("Shape driver failed to glue faces");
00878       return NULL;
00879     }
00880   }
00881   catch (Standard_Failure) {
00882     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
00883     SetErrorCode(aFail->GetMessageString());
00884     // to provide warning
00885     if (!aFunction->GetValue().IsNull()) {
00886       isWarning = Standard_True;
00887     } else {
00888       return NULL;
00889     }
00890   }
00891 
00892   //Make a Python command
00893 
00894   GEOM::TPythonDump pd(aFunction);
00895   pd << aGlued << " = geompy.MakeGlueFacesByList("
00896      << theShape << ", " << theTolerance << ", [";
00897   // Faces
00898   it = theFaces.begin();
00899   if (it != theFaces.end()) {
00900     pd << (*it++);
00901     while (it != theFaces.end()) {
00902       pd << ", " << (*it++);
00903     }
00904   }
00905   pd << "], " << (bool)doKeepNonSolids << ", " << (bool)doGlueAllEdges << ")";
00906 
00907   // to provide warning
00908   if (!isWarning) SetErrorCode(OK);
00909   return aGlued;
00910 }
00911 
00912 //=============================================================================
00916 //=============================================================================
00917 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeGlueEdges
00918                                                 (Handle(GEOM_Object) theShape,
00919                                                  const Standard_Real theTolerance)
00920 {
00921   SetErrorCode(KO);
00922 
00923   if (theShape.IsNull()) return NULL;
00924 
00925   //Add a new Glued object
00926   Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
00927 
00928   //Add a new Glue function
00929   Handle(GEOM_Function) aFunction;
00930   aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_EDGES);
00931   if (aFunction.IsNull()) return NULL;
00932 
00933   //Check if the function is set correctly
00934   if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
00935 
00936   GEOMImpl_IGlue aCI (aFunction);
00937 
00938   Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
00939   if (aRefShape.IsNull()) return NULL;
00940 
00941   aCI.SetBase(aRefShape);
00942   aCI.SetTolerance(theTolerance);
00943   aCI.SetKeepNonSolids(true);
00944 
00945   //Compute the sub-shape value
00946   Standard_Boolean isWarning = Standard_False;
00947   try {
00948 #if OCC_VERSION_LARGE > 0x06010000
00949     OCC_CATCH_SIGNALS;
00950 #endif
00951     if (!GetSolver()->ComputeFunction(aFunction)) {
00952       SetErrorCode("Shape driver failed to glue edges");
00953       return NULL;
00954     }
00955   }
00956   catch (Standard_Failure) {
00957     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
00958     SetErrorCode(aFail->GetMessageString());
00959     // to provide warning
00960     if (!aFunction->GetValue().IsNull()) {
00961       isWarning = Standard_True;
00962     } else {
00963       return NULL;
00964     }
00965   }
00966 
00967   //Make a Python command
00968   GEOM::TPythonDump(aFunction) << aGlued << " = geompy.MakeGlueEdges("
00969     << theShape << ", " << theTolerance << ")";
00970 
00971   // to provide warning
00972   if (!isWarning) SetErrorCode(OK);
00973   return aGlued;
00974 }
00975 
00976 //=============================================================================
00980 //=============================================================================
00981 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetGlueShapes
00982                                                 (Handle(GEOM_Object)    theShape,
00983                                                  const Standard_Real    theTolerance,
00984                                                  const TopAbs_ShapeEnum theType)
00985 {
00986   SetErrorCode(KO);
00987 
00988   if (theShape.IsNull()) return NULL;
00989   TopoDS_Shape aShape = theShape->GetValue();
00990   if (aShape.IsNull()) return NULL;
00991 
00992   Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
00993 
00994   GEOMAlgo_GlueDetector aGluer;
00995   aGluer.SetArgument(aShape);
00996   aGluer.SetTolerance(theTolerance);
00997   aGluer.Perform();
00998   Standard_Integer iErr = aGluer.ErrorStatus();
00999   if (iErr) return NULL;
01000 
01001   TCollection_AsciiString anAsciiList, anEntry;
01002   TopTools_IndexedMapOfShape anIndices;
01003   TopExp::MapShapes(aShape, anIndices);
01004   Handle(TColStd_HArray1OfInteger) anArray;
01005   Handle(GEOM_Object) anObj;
01006 
01007   TopTools_ListOfShape listOnePerSet;
01008 
01009   const TopTools_DataMapOfShapeListOfShape& aImages = aGluer.Images();
01010   TopTools_DataMapIteratorOfDataMapOfShapeListOfShape aItDMSLS (aImages);
01011   for (int index = 1; aItDMSLS.More(); aItDMSLS.Next(), ++index) {
01012     // some key shape
01013     //const TopoDS_Shape& aSkey = aItDMSLS.Key();  
01014 
01015     // list of shapes of the argument that can be glued
01016     const TopTools_ListOfShape& aLSD = aItDMSLS.Value(); 
01017 
01018     //listShape.Append(aLSD.First());
01019     TopoDS_Shape aValue = aLSD.First();
01020 
01021     if (aValue.ShapeType() == theType) {
01022       listOnePerSet.Append(aValue);
01023     }
01024   }
01025 
01026   // for stable order of returned entities
01027   GEOMImpl_IShapesOperations::SortShapes(listOnePerSet, Standard_False);
01028 
01029   TopTools_ListIteratorOfListOfShape aListIt (listOnePerSet);
01030   for (; aListIt.More(); aListIt.Next()) {
01031     TopoDS_Shape aValue = aListIt.Value();
01032     anArray = new TColStd_HArray1OfInteger(1,1);
01033     anArray->SetValue(1, anIndices.FindIndex(aValue));
01034     anObj = GetEngine()->AddSubShape(theShape, anArray);
01035     if (!anObj.IsNull()) {
01036       aSeq->Append(anObj);
01037 
01038       // for python command
01039       TDF_Tool::Entry(anObj->GetEntry(), anEntry);
01040       anAsciiList += anEntry;
01041       anAsciiList += ",";
01042     }
01043   }
01044 
01045   // Make a Python command
01046   if (anAsciiList.Length() > 0) {
01047     anAsciiList.Trunc(anAsciiList.Length() - 1);
01048     Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
01049     GEOM::TPythonDump pd (aFunction, /*append=*/true);
01050     pd << "[" << anAsciiList.ToCString();
01051     if (theType == TopAbs_FACE)
01052       pd << "] = geompy.GetGlueFaces(" << theShape << ", " << theTolerance << ")";
01053     else if (theType == TopAbs_EDGE)
01054       pd << "] = geompy.GetGlueEdges(" << theShape << ", " << theTolerance << ")";
01055   }
01056 
01057   SetErrorCode(OK);
01058 
01059   return aSeq;
01060 }
01061 
01062 //=============================================================================
01066 //=============================================================================
01067 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeGlueEdgesByList
01068                                                 (Handle(GEOM_Object) theShape,
01069                                                  const Standard_Real theTolerance,
01070                                                  std::list<Handle(GEOM_Object)> theEdges)
01071 {
01072   SetErrorCode(KO);
01073 
01074   if (theShape.IsNull()) return NULL;
01075 
01076   //Add a new Glued object
01077   Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
01078 
01079   //Add a new Glue function
01080   Handle(GEOM_Function) aFunction;
01081   aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_EDGES_BY_LIST);
01082   if (aFunction.IsNull()) return NULL;
01083 
01084   //Check if the function is set correctly
01085   if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
01086 
01087   GEOMImpl_IGlue aCI (aFunction);
01088 
01089   Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
01090   if (aRefShape.IsNull()) return NULL;
01091 
01092   aCI.SetBase(aRefShape);
01093   aCI.SetTolerance(theTolerance);
01094   aCI.SetKeepNonSolids(true);
01095 
01096   Handle(TColStd_HSequenceOfTransient) anEdges = new TColStd_HSequenceOfTransient;
01097   std::list<Handle(GEOM_Object)>::iterator it = theEdges.begin();
01098   for (; it != theEdges.end(); it++) {
01099     Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
01100     if (aRefSh.IsNull()) {
01101       SetErrorCode("NULL argument shape for the shape construction");
01102       return NULL;
01103     }
01104     anEdges->Append(aRefSh);
01105   }
01106   aCI.SetFaces(anEdges);
01107 
01108   //Compute the sub-shape value
01109   Standard_Boolean isWarning = Standard_False;
01110   try {
01111 #if OCC_VERSION_LARGE > 0x06010000
01112     OCC_CATCH_SIGNALS;
01113 #endif
01114     if (!GetSolver()->ComputeFunction(aFunction)) {
01115       SetErrorCode("Shape driver failed to glue edges");
01116       return NULL;
01117     }
01118   }
01119   catch (Standard_Failure) {
01120     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
01121     SetErrorCode(aFail->GetMessageString());
01122     // to provide warning
01123     if (!aFunction->GetValue().IsNull()) {
01124       isWarning = Standard_True;
01125     } else {
01126       return NULL;
01127     }
01128   }
01129 
01130   //Make a Python command
01131 
01132   GEOM::TPythonDump pd (aFunction);
01133   pd << aGlued << " = geompy.MakeGlueEdgesByList("
01134      << theShape << ", " << theTolerance << ", [";
01135   // Edges
01136   it = theEdges.begin();
01137   if (it != theEdges.end()) {
01138     pd << (*it++);
01139     while (it != theEdges.end()) {
01140       pd << ", " << (*it++);
01141     }
01142   }
01143   pd << "])";
01144 
01145   // to provide warning
01146   if (!isWarning) SetErrorCode(OK);
01147   return aGlued;
01148 }
01149 
01150 //=============================================================================
01154 //=============================================================================
01155 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetExistingSubObjects
01156                                           (Handle(GEOM_Object)    theShape,
01157                                            const Standard_Boolean theGroupsOnly)
01158 {
01159   SetErrorCode(KO);
01160 
01161   if (theShape.IsNull()) return NULL;
01162 
01163   Handle(GEOM_Function) aMainShape = theShape->GetLastFunction();
01164   if (aMainShape.IsNull()) return NULL;
01165 
01166   Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
01167   SetErrorCode(NOT_FOUND_ANY);
01168 
01169   if (!aMainShape->HasSubShapeReferences()) return aSeq;
01170   const TDataStd_ListOfExtendedString& aListEntries = aMainShape->GetSubShapeReferences();
01171   if (aListEntries.IsEmpty()) return aSeq;
01172 
01173   SetErrorCode(KO);
01174 
01175   TCollection_AsciiString anAsciiList;
01176 
01177   TDataStd_ListIteratorOfListOfExtendedString anIt (aListEntries);
01178   for (; anIt.More(); anIt.Next()) {
01179     TCollection_ExtendedString anEntry = anIt.Value();
01180     Standard_Integer aStrLen = anEntry.LengthOfCString();
01181     char* anEntryStr = new char[aStrLen];
01182     anEntry.ToUTF8CString(anEntryStr);
01183     Handle(GEOM_Object) anObj = GetEngine()->GetObject(GetDocID(), anEntryStr, false);
01184     if (!anObj.IsNull()) {
01185       if (!theGroupsOnly || anObj->GetType() == GEOM_GROUP) {
01186         aSeq->Append(anObj);
01187 
01188         // for python command
01189         anAsciiList += anEntryStr;
01190         anAsciiList += ",";
01191       }
01192     }
01193     delete [] anEntryStr;
01194   }
01195 
01196   if (aSeq->Length() == 0) {
01197     SetErrorCode(NOT_FOUND_ANY);
01198     return aSeq;
01199   }
01200 
01201   //Make a Python command
01202   anAsciiList.Trunc(anAsciiList.Length() - 1);
01203 
01204   GEOM::TPythonDump pd (aMainShape, /*append=*/true);
01205   pd << "[" << anAsciiList.ToCString();
01206   pd << "] = geompy.GetExistingSubObjects(";
01207   pd << theShape << ", " << (bool)theGroupsOnly << ")";
01208 
01209   SetErrorCode(OK);
01210 
01211   return aSeq;
01212 }
01213 
01214 //=============================================================================
01218 //=============================================================================
01219 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::MakeExplode
01220                                           (Handle(GEOM_Object)    theShape,
01221                                            const Standard_Integer theShapeType,
01222                                            const Standard_Boolean isSorted,
01223                                            const ExplodeType      theExplodeType)
01224 {
01225   SetErrorCode(KO);
01226 
01227   if (theShape.IsNull()) return NULL;
01228   TopoDS_Shape aShape = theShape->GetValue();
01229   if (aShape.IsNull()) return NULL;
01230 
01231   Handle(GEOM_Function) aMainShape = theShape->GetLastFunction();
01232 
01233   Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
01234   Handle(GEOM_Object) anObj;
01235   TopTools_MapOfShape mapShape;
01236   TopTools_ListOfShape listShape;
01237 
01238   if (aShape.ShapeType() == TopAbs_COMPOUND &&
01239       (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
01240        TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPSOLID ||
01241        TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPOUND))
01242   {
01243     TopoDS_Iterator It (aShape, Standard_True, Standard_True);
01244     for (; It.More(); It.Next()) {
01245       if (mapShape.Add(It.Value())) {
01246         if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
01247             TopAbs_ShapeEnum(theShapeType) == It.Value().ShapeType()) {
01248           listShape.Append(It.Value());
01249         }
01250       }
01251     }
01252   }
01253   else if (theExplodeType != EXPLODE_NEW_EXCLUDE_MAIN || aShape.ShapeType() != theShapeType) // issue 0021079
01254   {
01255     TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
01256     for (; exp.More(); exp.Next())
01257       if (mapShape.Add(exp.Current()))
01258         listShape.Append(exp.Current());
01259   }
01260 
01261   if (listShape.IsEmpty()) {
01262     //SetErrorCode("The given shape has no sub-shapes of the requested type");
01263     SetErrorCode(NOT_FOUND_ANY); // NPAL18017
01264     return aSeq;
01265   }
01266 
01267   if (isSorted) {
01268     bool isOldSorting = false;
01269     if (theExplodeType == EXPLODE_OLD_INCLUDE_MAIN)
01270       isOldSorting = true;
01271     SortShapes(listShape, isOldSorting);
01272   }
01273 
01274   TopTools_IndexedMapOfShape anIndices;
01275   TopExp::MapShapes(aShape, anIndices);
01276   Handle(TColStd_HArray1OfInteger) anArray;
01277 
01278   TopTools_ListIteratorOfListOfShape itSub (listShape);
01279   TCollection_AsciiString anAsciiList, anEntry;
01280   for (int index = 1; itSub.More(); itSub.Next(), ++index)
01281   {
01282     TopoDS_Shape aValue = itSub.Value();
01283     anArray = new TColStd_HArray1OfInteger(1,1);
01284     anArray->SetValue(1, anIndices.FindIndex(aValue));
01285 
01286     //anObj = GetEngine()->AddSubShape(theShape, anArray);
01287     {
01288       anObj = GetEngine()->AddObject(GetDocID(), GEOM_SUBSHAPE);
01289       Handle(GEOM_Function) aFunction = anObj->AddFunction(GEOM_Object::GetSubShapeID(), 1);
01290       if (aFunction.IsNull()) return aSeq;
01291 
01292       GEOM_ISubShape aSSI (aFunction);
01293       aSSI.SetMainShape(aMainShape);
01294       aSSI.SetIndices(anArray);
01295 
01296       // Set function value directly, as we know it.
01297       // Usage of Solver here would lead to significant loss of time,
01298       // because GEOM_SubShapeDriver will build TopTools_IndexedMapOfShape
01299       // on the main shape for each being calculated sub-shape separately.
01300       aFunction->SetValue(aValue);
01301 
01302       // Put this subshape in the list of sub-shapes of theMainShape
01303       aMainShape->AddSubShapeReference(aFunction);
01304     }
01305 
01306     if (!anObj.IsNull()) {
01307       aSeq->Append(anObj);
01308 
01309       // for python command
01310       TDF_Tool::Entry(anObj->GetEntry(), anEntry);
01311       anAsciiList += anEntry;
01312       anAsciiList += ",";
01313     }
01314   }
01315 
01316   //Make a Python command
01317   anAsciiList.Trunc(anAsciiList.Length() - 1);
01318 
01319   GEOM::TPythonDump pd (aMainShape, /*append=*/true);
01320   pd << "[" << anAsciiList.ToCString() << "] = geompy.";
01321   switch (theExplodeType) {
01322   case EXPLODE_NEW_EXCLUDE_MAIN:
01323     pd << "ExtractShapes(" << theShape << ", "
01324        << TopAbs_ShapeEnum(theShapeType) << ", " << (isSorted ? "True" : "False") << ")";
01325     break;
01326   case EXPLODE_NEW_INCLUDE_MAIN:
01327     pd << "SubShapeAll" << (isSorted ? "SortedCentres(" : "(")
01328        << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
01329     break;
01330   case EXPLODE_OLD_INCLUDE_MAIN:
01331     pd << "SubShapeAll" << (isSorted ? "Sorted(" : "(")
01332        << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
01333     break;
01334   default: ;
01335   }
01336   SetErrorCode(OK);
01337 
01338   return aSeq;
01339 }
01340 
01341 //=============================================================================
01345 //=============================================================================
01346 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::SubShapeAllIDs
01347                                           (Handle(GEOM_Object)    theShape,
01348                                            const Standard_Integer theShapeType,
01349                                            const Standard_Boolean isSorted,
01350                                            const ExplodeType      theExplodeType)
01351 {
01352   SetErrorCode(KO);
01353 
01354   if (theShape.IsNull()) return NULL;
01355   TopoDS_Shape aShape = theShape->GetValue();
01356   if (aShape.IsNull()) return NULL;
01357 
01358   Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
01359   TopTools_MapOfShape mapShape;
01360   TopTools_ListOfShape listShape;
01361 
01362   if (aShape.ShapeType() == TopAbs_COMPOUND &&
01363       (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
01364        TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPSOLID ||
01365        TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPOUND))
01366   {
01367     TopoDS_Iterator It (aShape, Standard_True, Standard_True);
01368     for (; It.More(); It.Next()) {
01369       if (mapShape.Add(It.Value())) {
01370         if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
01371             TopAbs_ShapeEnum(theShapeType) == It.Value().ShapeType()) {
01372           listShape.Append(It.Value());
01373         }
01374       }
01375     }
01376   }
01377   else if (theExplodeType != EXPLODE_NEW_EXCLUDE_MAIN || aShape.ShapeType() != theShapeType) // issue 0021079
01378   {
01379     TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
01380     for (; exp.More(); exp.Next())
01381       if (mapShape.Add(exp.Current()))
01382         listShape.Append(exp.Current());
01383   }
01384 
01385   if (listShape.IsEmpty()) {
01386     //SetErrorCode("The given shape has no sub-shapes of the requested type");
01387     SetErrorCode(NOT_FOUND_ANY); // NPAL18017
01388     return aSeq;
01389   }
01390 
01391   if (isSorted) {
01392     bool isOldSorting = false;
01393     if (theExplodeType == EXPLODE_OLD_INCLUDE_MAIN)
01394       isOldSorting = true;
01395     SortShapes(listShape, isOldSorting);
01396   }
01397 
01398   TopTools_IndexedMapOfShape anIndices;
01399   TopExp::MapShapes(aShape, anIndices);
01400   Handle(TColStd_HArray1OfInteger) anArray;
01401 
01402   TopTools_ListIteratorOfListOfShape itSub (listShape);
01403   for (int index = 1; itSub.More(); itSub.Next(), ++index) {
01404     TopoDS_Shape aValue = itSub.Value();
01405     aSeq->Append(anIndices.FindIndex(aValue));
01406   }
01407 
01408   Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
01409 
01410   //Make a Python command
01411   GEOM::TPythonDump pd (aFunction, /*append=*/true);
01412   pd << "listSubShapeIDs = geompy.SubShapeAll";
01413   switch (theExplodeType) {
01414   case EXPLODE_NEW_EXCLUDE_MAIN:
01415     break;
01416   case EXPLODE_NEW_INCLUDE_MAIN:
01417     pd << (isSorted ? "SortedCentresIDs(" : "IDs(")
01418        << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
01419     break;
01420   case EXPLODE_OLD_INCLUDE_MAIN:
01421     pd << (isSorted ? "SortedIDs(" : "IDs(")
01422        << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
01423     break;
01424   default: ;
01425   }
01426 
01427   SetErrorCode(OK);
01428   return aSeq;
01429 }
01430 
01431 //=============================================================================
01435 //=============================================================================
01436 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetSubShape
01437                                           (Handle(GEOM_Object)    theMainShape,
01438                                            const Standard_Integer theID)
01439 {
01440   SetErrorCode(KO);
01441 
01442   if (theMainShape.IsNull()) return NULL;
01443 
01444   Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
01445   anArray->SetValue(1, theID);
01446   Handle(GEOM_Object) anObj = GetEngine()->AddSubShape(theMainShape, anArray,true);
01447   if (anObj.IsNull()) {
01448     SetErrorCode("Can not get a sub-shape with the given ID");
01449     return NULL;
01450   }
01451 
01452   Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
01453 
01454   //Make a Python command
01455   GEOM::TPythonDump(aFunction) << anObj << " = geompy.GetSubShape("
01456                                << theMainShape << ", [" << theID << "])";
01457 
01458   SetErrorCode(OK);
01459   return anObj;
01460 }
01461 
01462 //=============================================================================
01466 //=============================================================================
01467 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::MakeSubShapes
01468                                 (Handle(GEOM_Object)              theMainShape,
01469                                  Handle(TColStd_HArray1OfInteger) theIndices)
01470 {
01471   SetErrorCode(KO);
01472 
01473   Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
01474 
01475   if (!theIndices->Length()) {
01476     SetErrorCode(NOT_FOUND_ANY);
01477     return aSeq;
01478   }
01479 
01480   if (theMainShape.IsNull()) return NULL;
01481   TopoDS_Shape aShape = theMainShape->GetValue();
01482   if (aShape.IsNull()) return NULL;
01483 
01484   Handle(GEOM_Function) aMainShape = theMainShape->GetLastFunction();
01485 
01486   TopTools_IndexedMapOfShape anIndices;
01487   TopExp::MapShapes(aShape, anIndices);
01488 
01489   Handle(TColStd_HArray1OfInteger) anArray;
01490   Handle(GEOM_Object) anObj;
01491 
01492   TCollection_AsciiString anAsciiList, anEntry;
01493   Standard_Integer i, low = theIndices->Lower(), up = theIndices->Upper();
01494   for (i = low; i <= up; i++) {
01495     int id = theIndices->Value(i);
01496     if (1 <= id && id <= anIndices.Extent()) {
01497       TopoDS_Shape aValue = anIndices.FindKey(id);
01498       anArray = new TColStd_HArray1OfInteger(1,1);
01499       anArray->SetValue(1, id);
01500 
01501       anObj = GetEngine()->AddObject(GetDocID(), GEOM_SUBSHAPE);
01502       if (!anObj.IsNull()) {
01503         Handle(GEOM_Function) aFunction = anObj->AddFunction(GEOM_Object::GetSubShapeID(), 1);
01504         if (aFunction.IsNull()) return aSeq;
01505 
01506         GEOM_ISubShape aSSI (aFunction);
01507         aSSI.SetMainShape(aMainShape);
01508         aSSI.SetIndices(anArray);
01509 
01510         // Set function value directly, as we know it.
01511         // Usage of Solver here would lead to significant loss of time,
01512         // because GEOM_SubShapeDriver will build TopTools_IndexedMapOfShape
01513         // on the main shape for each being calculated sub-shape separately.
01514         aFunction->SetValue(aValue);
01515 
01516         // Put this sub-shape in the list of sub-shapes of theMainShape
01517         aMainShape->AddSubShapeReference(aFunction);
01518 
01519         aSeq->Append(anObj);
01520 
01521         // for python command
01522         TDF_Tool::Entry(anObj->GetEntry(), anEntry);
01523         anAsciiList += anEntry;
01524         anAsciiList += ",";
01525       }
01526     }
01527   }
01528 
01529   //Make a Python command
01530   anAsciiList.Trunc(anAsciiList.Length() - 1);
01531 
01532   GEOM::TPythonDump pd (aMainShape, /*append=*/true);
01533   pd << "[" << anAsciiList.ToCString() << "] = geompy.SubShapes("
01534      << theMainShape << ", [" ;
01535   for (i = low; i <= up - 1; i++) {
01536     pd << theIndices->Value(i) << ", ";
01537   }
01538   pd << theIndices->Value(up) << "])";
01539 
01540   SetErrorCode(OK);
01541 
01542   return aSeq;
01543 }
01544 
01545 //=============================================================================
01549 //=============================================================================
01550 Standard_Integer GEOMImpl_IShapesOperations::GetSubShapeIndex (Handle(GEOM_Object) theMainShape,
01551                                                                Handle(GEOM_Object) theSubShape)
01552 {
01553   SetErrorCode(KO);
01554 
01555   TopoDS_Shape aMainShape = theMainShape->GetValue();
01556   TopoDS_Shape aSubShape = theSubShape->GetValue();
01557 
01558   if (aMainShape.IsNull() || aSubShape.IsNull()) return -1;
01559 
01560   TopTools_IndexedMapOfShape anIndices;
01561   TopExp::MapShapes(aMainShape, anIndices);
01562   if (anIndices.Contains(aSubShape)) {
01563     SetErrorCode(OK);
01564     return anIndices.FindIndex(aSubShape);
01565   }
01566 
01567   return -1;
01568 }
01569 
01570 //=============================================================================
01574 //=============================================================================
01575 Standard_Integer GEOMImpl_IShapesOperations::GetTopologyIndex (Handle(GEOM_Object) theMainShape,
01576                                                                Handle(GEOM_Object) theSubShape)
01577 {
01578   SetErrorCode(OK);
01579 
01580   TopoDS_Shape aMainShape = theMainShape->GetValue();
01581   TopoDS_Shape aSubShape = theSubShape->GetValue();
01582 
01583   if (aMainShape.IsNull() || aSubShape.IsNull()) {
01584     SetErrorCode("Null argument shape given");
01585     return -1;
01586   }
01587 
01588   int index = 1;
01589   if (aSubShape.ShapeType() == TopAbs_COMPOUND) {
01590     TopoDS_Iterator it;
01591     TopTools_ListOfShape CL;
01592     CL.Append(aMainShape);
01593     TopTools_ListIteratorOfListOfShape itC;
01594     for (itC.Initialize(CL); itC.More(); itC.Next()) {
01595       for (it.Initialize(itC.Value()); it.More(); it.Next()) {
01596         if (it.Value().ShapeType() == TopAbs_COMPOUND) {
01597           if (it.Value().IsSame(aSubShape))
01598             return index;
01599           else
01600             index++;
01601           CL.Append(it.Value());
01602         }
01603       }
01604     }
01605   } else {
01606     TopExp_Explorer anExp (aMainShape, aSubShape.ShapeType());
01607     TopTools_MapOfShape M;
01608     for (; anExp.More(); anExp.Next()) {
01609       if (M.Add(anExp.Current())) {
01610         if (anExp.Current().IsSame(aSubShape))
01611           return index;
01612         index++;
01613       }
01614     }
01615   }
01616 
01617   SetErrorCode("The sub-shape does not belong to the main shape");
01618   return -1;
01619 }
01620 
01621 //=============================================================================
01625 //=============================================================================
01626 TCollection_AsciiString GEOMImpl_IShapesOperations::GetShapeTypeString (Handle(GEOM_Object) theShape)
01627 {
01628   SetErrorCode(KO);
01629 
01630   TCollection_AsciiString aTypeName ("Null Shape");
01631 
01632   TopoDS_Shape aShape = theShape->GetValue();
01633   if (aShape.IsNull())
01634     return aTypeName;
01635 
01636   switch (aShape.ShapeType() )
01637   {
01638   case TopAbs_COMPOUND:
01639     aTypeName = "Compound";
01640     break;
01641   case  TopAbs_COMPSOLID:
01642     aTypeName = "Compound Solid";
01643     break;
01644   case TopAbs_SOLID:
01645     aTypeName = "Solid";
01646     break;
01647   case TopAbs_SHELL:
01648     aTypeName = "Shell";
01649     break;
01650   case TopAbs_FACE:
01651     {
01652       BRepAdaptor_Surface surf (TopoDS::Face(aShape));
01653       if (surf.GetType() == GeomAbs_Plane)
01654         aTypeName = "Plane";
01655       else if (surf.GetType() == GeomAbs_Cylinder)
01656         aTypeName = "Cylindrical Face";
01657       else if (surf.GetType() == GeomAbs_Sphere)
01658         aTypeName = "Spherical Face";
01659       else if (surf.GetType() == GeomAbs_Torus)
01660         aTypeName = "Toroidal Face";
01661       else if (surf.GetType() == GeomAbs_Cone)
01662         aTypeName = "Conical Face";
01663       else
01664         aTypeName = "GEOM::FACE";
01665     }
01666     break;
01667   case TopAbs_WIRE:
01668     aTypeName = "Wire";
01669     break;
01670   case TopAbs_EDGE:
01671     {
01672       BRepAdaptor_Curve curv (TopoDS::Edge(aShape));
01673       if (curv.GetType() == GeomAbs_Line) {
01674         if ((Abs(curv.FirstParameter()) >= 1E6) ||
01675             (Abs(curv.LastParameter()) >= 1E6))
01676           aTypeName = "Line";
01677         else
01678           aTypeName = "Edge";
01679       } else if (curv.GetType() == GeomAbs_Circle) {
01680         if (curv.IsClosed())
01681           aTypeName = "Circle";
01682         else
01683           aTypeName = "Arc";
01684       } else {
01685         aTypeName = "Edge";
01686       }
01687     }
01688     break;
01689   case TopAbs_VERTEX:
01690     aTypeName = "Vertex";
01691     break;
01692   case TopAbs_SHAPE:
01693     aTypeName = "Shape";
01694     break;
01695   default:
01696     aTypeName = "Shape of unknown type";
01697   }
01698 
01699   return aTypeName;
01700 }
01701 
01702 //=============================================================================
01706 //=============================================================================
01707 Standard_Integer GEOMImpl_IShapesOperations::NumberOfSubShapes
01708                                           (Handle(GEOM_Object)    theShape,
01709                                            const Standard_Integer theShapeType)
01710 {
01711   SetErrorCode(KO);
01712   Standard_Integer nbShapes = 0;
01713 
01714   if (theShape.IsNull()) return -1;
01715   TopoDS_Shape aShape = theShape->GetValue();
01716   if (aShape.IsNull()) return -1;
01717 
01718   /*
01719   TopTools_MapOfShape mapShape;
01720 
01721   if (aShape.ShapeType() == TopAbs_COMPOUND &&
01722       (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
01723        TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPSOLID ||
01724        TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPOUND)) {
01725     TopoDS_Iterator It (aShape, Standard_True, Standard_True);
01726     for (; It.More(); It.Next()) {
01727       if (mapShape.Add(It.Value())) {
01728         if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
01729             TopAbs_ShapeEnum(theShapeType) == It.Value().ShapeType()) {
01730           nbShapes++;
01731         }
01732       }
01733     }
01734   } else {
01735     TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
01736     for (; exp.More(); exp.Next())
01737       if (mapShape.Add(exp.Current()))
01738         nbShapes++;
01739   }
01740   */
01741 
01742   try {
01743 #if OCC_VERSION_LARGE > 0x06010000
01744     OCC_CATCH_SIGNALS;
01745 #endif
01746     int iType, nbTypes [TopAbs_SHAPE];
01747     for (iType = 0; iType < TopAbs_SHAPE; ++iType)
01748       nbTypes[iType] = 0;
01749     nbTypes[aShape.ShapeType()]++;
01750 
01751     TopTools_MapOfShape aMapOfShape;
01752     aMapOfShape.Add(aShape);
01753     TopTools_ListOfShape aListOfShape;
01754     aListOfShape.Append(aShape);
01755 
01756     TopTools_ListIteratorOfListOfShape itL (aListOfShape);
01757     for (; itL.More(); itL.Next()) {
01758       TopoDS_Iterator it (itL.Value());
01759       for (; it.More(); it.Next()) {
01760         TopoDS_Shape s = it.Value();
01761         if (aMapOfShape.Add(s)) {
01762           aListOfShape.Append(s);
01763           nbTypes[s.ShapeType()]++;
01764         }
01765       }
01766     }
01767 
01768     if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE)
01769       nbShapes = aMapOfShape.Extent();
01770     else
01771       nbShapes = nbTypes[theShapeType];
01772   }
01773   catch (Standard_Failure) {
01774     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
01775     SetErrorCode(aFail->GetMessageString());
01776     return -1;
01777   }
01778 
01779   SetErrorCode(OK);
01780   return nbShapes;
01781 }
01782 
01783 //=============================================================================
01787 //=============================================================================
01788 Handle(GEOM_Object) GEOMImpl_IShapesOperations::ReverseShape(Handle(GEOM_Object) theShape)
01789 {
01790   SetErrorCode(KO);
01791 
01792   if (theShape.IsNull()) return NULL;
01793 
01794   /*
01795   //Add a new reversed object
01796   Handle(GEOM_Object) aReversed = GetEngine()->AddObject(GetDocID(), theShape->GetType());
01797 
01798   //Add a new Revese function
01799   Handle(GEOM_Function) aFunction;
01800   aFunction = aReversed->AddFunction(GEOMImpl_ShapeDriver::GetID(), REVERSE_ORIENTATION);
01801   if (aFunction.IsNull()) return NULL;
01802 
01803   //Check if the function is set correctly
01804   if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
01805 
01806   GEOMImpl_IShapes aSI (aFunction);
01807 
01808   Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
01809   if (aRefShape.IsNull()) return NULL;
01810 
01811   aSI.SetBase(aRefShape);
01812 
01813   //Compute the sub-shape value
01814   try {
01815 #if OCC_VERSION_LARGE > 0x06010000
01816     OCC_CATCH_SIGNALS;
01817 #endif
01818     if (!GetSolver()->ComputeFunction(aFunction)) {
01819       SetErrorCode("Shape driver failed to reverse shape");
01820       return NULL;
01821     }
01822   }
01823   catch (Standard_Failure) {
01824     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
01825     SetErrorCode(aFail->GetMessageString());
01826     return NULL;
01827   }
01828 
01829   //Make a Python command
01830   GEOM::TPythonDump(aFunction) << aReversed
01831     << " = geompy.ChangeOrientation(" << theShape << ")";
01832 
01833   SetErrorCode(OK);
01834   */
01835 
01836   Handle(GEOM_Object) aReversed;
01837 
01838   GEOM_Engine* anEngine = GetEngine();
01839   //GEOMImpl_Gen* aGen = dynamic_cast<GEOMImpl_Gen*>(anEngine);
01840   GEOMImpl_Gen* aGen = (GEOMImpl_Gen*)anEngine;
01841 
01842   if (aGen) {
01843     GEOMImpl_IHealingOperations* anIHealingOperations =
01844       aGen->GetIHealingOperations(GetDocID());
01845     aReversed = anIHealingOperations->ChangeOrientationCopy(theShape);
01846     SetErrorCode(anIHealingOperations->GetErrorCode());
01847   }
01848 
01849   return aReversed;
01850 }
01851 
01852 //=============================================================================
01856 //=============================================================================
01857 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetFreeFacesIDs
01858                                                  (Handle(GEOM_Object) theShape)
01859 {
01860   SetErrorCode(KO);
01861 
01862   if (theShape.IsNull()) return NULL;
01863   TopoDS_Shape aShape = theShape->GetValue();
01864   if (aShape.IsNull()) return NULL;
01865 
01866   Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
01867 
01868   TopTools_IndexedDataMapOfShapeListOfShape mapFaceBlocks;
01869   GEOMImpl_Block6Explorer::MapShapesAndAncestors
01870     (aShape, TopAbs_FACE, TopAbs_SOLID, mapFaceBlocks);
01871 
01872   Standard_Integer ind = 1, nbFaces = mapFaceBlocks.Extent();
01873 
01874   if (nbFaces == 0) {
01875     SetErrorCode("The given shape has no faces");
01876     return aSeq;
01877   }
01878 
01879   TopTools_IndexedMapOfShape anIndices;
01880   TopExp::MapShapes(aShape, anIndices);
01881 
01882   Standard_Integer id;
01883   for (; ind <= nbFaces; ind++) {
01884     if (mapFaceBlocks.FindFromIndex(ind).Extent() != 2) {
01885       id = anIndices.FindIndex(mapFaceBlocks.FindKey(ind));
01886       aSeq->Append(id);
01887     }
01888   }
01889 
01890   //The explode doesn't change object so no new function is required.
01891   Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
01892 
01893   //Make a Python command
01894   GEOM::TPythonDump(aFunction, /*append=*/true)
01895     << "listFreeFacesIDs = geompy.GetFreeFacesIDs(" << theShape << ")";
01896 
01897   SetErrorCode(OK);
01898   return aSeq;
01899 }
01900 
01901 //=======================================================================
01902 //function : GetSharedShapes
01903 //purpose  :
01904 //=======================================================================
01905 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetSharedShapes
01906                                                 (Handle(GEOM_Object)    theShape1,
01907                                                  Handle(GEOM_Object)    theShape2,
01908                                                  const Standard_Integer theShapeType)
01909 {
01910   SetErrorCode(KO);
01911 
01912   if (theShape1.IsNull() || theShape2.IsNull()) return NULL;
01913 
01914   TopoDS_Shape aShape1 = theShape1->GetValue();
01915   TopoDS_Shape aShape2 = theShape2->GetValue();
01916 
01917   if (aShape1.IsNull() || aShape2.IsNull()) return NULL;
01918 
01919   TopTools_IndexedMapOfShape anIndices;
01920   TopExp::MapShapes(aShape1, anIndices);
01921   Handle(TColStd_HArray1OfInteger) anArray;
01922 
01923   TopTools_IndexedMapOfShape mapShape1;
01924   TopExp::MapShapes(aShape1, TopAbs_ShapeEnum(theShapeType), mapShape1);
01925 
01926   Handle(GEOM_Object) anObj;
01927   Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
01928   TCollection_AsciiString anAsciiList, anEntry;
01929 
01930   TopTools_MapOfShape mapShape2;
01931   TopExp_Explorer exp (aShape2, TopAbs_ShapeEnum(theShapeType));
01932   for (; exp.More(); exp.Next()) {
01933     TopoDS_Shape aSS = exp.Current();
01934     if (mapShape2.Add(aSS) && mapShape1.Contains(aSS)) {
01935       anArray = new TColStd_HArray1OfInteger(1,1);
01936       anArray->SetValue(1, anIndices.FindIndex(aSS));
01937       anObj = GetEngine()->AddSubShape(theShape1, anArray);
01938       aSeq->Append(anObj);
01939 
01940       // for python command
01941       TDF_Tool::Entry(anObj->GetEntry(), anEntry);
01942       anAsciiList += anEntry;
01943       anAsciiList += ",";
01944     }
01945   }
01946 
01947   if (aSeq->IsEmpty()) {
01948     SetErrorCode("The given shapes have no shared sub-shapes of the requested type");
01949     return aSeq;
01950   }
01951 
01952   //Make a Python command
01953   anAsciiList.Trunc(anAsciiList.Length() - 1);
01954 
01955   Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
01956 
01957   GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
01958     << "] = geompy.GetSharedShapes(" << theShape1 << ", "
01959       << theShape2 << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
01960 
01961   SetErrorCode(OK);
01962   return aSeq;
01963 }
01964 
01965 //=======================================================================
01966 //function : GetSharedShapes
01967 //purpose  :
01968 //=======================================================================
01969 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetSharedShapes
01970                                      (std::list<Handle(GEOM_Object)> theShapes,
01971                                       const Standard_Integer         theShapeType)
01972 {
01973   SetErrorCode(KO);
01974 
01975   int aLen = theShapes.size();
01976   if (aLen < 1) return NULL;
01977 
01978   int ind = 1;
01979   std::list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
01980 
01981   Handle(GEOM_Object) aMainObj = (*it++);
01982   Handle(GEOM_Function) aMainShape = aMainObj->GetLastFunction();
01983   if (aMainShape.IsNull()) {
01984     SetErrorCode("NULL shape for GetSharedShapes");
01985     return NULL;
01986   }
01987 
01988   TopoDS_Shape aShape1 = aMainShape->GetValue();
01989   if (aShape1.IsNull()) return NULL;
01990 
01991   TopTools_IndexedMapOfShape anIndices;
01992   TopExp::MapShapes(aShape1, anIndices);
01993 
01994   TopTools_IndexedMapOfShape mapSelected;
01995   TopExp::MapShapes(aShape1, TopAbs_ShapeEnum(theShapeType), mapSelected);
01996 
01997   // Find shared shapes
01998   BRep_Builder B;
01999   TopoDS_Compound aCurrSelection;
02000 
02001   for (; it != theShapes.end(); it++, ind++) {
02002     Handle(GEOM_Function) aRefShape = (*it)->GetLastFunction();
02003     if (aRefShape.IsNull()) {
02004       SetErrorCode("NULL shape for GetSharedShapes");
02005       return NULL;
02006     }
02007 
02008     TopoDS_Compound aCompound;
02009     B.MakeCompound(aCompound);
02010 
02011     TopoDS_Shape aShape2 = aRefShape->GetValue();
02012     if (aShape2.IsNull()) return NULL;
02013 
02014     TopTools_MapOfShape mapShape2;
02015     TopExp_Explorer exp (aShape2, TopAbs_ShapeEnum(theShapeType));
02016     for (; exp.More(); exp.Next()) {
02017       TopoDS_Shape aSS = exp.Current();
02018       if (mapShape2.Add(aSS) && mapSelected.Contains(aSS)) {
02019         B.Add(aCompound, aSS);
02020       }
02021     }
02022 
02023     mapSelected.Clear();
02024     TopExp::MapShapes(aCompound, TopAbs_ShapeEnum(theShapeType), mapSelected);
02025     aCurrSelection = aCompound;
02026   }
02027 
02028   // Create GEOM_Object for each found shared shape (collected in aCurrSelection)
02029   Handle(GEOM_Object) anObj;
02030   Handle(TColStd_HArray1OfInteger) anArray;
02031   Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
02032   TCollection_AsciiString anAsciiList, anEntry;
02033 
02034   TopoDS_Iterator itSel (aCurrSelection, Standard_True, Standard_True);
02035   for (; itSel.More(); itSel.Next()) {
02036     anArray = new TColStd_HArray1OfInteger(1,1);
02037     anArray->SetValue(1, anIndices.FindIndex(itSel.Value()));
02038     anObj = GetEngine()->AddSubShape(aMainObj, anArray);
02039     aSeq->Append(anObj);
02040 
02041     // for python command
02042     TDF_Tool::Entry(anObj->GetEntry(), anEntry);
02043     anAsciiList += anEntry;
02044     anAsciiList += ",";
02045   }
02046 
02047   if (aSeq->IsEmpty()) {
02048     SetErrorCode("The given shapes have no shared sub-shapes of the requested type");
02049     return aSeq;
02050   }
02051 
02052   // Make a Python command
02053   anAsciiList.Trunc(anAsciiList.Length() - 1);
02054 
02055   // IPAL22904: TC6.5.0: order of python commands is wrong after dump study
02056   Handle(TColStd_HSequenceOfTransient) anObjects = new TColStd_HSequenceOfTransient;
02057   for( it = theShapes.begin(); it != theShapes.end(); it++ )
02058   {
02059     Handle(GEOM_Object) anObj = *it;
02060     if( !anObj.IsNull() )
02061       anObjects->Append( anObj );
02062   }
02063 
02064   // Get the function of the latest published object
02065   Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast( anObjects )->GetLastFunction();
02066   if( aFunction.IsNull() ) // just in case
02067     aFunction = aMainShape;
02068 
02069   GEOM::TPythonDump pd (aFunction, /*append=*/true);
02070   pd << "[" << anAsciiList.ToCString()
02071      << "] = geompy.GetSharedShapesMulti([";
02072 
02073   it = theShapes.begin();
02074   pd << (*it++);
02075   while (it != theShapes.end()) {
02076     pd << ", " << (*it++);
02077   }
02078 
02079   pd << "], " << TopAbs_ShapeEnum(theShapeType) << ")";
02080 
02081   SetErrorCode(OK);
02082   return aSeq;
02083 }
02084 
02085 //=============================================================================
02089 //=============================================================================
02090 static GEOM::TPythonDump& operator<< (GEOM::TPythonDump&   theDump,
02091                                       const GEOMAlgo_State theState)
02092 {
02093   switch (theState) {
02094   case GEOMAlgo_ST_IN:
02095     theDump << "geompy.GEOM.ST_IN";
02096     break;
02097   case GEOMAlgo_ST_OUT:
02098     theDump << "geompy.GEOM.ST_OUT";
02099     break;
02100   case GEOMAlgo_ST_ON:
02101     theDump << "geompy.GEOM.ST_ON";
02102     break;
02103   case GEOMAlgo_ST_ONIN:
02104     theDump << "geompy.GEOM.ST_ONIN";
02105     break;
02106   case GEOMAlgo_ST_ONOUT:
02107     theDump << "geompy.GEOM.ST_ONOUT";
02108     break;
02109   default:
02110     theDump << "geompy.GEOM.ST_UNKNOWN";
02111     break;
02112   }
02113   return theDump;
02114 }
02115 
02116 //=======================================================================
02117 //function : checkTypeShapesOn
02123 //=======================================================================
02124 bool GEOMImpl_IShapesOperations::checkTypeShapesOn(const Standard_Integer theShapeType)
02125 {
02126   if (theShapeType != TopAbs_VERTEX &&
02127       theShapeType != TopAbs_EDGE &&
02128       theShapeType != TopAbs_FACE &&
02129       theShapeType != TopAbs_SOLID) {
02130     SetErrorCode("Only solids, vertices, edges or faces can be found by this method");
02131     return false;
02132   }
02133   return true;
02134 }
02135 
02136 //=======================================================================
02137 //function : makePlane
02143 //=======================================================================
02144 Handle(Geom_Surface) GEOMImpl_IShapesOperations::makePlane(const TopoDS_Shape& anAx1)
02145 {
02146   if (anAx1.ShapeType() != TopAbs_EDGE) return NULL;
02147   TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
02148   TopoDS_Vertex V1, V2;
02149   TopExp::Vertices(anEdge, V1, V2, Standard_True);
02150   if (V1.IsNull() || V2.IsNull()) {
02151     SetErrorCode("Bad edge given for the plane normal vector");
02152     return NULL;
02153   }
02154   gp_Pnt aLoc = BRep_Tool::Pnt(V1);
02155   gp_Vec aVec (aLoc, BRep_Tool::Pnt(V2));
02156   if (aVec.Magnitude() < Precision::Confusion()) {
02157     SetErrorCode("Vector with null magnitude given");
02158     return NULL;
02159   }
02160   return new Geom_Plane(aLoc, aVec);
02161 }
02162 
02163 //=======================================================================
02164 //function : makeCylinder
02171 //=======================================================================
02172 Handle(Geom_Surface) GEOMImpl_IShapesOperations::makeCylinder(const TopoDS_Shape& anAxis,
02173                                                               const Standard_Real theRadius)
02174 {
02175   //Axis of the cylinder
02176   if (anAxis.ShapeType() != TopAbs_EDGE) {
02177     SetErrorCode("Not an edge given for the axis");
02178     return NULL;
02179   }
02180   TopoDS_Edge anEdge = TopoDS::Edge(anAxis);
02181   TopoDS_Vertex V1, V2;
02182   TopExp::Vertices(anEdge, V1, V2, Standard_True);
02183   if (V1.IsNull() || V2.IsNull()) {
02184     SetErrorCode("Bad edge given for the axis");
02185     return NULL;
02186   }
02187   gp_Pnt aLoc = BRep_Tool::Pnt(V1);
02188   gp_Vec aVec (aLoc, BRep_Tool::Pnt(V2));
02189   if (aVec.Magnitude() < Precision::Confusion()) {
02190     SetErrorCode("Vector with null magnitude given");
02191     return NULL;
02192   }
02193 
02194   gp_Ax3 anAx3 (aLoc, aVec);
02195   return new Geom_CylindricalSurface(anAx3, theRadius);
02196 }
02197 
02198 //=======================================================================
02199 //function : getShapesOnBoxIDs
02208 //=======================================================================
02209 Handle(TColStd_HSequenceOfInteger)
02210   GEOMImpl_IShapesOperations::getShapesOnBoxIDs(const Handle(GEOM_Object)& theBox,
02211                                                 const Handle(GEOM_Object)& theShape,
02212                                                 const Standard_Integer theShapeType,
02213                                                 GEOMAlgo_State theState)
02214 {
02215   Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
02216 
02217   TopoDS_Shape aBox = theBox->GetValue();
02218   TopoDS_Shape aShape = theShape->GetValue();
02219 
02220   // Check presence of triangulation, build if need
02221   if (!CheckTriangulation(aShape)) {
02222     SetErrorCode("Cannot build triangulation on the shape");
02223     return aSeqOfIDs;
02224   }
02225 
02226   // Call algo
02227   GEOMAlgo_FinderShapeOn2 aFinder;
02228   Standard_Real aTol = 0.0001; // default value
02229 
02230   Handle(GEOMAlgo_ClsfBox) aClsfBox = new GEOMAlgo_ClsfBox;
02231   aClsfBox->SetBox(aBox);
02232 
02233   aFinder.SetShape(aShape);
02234   aFinder.SetTolerance(aTol);
02235   aFinder.SetClsf(aClsfBox);
02236   aFinder.SetShapeType( (TopAbs_ShapeEnum)theShapeType );
02237   aFinder.SetState(theState);
02238   aFinder.Perform();
02239 
02240   // Interprete results
02241   Standard_Integer iErr = aFinder.ErrorStatus();
02242   // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
02243   if (iErr) {
02244     MESSAGE(" iErr : " << iErr);
02245     TCollection_AsciiString aMsg (" iErr : ");
02246     aMsg += TCollection_AsciiString(iErr);
02247     SetErrorCode(aMsg);
02248     return aSeqOfIDs;
02249   }
02250   Standard_Integer iWrn = aFinder.WarningStatus();
02251   // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
02252   if (iWrn) {
02253     MESSAGE(" *** iWrn : " << iWrn);
02254   }
02255 
02256   const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
02257 
02258   if (listSS.Extent() < 1) {
02259     //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
02260     SetErrorCode(NOT_FOUND_ANY); // NPAL18017
02261     return aSeqOfIDs;
02262   }
02263 
02264   // Fill sequence of object IDs
02265   aSeqOfIDs = new TColStd_HSequenceOfInteger;
02266 
02267   TopTools_IndexedMapOfShape anIndices;
02268   TopExp::MapShapes(aShape, anIndices);
02269 
02270   TopTools_ListIteratorOfListOfShape itSub (listSS);
02271   for (int index = 1; itSub.More(); itSub.Next(), ++index) {
02272     int id = anIndices.FindIndex(itSub.Value());
02273     aSeqOfIDs->Append(id);
02274   }
02275 
02276   return aSeqOfIDs;
02277 }
02278 
02279 //=======================================================================
02280 //function : GetShapesOnBoxIDs
02289 //=======================================================================
02290 Handle(TColStd_HSequenceOfInteger)
02291     GEOMImpl_IShapesOperations::GetShapesOnBoxIDs(const Handle(GEOM_Object)& theBox,
02292                                                   const Handle(GEOM_Object)& theShape,
02293                                                   const Standard_Integer theShapeType,
02294                                                   GEOMAlgo_State theState)
02295 {
02296   // Find sub-shapes ids
02297   Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
02298     getShapesOnBoxIDs (theBox, theShape, theShapeType, theState);
02299   if ( aSeqOfIDs.IsNull()  || aSeqOfIDs->Length() == 0 )
02300     return NULL;
02301 
02302   // The GetShapesOnBox() doesn't change object so no new function is required.
02303   Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theBox)->GetLastFunction();
02304 
02305   // Make a Python command
02306   GEOM::TPythonDump(aFunction)
02307     << "listShapesOnBoxIDs = geompy.GetShapesOnBoxIDs("
02308     << theBox << ", "
02309     << theShape << ", "
02310     << TopAbs_ShapeEnum(theShapeType) << ", "
02311     << theState << ")";
02312 
02313   SetErrorCode(OK);
02314   return aSeqOfIDs;
02315 }
02316 
02317 //=======================================================================
02318 //function : GetShapesOnBox
02327 //=======================================================================
02328 Handle(TColStd_HSequenceOfTransient)
02329     GEOMImpl_IShapesOperations::GetShapesOnBox(const Handle(GEOM_Object)& theBox,
02330                                                const Handle(GEOM_Object)&  theShape,
02331                                                const Standard_Integer theShapeType,
02332                                                GEOMAlgo_State theState)
02333 {
02334   // Find sub-shapes ids
02335   Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
02336     getShapesOnBoxIDs (theBox, theShape, theShapeType, theState);
02337   if ( aSeqOfIDs.IsNull()  || aSeqOfIDs->Length() == 0 )
02338     return NULL;
02339 
02340   // Find objects by indices
02341   TCollection_AsciiString anAsciiList;
02342   Handle(TColStd_HSequenceOfTransient) aSeq;
02343   aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
02344   if ( aSeq.IsNull() || aSeq->IsEmpty() )
02345     return NULL;
02346 
02347   // Make a Python command
02348 
02349   Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
02350   Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
02351 
02352   GEOM::TPythonDump(aFunction)
02353     << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnBox("
02354     << theBox << ", "
02355     << theShape << ", "
02356     << TopAbs_ShapeEnum(theShapeType) << ", "
02357     << theState << ")";
02358 
02359   SetErrorCode(OK);
02360   return aSeq;
02361 }
02362 
02363 //=======================================================================
02364 //function : getShapesOnShapeIDs
02373 //=======================================================================
02374 Handle(TColStd_HSequenceOfInteger)
02375   GEOMImpl_IShapesOperations::getShapesOnShapeIDs
02376                                  (const Handle(GEOM_Object)& theCheckShape,
02377                                   const Handle(GEOM_Object)& theShape,
02378                                   const Standard_Integer theShapeType,
02379                                   GEOMAlgo_State theState)
02380 {
02381   Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
02382 
02383   TopoDS_Shape aCheckShape = theCheckShape->GetValue();
02384   TopoDS_Shape aShape = theShape->GetValue();
02385   TopTools_ListOfShape res;
02386 
02387   // Check presence of triangulation, build if need
02388   if (!CheckTriangulation(aShape)) {
02389     SetErrorCode("Cannot build triangulation on the shape");
02390     return aSeqOfIDs;
02391   }
02392 
02393   // Call algo
02394   GEOMAlgo_FinderShapeOn2 aFinder;
02395   Standard_Real aTol = 0.0001; // default value
02396 
02397   Handle(GEOMAlgo_ClsfSolid) aClsfSolid = new GEOMAlgo_ClsfSolid;
02398   aClsfSolid->SetShape(aCheckShape);
02399 
02400   aFinder.SetShape(aShape);
02401   aFinder.SetTolerance(aTol);
02402   aFinder.SetClsf(aClsfSolid);
02403   aFinder.SetShapeType( (TopAbs_ShapeEnum)theShapeType );
02404   aFinder.SetState(theState);
02405   aFinder.Perform();
02406 
02407   // Interprete results
02408   Standard_Integer iErr = aFinder.ErrorStatus();
02409   // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
02410   if (iErr) {
02411     if (iErr == 41) {
02412       SetErrorCode("theCheckShape must be a solid");
02413     }
02414     else {
02415       MESSAGE(" iErr : " << iErr);
02416       TCollection_AsciiString aMsg (" iErr : ");
02417       aMsg += TCollection_AsciiString(iErr);
02418       SetErrorCode(aMsg);
02419     }
02420     return aSeqOfIDs;
02421   }
02422   Standard_Integer iWrn = aFinder.WarningStatus();
02423   // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
02424   if (iWrn) {
02425     MESSAGE(" *** iWrn : " << iWrn);
02426   }
02427 
02428   const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
02429 
02430   if (listSS.Extent() < 1) {
02431     //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
02432     SetErrorCode(NOT_FOUND_ANY); // NPAL18017
02433   }
02434 
02435   // Fill sequence of object IDs
02436   aSeqOfIDs = new TColStd_HSequenceOfInteger;
02437 
02438   TopTools_IndexedMapOfShape anIndices;
02439   TopExp::MapShapes(aShape, anIndices);
02440 
02441   TopTools_ListIteratorOfListOfShape itSub (listSS);
02442   for (int index = 1; itSub.More(); itSub.Next(), ++index) {
02443     int id = anIndices.FindIndex(itSub.Value());
02444     aSeqOfIDs->Append(id);
02445   }
02446 
02447   return aSeqOfIDs;
02448 }
02449 
02450 //=======================================================================
02451 //function : GetShapesOnShapeIDs
02460 //=======================================================================
02461 Handle(TColStd_HSequenceOfInteger)
02462     GEOMImpl_IShapesOperations::GetShapesOnShapeIDs
02463                             (const Handle(GEOM_Object)& theCheckShape,
02464                              const Handle(GEOM_Object)& theShape,
02465                              const Standard_Integer theShapeType,
02466                              GEOMAlgo_State theState)
02467 {
02468   Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
02469     getShapesOnShapeIDs (theCheckShape, theShape, theShapeType, theState);
02470 
02471   if ( aSeqOfIDs.IsNull()  || aSeqOfIDs->Length() == 0 )
02472     return NULL;
02473 
02474   // The GetShapesOnShape() doesn't change object so no new function is required.
02475   Handle(GEOM_Function) aFunction =
02476     GEOM::GetCreatedLast(theShape,theCheckShape)->GetLastFunction();
02477 
02478   // Make a Python command
02479   GEOM::TPythonDump(aFunction)
02480     << "listShapesOnBoxIDs = geompy.GetShapesOnShapeIDs("
02481     << theCheckShape << ", "
02482     << theShape << ", "
02483     << TopAbs_ShapeEnum(theShapeType) << ", "
02484     << theState << ")";
02485 
02486   SetErrorCode(OK);
02487   return aSeqOfIDs;
02488 }
02489 
02490 //=======================================================================
02491 //function : GetShapesOnShape
02500 //=======================================================================
02501 Handle(TColStd_HSequenceOfTransient)
02502   GEOMImpl_IShapesOperations::GetShapesOnShape
02503                              (const Handle(GEOM_Object)& theCheckShape,
02504                               const Handle(GEOM_Object)&  theShape,
02505                               const Standard_Integer theShapeType,
02506                               GEOMAlgo_State theState)
02507 {
02508   Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
02509     getShapesOnShapeIDs (theCheckShape, theShape, theShapeType, theState);
02510   if ( aSeqOfIDs.IsNull()  || aSeqOfIDs->Length() == 0 )
02511     return NULL;
02512 
02513   // Find objects by indices
02514   TCollection_AsciiString anAsciiList;
02515   Handle(TColStd_HSequenceOfTransient) aSeq;
02516   aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
02517 
02518   if ( aSeq.IsNull() || aSeq->IsEmpty() )
02519     return NULL;
02520 
02521   // Make a Python command
02522 
02523   Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
02524   Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
02525 
02526   GEOM::TPythonDump(aFunction)
02527     << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnShape("
02528     << theCheckShape << ", "
02529     << theShape << ", "
02530     << TopAbs_ShapeEnum(theShapeType) << ", "
02531     << theState << ")";
02532 
02533   SetErrorCode(OK);
02534   return aSeq;
02535 }
02536 
02537 //=======================================================================
02538 //function : GetShapesOnShapeAsCompound
02539 //=======================================================================
02540 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetShapesOnShapeAsCompound
02541                              (const Handle(GEOM_Object)& theCheckShape,
02542                               const Handle(GEOM_Object)&  theShape,
02543                               const Standard_Integer theShapeType,
02544                               GEOMAlgo_State theState)
02545 {
02546   Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
02547     getShapesOnShapeIDs (theCheckShape, theShape, theShapeType, theState);
02548 
02549   if ( aSeqOfIDs.IsNull()  || aSeqOfIDs->Length() == 0 )
02550     return NULL;
02551 
02552   // Find objects by indices
02553   TCollection_AsciiString anAsciiList;
02554   Handle(TColStd_HSequenceOfTransient) aSeq;
02555   aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
02556 
02557   if ( aSeq.IsNull() || aSeq->IsEmpty() )
02558     return NULL;
02559 
02560   TopoDS_Compound aCompound;
02561   BRep_Builder B;
02562   B.MakeCompound(aCompound);
02563   int i = 1;
02564   for(; i<=aSeq->Length(); i++) {
02565     Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(aSeq->Value(i));
02566     TopoDS_Shape aShape_i = anObj->GetValue();
02567     B.Add(aCompound,aShape_i);
02568   }
02569 
02570   //Add a new result object
02571   Handle(GEOM_Object) aRes = GetEngine()->AddObject(GetDocID(), GEOM_SHAPES_ON_SHAPE);
02572   Handle(GEOM_Function) aFunction =
02573     aRes->AddFunction(GEOMImpl_ShapeDriver::GetID(), SHAPES_ON_SHAPE);
02574   aFunction->SetValue(aCompound);
02575 
02576   GEOM::TPythonDump(aFunction)
02577     << aRes << " = geompy.GetShapesOnShapeAsCompound("
02578     << theCheckShape << ", "
02579     << theShape << ", "
02580     << TopAbs_ShapeEnum(theShapeType) << ", "
02581     << theState << ")";
02582 
02583   SetErrorCode(OK);
02584 
02585   return aRes;
02586 }
02587 
02588 //=======================================================================
02589 //function : getShapesOnSurfaceIDs
02598 //=======================================================================
02599 Handle(TColStd_HSequenceOfInteger)
02600   GEOMImpl_IShapesOperations::getShapesOnSurfaceIDs(const Handle(Geom_Surface)& theSurface,
02601                                                     const TopoDS_Shape&         theShape,
02602                                                     TopAbs_ShapeEnum            theShapeType,
02603                                                     GEOMAlgo_State              theState)
02604 {
02605   Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
02606 
02607   // Check presence of triangulation, build if need
02608   if (!CheckTriangulation(theShape)) {
02609     SetErrorCode("Cannot build triangulation on the shape");
02610     return aSeqOfIDs;
02611   }
02612 
02613   // BEGIN: Mantis issue 0020961: Error on a pipe T-Shape
02614   // Compute tolerance
02615   Standard_Real T, VertMax = -RealLast();
02616   try {
02617 #if OCC_VERSION_LARGE > 0x06010000
02618     OCC_CATCH_SIGNALS;
02619 #endif
02620     for (TopExp_Explorer ExV (theShape, TopAbs_VERTEX); ExV.More(); ExV.Next()) {
02621       TopoDS_Vertex Vertex = TopoDS::Vertex(ExV.Current());
02622       T = BRep_Tool::Tolerance(Vertex);
02623       if (T > VertMax)
02624         VertMax = T;
02625     }
02626   }
02627   catch (Standard_Failure) {
02628     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
02629     SetErrorCode(aFail->GetMessageString());
02630     return aSeqOfIDs;
02631   }
02632   // END: Mantis issue 0020961
02633 
02634   // Call algo
02635   GEOMAlgo_FinderShapeOn1 aFinder;
02636   //Standard_Real aTol = 0.0001; // default value
02637   Standard_Real aTol = VertMax; // Mantis issue 0020961
02638 
02639   aFinder.SetShape(theShape);
02640   aFinder.SetTolerance(aTol);
02641   aFinder.SetSurface(theSurface);
02642   aFinder.SetShapeType(theShapeType);
02643   aFinder.SetState(theState);
02644 
02645   // Sets the minimal number of inner points for the faces that do not have own
02646   // inner points at all (for e.g. rectangular planar faces have just 2 triangles).
02647   // Default value=3
02648   aFinder.SetNbPntsMin(3);
02649   // Sets the maximal number of inner points for edges or faces.
02650   // It is usefull for the cases when this number is very big (e.g =2000) to improve
02651   // the performance. If this value =0, all inner points will be taken into account.
02652   // Default value=0
02653   aFinder.SetNbPntsMax(100);
02654 
02655   aFinder.Perform();
02656 
02657   // Interprete results
02658   Standard_Integer iErr = aFinder.ErrorStatus();
02659   // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
02660   if (iErr) {
02661     MESSAGE(" iErr : " << iErr);
02662     TCollection_AsciiString aMsg (" iErr : ");
02663     aMsg += TCollection_AsciiString(iErr);
02664     SetErrorCode(aMsg);
02665     return aSeqOfIDs;
02666   }
02667   Standard_Integer iWrn = aFinder.WarningStatus();
02668   // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
02669   if (iWrn) {
02670     MESSAGE(" *** iWrn : " << iWrn);
02671   }
02672 
02673   const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
02674 
02675   if (listSS.Extent() < 1) {
02676     //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
02677     SetErrorCode(NOT_FOUND_ANY); // NPAL18017
02678     return aSeqOfIDs;
02679   }
02680 
02681   // Fill sequence of object IDs
02682   aSeqOfIDs = new TColStd_HSequenceOfInteger;
02683 
02684   TopTools_IndexedMapOfShape anIndices;
02685   TopExp::MapShapes(theShape, anIndices);
02686 
02687   TopTools_ListIteratorOfListOfShape itSub (listSS);
02688   for (int index = 1; itSub.More(); itSub.Next(), ++index) {
02689     int id = anIndices.FindIndex(itSub.Value());
02690     aSeqOfIDs->Append(id);
02691   }
02692 
02693   return aSeqOfIDs;
02694 }
02695 
02696 //=======================================================================
02697 //function : getObjectsShapesOn
02704 //=======================================================================
02705 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::
02706  getObjectsShapesOn(const Handle(GEOM_Object)&                theShape,
02707                     const Handle(TColStd_HSequenceOfInteger)& theShapeIDs,
02708                     TCollection_AsciiString &                 theShapeEntries)
02709 {
02710   Handle(TColStd_HSequenceOfTransient) aSeq;
02711 
02712   if ( !theShapeIDs.IsNull() && theShapeIDs->Length() > 0 )
02713   {
02714     aSeq = new TColStd_HSequenceOfTransient;
02715     Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
02716     TCollection_AsciiString anEntry;
02717     for ( int i = 1; i <= theShapeIDs->Length(); ++i )
02718     {
02719       anArray->SetValue(1, theShapeIDs->Value( i ));
02720       Handle(GEOM_Object) anObj = GetEngine()->AddSubShape(theShape, anArray);
02721       aSeq->Append( anObj );
02722 
02723       TDF_Tool::Entry(anObj->GetEntry(), anEntry);
02724       if ( i != 1 ) theShapeEntries += ",";
02725       theShapeEntries += anEntry;
02726     }
02727   }
02728   return aSeq;
02729 }
02730 
02731 //=======================================================================
02732 //function : getShapesOnSurface
02742 //=======================================================================
02743 Handle(TColStd_HSequenceOfTransient)
02744     GEOMImpl_IShapesOperations::getShapesOnSurface(const Handle(Geom_Surface)& theSurface,
02745                                                    const Handle(GEOM_Object)&  theShape,
02746                                                    TopAbs_ShapeEnum            theShapeType,
02747                                                    GEOMAlgo_State              theState,
02748                                                    TCollection_AsciiString &   theShapeEntries)
02749 {
02750   // Find sub-shapes ids
02751   Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
02752     getShapesOnSurfaceIDs (theSurface, theShape->GetValue(), theShapeType, theState);
02753   if ( aSeqOfIDs.IsNull()  || aSeqOfIDs->Length() == 0 )
02754     return NULL;
02755 
02756   return getObjectsShapesOn( theShape, aSeqOfIDs, theShapeEntries );
02757 }
02758 
02759 //=============================================================================
02763 //=============================================================================
02764 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnPlane
02765                                         (const Handle(GEOM_Object)& theShape,
02766                                          const Standard_Integer     theShapeType,
02767                                          const Handle(GEOM_Object)& theAx1,
02768                                          const GEOMAlgo_State       theState)
02769 {
02770   SetErrorCode(KO);
02771 
02772   if (theShape.IsNull() || theAx1.IsNull()) return NULL;
02773 
02774   TopoDS_Shape aShape = theShape->GetValue();
02775   TopoDS_Shape anAx1  = theAx1->GetValue();
02776 
02777   if (aShape.IsNull() || anAx1.IsNull()) return NULL;
02778 
02779   TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
02780   if ( !checkTypeShapesOn( theShapeType ))
02781     return NULL;
02782 
02783   // Create plane
02784   Handle(Geom_Surface) aPlane = makePlane( anAx1 );
02785   if ( aPlane.IsNull() )
02786     return NULL;
02787 
02788   // Find objects
02789   TCollection_AsciiString anAsciiList;
02790   Handle(TColStd_HSequenceOfTransient) aSeq;
02791   aSeq = getShapesOnSurface( aPlane, theShape, aShapeType, theState, anAsciiList );
02792   if ( aSeq.IsNull() || aSeq->Length() == 0 )
02793     return NULL;
02794 
02795   // Make a Python command
02796 
02797   Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
02798   Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
02799 
02800   GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
02801     << "] = geompy.GetShapesOnPlane(" << theShape << ", "
02802       << aShapeType << ", " << theAx1 << ", " << theState << ")";
02803 
02804   SetErrorCode(OK);
02805   return aSeq;
02806 }
02807 
02808 //=============================================================================
02812 //=============================================================================
02813 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnPlaneWithLocation
02814                                         (const Handle(GEOM_Object)& theShape,
02815                                          const Standard_Integer     theShapeType,
02816                                          const Handle(GEOM_Object)& theAx1,
02817                                          const Handle(GEOM_Object)& thePnt,
02818                                          const GEOMAlgo_State       theState)
02819 {
02820   SetErrorCode(KO);
02821 
02822   if (theShape.IsNull() || theAx1.IsNull() || thePnt.IsNull()) return NULL;
02823 
02824   TopoDS_Shape aShape = theShape->GetValue();
02825   TopoDS_Shape anAx1  = theAx1->GetValue();
02826   TopoDS_Shape anPnt = thePnt->GetValue();
02827 
02828   if (aShape.IsNull() || anAx1.IsNull() || anPnt.IsNull()) return NULL;
02829 
02830   TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
02831   if ( !checkTypeShapesOn( theShapeType ))
02832     return NULL;
02833 
02834   // Create plane
02835   if ( anAx1.ShapeType() != TopAbs_EDGE || anPnt.ShapeType() != TopAbs_VERTEX ) return NULL;
02836   TopoDS_Vertex V1, V2, V3;
02837   TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
02838   TopExp::Vertices(anEdge, V1, V2, Standard_True);
02839 
02840   if (V1.IsNull() || V2.IsNull()) {
02841     SetErrorCode("Bad edge given for the plane normal vector");
02842     return NULL;
02843   }
02844   V3 = TopoDS::Vertex(anPnt);
02845 
02846   if(V3.IsNull()) {
02847     SetErrorCode("Bad vertex given for the plane location");
02848       return NULL;
02849   }
02850   gp_Pnt aLoc = BRep_Tool::Pnt(V3);
02851   gp_Vec aVec(BRep_Tool::Pnt(V1),BRep_Tool::Pnt(V2));
02852 
02853   if (aVec.Magnitude() < Precision::Confusion()) {
02854     SetErrorCode("Vector with null magnitude given");
02855     return NULL;
02856   }
02857   Handle(Geom_Surface) aPlane = new Geom_Plane(aLoc, aVec);
02858 
02859   if ( aPlane.IsNull() )
02860     return NULL;
02861 
02862   // Find objects
02863   TCollection_AsciiString anAsciiList;
02864   Handle(TColStd_HSequenceOfTransient) aSeq;
02865   aSeq = getShapesOnSurface( aPlane, theShape, aShapeType, theState, anAsciiList );
02866   if ( aSeq.IsNull() || aSeq->Length() == 0 )
02867     return NULL;
02868 
02869   // Make a Python command
02870 
02871   Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
02872   Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
02873 
02874   GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
02875     << "] = geompy.GetShapesOnPlaneWithLocation(" << theShape << ", "
02876     << aShapeType << ", " << theAx1 << ", "<< thePnt <<", " << theState << ")";
02877 
02878   SetErrorCode(OK);
02879   return aSeq;
02880 }
02881 
02882 //=============================================================================
02886 //=============================================================================
02887 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnCylinder
02888                                           (const Handle(GEOM_Object)& theShape,
02889                                            const Standard_Integer     theShapeType,
02890                                            const Handle(GEOM_Object)& theAxis,
02891                                            const Standard_Real        theRadius,
02892                                            const GEOMAlgo_State       theState)
02893 {
02894   SetErrorCode(KO);
02895 
02896   if (theShape.IsNull() || theAxis.IsNull()) return NULL;
02897 
02898   TopoDS_Shape aShape = theShape->GetValue();
02899   TopoDS_Shape anAxis = theAxis->GetValue();
02900 
02901   if (aShape.IsNull() || anAxis.IsNull()) return NULL;
02902 
02903   TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
02904   if ( !checkTypeShapesOn( aShapeType ))
02905     return NULL;
02906 
02907   // Create a cylinder surface
02908   Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
02909   if ( aCylinder.IsNull() )
02910     return NULL;
02911 
02912   // Find objects
02913   TCollection_AsciiString anAsciiList;
02914   Handle(TColStd_HSequenceOfTransient) aSeq;
02915   aSeq = getShapesOnSurface( aCylinder, theShape, aShapeType, theState, anAsciiList );
02916   if ( aSeq.IsNull() || aSeq->Length() == 0 )
02917     return NULL;
02918 
02919   // Make a Python command
02920 
02921   Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
02922   Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
02923 
02924   GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
02925     << "] = geompy.GetShapesOnCylinder(" << theShape << ", " << aShapeType
02926       << ", " << theAxis << ", " << theRadius << ", " << theState << ")";
02927 
02928   SetErrorCode(OK);
02929   return aSeq;
02930 }
02931 
02932 //=============================================================================
02936 //=============================================================================
02937 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnCylinderWithLocation
02938                                           (const Handle(GEOM_Object)& theShape,
02939                                            const Standard_Integer     theShapeType,
02940                                            const Handle(GEOM_Object)& theAxis,
02941                                            const Handle(GEOM_Object)& thePnt,
02942                                            const Standard_Real        theRadius,
02943                                            const GEOMAlgo_State       theState)
02944 {
02945   SetErrorCode(KO);
02946 
02947   if (theShape.IsNull() || theAxis.IsNull() || thePnt.IsNull()) return NULL;
02948 
02949   TopoDS_Shape aShape = theShape->GetValue();
02950   TopoDS_Shape anAxis = theAxis->GetValue();
02951   TopoDS_Shape aPnt   = thePnt->GetValue();
02952 
02953   if (aShape.IsNull() || anAxis.IsNull() || aPnt.IsNull()) return NULL;
02954 
02955   if (aPnt.ShapeType() != TopAbs_VERTEX )
02956   {
02957     SetErrorCode("Bottom location point must be vertex");
02958     return NULL;
02959   }
02960 
02961   TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
02962   if ( !checkTypeShapesOn( aShapeType ))
02963     return NULL;
02964 
02965   // Create a cylinder surface
02966   Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
02967   if ( aCylinder.IsNull() )
02968     return NULL;
02969 
02970   // translate the surface
02971   Handle(Geom_CylindricalSurface) aCylSurface =
02972     Handle(Geom_CylindricalSurface)::DownCast( aCylinder );
02973   if ( aCylSurface.IsNull() )
02974   {
02975     SetErrorCode("Unexpected surface type instead of Geom_CylindricalSurface");
02976     return NULL;
02977   }
02978   gp_Pnt fromLoc = aCylSurface->Cylinder().Location();
02979   gp_Pnt toLoc   = BRep_Tool::Pnt( TopoDS::Vertex( aPnt ));
02980   aCylinder->Translate( fromLoc, toLoc );
02981 
02982   // Find objects
02983   TCollection_AsciiString anAsciiList;
02984   Handle(TColStd_HSequenceOfTransient) aSeq;
02985   aSeq = getShapesOnSurface( aCylinder, theShape, aShapeType, theState, anAsciiList );
02986   if ( aSeq.IsNull() || aSeq->Length() == 0 )
02987     return NULL;
02988 
02989   // Make a Python command
02990 
02991   Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
02992   Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
02993 
02994   GEOM::TPythonDump(aFunction)
02995     << "[" << anAsciiList.ToCString()
02996     << "] = geompy.GetShapesOnCylinderWithLocation(" << theShape << ", " << aShapeType << ", "
02997     << theAxis << ", " << thePnt << ", " << theRadius << ", " << theState << ")";
02998 
02999   SetErrorCode(OK);
03000   return aSeq;
03001 }
03002 
03003 //=============================================================================
03007 //=============================================================================
03008 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnSphere
03009                                           (const Handle(GEOM_Object)& theShape,
03010                                            const Standard_Integer     theShapeType,
03011                                            const Handle(GEOM_Object)& theCenter,
03012                                            const Standard_Real        theRadius,
03013                                            const GEOMAlgo_State       theState)
03014 {
03015   SetErrorCode(KO);
03016 
03017   if (theShape.IsNull() || theCenter.IsNull()) return NULL;
03018 
03019   TopoDS_Shape aShape  = theShape->GetValue();
03020   TopoDS_Shape aCenter = theCenter->GetValue();
03021 
03022   if (aShape.IsNull() || aCenter.IsNull()) return NULL;
03023 
03024   TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
03025   if ( !checkTypeShapesOn( aShapeType ))
03026     return NULL;
03027 
03028   // Center of the sphere
03029   if (aCenter.ShapeType() != TopAbs_VERTEX) return NULL;
03030   gp_Pnt aLoc = BRep_Tool::Pnt(TopoDS::Vertex(aCenter));
03031 
03032   gp_Ax3 anAx3 (aLoc, gp::DZ());
03033   Handle(Geom_SphericalSurface) aSphere =
03034     new Geom_SphericalSurface(anAx3, theRadius);
03035 
03036   // Find objects
03037   TCollection_AsciiString anAsciiList;
03038   Handle(TColStd_HSequenceOfTransient) aSeq;
03039   aSeq = getShapesOnSurface( aSphere, theShape, aShapeType, theState, anAsciiList );
03040   if ( aSeq.IsNull() || aSeq->Length() == 0 )
03041     return NULL;
03042 
03043   // Make a Python command
03044 
03045   Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
03046   Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
03047 
03048   GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
03049     << "] = geompy.GetShapesOnSphere(" << theShape << ", " << aShapeType
03050       << ", " << theCenter << ", " << theRadius << ", " << theState << ")";
03051 
03052   SetErrorCode(OK);
03053   return aSeq;
03054 }
03055 
03056 //=============================================================================
03060 //=============================================================================
03061 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnPlaneIDs
03062                                         (const Handle(GEOM_Object)& theShape,
03063                                          const Standard_Integer     theShapeType,
03064                                          const Handle(GEOM_Object)& theAx1,
03065                                          const GEOMAlgo_State       theState)
03066 {
03067   SetErrorCode(KO);
03068 
03069   if (theShape.IsNull() || theAx1.IsNull()) return NULL;
03070 
03071   TopoDS_Shape aShape = theShape->GetValue();
03072   TopoDS_Shape anAx1  = theAx1->GetValue();
03073 
03074   if (aShape.IsNull() || anAx1.IsNull()) return NULL;
03075 
03076   TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
03077   if ( !checkTypeShapesOn( aShapeType ))
03078     return NULL;
03079 
03080   // Create plane
03081   Handle(Geom_Surface) aPlane = makePlane( anAx1 );
03082   if ( aPlane.IsNull() )
03083     return NULL;
03084 
03085   // Find object IDs
03086   Handle(TColStd_HSequenceOfInteger) aSeq;
03087   aSeq = getShapesOnSurfaceIDs( aPlane, aShape, aShapeType, theState );
03088 
03089   // The GetShapesOnPlaneIDs() doesn't change object so no new function is required.
03090   Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAx1)->GetLastFunction();
03091 
03092   // Make a Python command
03093   GEOM::TPythonDump(aFunction, /*append=*/true)
03094     << "listShapesOnPlane = geompy.GetShapesOnPlaneIDs"
03095     << "(" << theShape << "," << aShapeType << "," << theAx1 << "," << theState << ")";
03096 
03097   SetErrorCode(OK);
03098   return aSeq;
03099 }
03100 
03101 //=============================================================================
03105 //=============================================================================
03106 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnPlaneWithLocationIDs
03107                                         (const Handle(GEOM_Object)& theShape,
03108                                          const Standard_Integer     theShapeType,
03109                                          const Handle(GEOM_Object)& theAx1,
03110                                          const Handle(GEOM_Object)& thePnt,
03111                                          const GEOMAlgo_State       theState)
03112 {
03113   SetErrorCode(KO);
03114 
03115   if (theShape.IsNull() || theAx1.IsNull() || thePnt.IsNull()) return NULL;
03116 
03117   TopoDS_Shape aShape = theShape->GetValue();
03118   TopoDS_Shape anAx1  = theAx1->GetValue();
03119   TopoDS_Shape anPnt  = thePnt->GetValue();
03120 
03121   if (aShape.IsNull() || anAx1.IsNull() || anPnt.IsNull()) return NULL;
03122 
03123   TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
03124   if ( !checkTypeShapesOn( aShapeType ))
03125     return NULL;
03126 
03127   // Create plane
03128   if (anAx1.ShapeType() != TopAbs_EDGE || anPnt.ShapeType() != TopAbs_VERTEX) return NULL;
03129   TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
03130   TopoDS_Vertex V1, V2, V3;
03131   TopExp::Vertices(anEdge, V1, V2, Standard_True);
03132   if (V1.IsNull() || V2.IsNull()) {
03133     SetErrorCode("Bad edge given for the plane normal vector");
03134     return NULL;
03135   }
03136   V3 = TopoDS::Vertex(anPnt);
03137   if(V3.IsNull()) {
03138     SetErrorCode("Bad vertex given for the plane location");
03139       return NULL;
03140   }
03141   gp_Pnt aLoc = BRep_Tool::Pnt(V3);
03142   gp_Vec aVec(BRep_Tool::Pnt(V1),BRep_Tool::Pnt(V2));
03143   if (aVec.Magnitude() < Precision::Confusion()) {
03144     SetErrorCode("Vector with null magnitude given");
03145     return NULL;
03146   }
03147 
03148   Handle(Geom_Surface) aPlane = new Geom_Plane(aLoc, aVec);
03149   if ( aPlane.IsNull() )
03150     return NULL;
03151 
03152   // Find object IDs
03153   Handle(TColStd_HSequenceOfInteger) aSeq;
03154   aSeq = getShapesOnSurfaceIDs( aPlane, aShape, aShapeType, theState );
03155 
03156   // The GetShapesOnPlaneIDs() doesn't change object so no new function is required.
03157   Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAx1)->GetLastFunction();
03158 
03159   // Make a Python command
03160   GEOM::TPythonDump(aFunction, /*append=*/true)
03161     << "listShapesOnPlane = geompy.GetShapesOnPlaneWithLocationIDs"
03162     << "(" << theShape << ", " << aShapeType << ", " << theAx1 << ", "<< thePnt << ", "  << theState << ")";
03163 
03164   SetErrorCode(OK);
03165   return aSeq;
03166 }
03167 
03168 //=============================================================================
03172 //=============================================================================
03173 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnCylinderIDs
03174                                           (const Handle(GEOM_Object)& theShape,
03175                                            const Standard_Integer     theShapeType,
03176                                            const Handle(GEOM_Object)& theAxis,
03177                                            const Standard_Real        theRadius,
03178                                            const GEOMAlgo_State       theState)
03179 {
03180   SetErrorCode(KO);
03181 
03182   if (theShape.IsNull() || theAxis.IsNull()) return NULL;
03183 
03184   TopoDS_Shape aShape = theShape->GetValue();
03185   TopoDS_Shape anAxis = theAxis->GetValue();
03186 
03187   if (aShape.IsNull() || anAxis.IsNull()) return NULL;
03188 
03189   TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
03190   if ( !checkTypeShapesOn( aShapeType ))
03191     return NULL;
03192 
03193   // Create a cylinder surface
03194   Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
03195   if ( aCylinder.IsNull() )
03196     return NULL;
03197 
03198   // Find object IDs
03199   Handle(TColStd_HSequenceOfInteger) aSeq;
03200   aSeq = getShapesOnSurfaceIDs( aCylinder, aShape, aShapeType, theState );
03201 
03202   // The GetShapesOnCylinder() doesn't change object so no new function is required.
03203   Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAxis)->GetLastFunction();
03204 
03205   // Make a Python command
03206   GEOM::TPythonDump(aFunction, /*append=*/true)
03207     << "listShapesOnCylinder = geompy.GetShapesOnCylinderIDs"
03208     << "(" << theShape << ", " << aShapeType << ", " << theAxis << ", "
03209     << theRadius << ", " << theState << ")";
03210 
03211   SetErrorCode(OK);
03212   return aSeq;
03213 }
03214 
03215 //=============================================================================
03219 //=============================================================================
03220 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnCylinderWithLocationIDs
03221                                           (const Handle(GEOM_Object)& theShape,
03222                                            const Standard_Integer     theShapeType,
03223                                            const Handle(GEOM_Object)& theAxis,
03224                                            const Handle(GEOM_Object)& thePnt,
03225                                            const Standard_Real        theRadius,
03226                                            const GEOMAlgo_State       theState)
03227 {
03228   SetErrorCode(KO);
03229 
03230   if (theShape.IsNull() || theAxis.IsNull() || thePnt.IsNull()) return NULL;
03231 
03232   TopoDS_Shape aShape = theShape->GetValue();
03233   TopoDS_Shape anAxis = theAxis->GetValue();
03234   TopoDS_Shape aPnt   = thePnt->GetValue();
03235 
03236   if (aShape.IsNull() || anAxis.IsNull() || aPnt.IsNull()) return NULL;
03237 
03238   if (aPnt.ShapeType() != TopAbs_VERTEX )
03239   {
03240     SetErrorCode("Bottom location point must be vertex");
03241     return NULL;
03242   }
03243 
03244   TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
03245   if ( !checkTypeShapesOn( aShapeType ))
03246     return NULL;
03247 
03248   // Create a cylinder surface
03249   Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
03250   if ( aCylinder.IsNull() )
03251     return NULL;
03252 
03253   // translate the surface
03254   Handle(Geom_CylindricalSurface) aCylSurface =
03255     Handle(Geom_CylindricalSurface)::DownCast( aCylinder );
03256   if ( aCylSurface.IsNull() )
03257   {
03258     SetErrorCode("Unexpected surface type instead of Geom_CylindricalSurface");
03259     return NULL;
03260   }
03261   gp_Pnt fromLoc = aCylSurface->Cylinder().Location();
03262   gp_Pnt toLoc   = BRep_Tool::Pnt( TopoDS::Vertex( aPnt ));
03263   aCylinder->Translate( fromLoc, toLoc );
03264 
03265   // Find object IDs
03266   Handle(TColStd_HSequenceOfInteger) aSeq;
03267   aSeq = getShapesOnSurfaceIDs( aCylinder, aShape, aShapeType, theState );
03268 
03269   // The GetShapesOnCylinder() doesn't change object so no new function is required.
03270   Handle(GEOM_Function) aFunction =
03271     GEOM::GetCreatedLast(theShape, GEOM::GetCreatedLast(thePnt,theAxis))->GetLastFunction();
03272 
03273   // Make a Python command
03274   GEOM::TPythonDump(aFunction, /*append=*/true)
03275     << "listShapesOnCylinder = geompy.GetShapesOnCylinderWithLocationIDs"
03276     << "(" << theShape << ", " << aShapeType << ", " << theAxis << ", "
03277     << thePnt << ", " << theRadius << ", " << theState << ")";
03278 
03279   SetErrorCode(OK);
03280   return aSeq;
03281 }
03282 
03283 //=============================================================================
03287 //=============================================================================
03288 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnSphereIDs
03289                                           (const Handle(GEOM_Object)& theShape,
03290                                            const Standard_Integer     theShapeType,
03291                                            const Handle(GEOM_Object)& theCenter,
03292                                            const Standard_Real        theRadius,
03293                                            const GEOMAlgo_State       theState)
03294 {
03295   SetErrorCode(KO);
03296 
03297   if (theShape.IsNull() || theCenter.IsNull()) return NULL;
03298 
03299   TopoDS_Shape aShape  = theShape->GetValue();
03300   TopoDS_Shape aCenter = theCenter->GetValue();
03301 
03302   if (aShape.IsNull() || aCenter.IsNull()) return NULL;
03303 
03304   TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
03305   if ( !checkTypeShapesOn( aShapeType ))
03306     return NULL;
03307 
03308   // Center of the sphere
03309   if (aCenter.ShapeType() != TopAbs_VERTEX) return NULL;
03310   gp_Pnt aLoc = BRep_Tool::Pnt(TopoDS::Vertex(aCenter));
03311 
03312   gp_Ax3 anAx3 (aLoc, gp::DZ());
03313   Handle(Geom_SphericalSurface) aSphere =
03314     new Geom_SphericalSurface(anAx3, theRadius);
03315 
03316   // Find object IDs
03317   Handle(TColStd_HSequenceOfInteger) aSeq;
03318   aSeq = getShapesOnSurfaceIDs( aSphere, aShape, aShapeType, theState );
03319 
03320   // The GetShapesOnSphere() doesn't change object so no new function is required.
03321   Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theCenter)->GetLastFunction();
03322 
03323   // Make a Python command
03324   GEOM::TPythonDump(aFunction, /*append=*/true)
03325     << "listShapesOnCylinder = geompy.GetShapesOnCylinderIDs"
03326     << "(" << theShape << ", " << aShapeType << ", " << theCenter << ", "
03327     << theRadius << ", " << theState << ")";
03328 
03329   SetErrorCode(OK);
03330   return aSeq;
03331 }
03332 
03333 //=======================================================================
03334 //function : getShapesOnQuadrangleIDs
03346 //=======================================================================
03347 Handle(TColStd_HSequenceOfInteger)
03348   GEOMImpl_IShapesOperations::getShapesOnQuadrangleIDs (const Handle(GEOM_Object)& theShape,
03349                                                         const Standard_Integer     theShapeType,
03350                                                         const Handle(GEOM_Object)& theTopLeftPoint,
03351                                                         const Handle(GEOM_Object)& theTopRigthPoint,
03352                                                         const Handle(GEOM_Object)& theBottomLeftPoint,
03353                                                         const Handle(GEOM_Object)& theBottomRigthPoint,
03354                                                         const GEOMAlgo_State       theState)
03355 {
03356   SetErrorCode(KO);
03357 
03358   if ( theShape.IsNull() ||
03359        theTopLeftPoint.IsNull() ||
03360        theTopRigthPoint.IsNull() ||
03361        theBottomLeftPoint.IsNull() ||
03362        theBottomRigthPoint.IsNull() )
03363     return NULL;
03364 
03365   TopoDS_Shape aShape = theShape->GetValue();
03366   TopoDS_Shape aTL = theTopLeftPoint->GetValue();
03367   TopoDS_Shape aTR = theTopRigthPoint->GetValue();
03368   TopoDS_Shape aBL = theBottomLeftPoint->GetValue();
03369   TopoDS_Shape aBR = theBottomRigthPoint->GetValue();
03370 
03371   if (aShape.IsNull() ||
03372       aTL.IsNull() ||
03373       aTR.IsNull() ||
03374       aBL.IsNull() ||
03375       aBR.IsNull() ||
03376       aTL.ShapeType() != TopAbs_VERTEX ||
03377       aTR.ShapeType() != TopAbs_VERTEX ||
03378       aBL.ShapeType() != TopAbs_VERTEX ||
03379       aBR.ShapeType() != TopAbs_VERTEX )
03380     return NULL;
03381 
03382   TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
03383   if ( !checkTypeShapesOn( aShapeType ))
03384     return NULL;
03385 
03386   Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
03387 
03388   // Check presence of triangulation, build if need
03389   if (!CheckTriangulation(aShape)) {
03390     SetErrorCode("Cannot build triangulation on the shape");
03391     return aSeqOfIDs;
03392   }
03393 
03394   // Call algo
03395   gp_Pnt aPntTL = BRep_Tool::Pnt(TopoDS::Vertex(aTL));
03396   gp_Pnt aPntTR = BRep_Tool::Pnt(TopoDS::Vertex(aTR));
03397   gp_Pnt aPntBL = BRep_Tool::Pnt(TopoDS::Vertex(aBL));
03398   gp_Pnt aPntBR = BRep_Tool::Pnt(TopoDS::Vertex(aBR));
03399 
03400   GEOMAlgo_FinderShapeOnQuad aFinder( aPntTL, aPntTR, aPntBL, aPntBR );
03401   Standard_Real aTol = 0.0001; // default value
03402 
03403   aFinder.SetShape(aShape);
03404   aFinder.SetTolerance(aTol);
03405   //aFinder.SetSurface(theSurface);
03406   aFinder.SetShapeType(aShapeType);
03407   aFinder.SetState(theState);
03408 
03409   // Sets the minimal number of inner points for the faces that do not have own
03410   // inner points at all (for e.g. rectangular planar faces have just 2 triangles).
03411   // Default value=3
03412   aFinder.SetNbPntsMin(3);
03413   // Sets the maximal number of inner points for edges or faces.
03414   // It is usefull for the cases when this number is very big (e.g =2000) to improve
03415   // the performance. If this value =0, all inner points will be taken into account.
03416   // Default value=0
03417   aFinder.SetNbPntsMax(100);
03418 
03419   aFinder.Perform();
03420 
03421   // Interprete results
03422   Standard_Integer iErr = aFinder.ErrorStatus();
03423   // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
03424   if (iErr) {
03425     MESSAGE(" iErr : " << iErr);
03426     TCollection_AsciiString aMsg (" iErr : ");
03427     aMsg += TCollection_AsciiString(iErr);
03428     SetErrorCode(aMsg);
03429     return aSeqOfIDs;
03430   }
03431   Standard_Integer iWrn = aFinder.WarningStatus();
03432   // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
03433   if (iWrn) {
03434     MESSAGE(" *** iWrn : " << iWrn);
03435   }
03436 
03437   const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
03438 
03439   if (listSS.Extent() < 1) {
03440     //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
03441     SetErrorCode(NOT_FOUND_ANY); // NPAL18017
03442     return aSeqOfIDs;
03443   }
03444 
03445   // Fill sequence of object IDs
03446   aSeqOfIDs = new TColStd_HSequenceOfInteger;
03447 
03448   TopTools_IndexedMapOfShape anIndices;
03449   TopExp::MapShapes(aShape, anIndices);
03450 
03451   TopTools_ListIteratorOfListOfShape itSub (listSS);
03452   for (int index = 1; itSub.More(); itSub.Next(), ++index) {
03453     int id = anIndices.FindIndex(itSub.Value());
03454     aSeqOfIDs->Append(id);
03455   }
03456   return aSeqOfIDs;
03457 }
03458 
03459 //=======================================================================
03460 //function : GetShapesOnQuadrangle
03472 //=======================================================================
03473 Handle(TColStd_HSequenceOfTransient)
03474     GEOMImpl_IShapesOperations::GetShapesOnQuadrangle (const Handle(GEOM_Object)& theShape,
03475                                                        const Standard_Integer     theShapeType,
03476                                                        const Handle(GEOM_Object)& theTopLeftPoint,
03477                                                        const Handle(GEOM_Object)& theTopRigthPoint,
03478                                                        const Handle(GEOM_Object)& theBottomLeftPoint,
03479                                                        const Handle(GEOM_Object)& theBottomRigthPoint,
03480                                                        const GEOMAlgo_State       theState)
03481 {
03482   // Find indices
03483   Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
03484     getShapesOnQuadrangleIDs( theShape,
03485                               theShapeType,
03486                               theTopLeftPoint,
03487                               theTopRigthPoint,
03488                               theBottomLeftPoint,
03489                               theBottomRigthPoint,
03490                               theState);
03491   if ( aSeqOfIDs.IsNull() || aSeqOfIDs->IsEmpty() )
03492     return NULL;
03493 
03494   // Find objects by indices
03495   TCollection_AsciiString anAsciiList;
03496   Handle(TColStd_HSequenceOfTransient) aSeq;
03497   aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
03498   if ( aSeq.IsNull() || aSeq->IsEmpty() )
03499     return NULL;
03500 
03501   // Make a Python command
03502 
03503   Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
03504   Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
03505 
03506   GEOM::TPythonDump(aFunction)
03507     << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnQuadrangle("
03508     << theShape << ", "
03509     << TopAbs_ShapeEnum(theShapeType) << ", "
03510     << theTopLeftPoint << ", "
03511     << theTopRigthPoint << ", "
03512     << theBottomLeftPoint << ", "
03513     << theBottomRigthPoint << ", "
03514     << theState << ")";
03515 
03516   SetErrorCode(OK);
03517   return aSeq;
03518 }
03519 
03520 //=======================================================================
03521 //function : GetShapesOnQuadrangleIDs
03533 //=======================================================================
03534 Handle(TColStd_HSequenceOfInteger)
03535   GEOMImpl_IShapesOperations::GetShapesOnQuadrangleIDs (const Handle(GEOM_Object)& theShape,
03536                                                         const Standard_Integer     theShapeType,
03537                                                         const Handle(GEOM_Object)& theTopLeftPoint,
03538                                                         const Handle(GEOM_Object)& theTopRigthPoint,
03539                                                         const Handle(GEOM_Object)& theBottomLeftPoint,
03540                                                         const Handle(GEOM_Object)& theBottomRigthPoint,
03541                                                         const GEOMAlgo_State       theState)
03542 {
03543   // Find indices
03544   Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
03545     getShapesOnQuadrangleIDs( theShape,
03546                               theShapeType,
03547                               theTopLeftPoint,
03548                               theTopRigthPoint,
03549                               theBottomLeftPoint,
03550                               theBottomRigthPoint,
03551                               theState);
03552   if ( aSeqOfIDs.IsNull() || aSeqOfIDs->IsEmpty() )
03553     return NULL;
03554 
03555   // Make a Python command
03556 
03557   // The GetShapesOnCylinder() doesn't change object so no new function is required.
03558   Handle(GEOM_Object) lastObj = GEOM::GetCreatedLast(theShape,theTopLeftPoint);
03559   lastObj = GEOM::GetCreatedLast(lastObj,theTopRigthPoint);
03560   lastObj = GEOM::GetCreatedLast(lastObj,theBottomRigthPoint);
03561   lastObj = GEOM::GetCreatedLast(lastObj,theBottomLeftPoint);
03562   Handle(GEOM_Function) aFunction = lastObj->GetLastFunction();
03563 
03564   GEOM::TPythonDump(aFunction, /*append=*/true)
03565     << "listShapesOnQuadrangle = geompy.GetShapesOnQuadrangleIDs("
03566     << theShape << ", "
03567     << TopAbs_ShapeEnum(theShapeType) << ", "
03568     << theTopLeftPoint << ", "
03569     << theTopRigthPoint << ", "
03570     << theBottomLeftPoint << ", "
03571     << theBottomRigthPoint << ", "
03572     << theState << ")";
03573 
03574   SetErrorCode(OK);
03575   return aSeqOfIDs;
03576 }
03577 
03578 //=============================================================================
03582 //=============================================================================
03583 static bool GetInPlaceOfShape (const Handle(GEOM_Function)& theWhereFunction,
03584                                const TopTools_IndexedMapOfShape& theWhereIndices,
03585                                const TopoDS_Shape& theWhat,
03586                                TColStd_ListOfInteger& theModifiedList)
03587 {
03588   if (theWhereFunction.IsNull() || theWhat.IsNull()) return false;
03589 
03590   if (theWhereIndices.Contains(theWhat)) {
03591     // entity was not changed by the operation
03592     Standard_Integer aWhatIndex = theWhereIndices.FindIndex(theWhat);
03593     theModifiedList.Append(aWhatIndex);
03594     return true;
03595   }
03596 
03597   // try to find in history
03598   TDF_Label aHistoryLabel = theWhereFunction->GetHistoryEntry(Standard_False);
03599 
03600   // search in history for all argument shapes
03601   Standard_Boolean isFound = Standard_False;
03602   Standard_Boolean isGood = Standard_False;
03603 
03604   TDF_LabelSequence aLabelSeq;
03605   theWhereFunction->GetDependency(aLabelSeq);
03606   Standard_Integer nbArg = aLabelSeq.Length();
03607 
03608   for (Standard_Integer iarg = 1; iarg <= nbArg && !isFound; iarg++) {
03609 
03610     TDF_Label anArgumentRefLabel = aLabelSeq.Value(iarg);
03611 
03612     Handle(GEOM_Object) anArgumentObject = GEOM_Object::GetReferencedObject(anArgumentRefLabel);
03613     TopoDS_Shape anArgumentShape = anArgumentObject->GetValue();
03614 
03615     TopTools_IndexedMapOfShape anArgumentIndices;
03616     TopExp::MapShapes(anArgumentShape, anArgumentIndices);
03617 
03618     if (anArgumentIndices.Contains(theWhat)) {
03619       isFound = Standard_True;
03620       Standard_Integer aWhatIndex = anArgumentIndices.FindIndex(theWhat);
03621 
03622       // Find corresponding label in history
03623       TDF_Label anArgumentHistoryLabel =
03624         theWhereFunction->GetArgumentHistoryEntry(anArgumentRefLabel, Standard_False);
03625       if (anArgumentHistoryLabel.IsNull()) {
03626         // Lost History of operation argument. Possibly, all its entities was removed.
03627         isGood = Standard_True;
03628       }
03629       else {
03630         TDF_Label aWhatHistoryLabel = anArgumentHistoryLabel.FindChild(aWhatIndex, Standard_False);
03631 
03632         if (aWhatHistoryLabel.IsNull()) {
03633           // Removed entity ? Compound ? Compsolid ? Shell ? Wire
03634           isGood = Standard_False;
03635         } else {
03636           Handle(TDataStd_IntegerArray) anIntegerArray;
03637           if (!aWhatHistoryLabel.FindAttribute(TDataStd_IntegerArray::GetID(), anIntegerArray)) {
03638             //Error: Empty modifications history for the sought shape.
03639             isGood = Standard_False;
03640           }
03641           else {
03642             isGood = Standard_True;
03643             Standard_Integer imod, aModifLen = anIntegerArray->Array()->Length();
03644             for (imod = 1; imod <= aModifLen; imod++) {
03645               theModifiedList.Append(anIntegerArray->Array()->Value(imod));
03646             }
03647           }
03648         }
03649       }
03650     }
03651   }
03652 
03653   isFound = isGood;
03654 
03655   if (!isFound) {
03656     // try compound/compsolid/shell/wire element by element
03657     bool isFoundAny = false;
03658     TopTools_MapOfShape mapShape;
03659 
03660     if (theWhat.ShapeType() == TopAbs_COMPOUND ||
03661         theWhat.ShapeType() == TopAbs_COMPSOLID) {
03662       // recursive processing of compound/compsolid
03663       TopoDS_Iterator anIt (theWhat, Standard_True, Standard_True);
03664       for (; anIt.More(); anIt.Next()) {
03665         if (mapShape.Add(anIt.Value())) {
03666           TopoDS_Shape curWhat = anIt.Value();
03667           isFoundAny = GetInPlaceOfShape(theWhereFunction, theWhereIndices, curWhat, theModifiedList);
03668           if (isFoundAny) isFound = Standard_True;
03669         }
03670       }
03671     }
03672     else if (theWhat.ShapeType() == TopAbs_SHELL) {
03673       // try to replace a shell by its faces images
03674       TopExp_Explorer anExp (theWhat, TopAbs_FACE);
03675       for (; anExp.More(); anExp.Next()) {
03676         if (mapShape.Add(anExp.Current())) {
03677           TopoDS_Shape curWhat = anExp.Current();
03678           isFoundAny = GetInPlaceOfShape(theWhereFunction, theWhereIndices, curWhat, theModifiedList);
03679           if (isFoundAny) isFound = Standard_True;
03680         }
03681       }
03682     }
03683     else if (theWhat.ShapeType() == TopAbs_WIRE) {
03684       // try to replace a wire by its edges images
03685       TopExp_Explorer anExp (theWhat, TopAbs_EDGE);
03686       for (; anExp.More(); anExp.Next()) {
03687         if (mapShape.Add(anExp.Current())) {
03688           TopoDS_Shape curWhat = anExp.Current();
03689           isFoundAny = GetInPlaceOfShape(theWhereFunction, theWhereIndices, curWhat, theModifiedList);
03690           if (isFoundAny) isFound = Standard_True;
03691         }
03692       }
03693     }
03694     else {
03695       // Removed entity
03696     }
03697   }
03698 
03699   return isFound;
03700 }
03701 
03702 //=============================================================================
03706 //=============================================================================
03707 void GEOMImpl_IShapesOperations::GetShapeProperties( const TopoDS_Shape aShape, Standard_Real tab[],
03708                                                      gp_Pnt & aVertex )
03709 {
03710   GProp_GProps theProps;
03711   gp_Pnt aCenterMass;
03712   //TopoDS_Shape aPntShape;
03713   Standard_Real aShapeSize;
03714 
03715   if    (aShape.ShapeType() == TopAbs_VERTEX) aCenterMass = BRep_Tool::Pnt( TopoDS::Vertex( aShape ) );
03716   else if (aShape.ShapeType() == TopAbs_EDGE) BRepGProp::LinearProperties(aShape,  theProps);
03717   else if (aShape.ShapeType() == TopAbs_FACE) BRepGProp::SurfaceProperties(aShape, theProps);
03718   else                                        BRepGProp::VolumeProperties(aShape,  theProps);
03719 
03720   if (aShape.ShapeType() == TopAbs_VERTEX)
03721     aShapeSize = 1;
03722   else {
03723     aCenterMass = theProps.CentreOfMass();
03724     aShapeSize  = theProps.Mass();
03725   }
03726 
03727 //   aPntShape = BRepBuilderAPI_MakeVertex(aCenterMass).Shape();
03728 //   aVertex   = BRep_Tool::Pnt( TopoDS::Vertex( aPntShape ) );
03729   aVertex = aCenterMass;
03730   tab[0] = aVertex.X();
03731   tab[1] = aVertex.Y();
03732   tab[2] = aVertex.Z();
03733   tab[3] = aShapeSize;
03734   return;
03735 }
03736 
03737 namespace {
03738 
03739   //================================================================================
03743   //================================================================================
03744 
03745   gp_Vec GetNormal (const TopoDS_Face& face, const BRepExtrema_DistShapeShape& extrema)
03746   {
03747     gp_Vec defaultNorm(1,0,0); // to have same normals on different faces
03748     try {
03749       // get UV at extrema point
03750       Standard_Real u,v, f,l;
03751       switch ( extrema.SupportTypeShape2(1) ) {
03752       case BRepExtrema_IsInFace: {
03753         extrema.ParOnFaceS2(1, u, v );
03754         break;
03755       }
03756       case BRepExtrema_IsOnEdge: {
03757         TopoDS_Edge edge = TopoDS::Edge( extrema.SupportOnShape2(1));
03758         Handle(Geom2d_Curve) pcurve = BRep_Tool::CurveOnSurface( edge, face, f,l );
03759         extrema.ParOnEdgeS2( 1, u );
03760         gp_Pnt2d uv = pcurve->Value( u );
03761         u = uv.Coord(1);
03762         v = uv.Coord(2);
03763         break;
03764       }
03765       case BRepExtrema_IsVertex: return defaultNorm;
03766       }
03767       // get derivatives
03768       BRepAdaptor_Surface surface( face, false );
03769       gp_Vec du, dv; gp_Pnt p;
03770       surface.D1( u, v, p, du, dv );
03771 
03772       return du ^ dv;
03773 
03774     } catch (Standard_Failure ) {
03775     }
03776     return defaultNorm;
03777   }
03778 }
03779 
03780 //================================================================================
03784 //================================================================================
03785 TopAbs_ShapeEnum GEOMImpl_IShapesOperations::GetTypeOfSimplePart (const TopoDS_Shape& theShape)
03786 {
03787   TopAbs_ShapeEnum aType = theShape.ShapeType();
03788   if      (aType == TopAbs_VERTEX)                             return TopAbs_VERTEX;
03789   else if (aType == TopAbs_EDGE  || aType == TopAbs_WIRE)      return TopAbs_EDGE;
03790   else if (aType == TopAbs_FACE  || aType == TopAbs_SHELL)     return TopAbs_FACE;
03791   else if (aType == TopAbs_SOLID || aType == TopAbs_COMPSOLID) return TopAbs_SOLID;
03792   else if (aType == TopAbs_COMPOUND) {
03793     // Only the iType of the first shape in the compound is taken into account
03794     TopoDS_Iterator It (theShape, Standard_False, Standard_False);
03795     if (It.More()) {
03796       return GetTypeOfSimplePart(It.Value());
03797     }
03798   }
03799   return TopAbs_SHAPE;
03800 }
03801 
03802 //=============================================================================
03807 //=============================================================================
03808 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlace (Handle(GEOM_Object) theShapeWhere,
03809                                                             Handle(GEOM_Object) theShapeWhat)
03810 {
03811   SetErrorCode(KO);
03812 
03813   if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
03814 
03815   TopoDS_Shape aWhere = theShapeWhere->GetValue();
03816   TopoDS_Shape aWhat  = theShapeWhat->GetValue();
03817   TopoDS_Shape aPntShape;
03818   TopoDS_Vertex aVertex;
03819 
03820   if (aWhere.IsNull() || aWhat.IsNull()) {
03821     SetErrorCode("Error: aWhere and aWhat TopoDS_Shape are Null.");
03822     return NULL;
03823   }
03824 
03825   Handle(GEOM_Function) aWhereFunction = theShapeWhere->GetLastFunction();
03826   if (aWhereFunction.IsNull()) {
03827     SetErrorCode("Error: aWhereFunction is Null.");
03828     return NULL;
03829   }
03830 
03831   TopTools_IndexedMapOfShape aWhereIndices;
03832   TopExp::MapShapes(aWhere, aWhereIndices);
03833 
03834   TopAbs_ShapeEnum iType = TopAbs_SOLID;
03835   Standard_Real    dl_l = 1e-3;
03836   Standard_Real    min_l, Tol_0D, Tol_1D, Tol_2D, Tol_3D, Tol_Mass;
03837   Standard_Real    aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
03838   Bnd_Box          BoundingBox;
03839   gp_Pnt           aPnt, aPnt_aWhat, tab_Pnt[2];
03840   GProp_GProps     aProps;
03841 
03842   // Find the iType of the aWhat shape
03843   iType = GetTypeOfSimplePart(aWhat);
03844   if (iType == TopAbs_SHAPE) {
03845     SetErrorCode("Error: An attempt to extract a shape of not supported type.");
03846     return NULL;
03847   }
03848 
03849   TopExp_Explorer Exp_aWhat  ( aWhat,  iType );
03850   TopExp_Explorer Exp_aWhere ( aWhere, iType );
03851   TopExp_Explorer Exp_Edge   ( aWhere, TopAbs_EDGE );
03852 
03853   // Find the shortest edge in theShapeWhere shape
03854   BRepBndLib::Add(aWhere, BoundingBox);
03855   BoundingBox.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
03856   min_l = fabs(aXmax - aXmin);
03857   if( min_l < fabs(aYmax - aYmin) ) min_l = fabs(aYmax - aYmin);
03858   if( min_l < fabs(aZmax - aZmin) ) min_l = fabs(aZmax - aZmin);
03859   min_l /= dl_l;
03860   // Mantis issue 0020908 BEGIN
03861   if (!Exp_Edge.More()) {
03862     min_l = Precision::Confusion();
03863   }
03864   // Mantis issue 0020908 END
03865   for ( Standard_Integer nbEdge = 0; Exp_Edge.More(); Exp_Edge.Next(), nbEdge++ ) {
03866     TopExp_Explorer Exp_Vertex( Exp_Edge.Current(), TopAbs_VERTEX);
03867     for ( Standard_Integer nbVertex = 0; Exp_Vertex.More(); Exp_Vertex.Next(), nbVertex++ ) {
03868       aPnt = BRep_Tool::Pnt( TopoDS::Vertex( Exp_Vertex.Current() ) );
03869       tab_Pnt[nbVertex] = aPnt;
03870     }
03871     if ( ! tab_Pnt[0].IsEqual(tab_Pnt[1], dl_l) ) {
03872       BRepGProp::LinearProperties(Exp_Edge.Current(), aProps);
03873       if ( aProps.Mass() < min_l ) min_l = aProps.Mass();
03874     }
03875   }
03876 
03877   // Compute tolerances
03878   Tol_0D = dl_l;
03879   Tol_1D = dl_l * min_l;
03880   Tol_2D = dl_l * ( min_l * min_l) * ( 2. + dl_l);
03881   Tol_3D = dl_l * ( min_l * min_l * min_l ) * ( 3. + (3 * dl_l) + (dl_l * dl_l) );
03882 
03883   if (Tol_0D < Precision::Confusion()) Tol_0D = Precision::Confusion();
03884   if (Tol_1D < Precision::Confusion()) Tol_1D = Precision::Confusion();
03885   if (Tol_2D < Precision::Confusion()) Tol_2D = Precision::Confusion();
03886   if (Tol_3D < Precision::Confusion()) Tol_3D = Precision::Confusion();
03887 
03888   Tol_Mass = Tol_3D;
03889   if ( iType == TopAbs_VERTEX )    Tol_Mass = Tol_0D;
03890   else if ( iType == TopAbs_EDGE ) Tol_Mass = Tol_1D;
03891   else if ( iType == TopAbs_FACE ) Tol_Mass = Tol_2D;
03892 
03893   // Searching for the sub-shapes inside the ShapeWhere shape
03894   GEOMAlgo_GetInPlace aGIP;
03895   aGIP.SetTolerance(Tol_1D);
03896   aGIP.SetTolMass(Tol_Mass);
03897   aGIP.SetTolCG(Tol_1D);
03898 
03899   aGIP.SetArgument(aWhat);
03900   aGIP.SetShapeWhere(aWhere);
03901 
03902   aGIP.Perform();
03903   int iErr = aGIP.ErrorStatus();
03904   if (iErr) {
03905     SetErrorCode("Error in GEOMAlgo_GetInPlace");
03906     return NULL;
03907   }
03908 
03909   // aGIP.IsFound() returns true only when the whole theShapeWhat
03910   // is found (as one shape or several parts). But we are also interested
03911   // in the partial result, that is why this check is commented.
03912   //if (!aGIP.IsFound()) {
03913   //  SetErrorCode(NOT_FOUND_ANY);
03914   //  return NULL;
03915   //}
03916 
03917   const TopTools_DataMapOfShapeListOfShape& aDMSLS = aGIP.Images();
03918   if (!aDMSLS.IsBound(aWhat)) {
03919     SetErrorCode(NOT_FOUND_ANY);
03920     return NULL;
03921   }
03922 
03923   // the list of shapes aLSA contains the shapes 
03924   // of the Shape For Search that corresponds 
03925   // to the Argument aWhat
03926   const TopTools_ListOfShape& aLSA = aDMSLS.Find(aWhat);
03927   if (aLSA.Extent() == 0) {
03928     SetErrorCode(NOT_FOUND_ANY); // Not found any Results
03929     return NULL;
03930   }
03931 
03932   Handle(TColStd_HArray1OfInteger) aModifiedArray = new TColStd_HArray1OfInteger (1, aLSA.Extent());
03933   TopTools_ListIteratorOfListOfShape anIterModif (aLSA);
03934   for (Standard_Integer imod = 1; anIterModif.More(); anIterModif.Next(), imod++) {
03935     if (aWhereIndices.Contains(anIterModif.Value())) {
03936       aModifiedArray->SetValue(imod, aWhereIndices.FindIndex(anIterModif.Value()));
03937     }
03938     else {
03939       SetErrorCode("Error: wrong sub-shape returned");
03940       return NULL;
03941     }
03942   }
03943 
03944   //Add a new object
03945   Handle(GEOM_Object) aResult = GetEngine()->AddSubShape(theShapeWhere, aModifiedArray);
03946   if (aResult.IsNull()) {
03947     SetErrorCode("Error in algorithm: result found, but cannot be returned.");
03948     return NULL;
03949   }
03950 
03951   if (aModifiedArray->Length() > 1 || theShapeWhat->GetType() == GEOM_GROUP) {
03952     //Set a GROUP type
03953     aResult->SetType(GEOM_GROUP);
03954 
03955     //Set a sub-shape type
03956     TopoDS_Shape aFirstFound = aLSA.First();
03957     TopAbs_ShapeEnum aShapeType = aFirstFound.ShapeType();
03958 
03959     TDF_Label aFreeLabel = aResult->GetFreeLabel();
03960     TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aShapeType);
03961   }
03962 
03963   //Make a Python command
03964   Handle(GEOM_Function) aFunction = aResult->GetFunction(1);
03965 
03966   GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetInPlace("
03967     << theShapeWhere << ", " << theShapeWhat << ", True)";
03968 
03969   SetErrorCode(OK);
03970   return aResult;
03971 }
03972 
03973 //=============================================================================
03978 //=============================================================================
03979 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlaceOld (Handle(GEOM_Object) theShapeWhere,
03980                                                                Handle(GEOM_Object) theShapeWhat)
03981 {
03982   SetErrorCode(KO);
03983 
03984   if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
03985 
03986   TopoDS_Shape aWhere = theShapeWhere->GetValue();
03987   TopoDS_Shape aWhat  = theShapeWhat->GetValue();
03988   TopoDS_Shape aPntShape;
03989   TopoDS_Vertex aVertex;
03990 
03991   if (aWhere.IsNull() || aWhat.IsNull()) {
03992     SetErrorCode("Error: aWhere and aWhat TopoDS_Shape are Null.");
03993     return NULL;
03994   }
03995 
03996   Handle(GEOM_Function) aWhereFunction = theShapeWhere->GetLastFunction();
03997   if (aWhereFunction.IsNull()) {
03998     SetErrorCode("Error: aWhereFunction is Null.");
03999     return NULL;
04000   }
04001 
04002   TopTools_IndexedMapOfShape aWhereIndices;
04003   TopExp::MapShapes(aWhere, aWhereIndices);
04004 
04005   TColStd_ListOfInteger aModifiedList;
04006   Standard_Integer aWhereIndex;
04007   Handle(TColStd_HArray1OfInteger) aModifiedArray;
04008   Handle(GEOM_Object) aResult;
04009 
04010   bool isFound = false;
04011   TopAbs_ShapeEnum iType = TopAbs_SOLID;
04012   //Standard_Real    aWhat_Mass = 0., aWhere_Mass = 0.;
04013   Standard_Real    tab_aWhat[4],    tab_aWhere[4];
04014   Standard_Real    dl_l = 1e-3;
04015   Standard_Real    min_l, Tol_0D, Tol_1D, Tol_2D, Tol_3D, Tol_Mass;
04016   Standard_Real    aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
04017   Bnd_Box          BoundingBox;
04018   gp_Pnt           aPnt, aPnt_aWhat, tab_Pnt[2];
04019   GProp_GProps     aProps;
04020 
04021   // Find the iType of the aWhat shape
04022   /*
04023   if      ( aWhat.ShapeType() == TopAbs_VERTEX )                                         iType = TopAbs_VERTEX;
04024   else if ( aWhat.ShapeType() == TopAbs_EDGE  || aWhat.ShapeType() == TopAbs_WIRE )      iType = TopAbs_EDGE;
04025   else if ( aWhat.ShapeType() == TopAbs_FACE  || aWhat.ShapeType() == TopAbs_SHELL )     iType = TopAbs_FACE;
04026   else if ( aWhat.ShapeType() == TopAbs_SOLID || aWhat.ShapeType() == TopAbs_COMPSOLID ) iType = TopAbs_SOLID;
04027   else if ( aWhat.ShapeType() == TopAbs_COMPOUND ) {
04028     // Only the iType of the first shape in the compound is taken into account
04029     TopoDS_Iterator It (aWhat, Standard_False, Standard_False);
04030     if ( !It.More() ) {
04031       SetErrorCode("Error: theShapeWhat is an empty COMPOUND.");
04032       return NULL;
04033     }
04034     TopAbs_ShapeEnum compType = It.Value().ShapeType();
04035     if      ( compType == TopAbs_VERTEX )                               iType = TopAbs_VERTEX;
04036     else if ( compType == TopAbs_EDGE  || compType == TopAbs_WIRE )     iType = TopAbs_EDGE;
04037     else if ( compType == TopAbs_FACE  || compType == TopAbs_SHELL)     iType = TopAbs_FACE;
04038     else if ( compType == TopAbs_SOLID || compType == TopAbs_COMPSOLID) iType = TopAbs_SOLID;
04039   }
04040   else {
04041     SetErrorCode("Error: An attempt to extract a shape of not supported type.");
04042     return NULL;
04043   }
04044   */
04045   iType = GetTypeOfSimplePart(aWhat);
04046   if (iType == TopAbs_SHAPE) {
04047     SetErrorCode("Error: An attempt to extract a shape of not supported type.");
04048     return NULL;
04049   }
04050 
04051   TopExp_Explorer Exp_aWhat  ( aWhat,  iType );
04052   TopExp_Explorer Exp_aWhere ( aWhere, iType );
04053   TopExp_Explorer Exp_Edge   ( aWhere, TopAbs_EDGE );
04054 
04055   // Find the shortest edge in theShapeWhere shape
04056   BRepBndLib::Add(aWhere, BoundingBox);
04057   BoundingBox.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
04058   min_l = fabs(aXmax - aXmin);
04059   if( min_l < fabs(aYmax - aYmin) ) min_l = fabs(aYmax - aYmin);
04060   if( min_l < fabs(aZmax - aZmin) ) min_l = fabs(aZmax - aZmin);
04061   min_l /= dl_l;
04062   // Mantis issue 0020908 BEGIN
04063   if (!Exp_Edge.More()) {
04064     min_l = Precision::Confusion();
04065   }
04066   // Mantis issue 0020908 END
04067   for ( Standard_Integer nbEdge = 0; Exp_Edge.More(); Exp_Edge.Next(), nbEdge++ ) {
04068     TopExp_Explorer Exp_Vertex( Exp_Edge.Current(), TopAbs_VERTEX);
04069     for ( Standard_Integer nbVertex = 0; Exp_Vertex.More(); Exp_Vertex.Next(), nbVertex++ ) {
04070       aPnt = BRep_Tool::Pnt( TopoDS::Vertex( Exp_Vertex.Current() ) );
04071       tab_Pnt[nbVertex] = aPnt;
04072     }
04073     if ( ! tab_Pnt[0].IsEqual(tab_Pnt[1], dl_l) ) {
04074       BRepGProp::LinearProperties(Exp_Edge.Current(), aProps);
04075       if ( aProps.Mass() < min_l ) min_l = aProps.Mass();
04076     }
04077   }
04078 
04079   // Compute tolerances
04080   Tol_0D = dl_l;
04081   Tol_1D = dl_l * min_l;
04082   Tol_2D = dl_l * ( min_l * min_l) * ( 2. + dl_l);
04083   Tol_3D = dl_l * ( min_l * min_l * min_l ) * ( 3. + (3 * dl_l) + (dl_l * dl_l) );
04084 
04085   if (Tol_0D < Precision::Confusion()) Tol_0D = Precision::Confusion();
04086   if (Tol_1D < Precision::Confusion()) Tol_1D = Precision::Confusion();
04087   if (Tol_2D < Precision::Confusion()) Tol_2D = Precision::Confusion();
04088   if (Tol_3D < Precision::Confusion()) Tol_3D = Precision::Confusion();
04089 
04090   //if (Tol_1D > 1.0) Tol_1D = 1.0;
04091   //if (Tol_2D > 1.0) Tol_2D = 1.0;
04092   //if (Tol_3D > 1.0) Tol_3D = 1.0;
04093 
04094   Tol_Mass = Tol_3D;
04095   if ( iType == TopAbs_VERTEX )    Tol_Mass = Tol_0D;
04096   else if ( iType == TopAbs_EDGE ) Tol_Mass = Tol_1D;
04097   else if ( iType == TopAbs_FACE ) Tol_Mass = Tol_2D;
04098 
04099   // Compute the ShapeWhat Mass
04100   /*
04101   for ( ; Exp_aWhat.More(); Exp_aWhat.Next() ) {
04102     if ( iType == TopAbs_VERTEX ) {
04103       aWhat_Mass += 1;
04104       continue;
04105     }
04106     else if ( iType == TopAbs_EDGE ) BRepGProp::LinearProperties(Exp_aWhat.Current(),  aProps);
04107     else if ( iType == TopAbs_FACE ) BRepGProp::SurfaceProperties(Exp_aWhat.Current(), aProps);
04108     else                             BRepGProp::VolumeProperties(Exp_aWhat.Current(),  aProps);
04109     aWhat_Mass += aProps.Mass();
04110   }
04111   */
04112 
04113   // Searching for the sub-shapes inside the ShapeWhere shape
04114   TopTools_MapOfShape map_aWhere;
04115   for ( Exp_aWhere.ReInit(); Exp_aWhere.More(); Exp_aWhere.Next() ) {
04116     if (!map_aWhere.Add(Exp_aWhere.Current()))
04117       continue; // skip repeated shape to avoid mass addition
04118     GetShapeProperties( Exp_aWhere.Current(), tab_aWhere, aPnt );
04119     for ( Exp_aWhat.ReInit(); Exp_aWhat.More(); Exp_aWhat.Next() ) {
04120       GetShapeProperties( Exp_aWhat.Current(), tab_aWhat, aPnt_aWhat );
04121       if ( fabs(tab_aWhat[3] - tab_aWhere[3]) <= Tol_Mass && aPnt_aWhat.Distance(aPnt) <= Tol_1D )
04122         isFound = true;
04123       else {
04124         if ( (tab_aWhat[3] - tab_aWhere[3]) > Tol_Mass ) {
04125           aPntShape = BRepBuilderAPI_MakeVertex( aPnt ).Shape();
04126           aVertex   = TopoDS::Vertex( aPntShape );
04127           BRepExtrema_DistShapeShape aWhereDistance ( aVertex, Exp_aWhere.Current() );
04128           BRepExtrema_DistShapeShape aWhatDistance  ( aVertex, Exp_aWhat.Current() );
04129           if ( aWhereDistance.IsDone() && aWhatDistance.IsDone() &&
04130                fabs(aWhereDistance.Value() - aWhatDistance.Value()) <= Tol_1D )
04131           {
04132             // 0020162: "EDF 961 GEOM : Getinplace is getting additionnal orthogonal faces"
04133             // aVertex must be projected to the same point on Where and on What
04134             gp_Pnt pOnWhat  = aWhatDistance.PointOnShape2(1);
04135             gp_Pnt pOnWhere = aWhereDistance.PointOnShape2(1);
04136             isFound = ( pOnWhat.Distance(pOnWhere) <= Tol_1D );
04137             if ( isFound && iType == TopAbs_FACE )
04138             {
04139               // check normals at pOnWhat and pOnWhere
04140               const double angleTol = M_PI/180.;
04141               gp_Vec normToWhat  = GetNormal( TopoDS::Face(Exp_aWhat.Current()), aWhatDistance);
04142               gp_Vec normToWhere = GetNormal( TopoDS::Face(Exp_aWhere.Current()), aWhereDistance);
04143               if ( normToWhat * normToWhere < 0 )
04144                 normToWhat.Reverse();
04145               isFound = ( normToWhat.Angle( normToWhere ) < angleTol );
04146             }
04147           }
04148         }
04149       }
04150       if ( isFound ) {
04151         aWhereIndex = aWhereIndices.FindIndex(Exp_aWhere.Current());
04152         aModifiedList.Append(aWhereIndex);
04153         //aWhere_Mass += tab_aWhere[3];
04154         isFound = false;
04155         break;
04156       }
04157     }
04158     //if ( fabs( aWhat_Mass - aWhere_Mass ) <= Tol_Mass )
04159       //break;
04160   }
04161 
04162   if (aModifiedList.Extent() == 0) { // Not found any Results
04163     SetErrorCode(NOT_FOUND_ANY);
04164     return NULL;
04165   }
04166 
04167   aModifiedArray = new TColStd_HArray1OfInteger (1, aModifiedList.Extent());
04168   TColStd_ListIteratorOfListOfInteger anIterModif (aModifiedList);
04169   for (Standard_Integer imod = 1; anIterModif.More(); anIterModif.Next(), imod++)
04170     aModifiedArray->SetValue(imod, anIterModif.Value());
04171 
04172   //Add a new object
04173   aResult = GetEngine()->AddSubShape(theShapeWhere, aModifiedArray);
04174   if (aResult.IsNull()) {
04175     SetErrorCode("Error in algorithm: result found, but cannot be returned.");
04176     return NULL;
04177   }
04178 
04179   if (aModifiedArray->Length() > 1 || theShapeWhat->GetType() == GEOM_GROUP) {
04180     //Set a GROUP type
04181     aResult->SetType(GEOM_GROUP);
04182 
04183     //Set a sub-shape type
04184     TopoDS_Shape aFirstFound = aWhereIndices.FindKey(aModifiedArray->Value(1));
04185     TopAbs_ShapeEnum aShapeType = aFirstFound.ShapeType();
04186 
04187     TDF_Label aFreeLabel = aResult->GetFreeLabel();
04188     TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aShapeType);
04189   }
04190 
04191   //Make a Python command
04192   Handle(GEOM_Function) aFunction = aResult->GetFunction(1);
04193 
04194   GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetInPlace("
04195     << theShapeWhere << ", " << theShapeWhat << ", False)";
04196 
04197   SetErrorCode(OK);
04198   return aResult;
04199 }
04200 
04201 //=======================================================================
04202 //function : GetInPlaceByHistory
04203 //purpose  :
04204 //=======================================================================
04205 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlaceByHistory
04206                                           (Handle(GEOM_Object) theShapeWhere,
04207                                            Handle(GEOM_Object) theShapeWhat)
04208 {
04209   SetErrorCode(KO);
04210 
04211   if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
04212 
04213   TopoDS_Shape aWhere = theShapeWhere->GetValue();
04214   TopoDS_Shape aWhat  = theShapeWhat->GetValue();
04215 
04216   if (aWhere.IsNull() || aWhat.IsNull()) return NULL;
04217 
04218   Handle(GEOM_Function) aWhereFunction = theShapeWhere->GetLastFunction();
04219   if (aWhereFunction.IsNull()) return NULL;
04220 
04221   //Fill array of indices
04222   TopTools_IndexedMapOfShape aWhereIndices;
04223   TopExp::MapShapes(aWhere, aWhereIndices);
04224 
04225   // process shape
04226   TColStd_ListOfInteger aModifiedList;
04227   bool isFound = GetInPlaceOfShape(aWhereFunction, aWhereIndices, aWhat, aModifiedList);
04228 
04229   if (!isFound || aModifiedList.Extent() < 1) {
04230     SetErrorCode("Error: No history found for the sought shape or its sub-shapes.");
04231     return NULL;
04232   }
04233 
04234   Handle(TColStd_HArray1OfInteger) aModifiedArray =
04235     new TColStd_HArray1OfInteger (1, aModifiedList.Extent());
04236   TColStd_ListIteratorOfListOfInteger anIterModif (aModifiedList);
04237   for (Standard_Integer imod = 1; anIterModif.More(); anIterModif.Next(), imod++) {
04238     aModifiedArray->SetValue(imod, anIterModif.Value());
04239   }
04240 
04241   //Add a new object
04242   Handle(GEOM_Object) aResult = GetEngine()->AddSubShape(theShapeWhere, aModifiedArray);
04243   if (aResult.IsNull()) {
04244     SetErrorCode("Error in algorithm: result found, but cannot be returned.");
04245     return NULL;
04246   }
04247 
04248   if (aModifiedArray->Length() > 1) {
04249     //Set a GROUP type
04250     aResult->SetType(GEOM_GROUP);
04251 
04252     //Set a sub-shape type
04253     TopoDS_Shape aFirstFound = aWhereIndices.FindKey(aModifiedArray->Value(1));
04254     TopAbs_ShapeEnum aShapeType = aFirstFound.ShapeType();
04255 
04256     TDF_Label aFreeLabel = aResult->GetFreeLabel();
04257     TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aShapeType);
04258   }
04259 
04260   //Make a Python command
04261   Handle(GEOM_Function) aFunction = aResult->GetFunction(1);
04262 
04263   GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetInPlaceByHistory("
04264     << theShapeWhere << ", " << theShapeWhat << ")";
04265 
04266   SetErrorCode(OK);
04267   return aResult;
04268 }
04269 
04270 //=======================================================================
04271 //function : ShapeToDouble
04272 //purpose  : used by CompareShapes::operator()
04273 //=======================================================================
04274 std::pair<double, double> ShapeToDouble (const TopoDS_Shape& S, bool isOldSorting)
04275 {
04276   // Computing of CentreOfMass
04277   gp_Pnt GPoint;
04278   double Len;
04279 
04280   if (S.ShapeType() == TopAbs_VERTEX) {
04281     GPoint = BRep_Tool::Pnt(TopoDS::Vertex(S));
04282     Len = (double)S.Orientation();
04283   }
04284   else {
04285     GProp_GProps GPr;
04286     // BEGIN: fix for Mantis issue 0020842
04287     if (isOldSorting) {
04288       BRepGProp::LinearProperties(S, GPr);
04289     }
04290     else {
04291       if (S.ShapeType() == TopAbs_EDGE || S.ShapeType() == TopAbs_WIRE) {
04292         BRepGProp::LinearProperties(S, GPr);
04293       }
04294       else if (S.ShapeType() == TopAbs_FACE || S.ShapeType() == TopAbs_SHELL) {
04295         BRepGProp::SurfaceProperties(S, GPr);
04296       }
04297       else {
04298         BRepGProp::VolumeProperties(S, GPr);
04299       }
04300     }
04301     // END: fix for Mantis issue 0020842
04302     GPoint = GPr.CentreOfMass();
04303     Len = GPr.Mass();
04304   }
04305 
04306   double dMidXYZ = GPoint.X() * 999.0 + GPoint.Y() * 99.0 + GPoint.Z() * 0.9;
04307   return std::make_pair(dMidXYZ, Len);
04308 }
04309 
04310 //=======================================================================
04311 //function : CompareShapes::operator()
04312 //purpose  : used by std::sort(), called from SortShapes()
04313 //=======================================================================
04314 bool GEOMImpl_IShapesOperations::CompareShapes::operator()(const TopoDS_Shape& theShape1,
04315                                                            const TopoDS_Shape& theShape2)
04316 {
04317   if (!myMap.IsBound(theShape1)) {
04318     myMap.Bind(theShape1, ShapeToDouble(theShape1, myIsOldSorting));
04319   }
04320 
04321   if (!myMap.IsBound(theShape2)) {
04322     myMap.Bind(theShape2, ShapeToDouble(theShape2, myIsOldSorting));
04323   }
04324 
04325   std::pair<double, double> val1 = myMap.Find(theShape1);
04326   std::pair<double, double> val2 = myMap.Find(theShape2);
04327 
04328   double tol = Precision::Confusion();
04329   bool exchange = Standard_False;
04330 
04331   double dMidXYZ = val1.first - val2.first;
04332   if (dMidXYZ >= tol) {
04333     exchange = Standard_True;
04334   }
04335   else if (Abs(dMidXYZ) < tol) {
04336     double dLength = val1.second - val2.second;
04337     if (dLength >= tol) {
04338       exchange = Standard_True;
04339     }
04340     else if (Abs(dLength) < tol && theShape1.ShapeType() <= TopAbs_FACE) {
04341       // PAL17233
04342       // equal values possible on shapes such as two halves of a sphere and
04343       // a membrane inside the sphere
04344       Bnd_Box box1,box2;
04345       BRepBndLib::Add(theShape1, box1);
04346       if (!box1.IsVoid()) {
04347         BRepBndLib::Add(theShape2, box2);
04348         Standard_Real dSquareExtent = box1.SquareExtent() - box2.SquareExtent();
04349         if (dSquareExtent >= tol) {
04350           exchange = Standard_True;
04351         }
04352         else if (Abs(dSquareExtent) < tol) {
04353           Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax, val1, val2;
04354           box1.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
04355           val1 = (aXmin+aXmax)*999.0 + (aYmin+aYmax)*99.0 + (aZmin+aZmax)*0.9;
04356           box2.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
04357           val2 = (aXmin+aXmax)*999.0 + (aYmin+aYmax)*99.0 + (aZmin+aZmax)*0.9;
04358           if ((val1 - val2) >= tol) {
04359             exchange = Standard_True;
04360           }
04361         }
04362       }
04363     }
04364   }
04365 
04366   //return val1 < val2;
04367   return !exchange;
04368 }
04369 
04370 //=======================================================================
04371 //function : SortShapes
04372 //purpose  :
04373 //=======================================================================
04374 void GEOMImpl_IShapesOperations::SortShapes(TopTools_ListOfShape& SL,
04375                                             const Standard_Boolean isOldSorting)
04376 {
04377 #ifdef STD_SORT_ALGO
04378   std::vector<TopoDS_Shape> aShapesVec;
04379   aShapesVec.reserve(SL.Extent());
04380 
04381   TopTools_ListIteratorOfListOfShape it (SL);
04382   for (; it.More(); it.Next()) {
04383     aShapesVec.push_back(it.Value());
04384   }
04385   SL.Clear();
04386 
04387   CompareShapes shComp (isOldSorting);
04388   std::stable_sort(aShapesVec.begin(), aShapesVec.end(), shComp);
04389   //std::sort(aShapesVec.begin(), aShapesVec.end(), shComp);
04390 
04391   std::vector<TopoDS_Shape>::const_iterator anIter = aShapesVec.begin();
04392   for (; anIter != aShapesVec.end(); ++anIter) {
04393     SL.Append(*anIter);
04394   }
04395 #else
04396   // old implementation
04397   Standard_Integer MaxShapes = SL.Extent();
04398   TopTools_Array1OfShape  aShapes (1,MaxShapes);
04399   TColStd_Array1OfInteger OrderInd(1,MaxShapes);
04400   TColStd_Array1OfReal    MidXYZ  (1,MaxShapes); //X,Y,Z;
04401   TColStd_Array1OfReal    Length  (1,MaxShapes); //X,Y,Z;
04402 
04403   // Computing of CentreOfMass
04404   Standard_Integer Index;
04405   GProp_GProps GPr;
04406   gp_Pnt GPoint;
04407   TopTools_ListIteratorOfListOfShape it(SL);
04408   for (Index=1;  it.More();  Index++)
04409   {
04410     TopoDS_Shape S = it.Value();
04411     SL.Remove( it ); // == it.Next()
04412     aShapes(Index) = S;
04413     OrderInd.SetValue (Index, Index);
04414     if (S.ShapeType() == TopAbs_VERTEX) {
04415       GPoint = BRep_Tool::Pnt( TopoDS::Vertex( S ));
04416       Length.SetValue( Index, (Standard_Real) S.Orientation());
04417     }
04418     else {
04419       // BEGIN: fix for Mantis issue 0020842
04420       if (isOldSorting) {
04421         BRepGProp::LinearProperties (S, GPr);
04422       }
04423       else {
04424         if (S.ShapeType() == TopAbs_EDGE || S.ShapeType() == TopAbs_WIRE) {
04425           BRepGProp::LinearProperties (S, GPr);
04426         }
04427         else if (S.ShapeType() == TopAbs_FACE || S.ShapeType() == TopAbs_SHELL) {
04428           BRepGProp::SurfaceProperties(S, GPr);
04429         }
04430         else {
04431           BRepGProp::VolumeProperties(S, GPr);
04432         }
04433       }
04434       // END: fix for Mantis issue 0020842
04435       GPoint = GPr.CentreOfMass();
04436       Length.SetValue(Index, GPr.Mass());
04437     }
04438     MidXYZ.SetValue(Index, GPoint.X()*999.0 + GPoint.Y()*99.0 + GPoint.Z()*0.9);
04439     //cout << Index << " L: " << Length(Index) << "CG: " << MidXYZ(Index) << endl;
04440   }
04441 
04442   // Sorting
04443   Standard_Integer aTemp;
04444   Standard_Boolean exchange, Sort = Standard_True;
04445   Standard_Real    tol = Precision::Confusion();
04446   while (Sort)
04447   {
04448     Sort = Standard_False;
04449     for (Index=1; Index < MaxShapes; Index++)
04450     {
04451       exchange = Standard_False;
04452       Standard_Real dMidXYZ = MidXYZ(OrderInd(Index)) - MidXYZ(OrderInd(Index+1));
04453       Standard_Real dLength = Length(OrderInd(Index)) - Length(OrderInd(Index+1));
04454       if ( dMidXYZ >= tol ) {
04455 //         cout << "MidXYZ: " << MidXYZ(OrderInd(Index))<< " > " <<MidXYZ(OrderInd(Index+1))
04456 //              << " d: " << dMidXYZ << endl;
04457         exchange = Standard_True;
04458       }
04459       else if ( Abs(dMidXYZ) < tol && dLength >= tol ) {
04460 //         cout << "Length: " << Length(OrderInd(Index))<< " > " <<Length(OrderInd(Index+1))
04461 //              << " d: " << dLength << endl;
04462         exchange = Standard_True;
04463       }
04464       else if ( Abs(dMidXYZ) < tol && Abs(dLength) < tol &&
04465                 aShapes(OrderInd(Index)).ShapeType() <= TopAbs_FACE) {
04466         // PAL17233
04467         // equal values possible on shapes such as two halves of a sphere and
04468         // a membrane inside the sphere
04469         Bnd_Box box1,box2;
04470         BRepBndLib::Add( aShapes( OrderInd(Index) ), box1 );
04471         if ( box1.IsVoid() ) continue;
04472         BRepBndLib::Add( aShapes( OrderInd(Index+1) ), box2 );
04473         Standard_Real dSquareExtent = box1.SquareExtent() - box2.SquareExtent();
04474         if ( dSquareExtent >= tol ) {
04475 //           cout << "SquareExtent: " << box1.SquareExtent()<<" > "<<box2.SquareExtent() << endl;
04476           exchange = Standard_True;
04477         }
04478         else if ( Abs(dSquareExtent) < tol ) {
04479           Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax, val1, val2;
04480           box1.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
04481           val1 = (aXmin+aXmax)*999 + (aYmin+aYmax)*99 + (aZmin+aZmax)*0.9;
04482           box2.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
04483           val2 = (aXmin+aXmax)*999 + (aYmin+aYmax)*99 + (aZmin+aZmax)*0.9;
04484           //exchange = val1 > val2;
04485           if ((val1 - val2) >= tol) {
04486             exchange = Standard_True;
04487           }
04488           //cout << "box: " << val1<<" > "<<val2 << endl;
04489         }
04490       }
04491 
04492       if (exchange)
04493       {
04494 //         cout << "exchange " << Index << " & " << Index+1 << endl;
04495         aTemp = OrderInd(Index);
04496         OrderInd(Index) = OrderInd(Index+1);
04497         OrderInd(Index+1) = aTemp;
04498         Sort = Standard_True;
04499       }
04500     }
04501   }
04502 
04503   for (Index=1; Index <= MaxShapes; Index++)
04504     SL.Append( aShapes( OrderInd(Index) ));
04505 #endif
04506 }
04507 
04508 //=======================================================================
04509 //function : CompsolidToCompound
04510 //purpose  :
04511 //=======================================================================
04512 TopoDS_Shape GEOMImpl_IShapesOperations::CompsolidToCompound (const TopoDS_Shape& theCompsolid)
04513 {
04514   if (theCompsolid.ShapeType() != TopAbs_COMPSOLID) {
04515     return theCompsolid;
04516   }
04517 
04518   TopoDS_Compound aCompound;
04519   BRep_Builder B;
04520   B.MakeCompound(aCompound);
04521 
04522   TopTools_MapOfShape mapShape;
04523   TopoDS_Iterator It (theCompsolid, Standard_True, Standard_True);
04524 
04525   for (; It.More(); It.Next()) {
04526     TopoDS_Shape aShape_i = It.Value();
04527     if (mapShape.Add(aShape_i)) {
04528       B.Add(aCompound, aShape_i);
04529     }
04530   }
04531 
04532   return aCompound;
04533 }
04534 
04535 //=======================================================================
04536 //function : CheckTriangulation
04537 //purpose  :
04538 //=======================================================================
04539 bool GEOMImpl_IShapesOperations::CheckTriangulation (const TopoDS_Shape& aShape)
04540 {
04541   bool isTriangulation = true;
04542 
04543   TopExp_Explorer exp (aShape, TopAbs_FACE);
04544   if (exp.More())
04545   {
04546     TopLoc_Location aTopLoc;
04547     Handle(Poly_Triangulation) aTRF;
04548     aTRF = BRep_Tool::Triangulation(TopoDS::Face(exp.Current()), aTopLoc);
04549     if (aTRF.IsNull()) {
04550       isTriangulation = false;
04551     }
04552   }
04553   else // no faces, try edges
04554   {
04555     TopExp_Explorer expe (aShape, TopAbs_EDGE);
04556     if (!expe.More()) {
04557       return false;
04558     }
04559     TopLoc_Location aLoc;
04560     Handle(Poly_Polygon3D) aPE = BRep_Tool::Polygon3D(TopoDS::Edge(expe.Current()), aLoc);
04561     if (aPE.IsNull()) {
04562       isTriangulation = false;
04563     }
04564   }
04565 
04566   if (!isTriangulation) {
04567     // calculate deflection
04568     Standard_Real aDeviationCoefficient = 0.001;
04569 
04570     Bnd_Box B;
04571     BRepBndLib::Add(aShape, B);
04572     Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
04573     B.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
04574 
04575     Standard_Real dx = aXmax - aXmin, dy = aYmax - aYmin, dz = aZmax - aZmin;
04576     Standard_Real aDeflection = Max(Max(dx, dy), dz) * aDeviationCoefficient * 4;
04577     Standard_Real aHLRAngle = 0.349066;
04578 
04579     BRepMesh_IncrementalMesh Inc (aShape, aDeflection, Standard_False, aHLRAngle);
04580   }
04581 
04582   return true;
04583 }
04584 
04585 #define MAX_TOLERANCE 1.e-7
04586 
04587 //=======================================================================
04588 //function : isSameEdge
04589 //purpose  : Returns True if two edges coincide
04590 //=======================================================================
04591 static bool isSameEdge(const TopoDS_Edge& theEdge1, const TopoDS_Edge& theEdge2)
04592 {
04593   TopoDS_Vertex V11, V12, V21, V22;
04594   TopExp::Vertices(theEdge1, V11, V12);
04595   TopExp::Vertices(theEdge2, V21, V22);
04596   gp_Pnt P11 = BRep_Tool::Pnt(V11);
04597   gp_Pnt P12 = BRep_Tool::Pnt(V12);
04598   gp_Pnt P21 = BRep_Tool::Pnt(V21);
04599   gp_Pnt P22 = BRep_Tool::Pnt(V22);
04600   bool coincide = false;
04601 
04602   //Check that ends of edges coincide
04603   if(P11.Distance(P21) <= MAX_TOLERANCE) {
04604     if(P12.Distance(P22) <= MAX_TOLERANCE) coincide =  true;
04605   }
04606   else if(P11.Distance(P22) <= MAX_TOLERANCE) {
04607     if(P12.Distance(P21) <= MAX_TOLERANCE) coincide = true;
04608   }
04609 
04610   if(!coincide) return false;
04611 
04612   if (BRep_Tool::Degenerated(theEdge1))
04613     if (BRep_Tool::Degenerated(theEdge2)) return true;
04614     else return false;
04615   else
04616     if (BRep_Tool::Degenerated(theEdge2)) return false;
04617 
04618   double U11, U12, U21, U22;
04619   Handle(Geom_Curve) C1 = BRep_Tool::Curve(theEdge1, U11, U12);
04620   Handle(Geom_Curve) C2 = BRep_Tool::Curve(theEdge2, U21, U22);
04621   if(C1->DynamicType() == C2->DynamicType()) return true;
04622 
04623   //Check that both edges has the same geometry
04624   double range = U12-U11;
04625   double U = U11+ range/3.0;
04626   gp_Pnt P1 = C1->Value(U);     //Compute a point on one third of the edge's length
04627   U = U11+range*2.0/3.0;
04628   gp_Pnt P2 = C1->Value(U);     //Compute a point on two thirds of the edge's length
04629 
04630   if(!GeomLib_Tool::Parameter(C2, P1, MAX_TOLERANCE, U) ||  U < U21 || U > U22)
04631     return false;
04632 
04633   if(P1.Distance(C2->Value(U)) > MAX_TOLERANCE) return false;
04634 
04635   if(!GeomLib_Tool::Parameter(C2, P2, MAX_TOLERANCE, U) || U < U21 || U > U22)
04636     return false;
04637 
04638   if(P2.Distance(C2->Value(U)) > MAX_TOLERANCE) return false;
04639 
04640   return true;
04641 }
04642 
04643 #include <TopoDS_TShape.hxx>
04644 //=======================================================================
04645 //function : isSameFace
04646 //purpose  : Returns True if two faces coincide
04647 //=======================================================================
04648 static bool isSameFace(const TopoDS_Face& theFace1, const TopoDS_Face& theFace2)
04649 {
04650   TopExp_Explorer E(theFace1, TopAbs_EDGE);
04651   TopTools_ListOfShape LS1, LS2;
04652   for(; E.More(); E.Next()) LS1.Append(E.Current());
04653 
04654   E.Init(theFace2, TopAbs_EDGE);
04655   for(; E.More(); E.Next()) LS2.Append(E.Current());
04656 
04657   //Compare the number of edges in the faces
04658   if(LS1.Extent() != LS2.Extent()) return false;
04659 
04660   double aMin = RealFirst(), aMax = RealLast();
04661   double xminB1=aMax, yminB1=aMax, zminB1=aMax, xminB2=aMax, yminB2=aMax, zminB2=aMax;
04662   double xmaxB1=aMin, ymaxB1=aMin, zmaxB1=aMin, xmaxB2=aMin, ymaxB2=aMin, zmaxB2=aMin;
04663 
04664   for(E.Init(theFace1, TopAbs_VERTEX); E.More(); E.Next()) {
04665     gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
04666     if(P.X() < xminB1) xminB1 = P.X();
04667     if(P.Y() < yminB1) yminB1 = P.Y();
04668     if(P.Z() < zminB1) zminB1 = P.Z();
04669     if(P.X() > xmaxB1) xmaxB1 = P.X();
04670     if(P.Y() > ymaxB1) ymaxB1 = P.Y();
04671     if(P.Z() > zmaxB1) zmaxB1 = P.Z();
04672   }
04673 
04674   for(E.Init(theFace2, TopAbs_VERTEX); E.More(); E.Next()) {
04675     gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
04676     if(P.X() < xminB2) xminB2 = P.X();
04677     if(P.Y() < yminB2) yminB2 = P.Y();
04678     if(P.Z() < zminB2) zminB2 = P.Z();
04679     if(P.X() > xmaxB2) xmaxB2 = P.X();
04680     if(P.Y() > ymaxB2) ymaxB2 = P.Y();
04681     if(P.Z() > zmaxB2) zmaxB2 = P.Z();
04682   }
04683 
04684   //Compare the bounding boxes of both faces
04685   if(gp_Pnt(xminB1, yminB1, zminB1).Distance(gp_Pnt(xminB2, yminB2, zminB2)) > MAX_TOLERANCE)
04686     return false;
04687 
04688   if(gp_Pnt(xmaxB1, ymaxB1, zmaxB1).Distance(gp_Pnt(xmaxB2, ymaxB2, zmaxB2)) > MAX_TOLERANCE)
04689     return false;
04690 
04691   Handle(Geom_Surface) S1 = BRep_Tool::Surface(theFace1);
04692   Handle(Geom_Surface) S2 = BRep_Tool::Surface(theFace2);
04693 
04694   //Check if there a coincidence of two surfaces at least in two points
04695   double U11, U12, V11, V12, U21, U22, V21, V22;
04696   BRepTools::UVBounds(theFace1, U11, U12, V11, V12);
04697   BRepTools::UVBounds(theFace2, U21, U22, V21, V22);
04698 
04699   double rangeU = U12-U11;
04700   double rangeV = V12-V11;
04701   double U = U11 + rangeU/3.0;
04702   double V = V11 + rangeV/3.0;
04703   gp_Pnt P1 = S1->Value(U, V);
04704   U = U11+rangeU*2.0/3.0;
04705   V = V11+rangeV*2.0/3.0;
04706   gp_Pnt P2 = S1->Value(U, V);
04707 
04708   if (!GeomLib_Tool::Parameters(S2, P1, MAX_TOLERANCE, U, V) || U < U21 || U > U22 || V < V21 || V > V22)
04709     return false;
04710 
04711   if (P1.Distance(S2->Value(U,V)) > MAX_TOLERANCE) return false;
04712 
04713   if (!GeomLib_Tool::Parameters(S2, P2, MAX_TOLERANCE, U, V) || U < U21 || U > U22 || V < V21 || V > V22)
04714     return false;
04715 
04716   if (P2.Distance(S2->Value(U, V)) > MAX_TOLERANCE) return false;
04717 
04718   //Check that each edge of the Face1 has a counterpart in the Face2
04719   TopTools_MapOfOrientedShape aMap;
04720   TopTools_ListIteratorOfListOfShape LSI1(LS1);
04721   for(; LSI1.More(); LSI1.Next()) {
04722     TopoDS_Edge E = TopoDS::Edge(LSI1.Value());
04723     bool isFound = false;
04724     TopTools_ListIteratorOfListOfShape LSI2(LS2);
04725     for(; LSI2.More(); LSI2.Next()) {
04726       TopoDS_Shape aValue = LSI2.Value();
04727       if(aMap.Contains(aValue)) continue; //To avoid checking already found edge several times
04728       if(isSameEdge(E, TopoDS::Edge(aValue))) {
04729         aMap.Add(aValue);
04730         isFound = true;
04731         break;
04732       }
04733     }
04734     if(!isFound) return false;
04735   }
04736 
04737   return true;
04738 }
04739 
04740 //=======================================================================
04741 //function : isSameSolid
04742 //purpose  : Returns True if two solids coincide
04743 //=======================================================================
04744 bool isSameSolid(const TopoDS_Solid& theSolid1, const TopoDS_Solid& theSolid2)
04745 {
04746   TopExp_Explorer E(theSolid1, TopAbs_FACE);
04747   TopTools_ListOfShape LS1, LS2;
04748   for(; E.More(); E.Next()) LS1.Append(E.Current());
04749   E.Init(theSolid2, TopAbs_FACE);
04750   for(; E.More(); E.Next()) LS2.Append(E.Current());
04751 
04752   if(LS1.Extent() != LS2.Extent()) return false;
04753 
04754   double aMin = RealFirst(), aMax = RealLast();
04755   double xminB1=aMax, yminB1=aMax, zminB1=aMax, xminB2=aMax, yminB2=aMax, zminB2=aMax;
04756   double xmaxB1=aMin, ymaxB1=aMin, zmaxB1=aMin, xmaxB2=aMin, ymaxB2=aMin, zmaxB2=aMin;
04757 
04758   for(E.Init(theSolid1, TopAbs_VERTEX); E.More(); E.Next()) {
04759     gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
04760     if(P.X() < xminB1) xminB1 = P.X();
04761     if(P.Y() < yminB1) yminB1 = P.Y();
04762     if(P.Z() < zminB1) zminB1 = P.Z();
04763     if(P.X() > xmaxB1) xmaxB1 = P.X();
04764     if(P.Y() > ymaxB1) ymaxB1 = P.Y();
04765     if(P.Z() > zmaxB1) zmaxB1 = P.Z();
04766   }
04767 
04768   for(E.Init(theSolid2, TopAbs_VERTEX); E.More(); E.Next()) {
04769     gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
04770     if(P.X() < xminB2) xminB2 = P.X();
04771     if(P.Y() < yminB2) yminB2 = P.Y();
04772     if(P.Z() < zminB2) zminB2 = P.Z();
04773     if(P.X() > xmaxB2) xmaxB2 = P.X();
04774     if(P.Y() > ymaxB2) ymaxB2 = P.Y();
04775     if(P.Z() > zmaxB2) zmaxB2 = P.Z();
04776   }
04777 
04778   //Compare the bounding boxes of both solids
04779   if(gp_Pnt(xminB1, yminB1, zminB1).Distance(gp_Pnt(xminB2, yminB2, zminB2)) > MAX_TOLERANCE)
04780     return false;
04781 
04782   if(gp_Pnt(xmaxB1, ymaxB1, zmaxB1).Distance(gp_Pnt(xmaxB2, ymaxB2, zmaxB2)) > MAX_TOLERANCE)
04783     return false;
04784 
04785   //Check that each face of the Solid1 has a counterpart in the Solid2
04786   TopTools_MapOfOrientedShape aMap;
04787   TopTools_ListIteratorOfListOfShape LSI1(LS1);
04788   for(; LSI1.More(); LSI1.Next()) {
04789     TopoDS_Face F = TopoDS::Face(LSI1.Value());
04790     bool isFound = false;
04791     TopTools_ListIteratorOfListOfShape LSI2(LS2);
04792     for(; LSI2.More(); LSI2.Next()) {
04793       if(aMap.Contains(LSI2.Value())) continue; //To avoid checking already found faces several times
04794       if(isSameFace(F, TopoDS::Face(LSI2.Value()))) {
04795         aMap.Add(LSI2.Value());
04796         isFound = true;
04797         break;
04798       }
04799     }
04800     if(!isFound) return false;
04801   }
04802 
04803   return true;
04804 }
04805 
04806 //=======================================================================
04807 //function : GetSame
04808 //purpose  :
04809 //=======================================================================
04810 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetSame(const Handle(GEOM_Object)& theShapeWhere,
04811                                                         const Handle(GEOM_Object)& theShapeWhat)
04812 {
04813   SetErrorCode(KO);
04814   if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
04815 
04816   TopoDS_Shape aWhere = theShapeWhere->GetValue();
04817   TopoDS_Shape aWhat  = theShapeWhat->GetValue();
04818 
04819   if (aWhere.IsNull() || aWhat.IsNull()) return NULL;
04820 
04821   int anIndex = -1;
04822   bool isFound = false;
04823   TopoDS_Shape aSubShape;
04824   TopTools_MapOfShape aMap;
04825 
04826   if (aWhat.ShapeType() == TopAbs_COMPOUND || aWhat.ShapeType() == TopAbs_COMPSOLID) {
04827     TopoDS_Iterator It (aWhat, Standard_True, Standard_True);
04828     if (It.More()) aWhat = It.Value();
04829     It.Next();
04830     if (It.More()) {
04831       SetErrorCode("Compounds of two or more shapes are not allowed for aWhat argument");
04832       return NULL;
04833     }
04834   }
04835 
04836   switch (aWhat.ShapeType()) {
04837     case TopAbs_VERTEX: {
04838       gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(aWhat));
04839       TopExp_Explorer E(aWhere, TopAbs_VERTEX);
04840       for(; E.More(); E.Next()) {
04841         if(!aMap.Add(E.Current())) continue;
04842         gp_Pnt P2 = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
04843         if(P.Distance(P2) <= MAX_TOLERANCE) {
04844           isFound = true;
04845           aSubShape = E.Current();
04846           break;
04847         }
04848       }
04849       break;
04850                         }
04851     case TopAbs_EDGE: {
04852       TopoDS_Edge anEdge = TopoDS::Edge(aWhat);
04853       TopExp_Explorer E(aWhere, TopAbs_EDGE);
04854       for(; E.More(); E.Next()) {
04855         if(!aMap.Add(E.Current())) continue;
04856         if(isSameEdge(anEdge, TopoDS::Edge(E.Current()))) {
04857           aSubShape = E.Current();
04858           isFound = true;
04859           break;
04860         }
04861       }
04862       break;
04863                       }
04864     case TopAbs_FACE: {
04865       TopoDS_Face aFace = TopoDS::Face(aWhat);
04866       TopExp_Explorer E(aWhere, TopAbs_FACE);
04867       for(; E.More(); E.Next()) {
04868         if(!aMap.Add(E.Current())) continue;
04869         if(isSameFace(aFace, TopoDS::Face(E.Current()))) {
04870           aSubShape = E.Current();
04871           isFound = true;
04872           break;
04873         }
04874       }
04875       break;
04876                       }
04877     case TopAbs_SOLID: {
04878       TopoDS_Solid aSolid = TopoDS::Solid(aWhat);
04879       TopExp_Explorer E(aWhere, TopAbs_SOLID);
04880       for(; E.More(); E.Next()) {
04881         if(!aMap.Add(E.Current())) continue;
04882         if(isSameSolid(aSolid, TopoDS::Solid(E.Current()))) {
04883           aSubShape = E.Current();
04884           isFound = true;
04885           break;
04886         }
04887       }
04888       break;
04889                        }
04890     default:
04891       return NULL;
04892   }
04893 
04894   if (isFound) {
04895     TopTools_IndexedMapOfShape anIndices;
04896     TopExp::MapShapes(aWhere, anIndices);
04897     if (anIndices.Contains(aSubShape))
04898       anIndex = anIndices.FindIndex(aSubShape);
04899   }
04900 
04901   if (anIndex < 0) return NULL;
04902 
04903   Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
04904 
04905   anArray->SetValue(1, anIndex);
04906 
04907   Handle(GEOM_Object) aResult = GetEngine()->AddSubShape(theShapeWhere, anArray);
04908   Handle(GEOM_Function) aFunction = aResult->GetLastFunction();
04909 
04910   GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetSame("
04911     << theShapeWhere << ", " << theShapeWhat << ")";
04912 
04913   SetErrorCode(OK);
04914 
04915   return aResult;
04916 }
04917 
04918 
04919 //=======================================================================
04920 //function : GetSameIDs
04921 //purpose  :
04922 //=======================================================================
04923 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetSameIDs(const Handle(GEOM_Object)& theShapeWhere,
04924                                                         const Handle(GEOM_Object)& theShapeWhat)
04925 {
04926   SetErrorCode(KO);
04927   if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
04928 
04929   TopoDS_Shape aWhere = theShapeWhere->GetValue();
04930   TopoDS_Shape aWhat  = theShapeWhat->GetValue();
04931 
04932   if (aWhere.IsNull() || aWhat.IsNull()) return NULL;
04933 
04934   int anIndex = -1;
04935   bool isFound = false;
04936   TopTools_ListOfShape listShape;
04937   TopTools_MapOfShape aMap;
04938 
04939   if (aWhat.ShapeType() == TopAbs_COMPOUND || aWhat.ShapeType() == TopAbs_COMPSOLID) {
04940     TopoDS_Iterator It (aWhat, Standard_True, Standard_True);
04941     if (It.More()) aWhat = It.Value();
04942     It.Next();
04943     if (It.More()) {
04944       SetErrorCode("Compounds of two or more shapes are not allowed for aWhat argument");
04945       return NULL;
04946     }
04947   }
04948 
04949   switch (aWhat.ShapeType()) {
04950     case TopAbs_VERTEX: {
04951       gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(aWhat));
04952       TopExp_Explorer E(aWhere, TopAbs_VERTEX);
04953       for(; E.More(); E.Next()) {
04954         if(!aMap.Add(E.Current())) continue;
04955         gp_Pnt P2 = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
04956         if(P.Distance(P2) <= MAX_TOLERANCE) {
04957           listShape.Append(E.Current());
04958         }
04959       }
04960       break;
04961                         }
04962     case TopAbs_EDGE: {
04963       TopoDS_Edge anEdge = TopoDS::Edge(aWhat);
04964       TopExp_Explorer E(aWhere, TopAbs_EDGE);
04965       for(; E.More(); E.Next()) {
04966         if(!aMap.Add(E.Current())) continue;
04967         if(isSameEdge(anEdge, TopoDS::Edge(E.Current()))) {
04968           listShape.Append(E.Current());
04969         }
04970       }
04971       break;
04972                       }
04973     case TopAbs_FACE: {
04974       TopoDS_Face aFace = TopoDS::Face(aWhat);
04975       TopExp_Explorer E(aWhere, TopAbs_FACE);
04976       for(; E.More(); E.Next()) {
04977         if(!aMap.Add(E.Current())) continue;
04978         if(isSameFace(aFace, TopoDS::Face(E.Current()))) {
04979           listShape.Append(E.Current());
04980         }
04981       }
04982       break;
04983                       }
04984     case TopAbs_SOLID: {
04985       TopoDS_Solid aSolid = TopoDS::Solid(aWhat);
04986       TopExp_Explorer E(aWhere, TopAbs_SOLID);
04987       for(; E.More(); E.Next()) {
04988         if(!aMap.Add(E.Current())) continue;
04989         if(isSameSolid(aSolid, TopoDS::Solid(E.Current()))) {
04990           listShape.Append(E.Current());
04991         }
04992       }
04993       break;
04994                        }
04995     default:
04996       return NULL;
04997   }
04998 
04999   if ( !listShape.IsEmpty() ) {
05000     TopTools_IndexedMapOfShape anIndices;
05001     TopExp::MapShapes(aWhere, anIndices);
05002     TopTools_ListIteratorOfListOfShape itSub (listShape);
05003     Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
05004     for (; itSub.More(); itSub.Next()) {
05005       if (anIndices.Contains(itSub.Value()))
05006         aSeq->Append(anIndices.FindIndex(itSub.Value()));
05007     }
05008     SetErrorCode(OK);
05009     // The GetSameIDs() doesn't change object so no new function is required.
05010     Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShapeWhere,theShapeWhat)->GetLastFunction();
05011 
05012   // Make a Python command
05013   GEOM::TPythonDump(aFunction)
05014     << "listSameIDs = geompy.GetSameIDs("
05015     << theShapeWhere << ", "
05016     << theShapeWhat << ")";
05017     return aSeq;
05018   } else {
05019     SetErrorCode(NOT_FOUND_ANY);
05020     return NULL; 
05021   }
05022 }