1 // Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
2 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License.
9 // This library is distributed in the hope that it will be useful
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // Lesser General Public License for more details.
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 #include <Standard_Stream.hxx>
23 #include "GEOMImpl_IShapesOperations.hxx"
25 #include "GEOMImpl_Types.hxx"
27 #include "GEOMImpl_VectorDriver.hxx"
28 #include "GEOMImpl_ShapeDriver.hxx"
29 #include "GEOMImpl_CopyDriver.hxx"
30 #include "GEOMImpl_GlueDriver.hxx"
32 #include "GEOMImpl_IVector.hxx"
33 #include "GEOMImpl_IShapes.hxx"
34 #include "GEOMImpl_IGlue.hxx"
36 #include "GEOMImpl_Block6Explorer.hxx"
38 #include "GEOM_Function.hxx"
39 #include "GEOM_PythonDump.hxx"
41 #include "GEOMAlgo_FinderShapeOn1.hxx"
42 #include "GEOMAlgo_FinderShapeOnQuad.hxx"
43 #include "GEOMAlgo_FinderShapeOn2.hxx"
44 #include "GEOMAlgo_ClsfBox.hxx"
45 //#include "GEOMAlgo_ClsfSurf.hxx"
47 #include "utilities.h"
49 #include "Utils_ExceptHandlers.hxx"
51 #include <TFunction_DriverTable.hxx>
52 #include <TFunction_Driver.hxx>
53 #include <TFunction_Logbook.hxx>
54 #include <TDataStd_Integer.hxx>
55 #include <TDataStd_IntegerArray.hxx>
56 #include <TDF_Tool.hxx>
58 #include <BRepExtrema_ExtCF.hxx>
60 #include <BRep_Tool.hxx>
61 #include <BRepTools.hxx>
62 #include <BRepGProp.hxx>
63 #include <BRepAdaptor_Curve.hxx>
64 #include <BRepAdaptor_Surface.hxx>
65 #include <BRepBndLib.hxx>
66 #include <BRepBuilderAPI_MakeFace.hxx>
67 #include <BRepMesh_IncrementalMesh.hxx>
72 #include <TopoDS_Shape.hxx>
73 #include <TopoDS_Solid.hxx>
74 #include <TopoDS_Face.hxx>
75 #include <TopoDS_Edge.hxx>
76 #include <TopoDS_Vertex.hxx>
77 #include <TopoDS_Iterator.hxx>
78 #include <TopExp_Explorer.hxx>
79 #include <TopLoc_Location.hxx>
80 #include <TopTools_MapOfShape.hxx>
81 #include <TopTools_MapOfOrientedShape.hxx>
82 #include <TopTools_Array1OfShape.hxx>
83 #include <TopTools_ListIteratorOfListOfShape.hxx>
84 #include <TopTools_IndexedMapOfShape.hxx>
86 #include <Geom_Surface.hxx>
87 #include <Geom_Plane.hxx>
88 #include <Geom_SphericalSurface.hxx>
89 #include <Geom_CylindricalSurface.hxx>
90 #include <GeomAdaptor_Surface.hxx>
92 #include <GeomLib_Tool.hxx>
93 #include <Geom2d_Curve.hxx>
95 #include <Bnd_Box.hxx>
96 #include <GProp_GProps.hxx>
99 #include <TColStd_ListOfInteger.hxx>
100 #include <TColStd_ListIteratorOfListOfInteger.hxx>
101 #include <TColStd_Array1OfReal.hxx>
102 #include <TColStd_HArray1OfInteger.hxx>
106 #include <Standard_Failure.hxx>
107 #include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
109 //=============================================================================
113 //=============================================================================
114 GEOMImpl_IShapesOperations::GEOMImpl_IShapesOperations (GEOM_Engine* theEngine, int theDocID)
115 : GEOM_IOperations(theEngine, theDocID)
117 MESSAGE("GEOMImpl_IShapesOperations::GEOMImpl_IShapesOperations");
120 //=============================================================================
124 //=============================================================================
125 GEOMImpl_IShapesOperations::~GEOMImpl_IShapesOperations()
127 MESSAGE("GEOMImpl_IShapesOperations::~GEOMImpl_IShapesOperations");
131 //=============================================================================
135 //=============================================================================
136 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeEdge
137 (Handle(GEOM_Object) thePnt1, Handle(GEOM_Object) thePnt2)
141 if (thePnt1.IsNull() || thePnt2.IsNull()) return NULL;
143 //Add a new Edge object
144 Handle(GEOM_Object) anEdge = GetEngine()->AddObject(GetDocID(), GEOM_EDGE);
146 //Add a new Vector function
147 Handle(GEOM_Function) aFunction =
148 anEdge->AddFunction(GEOMImpl_VectorDriver::GetID(), VECTOR_TWO_PNT);
150 //Check if the function is set correctly
151 if (aFunction->GetDriverGUID() != GEOMImpl_VectorDriver::GetID()) return NULL;
153 GEOMImpl_IVector aPI (aFunction);
155 Handle(GEOM_Function) aRef1 = thePnt1->GetLastFunction();
156 Handle(GEOM_Function) aRef2 = thePnt2->GetLastFunction();
157 if (aRef1.IsNull() || aRef2.IsNull()) return NULL;
159 aPI.SetPoint1(aRef1);
160 aPI.SetPoint2(aRef2);
162 //Compute the Edge value
164 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
167 if (!GetSolver()->ComputeFunction(aFunction)) {
168 SetErrorCode("Vector driver failed");
172 catch (Standard_Failure) {
173 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
174 SetErrorCode(aFail->GetMessageString());
178 //Make a Python command
179 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdge("
180 << thePnt1 << ", " << thePnt2 << ")";
186 //=============================================================================
190 //=============================================================================
191 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeWire
192 (list<Handle(GEOM_Object)> theShapes)
194 return MakeShape(theShapes, GEOM_WIRE, WIRE_EDGES, "MakeWire");
197 //=============================================================================
201 //=============================================================================
202 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFace (Handle(GEOM_Object) theWire,
203 const bool isPlanarWanted)
207 if (theWire.IsNull()) return NULL;
209 //Add a new Face object
210 Handle(GEOM_Object) aFace = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
212 //Add a new Shape function for creation of a face from a wire
213 Handle(GEOM_Function) aFunction =
214 aFace->AddFunction(GEOMImpl_ShapeDriver::GetID(), FACE_WIRE);
215 if (aFunction.IsNull()) return NULL;
217 //Check if the function is set correctly
218 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
220 GEOMImpl_IShapes aCI (aFunction);
222 Handle(GEOM_Function) aRefWire = theWire->GetLastFunction();
224 if (aRefWire.IsNull()) return NULL;
226 aCI.SetBase(aRefWire);
227 aCI.SetIsPlanar(isPlanarWanted);
229 //Compute the Face value
231 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
234 if (!GetSolver()->ComputeFunction(aFunction)) {
235 SetErrorCode("Shape driver failed to compute a face");
239 catch (Standard_Failure) {
240 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
241 SetErrorCode(aFail->GetMessageString());
245 //Make a Python command
246 GEOM::TPythonDump(aFunction) << aFace << " = geompy.MakeFace("
247 << theWire << ", " << (int)isPlanarWanted << ")";
253 //=============================================================================
257 //=============================================================================
258 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFaceWires
259 (list<Handle(GEOM_Object)> theShapes,
260 const bool isPlanarWanted)
265 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
268 Handle(GEOM_Function) aFunction =
269 aShape->AddFunction(GEOMImpl_ShapeDriver::GetID(), FACE_WIRES);
270 if (aFunction.IsNull()) return NULL;
272 //Check if the function is set correctly
273 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
275 GEOMImpl_IShapes aCI (aFunction);
277 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
280 list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
281 for (; it != theShapes.end(); it++) {
282 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
283 if (aRefSh.IsNull()) {
284 SetErrorCode("NULL argument shape for the face construction");
287 aShapesSeq->Append(aRefSh);
289 aCI.SetShapes(aShapesSeq);
291 aCI.SetIsPlanar(isPlanarWanted);
295 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
298 if (!GetSolver()->ComputeFunction(aFunction)) {
299 SetErrorCode("Shape driver failed");
303 catch (Standard_Failure) {
304 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
305 SetErrorCode(aFail->GetMessageString());
309 //Make a Python command
310 GEOM::TPythonDump pd (aFunction);
311 pd << aShape << " = geompy.MakeFaceWires([";
314 it = theShapes.begin();
315 if (it != theShapes.end()) {
317 while (it != theShapes.end()) {
318 pd << ", " << (*it++);
321 pd << "], " << (int)isPlanarWanted << ")";
327 //=============================================================================
331 //=============================================================================
332 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeShell
333 (list<Handle(GEOM_Object)> theShapes)
335 return MakeShape(theShapes, GEOM_SHELL, SHELL_FACES, "MakeShell");
338 //=============================================================================
342 //=============================================================================
343 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeSolidShells
344 (list<Handle(GEOM_Object)> theShapes)
346 return MakeShape(theShapes, GEOM_SOLID, SOLID_SHELLS, "MakeSolid");
349 //=============================================================================
353 //=============================================================================
354 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeSolidShell (Handle(GEOM_Object) theShell)
358 if (theShell.IsNull()) return NULL;
360 //Add a new Solid object
361 Handle(GEOM_Object) aSolid = GetEngine()->AddObject(GetDocID(), GEOM_SOLID);
363 //Add a new Solid function for creation of a solid from a shell
364 Handle(GEOM_Function) aFunction =
365 aSolid->AddFunction(GEOMImpl_ShapeDriver::GetID(), SOLID_SHELL);
366 if (aFunction.IsNull()) return NULL;
368 //Check if the function is set correctly
369 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
371 GEOMImpl_IShapes aCI (aFunction);
373 Handle(GEOM_Function) aRefShell = theShell->GetLastFunction();
375 if (aRefShell.IsNull()) return NULL;
377 aCI.SetBase(aRefShell);
379 //Compute the Solid value
381 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
384 if (!GetSolver()->ComputeFunction(aFunction)) {
385 SetErrorCode("Solid driver failed");
389 catch (Standard_Failure) {
390 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
391 SetErrorCode(aFail->GetMessageString());
395 //Make a Python command
396 GEOM::TPythonDump(aFunction) << aSolid
397 << " = geompy.MakeSolid(" << theShell << ")";
403 //=============================================================================
407 //=============================================================================
408 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeCompound
409 (list<Handle(GEOM_Object)> theShapes)
411 return MakeShape(theShapes, GEOM_COMPOUND, COMPOUND_SHAPES, "MakeCompound");
414 //=============================================================================
418 //=============================================================================
419 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeShape
420 (list<Handle(GEOM_Object)> theShapes,
421 const Standard_Integer theObjectType,
422 const Standard_Integer theFunctionType,
423 const TCollection_AsciiString& theMethodName)
428 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), theObjectType);
431 Handle(GEOM_Function) aFunction =
432 aShape->AddFunction(GEOMImpl_ShapeDriver::GetID(), theFunctionType);
433 if (aFunction.IsNull()) return NULL;
435 //Check if the function is set correctly
436 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
438 GEOMImpl_IShapes aCI (aFunction);
440 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
443 list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
444 for (; it != theShapes.end(); it++) {
445 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
446 if (aRefSh.IsNull()) {
447 SetErrorCode("NULL argument shape for the shape construction");
450 aShapesSeq->Append(aRefSh);
452 aCI.SetShapes(aShapesSeq);
456 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
459 if (!GetSolver()->ComputeFunction(aFunction)) {
460 SetErrorCode("Shape driver failed");
464 catch (Standard_Failure) {
465 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
466 SetErrorCode(aFail->GetMessageString());
470 //Make a Python command
471 GEOM::TPythonDump pd (aFunction);
472 pd << aShape << " = geompy." << theMethodName.ToCString() << "([";
475 it = theShapes.begin();
476 if (it != theShapes.end()) {
478 while (it != theShapes.end()) {
479 pd << ", " << (*it++);
488 //=============================================================================
492 //=============================================================================
493 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeGlueFaces
494 (Handle(GEOM_Object) theShape,
495 const Standard_Real theTolerance)
499 if (theShape.IsNull()) return NULL;
501 //Add a new Glued object
502 Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
504 //Add a new Glue function
505 Handle(GEOM_Function) aFunction;
506 aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_FACES);
507 if (aFunction.IsNull()) return NULL;
509 //Check if the function is set correctly
510 if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
512 GEOMImpl_IGlue aCI (aFunction);
514 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
515 if (aRefShape.IsNull()) return NULL;
517 aCI.SetBase(aRefShape);
518 aCI.SetTolerance(theTolerance);
520 //Compute the sub-shape value
521 Standard_Boolean isWarning = Standard_False;
523 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
526 if (!GetSolver()->ComputeFunction(aFunction)) {
527 SetErrorCode("Shape driver failed to glue faces");
531 catch (Standard_Failure) {
532 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
533 SetErrorCode(aFail->GetMessageString());
534 // to provide warning
535 if (!aFunction->GetValue().IsNull()) {
536 isWarning = Standard_True;
542 //Make a Python command
543 GEOM::TPythonDump(aFunction) << aGlued << " = geompy.MakeGlueFaces("
544 << theShape << ", " << theTolerance << ")";
546 // to provide warning
547 if (!isWarning) SetErrorCode(OK);
551 //=============================================================================
555 //=============================================================================
556 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::MakeExplode
557 (Handle(GEOM_Object) theShape,
558 const Standard_Integer theShapeType,
559 const Standard_Boolean isSorted)
563 if (theShape.IsNull()) return NULL;
564 TopoDS_Shape aShape = theShape->GetValue();
565 if (aShape.IsNull()) return NULL;
567 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
568 Handle(GEOM_Object) anObj;
569 Handle(GEOM_Function) aFunction;
570 TopTools_MapOfShape mapShape;
571 TopTools_ListOfShape listShape;
573 if (aShape.ShapeType() == TopAbs_COMPOUND &&
574 (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
575 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPSOLID ||
576 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPOUND)) {
577 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
578 for (; It.More(); It.Next()) {
579 if (mapShape.Add(It.Value())) {
580 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
581 TopAbs_ShapeEnum(theShapeType) == It.Value().ShapeType()) {
582 listShape.Append(It.Value());
587 TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
588 for (; exp.More(); exp.Next())
589 if (mapShape.Add(exp.Current()))
590 listShape.Append(exp.Current());
593 if (listShape.IsEmpty()) {
594 SetErrorCode("The given shape has no sub-shapes of the requested type");
599 SortShapes(listShape);
601 TopTools_IndexedMapOfShape anIndices;
602 TopExp::MapShapes(aShape, anIndices);
603 Handle(TColStd_HArray1OfInteger) anArray;
605 TopTools_ListIteratorOfListOfShape itSub (listShape);
606 TCollection_AsciiString anAsciiList, anEntry;
607 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
608 TopoDS_Shape aValue = itSub.Value();
609 anArray = new TColStd_HArray1OfInteger(1,1);
610 anArray->SetValue(1, anIndices.FindIndex(aValue));
611 anObj = GetEngine()->AddSubShape(theShape, anArray);
612 if (!anObj.IsNull()) {
615 // for python command
616 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
617 anAsciiList += anEntry;
622 //Make a Python command
623 anAsciiList.Trunc(anAsciiList.Length() - 1);
625 aFunction = theShape->GetLastFunction();
627 GEOM::TPythonDump pd (aFunction, /*append=*/true);
628 pd << "[" << anAsciiList.ToCString();
629 pd << "] = geompy.SubShapeAll" << (isSorted ? "Sorted(" : "(");
630 pd << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
637 //=============================================================================
641 //=============================================================================
642 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::SubShapeAllIDs
643 (Handle(GEOM_Object) theShape,
644 const Standard_Integer theShapeType,
645 const Standard_Boolean isSorted)
649 if (theShape.IsNull()) return NULL;
650 TopoDS_Shape aShape = theShape->GetValue();
651 if (aShape.IsNull()) return NULL;
653 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
654 TopTools_MapOfShape mapShape;
655 TopTools_ListOfShape listShape;
657 if (aShape.ShapeType() == TopAbs_COMPOUND &&
658 (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
659 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPSOLID ||
660 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPOUND)) {
661 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
662 for (; It.More(); It.Next()) {
663 if (mapShape.Add(It.Value())) {
664 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
665 TopAbs_ShapeEnum(theShapeType) == It.Value().ShapeType()) {
666 listShape.Append(It.Value());
671 TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
672 for (; exp.More(); exp.Next())
673 if (mapShape.Add(exp.Current()))
674 listShape.Append(exp.Current());
677 if (listShape.IsEmpty()) {
678 SetErrorCode("The given shape has no sub-shapes of the requested type");
683 SortShapes(listShape);
685 TopTools_IndexedMapOfShape anIndices;
686 TopExp::MapShapes(aShape, anIndices);
687 Handle(TColStd_HArray1OfInteger) anArray;
689 TopTools_ListIteratorOfListOfShape itSub (listShape);
690 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
691 TopoDS_Shape aValue = itSub.Value();
692 aSeq->Append(anIndices.FindIndex(aValue));
695 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
697 //Make a Python command
698 GEOM::TPythonDump pd (aFunction, /*append=*/true);
699 pd << "listSubShapeIDs = geompy.SubShapeAll";
700 pd << (isSorted ? "SortedIDs(" : "IDs(");
701 pd << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
707 //=============================================================================
711 //=============================================================================
712 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetSubShape
713 (Handle(GEOM_Object) theMainShape,
714 const Standard_Integer theID)
718 if (theMainShape.IsNull()) return NULL;
720 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
721 anArray->SetValue(1, theID);
722 Handle(GEOM_Object) anObj = GetEngine()->AddSubShape(theMainShape, anArray,true);
723 if (anObj.IsNull()) {
724 SetErrorCode("Can not get a sub-shape with the given ID");
728 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
730 //Make a Python command
731 GEOM::TPythonDump(aFunction) << anObj << " = geompy.GetSubShape("
732 << theMainShape << ", [" << theID << "])";
738 //=============================================================================
742 //=============================================================================
743 Standard_Integer GEOMImpl_IShapesOperations::GetSubShapeIndex (Handle(GEOM_Object) theMainShape,
744 Handle(GEOM_Object) theSubShape)
748 TopoDS_Shape aMainShape = theMainShape->GetValue();
749 TopoDS_Shape aSubShape = theSubShape->GetValue();
751 if (aMainShape.IsNull() || aSubShape.IsNull()) return -1;
753 TopTools_IndexedMapOfShape anIndices;
754 TopExp::MapShapes(aMainShape, anIndices);
755 if (anIndices.Contains(aSubShape)) {
757 return anIndices.FindIndex(aSubShape);
763 //=============================================================================
767 //=============================================================================
768 Standard_Integer GEOMImpl_IShapesOperations::GetTopologyIndex (Handle(GEOM_Object) theMainShape,
769 Handle(GEOM_Object) theSubShape)
773 TopoDS_Shape aMainShape = theMainShape->GetValue();
774 TopoDS_Shape aSubShape = theSubShape->GetValue();
776 if (aMainShape.IsNull() || aSubShape.IsNull()) {
777 SetErrorCode("Null argument shape given");
782 if (aSubShape.ShapeType() == TopAbs_COMPOUND) {
784 TopTools_ListOfShape CL;
785 CL.Append(aMainShape);
786 TopTools_ListIteratorOfListOfShape itC;
787 for (itC.Initialize(CL); itC.More(); itC.Next()) {
788 for (it.Initialize(itC.Value()); it.More(); it.Next()) {
789 if (it.Value().ShapeType() == TopAbs_COMPOUND) {
790 if (it.Value().IsSame(aSubShape))
794 CL.Append(it.Value());
799 TopExp_Explorer anExp (aMainShape, aSubShape.ShapeType());
800 TopTools_MapOfShape M;
801 for (; anExp.More(); anExp.Next()) {
802 if (M.Add(anExp.Current())) {
803 if (anExp.Current().IsSame(aSubShape))
810 SetErrorCode("The sub-shape does not belong to the main shape");
814 //=============================================================================
818 //=============================================================================
819 TCollection_AsciiString GEOMImpl_IShapesOperations::GetShapeTypeString (Handle(GEOM_Object) theShape)
823 TCollection_AsciiString aTypeName ("Null Shape");
825 TopoDS_Shape aShape = theShape->GetValue();
829 switch (aShape.ShapeType() )
831 case TopAbs_COMPOUND:
832 aTypeName = "Compound";
834 case TopAbs_COMPSOLID:
835 aTypeName = "Compound Solid";
845 BRepAdaptor_Surface surf (TopoDS::Face(aShape));
846 if (surf.GetType() == GeomAbs_Plane)
848 else if (surf.GetType() == GeomAbs_Cylinder)
849 aTypeName = "Cylindrical Face";
850 else if (surf.GetType() == GeomAbs_Sphere)
851 aTypeName = "Spherical Face";
852 else if (surf.GetType() == GeomAbs_Torus)
853 aTypeName = "Toroidal Face";
854 else if (surf.GetType() == GeomAbs_Cone)
855 aTypeName = "Conical Face";
857 aTypeName = "GEOM::FACE";
865 BRepAdaptor_Curve curv (TopoDS::Edge(aShape));
866 if (curv.GetType() == GeomAbs_Line) {
867 if ((Abs(curv.FirstParameter()) >= 1E6) ||
868 (Abs(curv.LastParameter()) >= 1E6))
872 } else if (curv.GetType() == GeomAbs_Circle) {
874 aTypeName = "Circle";
883 aTypeName = "Vertex";
889 aTypeName = "Shape of unknown type";
896 //=============================================================================
900 //=============================================================================
901 Standard_Integer GEOMImpl_IShapesOperations::NumberOfFaces (Handle(GEOM_Object) theShape)
905 Standard_Integer nb = 0;
907 if (theShape.IsNull()) return -1;
908 TopoDS_Shape aShape = theShape->GetValue();
909 if (aShape.IsNull()) return -1;
911 TopTools_MapOfShape mapShape;
913 TopExp_Explorer exp (aShape, TopAbs_FACE);
914 for (; exp.More(); exp.Next())
915 if (mapShape.Add(exp.Current()))
922 //=============================================================================
926 //=============================================================================
927 Standard_Integer GEOMImpl_IShapesOperations::NumberOfEdges (Handle(GEOM_Object) theShape)
931 Standard_Integer nb = 0;
933 if (theShape.IsNull()) return -1;
934 TopoDS_Shape aShape = theShape->GetValue();
935 if (aShape.IsNull()) return -1;
937 TopTools_MapOfShape mapShape;
939 TopExp_Explorer exp (aShape, TopAbs_EDGE);
940 for (; exp.More(); exp.Next())
941 if (mapShape.Add(exp.Current()))
948 //=============================================================================
952 //=============================================================================
953 Handle(GEOM_Object) GEOMImpl_IShapesOperations::ReverseShape(Handle(GEOM_Object) theShape)
957 if (theShape.IsNull()) return NULL;
959 //Add a new reversed object
960 Handle(GEOM_Object) aReversed = GetEngine()->AddObject(GetDocID(), theShape->GetType());
962 //Add a new Revese function
963 Handle(GEOM_Function) aFunction;
964 aFunction = aReversed->AddFunction(GEOMImpl_ShapeDriver::GetID(), REVERSE_ORIENTATION);
965 if (aFunction.IsNull()) return NULL;
967 //Check if the function is set correctly
968 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
970 GEOMImpl_IShapes aSI (aFunction);
972 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
973 if (aRefShape.IsNull()) return NULL;
975 aSI.SetBase(aRefShape);
977 //Compute the sub-shape value
979 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
982 if (!GetSolver()->ComputeFunction(aFunction)) {
983 SetErrorCode("Shape driver failed to reverse shape");
987 catch (Standard_Failure) {
988 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
989 SetErrorCode(aFail->GetMessageString());
993 //Make a Python command
994 GEOM::TPythonDump(aFunction) << aReversed
995 << " = geompy.ChangeOrientation(" << theShape << ")";
1001 //=============================================================================
1005 //=============================================================================
1006 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetFreeFacesIDs
1007 (Handle(GEOM_Object) theShape)
1011 if (theShape.IsNull()) return NULL;
1012 TopoDS_Shape aShape = theShape->GetValue();
1013 if (aShape.IsNull()) return NULL;
1015 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
1017 TopTools_IndexedDataMapOfShapeListOfShape mapFaceBlocks;
1018 GEOMImpl_Block6Explorer::MapShapesAndAncestors
1019 (aShape, TopAbs_FACE, TopAbs_SOLID, mapFaceBlocks);
1021 Standard_Integer ind = 1, nbFaces = mapFaceBlocks.Extent();
1024 SetErrorCode("The given shape has no faces");
1028 TopTools_IndexedMapOfShape anIndices;
1029 TopExp::MapShapes(aShape, anIndices);
1031 Standard_Integer id;
1032 for (; ind <= nbFaces; ind++) {
1033 if (mapFaceBlocks.FindFromIndex(ind).Extent() != 2) {
1034 id = anIndices.FindIndex(mapFaceBlocks.FindKey(ind));
1039 //The explode doesn't change object so no new function is required.
1040 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
1042 //Make a Python command
1043 GEOM::TPythonDump(aFunction, /*append=*/true)
1044 << "listFreeFacesIDs = geompy.GetFreeFacesIDs(" << theShape << ")";
1050 //=======================================================================
1051 //function : GetSharedShapes
1053 //=======================================================================
1055 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetSharedShapes
1056 (Handle(GEOM_Object) theShape1,
1057 Handle(GEOM_Object) theShape2,
1058 const Standard_Integer theShapeType)
1062 if (theShape1.IsNull() || theShape2.IsNull()) return NULL;
1064 TopoDS_Shape aShape1 = theShape1->GetValue();
1065 TopoDS_Shape aShape2 = theShape2->GetValue();
1067 if (aShape1.IsNull() || aShape2.IsNull()) return NULL;
1069 TopTools_IndexedMapOfShape anIndices;
1070 TopExp::MapShapes(aShape1, anIndices);
1071 Handle(TColStd_HArray1OfInteger) anArray;
1073 TopTools_IndexedMapOfShape mapShape1;
1074 TopExp::MapShapes(aShape1, TopAbs_ShapeEnum(theShapeType), mapShape1);
1076 Handle(GEOM_Object) anObj;
1077 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1078 TCollection_AsciiString anAsciiList, anEntry;
1080 TopTools_MapOfShape mapShape2;
1081 TopExp_Explorer exp (aShape2, TopAbs_ShapeEnum(theShapeType));
1082 for (; exp.More(); exp.Next()) {
1083 TopoDS_Shape aSS = exp.Current();
1084 if (mapShape2.Add(aSS) && mapShape1.Contains(aSS)) {
1085 anArray = new TColStd_HArray1OfInteger(1,1);
1086 anArray->SetValue(1, anIndices.FindIndex(aSS));
1087 anObj = GetEngine()->AddSubShape(theShape1, anArray);
1088 aSeq->Append(anObj);
1090 // for python command
1091 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
1092 anAsciiList += anEntry;
1097 if (aSeq->IsEmpty()) {
1098 SetErrorCode("The given shapes have no shared sub-shapes of the requested type");
1102 //Make a Python command
1103 anAsciiList.Trunc(anAsciiList.Length() - 1);
1105 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1107 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
1108 << "] = geompy.GetSharedShapes(" << theShape1 << ", "
1109 << theShape2 << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
1115 //=============================================================================
1119 //=============================================================================
1120 static GEOM::TPythonDump& operator<< (GEOM::TPythonDump& theDump,
1121 const GEOMAlgo_State theState)
1124 case GEOMAlgo_ST_IN:
1125 theDump << "geompy.GEOM.ST_IN";
1127 case GEOMAlgo_ST_OUT:
1128 theDump << "geompy.GEOM.ST_OUT";
1130 case GEOMAlgo_ST_ON:
1131 theDump << "geompy.GEOM.ST_ON";
1133 case GEOMAlgo_ST_ONIN:
1134 theDump << "geompy.GEOM.ST_ONIN";
1136 case GEOMAlgo_ST_ONOUT:
1137 theDump << "geompy.GEOM.ST_ONOUT";
1140 theDump << "geompy.GEOM.ST_UNKNOWN";
1146 //=======================================================================
1147 //function : checkTypeShapesOn
1149 * \brief Checks if theShapeType parameter of GetShapesOnXXX() is OK
1150 * \param theShapeType - the shape type to check
1151 * \retval bool - result of the check
1153 //=======================================================================
1155 bool GEOMImpl_IShapesOperations::checkTypeShapesOn(const Standard_Integer theShapeType)
1157 if (theShapeType != TopAbs_VERTEX &&
1158 theShapeType != TopAbs_EDGE &&
1159 theShapeType != TopAbs_FACE &&
1160 theShapeType != TopAbs_SOLID) {
1161 SetErrorCode("Only solids, vertices, edges or faces can be found by this method");
1167 //=======================================================================
1168 //function : makePlane
1170 * \brief Creates Geom_Plane
1171 * \param theAx1 - shape object defining plane parameters
1172 * \retval Handle(Geom_Surface) - resulting surface
1174 //=======================================================================
1176 Handle(Geom_Surface) GEOMImpl_IShapesOperations::makePlane(const TopoDS_Shape& anAx1)
1178 if (anAx1.ShapeType() != TopAbs_EDGE) return NULL;
1179 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
1180 TopoDS_Vertex V1, V2;
1181 TopExp::Vertices(anEdge, V1, V2, Standard_True);
1182 if (V1.IsNull() || V2.IsNull()) {
1183 SetErrorCode("Bad edge given for the plane normal vector");
1186 gp_Pnt aLoc = BRep_Tool::Pnt(V1);
1187 gp_Vec aVec (aLoc, BRep_Tool::Pnt(V2));
1188 if (aVec.Magnitude() < Precision::Confusion()) {
1189 SetErrorCode("Vector with null magnitude given");
1192 return new Geom_Plane(aLoc, aVec);
1195 //=======================================================================
1196 //function : makeCylinder
1198 * \brief Creates Geom_CylindricalSurface
1199 * \param theAx1 - edge defining cylinder axis
1200 * \param theRadius - cylinder radius
1201 * \retval Handle(Geom_Surface) - resulting surface
1203 //=======================================================================
1205 Handle(Geom_Surface) GEOMImpl_IShapesOperations::makeCylinder(const TopoDS_Shape& anAxis,
1206 const Standard_Real theRadius)
1208 //Axis of the cylinder
1209 if (anAxis.ShapeType() != TopAbs_EDGE) {
1210 SetErrorCode("Not an edge given for the axis");
1213 TopoDS_Edge anEdge = TopoDS::Edge(anAxis);
1214 TopoDS_Vertex V1, V2;
1215 TopExp::Vertices(anEdge, V1, V2, Standard_True);
1216 if (V1.IsNull() || V2.IsNull()) {
1217 SetErrorCode("Bad edge given for the axis");
1220 gp_Pnt aLoc = BRep_Tool::Pnt(V1);
1221 gp_Vec aVec (aLoc, BRep_Tool::Pnt(V2));
1222 if (aVec.Magnitude() < Precision::Confusion()) {
1223 SetErrorCode("Vector with null magnitude given");
1227 gp_Ax3 anAx3 (aLoc, aVec);
1228 return new Geom_CylindricalSurface(anAx3, theRadius);
1232 //=======================================================================
1233 //function : getShapesOnBoxIDs
1235 * \brief Find IDs of subshapes complying with given status about surface
1236 * \param theBox - the box to check state of subshapes against
1237 * \param theShape - the shape to explore
1238 * \param theShapeType - type of subshape of theShape
1239 * \param theState - required state
1240 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1242 //=======================================================================
1244 Handle(TColStd_HSequenceOfInteger)
1245 GEOMImpl_IShapesOperations::getShapesOnBoxIDs(const Handle(GEOM_Object)& theBox,
1246 const Handle(GEOM_Object)& theShape,
1247 const Standard_Integer theShapeType,
1248 GEOMAlgo_State theState)
1250 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
1252 TopoDS_Shape aBox = theBox->GetValue();
1253 TopoDS_Shape aShape = theShape->GetValue();
1256 GEOMAlgo_FinderShapeOn2 aFinder;
1257 Standard_Real aTol = 0.0001; // default value
1259 Handle(GEOMAlgo_ClsfBox) aClsfBox = new GEOMAlgo_ClsfBox;
1260 aClsfBox->SetBox(aBox);
1262 aFinder.SetShape(aShape);
1263 aFinder.SetTolerance(aTol);
1264 aFinder.SetClsf(aClsfBox);
1265 aFinder.SetShapeType( (TopAbs_ShapeEnum)theShapeType );
1266 aFinder.SetState(theState);
1269 // Interprete results
1270 Standard_Integer iErr = aFinder.ErrorStatus();
1271 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
1273 MESSAGE(" iErr : " << iErr);
1274 TCollection_AsciiString aMsg (" iErr : ");
1275 aMsg += TCollection_AsciiString(iErr);
1279 Standard_Integer iWrn = aFinder.WarningStatus();
1280 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
1282 MESSAGE(" *** iWrn : " << iWrn);
1285 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
1287 if (listSS.Extent() < 1) {
1288 SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
1292 // Fill sequence of object IDs
1293 aSeqOfIDs = new TColStd_HSequenceOfInteger;
1295 TopTools_IndexedMapOfShape anIndices;
1296 TopExp::MapShapes(aShape, anIndices);
1298 TopTools_ListIteratorOfListOfShape itSub (listSS);
1299 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
1300 int id = anIndices.FindIndex(itSub.Value());
1301 aSeqOfIDs->Append(id);
1308 //=======================================================================
1309 //function : GetShapesOnBoxIDs
1311 * \brief Find subshapes complying with given status about surface
1312 * \param theBox - the box to check state of subshapes against
1313 * \param theShape - the shape to explore
1314 * \param theShapeType - type of subshape of theShape
1315 * \param theState - required state
1316 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1318 //=======================================================================
1320 Handle(TColStd_HSequenceOfInteger)
1321 GEOMImpl_IShapesOperations::GetShapesOnBoxIDs(const Handle(GEOM_Object)& theBox,
1322 const Handle(GEOM_Object)& theShape,
1323 const Standard_Integer theShapeType,
1324 GEOMAlgo_State theState)
1326 // Find subshapes ids
1327 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
1328 getShapesOnBoxIDs (theBox, theShape, theShapeType, theState);
1329 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
1332 // The GetShapesOnBox() doesn't change object so no new function is required.
1333 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theBox)->GetLastFunction();
1335 // Make a Python command
1336 GEOM::TPythonDump(aFunction)
1337 << "listShapesOnBoxIDs = geompy.GetShapesOnQuadrangleIDs("
1340 << TopAbs_ShapeEnum(theShapeType) << ", "
1347 //=======================================================================
1348 //function : GetShapesOnBox
1350 * \brief Find subshapes complying with given status about surface
1351 * \param theBox - the box to check state of subshapes against
1352 * \param theShape - the shape to explore
1353 * \param theShapeType - type of subshape of theShape
1354 * \param theState - required state
1355 * \retval Handle(TColStd_HSequenceOfTransient) - found subshapes
1357 //=======================================================================
1359 Handle(TColStd_HSequenceOfTransient)
1360 GEOMImpl_IShapesOperations::GetShapesOnBox(const Handle(GEOM_Object)& theBox,
1361 const Handle(GEOM_Object)& theShape,
1362 const Standard_Integer theShapeType,
1363 GEOMAlgo_State theState)
1365 // Find subshapes ids
1366 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
1367 getShapesOnBoxIDs (theBox, theShape, theShapeType, theState);
1368 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
1371 // Find objects by indices
1372 TCollection_AsciiString anAsciiList;
1373 Handle(TColStd_HSequenceOfTransient) aSeq;
1374 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
1375 if ( aSeq.IsNull() || aSeq->IsEmpty() )
1378 // Make a Python command
1380 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
1381 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1383 GEOM::TPythonDump(aFunction)
1384 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnBox("
1387 << TopAbs_ShapeEnum(theShapeType) << ", "
1395 //=======================================================================
1396 //function : getShapesOnSurfaceIDs
1398 * \brief Find IDs of subshapes complying with given status about surface
1399 * \param theSurface - the surface to check state of subshapes against
1400 * \param theShape - the shape to explore
1401 * \param theShapeType - type of subshape of theShape
1402 * \param theState - required state
1403 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1405 //=======================================================================
1407 Handle(TColStd_HSequenceOfInteger)
1408 GEOMImpl_IShapesOperations::getShapesOnSurfaceIDs(const Handle(Geom_Surface)& theSurface,
1409 const TopoDS_Shape& theShape,
1410 TopAbs_ShapeEnum theShapeType,
1411 GEOMAlgo_State theState)
1413 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
1415 // Check presence of triangulation, build if need
1416 if (!CheckTriangulation(theShape))
1420 GEOMAlgo_FinderShapeOn1 aFinder;
1421 Standard_Real aTol = 0.0001; // default value
1423 aFinder.SetShape(theShape);
1424 aFinder.SetTolerance(aTol);
1425 aFinder.SetSurface(theSurface);
1426 aFinder.SetShapeType(theShapeType);
1427 aFinder.SetState(theState);
1429 // Sets the minimal number of inner points for the faces that do not have own
1430 // inner points at all (for e.g. rectangular planar faces have just 2 triangles).
1432 aFinder.SetNbPntsMin(3);
1433 // Sets the maximal number of inner points for edges or faces.
1434 // It is usefull for the cases when this number is very big (e.g =2000) to improve
1435 // the performance. If this value =0, all inner points will be taken into account.
1437 aFinder.SetNbPntsMax(100);
1441 // Interprete results
1442 Standard_Integer iErr = aFinder.ErrorStatus();
1443 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
1445 MESSAGE(" iErr : " << iErr);
1446 TCollection_AsciiString aMsg (" iErr : ");
1447 aMsg += TCollection_AsciiString(iErr);
1451 Standard_Integer iWrn = aFinder.WarningStatus();
1452 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
1454 MESSAGE(" *** iWrn : " << iWrn);
1457 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
1459 if (listSS.Extent() < 1) {
1460 SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
1464 // Fill sequence of object IDs
1465 aSeqOfIDs = new TColStd_HSequenceOfInteger;
1467 TopTools_IndexedMapOfShape anIndices;
1468 TopExp::MapShapes(theShape, anIndices);
1470 TopTools_ListIteratorOfListOfShape itSub (listSS);
1471 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
1472 int id = anIndices.FindIndex(itSub.Value());
1473 aSeqOfIDs->Append(id);
1479 //=======================================================================
1480 //function : getObjectsShapesOn
1482 * \brief Find shape objects and their entries by their ids
1483 * \param theShapeIDs - incoming shape ids
1484 * \param theShapeEntries - outgoing entries like "entry1, entry2, ..."
1485 * \retval Handle(TColStd_HSequenceOfTransient) - found shape objects
1487 //=======================================================================
1489 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::
1490 getObjectsShapesOn(const Handle(GEOM_Object)& theShape,
1491 const Handle(TColStd_HSequenceOfInteger)& theShapeIDs,
1492 TCollection_AsciiString & theShapeEntries)
1494 Handle(TColStd_HSequenceOfTransient) aSeq;
1496 if ( !theShapeIDs.IsNull() && theShapeIDs->Length() > 0 )
1498 aSeq = new TColStd_HSequenceOfTransient;
1499 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
1500 TCollection_AsciiString anEntry;
1501 for ( int i = 1; i <= theShapeIDs->Length(); ++i )
1503 anArray->SetValue(1, theShapeIDs->Value( i ));
1504 Handle(GEOM_Object) anObj = GetEngine()->AddSubShape(theShape, anArray);
1505 aSeq->Append( anObj );
1507 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
1508 if ( i != 1 ) theShapeEntries += ",";
1509 theShapeEntries += anEntry;
1515 //=======================================================================
1516 //function : getShapesOnSurface
1518 * \brief Find subshapes complying with given status about surface
1519 * \param theSurface - the surface to check state of subshapes against
1520 * \param theShape - the shape to explore
1521 * \param theShapeType - type of subshape of theShape
1522 * \param theState - required state
1523 * \param theShapeEntries - outgoing entries like "entry1, entry2, ..."
1524 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1526 //=======================================================================
1528 Handle(TColStd_HSequenceOfTransient)
1529 GEOMImpl_IShapesOperations::getShapesOnSurface(const Handle(Geom_Surface)& theSurface,
1530 const Handle(GEOM_Object)& theShape,
1531 TopAbs_ShapeEnum theShapeType,
1532 GEOMAlgo_State theState,
1533 TCollection_AsciiString & theShapeEntries)
1535 // Find subshapes ids
1536 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
1537 getShapesOnSurfaceIDs (theSurface, theShape->GetValue(), theShapeType, theState);
1538 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
1541 return getObjectsShapesOn( theShape, aSeqOfIDs, theShapeEntries );
1544 //=============================================================================
1548 //=============================================================================
1549 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnPlane
1550 (const Handle(GEOM_Object)& theShape,
1551 const Standard_Integer theShapeType,
1552 const Handle(GEOM_Object)& theAx1,
1553 const GEOMAlgo_State theState)
1557 if (theShape.IsNull() || theAx1.IsNull()) return NULL;
1559 TopoDS_Shape aShape = theShape->GetValue();
1560 TopoDS_Shape anAx1 = theAx1->GetValue();
1562 if (aShape.IsNull() || anAx1.IsNull()) return NULL;
1564 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
1565 if ( !checkTypeShapesOn( theShapeType ))
1569 Handle(Geom_Surface) aPlane = makePlane( anAx1 );
1570 if ( aPlane.IsNull() )
1574 TCollection_AsciiString anAsciiList;
1575 Handle(TColStd_HSequenceOfTransient) aSeq;
1576 aSeq = getShapesOnSurface( aPlane, theShape, aShapeType, theState, anAsciiList );
1577 if ( aSeq.IsNull() || aSeq->Length() == 0 )
1580 // Make a Python command
1582 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
1583 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1585 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
1586 << "] = geompy.GetShapesOnPlane(" << theShape << ", "
1587 << aShapeType << ", " << theAx1 << ", " << theState << ")";
1593 //=============================================================================
1595 * GetShapesOnPlaneWithLocation
1597 //=============================================================================
1598 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnPlaneWithLocation
1599 (const Handle(GEOM_Object)& theShape,
1600 const Standard_Integer theShapeType,
1601 const Handle(GEOM_Object)& theAx1,
1602 const Handle(GEOM_Object)& thePnt,
1603 const GEOMAlgo_State theState)
1607 if (theShape.IsNull() || theAx1.IsNull() || thePnt.IsNull()) return NULL;
1609 TopoDS_Shape aShape = theShape->GetValue();
1610 TopoDS_Shape anAx1 = theAx1->GetValue();
1611 TopoDS_Shape anPnt = thePnt->GetValue();
1613 if (aShape.IsNull() || anAx1.IsNull() || anPnt.IsNull()) return NULL;
1615 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
1616 if ( !checkTypeShapesOn( theShapeType ))
1620 if ( anAx1.ShapeType() != TopAbs_EDGE || anPnt.ShapeType() != TopAbs_VERTEX ) return NULL;
1621 TopoDS_Vertex V1, V2, V3;
1622 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
1623 TopExp::Vertices(anEdge, V1, V2, Standard_True);
1625 if (V1.IsNull() || V2.IsNull()) {
1626 SetErrorCode("Bad edge given for the plane normal vector");
1629 V3 = TopoDS::Vertex(anPnt);
1632 SetErrorCode("Bad vertex given for the plane location");
1635 gp_Pnt aLoc = BRep_Tool::Pnt(V3);
1636 gp_Vec aVec(BRep_Tool::Pnt(V1),BRep_Tool::Pnt(V2));
1638 if (aVec.Magnitude() < Precision::Confusion()) {
1639 SetErrorCode("Vector with null magnitude given");
1642 Handle(Geom_Surface) aPlane = new Geom_Plane(aLoc, aVec);
1644 if ( aPlane.IsNull() )
1648 TCollection_AsciiString anAsciiList;
1649 Handle(TColStd_HSequenceOfTransient) aSeq;
1650 aSeq = getShapesOnSurface( aPlane, theShape, aShapeType, theState, anAsciiList );
1651 if ( aSeq.IsNull() || aSeq->Length() == 0 )
1654 // Make a Python command
1656 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
1657 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1659 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
1660 << "] = geompy.GetShapesOnPlaneWithLocation(" << theShape << ", "
1661 << aShapeType << ", " << theAx1 << ", "<< thePnt <<", " << theState << ")";
1667 //=============================================================================
1669 * GetShapesOnCylinder
1671 //=============================================================================
1672 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnCylinder
1673 (const Handle(GEOM_Object)& theShape,
1674 const Standard_Integer theShapeType,
1675 const Handle(GEOM_Object)& theAxis,
1676 const Standard_Real theRadius,
1677 const GEOMAlgo_State theState)
1681 if (theShape.IsNull() || theAxis.IsNull()) return NULL;
1683 TopoDS_Shape aShape = theShape->GetValue();
1684 TopoDS_Shape anAxis = theAxis->GetValue();
1686 if (aShape.IsNull() || anAxis.IsNull()) return NULL;
1688 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
1689 if ( !checkTypeShapesOn( aShapeType ))
1692 // Create a cylinder surface
1693 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
1694 if ( aCylinder.IsNull() )
1698 TCollection_AsciiString anAsciiList;
1699 Handle(TColStd_HSequenceOfTransient) aSeq;
1700 aSeq = getShapesOnSurface( aCylinder, theShape, aShapeType, theState, anAsciiList );
1701 if ( aSeq.IsNull() || aSeq->Length() == 0 )
1704 // Make a Python command
1706 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
1707 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1709 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
1710 << "] = geompy.GetShapesOnCylinder(" << theShape << ", " << aShapeType
1711 << ", " << theAxis << ", " << theRadius << ", " << theState << ")";
1717 //=============================================================================
1721 //=============================================================================
1722 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnSphere
1723 (const Handle(GEOM_Object)& theShape,
1724 const Standard_Integer theShapeType,
1725 const Handle(GEOM_Object)& theCenter,
1726 const Standard_Real theRadius,
1727 const GEOMAlgo_State theState)
1731 if (theShape.IsNull() || theCenter.IsNull()) return NULL;
1733 TopoDS_Shape aShape = theShape->GetValue();
1734 TopoDS_Shape aCenter = theCenter->GetValue();
1736 if (aShape.IsNull() || aCenter.IsNull()) return NULL;
1738 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
1739 if ( !checkTypeShapesOn( aShapeType ))
1742 // Center of the sphere
1743 if (aCenter.ShapeType() != TopAbs_VERTEX) return NULL;
1744 gp_Pnt aLoc = BRep_Tool::Pnt(TopoDS::Vertex(aCenter));
1746 gp_Ax3 anAx3 (aLoc, gp::DZ());
1747 Handle(Geom_SphericalSurface) aSphere =
1748 new Geom_SphericalSurface(anAx3, theRadius);
1751 TCollection_AsciiString anAsciiList;
1752 Handle(TColStd_HSequenceOfTransient) aSeq;
1753 aSeq = getShapesOnSurface( aSphere, theShape, aShapeType, theState, anAsciiList );
1754 if ( aSeq.IsNull() || aSeq->Length() == 0 )
1757 // Make a Python command
1759 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
1760 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1762 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
1763 << "] = geompy.GetShapesOnSphere(" << theShape << ", " << aShapeType
1764 << ", " << theCenter << ", " << theRadius << ", " << theState << ")";
1770 //=============================================================================
1772 * GetShapesOnPlaneIDs
1774 //=============================================================================
1775 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnPlaneIDs
1776 (const Handle(GEOM_Object)& theShape,
1777 const Standard_Integer theShapeType,
1778 const Handle(GEOM_Object)& theAx1,
1779 const GEOMAlgo_State theState)
1783 if (theShape.IsNull() || theAx1.IsNull()) return NULL;
1785 TopoDS_Shape aShape = theShape->GetValue();
1786 TopoDS_Shape anAx1 = theAx1->GetValue();
1788 if (aShape.IsNull() || anAx1.IsNull()) return NULL;
1790 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
1791 if ( !checkTypeShapesOn( aShapeType ))
1795 Handle(Geom_Surface) aPlane = makePlane( anAx1 );
1796 if ( aPlane.IsNull() )
1800 Handle(TColStd_HSequenceOfInteger) aSeq;
1801 aSeq = getShapesOnSurfaceIDs( aPlane, aShape, aShapeType, theState );
1803 // The GetShapesOnPlaneIDs() doesn't change object so no new function is required.
1804 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAx1)->GetLastFunction();
1806 // Make a Python command
1807 GEOM::TPythonDump(aFunction, /*append=*/true)
1808 << "listShapesOnPlane = geompy.GetShapesOnPlaneIDs"
1809 << "(" << theShape << "," << aShapeType << "," << theAx1 << "," << theState << ")";
1815 //=============================================================================
1817 * GetShapesOnPlaneWithLocationIDs
1819 //=============================================================================
1820 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnPlaneWithLocationIDs
1821 (const Handle(GEOM_Object)& theShape,
1822 const Standard_Integer theShapeType,
1823 const Handle(GEOM_Object)& theAx1,
1824 const Handle(GEOM_Object)& thePnt,
1825 const GEOMAlgo_State theState)
1829 if (theShape.IsNull() || theAx1.IsNull() || thePnt.IsNull()) return NULL;
1831 TopoDS_Shape aShape = theShape->GetValue();
1832 TopoDS_Shape anAx1 = theAx1->GetValue();
1833 TopoDS_Shape anPnt = thePnt->GetValue();
1835 if (aShape.IsNull() || anAx1.IsNull() || anPnt.IsNull()) return NULL;
1837 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
1838 if ( !checkTypeShapesOn( aShapeType ))
1842 if (anAx1.ShapeType() != TopAbs_EDGE || anPnt.ShapeType() != TopAbs_VERTEX) return NULL;
1843 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
1844 TopoDS_Vertex V1, V2, V3;
1845 TopExp::Vertices(anEdge, V1, V2, Standard_True);
1846 if (V1.IsNull() || V2.IsNull()) {
1847 SetErrorCode("Bad edge given for the plane normal vector");
1850 V3 = TopoDS::Vertex(anPnt);
1852 SetErrorCode("Bad vertex given for the plane location");
1855 gp_Pnt aLoc = BRep_Tool::Pnt(V3);
1856 gp_Vec aVec(BRep_Tool::Pnt(V1),BRep_Tool::Pnt(V2));
1857 if (aVec.Magnitude() < Precision::Confusion()) {
1858 SetErrorCode("Vector with null magnitude given");
1862 Handle(Geom_Surface) aPlane = new Geom_Plane(aLoc, aVec);
1863 if ( aPlane.IsNull() )
1867 Handle(TColStd_HSequenceOfInteger) aSeq;
1868 aSeq = getShapesOnSurfaceIDs( aPlane, aShape, aShapeType, theState );
1870 // The GetShapesOnPlaneIDs() doesn't change object so no new function is required.
1871 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAx1)->GetLastFunction();
1873 // Make a Python command
1874 GEOM::TPythonDump(aFunction, /*append=*/true)
1875 << "listShapesOnPlane = geompy.GetShapesOnPlaneWithLocationIDs"
1876 << "(" << theShape << ", " << aShapeType << ", " << theAx1 << ", "<< thePnt << ", " << theState << ")";
1882 //=============================================================================
1884 * GetShapesOnCylinderIDs
1886 //=============================================================================
1887 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnCylinderIDs
1888 (const Handle(GEOM_Object)& theShape,
1889 const Standard_Integer theShapeType,
1890 const Handle(GEOM_Object)& theAxis,
1891 const Standard_Real theRadius,
1892 const GEOMAlgo_State theState)
1896 if (theShape.IsNull() || theAxis.IsNull()) return NULL;
1898 TopoDS_Shape aShape = theShape->GetValue();
1899 TopoDS_Shape anAxis = theAxis->GetValue();
1901 if (aShape.IsNull() || anAxis.IsNull()) return NULL;
1903 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
1904 if ( !checkTypeShapesOn( aShapeType ))
1907 // Create a cylinder surface
1908 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
1909 if ( aCylinder.IsNull() )
1913 Handle(TColStd_HSequenceOfInteger) aSeq;
1914 aSeq = getShapesOnSurfaceIDs( aCylinder, aShape, aShapeType, theState );
1916 // The GetShapesOnCylinder() doesn't change object so no new function is required.
1917 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAxis)->GetLastFunction();
1919 // Make a Python command
1920 GEOM::TPythonDump(aFunction, /*append=*/true)
1921 << "listShapesOnCylinder = geompy.GetShapesOnCylinderIDs"
1922 << "(" << theShape << ", " << aShapeType << ", " << theAxis << ", "
1923 << theRadius << ", " << theState << ")";
1929 //=============================================================================
1931 * GetShapesOnSphereIDs
1933 //=============================================================================
1934 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnSphereIDs
1935 (const Handle(GEOM_Object)& theShape,
1936 const Standard_Integer theShapeType,
1937 const Handle(GEOM_Object)& theCenter,
1938 const Standard_Real theRadius,
1939 const GEOMAlgo_State theState)
1943 if (theShape.IsNull() || theCenter.IsNull()) return NULL;
1945 TopoDS_Shape aShape = theShape->GetValue();
1946 TopoDS_Shape aCenter = theCenter->GetValue();
1948 if (aShape.IsNull() || aCenter.IsNull()) return NULL;
1950 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
1951 if ( !checkTypeShapesOn( aShapeType ))
1954 // Center of the sphere
1955 if (aCenter.ShapeType() != TopAbs_VERTEX) return NULL;
1956 gp_Pnt aLoc = BRep_Tool::Pnt(TopoDS::Vertex(aCenter));
1958 gp_Ax3 anAx3 (aLoc, gp::DZ());
1959 Handle(Geom_SphericalSurface) aSphere =
1960 new Geom_SphericalSurface(anAx3, theRadius);
1963 Handle(TColStd_HSequenceOfInteger) aSeq;
1964 aSeq = getShapesOnSurfaceIDs( aSphere, aShape, aShapeType, theState );
1966 // The GetShapesOnSphere() doesn't change object so no new function is required.
1967 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theCenter)->GetLastFunction();
1969 // Make a Python command
1970 GEOM::TPythonDump(aFunction, /*append=*/true)
1971 << "listShapesOnCylinder = geompy.GetShapesOnCylinderIDs"
1972 << "(" << theShape << ", " << aShapeType << ", " << theCenter << ", "
1973 << theRadius << ", " << theState << ")";
1979 //=======================================================================
1980 //function : getShapesOnQuadrangleIDs
1982 * \brief Find IDs of subshapes complying with given status about quadrangle
1983 * \param theShape - the shape to explore
1984 * \param theShapeType - type of subshape of theShape
1985 * \param theTopLeftPoint - top left quadrangle corner
1986 * \param theTopRigthPoint - top right quadrangle corner
1987 * \param theBottomLeftPoint - bottom left quadrangle corner
1988 * \param theBottomRigthPoint - bottom right quadrangle corner
1989 * \param theState - required state
1990 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1992 //=======================================================================
1994 Handle(TColStd_HSequenceOfInteger)
1995 GEOMImpl_IShapesOperations::getShapesOnQuadrangleIDs (const Handle(GEOM_Object)& theShape,
1996 const Standard_Integer theShapeType,
1997 const Handle(GEOM_Object)& theTopLeftPoint,
1998 const Handle(GEOM_Object)& theTopRigthPoint,
1999 const Handle(GEOM_Object)& theBottomLeftPoint,
2000 const Handle(GEOM_Object)& theBottomRigthPoint,
2001 const GEOMAlgo_State theState)
2005 if ( theShape.IsNull() ||
2006 theTopLeftPoint.IsNull() ||
2007 theTopRigthPoint.IsNull() ||
2008 theBottomLeftPoint.IsNull() ||
2009 theBottomRigthPoint.IsNull() )
2012 TopoDS_Shape aShape = theShape->GetValue();
2013 TopoDS_Shape aTL = theTopLeftPoint->GetValue();
2014 TopoDS_Shape aTR = theTopRigthPoint->GetValue();
2015 TopoDS_Shape aBL = theBottomLeftPoint->GetValue();
2016 TopoDS_Shape aBR = theBottomRigthPoint->GetValue();
2018 if (aShape.IsNull() ||
2023 aTL.ShapeType() != TopAbs_VERTEX ||
2024 aTR.ShapeType() != TopAbs_VERTEX ||
2025 aBL.ShapeType() != TopAbs_VERTEX ||
2026 aBR.ShapeType() != TopAbs_VERTEX )
2029 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2030 if ( !checkTypeShapesOn( aShapeType ))
2033 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
2035 // Check presence of triangulation, build if need
2036 if (!CheckTriangulation(aShape))
2040 gp_Pnt aPntTL = BRep_Tool::Pnt(TopoDS::Vertex(aTL));
2041 gp_Pnt aPntTR = BRep_Tool::Pnt(TopoDS::Vertex(aTR));
2042 gp_Pnt aPntBL = BRep_Tool::Pnt(TopoDS::Vertex(aBL));
2043 gp_Pnt aPntBR = BRep_Tool::Pnt(TopoDS::Vertex(aBR));
2045 GEOMAlgo_FinderShapeOnQuad aFinder( aPntTL, aPntTR, aPntBL, aPntBR );
2046 Standard_Real aTol = 0.0001; // default value
2048 aFinder.SetShape(aShape);
2049 aFinder.SetTolerance(aTol);
2050 //aFinder.SetSurface(theSurface);
2051 aFinder.SetShapeType(aShapeType);
2052 aFinder.SetState(theState);
2054 // Sets the minimal number of inner points for the faces that do not have own
2055 // inner points at all (for e.g. rectangular planar faces have just 2 triangles).
2057 aFinder.SetNbPntsMin(3);
2058 // Sets the maximal number of inner points for edges or faces.
2059 // It is usefull for the cases when this number is very big (e.g =2000) to improve
2060 // the performance. If this value =0, all inner points will be taken into account.
2062 aFinder.SetNbPntsMax(100);
2066 // Interprete results
2067 Standard_Integer iErr = aFinder.ErrorStatus();
2068 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
2070 MESSAGE(" iErr : " << iErr);
2071 TCollection_AsciiString aMsg (" iErr : ");
2072 aMsg += TCollection_AsciiString(iErr);
2076 Standard_Integer iWrn = aFinder.WarningStatus();
2077 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
2079 MESSAGE(" *** iWrn : " << iWrn);
2082 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
2084 if (listSS.Extent() < 1) {
2085 SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
2089 // Fill sequence of object IDs
2090 aSeqOfIDs = new TColStd_HSequenceOfInteger;
2092 TopTools_IndexedMapOfShape anIndices;
2093 TopExp::MapShapes(aShape, anIndices);
2095 TopTools_ListIteratorOfListOfShape itSub (listSS);
2096 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
2097 int id = anIndices.FindIndex(itSub.Value());
2098 aSeqOfIDs->Append(id);
2103 //=======================================================================
2104 //function : GetShapesOnQuadrangle
2106 * \brief Find subshapes complying with given status about quadrangle
2107 * \param theShape - the shape to explore
2108 * \param theShapeType - type of subshape of theShape
2109 * \param theTopLeftPoint - top left quadrangle corner
2110 * \param theTopRigthPoint - top right quadrangle corner
2111 * \param theBottomLeftPoint - bottom left quadrangle corner
2112 * \param theBottomRigthPoint - bottom right quadrangle corner
2113 * \param theState - required state
2114 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
2116 //=======================================================================
2118 Handle(TColStd_HSequenceOfTransient)
2119 GEOMImpl_IShapesOperations::GetShapesOnQuadrangle (const Handle(GEOM_Object)& theShape,
2120 const Standard_Integer theShapeType,
2121 const Handle(GEOM_Object)& theTopLeftPoint,
2122 const Handle(GEOM_Object)& theTopRigthPoint,
2123 const Handle(GEOM_Object)& theBottomLeftPoint,
2124 const Handle(GEOM_Object)& theBottomRigthPoint,
2125 const GEOMAlgo_State theState)
2128 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2129 getShapesOnQuadrangleIDs( theShape,
2134 theBottomRigthPoint,
2136 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->IsEmpty() )
2139 // Find objects by indices
2140 TCollection_AsciiString anAsciiList;
2141 Handle(TColStd_HSequenceOfTransient) aSeq;
2142 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
2143 if ( aSeq.IsNull() || aSeq->IsEmpty() )
2146 // Make a Python command
2148 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2149 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2151 GEOM::TPythonDump(aFunction)
2152 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnQuadrangle("
2154 << TopAbs_ShapeEnum(theShapeType) << ", "
2155 << theTopLeftPoint << ", "
2156 << theTopRigthPoint << ", "
2157 << theBottomLeftPoint << ", "
2158 << theBottomRigthPoint << ", "
2165 //=======================================================================
2166 //function : GetShapesOnQuadrangleIDs
2168 * \brief Find IDs of subshapes complying with given status about quadrangle
2169 * \param theShape - the shape to explore
2170 * \param theShapeType - type of subshape of theShape
2171 * \param theTopLeftPoint - top left quadrangle corner
2172 * \param theTopRigthPoint - top right quadrangle corner
2173 * \param theBottomLeftPoint - bottom left quadrangle corner
2174 * \param theBottomRigthPoint - bottom right quadrangle corner
2175 * \param theState - required state
2176 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
2178 //=======================================================================
2180 Handle(TColStd_HSequenceOfInteger)
2181 GEOMImpl_IShapesOperations::GetShapesOnQuadrangleIDs (const Handle(GEOM_Object)& theShape,
2182 const Standard_Integer theShapeType,
2183 const Handle(GEOM_Object)& theTopLeftPoint,
2184 const Handle(GEOM_Object)& theTopRigthPoint,
2185 const Handle(GEOM_Object)& theBottomLeftPoint,
2186 const Handle(GEOM_Object)& theBottomRigthPoint,
2187 const GEOMAlgo_State theState)
2190 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2191 getShapesOnQuadrangleIDs( theShape,
2196 theBottomRigthPoint,
2198 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->IsEmpty() )
2201 // Make a Python command
2203 // The GetShapesOnCylinder() doesn't change object so no new function is required.
2204 Handle(GEOM_Object) lastObj = GEOM::GetCreatedLast(theShape,theTopLeftPoint);
2205 lastObj = GEOM::GetCreatedLast(lastObj,theTopRigthPoint);
2206 lastObj = GEOM::GetCreatedLast(lastObj,theBottomRigthPoint);
2207 lastObj = GEOM::GetCreatedLast(lastObj,theBottomLeftPoint);
2208 Handle(GEOM_Function) aFunction = lastObj->GetLastFunction();
2210 GEOM::TPythonDump(aFunction, /*append=*/true)
2211 << "listShapesOnQuadrangle = geompy.GetShapesOnQuadrangleIDs("
2213 << TopAbs_ShapeEnum(theShapeType) << ", "
2214 << theTopLeftPoint << ", "
2215 << theTopRigthPoint << ", "
2216 << theBottomLeftPoint << ", "
2217 << theBottomRigthPoint << ", "
2225 //=============================================================================
2229 //=============================================================================
2230 static bool GetInPlaceOfShape (const Handle(GEOM_Function)& theWhereFunction,
2231 const TopTools_IndexedMapOfShape& theWhereIndices,
2232 const TopoDS_Shape& theWhat,
2233 TColStd_ListOfInteger& theModifiedList)
2235 if (theWhereFunction.IsNull() || theWhat.IsNull()) return false;
2237 if (theWhereIndices.Contains(theWhat)) {
2238 // entity was not changed by the operation
2239 Standard_Integer aWhatIndex = theWhereIndices.FindIndex(theWhat);
2240 theModifiedList.Append(aWhatIndex);
2244 // try to find in history
2245 TDF_Label aHistoryLabel = theWhereFunction->GetHistoryEntry(Standard_False);
2247 // search in history for all argument shapes
2248 Standard_Boolean isFound = Standard_False;
2249 Standard_Boolean isGood = Standard_False;
2251 TDF_LabelSequence aLabelSeq;
2252 theWhereFunction->GetDependency(aLabelSeq);
2253 Standard_Integer nbArg = aLabelSeq.Length();
2255 for (Standard_Integer iarg = 1; iarg <= nbArg && !isFound; iarg++) {
2257 TDF_Label anArgumentRefLabel = aLabelSeq.Value(iarg);
2259 Handle(GEOM_Object) anArgumentObject = GEOM_Object::GetReferencedObject(anArgumentRefLabel);
2260 TopoDS_Shape anArgumentShape = anArgumentObject->GetValue();
2262 TopTools_IndexedMapOfShape anArgumentIndices;
2263 TopExp::MapShapes(anArgumentShape, anArgumentIndices);
2265 if (anArgumentIndices.Contains(theWhat)) {
2266 isFound = Standard_True;
2267 Standard_Integer aWhatIndex = anArgumentIndices.FindIndex(theWhat);
2269 // Find corresponding label in history
2270 TDF_Label anArgumentHistoryLabel =
2271 theWhereFunction->GetArgumentHistoryEntry(anArgumentRefLabel, Standard_False);
2272 if (anArgumentHistoryLabel.IsNull()) {
2273 // Lost History of operation argument. Possibly, all its entities was removed.
2274 isGood = Standard_True;
2277 TDF_Label aWhatHistoryLabel = anArgumentHistoryLabel.FindChild(aWhatIndex, Standard_False);
2279 if (aWhatHistoryLabel.IsNull()) {
2280 // Removed entity ? Compound ? Compsolid ? Shell ? Wire
2281 isGood = Standard_False;
2283 Handle(TDataStd_IntegerArray) anIntegerArray;
2284 if (!aWhatHistoryLabel.FindAttribute(TDataStd_IntegerArray::GetID(), anIntegerArray)) {
2285 //Error: Empty modifications history for the sought shape.
2286 isGood = Standard_False;
2289 isGood = Standard_True;
2290 Standard_Integer imod, aModifLen = anIntegerArray->Array()->Length();
2291 for (imod = 1; imod <= aModifLen; imod++) {
2292 theModifiedList.Append(anIntegerArray->Array()->Value(imod));
2303 // try compound/compsolid/shell/wire element by element
2304 bool isFoundAny = false;
2305 TopTools_MapOfShape mapShape;
2307 if (theWhat.ShapeType() == TopAbs_COMPOUND ||
2308 theWhat.ShapeType() == TopAbs_COMPSOLID) {
2309 // recursive processing of compound/compsolid
2310 TopoDS_Iterator anIt (theWhat, Standard_True, Standard_True);
2311 for (; anIt.More(); anIt.Next()) {
2312 if (mapShape.Add(anIt.Value())) {
2313 TopoDS_Shape curWhat = anIt.Value();
2314 isFoundAny = GetInPlaceOfShape(theWhereFunction, theWhereIndices, curWhat, theModifiedList);
2315 if (isFoundAny) isFound = Standard_True;
2319 else if (theWhat.ShapeType() == TopAbs_SHELL) {
2320 // try to replace a shell by its faces images
2321 TopExp_Explorer anExp (theWhat, TopAbs_FACE);
2322 for (; anExp.More(); anExp.Next()) {
2323 if (mapShape.Add(anExp.Current())) {
2324 TopoDS_Shape curWhat = anExp.Current();
2325 isFoundAny = GetInPlaceOfShape(theWhereFunction, theWhereIndices, curWhat, theModifiedList);
2326 if (isFoundAny) isFound = Standard_True;
2330 else if (theWhat.ShapeType() == TopAbs_WIRE) {
2331 // try to replace a wire by its edges images
2332 TopExp_Explorer anExp (theWhat, TopAbs_EDGE);
2333 for (; anExp.More(); anExp.Next()) {
2334 if (mapShape.Add(anExp.Current())) {
2335 TopoDS_Shape curWhat = anExp.Current();
2336 isFoundAny = GetInPlaceOfShape(theWhereFunction, theWhereIndices, curWhat, theModifiedList);
2337 if (isFoundAny) isFound = Standard_True;
2349 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlace
2350 (Handle(GEOM_Object) theShapeWhere,
2351 Handle(GEOM_Object) theShapeWhat)
2355 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
2357 TopoDS_Shape aWhere = theShapeWhere->GetValue();
2358 TopoDS_Shape aWhat = theShapeWhat->GetValue();
2360 if (aWhere.IsNull() || aWhat.IsNull()) return NULL;
2362 Handle(GEOM_Function) aWhereFunction = theShapeWhere->GetLastFunction();
2363 if (aWhereFunction.IsNull()) return NULL;
2365 //Fill array of indices
2366 TopTools_IndexedMapOfShape aWhereIndices;
2367 TopExp::MapShapes(aWhere, aWhereIndices);
2370 TColStd_ListOfInteger aModifiedList;
2371 bool isFound = GetInPlaceOfShape(aWhereFunction, aWhereIndices, aWhat, aModifiedList);
2373 if (!isFound || aModifiedList.Extent() < 1) {
2374 SetErrorCode("Error: No history found for the sought shape or its sub-shapes.");
2378 Handle(TColStd_HArray1OfInteger) aModifiedArray =
2379 new TColStd_HArray1OfInteger (1, aModifiedList.Extent());
2380 TColStd_ListIteratorOfListOfInteger anIterModif (aModifiedList);
2381 for (Standard_Integer imod = 1; anIterModif.More(); anIterModif.Next(), imod++) {
2382 aModifiedArray->SetValue(imod, anIterModif.Value());
2386 Handle(GEOM_Object) aResult = GetEngine()->AddSubShape(theShapeWhere, aModifiedArray);
2387 if (aResult.IsNull()) {
2388 SetErrorCode("Error in algorithm: result found, but cannot be returned.");
2392 if (aModifiedArray->Length() > 1) {
2394 aResult->SetType(GEOM_GROUP);
2396 //Set a sub shape type
2397 TopoDS_Shape aFirstFound = aWhereIndices.FindKey(aModifiedArray->Value(1));
2398 TopAbs_ShapeEnum aShapeType = aFirstFound.ShapeType();
2400 TDF_Label aFreeLabel = aResult->GetFreeLabel();
2401 TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aShapeType);
2404 //Make a Python command
2405 Handle(GEOM_Function) aFunction = aResult->GetFunction(1);
2407 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetInPlace("
2408 << theShapeWhere << ", " << theShapeWhat << ")";
2414 //=======================================================================
2415 //function : SortShapes
2417 //=======================================================================
2418 void GEOMImpl_IShapesOperations::SortShapes(TopTools_ListOfShape& SL)
2420 Standard_Integer MaxShapes = SL.Extent();
2421 TopTools_Array1OfShape aShapes (1,MaxShapes);
2422 TColStd_Array1OfInteger OrderInd(1,MaxShapes);
2423 TColStd_Array1OfReal MidXYZ (1,MaxShapes); //X,Y,Z;
2424 TColStd_Array1OfReal Length (1,MaxShapes); //X,Y,Z;
2426 // Computing of CentreOfMass
2427 Standard_Integer Index;
2430 TopTools_ListIteratorOfListOfShape it(SL);
2431 for (Index=1; it.More(); Index++)
2433 TopoDS_Shape S = it.Value();
2434 SL.Remove( it ); // == it.Next()
2436 OrderInd.SetValue (Index, Index);
2437 if (S.ShapeType() == TopAbs_VERTEX)
2439 GPoint = BRep_Tool::Pnt( TopoDS::Vertex( S ));
2440 Length.SetValue( Index, (Standard_Real) S.Orientation());
2444 BRepGProp::LinearProperties (S, GPr);
2445 GPoint = GPr.CentreOfMass();
2446 Length.SetValue( Index, GPr.Mass() );
2448 MidXYZ.SetValue(Index,
2449 GPoint.X()*999 + GPoint.Y()*99 + GPoint.Z()*0.9);
2453 Standard_Integer aTemp;
2454 Standard_Boolean exchange, Sort = Standard_True;
2457 Sort = Standard_False;
2458 for (Index=1; Index < MaxShapes; Index++)
2460 if (MidXYZ(OrderInd(Index)) > MidXYZ(OrderInd(Index+1)))
2461 exchange = Standard_True;
2462 else if (MidXYZ(OrderInd(Index)) == MidXYZ(OrderInd(Index+1)) &&
2463 Length(OrderInd(Index)) > Length(OrderInd(Index+1)) )
2464 exchange = Standard_True;
2466 exchange = Standard_False;
2469 aTemp = OrderInd(Index);
2470 OrderInd(Index) = OrderInd(Index+1);
2471 OrderInd(Index+1) = aTemp;
2472 Sort = Standard_True;
2476 for (Index=1; Index <= MaxShapes; Index++)
2477 SL.Append( aShapes( OrderInd(Index) ));
2480 //=======================================================================
2481 //function : CheckTriangulation
2483 //=======================================================================
2484 bool GEOMImpl_IShapesOperations::CheckTriangulation (const TopoDS_Shape& aShape)
2486 TopExp_Explorer exp (aShape, TopAbs_FACE);
2488 SetErrorCode("Shape without faces given");
2492 TopLoc_Location aTopLoc;
2493 Handle(Poly_Triangulation) aTRF;
2494 aTRF = BRep_Tool::Triangulation(TopoDS::Face(exp.Current()), aTopLoc);
2495 if (aTRF.IsNull()) {
2496 // calculate deflection
2497 Standard_Real aDeviationCoefficient = 0.001;
2500 BRepBndLib::Add(aShape, B);
2501 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
2502 B.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
2504 Standard_Real dx = aXmax - aXmin, dy = aYmax - aYmin, dz = aZmax - aZmin;
2505 Standard_Real aDeflection = Max(Max(dx, dy), dz) * aDeviationCoefficient * 4;
2506 Standard_Real aHLRAngle = 0.349066;
2508 BRepMesh_IncrementalMesh Inc (aShape, aDeflection, Standard_False, aHLRAngle);
2514 #define MAX_TOLERANCE 1.e-7
2517 //=======================================================================
2518 //function : isSameEdge
2519 //purpose : Returns True if two edges coincide
2520 //=======================================================================
2521 static bool isSameEdge(const TopoDS_Edge& theEdge1, const TopoDS_Edge& theEdge2)
2523 TopoDS_Vertex V11, V12, V21, V22;
2524 TopExp::Vertices(theEdge1, V11, V12);
2525 TopExp::Vertices(theEdge2, V21, V22);
2526 gp_Pnt P11 = BRep_Tool::Pnt(V11);
2527 gp_Pnt P12 = BRep_Tool::Pnt(V12);
2528 gp_Pnt P21 = BRep_Tool::Pnt(V21);
2529 gp_Pnt P22 = BRep_Tool::Pnt(V22);
2530 bool coincide = false;
2532 //Check that ends of edges coincide
2533 if(P11.Distance(P21) <= MAX_TOLERANCE) {
2534 if(P12.Distance(P22) <= MAX_TOLERANCE) coincide = true;
2536 else if(P11.Distance(P22) <= MAX_TOLERANCE) {
2537 if(P12.Distance(P21) <= MAX_TOLERANCE) coincide = true;
2540 if(!coincide) return false;
2542 double U11, U12, U21, U22;
2543 Handle(Geom_Curve) C1 = BRep_Tool::Curve(theEdge1, U11, U12);
2544 Handle(Geom_Curve) C2 = BRep_Tool::Curve(theEdge2, U21, U22);
2545 if(C1->DynamicType() == C2->DynamicType()) return true;
2547 //Check that both edges has the same geometry
2548 double range = U12-U11;
2549 double U = U11+ range/3.0;
2550 gp_Pnt P1 = C1->Value(U); //Compute a point on one third of the edge's length
2551 U = U11+range*2.0/3.0;
2552 gp_Pnt P2 = C1->Value(U); //Compute a point on two thirds of the edge's length
2554 if(!GeomLib_Tool::Parameter(C2, P1, MAX_TOLERANCE, U) || U < U21 || U > U22)
2557 if(P1.Distance(C2->Value(U)) > MAX_TOLERANCE) return false;
2559 if(!GeomLib_Tool::Parameter(C2, P2, MAX_TOLERANCE, U) || U < U21 || U > U22)
2562 if(P2.Distance(C2->Value(U)) > MAX_TOLERANCE) return false;
2567 #include <TopoDS_TShape.hxx>
2568 //=======================================================================
2569 //function : isSameFace
2570 //purpose : Returns True if two faces coincide
2571 //=======================================================================
2572 static bool isSameFace(const TopoDS_Face& theFace1, const TopoDS_Face& theFace2)
2574 TopExp_Explorer E(theFace1, TopAbs_EDGE);
2575 TopTools_ListOfShape LS1, LS2;
2576 for(; E.More(); E.Next()) LS1.Append(E.Current());
2578 E.Init(theFace2, TopAbs_EDGE);
2579 for(; E.More(); E.Next()) LS2.Append(E.Current());
2581 //Compare the number of edges in the faces
2582 if(LS1.Extent() != LS2.Extent()) return false;
2584 double aMin = RealFirst(), aMax = RealLast();
2585 double xminB1=aMax, yminB1=aMax, zminB1=aMax, xminB2=aMax, yminB2=aMax, zminB2=aMax;
2586 double xmaxB1=aMin, ymaxB1=aMin, zmaxB1=aMin, xmaxB2=aMin, ymaxB2=aMin, zmaxB2=aMin;
2588 for(E.Init(theFace1, TopAbs_VERTEX); E.More(); E.Next()) {
2589 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
2590 if(P.X() < xminB1) xminB1 = P.X();
2591 if(P.Y() < yminB1) yminB1 = P.Y();
2592 if(P.Z() < zminB1) zminB1 = P.Z();
2593 if(P.X() > xmaxB1) xmaxB1 = P.X();
2594 if(P.Y() > ymaxB1) ymaxB1 = P.Y();
2595 if(P.Z() > zmaxB1) zmaxB1 = P.Z();
2598 for(E.Init(theFace2, TopAbs_VERTEX); E.More(); E.Next()) {
2599 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
2600 if(P.X() < xminB2) xminB2 = P.X();
2601 if(P.Y() < yminB2) yminB2 = P.Y();
2602 if(P.Z() < zminB2) zminB2 = P.Z();
2603 if(P.X() > xmaxB2) xmaxB2 = P.X();
2604 if(P.Y() > ymaxB2) ymaxB2 = P.Y();
2605 if(P.Z() > zmaxB2) zmaxB2 = P.Z();
2608 //Compare the bounding boxes of both faces
2609 if(gp_Pnt(xminB1, yminB1, zminB1).Distance(gp_Pnt(xminB2, yminB2, zminB2)) > MAX_TOLERANCE)
2612 if(gp_Pnt(xmaxB1, ymaxB1, zmaxB1).Distance(gp_Pnt(xmaxB2, ymaxB2, zmaxB2)) > MAX_TOLERANCE)
2615 //Check that each edge of the Face1 has a counterpart in the Face2
2616 TopTools_MapOfOrientedShape aMap;
2617 TopTools_ListIteratorOfListOfShape LSI1(LS1);
2618 for(; LSI1.More(); LSI1.Next()) {
2619 TopoDS_Edge E = TopoDS::Edge(LSI1.Value());
2620 bool isFound = false;
2621 TopTools_ListIteratorOfListOfShape LSI2(LS2);
2622 for(; LSI2.More(); LSI2.Next()) {
2623 TopoDS_Shape aValue = LSI2.Value();
2624 if(aMap.Contains(aValue)) continue; //To avoid checking already found edge several times
2625 if(isSameEdge(E, TopoDS::Edge(aValue))) {
2631 if(!isFound) return false;
2634 Handle(Geom_Surface) S1 = BRep_Tool::Surface(theFace1);
2635 Handle(Geom_Surface) S2 = BRep_Tool::Surface(theFace2);
2636 if(S1->DynamicType() == S2->DynamicType()) {
2639 else { //Check if there a coincidence of two surfaces at least in two points
2640 double U11, U12, V11, V12, U21, U22, V21, V22;
2641 BRepTools::UVBounds(theFace1, U11, U12, V11, V12);
2642 BRepTools::UVBounds(theFace2, U21, U22, V21, V22);
2644 double rangeU = U12-U11;
2645 double rangeV = V12-V11;
2646 double U = U11 + rangeU/3.0;
2647 double V = V11 + rangeV/3.0;
2648 gp_Pnt P1 = S1->Value(U, V);
2649 U = U11+rangeU*2.0/3.0;
2650 V = V11+rangeV*2.0/3.0;
2651 gp_Pnt P2 = S1->Value(U, V);
2653 if(!GeomLib_Tool::Parameters(S2, P1, MAX_TOLERANCE, U, V) || U < U21 || U > U22 || V < V21 || V > V22)
2656 if(P1.Distance(S2->Value(U,V)) > MAX_TOLERANCE) return false;
2658 if(!GeomLib_Tool::Parameters(S2, P2, MAX_TOLERANCE, U, V) || U < U21 || U > U22 || V < V21 || V > V22)
2661 if(P2.Distance(S2->Value(U, V)) > MAX_TOLERANCE) return false;
2667 //=======================================================================
2668 //function : isSameSolid
2669 //purpose : Returns True if two solids coincide
2670 //=======================================================================
2671 bool isSameSolid(const TopoDS_Solid& theSolid1, const TopoDS_Solid& theSolid2)
2673 TopExp_Explorer E(theSolid1, TopAbs_FACE);
2674 TopTools_ListOfShape LS1, LS2;
2675 for(; E.More(); E.Next()) LS1.Append(E.Current());
2676 E.Init(theSolid2, TopAbs_FACE);
2677 for(; E.More(); E.Next()) LS2.Append(E.Current());
2679 if(LS1.Extent() != LS2.Extent()) return false;
2681 double aMin = RealFirst(), aMax = RealLast();
2682 double xminB1=aMax, yminB1=aMax, zminB1=aMax, xminB2=aMax, yminB2=aMax, zminB2=aMax;
2683 double xmaxB1=aMin, ymaxB1=aMin, zmaxB1=aMin, xmaxB2=aMin, ymaxB2=aMin, zmaxB2=aMin;
2685 for(E.Init(theSolid1, TopAbs_VERTEX); E.More(); E.Next()) {
2686 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
2687 if(P.X() < xminB1) xminB1 = P.X();
2688 if(P.Y() < yminB1) yminB1 = P.Y();
2689 if(P.Z() < zminB1) zminB1 = P.Z();
2690 if(P.X() > xmaxB1) xmaxB1 = P.X();
2691 if(P.Y() > ymaxB1) ymaxB1 = P.Y();
2692 if(P.Z() > zmaxB1) zmaxB1 = P.Z();
2695 for(E.Init(theSolid2, TopAbs_VERTEX); E.More(); E.Next()) {
2696 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
2697 if(P.X() < xminB2) xminB2 = P.X();
2698 if(P.Y() < yminB2) yminB2 = P.Y();
2699 if(P.Z() < zminB2) zminB2 = P.Z();
2700 if(P.X() > xmaxB2) xmaxB2 = P.X();
2701 if(P.Y() > ymaxB2) ymaxB2 = P.Y();
2702 if(P.Z() > zmaxB2) zmaxB2 = P.Z();
2705 //Compare the bounding boxes of both solids
2706 if(gp_Pnt(xminB1, yminB1, zminB1).Distance(gp_Pnt(xminB2, yminB2, zminB2)) > MAX_TOLERANCE)
2709 if(gp_Pnt(xmaxB1, ymaxB1, zmaxB1).Distance(gp_Pnt(xmaxB2, ymaxB2, zmaxB2)) > MAX_TOLERANCE)
2712 //Check that each face of the Solid1 has a counterpart in the Solid2
2713 TopTools_MapOfOrientedShape aMap;
2714 TopTools_ListIteratorOfListOfShape LSI1(LS1);
2715 for(; LSI1.More(); LSI1.Next()) {
2716 TopoDS_Face F = TopoDS::Face(LSI1.Value());
2717 bool isFound = false;
2718 TopTools_ListIteratorOfListOfShape LSI2(LS2);
2719 for(; LSI2.More(); LSI2.Next()) {
2720 if(aMap.Contains(LSI2.Value())) continue; //To avoid checking already found faces several times
2721 if(isSameFace(F, TopoDS::Face(LSI2.Value()))) {
2722 aMap.Add(LSI2.Value());
2727 if(!isFound) return false;
2733 //=======================================================================
2734 //function : GetSame
2736 //=======================================================================
2737 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetSame(const Handle(GEOM_Object)& theShapeWhere,
2738 const Handle(GEOM_Object)& theShapeWhat)
2741 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
2743 TopoDS_Shape aWhere = theShapeWhere->GetValue();
2744 TopoDS_Shape aWhat = theShapeWhat->GetValue();
2746 if (aWhere.IsNull() || aWhat.IsNull()) return NULL;
2749 bool isFound = false;
2750 TopoDS_Shape aSubShape;
2751 TopTools_MapOfShape aMap;
2753 switch(aWhat.ShapeType()) {
2754 case TopAbs_VERTEX: {
2755 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(aWhat));
2756 TopExp_Explorer E(aWhere, TopAbs_VERTEX);
2757 for(; E.More(); E.Next()) {
2758 if(!aMap.Add(E.Current())) continue;
2759 gp_Pnt P2 = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
2760 if(P.Distance(P2) <= MAX_TOLERANCE) {
2762 aSubShape = E.Current();
2769 TopoDS_Face aFace = TopoDS::Face(aWhat);
2770 TopExp_Explorer E(aWhere, TopAbs_FACE);
2771 for(; E.More(); E.Next()) {
2772 if(!aMap.Add(E.Current())) continue;
2773 if(isSameFace(aFace, TopoDS::Face(E.Current()))) {
2774 aSubShape = E.Current();
2782 TopoDS_Edge anEdge = TopoDS::Edge(aWhat);
2783 TopExp_Explorer E(aWhere, TopAbs_EDGE);
2784 for(; E.More(); E.Next()) {
2785 if(!aMap.Add(E.Current())) continue;
2786 if(isSameEdge(anEdge, TopoDS::Edge(E.Current()))) {
2787 aSubShape = E.Current();
2794 case TopAbs_SOLID: {
2795 TopoDS_Solid aSolid = TopoDS::Solid(aWhat);
2796 TopExp_Explorer E(aWhere, TopAbs_SOLID);
2797 for(; E.More(); E.Next()) {
2798 if(!aMap.Add(E.Current())) continue;
2799 if(isSameSolid(aSolid, TopoDS::Solid(E.Current()))) {
2800 aSubShape = E.Current();
2812 TopTools_IndexedMapOfShape anIndices;
2813 TopExp::MapShapes(aWhere, anIndices);
2814 if (anIndices.Contains(aSubShape))
2815 anIndex = anIndices.FindIndex(aSubShape);
2818 if(anIndex < 0) return NULL;
2820 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
2822 anArray->SetValue(1, anIndex);
2824 Handle(GEOM_Object) aResult = GetEngine()->AddSubShape(theShapeWhere, anArray);
2825 Handle(GEOM_Function) aFunction = aResult->GetLastFunction();
2827 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetSame("
2828 << theShapeWhere << ", " << theShapeWhat << ")";