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
20 #include <Standard_Stream.hxx>
22 #include "GEOMImpl_IShapesOperations.hxx"
24 #include "GEOMImpl_Types.hxx"
26 #include "GEOMImpl_VectorDriver.hxx"
27 #include "GEOMImpl_ShapeDriver.hxx"
28 #include "GEOMImpl_CopyDriver.hxx"
29 #include "GEOMImpl_GlueDriver.hxx"
31 #include "GEOMImpl_IVector.hxx"
32 #include "GEOMImpl_IShapes.hxx"
33 #include "GEOMImpl_IGlue.hxx"
35 #include "GEOMImpl_Block6Explorer.hxx"
37 #include "GEOM_Function.hxx"
38 #include "GEOM_PythonDump.hxx"
40 #include "GEOMAlgo_FinderShapeOn1.hxx"
41 #include "GEOMAlgo_FinderShapeOnQuad.hxx"
42 #include "GEOMAlgo_FinderShapeOn2.hxx"
43 #include "GEOMAlgo_ClsfBox.hxx"
44 //#include "GEOMAlgo_ClsfSurf.hxx"
46 #include "utilities.h"
48 #include "Utils_ExceptHandlers.hxx"
50 #include <TFunction_DriverTable.hxx>
51 #include <TFunction_Driver.hxx>
52 #include <TFunction_Logbook.hxx>
53 #include <TDataStd_Integer.hxx>
54 #include <TDataStd_IntegerArray.hxx>
55 #include <TDF_Tool.hxx>
57 #include <BRepExtrema_ExtCF.hxx>
59 #include <BRep_Tool.hxx>
60 #include <BRepTools.hxx>
61 #include <BRepGProp.hxx>
62 #include <BRepAdaptor_Curve.hxx>
63 #include <BRepAdaptor_Surface.hxx>
64 #include <BRepBndLib.hxx>
65 #include <BRepBuilderAPI_MakeFace.hxx>
66 #include <BRepMesh_IncrementalMesh.hxx>
71 #include <TopoDS_Shape.hxx>
72 #include <TopoDS_Solid.hxx>
73 #include <TopoDS_Face.hxx>
74 #include <TopoDS_Edge.hxx>
75 #include <TopoDS_Vertex.hxx>
76 #include <TopoDS_Iterator.hxx>
77 #include <TopExp_Explorer.hxx>
78 #include <TopLoc_Location.hxx>
79 #include <TopTools_MapOfShape.hxx>
80 #include <TopTools_MapOfOrientedShape.hxx>
81 #include <TopTools_Array1OfShape.hxx>
82 #include <TopTools_ListIteratorOfListOfShape.hxx>
83 #include <TopTools_IndexedMapOfShape.hxx>
85 #include <Geom_Surface.hxx>
86 #include <Geom_Plane.hxx>
87 #include <Geom_SphericalSurface.hxx>
88 #include <Geom_CylindricalSurface.hxx>
89 #include <GeomAdaptor_Surface.hxx>
91 #include <GeomLib_Tool.hxx>
92 #include <Geom2d_Curve.hxx>
94 #include <Bnd_Box.hxx>
95 #include <GProp_GProps.hxx>
98 #include <TColStd_ListOfInteger.hxx>
99 #include <TColStd_ListIteratorOfListOfInteger.hxx>
100 #include <TColStd_Array1OfReal.hxx>
101 #include <TColStd_HArray1OfInteger.hxx>
105 #include <Standard_Failure.hxx>
106 #include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
108 //=============================================================================
112 //=============================================================================
113 GEOMImpl_IShapesOperations::GEOMImpl_IShapesOperations (GEOM_Engine* theEngine, int theDocID)
114 : GEOM_IOperations(theEngine, theDocID)
116 MESSAGE("GEOMImpl_IShapesOperations::GEOMImpl_IShapesOperations");
119 //=============================================================================
123 //=============================================================================
124 GEOMImpl_IShapesOperations::~GEOMImpl_IShapesOperations()
126 MESSAGE("GEOMImpl_IShapesOperations::~GEOMImpl_IShapesOperations");
130 //=============================================================================
134 //=============================================================================
135 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeEdge
136 (Handle(GEOM_Object) thePnt1, Handle(GEOM_Object) thePnt2)
140 if (thePnt1.IsNull() || thePnt2.IsNull()) return NULL;
142 //Add a new Edge object
143 Handle(GEOM_Object) anEdge = GetEngine()->AddObject(GetDocID(), GEOM_EDGE);
145 //Add a new Vector function
146 Handle(GEOM_Function) aFunction =
147 anEdge->AddFunction(GEOMImpl_VectorDriver::GetID(), VECTOR_TWO_PNT);
149 //Check if the function is set correctly
150 if (aFunction->GetDriverGUID() != GEOMImpl_VectorDriver::GetID()) return NULL;
152 GEOMImpl_IVector aPI (aFunction);
154 Handle(GEOM_Function) aRef1 = thePnt1->GetLastFunction();
155 Handle(GEOM_Function) aRef2 = thePnt2->GetLastFunction();
156 if (aRef1.IsNull() || aRef2.IsNull()) return NULL;
158 aPI.SetPoint1(aRef1);
159 aPI.SetPoint2(aRef2);
161 //Compute the Edge value
163 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
166 if (!GetSolver()->ComputeFunction(aFunction)) {
167 SetErrorCode("Vector driver failed");
171 catch (Standard_Failure) {
172 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
173 SetErrorCode(aFail->GetMessageString());
177 //Make a Python command
178 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdge("
179 << thePnt1 << ", " << thePnt2 << ")";
185 //=============================================================================
189 //=============================================================================
190 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeWire
191 (list<Handle(GEOM_Object)> theShapes)
193 return MakeShape(theShapes, GEOM_WIRE, WIRE_EDGES, "MakeWire");
196 //=============================================================================
200 //=============================================================================
201 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFace (Handle(GEOM_Object) theWire,
202 const bool isPlanarWanted)
206 if (theWire.IsNull()) return NULL;
208 //Add a new Face object
209 Handle(GEOM_Object) aFace = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
211 //Add a new Shape function for creation of a face from a wire
212 Handle(GEOM_Function) aFunction =
213 aFace->AddFunction(GEOMImpl_ShapeDriver::GetID(), FACE_WIRE);
214 if (aFunction.IsNull()) return NULL;
216 //Check if the function is set correctly
217 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
219 GEOMImpl_IShapes aCI (aFunction);
221 Handle(GEOM_Function) aRefWire = theWire->GetLastFunction();
223 if (aRefWire.IsNull()) return NULL;
225 aCI.SetBase(aRefWire);
226 aCI.SetIsPlanar(isPlanarWanted);
228 //Compute the Face value
230 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
233 if (!GetSolver()->ComputeFunction(aFunction)) {
234 SetErrorCode("Shape driver failed to compute a face");
238 catch (Standard_Failure) {
239 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
240 SetErrorCode(aFail->GetMessageString());
244 //Make a Python command
245 GEOM::TPythonDump(aFunction) << aFace << " = geompy.MakeFace("
246 << theWire << ", " << (int)isPlanarWanted << ")";
252 //=============================================================================
256 //=============================================================================
257 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFaceWires
258 (list<Handle(GEOM_Object)> theShapes,
259 const bool isPlanarWanted)
264 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
267 Handle(GEOM_Function) aFunction =
268 aShape->AddFunction(GEOMImpl_ShapeDriver::GetID(), FACE_WIRES);
269 if (aFunction.IsNull()) return NULL;
271 //Check if the function is set correctly
272 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
274 GEOMImpl_IShapes aCI (aFunction);
276 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
279 list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
280 for (; it != theShapes.end(); it++) {
281 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
282 if (aRefSh.IsNull()) {
283 SetErrorCode("NULL argument shape for the face construction");
286 aShapesSeq->Append(aRefSh);
288 aCI.SetShapes(aShapesSeq);
290 aCI.SetIsPlanar(isPlanarWanted);
294 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
297 if (!GetSolver()->ComputeFunction(aFunction)) {
298 SetErrorCode("Shape driver failed");
302 catch (Standard_Failure) {
303 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
304 SetErrorCode(aFail->GetMessageString());
308 //Make a Python command
309 GEOM::TPythonDump pd (aFunction);
310 pd << aShape << " = geompy.MakeFaceWires([";
313 it = theShapes.begin();
314 if (it != theShapes.end()) {
316 while (it != theShapes.end()) {
317 pd << ", " << (*it++);
320 pd << "], " << (int)isPlanarWanted << ")";
326 //=============================================================================
330 //=============================================================================
331 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeShell
332 (list<Handle(GEOM_Object)> theShapes)
334 return MakeShape(theShapes, GEOM_SHELL, SHELL_FACES, "MakeShell");
337 //=============================================================================
341 //=============================================================================
342 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeSolidShells
343 (list<Handle(GEOM_Object)> theShapes)
345 return MakeShape(theShapes, GEOM_SOLID, SOLID_SHELLS, "MakeSolid");
348 //=============================================================================
352 //=============================================================================
353 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeSolidShell (Handle(GEOM_Object) theShell)
357 if (theShell.IsNull()) return NULL;
359 //Add a new Solid object
360 Handle(GEOM_Object) aSolid = GetEngine()->AddObject(GetDocID(), GEOM_SOLID);
362 //Add a new Solid function for creation of a solid from a shell
363 Handle(GEOM_Function) aFunction =
364 aSolid->AddFunction(GEOMImpl_ShapeDriver::GetID(), SOLID_SHELL);
365 if (aFunction.IsNull()) return NULL;
367 //Check if the function is set correctly
368 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
370 GEOMImpl_IShapes aCI (aFunction);
372 Handle(GEOM_Function) aRefShell = theShell->GetLastFunction();
374 if (aRefShell.IsNull()) return NULL;
376 aCI.SetBase(aRefShell);
378 //Compute the Solid value
380 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
383 if (!GetSolver()->ComputeFunction(aFunction)) {
384 SetErrorCode("Solid driver failed");
388 catch (Standard_Failure) {
389 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
390 SetErrorCode(aFail->GetMessageString());
394 //Make a Python command
395 GEOM::TPythonDump(aFunction) << aSolid
396 << " = geompy.MakeSolid(" << theShell << ")";
402 //=============================================================================
406 //=============================================================================
407 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeCompound
408 (list<Handle(GEOM_Object)> theShapes)
410 return MakeShape(theShapes, GEOM_COMPOUND, COMPOUND_SHAPES, "MakeCompound");
413 //=============================================================================
417 //=============================================================================
418 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeShape
419 (list<Handle(GEOM_Object)> theShapes,
420 const Standard_Integer theObjectType,
421 const Standard_Integer theFunctionType,
422 const TCollection_AsciiString& theMethodName)
427 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), theObjectType);
430 Handle(GEOM_Function) aFunction =
431 aShape->AddFunction(GEOMImpl_ShapeDriver::GetID(), theFunctionType);
432 if (aFunction.IsNull()) return NULL;
434 //Check if the function is set correctly
435 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
437 GEOMImpl_IShapes aCI (aFunction);
439 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
442 list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
443 for (; it != theShapes.end(); it++) {
444 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
445 if (aRefSh.IsNull()) {
446 SetErrorCode("NULL argument shape for the shape construction");
449 aShapesSeq->Append(aRefSh);
451 aCI.SetShapes(aShapesSeq);
455 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
458 if (!GetSolver()->ComputeFunction(aFunction)) {
459 SetErrorCode("Shape driver failed");
463 catch (Standard_Failure) {
464 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
465 SetErrorCode(aFail->GetMessageString());
469 //Make a Python command
470 GEOM::TPythonDump pd (aFunction);
471 pd << aShape << " = geompy." << theMethodName.ToCString() << "([";
474 it = theShapes.begin();
475 if (it != theShapes.end()) {
477 while (it != theShapes.end()) {
478 pd << ", " << (*it++);
487 //=============================================================================
491 //=============================================================================
492 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeGlueFaces
493 (Handle(GEOM_Object) theShape,
494 const Standard_Real theTolerance)
498 if (theShape.IsNull()) return NULL;
500 //Add a new Glued object
501 Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
503 //Add a new Glue function
504 Handle(GEOM_Function) aFunction;
505 aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_FACES);
506 if (aFunction.IsNull()) return NULL;
508 //Check if the function is set correctly
509 if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
511 GEOMImpl_IGlue aCI (aFunction);
513 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
514 if (aRefShape.IsNull()) return NULL;
516 aCI.SetBase(aRefShape);
517 aCI.SetTolerance(theTolerance);
519 //Compute the sub-shape value
520 Standard_Boolean isWarning = Standard_False;
522 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
525 if (!GetSolver()->ComputeFunction(aFunction)) {
526 SetErrorCode("Shape driver failed to glue faces");
530 catch (Standard_Failure) {
531 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
532 SetErrorCode(aFail->GetMessageString());
533 // to provide warning
534 if (!aFunction->GetValue().IsNull()) {
535 isWarning = Standard_True;
541 //Make a Python command
542 GEOM::TPythonDump(aFunction) << aGlued << " = geompy.MakeGlueFaces("
543 << theShape << ", " << theTolerance << ")";
545 // to provide warning
546 if (!isWarning) SetErrorCode(OK);
550 //=============================================================================
554 //=============================================================================
555 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::MakeExplode
556 (Handle(GEOM_Object) theShape,
557 const Standard_Integer theShapeType,
558 const Standard_Boolean isSorted)
562 if (theShape.IsNull()) return NULL;
563 TopoDS_Shape aShape = theShape->GetValue();
564 if (aShape.IsNull()) return NULL;
566 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
567 Handle(GEOM_Object) anObj;
568 Handle(GEOM_Function) aFunction;
569 TopTools_MapOfShape mapShape;
570 TopTools_ListOfShape listShape;
572 if (aShape.ShapeType() == TopAbs_COMPOUND &&
573 (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
574 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPSOLID ||
575 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPOUND)) {
576 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
577 for (; It.More(); It.Next()) {
578 if (mapShape.Add(It.Value())) {
579 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
580 TopAbs_ShapeEnum(theShapeType) == It.Value().ShapeType()) {
581 listShape.Append(It.Value());
586 TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
587 for (; exp.More(); exp.Next())
588 if (mapShape.Add(exp.Current()))
589 listShape.Append(exp.Current());
592 if (listShape.IsEmpty()) {
593 SetErrorCode("The given shape has no sub-shapes of the requested type");
598 SortShapes(listShape);
600 TopTools_IndexedMapOfShape anIndices;
601 TopExp::MapShapes(aShape, anIndices);
602 Handle(TColStd_HArray1OfInteger) anArray;
604 TopTools_ListIteratorOfListOfShape itSub (listShape);
605 TCollection_AsciiString anAsciiList, anEntry;
606 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
607 TopoDS_Shape aValue = itSub.Value();
608 anArray = new TColStd_HArray1OfInteger(1,1);
609 anArray->SetValue(1, anIndices.FindIndex(aValue));
610 anObj = GetEngine()->AddSubShape(theShape, anArray);
611 if (!anObj.IsNull()) {
614 // for python command
615 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
616 anAsciiList += anEntry;
621 //Make a Python command
622 anAsciiList.Trunc(anAsciiList.Length() - 1);
624 aFunction = theShape->GetLastFunction();
626 GEOM::TPythonDump pd (aFunction, /*append=*/true);
627 pd << "[" << anAsciiList.ToCString();
628 pd << "] = geompy.SubShapeAll" << (isSorted ? "Sorted(" : "(");
629 pd << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
636 //=============================================================================
640 //=============================================================================
641 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::SubShapeAllIDs
642 (Handle(GEOM_Object) theShape,
643 const Standard_Integer theShapeType,
644 const Standard_Boolean isSorted)
648 if (theShape.IsNull()) return NULL;
649 TopoDS_Shape aShape = theShape->GetValue();
650 if (aShape.IsNull()) return NULL;
652 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
653 TopTools_MapOfShape mapShape;
654 TopTools_ListOfShape listShape;
656 if (aShape.ShapeType() == TopAbs_COMPOUND &&
657 (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
658 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPSOLID ||
659 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPOUND)) {
660 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
661 for (; It.More(); It.Next()) {
662 if (mapShape.Add(It.Value())) {
663 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
664 TopAbs_ShapeEnum(theShapeType) == It.Value().ShapeType()) {
665 listShape.Append(It.Value());
670 TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
671 for (; exp.More(); exp.Next())
672 if (mapShape.Add(exp.Current()))
673 listShape.Append(exp.Current());
676 if (listShape.IsEmpty()) {
677 SetErrorCode("The given shape has no sub-shapes of the requested type");
682 SortShapes(listShape);
684 TopTools_IndexedMapOfShape anIndices;
685 TopExp::MapShapes(aShape, anIndices);
686 Handle(TColStd_HArray1OfInteger) anArray;
688 TopTools_ListIteratorOfListOfShape itSub (listShape);
689 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
690 TopoDS_Shape aValue = itSub.Value();
691 aSeq->Append(anIndices.FindIndex(aValue));
694 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
696 //Make a Python command
697 GEOM::TPythonDump pd (aFunction, /*append=*/true);
698 pd << "listSubShapeIDs = geompy.SubShapeAll";
699 pd << (isSorted ? "SortedIDs(" : "IDs(");
700 pd << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
706 //=============================================================================
710 //=============================================================================
711 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetSubShape
712 (Handle(GEOM_Object) theMainShape,
713 const Standard_Integer theID)
717 if (theMainShape.IsNull()) return NULL;
719 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
720 anArray->SetValue(1, theID);
721 Handle(GEOM_Object) anObj = GetEngine()->AddSubShape(theMainShape, anArray,true);
722 if (anObj.IsNull()) {
723 SetErrorCode("Can not get a sub-shape with the given ID");
727 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
729 //Make a Python command
730 GEOM::TPythonDump(aFunction) << anObj << " = geompy.GetSubShape("
731 << theMainShape << ", [" << theID << "])";
737 //=============================================================================
741 //=============================================================================
742 Standard_Integer GEOMImpl_IShapesOperations::GetSubShapeIndex (Handle(GEOM_Object) theMainShape,
743 Handle(GEOM_Object) theSubShape)
747 TopoDS_Shape aMainShape = theMainShape->GetValue();
748 TopoDS_Shape aSubShape = theSubShape->GetValue();
750 if (aMainShape.IsNull() || aSubShape.IsNull()) return -1;
752 TopTools_IndexedMapOfShape anIndices;
753 TopExp::MapShapes(aMainShape, anIndices);
754 if (anIndices.Contains(aSubShape)) {
756 return anIndices.FindIndex(aSubShape);
762 //=============================================================================
766 //=============================================================================
767 Standard_Integer GEOMImpl_IShapesOperations::GetTopologyIndex (Handle(GEOM_Object) theMainShape,
768 Handle(GEOM_Object) theSubShape)
772 TopoDS_Shape aMainShape = theMainShape->GetValue();
773 TopoDS_Shape aSubShape = theSubShape->GetValue();
775 if (aMainShape.IsNull() || aSubShape.IsNull()) {
776 SetErrorCode("Null argument shape given");
781 if (aSubShape.ShapeType() == TopAbs_COMPOUND) {
783 TopTools_ListOfShape CL;
784 CL.Append(aMainShape);
785 TopTools_ListIteratorOfListOfShape itC;
786 for (itC.Initialize(CL); itC.More(); itC.Next()) {
787 for (it.Initialize(itC.Value()); it.More(); it.Next()) {
788 if (it.Value().ShapeType() == TopAbs_COMPOUND) {
789 if (it.Value().IsSame(aSubShape))
793 CL.Append(it.Value());
798 TopExp_Explorer anExp (aMainShape, aSubShape.ShapeType());
799 TopTools_MapOfShape M;
800 for (; anExp.More(); anExp.Next()) {
801 if (M.Add(anExp.Current())) {
802 if (anExp.Current().IsSame(aSubShape))
809 SetErrorCode("The sub-shape does not belong to the main shape");
813 //=============================================================================
817 //=============================================================================
818 TCollection_AsciiString GEOMImpl_IShapesOperations::GetShapeTypeString (Handle(GEOM_Object) theShape)
822 TCollection_AsciiString aTypeName ("Null Shape");
824 TopoDS_Shape aShape = theShape->GetValue();
828 switch (aShape.ShapeType() )
830 case TopAbs_COMPOUND:
831 aTypeName = "Compound";
833 case TopAbs_COMPSOLID:
834 aTypeName = "Compound Solid";
844 BRepAdaptor_Surface surf (TopoDS::Face(aShape));
845 if (surf.GetType() == GeomAbs_Plane)
847 else if (surf.GetType() == GeomAbs_Cylinder)
848 aTypeName = "Cylindrical Face";
849 else if (surf.GetType() == GeomAbs_Sphere)
850 aTypeName = "Spherical Face";
851 else if (surf.GetType() == GeomAbs_Torus)
852 aTypeName = "Toroidal Face";
853 else if (surf.GetType() == GeomAbs_Cone)
854 aTypeName = "Conical Face";
856 aTypeName = "GEOM::FACE";
864 BRepAdaptor_Curve curv (TopoDS::Edge(aShape));
865 if (curv.GetType() == GeomAbs_Line) {
866 if ((Abs(curv.FirstParameter()) >= 1E6) ||
867 (Abs(curv.LastParameter()) >= 1E6))
871 } else if (curv.GetType() == GeomAbs_Circle) {
873 aTypeName = "Circle";
882 aTypeName = "Vertex";
888 aTypeName = "Shape of unknown type";
895 //=============================================================================
899 //=============================================================================
900 Standard_Integer GEOMImpl_IShapesOperations::NumberOfFaces (Handle(GEOM_Object) theShape)
904 Standard_Integer nb = 0;
906 if (theShape.IsNull()) return -1;
907 TopoDS_Shape aShape = theShape->GetValue();
908 if (aShape.IsNull()) return -1;
910 TopTools_MapOfShape mapShape;
912 TopExp_Explorer exp (aShape, TopAbs_FACE);
913 for (; exp.More(); exp.Next())
914 if (mapShape.Add(exp.Current()))
921 //=============================================================================
925 //=============================================================================
926 Standard_Integer GEOMImpl_IShapesOperations::NumberOfEdges (Handle(GEOM_Object) theShape)
930 Standard_Integer nb = 0;
932 if (theShape.IsNull()) return -1;
933 TopoDS_Shape aShape = theShape->GetValue();
934 if (aShape.IsNull()) return -1;
936 TopTools_MapOfShape mapShape;
938 TopExp_Explorer exp (aShape, TopAbs_EDGE);
939 for (; exp.More(); exp.Next())
940 if (mapShape.Add(exp.Current()))
947 //=============================================================================
951 //=============================================================================
952 Handle(GEOM_Object) GEOMImpl_IShapesOperations::ReverseShape(Handle(GEOM_Object) theShape)
956 if (theShape.IsNull()) return NULL;
958 //Add a new reversed object
959 Handle(GEOM_Object) aReversed = GetEngine()->AddObject(GetDocID(), theShape->GetType());
961 //Add a new Revese function
962 Handle(GEOM_Function) aFunction;
963 aFunction = aReversed->AddFunction(GEOMImpl_ShapeDriver::GetID(), REVERSE_ORIENTATION);
964 if (aFunction.IsNull()) return NULL;
966 //Check if the function is set correctly
967 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
969 GEOMImpl_IShapes aSI (aFunction);
971 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
972 if (aRefShape.IsNull()) return NULL;
974 aSI.SetBase(aRefShape);
976 //Compute the sub-shape value
978 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
981 if (!GetSolver()->ComputeFunction(aFunction)) {
982 SetErrorCode("Shape driver failed to reverse shape");
986 catch (Standard_Failure) {
987 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
988 SetErrorCode(aFail->GetMessageString());
992 //Make a Python command
993 GEOM::TPythonDump(aFunction) << aReversed
994 << " = geompy.ChangeOrientation(" << theShape << ")";
1000 //=============================================================================
1004 //=============================================================================
1005 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetFreeFacesIDs
1006 (Handle(GEOM_Object) theShape)
1010 if (theShape.IsNull()) return NULL;
1011 TopoDS_Shape aShape = theShape->GetValue();
1012 if (aShape.IsNull()) return NULL;
1014 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
1016 TopTools_IndexedDataMapOfShapeListOfShape mapFaceBlocks;
1017 GEOMImpl_Block6Explorer::MapShapesAndAncestors
1018 (aShape, TopAbs_FACE, TopAbs_SOLID, mapFaceBlocks);
1020 Standard_Integer ind = 1, nbFaces = mapFaceBlocks.Extent();
1023 SetErrorCode("The given shape has no faces");
1027 TopTools_IndexedMapOfShape anIndices;
1028 TopExp::MapShapes(aShape, anIndices);
1030 Standard_Integer id;
1031 for (; ind <= nbFaces; ind++) {
1032 if (mapFaceBlocks.FindFromIndex(ind).Extent() != 2) {
1033 id = anIndices.FindIndex(mapFaceBlocks.FindKey(ind));
1038 //The explode doesn't change object so no new function is required.
1039 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
1041 //Make a Python command
1042 GEOM::TPythonDump(aFunction, /*append=*/true)
1043 << "listFreeFacesIDs = geompy.GetFreeFacesIDs(" << theShape << ")";
1049 //=======================================================================
1050 //function : GetSharedShapes
1052 //=======================================================================
1054 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetSharedShapes
1055 (Handle(GEOM_Object) theShape1,
1056 Handle(GEOM_Object) theShape2,
1057 const Standard_Integer theShapeType)
1061 if (theShape1.IsNull() || theShape2.IsNull()) return NULL;
1063 TopoDS_Shape aShape1 = theShape1->GetValue();
1064 TopoDS_Shape aShape2 = theShape2->GetValue();
1066 if (aShape1.IsNull() || aShape2.IsNull()) return NULL;
1068 TopTools_IndexedMapOfShape anIndices;
1069 TopExp::MapShapes(aShape1, anIndices);
1070 Handle(TColStd_HArray1OfInteger) anArray;
1072 TopTools_IndexedMapOfShape mapShape1;
1073 TopExp::MapShapes(aShape1, TopAbs_ShapeEnum(theShapeType), mapShape1);
1075 Handle(GEOM_Object) anObj;
1076 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1077 TCollection_AsciiString anAsciiList, anEntry;
1079 TopTools_MapOfShape mapShape2;
1080 TopExp_Explorer exp (aShape2, TopAbs_ShapeEnum(theShapeType));
1081 for (; exp.More(); exp.Next()) {
1082 TopoDS_Shape aSS = exp.Current();
1083 if (mapShape2.Add(aSS) && mapShape1.Contains(aSS)) {
1084 anArray = new TColStd_HArray1OfInteger(1,1);
1085 anArray->SetValue(1, anIndices.FindIndex(aSS));
1086 anObj = GetEngine()->AddSubShape(theShape1, anArray);
1087 aSeq->Append(anObj);
1089 // for python command
1090 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
1091 anAsciiList += anEntry;
1096 if (aSeq->IsEmpty()) {
1097 SetErrorCode("The given shapes have no shared sub-shapes of the requested type");
1101 //Make a Python command
1102 anAsciiList.Trunc(anAsciiList.Length() - 1);
1104 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1106 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
1107 << "] = geompy.GetSharedShapes(" << theShape1 << ", "
1108 << theShape2 << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
1114 //=============================================================================
1118 //=============================================================================
1119 static GEOM::TPythonDump& operator<< (GEOM::TPythonDump& theDump,
1120 const GEOMAlgo_State theState)
1123 case GEOMAlgo_ST_IN:
1124 theDump << "geompy.GEOM.ST_IN";
1126 case GEOMAlgo_ST_OUT:
1127 theDump << "geompy.GEOM.ST_OUT";
1129 case GEOMAlgo_ST_ON:
1130 theDump << "geompy.GEOM.ST_ON";
1132 case GEOMAlgo_ST_ONIN:
1133 theDump << "geompy.GEOM.ST_ONIN";
1135 case GEOMAlgo_ST_ONOUT:
1136 theDump << "geompy.GEOM.ST_ONOUT";
1139 theDump << "geompy.GEOM.ST_UNKNOWN";
1145 //=======================================================================
1146 //function : checkTypeShapesOn
1148 * \brief Checks if theShapeType parameter of GetShapesOnXXX() is OK
1149 * \param theShapeType - the shape type to check
1150 * \retval bool - result of the check
1152 //=======================================================================
1154 bool GEOMImpl_IShapesOperations::checkTypeShapesOn(const Standard_Integer theShapeType)
1156 if (theShapeType != TopAbs_VERTEX &&
1157 theShapeType != TopAbs_EDGE &&
1158 theShapeType != TopAbs_FACE &&
1159 theShapeType != TopAbs_SOLID) {
1160 SetErrorCode("Only solids, vertices, edges or faces can be found by this method");
1166 //=======================================================================
1167 //function : makePlane
1169 * \brief Creates Geom_Plane
1170 * \param theAx1 - shape object defining plane parameters
1171 * \retval Handle(Geom_Surface) - resulting surface
1173 //=======================================================================
1175 Handle(Geom_Surface) GEOMImpl_IShapesOperations::makePlane(const TopoDS_Shape& anAx1)
1177 if (anAx1.ShapeType() != TopAbs_EDGE) return NULL;
1178 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
1179 TopoDS_Vertex V1, V2;
1180 TopExp::Vertices(anEdge, V1, V2, Standard_True);
1181 if (V1.IsNull() || V2.IsNull()) {
1182 SetErrorCode("Bad edge given for the plane normal vector");
1185 gp_Pnt aLoc = BRep_Tool::Pnt(V1);
1186 gp_Vec aVec (aLoc, BRep_Tool::Pnt(V2));
1187 if (aVec.Magnitude() < Precision::Confusion()) {
1188 SetErrorCode("Vector with null magnitude given");
1191 return new Geom_Plane(aLoc, aVec);
1194 //=======================================================================
1195 //function : makeCylinder
1197 * \brief Creates Geom_CylindricalSurface
1198 * \param theAx1 - edge defining cylinder axis
1199 * \param theRadius - cylinder radius
1200 * \retval Handle(Geom_Surface) - resulting surface
1202 //=======================================================================
1204 Handle(Geom_Surface) GEOMImpl_IShapesOperations::makeCylinder(const TopoDS_Shape& anAxis,
1205 const Standard_Real theRadius)
1207 //Axis of the cylinder
1208 if (anAxis.ShapeType() != TopAbs_EDGE) {
1209 SetErrorCode("Not an edge given for the axis");
1212 TopoDS_Edge anEdge = TopoDS::Edge(anAxis);
1213 TopoDS_Vertex V1, V2;
1214 TopExp::Vertices(anEdge, V1, V2, Standard_True);
1215 if (V1.IsNull() || V2.IsNull()) {
1216 SetErrorCode("Bad edge given for the axis");
1219 gp_Pnt aLoc = BRep_Tool::Pnt(V1);
1220 gp_Vec aVec (aLoc, BRep_Tool::Pnt(V2));
1221 if (aVec.Magnitude() < Precision::Confusion()) {
1222 SetErrorCode("Vector with null magnitude given");
1226 gp_Ax3 anAx3 (aLoc, aVec);
1227 return new Geom_CylindricalSurface(anAx3, theRadius);
1231 //=======================================================================
1232 //function : getShapesOnBoxIDs
1234 * \brief Find IDs of subshapes complying with given status about surface
1235 * \param theBox - the box to check state of subshapes against
1236 * \param theShape - the shape to explore
1237 * \param theShapeType - type of subshape of theShape
1238 * \param theState - required state
1239 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1241 //=======================================================================
1243 Handle(TColStd_HSequenceOfInteger)
1244 GEOMImpl_IShapesOperations::getShapesOnBoxIDs(const Handle(GEOM_Object)& theBox,
1245 const Handle(GEOM_Object)& theShape,
1246 const Standard_Integer theShapeType,
1247 GEOMAlgo_State theState)
1249 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
1251 TopoDS_Shape aBox = theBox->GetValue();
1252 TopoDS_Shape aShape = theShape->GetValue();
1255 GEOMAlgo_FinderShapeOn2 aFinder;
1256 Standard_Real aTol = 0.0001; // default value
1258 Handle(GEOMAlgo_ClsfBox) aClsfBox = new GEOMAlgo_ClsfBox;
1259 aClsfBox->SetBox(aBox);
1261 aFinder.SetShape(aShape);
1262 aFinder.SetTolerance(aTol);
1263 aFinder.SetClsf(aClsfBox);
1264 aFinder.SetShapeType( (TopAbs_ShapeEnum)theShapeType );
1265 aFinder.SetState(theState);
1268 // Interprete results
1269 Standard_Integer iErr = aFinder.ErrorStatus();
1270 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
1272 MESSAGE(" iErr : " << iErr);
1273 TCollection_AsciiString aMsg (" iErr : ");
1274 aMsg += TCollection_AsciiString(iErr);
1278 Standard_Integer iWrn = aFinder.WarningStatus();
1279 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
1281 MESSAGE(" *** iWrn : " << iWrn);
1284 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
1286 if (listSS.Extent() < 1) {
1287 SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
1291 // Fill sequence of object IDs
1292 aSeqOfIDs = new TColStd_HSequenceOfInteger;
1294 TopTools_IndexedMapOfShape anIndices;
1295 TopExp::MapShapes(aShape, anIndices);
1297 TopTools_ListIteratorOfListOfShape itSub (listSS);
1298 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
1299 int id = anIndices.FindIndex(itSub.Value());
1300 aSeqOfIDs->Append(id);
1307 //=======================================================================
1308 //function : GetShapesOnBoxIDs
1310 * \brief Find subshapes complying with given status about surface
1311 * \param theBox - the box to check state of subshapes against
1312 * \param theShape - the shape to explore
1313 * \param theShapeType - type of subshape of theShape
1314 * \param theState - required state
1315 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1317 //=======================================================================
1319 Handle(TColStd_HSequenceOfInteger)
1320 GEOMImpl_IShapesOperations::GetShapesOnBoxIDs(const Handle(GEOM_Object)& theBox,
1321 const Handle(GEOM_Object)& theShape,
1322 const Standard_Integer theShapeType,
1323 GEOMAlgo_State theState)
1325 // Find subshapes ids
1326 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
1327 getShapesOnBoxIDs (theBox, theShape, theShapeType, theState);
1328 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
1331 // The GetShapesOnBox() doesn't change object so no new function is required.
1332 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theBox)->GetLastFunction();
1334 // Make a Python command
1335 GEOM::TPythonDump(aFunction)
1336 << "listShapesOnBoxIDs = geompy.GetShapesOnQuadrangleIDs("
1339 << TopAbs_ShapeEnum(theShapeType) << ", "
1346 //=======================================================================
1347 //function : GetShapesOnBox
1349 * \brief Find subshapes complying with given status about surface
1350 * \param theBox - the box to check state of subshapes against
1351 * \param theShape - the shape to explore
1352 * \param theShapeType - type of subshape of theShape
1353 * \param theState - required state
1354 * \retval Handle(TColStd_HSequenceOfTransient) - found subshapes
1356 //=======================================================================
1358 Handle(TColStd_HSequenceOfTransient)
1359 GEOMImpl_IShapesOperations::GetShapesOnBox(const Handle(GEOM_Object)& theBox,
1360 const Handle(GEOM_Object)& theShape,
1361 const Standard_Integer theShapeType,
1362 GEOMAlgo_State theState)
1364 // Find subshapes ids
1365 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
1366 getShapesOnBoxIDs (theBox, theShape, theShapeType, theState);
1367 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
1370 // Find objects by indices
1371 TCollection_AsciiString anAsciiList;
1372 Handle(TColStd_HSequenceOfTransient) aSeq;
1373 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
1374 if ( aSeq.IsNull() || aSeq->IsEmpty() )
1377 // Make a Python command
1379 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
1380 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1382 GEOM::TPythonDump(aFunction)
1383 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnBox("
1386 << TopAbs_ShapeEnum(theShapeType) << ", "
1394 //=======================================================================
1395 //function : getShapesOnSurfaceIDs
1397 * \brief Find IDs of subshapes complying with given status about surface
1398 * \param theSurface - the surface to check state of subshapes against
1399 * \param theShape - the shape to explore
1400 * \param theShapeType - type of subshape of theShape
1401 * \param theState - required state
1402 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1404 //=======================================================================
1406 Handle(TColStd_HSequenceOfInteger)
1407 GEOMImpl_IShapesOperations::getShapesOnSurfaceIDs(const Handle(Geom_Surface)& theSurface,
1408 const TopoDS_Shape& theShape,
1409 TopAbs_ShapeEnum theShapeType,
1410 GEOMAlgo_State theState)
1412 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
1414 // Check presence of triangulation, build if need
1415 if (!CheckTriangulation(theShape))
1419 GEOMAlgo_FinderShapeOn1 aFinder;
1420 Standard_Real aTol = 0.0001; // default value
1422 aFinder.SetShape(theShape);
1423 aFinder.SetTolerance(aTol);
1424 aFinder.SetSurface(theSurface);
1425 aFinder.SetShapeType(theShapeType);
1426 aFinder.SetState(theState);
1428 // Sets the minimal number of inner points for the faces that do not have own
1429 // inner points at all (for e.g. rectangular planar faces have just 2 triangles).
1431 aFinder.SetNbPntsMin(3);
1432 // Sets the maximal number of inner points for edges or faces.
1433 // It is usefull for the cases when this number is very big (e.g =2000) to improve
1434 // the performance. If this value =0, all inner points will be taken into account.
1436 aFinder.SetNbPntsMax(100);
1440 // Interprete results
1441 Standard_Integer iErr = aFinder.ErrorStatus();
1442 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
1444 MESSAGE(" iErr : " << iErr);
1445 TCollection_AsciiString aMsg (" iErr : ");
1446 aMsg += TCollection_AsciiString(iErr);
1450 Standard_Integer iWrn = aFinder.WarningStatus();
1451 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
1453 MESSAGE(" *** iWrn : " << iWrn);
1456 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
1458 if (listSS.Extent() < 1) {
1459 SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
1463 // Fill sequence of object IDs
1464 aSeqOfIDs = new TColStd_HSequenceOfInteger;
1466 TopTools_IndexedMapOfShape anIndices;
1467 TopExp::MapShapes(theShape, anIndices);
1469 TopTools_ListIteratorOfListOfShape itSub (listSS);
1470 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
1471 int id = anIndices.FindIndex(itSub.Value());
1472 aSeqOfIDs->Append(id);
1478 //=======================================================================
1479 //function : getObjectsShapesOn
1481 * \brief Find shape objects and their entries by their ids
1482 * \param theShapeIDs - incoming shape ids
1483 * \param theShapeEntries - outgoing entries like "entry1, entry2, ..."
1484 * \retval Handle(TColStd_HSequenceOfTransient) - found shape objects
1486 //=======================================================================
1488 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::
1489 getObjectsShapesOn(const Handle(GEOM_Object)& theShape,
1490 const Handle(TColStd_HSequenceOfInteger)& theShapeIDs,
1491 TCollection_AsciiString & theShapeEntries)
1493 Handle(TColStd_HSequenceOfTransient) aSeq;
1495 if ( !theShapeIDs.IsNull() && theShapeIDs->Length() > 0 )
1497 aSeq = new TColStd_HSequenceOfTransient;
1498 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
1499 TCollection_AsciiString anEntry;
1500 for ( int i = 1; i <= theShapeIDs->Length(); ++i )
1502 anArray->SetValue(1, theShapeIDs->Value( i ));
1503 Handle(GEOM_Object) anObj = GetEngine()->AddSubShape(theShape, anArray);
1504 aSeq->Append( anObj );
1506 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
1507 if ( i != 1 ) theShapeEntries += ",";
1508 theShapeEntries += anEntry;
1514 //=======================================================================
1515 //function : getShapesOnSurface
1517 * \brief Find subshapes complying with given status about surface
1518 * \param theSurface - the surface to check state of subshapes against
1519 * \param theShape - the shape to explore
1520 * \param theShapeType - type of subshape of theShape
1521 * \param theState - required state
1522 * \param theShapeEntries - outgoing entries like "entry1, entry2, ..."
1523 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1525 //=======================================================================
1527 Handle(TColStd_HSequenceOfTransient)
1528 GEOMImpl_IShapesOperations::getShapesOnSurface(const Handle(Geom_Surface)& theSurface,
1529 const Handle(GEOM_Object)& theShape,
1530 TopAbs_ShapeEnum theShapeType,
1531 GEOMAlgo_State theState,
1532 TCollection_AsciiString & theShapeEntries)
1534 // Find subshapes ids
1535 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
1536 getShapesOnSurfaceIDs (theSurface, theShape->GetValue(), theShapeType, theState);
1537 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
1540 return getObjectsShapesOn( theShape, aSeqOfIDs, theShapeEntries );
1543 //=============================================================================
1547 //=============================================================================
1548 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnPlane
1549 (const Handle(GEOM_Object)& theShape,
1550 const Standard_Integer theShapeType,
1551 const Handle(GEOM_Object)& theAx1,
1552 const GEOMAlgo_State theState)
1556 if (theShape.IsNull() || theAx1.IsNull()) return NULL;
1558 TopoDS_Shape aShape = theShape->GetValue();
1559 TopoDS_Shape anAx1 = theAx1->GetValue();
1561 if (aShape.IsNull() || anAx1.IsNull()) return NULL;
1563 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
1564 if ( !checkTypeShapesOn( theShapeType ))
1568 Handle(Geom_Surface) aPlane = makePlane( anAx1 );
1569 if ( aPlane.IsNull() )
1573 TCollection_AsciiString anAsciiList;
1574 Handle(TColStd_HSequenceOfTransient) aSeq;
1575 aSeq = getShapesOnSurface( aPlane, theShape, aShapeType, theState, anAsciiList );
1576 if ( aSeq.IsNull() || aSeq->Length() == 0 )
1579 // Make a Python command
1581 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
1582 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1584 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
1585 << "] = geompy.GetShapesOnPlane(" << theShape << ", "
1586 << aShapeType << ", " << theAx1 << ", " << theState << ")";
1592 //=============================================================================
1594 * GetShapesOnPlaneWithLocation
1596 //=============================================================================
1597 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnPlaneWithLocation
1598 (const Handle(GEOM_Object)& theShape,
1599 const Standard_Integer theShapeType,
1600 const Handle(GEOM_Object)& theAx1,
1601 const Handle(GEOM_Object)& thePnt,
1602 const GEOMAlgo_State theState)
1606 if (theShape.IsNull() || theAx1.IsNull() || thePnt.IsNull()) return NULL;
1608 TopoDS_Shape aShape = theShape->GetValue();
1609 TopoDS_Shape anAx1 = theAx1->GetValue();
1610 TopoDS_Shape anPnt = thePnt->GetValue();
1612 if (aShape.IsNull() || anAx1.IsNull() || anPnt.IsNull()) return NULL;
1614 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
1615 if ( !checkTypeShapesOn( theShapeType ))
1619 if ( anAx1.ShapeType() != TopAbs_EDGE || anPnt.ShapeType() != TopAbs_VERTEX ) return NULL;
1620 TopoDS_Vertex V1, V2, V3;
1621 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
1622 TopExp::Vertices(anEdge, V1, V2, Standard_True);
1624 if (V1.IsNull() || V2.IsNull()) {
1625 SetErrorCode("Bad edge given for the plane normal vector");
1628 V3 = TopoDS::Vertex(anPnt);
1631 SetErrorCode("Bad vertex given for the plane location");
1634 gp_Pnt aLoc = BRep_Tool::Pnt(V3);
1635 gp_Vec aVec(BRep_Tool::Pnt(V1),BRep_Tool::Pnt(V2));
1637 if (aVec.Magnitude() < Precision::Confusion()) {
1638 SetErrorCode("Vector with null magnitude given");
1641 Handle(Geom_Surface) aPlane = new Geom_Plane(aLoc, aVec);
1643 if ( aPlane.IsNull() )
1647 TCollection_AsciiString anAsciiList;
1648 Handle(TColStd_HSequenceOfTransient) aSeq;
1649 aSeq = getShapesOnSurface( aPlane, theShape, aShapeType, theState, anAsciiList );
1650 if ( aSeq.IsNull() || aSeq->Length() == 0 )
1653 // Make a Python command
1655 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
1656 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1658 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
1659 << "] = geompy.GetShapesOnPlaneWithLocation(" << theShape << ", "
1660 << aShapeType << ", " << theAx1 << ", "<< thePnt <<", " << theState << ")";
1666 //=============================================================================
1668 * GetShapesOnCylinder
1670 //=============================================================================
1671 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnCylinder
1672 (const Handle(GEOM_Object)& theShape,
1673 const Standard_Integer theShapeType,
1674 const Handle(GEOM_Object)& theAxis,
1675 const Standard_Real theRadius,
1676 const GEOMAlgo_State theState)
1680 if (theShape.IsNull() || theAxis.IsNull()) return NULL;
1682 TopoDS_Shape aShape = theShape->GetValue();
1683 TopoDS_Shape anAxis = theAxis->GetValue();
1685 if (aShape.IsNull() || anAxis.IsNull()) return NULL;
1687 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
1688 if ( !checkTypeShapesOn( aShapeType ))
1691 // Create a cylinder surface
1692 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
1693 if ( aCylinder.IsNull() )
1697 TCollection_AsciiString anAsciiList;
1698 Handle(TColStd_HSequenceOfTransient) aSeq;
1699 aSeq = getShapesOnSurface( aCylinder, theShape, aShapeType, theState, anAsciiList );
1700 if ( aSeq.IsNull() || aSeq->Length() == 0 )
1703 // Make a Python command
1705 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
1706 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1708 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
1709 << "] = geompy.GetShapesOnCylinder(" << theShape << ", " << aShapeType
1710 << ", " << theAxis << ", " << theRadius << ", " << theState << ")";
1716 //=============================================================================
1720 //=============================================================================
1721 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnSphere
1722 (const Handle(GEOM_Object)& theShape,
1723 const Standard_Integer theShapeType,
1724 const Handle(GEOM_Object)& theCenter,
1725 const Standard_Real theRadius,
1726 const GEOMAlgo_State theState)
1730 if (theShape.IsNull() || theCenter.IsNull()) return NULL;
1732 TopoDS_Shape aShape = theShape->GetValue();
1733 TopoDS_Shape aCenter = theCenter->GetValue();
1735 if (aShape.IsNull() || aCenter.IsNull()) return NULL;
1737 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
1738 if ( !checkTypeShapesOn( aShapeType ))
1741 // Center of the sphere
1742 if (aCenter.ShapeType() != TopAbs_VERTEX) return NULL;
1743 gp_Pnt aLoc = BRep_Tool::Pnt(TopoDS::Vertex(aCenter));
1745 gp_Ax3 anAx3 (aLoc, gp::DZ());
1746 Handle(Geom_SphericalSurface) aSphere =
1747 new Geom_SphericalSurface(anAx3, theRadius);
1750 TCollection_AsciiString anAsciiList;
1751 Handle(TColStd_HSequenceOfTransient) aSeq;
1752 aSeq = getShapesOnSurface( aSphere, theShape, aShapeType, theState, anAsciiList );
1753 if ( aSeq.IsNull() || aSeq->Length() == 0 )
1756 // Make a Python command
1758 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
1759 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1761 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
1762 << "] = geompy.GetShapesOnSphere(" << theShape << ", " << aShapeType
1763 << ", " << theCenter << ", " << theRadius << ", " << theState << ")";
1769 //=============================================================================
1771 * GetShapesOnPlaneIDs
1773 //=============================================================================
1774 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnPlaneIDs
1775 (const Handle(GEOM_Object)& theShape,
1776 const Standard_Integer theShapeType,
1777 const Handle(GEOM_Object)& theAx1,
1778 const GEOMAlgo_State theState)
1782 if (theShape.IsNull() || theAx1.IsNull()) return NULL;
1784 TopoDS_Shape aShape = theShape->GetValue();
1785 TopoDS_Shape anAx1 = theAx1->GetValue();
1787 if (aShape.IsNull() || anAx1.IsNull()) return NULL;
1789 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
1790 if ( !checkTypeShapesOn( aShapeType ))
1794 Handle(Geom_Surface) aPlane = makePlane( anAx1 );
1795 if ( aPlane.IsNull() )
1799 Handle(TColStd_HSequenceOfInteger) aSeq;
1800 aSeq = getShapesOnSurfaceIDs( aPlane, aShape, aShapeType, theState );
1802 // The GetShapesOnPlaneIDs() doesn't change object so no new function is required.
1803 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAx1)->GetLastFunction();
1805 // Make a Python command
1806 GEOM::TPythonDump(aFunction, /*append=*/true)
1807 << "listShapesOnPlane = geompy.GetShapesOnPlaneIDs"
1808 << "(" << theShape << "," << aShapeType << "," << theAx1 << "," << theState << ")";
1814 //=============================================================================
1816 * GetShapesOnPlaneWithLocationIDs
1818 //=============================================================================
1819 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnPlaneWithLocationIDs
1820 (const Handle(GEOM_Object)& theShape,
1821 const Standard_Integer theShapeType,
1822 const Handle(GEOM_Object)& theAx1,
1823 const Handle(GEOM_Object)& thePnt,
1824 const GEOMAlgo_State theState)
1828 if (theShape.IsNull() || theAx1.IsNull() || thePnt.IsNull()) return NULL;
1830 TopoDS_Shape aShape = theShape->GetValue();
1831 TopoDS_Shape anAx1 = theAx1->GetValue();
1832 TopoDS_Shape anPnt = thePnt->GetValue();
1834 if (aShape.IsNull() || anAx1.IsNull() || anPnt.IsNull()) return NULL;
1836 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
1837 if ( !checkTypeShapesOn( aShapeType ))
1841 if (anAx1.ShapeType() != TopAbs_EDGE || anPnt.ShapeType() != TopAbs_VERTEX) return NULL;
1842 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
1843 TopoDS_Vertex V1, V2, V3;
1844 TopExp::Vertices(anEdge, V1, V2, Standard_True);
1845 if (V1.IsNull() || V2.IsNull()) {
1846 SetErrorCode("Bad edge given for the plane normal vector");
1849 V3 = TopoDS::Vertex(anPnt);
1851 SetErrorCode("Bad vertex given for the plane location");
1854 gp_Pnt aLoc = BRep_Tool::Pnt(V3);
1855 gp_Vec aVec(BRep_Tool::Pnt(V1),BRep_Tool::Pnt(V2));
1856 if (aVec.Magnitude() < Precision::Confusion()) {
1857 SetErrorCode("Vector with null magnitude given");
1861 Handle(Geom_Surface) aPlane = new Geom_Plane(aLoc, aVec);
1862 if ( aPlane.IsNull() )
1866 Handle(TColStd_HSequenceOfInteger) aSeq;
1867 aSeq = getShapesOnSurfaceIDs( aPlane, aShape, aShapeType, theState );
1869 // The GetShapesOnPlaneIDs() doesn't change object so no new function is required.
1870 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAx1)->GetLastFunction();
1872 // Make a Python command
1873 GEOM::TPythonDump(aFunction, /*append=*/true)
1874 << "listShapesOnPlane = geompy.GetShapesOnPlaneWithLocationIDs"
1875 << "(" << theShape << ", " << aShapeType << ", " << theAx1 << ", "<< thePnt << ", " << theState << ")";
1881 //=============================================================================
1883 * GetShapesOnCylinderIDs
1885 //=============================================================================
1886 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnCylinderIDs
1887 (const Handle(GEOM_Object)& theShape,
1888 const Standard_Integer theShapeType,
1889 const Handle(GEOM_Object)& theAxis,
1890 const Standard_Real theRadius,
1891 const GEOMAlgo_State theState)
1895 if (theShape.IsNull() || theAxis.IsNull()) return NULL;
1897 TopoDS_Shape aShape = theShape->GetValue();
1898 TopoDS_Shape anAxis = theAxis->GetValue();
1900 if (aShape.IsNull() || anAxis.IsNull()) return NULL;
1902 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
1903 if ( !checkTypeShapesOn( aShapeType ))
1906 // Create a cylinder surface
1907 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
1908 if ( aCylinder.IsNull() )
1912 Handle(TColStd_HSequenceOfInteger) aSeq;
1913 aSeq = getShapesOnSurfaceIDs( aCylinder, aShape, aShapeType, theState );
1915 // The GetShapesOnCylinder() doesn't change object so no new function is required.
1916 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAxis)->GetLastFunction();
1918 // Make a Python command
1919 GEOM::TPythonDump(aFunction, /*append=*/true)
1920 << "listShapesOnCylinder = geompy.GetShapesOnCylinderIDs"
1921 << "(" << theShape << ", " << aShapeType << ", " << theAxis << ", "
1922 << theRadius << ", " << theState << ")";
1928 //=============================================================================
1930 * GetShapesOnSphereIDs
1932 //=============================================================================
1933 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnSphereIDs
1934 (const Handle(GEOM_Object)& theShape,
1935 const Standard_Integer theShapeType,
1936 const Handle(GEOM_Object)& theCenter,
1937 const Standard_Real theRadius,
1938 const GEOMAlgo_State theState)
1942 if (theShape.IsNull() || theCenter.IsNull()) return NULL;
1944 TopoDS_Shape aShape = theShape->GetValue();
1945 TopoDS_Shape aCenter = theCenter->GetValue();
1947 if (aShape.IsNull() || aCenter.IsNull()) return NULL;
1949 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
1950 if ( !checkTypeShapesOn( aShapeType ))
1953 // Center of the sphere
1954 if (aCenter.ShapeType() != TopAbs_VERTEX) return NULL;
1955 gp_Pnt aLoc = BRep_Tool::Pnt(TopoDS::Vertex(aCenter));
1957 gp_Ax3 anAx3 (aLoc, gp::DZ());
1958 Handle(Geom_SphericalSurface) aSphere =
1959 new Geom_SphericalSurface(anAx3, theRadius);
1962 Handle(TColStd_HSequenceOfInteger) aSeq;
1963 aSeq = getShapesOnSurfaceIDs( aSphere, aShape, aShapeType, theState );
1965 // The GetShapesOnSphere() doesn't change object so no new function is required.
1966 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theCenter)->GetLastFunction();
1968 // Make a Python command
1969 GEOM::TPythonDump(aFunction, /*append=*/true)
1970 << "listShapesOnCylinder = geompy.GetShapesOnCylinderIDs"
1971 << "(" << theShape << ", " << aShapeType << ", " << theCenter << ", "
1972 << theRadius << ", " << theState << ")";
1978 //=======================================================================
1979 //function : getShapesOnQuadrangleIDs
1981 * \brief Find IDs of subshapes complying with given status about quadrangle
1982 * \param theShape - the shape to explore
1983 * \param theShapeType - type of subshape of theShape
1984 * \param theTopLeftPoint - top left quadrangle corner
1985 * \param theTopRigthPoint - top right quadrangle corner
1986 * \param theBottomLeftPoint - bottom left quadrangle corner
1987 * \param theBottomRigthPoint - bottom right quadrangle corner
1988 * \param theState - required state
1989 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1991 //=======================================================================
1993 Handle(TColStd_HSequenceOfInteger)
1994 GEOMImpl_IShapesOperations::getShapesOnQuadrangleIDs (const Handle(GEOM_Object)& theShape,
1995 const Standard_Integer theShapeType,
1996 const Handle(GEOM_Object)& theTopLeftPoint,
1997 const Handle(GEOM_Object)& theTopRigthPoint,
1998 const Handle(GEOM_Object)& theBottomLeftPoint,
1999 const Handle(GEOM_Object)& theBottomRigthPoint,
2000 const GEOMAlgo_State theState)
2004 if ( theShape.IsNull() ||
2005 theTopLeftPoint.IsNull() ||
2006 theTopRigthPoint.IsNull() ||
2007 theBottomLeftPoint.IsNull() ||
2008 theBottomRigthPoint.IsNull() )
2011 TopoDS_Shape aShape = theShape->GetValue();
2012 TopoDS_Shape aTL = theTopLeftPoint->GetValue();
2013 TopoDS_Shape aTR = theTopRigthPoint->GetValue();
2014 TopoDS_Shape aBL = theBottomLeftPoint->GetValue();
2015 TopoDS_Shape aBR = theBottomRigthPoint->GetValue();
2017 if (aShape.IsNull() ||
2022 aTL.ShapeType() != TopAbs_VERTEX ||
2023 aTR.ShapeType() != TopAbs_VERTEX ||
2024 aBL.ShapeType() != TopAbs_VERTEX ||
2025 aBR.ShapeType() != TopAbs_VERTEX )
2028 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2029 if ( !checkTypeShapesOn( aShapeType ))
2032 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
2034 // Check presence of triangulation, build if need
2035 if (!CheckTriangulation(aShape))
2039 gp_Pnt aPntTL = BRep_Tool::Pnt(TopoDS::Vertex(aTL));
2040 gp_Pnt aPntTR = BRep_Tool::Pnt(TopoDS::Vertex(aTR));
2041 gp_Pnt aPntBL = BRep_Tool::Pnt(TopoDS::Vertex(aBL));
2042 gp_Pnt aPntBR = BRep_Tool::Pnt(TopoDS::Vertex(aBR));
2044 GEOMAlgo_FinderShapeOnQuad aFinder( aPntTL, aPntTR, aPntBL, aPntBR );
2045 Standard_Real aTol = 0.0001; // default value
2047 aFinder.SetShape(aShape);
2048 aFinder.SetTolerance(aTol);
2049 //aFinder.SetSurface(theSurface);
2050 aFinder.SetShapeType(aShapeType);
2051 aFinder.SetState(theState);
2053 // Sets the minimal number of inner points for the faces that do not have own
2054 // inner points at all (for e.g. rectangular planar faces have just 2 triangles).
2056 aFinder.SetNbPntsMin(3);
2057 // Sets the maximal number of inner points for edges or faces.
2058 // It is usefull for the cases when this number is very big (e.g =2000) to improve
2059 // the performance. If this value =0, all inner points will be taken into account.
2061 aFinder.SetNbPntsMax(100);
2065 // Interprete results
2066 Standard_Integer iErr = aFinder.ErrorStatus();
2067 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
2069 MESSAGE(" iErr : " << iErr);
2070 TCollection_AsciiString aMsg (" iErr : ");
2071 aMsg += TCollection_AsciiString(iErr);
2075 Standard_Integer iWrn = aFinder.WarningStatus();
2076 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
2078 MESSAGE(" *** iWrn : " << iWrn);
2081 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
2083 if (listSS.Extent() < 1) {
2084 SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
2088 // Fill sequence of object IDs
2089 aSeqOfIDs = new TColStd_HSequenceOfInteger;
2091 TopTools_IndexedMapOfShape anIndices;
2092 TopExp::MapShapes(aShape, anIndices);
2094 TopTools_ListIteratorOfListOfShape itSub (listSS);
2095 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
2096 int id = anIndices.FindIndex(itSub.Value());
2097 aSeqOfIDs->Append(id);
2102 //=======================================================================
2103 //function : GetShapesOnQuadrangle
2105 * \brief Find subshapes complying with given status about quadrangle
2106 * \param theShape - the shape to explore
2107 * \param theShapeType - type of subshape of theShape
2108 * \param theTopLeftPoint - top left quadrangle corner
2109 * \param theTopRigthPoint - top right quadrangle corner
2110 * \param theBottomLeftPoint - bottom left quadrangle corner
2111 * \param theBottomRigthPoint - bottom right quadrangle corner
2112 * \param theState - required state
2113 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
2115 //=======================================================================
2117 Handle(TColStd_HSequenceOfTransient)
2118 GEOMImpl_IShapesOperations::GetShapesOnQuadrangle (const Handle(GEOM_Object)& theShape,
2119 const Standard_Integer theShapeType,
2120 const Handle(GEOM_Object)& theTopLeftPoint,
2121 const Handle(GEOM_Object)& theTopRigthPoint,
2122 const Handle(GEOM_Object)& theBottomLeftPoint,
2123 const Handle(GEOM_Object)& theBottomRigthPoint,
2124 const GEOMAlgo_State theState)
2127 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2128 getShapesOnQuadrangleIDs( theShape,
2133 theBottomRigthPoint,
2135 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->IsEmpty() )
2138 // Find objects by indices
2139 TCollection_AsciiString anAsciiList;
2140 Handle(TColStd_HSequenceOfTransient) aSeq;
2141 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
2142 if ( aSeq.IsNull() || aSeq->IsEmpty() )
2145 // Make a Python command
2147 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2148 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2150 GEOM::TPythonDump(aFunction)
2151 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnQuadrangle("
2153 << TopAbs_ShapeEnum(theShapeType) << ", "
2154 << theTopLeftPoint << ", "
2155 << theTopRigthPoint << ", "
2156 << theBottomLeftPoint << ", "
2157 << theBottomRigthPoint << ", "
2164 //=======================================================================
2165 //function : GetShapesOnQuadrangleIDs
2167 * \brief Find IDs of subshapes complying with given status about quadrangle
2168 * \param theShape - the shape to explore
2169 * \param theShapeType - type of subshape of theShape
2170 * \param theTopLeftPoint - top left quadrangle corner
2171 * \param theTopRigthPoint - top right quadrangle corner
2172 * \param theBottomLeftPoint - bottom left quadrangle corner
2173 * \param theBottomRigthPoint - bottom right quadrangle corner
2174 * \param theState - required state
2175 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
2177 //=======================================================================
2179 Handle(TColStd_HSequenceOfInteger)
2180 GEOMImpl_IShapesOperations::GetShapesOnQuadrangleIDs (const Handle(GEOM_Object)& theShape,
2181 const Standard_Integer theShapeType,
2182 const Handle(GEOM_Object)& theTopLeftPoint,
2183 const Handle(GEOM_Object)& theTopRigthPoint,
2184 const Handle(GEOM_Object)& theBottomLeftPoint,
2185 const Handle(GEOM_Object)& theBottomRigthPoint,
2186 const GEOMAlgo_State theState)
2189 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2190 getShapesOnQuadrangleIDs( theShape,
2195 theBottomRigthPoint,
2197 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->IsEmpty() )
2200 // Make a Python command
2202 // The GetShapesOnCylinder() doesn't change object so no new function is required.
2203 Handle(GEOM_Object) lastObj = GEOM::GetCreatedLast(theShape,theTopLeftPoint);
2204 lastObj = GEOM::GetCreatedLast(lastObj,theTopRigthPoint);
2205 lastObj = GEOM::GetCreatedLast(lastObj,theBottomRigthPoint);
2206 lastObj = GEOM::GetCreatedLast(lastObj,theBottomLeftPoint);
2207 Handle(GEOM_Function) aFunction = lastObj->GetLastFunction();
2209 GEOM::TPythonDump(aFunction, /*append=*/true)
2210 << "listShapesOnQuadrangle = geompy.GetShapesOnQuadrangleIDs("
2212 << TopAbs_ShapeEnum(theShapeType) << ", "
2213 << theTopLeftPoint << ", "
2214 << theTopRigthPoint << ", "
2215 << theBottomLeftPoint << ", "
2216 << theBottomRigthPoint << ", "
2224 //=============================================================================
2228 //=============================================================================
2229 static void SimplifyWhat (TopoDS_Shape& theWhat,
2230 TopTools_IndexedMapOfShape& theArgumentIndices,
2231 TColStd_ListOfInteger& theSimpleSubWhat)
2233 TopTools_MapOfShape mapShape;
2234 TopoDS_Iterator It (theWhat, Standard_True, Standard_True);
2235 for (; It.More(); It.Next()) {
2236 if (mapShape.Add(It.Value())) {
2237 TopoDS_Shape curSh = It.Value();
2238 if (curSh.ShapeType() == TopAbs_COMPOUND ||
2239 curSh.ShapeType() == TopAbs_COMPSOLID) {
2240 SimplifyWhat(curSh, theArgumentIndices, theSimpleSubWhat);
2242 theSimpleSubWhat.Append(theArgumentIndices.FindIndex(curSh));
2248 static bool GetInPlaceOfCompound (Handle(GEOM_Function)& theWhereFunction,
2249 TopoDS_Shape& theWhat,
2250 TColStd_ListOfInteger& theModifiedArray)
2252 bool isFoundAny = false;
2253 TopTools_MapOfShape mapShape;
2254 TopoDS_Iterator It (theWhat, Standard_True, Standard_True);
2255 for (; It.More(); It.Next()) {
2256 if (mapShape.Add(It.Value())) {
2257 TopoDS_Shape curWhat = It.Value();
2258 if (curWhat.ShapeType() == TopAbs_COMPOUND ||
2259 curWhat.ShapeType() == TopAbs_COMPSOLID) {
2260 // Recursive call for compound or compsolid
2261 if (GetInPlaceOfCompound(theWhereFunction, curWhat, theModifiedArray))
2264 // Try to find for "simple" shape
2265 bool isFound = false;
2267 TDF_LabelSequence aLabelSeq;
2268 theWhereFunction->GetDependency(aLabelSeq);
2269 Standard_Integer nbArg = aLabelSeq.Length();
2271 for (Standard_Integer iarg = 1; iarg <= nbArg && !isFound; iarg++) {
2273 TDF_Label anArgumentRefLabel = aLabelSeq.Value(iarg);
2275 Handle(GEOM_Object) anArgumentObject = GEOM_Object::GetReferencedObject(anArgumentRefLabel);
2276 TopoDS_Shape anArgumentShape = anArgumentObject->GetValue();
2278 TopTools_IndexedMapOfShape anArgumentIndices;
2279 TopExp::MapShapes(anArgumentShape, anArgumentIndices);
2281 if (anArgumentIndices.Contains(curWhat)) {
2282 isFound = Standard_True;
2283 Standard_Integer aWhatIndex = anArgumentIndices.FindIndex(curWhat);
2285 // Find corresponding label in history
2286 TDF_Label anArgumentHistoryLabel =
2287 theWhereFunction->GetArgumentHistoryEntry(anArgumentRefLabel, Standard_False);
2288 if (!anArgumentHistoryLabel.IsNull()) {
2289 TDF_Label aWhatHistoryLabel = anArgumentHistoryLabel.FindChild(aWhatIndex, Standard_False);
2290 if (!aWhatHistoryLabel.IsNull()) {
2291 Handle(TDataStd_IntegerArray) anIntegerArray;
2292 if (aWhatHistoryLabel.FindAttribute(TDataStd_IntegerArray::GetID(), anIntegerArray)) {
2293 Standard_Integer imod, aModifLen = anIntegerArray->Array()->Length();
2294 for (imod = 1; imod <= aModifLen; imod++) {
2295 theModifiedArray.Append(anIntegerArray->Array()->Value(imod));
2310 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlace
2311 (Handle(GEOM_Object) theShapeWhere,
2312 Handle(GEOM_Object) theShapeWhat)
2316 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
2318 TopoDS_Shape aWhere = theShapeWhere->GetValue();
2319 TopoDS_Shape aWhat = theShapeWhat->GetValue();
2321 if (aWhere.IsNull() || aWhat.IsNull()) return NULL;
2323 //Fill array of indices
2324 Handle(TColStd_HArray1OfInteger) aModifiedArray;
2326 Handle(GEOM_Function) aWhereFunction = theShapeWhere->GetLastFunction();
2328 TopTools_IndexedMapOfShape aWhereIndices;
2329 TopExp::MapShapes(aWhere, aWhereIndices);
2331 if (aWhereIndices.Contains(aWhat)) {
2333 // entity was not changed by the operation
2334 Standard_Integer aWhatIndex = aWhereIndices.FindIndex(aWhat);
2335 aModifiedArray = new TColStd_HArray1OfInteger(1,1);
2336 aModifiedArray->SetValue(1, aWhatIndex);
2340 TDF_Label aHistoryLabel = aWhereFunction->GetHistoryEntry(Standard_False);
2341 if (aHistoryLabel.IsNull()) {
2342 SetErrorCode("Modifications history does not exist for the shape under consideration.");
2346 // search in history for all argument shapes
2347 Standard_Boolean isFound = Standard_False;
2349 TDF_LabelSequence aLabelSeq;
2350 aWhereFunction->GetDependency(aLabelSeq);
2351 Standard_Integer nbArg = aLabelSeq.Length();
2353 for (Standard_Integer iarg = 1; iarg <= nbArg && !isFound; iarg++) {
2355 TDF_Label anArgumentRefLabel = aLabelSeq.Value(iarg);
2357 Handle(GEOM_Object) anArgumentObject = GEOM_Object::GetReferencedObject(anArgumentRefLabel);
2358 TopoDS_Shape anArgumentShape = anArgumentObject->GetValue();
2360 TopTools_IndexedMapOfShape anArgumentIndices;
2361 TopExp::MapShapes(anArgumentShape, anArgumentIndices);
2363 if (anArgumentIndices.Contains(aWhat)) {
2364 isFound = Standard_True;
2365 Standard_Integer aWhatIndex = anArgumentIndices.FindIndex(aWhat);
2367 // Find corresponding label in history
2368 TDF_Label anArgumentHistoryLabel =
2369 aWhereFunction->GetArgumentHistoryEntry(anArgumentRefLabel, Standard_False);
2370 if (anArgumentHistoryLabel.IsNull()) {
2371 // Lost History of operation argument. Possibly, all its entities was removed.
2376 TDF_Label aWhatHistoryLabel = anArgumentHistoryLabel.FindChild(aWhatIndex, Standard_False);
2377 if (aWhatHistoryLabel.IsNull()) {
2378 // Check, if the sought shape is Compound or Compsolid.
2379 // In that case we will try to find history for its sub-shapes
2380 if (aWhat.ShapeType() == TopAbs_COMPOUND ||
2381 aWhat.ShapeType() == TopAbs_COMPSOLID) {
2382 TColStd_ListOfInteger aSimpleSubWhat, aModifiedList;
2383 SimplifyWhat(aWhat, anArgumentIndices, aSimpleSubWhat);
2384 TColStd_ListIteratorOfListOfInteger anIterSub (aSimpleSubWhat);
2385 for (; anIterSub.More(); anIterSub.Next()) {
2386 Standard_Integer aSubWhatIndex = anIterSub.Value();
2387 TDF_Label aSubWhatHistoryLabel =
2388 anArgumentHistoryLabel.FindChild(aSubWhatIndex, Standard_False);
2389 if (!aSubWhatHistoryLabel.IsNull()) {
2390 Handle(TDataStd_IntegerArray) anIntegerArray;
2391 if (aSubWhatHistoryLabel.FindAttribute(TDataStd_IntegerArray::GetID(), anIntegerArray)) {
2392 for (Standard_Integer isub = 1; isub <= anIntegerArray->Length(); isub++) {
2393 aModifiedList.Append(anIntegerArray->Value(isub));
2398 if (aModifiedList.Extent() > 0) {
2399 Handle(TColStd_HArray1OfInteger) aModifiedArraySub =
2400 new TColStd_HArray1OfInteger (1, aModifiedList.Extent());
2401 TColStd_ListIteratorOfListOfInteger anIterModif (aModifiedList);
2402 for (Standard_Integer imod = 1; anIterModif.More(); anIterModif.Next(), imod++) {
2403 aModifiedArraySub->SetValue(imod, anIterModif.Value());
2405 aModifiedArray = aModifiedArraySub;
2417 Handle(TDataStd_IntegerArray) anIntegerArray;
2418 if (!aWhatHistoryLabel.FindAttribute(TDataStd_IntegerArray::GetID(), anIntegerArray)) {
2419 SetErrorCode("Error: Empty modifications history for the sought shape.");
2423 aModifiedArray = anIntegerArray->Array();
2424 if (aModifiedArray->Length() == 0) {
2425 SetErrorCode("Error: Empty modifications history for the sought shape.");
2433 // try compound element by element
2434 if (aWhat.ShapeType() == TopAbs_COMPOUND ||
2435 aWhat.ShapeType() == TopAbs_COMPSOLID) {
2436 TColStd_ListOfInteger aModifiedList;
2437 isFound = GetInPlaceOfCompound(aWhereFunction, aWhat, aModifiedList);
2439 if (aModifiedList.Extent() < 1) {
2440 SetErrorCode("Error: Empty modifications history for all sub-shapes of the sought shape.");
2443 aModifiedArray = new TColStd_HArray1OfInteger (1, aModifiedList.Extent());
2444 TColStd_ListIteratorOfListOfInteger anIterModif (aModifiedList);
2445 for (Standard_Integer imod = 1; anIterModif.More(); anIterModif.Next(), imod++) {
2446 aModifiedArray->SetValue(imod, anIterModif.Value());
2451 SetErrorCode("The sought shape does not belong to any operation argument.");
2458 Handle(GEOM_Object) aResult = GetEngine()->AddSubShape(theShapeWhere, aModifiedArray);
2459 if (aResult.IsNull()) {
2460 SetErrorCode("Error in algorithm: result found, but cannot be returned.");
2464 if (aModifiedArray->Length() > 1) {
2466 aResult->SetType(GEOM_GROUP);
2468 //Set a sub shape type
2469 TDF_Label aFreeLabel = aResult->GetFreeLabel();
2470 TopAbs_ShapeEnum aShapeType = aWhat.ShapeType();
2471 TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aShapeType);
2474 //Make a Python command
2475 Handle(GEOM_Function) aFunction = aResult->GetFunction(1);
2477 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetInPlace("
2478 << theShapeWhere << ", " << theShapeWhat << ")";
2484 //=======================================================================
2485 //function : SortShapes
2487 //=======================================================================
2488 void GEOMImpl_IShapesOperations::SortShapes(TopTools_ListOfShape& SL)
2490 Standard_Integer MaxShapes = SL.Extent();
2491 TopTools_Array1OfShape aShapes (1,MaxShapes);
2492 TColStd_Array1OfInteger OrderInd(1,MaxShapes);
2493 TColStd_Array1OfReal MidXYZ (1,MaxShapes); //X,Y,Z;
2494 TColStd_Array1OfReal Length (1,MaxShapes); //X,Y,Z;
2496 // Computing of CentreOfMass
2497 Standard_Integer Index;
2500 TopTools_ListIteratorOfListOfShape it(SL);
2501 for (Index=1; it.More(); Index++)
2503 TopoDS_Shape S = it.Value();
2504 SL.Remove( it ); // == it.Next()
2506 OrderInd.SetValue (Index, Index);
2507 if (S.ShapeType() == TopAbs_VERTEX)
2509 GPoint = BRep_Tool::Pnt( TopoDS::Vertex( S ));
2510 Length.SetValue( Index, (Standard_Real) S.Orientation());
2514 BRepGProp::LinearProperties (S, GPr);
2515 GPoint = GPr.CentreOfMass();
2516 Length.SetValue( Index, GPr.Mass() );
2518 MidXYZ.SetValue(Index,
2519 GPoint.X()*999 + GPoint.Y()*99 + GPoint.Z()*0.9);
2523 Standard_Integer aTemp;
2524 Standard_Boolean exchange, Sort = Standard_True;
2527 Sort = Standard_False;
2528 for (Index=1; Index < MaxShapes; Index++)
2530 if (MidXYZ(OrderInd(Index)) > MidXYZ(OrderInd(Index+1)))
2531 exchange = Standard_True;
2532 else if (MidXYZ(OrderInd(Index)) == MidXYZ(OrderInd(Index+1)) &&
2533 Length(OrderInd(Index)) > Length(OrderInd(Index+1)) )
2534 exchange = Standard_True;
2536 exchange = Standard_False;
2539 aTemp = OrderInd(Index);
2540 OrderInd(Index) = OrderInd(Index+1);
2541 OrderInd(Index+1) = aTemp;
2542 Sort = Standard_True;
2546 for (Index=1; Index <= MaxShapes; Index++)
2547 SL.Append( aShapes( OrderInd(Index) ));
2550 //=======================================================================
2551 //function : CheckTriangulation
2553 //=======================================================================
2554 bool GEOMImpl_IShapesOperations::CheckTriangulation (const TopoDS_Shape& aShape)
2556 TopExp_Explorer exp (aShape, TopAbs_FACE);
2558 SetErrorCode("Shape without faces given");
2562 TopLoc_Location aTopLoc;
2563 Handle(Poly_Triangulation) aTRF;
2564 aTRF = BRep_Tool::Triangulation(TopoDS::Face(exp.Current()), aTopLoc);
2565 if (aTRF.IsNull()) {
2566 // calculate deflection
2567 Standard_Real aDeviationCoefficient = 0.001;
2570 BRepBndLib::Add(aShape, B);
2571 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
2572 B.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
2574 Standard_Real dx = aXmax - aXmin, dy = aYmax - aYmin, dz = aZmax - aZmin;
2575 Standard_Real aDeflection = Max(Max(dx, dy), dz) * aDeviationCoefficient * 4;
2576 Standard_Real aHLRAngle = 0.349066;
2578 BRepMesh_IncrementalMesh Inc (aShape, aDeflection, Standard_False, aHLRAngle);
2584 #define MAX_TOLERANCE 1.e-7
2587 //=======================================================================
2588 //function : isSameEdge
2589 //purpose : Returns True if two edges coincide
2590 //=======================================================================
2591 static bool isSameEdge(const TopoDS_Edge& theEdge1, const TopoDS_Edge& theEdge2)
2593 TopoDS_Vertex V11, V12, V21, V22;
2594 TopExp::Vertices(theEdge1, V11, V12);
2595 TopExp::Vertices(theEdge2, V21, V22);
2596 gp_Pnt P11 = BRep_Tool::Pnt(V11);
2597 gp_Pnt P12 = BRep_Tool::Pnt(V12);
2598 gp_Pnt P21 = BRep_Tool::Pnt(V21);
2599 gp_Pnt P22 = BRep_Tool::Pnt(V22);
2600 bool coincide = false;
2602 //Check that ends of edges coincide
2603 if(P11.Distance(P21) <= MAX_TOLERANCE) {
2604 if(P12.Distance(P22) <= MAX_TOLERANCE) coincide = true;
2606 else if(P11.Distance(P22) <= MAX_TOLERANCE) {
2607 if(P12.Distance(P21) <= MAX_TOLERANCE) coincide = true;
2610 if(!coincide) return false;
2612 double U11, U12, U21, U22;
2613 Handle(Geom_Curve) C1 = BRep_Tool::Curve(theEdge1, U11, U12);
2614 Handle(Geom_Curve) C2 = BRep_Tool::Curve(theEdge2, U21, U22);
2615 if(C1->DynamicType() == C2->DynamicType()) return true;
2617 //Check that both edges has the same geometry
2618 double range = U12-U11;
2619 double U = U11+ range/3.0;
2620 gp_Pnt P1 = C1->Value(U); //Compute a point on one third of the edge's length
2621 U = U11+range*2.0/3.0;
2622 gp_Pnt P2 = C1->Value(U); //Compute a point on two thirds of the edge's length
2624 if(!GeomLib_Tool::Parameter(C2, P1, MAX_TOLERANCE, U) || U < U21 || U > U22)
2627 if(P1.Distance(C2->Value(U)) > MAX_TOLERANCE) return false;
2629 if(!GeomLib_Tool::Parameter(C2, P2, MAX_TOLERANCE, U) || U < U21 || U > U22)
2632 if(P2.Distance(C2->Value(U)) > MAX_TOLERANCE) return false;
2637 #include <TopoDS_TShape.hxx>
2638 //=======================================================================
2639 //function : isSameFace
2640 //purpose : Returns True if two faces coincide
2641 //=======================================================================
2642 static bool isSameFace(const TopoDS_Face& theFace1, const TopoDS_Face& theFace2)
2644 TopExp_Explorer E(theFace1, TopAbs_EDGE);
2645 TopTools_ListOfShape LS1, LS2;
2646 for(; E.More(); E.Next()) LS1.Append(E.Current());
2648 E.Init(theFace2, TopAbs_EDGE);
2649 for(; E.More(); E.Next()) LS2.Append(E.Current());
2651 //Compare the number of edges in the faces
2652 if(LS1.Extent() != LS2.Extent()) return false;
2654 double aMin = RealFirst(), aMax = RealLast();
2655 double xminB1=aMax, yminB1=aMax, zminB1=aMax, xminB2=aMax, yminB2=aMax, zminB2=aMax;
2656 double xmaxB1=aMin, ymaxB1=aMin, zmaxB1=aMin, xmaxB2=aMin, ymaxB2=aMin, zmaxB2=aMin;
2658 for(E.Init(theFace1, TopAbs_VERTEX); E.More(); E.Next()) {
2659 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
2660 if(P.X() < xminB1) xminB1 = P.X();
2661 if(P.Y() < yminB1) yminB1 = P.Y();
2662 if(P.Z() < zminB1) zminB1 = P.Z();
2663 if(P.X() > xmaxB1) xmaxB1 = P.X();
2664 if(P.Y() > ymaxB1) ymaxB1 = P.Y();
2665 if(P.Z() > zmaxB1) zmaxB1 = P.Z();
2668 for(E.Init(theFace2, TopAbs_VERTEX); E.More(); E.Next()) {
2669 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
2670 if(P.X() < xminB2) xminB2 = P.X();
2671 if(P.Y() < yminB2) yminB2 = P.Y();
2672 if(P.Z() < zminB2) zminB2 = P.Z();
2673 if(P.X() > xmaxB2) xmaxB2 = P.X();
2674 if(P.Y() > ymaxB2) ymaxB2 = P.Y();
2675 if(P.Z() > zmaxB2) zmaxB2 = P.Z();
2678 //Compare the bounding boxes of both faces
2679 if(gp_Pnt(xminB1, yminB1, zminB1).Distance(gp_Pnt(xminB2, yminB2, zminB2)) > MAX_TOLERANCE)
2682 if(gp_Pnt(xmaxB1, ymaxB1, zmaxB1).Distance(gp_Pnt(xmaxB2, ymaxB2, zmaxB2)) > MAX_TOLERANCE)
2685 //Check that each edge of the Face1 has a counterpart in the Face2
2686 TopTools_MapOfOrientedShape aMap;
2687 TopTools_ListIteratorOfListOfShape LSI1(LS1);
2688 for(; LSI1.More(); LSI1.Next()) {
2689 TopoDS_Edge E = TopoDS::Edge(LSI1.Value());
2690 bool isFound = false;
2691 TopTools_ListIteratorOfListOfShape LSI2(LS2);
2692 for(; LSI2.More(); LSI2.Next()) {
2693 TopoDS_Shape aValue = LSI2.Value();
2694 if(aMap.Contains(aValue)) continue; //To avoid checking already found edge several times
2695 if(isSameEdge(E, TopoDS::Edge(aValue))) {
2701 if(!isFound) return false;
2704 Handle(Geom_Surface) S1 = BRep_Tool::Surface(theFace1);
2705 Handle(Geom_Surface) S2 = BRep_Tool::Surface(theFace2);
2706 if(S1->DynamicType() == S2->DynamicType()) {
2709 else { //Check if there a coincidence of two surfaces at least in two points
2710 double U11, U12, V11, V12, U21, U22, V21, V22;
2711 BRepTools::UVBounds(theFace1, U11, U12, V11, V12);
2712 BRepTools::UVBounds(theFace2, U21, U22, V21, V22);
2714 double rangeU = U12-U11;
2715 double rangeV = V12-V11;
2716 double U = U11 + rangeU/3.0;
2717 double V = V11 + rangeV/3.0;
2718 gp_Pnt P1 = S1->Value(U, V);
2719 U = U11+rangeU*2.0/3.0;
2720 V = V11+rangeV*2.0/3.0;
2721 gp_Pnt P2 = S1->Value(U, V);
2723 if(!GeomLib_Tool::Parameters(S2, P1, MAX_TOLERANCE, U, V) || U < U21 || U > U22 || V < V21 || V > V22)
2726 if(P1.Distance(S2->Value(U,V)) > MAX_TOLERANCE) return false;
2728 if(!GeomLib_Tool::Parameters(S2, P2, MAX_TOLERANCE, U, V) || U < U21 || U > U22 || V < V21 || V > V22)
2731 if(P2.Distance(S2->Value(U, V)) > MAX_TOLERANCE) return false;
2737 //=======================================================================
2738 //function : isSameSolid
2739 //purpose : Returns True if two solids coincide
2740 //=======================================================================
2741 bool isSameSolid(const TopoDS_Solid& theSolid1, const TopoDS_Solid& theSolid2)
2743 TopExp_Explorer E(theSolid1, TopAbs_FACE);
2744 TopTools_ListOfShape LS1, LS2;
2745 for(; E.More(); E.Next()) LS1.Append(E.Current());
2746 E.Init(theSolid2, TopAbs_FACE);
2747 for(; E.More(); E.Next()) LS2.Append(E.Current());
2749 if(LS1.Extent() != LS2.Extent()) return false;
2751 double aMin = RealFirst(), aMax = RealLast();
2752 double xminB1=aMax, yminB1=aMax, zminB1=aMax, xminB2=aMax, yminB2=aMax, zminB2=aMax;
2753 double xmaxB1=aMin, ymaxB1=aMin, zmaxB1=aMin, xmaxB2=aMin, ymaxB2=aMin, zmaxB2=aMin;
2755 for(E.Init(theSolid1, TopAbs_VERTEX); E.More(); E.Next()) {
2756 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
2757 if(P.X() < xminB1) xminB1 = P.X();
2758 if(P.Y() < yminB1) yminB1 = P.Y();
2759 if(P.Z() < zminB1) zminB1 = P.Z();
2760 if(P.X() > xmaxB1) xmaxB1 = P.X();
2761 if(P.Y() > ymaxB1) ymaxB1 = P.Y();
2762 if(P.Z() > zmaxB1) zmaxB1 = P.Z();
2765 for(E.Init(theSolid2, TopAbs_VERTEX); E.More(); E.Next()) {
2766 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
2767 if(P.X() < xminB2) xminB2 = P.X();
2768 if(P.Y() < yminB2) yminB2 = P.Y();
2769 if(P.Z() < zminB2) zminB2 = P.Z();
2770 if(P.X() > xmaxB2) xmaxB2 = P.X();
2771 if(P.Y() > ymaxB2) ymaxB2 = P.Y();
2772 if(P.Z() > zmaxB2) zmaxB2 = P.Z();
2775 //Compare the bounding boxes of both solids
2776 if(gp_Pnt(xminB1, yminB1, zminB1).Distance(gp_Pnt(xminB2, yminB2, zminB2)) > MAX_TOLERANCE)
2779 if(gp_Pnt(xmaxB1, ymaxB1, zmaxB1).Distance(gp_Pnt(xmaxB2, ymaxB2, zmaxB2)) > MAX_TOLERANCE)
2782 //Check that each face of the Solid1 has a counterpart in the Solid2
2783 TopTools_MapOfOrientedShape aMap;
2784 TopTools_ListIteratorOfListOfShape LSI1(LS1);
2785 for(; LSI1.More(); LSI1.Next()) {
2786 TopoDS_Face F = TopoDS::Face(LSI1.Value());
2787 bool isFound = false;
2788 TopTools_ListIteratorOfListOfShape LSI2(LS2);
2789 for(; LSI2.More(); LSI2.Next()) {
2790 if(aMap.Contains(LSI2.Value())) continue; //To avoid checking already found faces several times
2791 if(isSameFace(F, TopoDS::Face(LSI2.Value()))) {
2792 aMap.Add(LSI2.Value());
2797 if(!isFound) return false;
2803 //=======================================================================
2804 //function : GetSame
2806 //=======================================================================
2807 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetSame(const Handle(GEOM_Object)& theShapeWhere,
2808 const Handle(GEOM_Object)& theShapeWhat)
2811 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
2813 TopoDS_Shape aWhere = theShapeWhere->GetValue();
2814 TopoDS_Shape aWhat = theShapeWhat->GetValue();
2816 if (aWhere.IsNull() || aWhat.IsNull()) return NULL;
2819 bool isFound = false;
2820 TopoDS_Shape aSubShape;
2821 TopTools_MapOfShape aMap;
2823 switch(aWhat.ShapeType()) {
2824 case TopAbs_VERTEX: {
2825 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(aWhat));
2826 TopExp_Explorer E(aWhere, TopAbs_VERTEX);
2827 for(; E.More(); E.Next()) {
2828 if(!aMap.Add(E.Current())) continue;
2829 gp_Pnt P2 = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
2830 if(P.Distance(P2) <= MAX_TOLERANCE) {
2832 aSubShape = E.Current();
2839 TopoDS_Face aFace = TopoDS::Face(aWhat);
2840 TopExp_Explorer E(aWhere, TopAbs_FACE);
2841 for(; E.More(); E.Next()) {
2842 if(!aMap.Add(E.Current())) continue;
2843 if(isSameFace(aFace, TopoDS::Face(E.Current()))) {
2844 aSubShape = E.Current();
2852 TopoDS_Edge anEdge = TopoDS::Edge(aWhat);
2853 TopExp_Explorer E(aWhere, TopAbs_EDGE);
2854 for(; E.More(); E.Next()) {
2855 if(!aMap.Add(E.Current())) continue;
2856 if(isSameEdge(anEdge, TopoDS::Edge(E.Current()))) {
2857 aSubShape = E.Current();
2864 case TopAbs_SOLID: {
2865 TopoDS_Solid aSolid = TopoDS::Solid(aWhat);
2866 TopExp_Explorer E(aWhere, TopAbs_SOLID);
2867 for(; E.More(); E.Next()) {
2868 if(!aMap.Add(E.Current())) continue;
2869 if(isSameSolid(aSolid, TopoDS::Solid(E.Current()))) {
2870 aSubShape = E.Current();
2882 TopTools_IndexedMapOfShape anIndices;
2883 TopExp::MapShapes(aWhere, anIndices);
2884 if (anIndices.Contains(aSubShape))
2885 anIndex = anIndices.FindIndex(aSubShape);
2888 if(anIndex < 0) return NULL;
2890 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
2892 anArray->SetValue(1, anIndex);
2894 Handle(GEOM_Object) aResult = GetEngine()->AddSubShape(theShapeWhere, anArray);
2895 Handle(GEOM_Function) aFunction = aResult->GetLastFunction();
2897 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetSame("
2898 << theShapeWhere << ", " << theShapeWhat << ")";