1 // Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 // File : GEOMImpl_IShapesOperations.cxx
24 // Author : modified by Lioka RAZAFINDRAZAKA (CEA) 22/06/2007
28 #include <Standard_Stream.hxx>
30 #include "GEOMImpl_IShapesOperations.hxx"
32 #include "GEOMImpl_Types.hxx"
34 #include "GEOMImpl_VectorDriver.hxx"
35 #include "GEOMImpl_ShapeDriver.hxx"
36 #include "GEOMImpl_CopyDriver.hxx"
37 #include "GEOMImpl_GlueDriver.hxx"
39 #include "GEOMImpl_IVector.hxx"
40 #include "GEOMImpl_IShapes.hxx"
41 #include "GEOMImpl_IGlue.hxx"
43 #include "GEOMImpl_Block6Explorer.hxx"
45 #include "GEOM_Function.hxx"
46 #include "GEOM_ISubShape.hxx"
47 #include "GEOM_PythonDump.hxx"
49 #include "GEOMAlgo_FinderShapeOn1.hxx"
50 #include "GEOMAlgo_FinderShapeOnQuad.hxx"
51 #include "GEOMAlgo_FinderShapeOn2.hxx"
52 #include "GEOMAlgo_ClsfBox.hxx"
53 #include "GEOMAlgo_ClsfSolid.hxx"
54 #include "GEOMAlgo_Gluer1.hxx"
55 #include "GEOMAlgo_ListIteratorOfListOfCoupleOfShapes.hxx"
56 #include "GEOMAlgo_CoupleOfShapes.hxx"
57 #include "GEOMAlgo_ListOfCoupleOfShapes.hxx"
59 #include "utilities.h"
61 #include "Utils_ExceptHandlers.hxx"
63 #include <TFunction_DriverTable.hxx>
64 #include <TFunction_Driver.hxx>
65 #include <TFunction_Logbook.hxx>
66 #include <TDataStd_Integer.hxx>
67 #include <TDataStd_IntegerArray.hxx>
68 #include <TDF_Tool.hxx>
70 #include <BRepExtrema_ExtCF.hxx>
71 #include <BRepExtrema_DistShapeShape.hxx>
73 #include <BRep_Tool.hxx>
74 #include <BRep_Builder.hxx>
75 #include <BRepTools.hxx>
76 #include <BRepGProp.hxx>
77 #include <BRepAdaptor_Curve.hxx>
78 #include <BRepAdaptor_Surface.hxx>
79 #include <BRepBndLib.hxx>
80 #include <BRepBuilderAPI_MakeFace.hxx>
81 #include <BRepMesh_IncrementalMesh.hxx>
86 #include <TopoDS_Shape.hxx>
87 #include <TopoDS_Solid.hxx>
88 #include <TopoDS_Face.hxx>
89 #include <TopoDS_Edge.hxx>
90 #include <TopoDS_Vertex.hxx>
91 #include <TopoDS_Compound.hxx>
92 #include <TopoDS_Iterator.hxx>
93 #include <TopExp_Explorer.hxx>
94 #include <TopLoc_Location.hxx>
95 #include <TopTools_MapOfShape.hxx>
96 #include <TopTools_MapOfOrientedShape.hxx>
97 #include <TopTools_Array1OfShape.hxx>
98 #include <TopTools_ListIteratorOfListOfShape.hxx>
99 #include <TopTools_IndexedMapOfShape.hxx>
101 #include <Geom_Surface.hxx>
102 #include <Geom_Plane.hxx>
103 #include <Geom_SphericalSurface.hxx>
104 #include <Geom_CylindricalSurface.hxx>
105 #include <GeomAdaptor_Surface.hxx>
107 #include <GeomLib_Tool.hxx>
108 #include <Geom2d_Curve.hxx>
110 #include <Bnd_Box.hxx>
111 #include <GProp_GProps.hxx>
112 #include <TColStd_Array1OfReal.hxx>
113 #include <TColStd_HArray1OfInteger.hxx>
114 #include <TColStd_ListIteratorOfListOfInteger.hxx>
115 #include <TColStd_ListOfInteger.hxx>
116 #include <gp_Cylinder.hxx>
117 #include <gp_Lin.hxx>
118 #include <gp_Pnt.hxx>
122 #include <Standard_NullObject.hxx>
123 #include <Standard_Failure.hxx>
124 #include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
126 // Includes added for GetInPlace algorithm improvement
128 #include <GEOMImpl_MeasureDriver.hxx>
129 #include <GEOMImpl_IMeasure.hxx>
130 #include <BRepBuilderAPI_MakeVertex.hxx>
132 #include <BRepClass_FaceClassifier.hxx>
133 #include <BRepClass3d_SolidClassifier.hxx>
134 #include <Precision.hxx>
136 //=============================================================================
140 //=============================================================================
141 GEOMImpl_IShapesOperations::GEOMImpl_IShapesOperations (GEOM_Engine* theEngine, int theDocID)
142 : GEOM_IOperations(theEngine, theDocID)
144 MESSAGE("GEOMImpl_IShapesOperations::GEOMImpl_IShapesOperations");
147 //=============================================================================
151 //=============================================================================
152 GEOMImpl_IShapesOperations::~GEOMImpl_IShapesOperations()
154 MESSAGE("GEOMImpl_IShapesOperations::~GEOMImpl_IShapesOperations");
157 //=============================================================================
161 //=============================================================================
162 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeEdge
163 (Handle(GEOM_Object) thePnt1, Handle(GEOM_Object) thePnt2)
167 if (thePnt1.IsNull() || thePnt2.IsNull()) return NULL;
169 //Add a new Edge object
170 Handle(GEOM_Object) anEdge = GetEngine()->AddObject(GetDocID(), GEOM_EDGE);
172 //Add a new Vector function
173 Handle(GEOM_Function) aFunction =
174 anEdge->AddFunction(GEOMImpl_VectorDriver::GetID(), VECTOR_TWO_PNT);
176 //Check if the function is set correctly
177 if (aFunction->GetDriverGUID() != GEOMImpl_VectorDriver::GetID()) return NULL;
179 GEOMImpl_IVector aPI (aFunction);
181 Handle(GEOM_Function) aRef1 = thePnt1->GetLastFunction();
182 Handle(GEOM_Function) aRef2 = thePnt2->GetLastFunction();
183 if (aRef1.IsNull() || aRef2.IsNull()) return NULL;
185 aPI.SetPoint1(aRef1);
186 aPI.SetPoint2(aRef2);
188 //Compute the Edge value
190 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
193 if (!GetSolver()->ComputeFunction(aFunction)) {
194 SetErrorCode("Vector driver failed");
198 catch (Standard_Failure) {
199 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
200 SetErrorCode(aFail->GetMessageString());
204 //Make a Python command
205 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdge("
206 << thePnt1 << ", " << thePnt2 << ")";
212 //=============================================================================
216 //=============================================================================
217 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeWire
218 (std::list<Handle(GEOM_Object)> theShapes,
219 const Standard_Real theTolerance)
224 Handle(GEOM_Object) aWire = GetEngine()->AddObject(GetDocID(), GEOM_WIRE);
227 Handle(GEOM_Function) aFunction =
228 aWire->AddFunction(GEOMImpl_ShapeDriver::GetID(), WIRE_EDGES);
229 if (aFunction.IsNull()) return NULL;
231 //Check if the function is set correctly
232 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
234 GEOMImpl_IShapes aCI (aFunction);
235 aCI.SetTolerance(theTolerance);
237 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
240 std::list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
241 for (; it != theShapes.end(); it++) {
242 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
243 if (aRefSh.IsNull()) {
244 SetErrorCode("NULL argument shape for the shape construction");
247 aShapesSeq->Append(aRefSh);
249 aCI.SetShapes(aShapesSeq);
253 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
256 if (!GetSolver()->ComputeFunction(aFunction)) {
257 SetErrorCode("Shape driver failed");
261 catch (Standard_Failure) {
262 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
263 SetErrorCode(aFail->GetMessageString());
267 //Make a Python command
268 GEOM::TPythonDump pd (aFunction);
269 pd << aWire << " = geompy.MakeWire([";
272 it = theShapes.begin();
273 if (it != theShapes.end()) {
275 while (it != theShapes.end()) {
276 pd << ", " << (*it++);
279 pd << "], " << theTolerance << ")";
285 //=============================================================================
289 //=============================================================================
290 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFace (Handle(GEOM_Object) theWire,
291 const bool isPlanarWanted)
295 if (theWire.IsNull()) return NULL;
297 //Add a new Face object
298 Handle(GEOM_Object) aFace = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
300 //Add a new Shape function for creation of a face from a wire
301 Handle(GEOM_Function) aFunction =
302 aFace->AddFunction(GEOMImpl_ShapeDriver::GetID(), FACE_WIRE);
303 if (aFunction.IsNull()) return NULL;
305 //Check if the function is set correctly
306 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
308 GEOMImpl_IShapes aCI (aFunction);
310 Handle(GEOM_Function) aRefWire = theWire->GetLastFunction();
312 if (aRefWire.IsNull()) return NULL;
314 aCI.SetBase(aRefWire);
315 aCI.SetIsPlanar(isPlanarWanted);
317 //Compute the Face value
319 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
322 if (!GetSolver()->ComputeFunction(aFunction)) {
323 SetErrorCode("Shape driver failed to compute a face");
327 catch (Standard_Failure) {
328 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
329 SetErrorCode(aFail->GetMessageString());
333 //Make a Python command
334 GEOM::TPythonDump(aFunction) << aFace << " = geompy.MakeFace("
335 << theWire << ", " << (int)isPlanarWanted << ")";
341 //=============================================================================
345 //=============================================================================
346 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFaceWires
347 (std::list<Handle(GEOM_Object)> theShapes,
348 const bool isPlanarWanted)
353 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
356 Handle(GEOM_Function) aFunction =
357 aShape->AddFunction(GEOMImpl_ShapeDriver::GetID(), FACE_WIRES);
358 if (aFunction.IsNull()) return NULL;
360 //Check if the function is set correctly
361 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
363 GEOMImpl_IShapes aCI (aFunction);
365 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
368 std::list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
369 for (; it != theShapes.end(); it++) {
370 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
371 if (aRefSh.IsNull()) {
372 SetErrorCode("NULL argument shape for the face construction");
375 aShapesSeq->Append(aRefSh);
377 aCI.SetShapes(aShapesSeq);
379 aCI.SetIsPlanar(isPlanarWanted);
383 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
386 if (!GetSolver()->ComputeFunction(aFunction)) {
387 SetErrorCode("Shape driver failed");
391 catch (Standard_Failure) {
392 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
393 SetErrorCode(aFail->GetMessageString());
397 //Make a Python command
398 GEOM::TPythonDump pd (aFunction);
399 pd << aShape << " = geompy.MakeFaceWires([";
402 it = theShapes.begin();
403 if (it != theShapes.end()) {
405 while (it != theShapes.end()) {
406 pd << ", " << (*it++);
409 pd << "], " << (int)isPlanarWanted << ")";
415 //=============================================================================
419 //=============================================================================
420 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeShell
421 (std::list<Handle(GEOM_Object)> theShapes)
423 return MakeShape(theShapes, GEOM_SHELL, SHELL_FACES, "MakeShell");
426 //=============================================================================
430 //=============================================================================
431 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeSolidShells
432 (std::list<Handle(GEOM_Object)> theShapes)
434 return MakeShape(theShapes, GEOM_SOLID, SOLID_SHELLS, "MakeSolid");
437 //=============================================================================
441 //=============================================================================
442 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeSolidShell (Handle(GEOM_Object) theShell)
446 if (theShell.IsNull()) return NULL;
448 //Add a new Solid object
449 Handle(GEOM_Object) aSolid = GetEngine()->AddObject(GetDocID(), GEOM_SOLID);
451 //Add a new Solid function for creation of a solid from a shell
452 Handle(GEOM_Function) aFunction =
453 aSolid->AddFunction(GEOMImpl_ShapeDriver::GetID(), SOLID_SHELL);
454 if (aFunction.IsNull()) return NULL;
456 //Check if the function is set correctly
457 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
459 GEOMImpl_IShapes aCI (aFunction);
461 Handle(GEOM_Function) aRefShell = theShell->GetLastFunction();
463 if (aRefShell.IsNull()) return NULL;
465 aCI.SetBase(aRefShell);
467 //Compute the Solid value
469 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
472 if (!GetSolver()->ComputeFunction(aFunction)) {
473 SetErrorCode("Solid driver failed");
477 catch (Standard_Failure) {
478 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
479 SetErrorCode(aFail->GetMessageString());
483 //Make a Python command
484 GEOM::TPythonDump(aFunction) << aSolid
485 << " = geompy.MakeSolid(" << theShell << ")";
491 //=============================================================================
495 //=============================================================================
496 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeCompound
497 (std::list<Handle(GEOM_Object)> theShapes)
499 return MakeShape(theShapes, GEOM_COMPOUND, COMPOUND_SHAPES, "MakeCompound");
502 //=============================================================================
506 //=============================================================================
507 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeShape
508 (std::list<Handle(GEOM_Object)> theShapes,
509 const Standard_Integer theObjectType,
510 const Standard_Integer theFunctionType,
511 const TCollection_AsciiString& theMethodName)
516 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), theObjectType);
519 Handle(GEOM_Function) aFunction =
520 aShape->AddFunction(GEOMImpl_ShapeDriver::GetID(), theFunctionType);
521 if (aFunction.IsNull()) return NULL;
523 //Check if the function is set correctly
524 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
526 GEOMImpl_IShapes aCI (aFunction);
528 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
531 std::list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
532 for (; it != theShapes.end(); it++) {
533 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
534 if (aRefSh.IsNull()) {
535 SetErrorCode("NULL argument shape for the shape construction");
538 aShapesSeq->Append(aRefSh);
540 aCI.SetShapes(aShapesSeq);
544 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
547 if (!GetSolver()->ComputeFunction(aFunction)) {
548 SetErrorCode("Shape driver failed");
552 catch (Standard_Failure) {
553 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
554 SetErrorCode(aFail->GetMessageString());
558 //Make a Python command
559 GEOM::TPythonDump pd (aFunction);
560 pd << aShape << " = geompy." << theMethodName.ToCString() << "([";
563 it = theShapes.begin();
564 if (it != theShapes.end()) {
566 while (it != theShapes.end()) {
567 pd << ", " << (*it++);
576 //=============================================================================
580 //=============================================================================
581 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeGlueFaces
582 (Handle(GEOM_Object) theShape,
583 const Standard_Real theTolerance,
584 const Standard_Boolean doKeepNonSolids)
588 if (theShape.IsNull()) return NULL;
590 //Add a new Glued object
591 Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
593 //Add a new Glue function
594 Handle(GEOM_Function) aFunction;
595 aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_FACES);
596 if (aFunction.IsNull()) return NULL;
598 //Check if the function is set correctly
599 if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
601 GEOMImpl_IGlue aCI (aFunction);
603 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
604 if (aRefShape.IsNull()) return NULL;
606 aCI.SetBase(aRefShape);
607 aCI.SetTolerance(theTolerance);
608 aCI.SetKeepNonSolids(doKeepNonSolids);
610 //Compute the sub-shape value
611 Standard_Boolean isWarning = Standard_False;
613 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
616 if (!GetSolver()->ComputeFunction(aFunction)) {
617 SetErrorCode("Shape driver failed to glue faces");
621 catch (Standard_Failure) {
622 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
623 SetErrorCode(aFail->GetMessageString());
624 // to provide warning
625 if (!aFunction->GetValue().IsNull()) {
626 isWarning = Standard_True;
632 //Make a Python command
633 GEOM::TPythonDump(aFunction) << aGlued << " = geompy.MakeGlueFaces("
634 << theShape << ", " << theTolerance << ")";
636 // to provide warning
637 if (!isWarning) SetErrorCode(OK);
641 //=============================================================================
645 //=============================================================================
646 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetGlueFaces
647 (Handle(GEOM_Object) theShape,
648 const Standard_Real theTolerance)
652 if (theShape.IsNull()) return NULL;
653 TopoDS_Shape aShape = theShape->GetValue();
654 if (aShape.IsNull()) return NULL;
656 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
658 Standard_Integer iErr;
660 GEOMAlgo_Gluer1 aGluer;
661 GEOMAlgo_ListIteratorOfListOfCoupleOfShapes aItCS;
662 GEOMAlgo_CoupleOfShapes aCS;
663 GEOMAlgo_ListOfCoupleOfShapes aLCS;
665 //aGluer = new GEOMAlgo_Gluer1;
666 aGluer.SetShape(aShape);
667 aGluer.SetTolerance(theTolerance);
669 iErr = aGluer.ErrorStatus();
670 if (iErr) return NULL;
672 TopTools_ListOfShape listShape;
673 const GEOMAlgo_ListOfCoupleOfShapes& aLCSG = aGluer.GluedFaces();
675 aItCS.Initialize(aLCSG);
676 for (; aItCS.More(); aItCS.Next()) {
677 const GEOMAlgo_CoupleOfShapes& aCSG = aItCS.Value();
678 listShape.Append(aCSG.Shape1());
681 TopTools_ListIteratorOfListOfShape itSub (listShape);
682 TCollection_AsciiString anAsciiList, anEntry;
683 TopTools_IndexedMapOfShape anIndices;
684 TopExp::MapShapes(aShape, anIndices);
685 Handle(TColStd_HArray1OfInteger) anArray;
686 Handle(GEOM_Object) anObj;
687 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
688 TopoDS_Shape aValue = itSub.Value();
689 anArray = new TColStd_HArray1OfInteger(1,1);
690 anArray->SetValue(1, anIndices.FindIndex(aValue));
691 anObj = GetEngine()->AddSubShape(theShape, anArray);
692 if (!anObj.IsNull()) {
695 // for python command
696 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
697 anAsciiList += anEntry;
702 //Make a Python command
703 if( anAsciiList.Length() > 0 ) {
704 anAsciiList.Trunc(anAsciiList.Length() - 1);
705 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
706 GEOM::TPythonDump pd (aFunction, /*append=*/true);
707 pd << "[" << anAsciiList.ToCString();
708 pd << "] = geompy.GetGlueFaces(" << theShape << ", " << theTolerance << ")";
716 //=============================================================================
718 * MakeGlueFacesByList
720 //=============================================================================
721 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeGlueFacesByList
722 (Handle(GEOM_Object) theShape,
723 const Standard_Real theTolerance,
724 std::list<Handle(GEOM_Object)> theFaces,
725 const Standard_Boolean doKeepNonSolids)
729 if (theShape.IsNull()) return NULL;
731 //Add a new Glued object
732 Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
734 //Add a new Glue function
735 Handle(GEOM_Function) aFunction;
736 aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_FACES_BY_LIST);
737 if (aFunction.IsNull()) return NULL;
739 //Check if the function is set correctly
740 if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
742 GEOMImpl_IGlue aCI (aFunction);
744 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
745 if (aRefShape.IsNull()) return NULL;
747 aCI.SetBase(aRefShape);
748 aCI.SetTolerance(theTolerance);
749 aCI.SetKeepNonSolids(doKeepNonSolids);
751 Handle(TColStd_HSequenceOfTransient) aFaces = new TColStd_HSequenceOfTransient;
752 std::list<Handle(GEOM_Object)>::iterator it = theFaces.begin();
753 for (; it != theFaces.end(); it++) {
754 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
755 if (aRefSh.IsNull()) {
756 SetErrorCode("NULL argument shape for the shape construction");
759 aFaces->Append(aRefSh);
761 aCI.SetFaces(aFaces);
763 //Compute the sub-shape value
764 Standard_Boolean isWarning = Standard_False;
766 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
769 if (!GetSolver()->ComputeFunction(aFunction)) {
770 SetErrorCode("Shape driver failed to glue faces");
774 catch (Standard_Failure) {
775 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
776 SetErrorCode(aFail->GetMessageString());
777 // to provide warning
778 if (!aFunction->GetValue().IsNull()) {
779 isWarning = Standard_True;
785 //Make a Python command
787 GEOM::TPythonDump pd(aFunction);
788 pd << aGlued << " = geompy.MakeGlueFacesByList("
789 << theShape << ", " << theTolerance << ", [";
791 it = theFaces.begin();
792 if (it != theFaces.end()) {
794 while (it != theFaces.end()) {
795 pd << ", " << (*it++);
800 // to provide warning
801 if (!isWarning) SetErrorCode(OK);
805 //=============================================================================
809 //=============================================================================
810 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::MakeExplode
811 (Handle(GEOM_Object) theShape,
812 const Standard_Integer theShapeType,
813 const Standard_Boolean isSorted,
814 const Standard_Boolean isOldSorting)
818 if (theShape.IsNull()) return NULL;
819 TopoDS_Shape aShape = theShape->GetValue();
820 if (aShape.IsNull()) return NULL;
822 Handle(GEOM_Function) aMainShape = theShape->GetLastFunction();
824 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
825 Handle(GEOM_Object) anObj;
826 TopTools_MapOfShape mapShape;
827 TopTools_ListOfShape listShape;
829 if (aShape.ShapeType() == TopAbs_COMPOUND &&
830 (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
831 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPSOLID ||
832 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPOUND)) {
833 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
834 for (; It.More(); It.Next()) {
835 if (mapShape.Add(It.Value())) {
836 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
837 TopAbs_ShapeEnum(theShapeType) == It.Value().ShapeType()) {
838 listShape.Append(It.Value());
843 TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
844 for (; exp.More(); exp.Next())
845 if (mapShape.Add(exp.Current()))
846 listShape.Append(exp.Current());
849 if (listShape.IsEmpty()) {
850 //SetErrorCode("The given shape has no sub-shapes of the requested type");
851 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
856 SortShapes(listShape, isOldSorting);
858 TopTools_IndexedMapOfShape anIndices;
859 TopExp::MapShapes(aShape, anIndices);
860 Handle(TColStd_HArray1OfInteger) anArray;
862 TopTools_ListIteratorOfListOfShape itSub (listShape);
863 TCollection_AsciiString anAsciiList, anEntry;
864 for (int index = 1; itSub.More(); itSub.Next(), ++index)
866 TopoDS_Shape aValue = itSub.Value();
867 anArray = new TColStd_HArray1OfInteger(1,1);
868 anArray->SetValue(1, anIndices.FindIndex(aValue));
870 //anObj = GetEngine()->AddSubShape(theShape, anArray);
872 anObj = GetEngine()->AddObject(GetDocID(), GEOM_SUBSHAPE);
873 Handle(GEOM_Function) aFunction = anObj->AddFunction(GEOM_Object::GetSubShapeID(), 1);
874 if (aFunction.IsNull()) return aSeq;
876 GEOM_ISubShape aSSI (aFunction);
877 aSSI.SetMainShape(aMainShape);
878 aSSI.SetIndices(anArray);
880 // Set function value directly, as we know it.
881 // Usage of Solver here would lead to significant loss of time,
882 // because GEOM_SubShapeDriver will build TopTools_IndexedMapOfShape
883 // on the main shape for each being calculated sub-shape separately.
884 aFunction->SetValue(aValue);
887 if (!anObj.IsNull()) {
890 // for python command
891 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
892 anAsciiList += anEntry;
897 //Make a Python command
898 anAsciiList.Trunc(anAsciiList.Length() - 1);
900 GEOM::TPythonDump pd (aMainShape, /*append=*/true);
901 pd << "[" << anAsciiList.ToCString();
903 pd << "] = geompy.SubShapeAllSorted" << (isOldSorting ? "(" : "Centres(");
905 pd << "] = geompy.SubShapeAll(";
906 pd << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
913 //=============================================================================
917 //=============================================================================
918 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::SubShapeAllIDs
919 (Handle(GEOM_Object) theShape,
920 const Standard_Integer theShapeType,
921 const Standard_Boolean isSorted,
922 const Standard_Boolean isOldSorting)
926 if (theShape.IsNull()) return NULL;
927 TopoDS_Shape aShape = theShape->GetValue();
928 if (aShape.IsNull()) return NULL;
930 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
931 TopTools_MapOfShape mapShape;
932 TopTools_ListOfShape listShape;
934 if (aShape.ShapeType() == TopAbs_COMPOUND &&
935 (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
936 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPSOLID ||
937 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPOUND)) {
938 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
939 for (; It.More(); It.Next()) {
940 if (mapShape.Add(It.Value())) {
941 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
942 TopAbs_ShapeEnum(theShapeType) == It.Value().ShapeType()) {
943 listShape.Append(It.Value());
948 TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
949 for (; exp.More(); exp.Next())
950 if (mapShape.Add(exp.Current()))
951 listShape.Append(exp.Current());
954 if (listShape.IsEmpty()) {
955 //SetErrorCode("The given shape has no sub-shapes of the requested type");
956 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
961 SortShapes(listShape, isOldSorting);
963 TopTools_IndexedMapOfShape anIndices;
964 TopExp::MapShapes(aShape, anIndices);
965 Handle(TColStd_HArray1OfInteger) anArray;
967 TopTools_ListIteratorOfListOfShape itSub (listShape);
968 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
969 TopoDS_Shape aValue = itSub.Value();
970 aSeq->Append(anIndices.FindIndex(aValue));
973 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
975 //Make a Python command
976 GEOM::TPythonDump pd (aFunction, /*append=*/true);
977 pd << "listSubShapeIDs = geompy.SubShapeAll";
979 pd << "Sorted" << (isOldSorting ? "IDs(" : "CentresIDs(");
982 pd << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
988 //=============================================================================
992 //=============================================================================
993 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetSubShape
994 (Handle(GEOM_Object) theMainShape,
995 const Standard_Integer theID)
999 if (theMainShape.IsNull()) return NULL;
1001 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
1002 anArray->SetValue(1, theID);
1003 Handle(GEOM_Object) anObj = GetEngine()->AddSubShape(theMainShape, anArray,true);
1004 if (anObj.IsNull()) {
1005 SetErrorCode("Can not get a sub-shape with the given ID");
1009 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1011 //Make a Python command
1012 GEOM::TPythonDump(aFunction) << anObj << " = geompy.GetSubShape("
1013 << theMainShape << ", [" << theID << "])";
1019 //=============================================================================
1023 //=============================================================================
1024 Standard_Integer GEOMImpl_IShapesOperations::GetSubShapeIndex (Handle(GEOM_Object) theMainShape,
1025 Handle(GEOM_Object) theSubShape)
1029 TopoDS_Shape aMainShape = theMainShape->GetValue();
1030 TopoDS_Shape aSubShape = theSubShape->GetValue();
1032 if (aMainShape.IsNull() || aSubShape.IsNull()) return -1;
1034 TopTools_IndexedMapOfShape anIndices;
1035 TopExp::MapShapes(aMainShape, anIndices);
1036 if (anIndices.Contains(aSubShape)) {
1038 return anIndices.FindIndex(aSubShape);
1044 //=============================================================================
1048 //=============================================================================
1049 Standard_Integer GEOMImpl_IShapesOperations::GetTopologyIndex (Handle(GEOM_Object) theMainShape,
1050 Handle(GEOM_Object) theSubShape)
1054 TopoDS_Shape aMainShape = theMainShape->GetValue();
1055 TopoDS_Shape aSubShape = theSubShape->GetValue();
1057 if (aMainShape.IsNull() || aSubShape.IsNull()) {
1058 SetErrorCode("Null argument shape given");
1063 if (aSubShape.ShapeType() == TopAbs_COMPOUND) {
1065 TopTools_ListOfShape CL;
1066 CL.Append(aMainShape);
1067 TopTools_ListIteratorOfListOfShape itC;
1068 for (itC.Initialize(CL); itC.More(); itC.Next()) {
1069 for (it.Initialize(itC.Value()); it.More(); it.Next()) {
1070 if (it.Value().ShapeType() == TopAbs_COMPOUND) {
1071 if (it.Value().IsSame(aSubShape))
1075 CL.Append(it.Value());
1080 TopExp_Explorer anExp (aMainShape, aSubShape.ShapeType());
1081 TopTools_MapOfShape M;
1082 for (; anExp.More(); anExp.Next()) {
1083 if (M.Add(anExp.Current())) {
1084 if (anExp.Current().IsSame(aSubShape))
1091 SetErrorCode("The sub-shape does not belong to the main shape");
1095 //=============================================================================
1097 * GetShapeTypeString
1099 //=============================================================================
1100 TCollection_AsciiString GEOMImpl_IShapesOperations::GetShapeTypeString (Handle(GEOM_Object) theShape)
1104 TCollection_AsciiString aTypeName ("Null Shape");
1106 TopoDS_Shape aShape = theShape->GetValue();
1107 if (aShape.IsNull())
1110 switch (aShape.ShapeType() )
1112 case TopAbs_COMPOUND:
1113 aTypeName = "Compound";
1115 case TopAbs_COMPSOLID:
1116 aTypeName = "Compound Solid";
1119 aTypeName = "Solid";
1122 aTypeName = "Shell";
1126 BRepAdaptor_Surface surf (TopoDS::Face(aShape));
1127 if (surf.GetType() == GeomAbs_Plane)
1128 aTypeName = "Plane";
1129 else if (surf.GetType() == GeomAbs_Cylinder)
1130 aTypeName = "Cylindrical Face";
1131 else if (surf.GetType() == GeomAbs_Sphere)
1132 aTypeName = "Spherical Face";
1133 else if (surf.GetType() == GeomAbs_Torus)
1134 aTypeName = "Toroidal Face";
1135 else if (surf.GetType() == GeomAbs_Cone)
1136 aTypeName = "Conical Face";
1138 aTypeName = "GEOM::FACE";
1146 BRepAdaptor_Curve curv (TopoDS::Edge(aShape));
1147 if (curv.GetType() == GeomAbs_Line) {
1148 if ((Abs(curv.FirstParameter()) >= 1E6) ||
1149 (Abs(curv.LastParameter()) >= 1E6))
1153 } else if (curv.GetType() == GeomAbs_Circle) {
1154 if (curv.IsClosed())
1155 aTypeName = "Circle";
1164 aTypeName = "Vertex";
1167 aTypeName = "Shape";
1170 aTypeName = "Shape of unknown type";
1176 //=============================================================================
1180 //=============================================================================
1181 Standard_Integer GEOMImpl_IShapesOperations::NumberOfSubShapes
1182 (Handle(GEOM_Object) theShape,
1183 const Standard_Integer theShapeType)
1186 Standard_Integer nbShapes = 0;
1188 if (theShape.IsNull()) return -1;
1189 TopoDS_Shape aShape = theShape->GetValue();
1190 if (aShape.IsNull()) return -1;
1193 TopTools_MapOfShape mapShape;
1195 if (aShape.ShapeType() == TopAbs_COMPOUND &&
1196 (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
1197 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPSOLID ||
1198 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPOUND)) {
1199 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
1200 for (; It.More(); It.Next()) {
1201 if (mapShape.Add(It.Value())) {
1202 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
1203 TopAbs_ShapeEnum(theShapeType) == It.Value().ShapeType()) {
1209 TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
1210 for (; exp.More(); exp.Next())
1211 if (mapShape.Add(exp.Current()))
1217 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
1220 int iType, nbTypes [TopAbs_SHAPE];
1221 for (iType = 0; iType < TopAbs_SHAPE; ++iType)
1223 nbTypes[aShape.ShapeType()]++;
1225 TopTools_MapOfShape aMapOfShape;
1226 aMapOfShape.Add(aShape);
1227 TopTools_ListOfShape aListOfShape;
1228 aListOfShape.Append(aShape);
1230 TopTools_ListIteratorOfListOfShape itL (aListOfShape);
1231 for (; itL.More(); itL.Next()) {
1232 TopoDS_Iterator it (itL.Value());
1233 for (; it.More(); it.Next()) {
1234 TopoDS_Shape s = it.Value();
1235 if (aMapOfShape.Add(s)) {
1236 aListOfShape.Append(s);
1237 nbTypes[s.ShapeType()]++;
1242 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE)
1243 nbShapes = aMapOfShape.Extent();
1245 nbShapes = nbTypes[theShapeType];
1247 catch (Standard_Failure) {
1248 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1249 SetErrorCode(aFail->GetMessageString());
1257 //=============================================================================
1261 //=============================================================================
1262 Handle(GEOM_Object) GEOMImpl_IShapesOperations::ReverseShape(Handle(GEOM_Object) theShape)
1266 if (theShape.IsNull()) return NULL;
1268 //Add a new reversed object
1269 Handle(GEOM_Object) aReversed = GetEngine()->AddObject(GetDocID(), theShape->GetType());
1271 //Add a new Revese function
1272 Handle(GEOM_Function) aFunction;
1273 aFunction = aReversed->AddFunction(GEOMImpl_ShapeDriver::GetID(), REVERSE_ORIENTATION);
1274 if (aFunction.IsNull()) return NULL;
1276 //Check if the function is set correctly
1277 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
1279 GEOMImpl_IShapes aSI (aFunction);
1281 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
1282 if (aRefShape.IsNull()) return NULL;
1284 aSI.SetBase(aRefShape);
1286 //Compute the sub-shape value
1288 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
1291 if (!GetSolver()->ComputeFunction(aFunction)) {
1292 SetErrorCode("Shape driver failed to reverse shape");
1296 catch (Standard_Failure) {
1297 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1298 SetErrorCode(aFail->GetMessageString());
1302 //Make a Python command
1303 GEOM::TPythonDump(aFunction) << aReversed
1304 << " = geompy.ChangeOrientation(" << theShape << ")";
1310 //=============================================================================
1314 //=============================================================================
1315 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetFreeFacesIDs
1316 (Handle(GEOM_Object) theShape)
1320 if (theShape.IsNull()) return NULL;
1321 TopoDS_Shape aShape = theShape->GetValue();
1322 if (aShape.IsNull()) return NULL;
1324 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
1326 TopTools_IndexedDataMapOfShapeListOfShape mapFaceBlocks;
1327 GEOMImpl_Block6Explorer::MapShapesAndAncestors
1328 (aShape, TopAbs_FACE, TopAbs_SOLID, mapFaceBlocks);
1330 Standard_Integer ind = 1, nbFaces = mapFaceBlocks.Extent();
1333 SetErrorCode("The given shape has no faces");
1337 TopTools_IndexedMapOfShape anIndices;
1338 TopExp::MapShapes(aShape, anIndices);
1340 Standard_Integer id;
1341 for (; ind <= nbFaces; ind++) {
1342 if (mapFaceBlocks.FindFromIndex(ind).Extent() != 2) {
1343 id = anIndices.FindIndex(mapFaceBlocks.FindKey(ind));
1348 //The explode doesn't change object so no new function is required.
1349 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
1351 //Make a Python command
1352 GEOM::TPythonDump(aFunction, /*append=*/true)
1353 << "listFreeFacesIDs = geompy.GetFreeFacesIDs(" << theShape << ")";
1359 //=======================================================================
1360 //function : GetSharedShapes
1362 //=======================================================================
1363 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetSharedShapes
1364 (Handle(GEOM_Object) theShape1,
1365 Handle(GEOM_Object) theShape2,
1366 const Standard_Integer theShapeType)
1370 if (theShape1.IsNull() || theShape2.IsNull()) return NULL;
1372 TopoDS_Shape aShape1 = theShape1->GetValue();
1373 TopoDS_Shape aShape2 = theShape2->GetValue();
1375 if (aShape1.IsNull() || aShape2.IsNull()) return NULL;
1377 TopTools_IndexedMapOfShape anIndices;
1378 TopExp::MapShapes(aShape1, anIndices);
1379 Handle(TColStd_HArray1OfInteger) anArray;
1381 TopTools_IndexedMapOfShape mapShape1;
1382 TopExp::MapShapes(aShape1, TopAbs_ShapeEnum(theShapeType), mapShape1);
1384 Handle(GEOM_Object) anObj;
1385 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1386 TCollection_AsciiString anAsciiList, anEntry;
1388 TopTools_MapOfShape mapShape2;
1389 TopExp_Explorer exp (aShape2, TopAbs_ShapeEnum(theShapeType));
1390 for (; exp.More(); exp.Next()) {
1391 TopoDS_Shape aSS = exp.Current();
1392 if (mapShape2.Add(aSS) && mapShape1.Contains(aSS)) {
1393 anArray = new TColStd_HArray1OfInteger(1,1);
1394 anArray->SetValue(1, anIndices.FindIndex(aSS));
1395 anObj = GetEngine()->AddSubShape(theShape1, anArray);
1396 aSeq->Append(anObj);
1398 // for python command
1399 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
1400 anAsciiList += anEntry;
1405 if (aSeq->IsEmpty()) {
1406 SetErrorCode("The given shapes have no shared sub-shapes of the requested type");
1410 //Make a Python command
1411 anAsciiList.Trunc(anAsciiList.Length() - 1);
1413 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1415 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
1416 << "] = geompy.GetSharedShapes(" << theShape1 << ", "
1417 << theShape2 << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
1423 //=======================================================================
1424 //function : GetSharedShapes
1426 //=======================================================================
1427 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetSharedShapes
1428 (std::list<Handle(GEOM_Object)> theShapes,
1429 const Standard_Integer theShapeType)
1433 int aLen = theShapes.size();
1434 if (aLen < 1) return NULL;
1437 std::list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
1439 Handle(GEOM_Object) aMainObj = (*it++);
1440 Handle(GEOM_Function) aMainShape = aMainObj->GetLastFunction();
1441 if (aMainShape.IsNull()) {
1442 SetErrorCode("NULL shape for GetSharedShapes");
1446 TopoDS_Shape aShape1 = aMainShape->GetValue();
1447 if (aShape1.IsNull()) return NULL;
1449 TopTools_IndexedMapOfShape anIndices;
1450 TopExp::MapShapes(aShape1, anIndices);
1452 TopTools_IndexedMapOfShape mapSelected;
1453 TopExp::MapShapes(aShape1, TopAbs_ShapeEnum(theShapeType), mapSelected);
1455 // Find shared shapes
1457 TopoDS_Compound aCurrSelection;
1459 for (; it != theShapes.end(); it++, ind++) {
1460 Handle(GEOM_Function) aRefShape = (*it)->GetLastFunction();
1461 if (aRefShape.IsNull()) {
1462 SetErrorCode("NULL shape for GetSharedShapes");
1466 TopoDS_Compound aCompound;
1467 B.MakeCompound(aCompound);
1469 TopoDS_Shape aShape2 = aRefShape->GetValue();
1470 if (aShape2.IsNull()) return NULL;
1472 TopTools_MapOfShape mapShape2;
1473 TopExp_Explorer exp (aShape2, TopAbs_ShapeEnum(theShapeType));
1474 for (; exp.More(); exp.Next()) {
1475 TopoDS_Shape aSS = exp.Current();
1476 if (mapShape2.Add(aSS) && mapSelected.Contains(aSS)) {
1477 B.Add(aCompound, aSS);
1481 mapSelected.Clear();
1482 TopExp::MapShapes(aCompound, TopAbs_ShapeEnum(theShapeType), mapSelected);
1483 aCurrSelection = aCompound;
1486 // Create GEOM_Object for each found shared shape (collected in aCurrSelection)
1487 Handle(GEOM_Object) anObj;
1488 Handle(TColStd_HArray1OfInteger) anArray;
1489 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1490 TCollection_AsciiString anAsciiList, anEntry;
1492 TopoDS_Iterator itSel (aCurrSelection, Standard_True, Standard_True);
1493 for (; itSel.More(); itSel.Next()) {
1494 anArray = new TColStd_HArray1OfInteger(1,1);
1495 anArray->SetValue(1, anIndices.FindIndex(itSel.Value()));
1496 anObj = GetEngine()->AddSubShape(aMainObj, anArray);
1497 aSeq->Append(anObj);
1499 // for python command
1500 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
1501 anAsciiList += anEntry;
1505 if (aSeq->IsEmpty()) {
1506 SetErrorCode("The given shapes have no shared sub-shapes of the requested type");
1510 // Make a Python command
1511 anAsciiList.Trunc(anAsciiList.Length() - 1);
1513 GEOM::TPythonDump pd (aMainShape, /*append=*/true);
1514 pd << "[" << anAsciiList.ToCString()
1515 << "] = geompy.GetSharedShapesMulti([";
1517 it = theShapes.begin();
1519 while (it != theShapes.end()) {
1520 pd << ", " << (*it++);
1523 pd << "], " << TopAbs_ShapeEnum(theShapeType) << ")";
1529 //=============================================================================
1533 //=============================================================================
1534 static GEOM::TPythonDump& operator<< (GEOM::TPythonDump& theDump,
1535 const GEOMAlgo_State theState)
1538 case GEOMAlgo_ST_IN:
1539 theDump << "geompy.GEOM.ST_IN";
1541 case GEOMAlgo_ST_OUT:
1542 theDump << "geompy.GEOM.ST_OUT";
1544 case GEOMAlgo_ST_ON:
1545 theDump << "geompy.GEOM.ST_ON";
1547 case GEOMAlgo_ST_ONIN:
1548 theDump << "geompy.GEOM.ST_ONIN";
1550 case GEOMAlgo_ST_ONOUT:
1551 theDump << "geompy.GEOM.ST_ONOUT";
1554 theDump << "geompy.GEOM.ST_UNKNOWN";
1560 //=======================================================================
1561 //function : checkTypeShapesOn
1563 * \brief Checks if theShapeType parameter of GetShapesOnXXX() is OK
1564 * \param theShapeType - the shape type to check
1565 * \retval bool - result of the check
1567 //=======================================================================
1568 bool GEOMImpl_IShapesOperations::checkTypeShapesOn(const Standard_Integer theShapeType)
1570 if (theShapeType != TopAbs_VERTEX &&
1571 theShapeType != TopAbs_EDGE &&
1572 theShapeType != TopAbs_FACE &&
1573 theShapeType != TopAbs_SOLID) {
1574 SetErrorCode("Only solids, vertices, edges or faces can be found by this method");
1580 //=======================================================================
1581 //function : makePlane
1583 * \brief Creates Geom_Plane
1584 * \param theAx1 - shape object defining plane parameters
1585 * \retval Handle(Geom_Surface) - resulting surface
1587 //=======================================================================
1588 Handle(Geom_Surface) GEOMImpl_IShapesOperations::makePlane(const TopoDS_Shape& anAx1)
1590 if (anAx1.ShapeType() != TopAbs_EDGE) return NULL;
1591 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
1592 TopoDS_Vertex V1, V2;
1593 TopExp::Vertices(anEdge, V1, V2, Standard_True);
1594 if (V1.IsNull() || V2.IsNull()) {
1595 SetErrorCode("Bad edge given for the plane normal vector");
1598 gp_Pnt aLoc = BRep_Tool::Pnt(V1);
1599 gp_Vec aVec (aLoc, BRep_Tool::Pnt(V2));
1600 if (aVec.Magnitude() < Precision::Confusion()) {
1601 SetErrorCode("Vector with null magnitude given");
1604 return new Geom_Plane(aLoc, aVec);
1607 //=======================================================================
1608 //function : makeCylinder
1610 * \brief Creates Geom_CylindricalSurface
1611 * \param theAx1 - edge defining cylinder axis
1612 * \param theRadius - cylinder radius
1613 * \retval Handle(Geom_Surface) - resulting surface
1615 //=======================================================================
1616 Handle(Geom_Surface) GEOMImpl_IShapesOperations::makeCylinder(const TopoDS_Shape& anAxis,
1617 const Standard_Real theRadius)
1619 //Axis of the cylinder
1620 if (anAxis.ShapeType() != TopAbs_EDGE) {
1621 SetErrorCode("Not an edge given for the axis");
1624 TopoDS_Edge anEdge = TopoDS::Edge(anAxis);
1625 TopoDS_Vertex V1, V2;
1626 TopExp::Vertices(anEdge, V1, V2, Standard_True);
1627 if (V1.IsNull() || V2.IsNull()) {
1628 SetErrorCode("Bad edge given for the axis");
1631 gp_Pnt aLoc = BRep_Tool::Pnt(V1);
1632 gp_Vec aVec (aLoc, BRep_Tool::Pnt(V2));
1633 if (aVec.Magnitude() < Precision::Confusion()) {
1634 SetErrorCode("Vector with null magnitude given");
1638 gp_Ax3 anAx3 (aLoc, aVec);
1639 return new Geom_CylindricalSurface(anAx3, theRadius);
1642 //=======================================================================
1643 //function : getShapesOnBoxIDs
1645 * \brief Find IDs of subshapes complying with given status about surface
1646 * \param theBox - the box to check state of subshapes against
1647 * \param theShape - the shape to explore
1648 * \param theShapeType - type of subshape of theShape
1649 * \param theState - required state
1650 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1652 //=======================================================================
1653 Handle(TColStd_HSequenceOfInteger)
1654 GEOMImpl_IShapesOperations::getShapesOnBoxIDs(const Handle(GEOM_Object)& theBox,
1655 const Handle(GEOM_Object)& theShape,
1656 const Standard_Integer theShapeType,
1657 GEOMAlgo_State theState)
1659 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
1661 TopoDS_Shape aBox = theBox->GetValue();
1662 TopoDS_Shape aShape = theShape->GetValue();
1664 // Check presence of triangulation, build if need
1665 if (!CheckTriangulation(aShape)) {
1666 SetErrorCode("Cannot build triangulation on the shape");
1671 GEOMAlgo_FinderShapeOn2 aFinder;
1672 Standard_Real aTol = 0.0001; // default value
1674 Handle(GEOMAlgo_ClsfBox) aClsfBox = new GEOMAlgo_ClsfBox;
1675 aClsfBox->SetBox(aBox);
1677 aFinder.SetShape(aShape);
1678 aFinder.SetTolerance(aTol);
1679 aFinder.SetClsf(aClsfBox);
1680 aFinder.SetShapeType( (TopAbs_ShapeEnum)theShapeType );
1681 aFinder.SetState(theState);
1684 // Interprete results
1685 Standard_Integer iErr = aFinder.ErrorStatus();
1686 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
1688 MESSAGE(" iErr : " << iErr);
1689 TCollection_AsciiString aMsg (" iErr : ");
1690 aMsg += TCollection_AsciiString(iErr);
1694 Standard_Integer iWrn = aFinder.WarningStatus();
1695 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
1697 MESSAGE(" *** iWrn : " << iWrn);
1700 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
1702 if (listSS.Extent() < 1) {
1703 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
1704 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
1708 // Fill sequence of object IDs
1709 aSeqOfIDs = new TColStd_HSequenceOfInteger;
1711 TopTools_IndexedMapOfShape anIndices;
1712 TopExp::MapShapes(aShape, anIndices);
1714 TopTools_ListIteratorOfListOfShape itSub (listSS);
1715 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
1716 int id = anIndices.FindIndex(itSub.Value());
1717 aSeqOfIDs->Append(id);
1723 //=======================================================================
1724 //function : GetShapesOnBoxIDs
1726 * \brief Find subshapes complying with given status about surface
1727 * \param theBox - the box to check state of subshapes against
1728 * \param theShape - the shape to explore
1729 * \param theShapeType - type of subshape of theShape
1730 * \param theState - required state
1731 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1733 //=======================================================================
1734 Handle(TColStd_HSequenceOfInteger)
1735 GEOMImpl_IShapesOperations::GetShapesOnBoxIDs(const Handle(GEOM_Object)& theBox,
1736 const Handle(GEOM_Object)& theShape,
1737 const Standard_Integer theShapeType,
1738 GEOMAlgo_State theState)
1740 // Find subshapes ids
1741 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
1742 getShapesOnBoxIDs (theBox, theShape, theShapeType, theState);
1743 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
1746 // The GetShapesOnBox() doesn't change object so no new function is required.
1747 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theBox)->GetLastFunction();
1749 // Make a Python command
1750 GEOM::TPythonDump(aFunction)
1751 << "listShapesOnBoxIDs = geompy.GetShapesOnBoxIDs("
1754 << TopAbs_ShapeEnum(theShapeType) << ", "
1761 //=======================================================================
1762 //function : GetShapesOnBox
1764 * \brief Find subshapes complying with given status about surface
1765 * \param theBox - the box to check state of subshapes against
1766 * \param theShape - the shape to explore
1767 * \param theShapeType - type of subshape of theShape
1768 * \param theState - required state
1769 * \retval Handle(TColStd_HSequenceOfTransient) - found subshapes
1771 //=======================================================================
1772 Handle(TColStd_HSequenceOfTransient)
1773 GEOMImpl_IShapesOperations::GetShapesOnBox(const Handle(GEOM_Object)& theBox,
1774 const Handle(GEOM_Object)& theShape,
1775 const Standard_Integer theShapeType,
1776 GEOMAlgo_State theState)
1778 // Find subshapes ids
1779 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
1780 getShapesOnBoxIDs (theBox, theShape, theShapeType, theState);
1781 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
1784 // Find objects by indices
1785 TCollection_AsciiString anAsciiList;
1786 Handle(TColStd_HSequenceOfTransient) aSeq;
1787 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
1788 if ( aSeq.IsNull() || aSeq->IsEmpty() )
1791 // Make a Python command
1793 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
1794 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1796 GEOM::TPythonDump(aFunction)
1797 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnBox("
1800 << TopAbs_ShapeEnum(theShapeType) << ", "
1807 //=======================================================================
1808 //function : getShapesOnShapeIDs
1810 * \brief Find IDs of subshapes complying with given status about surface
1811 * \param theCheckShape - the shape to check state of subshapes against
1812 * \param theShape - the shape to explore
1813 * \param theShapeType - type of subshape of theShape
1814 * \param theState - required state
1815 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1817 //=======================================================================
1818 Handle(TColStd_HSequenceOfInteger)
1819 GEOMImpl_IShapesOperations::getShapesOnShapeIDs
1820 (const Handle(GEOM_Object)& theCheckShape,
1821 const Handle(GEOM_Object)& theShape,
1822 const Standard_Integer theShapeType,
1823 GEOMAlgo_State theState)
1825 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
1827 TopoDS_Shape aCheckShape = theCheckShape->GetValue();
1828 TopoDS_Shape aShape = theShape->GetValue();
1829 TopTools_ListOfShape res;
1831 // Check presence of triangulation, build if need
1832 if (!CheckTriangulation(aShape)) {
1833 SetErrorCode("Cannot build triangulation on the shape");
1838 GEOMAlgo_FinderShapeOn2 aFinder;
1839 Standard_Real aTol = 0.0001; // default value
1841 Handle(GEOMAlgo_ClsfSolid) aClsfSolid = new GEOMAlgo_ClsfSolid;
1842 aClsfSolid->SetShape(aCheckShape);
1844 aFinder.SetShape(aShape);
1845 aFinder.SetTolerance(aTol);
1846 aFinder.SetClsf(aClsfSolid);
1847 aFinder.SetShapeType( (TopAbs_ShapeEnum)theShapeType );
1848 aFinder.SetState(theState);
1851 // Interprete results
1852 Standard_Integer iErr = aFinder.ErrorStatus();
1853 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
1856 SetErrorCode("theCheckShape must be a solid");
1859 MESSAGE(" iErr : " << iErr);
1860 TCollection_AsciiString aMsg (" iErr : ");
1861 aMsg += TCollection_AsciiString(iErr);
1866 Standard_Integer iWrn = aFinder.WarningStatus();
1867 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
1869 MESSAGE(" *** iWrn : " << iWrn);
1872 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
1874 if (listSS.Extent() < 1) {
1875 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
1876 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
1879 // Fill sequence of object IDs
1880 aSeqOfIDs = new TColStd_HSequenceOfInteger;
1882 TopTools_IndexedMapOfShape anIndices;
1883 TopExp::MapShapes(aShape, anIndices);
1885 TopTools_ListIteratorOfListOfShape itSub (listSS);
1886 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
1887 int id = anIndices.FindIndex(itSub.Value());
1888 aSeqOfIDs->Append(id);
1894 //=======================================================================
1895 //function : GetShapesOnShapeIDs
1897 * \brief Find subshapes complying with given status about surface
1898 * \param theCheckShape - the shape to check state of subshapes against
1899 * \param theShape - the shape to explore
1900 * \param theShapeType - type of subshape of theShape
1901 * \param theState - required state
1902 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1904 //=======================================================================
1905 Handle(TColStd_HSequenceOfInteger)
1906 GEOMImpl_IShapesOperations::GetShapesOnShapeIDs
1907 (const Handle(GEOM_Object)& theCheckShape,
1908 const Handle(GEOM_Object)& theShape,
1909 const Standard_Integer theShapeType,
1910 GEOMAlgo_State theState)
1912 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
1913 getShapesOnShapeIDs (theCheckShape, theShape, theShapeType, theState);
1915 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
1918 // The GetShapesOnShape() doesn't change object so no new function is required.
1919 Handle(GEOM_Function) aFunction =
1920 GEOM::GetCreatedLast(theShape,theCheckShape)->GetLastFunction();
1922 // Make a Python command
1923 GEOM::TPythonDump(aFunction)
1924 << "listShapesOnBoxIDs = geompy.GetShapesOnShapeIDs("
1925 << theCheckShape << ", "
1927 << TopAbs_ShapeEnum(theShapeType) << ", "
1934 //=======================================================================
1935 //function : GetShapesOnShape
1937 * \brief Find subshapes complying with given status about surface
1938 * \param theCheckShape - the shape to check state of subshapes against
1939 * \param theShape - the shape to explore
1940 * \param theShapeType - type of subshape of theShape
1941 * \param theState - required state
1942 * \retval Handle(TColStd_HSequenceOfTransient) - found subshapes
1944 //=======================================================================
1945 Handle(TColStd_HSequenceOfTransient)
1946 GEOMImpl_IShapesOperations::GetShapesOnShape
1947 (const Handle(GEOM_Object)& theCheckShape,
1948 const Handle(GEOM_Object)& theShape,
1949 const Standard_Integer theShapeType,
1950 GEOMAlgo_State theState)
1952 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
1953 getShapesOnShapeIDs (theCheckShape, theShape, theShapeType, theState);
1954 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
1957 // Find objects by indices
1958 TCollection_AsciiString anAsciiList;
1959 Handle(TColStd_HSequenceOfTransient) aSeq;
1960 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
1962 if ( aSeq.IsNull() || aSeq->IsEmpty() )
1965 // Make a Python command
1967 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
1968 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1970 GEOM::TPythonDump(aFunction)
1971 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnShape("
1972 << theCheckShape << ", "
1974 << TopAbs_ShapeEnum(theShapeType) << ", "
1981 //=======================================================================
1982 //function : GetShapesOnShapeAsCompound
1983 //=======================================================================
1984 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetShapesOnShapeAsCompound
1985 (const Handle(GEOM_Object)& theCheckShape,
1986 const Handle(GEOM_Object)& theShape,
1987 const Standard_Integer theShapeType,
1988 GEOMAlgo_State theState)
1990 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
1991 getShapesOnShapeIDs (theCheckShape, theShape, theShapeType, theState);
1993 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
1996 // Find objects by indices
1997 TCollection_AsciiString anAsciiList;
1998 Handle(TColStd_HSequenceOfTransient) aSeq;
1999 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
2001 if ( aSeq.IsNull() || aSeq->IsEmpty() )
2004 TopoDS_Compound aCompound;
2006 B.MakeCompound(aCompound);
2008 for(; i<=aSeq->Length(); i++) {
2009 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(aSeq->Value(i));
2010 TopoDS_Shape aShape_i = anObj->GetValue();
2011 B.Add(aCompound,aShape_i);
2014 //Add a new result object
2015 Handle(GEOM_Object) aRes = GetEngine()->AddObject(GetDocID(), GEOM_SHAPES_ON_SHAPE);
2016 Handle(GEOM_Function) aFunction =
2017 aRes->AddFunction(GEOMImpl_ShapeDriver::GetID(), SHAPES_ON_SHAPE);
2018 aFunction->SetValue(aCompound);
2020 GEOM::TPythonDump(aFunction)
2021 << aRes << " = geompy.GetShapesOnShapeAsCompound("
2022 << theCheckShape << ", "
2024 << TopAbs_ShapeEnum(theShapeType) << ", "
2032 //=======================================================================
2033 //function : getShapesOnSurfaceIDs
2035 * \brief Find IDs of subshapes complying with given status about surface
2036 * \param theSurface - the surface to check state of subshapes against
2037 * \param theShape - the shape to explore
2038 * \param theShapeType - type of subshape of theShape
2039 * \param theState - required state
2040 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
2042 //=======================================================================
2043 Handle(TColStd_HSequenceOfInteger)
2044 GEOMImpl_IShapesOperations::getShapesOnSurfaceIDs(const Handle(Geom_Surface)& theSurface,
2045 const TopoDS_Shape& theShape,
2046 TopAbs_ShapeEnum theShapeType,
2047 GEOMAlgo_State theState)
2049 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
2051 // Check presence of triangulation, build if need
2052 if (!CheckTriangulation(theShape)) {
2053 SetErrorCode("Cannot build triangulation on the shape");
2058 GEOMAlgo_FinderShapeOn1 aFinder;
2059 Standard_Real aTol = 0.0001; // default value
2061 aFinder.SetShape(theShape);
2062 aFinder.SetTolerance(aTol);
2063 aFinder.SetSurface(theSurface);
2064 aFinder.SetShapeType(theShapeType);
2065 aFinder.SetState(theState);
2067 // Sets the minimal number of inner points for the faces that do not have own
2068 // inner points at all (for e.g. rectangular planar faces have just 2 triangles).
2070 aFinder.SetNbPntsMin(3);
2071 // Sets the maximal number of inner points for edges or faces.
2072 // It is usefull for the cases when this number is very big (e.g =2000) to improve
2073 // the performance. If this value =0, all inner points will be taken into account.
2075 aFinder.SetNbPntsMax(100);
2079 // Interprete results
2080 Standard_Integer iErr = aFinder.ErrorStatus();
2081 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
2083 MESSAGE(" iErr : " << iErr);
2084 TCollection_AsciiString aMsg (" iErr : ");
2085 aMsg += TCollection_AsciiString(iErr);
2089 Standard_Integer iWrn = aFinder.WarningStatus();
2090 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
2092 MESSAGE(" *** iWrn : " << iWrn);
2095 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
2097 if (listSS.Extent() < 1) {
2098 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
2099 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
2103 // Fill sequence of object IDs
2104 aSeqOfIDs = new TColStd_HSequenceOfInteger;
2106 TopTools_IndexedMapOfShape anIndices;
2107 TopExp::MapShapes(theShape, anIndices);
2109 TopTools_ListIteratorOfListOfShape itSub (listSS);
2110 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
2111 int id = anIndices.FindIndex(itSub.Value());
2112 aSeqOfIDs->Append(id);
2118 //=======================================================================
2119 //function : getObjectsShapesOn
2121 * \brief Find shape objects and their entries by their ids
2122 * \param theShapeIDs - incoming shape ids
2123 * \param theShapeEntries - outgoing entries like "entry1, entry2, ..."
2124 * \retval Handle(TColStd_HSequenceOfTransient) - found shape objects
2126 //=======================================================================
2127 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::
2128 getObjectsShapesOn(const Handle(GEOM_Object)& theShape,
2129 const Handle(TColStd_HSequenceOfInteger)& theShapeIDs,
2130 TCollection_AsciiString & theShapeEntries)
2132 Handle(TColStd_HSequenceOfTransient) aSeq;
2134 if ( !theShapeIDs.IsNull() && theShapeIDs->Length() > 0 )
2136 aSeq = new TColStd_HSequenceOfTransient;
2137 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
2138 TCollection_AsciiString anEntry;
2139 for ( int i = 1; i <= theShapeIDs->Length(); ++i )
2141 anArray->SetValue(1, theShapeIDs->Value( i ));
2142 Handle(GEOM_Object) anObj = GetEngine()->AddSubShape(theShape, anArray);
2143 aSeq->Append( anObj );
2145 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
2146 if ( i != 1 ) theShapeEntries += ",";
2147 theShapeEntries += anEntry;
2153 //=======================================================================
2154 //function : getShapesOnSurface
2156 * \brief Find subshapes complying with given status about surface
2157 * \param theSurface - the surface to check state of subshapes against
2158 * \param theShape - the shape to explore
2159 * \param theShapeType - type of subshape of theShape
2160 * \param theState - required state
2161 * \param theShapeEntries - outgoing entries like "entry1, entry2, ..."
2162 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
2164 //=======================================================================
2165 Handle(TColStd_HSequenceOfTransient)
2166 GEOMImpl_IShapesOperations::getShapesOnSurface(const Handle(Geom_Surface)& theSurface,
2167 const Handle(GEOM_Object)& theShape,
2168 TopAbs_ShapeEnum theShapeType,
2169 GEOMAlgo_State theState,
2170 TCollection_AsciiString & theShapeEntries)
2172 // Find subshapes ids
2173 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2174 getShapesOnSurfaceIDs (theSurface, theShape->GetValue(), theShapeType, theState);
2175 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2178 return getObjectsShapesOn( theShape, aSeqOfIDs, theShapeEntries );
2181 //=============================================================================
2185 //=============================================================================
2186 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnPlane
2187 (const Handle(GEOM_Object)& theShape,
2188 const Standard_Integer theShapeType,
2189 const Handle(GEOM_Object)& theAx1,
2190 const GEOMAlgo_State theState)
2194 if (theShape.IsNull() || theAx1.IsNull()) return NULL;
2196 TopoDS_Shape aShape = theShape->GetValue();
2197 TopoDS_Shape anAx1 = theAx1->GetValue();
2199 if (aShape.IsNull() || anAx1.IsNull()) return NULL;
2201 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2202 if ( !checkTypeShapesOn( theShapeType ))
2206 Handle(Geom_Surface) aPlane = makePlane( anAx1 );
2207 if ( aPlane.IsNull() )
2211 TCollection_AsciiString anAsciiList;
2212 Handle(TColStd_HSequenceOfTransient) aSeq;
2213 aSeq = getShapesOnSurface( aPlane, theShape, aShapeType, theState, anAsciiList );
2214 if ( aSeq.IsNull() || aSeq->Length() == 0 )
2217 // Make a Python command
2219 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2220 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2222 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
2223 << "] = geompy.GetShapesOnPlane(" << theShape << ", "
2224 << aShapeType << ", " << theAx1 << ", " << theState << ")";
2230 //=============================================================================
2232 * GetShapesOnPlaneWithLocation
2234 //=============================================================================
2235 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnPlaneWithLocation
2236 (const Handle(GEOM_Object)& theShape,
2237 const Standard_Integer theShapeType,
2238 const Handle(GEOM_Object)& theAx1,
2239 const Handle(GEOM_Object)& thePnt,
2240 const GEOMAlgo_State theState)
2244 if (theShape.IsNull() || theAx1.IsNull() || thePnt.IsNull()) return NULL;
2246 TopoDS_Shape aShape = theShape->GetValue();
2247 TopoDS_Shape anAx1 = theAx1->GetValue();
2248 TopoDS_Shape anPnt = thePnt->GetValue();
2250 if (aShape.IsNull() || anAx1.IsNull() || anPnt.IsNull()) return NULL;
2252 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2253 if ( !checkTypeShapesOn( theShapeType ))
2257 if ( anAx1.ShapeType() != TopAbs_EDGE || anPnt.ShapeType() != TopAbs_VERTEX ) return NULL;
2258 TopoDS_Vertex V1, V2, V3;
2259 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
2260 TopExp::Vertices(anEdge, V1, V2, Standard_True);
2262 if (V1.IsNull() || V2.IsNull()) {
2263 SetErrorCode("Bad edge given for the plane normal vector");
2266 V3 = TopoDS::Vertex(anPnt);
2269 SetErrorCode("Bad vertex given for the plane location");
2272 gp_Pnt aLoc = BRep_Tool::Pnt(V3);
2273 gp_Vec aVec(BRep_Tool::Pnt(V1),BRep_Tool::Pnt(V2));
2275 if (aVec.Magnitude() < Precision::Confusion()) {
2276 SetErrorCode("Vector with null magnitude given");
2279 Handle(Geom_Surface) aPlane = new Geom_Plane(aLoc, aVec);
2281 if ( aPlane.IsNull() )
2285 TCollection_AsciiString anAsciiList;
2286 Handle(TColStd_HSequenceOfTransient) aSeq;
2287 aSeq = getShapesOnSurface( aPlane, theShape, aShapeType, theState, anAsciiList );
2288 if ( aSeq.IsNull() || aSeq->Length() == 0 )
2291 // Make a Python command
2293 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2294 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2296 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
2297 << "] = geompy.GetShapesOnPlaneWithLocation(" << theShape << ", "
2298 << aShapeType << ", " << theAx1 << ", "<< thePnt <<", " << theState << ")";
2304 //=============================================================================
2306 * GetShapesOnCylinder
2308 //=============================================================================
2309 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnCylinder
2310 (const Handle(GEOM_Object)& theShape,
2311 const Standard_Integer theShapeType,
2312 const Handle(GEOM_Object)& theAxis,
2313 const Standard_Real theRadius,
2314 const GEOMAlgo_State theState)
2318 if (theShape.IsNull() || theAxis.IsNull()) return NULL;
2320 TopoDS_Shape aShape = theShape->GetValue();
2321 TopoDS_Shape anAxis = theAxis->GetValue();
2323 if (aShape.IsNull() || anAxis.IsNull()) return NULL;
2325 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2326 if ( !checkTypeShapesOn( aShapeType ))
2329 // Create a cylinder surface
2330 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
2331 if ( aCylinder.IsNull() )
2335 TCollection_AsciiString anAsciiList;
2336 Handle(TColStd_HSequenceOfTransient) aSeq;
2337 aSeq = getShapesOnSurface( aCylinder, theShape, aShapeType, theState, anAsciiList );
2338 if ( aSeq.IsNull() || aSeq->Length() == 0 )
2341 // Make a Python command
2343 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2344 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2346 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
2347 << "] = geompy.GetShapesOnCylinder(" << theShape << ", " << aShapeType
2348 << ", " << theAxis << ", " << theRadius << ", " << theState << ")";
2354 //=============================================================================
2356 * GetShapesOnCylinderWithLocation
2358 //=============================================================================
2359 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnCylinderWithLocation
2360 (const Handle(GEOM_Object)& theShape,
2361 const Standard_Integer theShapeType,
2362 const Handle(GEOM_Object)& theAxis,
2363 const Handle(GEOM_Object)& thePnt,
2364 const Standard_Real theRadius,
2365 const GEOMAlgo_State theState)
2369 if (theShape.IsNull() || theAxis.IsNull() || thePnt.IsNull()) return NULL;
2371 TopoDS_Shape aShape = theShape->GetValue();
2372 TopoDS_Shape anAxis = theAxis->GetValue();
2373 TopoDS_Shape aPnt = thePnt->GetValue();
2375 if (aShape.IsNull() || anAxis.IsNull() || aPnt.IsNull()) return NULL;
2377 if (aPnt.ShapeType() != TopAbs_VERTEX )
2379 SetErrorCode("Bottom location point must be vertex");
2383 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2384 if ( !checkTypeShapesOn( aShapeType ))
2387 // Create a cylinder surface
2388 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
2389 if ( aCylinder.IsNull() )
2392 // translate the surface
2393 Handle(Geom_CylindricalSurface) aCylSurface =
2394 Handle(Geom_CylindricalSurface)::DownCast( aCylinder );
2395 if ( aCylSurface.IsNull() )
2397 SetErrorCode("Unexpected surface type instead of Geom_CylindricalSurface");
2400 gp_Pnt fromLoc = aCylSurface->Cylinder().Location();
2401 gp_Pnt toLoc = BRep_Tool::Pnt( TopoDS::Vertex( aPnt ));
2402 aCylinder->Translate( fromLoc, toLoc );
2405 TCollection_AsciiString anAsciiList;
2406 Handle(TColStd_HSequenceOfTransient) aSeq;
2407 aSeq = getShapesOnSurface( aCylinder, theShape, aShapeType, theState, anAsciiList );
2408 if ( aSeq.IsNull() || aSeq->Length() == 0 )
2411 // Make a Python command
2413 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2414 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2416 GEOM::TPythonDump(aFunction)
2417 << "[" << anAsciiList.ToCString()
2418 << "] = geompy.GetShapesOnCylinderWithLocation(" << theShape << ", " << aShapeType << ", "
2419 << theAxis << ", " << thePnt << ", " << theRadius << ", " << theState << ")";
2425 //=============================================================================
2429 //=============================================================================
2430 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnSphere
2431 (const Handle(GEOM_Object)& theShape,
2432 const Standard_Integer theShapeType,
2433 const Handle(GEOM_Object)& theCenter,
2434 const Standard_Real theRadius,
2435 const GEOMAlgo_State theState)
2439 if (theShape.IsNull() || theCenter.IsNull()) return NULL;
2441 TopoDS_Shape aShape = theShape->GetValue();
2442 TopoDS_Shape aCenter = theCenter->GetValue();
2444 if (aShape.IsNull() || aCenter.IsNull()) return NULL;
2446 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2447 if ( !checkTypeShapesOn( aShapeType ))
2450 // Center of the sphere
2451 if (aCenter.ShapeType() != TopAbs_VERTEX) return NULL;
2452 gp_Pnt aLoc = BRep_Tool::Pnt(TopoDS::Vertex(aCenter));
2454 gp_Ax3 anAx3 (aLoc, gp::DZ());
2455 Handle(Geom_SphericalSurface) aSphere =
2456 new Geom_SphericalSurface(anAx3, theRadius);
2459 TCollection_AsciiString anAsciiList;
2460 Handle(TColStd_HSequenceOfTransient) aSeq;
2461 aSeq = getShapesOnSurface( aSphere, theShape, aShapeType, theState, anAsciiList );
2462 if ( aSeq.IsNull() || aSeq->Length() == 0 )
2465 // Make a Python command
2467 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2468 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2470 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
2471 << "] = geompy.GetShapesOnSphere(" << theShape << ", " << aShapeType
2472 << ", " << theCenter << ", " << theRadius << ", " << theState << ")";
2478 //=============================================================================
2480 * GetShapesOnPlaneIDs
2482 //=============================================================================
2483 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnPlaneIDs
2484 (const Handle(GEOM_Object)& theShape,
2485 const Standard_Integer theShapeType,
2486 const Handle(GEOM_Object)& theAx1,
2487 const GEOMAlgo_State theState)
2491 if (theShape.IsNull() || theAx1.IsNull()) return NULL;
2493 TopoDS_Shape aShape = theShape->GetValue();
2494 TopoDS_Shape anAx1 = theAx1->GetValue();
2496 if (aShape.IsNull() || anAx1.IsNull()) return NULL;
2498 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2499 if ( !checkTypeShapesOn( aShapeType ))
2503 Handle(Geom_Surface) aPlane = makePlane( anAx1 );
2504 if ( aPlane.IsNull() )
2508 Handle(TColStd_HSequenceOfInteger) aSeq;
2509 aSeq = getShapesOnSurfaceIDs( aPlane, aShape, aShapeType, theState );
2511 // The GetShapesOnPlaneIDs() doesn't change object so no new function is required.
2512 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAx1)->GetLastFunction();
2514 // Make a Python command
2515 GEOM::TPythonDump(aFunction, /*append=*/true)
2516 << "listShapesOnPlane = geompy.GetShapesOnPlaneIDs"
2517 << "(" << theShape << "," << aShapeType << "," << theAx1 << "," << theState << ")";
2523 //=============================================================================
2525 * GetShapesOnPlaneWithLocationIDs
2527 //=============================================================================
2528 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnPlaneWithLocationIDs
2529 (const Handle(GEOM_Object)& theShape,
2530 const Standard_Integer theShapeType,
2531 const Handle(GEOM_Object)& theAx1,
2532 const Handle(GEOM_Object)& thePnt,
2533 const GEOMAlgo_State theState)
2537 if (theShape.IsNull() || theAx1.IsNull() || thePnt.IsNull()) return NULL;
2539 TopoDS_Shape aShape = theShape->GetValue();
2540 TopoDS_Shape anAx1 = theAx1->GetValue();
2541 TopoDS_Shape anPnt = thePnt->GetValue();
2543 if (aShape.IsNull() || anAx1.IsNull() || anPnt.IsNull()) return NULL;
2545 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2546 if ( !checkTypeShapesOn( aShapeType ))
2550 if (anAx1.ShapeType() != TopAbs_EDGE || anPnt.ShapeType() != TopAbs_VERTEX) return NULL;
2551 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
2552 TopoDS_Vertex V1, V2, V3;
2553 TopExp::Vertices(anEdge, V1, V2, Standard_True);
2554 if (V1.IsNull() || V2.IsNull()) {
2555 SetErrorCode("Bad edge given for the plane normal vector");
2558 V3 = TopoDS::Vertex(anPnt);
2560 SetErrorCode("Bad vertex given for the plane location");
2563 gp_Pnt aLoc = BRep_Tool::Pnt(V3);
2564 gp_Vec aVec(BRep_Tool::Pnt(V1),BRep_Tool::Pnt(V2));
2565 if (aVec.Magnitude() < Precision::Confusion()) {
2566 SetErrorCode("Vector with null magnitude given");
2570 Handle(Geom_Surface) aPlane = new Geom_Plane(aLoc, aVec);
2571 if ( aPlane.IsNull() )
2575 Handle(TColStd_HSequenceOfInteger) aSeq;
2576 aSeq = getShapesOnSurfaceIDs( aPlane, aShape, aShapeType, theState );
2578 // The GetShapesOnPlaneIDs() doesn't change object so no new function is required.
2579 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAx1)->GetLastFunction();
2581 // Make a Python command
2582 GEOM::TPythonDump(aFunction, /*append=*/true)
2583 << "listShapesOnPlane = geompy.GetShapesOnPlaneWithLocationIDs"
2584 << "(" << theShape << ", " << aShapeType << ", " << theAx1 << ", "<< thePnt << ", " << theState << ")";
2590 //=============================================================================
2592 * GetShapesOnCylinderIDs
2594 //=============================================================================
2595 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnCylinderIDs
2596 (const Handle(GEOM_Object)& theShape,
2597 const Standard_Integer theShapeType,
2598 const Handle(GEOM_Object)& theAxis,
2599 const Standard_Real theRadius,
2600 const GEOMAlgo_State theState)
2604 if (theShape.IsNull() || theAxis.IsNull()) return NULL;
2606 TopoDS_Shape aShape = theShape->GetValue();
2607 TopoDS_Shape anAxis = theAxis->GetValue();
2609 if (aShape.IsNull() || anAxis.IsNull()) return NULL;
2611 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2612 if ( !checkTypeShapesOn( aShapeType ))
2615 // Create a cylinder surface
2616 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
2617 if ( aCylinder.IsNull() )
2621 Handle(TColStd_HSequenceOfInteger) aSeq;
2622 aSeq = getShapesOnSurfaceIDs( aCylinder, aShape, aShapeType, theState );
2624 // The GetShapesOnCylinder() doesn't change object so no new function is required.
2625 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAxis)->GetLastFunction();
2627 // Make a Python command
2628 GEOM::TPythonDump(aFunction, /*append=*/true)
2629 << "listShapesOnCylinder = geompy.GetShapesOnCylinderIDs"
2630 << "(" << theShape << ", " << aShapeType << ", " << theAxis << ", "
2631 << theRadius << ", " << theState << ")";
2637 //=============================================================================
2639 * GetShapesOnCylinderWithLocationIDs
2641 //=============================================================================
2642 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnCylinderWithLocationIDs
2643 (const Handle(GEOM_Object)& theShape,
2644 const Standard_Integer theShapeType,
2645 const Handle(GEOM_Object)& theAxis,
2646 const Handle(GEOM_Object)& thePnt,
2647 const Standard_Real theRadius,
2648 const GEOMAlgo_State theState)
2652 if (theShape.IsNull() || theAxis.IsNull() || thePnt.IsNull()) return NULL;
2654 TopoDS_Shape aShape = theShape->GetValue();
2655 TopoDS_Shape anAxis = theAxis->GetValue();
2656 TopoDS_Shape aPnt = thePnt->GetValue();
2658 if (aShape.IsNull() || anAxis.IsNull() || aPnt.IsNull()) return NULL;
2660 if (aPnt.ShapeType() != TopAbs_VERTEX )
2662 SetErrorCode("Bottom location point must be vertex");
2666 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2667 if ( !checkTypeShapesOn( aShapeType ))
2670 // Create a cylinder surface
2671 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
2672 if ( aCylinder.IsNull() )
2675 // translate the surface
2676 Handle(Geom_CylindricalSurface) aCylSurface =
2677 Handle(Geom_CylindricalSurface)::DownCast( aCylinder );
2678 if ( aCylSurface.IsNull() )
2680 SetErrorCode("Unexpected surface type instead of Geom_CylindricalSurface");
2683 gp_Pnt fromLoc = aCylSurface->Cylinder().Location();
2684 gp_Pnt toLoc = BRep_Tool::Pnt( TopoDS::Vertex( aPnt ));
2685 aCylinder->Translate( fromLoc, toLoc );
2688 Handle(TColStd_HSequenceOfInteger) aSeq;
2689 aSeq = getShapesOnSurfaceIDs( aCylinder, aShape, aShapeType, theState );
2691 // The GetShapesOnCylinder() doesn't change object so no new function is required.
2692 Handle(GEOM_Function) aFunction =
2693 GEOM::GetCreatedLast(theShape, GEOM::GetCreatedLast(thePnt,theAxis))->GetLastFunction();
2695 // Make a Python command
2696 GEOM::TPythonDump(aFunction, /*append=*/true)
2697 << "listShapesOnCylinder = geompy.GetShapesOnCylinderWithLocationIDs"
2698 << "(" << theShape << ", " << aShapeType << ", " << theAxis << ", "
2699 << thePnt << ", " << theRadius << ", " << theState << ")";
2705 //=============================================================================
2707 * GetShapesOnSphereIDs
2709 //=============================================================================
2710 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnSphereIDs
2711 (const Handle(GEOM_Object)& theShape,
2712 const Standard_Integer theShapeType,
2713 const Handle(GEOM_Object)& theCenter,
2714 const Standard_Real theRadius,
2715 const GEOMAlgo_State theState)
2719 if (theShape.IsNull() || theCenter.IsNull()) return NULL;
2721 TopoDS_Shape aShape = theShape->GetValue();
2722 TopoDS_Shape aCenter = theCenter->GetValue();
2724 if (aShape.IsNull() || aCenter.IsNull()) return NULL;
2726 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2727 if ( !checkTypeShapesOn( aShapeType ))
2730 // Center of the sphere
2731 if (aCenter.ShapeType() != TopAbs_VERTEX) return NULL;
2732 gp_Pnt aLoc = BRep_Tool::Pnt(TopoDS::Vertex(aCenter));
2734 gp_Ax3 anAx3 (aLoc, gp::DZ());
2735 Handle(Geom_SphericalSurface) aSphere =
2736 new Geom_SphericalSurface(anAx3, theRadius);
2739 Handle(TColStd_HSequenceOfInteger) aSeq;
2740 aSeq = getShapesOnSurfaceIDs( aSphere, aShape, aShapeType, theState );
2742 // The GetShapesOnSphere() doesn't change object so no new function is required.
2743 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theCenter)->GetLastFunction();
2745 // Make a Python command
2746 GEOM::TPythonDump(aFunction, /*append=*/true)
2747 << "listShapesOnCylinder = geompy.GetShapesOnCylinderIDs"
2748 << "(" << theShape << ", " << aShapeType << ", " << theCenter << ", "
2749 << theRadius << ", " << theState << ")";
2755 //=======================================================================
2756 //function : getShapesOnQuadrangleIDs
2758 * \brief Find IDs of subshapes complying with given status about quadrangle
2759 * \param theShape - the shape to explore
2760 * \param theShapeType - type of subshape of theShape
2761 * \param theTopLeftPoint - top left quadrangle corner
2762 * \param theTopRigthPoint - top right quadrangle corner
2763 * \param theBottomLeftPoint - bottom left quadrangle corner
2764 * \param theBottomRigthPoint - bottom right quadrangle corner
2765 * \param theState - required state
2766 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
2768 //=======================================================================
2769 Handle(TColStd_HSequenceOfInteger)
2770 GEOMImpl_IShapesOperations::getShapesOnQuadrangleIDs (const Handle(GEOM_Object)& theShape,
2771 const Standard_Integer theShapeType,
2772 const Handle(GEOM_Object)& theTopLeftPoint,
2773 const Handle(GEOM_Object)& theTopRigthPoint,
2774 const Handle(GEOM_Object)& theBottomLeftPoint,
2775 const Handle(GEOM_Object)& theBottomRigthPoint,
2776 const GEOMAlgo_State theState)
2780 if ( theShape.IsNull() ||
2781 theTopLeftPoint.IsNull() ||
2782 theTopRigthPoint.IsNull() ||
2783 theBottomLeftPoint.IsNull() ||
2784 theBottomRigthPoint.IsNull() )
2787 TopoDS_Shape aShape = theShape->GetValue();
2788 TopoDS_Shape aTL = theTopLeftPoint->GetValue();
2789 TopoDS_Shape aTR = theTopRigthPoint->GetValue();
2790 TopoDS_Shape aBL = theBottomLeftPoint->GetValue();
2791 TopoDS_Shape aBR = theBottomRigthPoint->GetValue();
2793 if (aShape.IsNull() ||
2798 aTL.ShapeType() != TopAbs_VERTEX ||
2799 aTR.ShapeType() != TopAbs_VERTEX ||
2800 aBL.ShapeType() != TopAbs_VERTEX ||
2801 aBR.ShapeType() != TopAbs_VERTEX )
2804 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2805 if ( !checkTypeShapesOn( aShapeType ))
2808 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
2810 // Check presence of triangulation, build if need
2811 if (!CheckTriangulation(aShape)) {
2812 SetErrorCode("Cannot build triangulation on the shape");
2817 gp_Pnt aPntTL = BRep_Tool::Pnt(TopoDS::Vertex(aTL));
2818 gp_Pnt aPntTR = BRep_Tool::Pnt(TopoDS::Vertex(aTR));
2819 gp_Pnt aPntBL = BRep_Tool::Pnt(TopoDS::Vertex(aBL));
2820 gp_Pnt aPntBR = BRep_Tool::Pnt(TopoDS::Vertex(aBR));
2822 GEOMAlgo_FinderShapeOnQuad aFinder( aPntTL, aPntTR, aPntBL, aPntBR );
2823 Standard_Real aTol = 0.0001; // default value
2825 aFinder.SetShape(aShape);
2826 aFinder.SetTolerance(aTol);
2827 //aFinder.SetSurface(theSurface);
2828 aFinder.SetShapeType(aShapeType);
2829 aFinder.SetState(theState);
2831 // Sets the minimal number of inner points for the faces that do not have own
2832 // inner points at all (for e.g. rectangular planar faces have just 2 triangles).
2834 aFinder.SetNbPntsMin(3);
2835 // Sets the maximal number of inner points for edges or faces.
2836 // It is usefull for the cases when this number is very big (e.g =2000) to improve
2837 // the performance. If this value =0, all inner points will be taken into account.
2839 aFinder.SetNbPntsMax(100);
2843 // Interprete results
2844 Standard_Integer iErr = aFinder.ErrorStatus();
2845 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
2847 MESSAGE(" iErr : " << iErr);
2848 TCollection_AsciiString aMsg (" iErr : ");
2849 aMsg += TCollection_AsciiString(iErr);
2853 Standard_Integer iWrn = aFinder.WarningStatus();
2854 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
2856 MESSAGE(" *** iWrn : " << iWrn);
2859 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
2861 if (listSS.Extent() < 1) {
2862 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
2863 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
2867 // Fill sequence of object IDs
2868 aSeqOfIDs = new TColStd_HSequenceOfInteger;
2870 TopTools_IndexedMapOfShape anIndices;
2871 TopExp::MapShapes(aShape, anIndices);
2873 TopTools_ListIteratorOfListOfShape itSub (listSS);
2874 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
2875 int id = anIndices.FindIndex(itSub.Value());
2876 aSeqOfIDs->Append(id);
2881 //=======================================================================
2882 //function : GetShapesOnQuadrangle
2884 * \brief Find subshapes complying with given status about quadrangle
2885 * \param theShape - the shape to explore
2886 * \param theShapeType - type of subshape of theShape
2887 * \param theTopLeftPoint - top left quadrangle corner
2888 * \param theTopRigthPoint - top right quadrangle corner
2889 * \param theBottomLeftPoint - bottom left quadrangle corner
2890 * \param theBottomRigthPoint - bottom right quadrangle corner
2891 * \param theState - required state
2892 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
2894 //=======================================================================
2895 Handle(TColStd_HSequenceOfTransient)
2896 GEOMImpl_IShapesOperations::GetShapesOnQuadrangle (const Handle(GEOM_Object)& theShape,
2897 const Standard_Integer theShapeType,
2898 const Handle(GEOM_Object)& theTopLeftPoint,
2899 const Handle(GEOM_Object)& theTopRigthPoint,
2900 const Handle(GEOM_Object)& theBottomLeftPoint,
2901 const Handle(GEOM_Object)& theBottomRigthPoint,
2902 const GEOMAlgo_State theState)
2905 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2906 getShapesOnQuadrangleIDs( theShape,
2911 theBottomRigthPoint,
2913 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->IsEmpty() )
2916 // Find objects by indices
2917 TCollection_AsciiString anAsciiList;
2918 Handle(TColStd_HSequenceOfTransient) aSeq;
2919 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
2920 if ( aSeq.IsNull() || aSeq->IsEmpty() )
2923 // Make a Python command
2925 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2926 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2928 GEOM::TPythonDump(aFunction)
2929 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnQuadrangle("
2931 << TopAbs_ShapeEnum(theShapeType) << ", "
2932 << theTopLeftPoint << ", "
2933 << theTopRigthPoint << ", "
2934 << theBottomLeftPoint << ", "
2935 << theBottomRigthPoint << ", "
2942 //=======================================================================
2943 //function : GetShapesOnQuadrangleIDs
2945 * \brief Find IDs of subshapes complying with given status about quadrangle
2946 * \param theShape - the shape to explore
2947 * \param theShapeType - type of subshape of theShape
2948 * \param theTopLeftPoint - top left quadrangle corner
2949 * \param theTopRigthPoint - top right quadrangle corner
2950 * \param theBottomLeftPoint - bottom left quadrangle corner
2951 * \param theBottomRigthPoint - bottom right quadrangle corner
2952 * \param theState - required state
2953 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
2955 //=======================================================================
2956 Handle(TColStd_HSequenceOfInteger)
2957 GEOMImpl_IShapesOperations::GetShapesOnQuadrangleIDs (const Handle(GEOM_Object)& theShape,
2958 const Standard_Integer theShapeType,
2959 const Handle(GEOM_Object)& theTopLeftPoint,
2960 const Handle(GEOM_Object)& theTopRigthPoint,
2961 const Handle(GEOM_Object)& theBottomLeftPoint,
2962 const Handle(GEOM_Object)& theBottomRigthPoint,
2963 const GEOMAlgo_State theState)
2966 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2967 getShapesOnQuadrangleIDs( theShape,
2972 theBottomRigthPoint,
2974 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->IsEmpty() )
2977 // Make a Python command
2979 // The GetShapesOnCylinder() doesn't change object so no new function is required.
2980 Handle(GEOM_Object) lastObj = GEOM::GetCreatedLast(theShape,theTopLeftPoint);
2981 lastObj = GEOM::GetCreatedLast(lastObj,theTopRigthPoint);
2982 lastObj = GEOM::GetCreatedLast(lastObj,theBottomRigthPoint);
2983 lastObj = GEOM::GetCreatedLast(lastObj,theBottomLeftPoint);
2984 Handle(GEOM_Function) aFunction = lastObj->GetLastFunction();
2986 GEOM::TPythonDump(aFunction, /*append=*/true)
2987 << "listShapesOnQuadrangle = geompy.GetShapesOnQuadrangleIDs("
2989 << TopAbs_ShapeEnum(theShapeType) << ", "
2990 << theTopLeftPoint << ", "
2991 << theTopRigthPoint << ", "
2992 << theBottomLeftPoint << ", "
2993 << theBottomRigthPoint << ", "
3000 //=============================================================================
3004 //=============================================================================
3005 static bool GetInPlaceOfShape (const Handle(GEOM_Function)& theWhereFunction,
3006 const TopTools_IndexedMapOfShape& theWhereIndices,
3007 const TopoDS_Shape& theWhat,
3008 TColStd_ListOfInteger& theModifiedList)
3010 if (theWhereFunction.IsNull() || theWhat.IsNull()) return false;
3012 if (theWhereIndices.Contains(theWhat)) {
3013 // entity was not changed by the operation
3014 Standard_Integer aWhatIndex = theWhereIndices.FindIndex(theWhat);
3015 theModifiedList.Append(aWhatIndex);
3019 // try to find in history
3020 TDF_Label aHistoryLabel = theWhereFunction->GetHistoryEntry(Standard_False);
3022 // search in history for all argument shapes
3023 Standard_Boolean isFound = Standard_False;
3024 Standard_Boolean isGood = Standard_False;
3026 TDF_LabelSequence aLabelSeq;
3027 theWhereFunction->GetDependency(aLabelSeq);
3028 Standard_Integer nbArg = aLabelSeq.Length();
3030 for (Standard_Integer iarg = 1; iarg <= nbArg && !isFound; iarg++) {
3032 TDF_Label anArgumentRefLabel = aLabelSeq.Value(iarg);
3034 Handle(GEOM_Object) anArgumentObject = GEOM_Object::GetReferencedObject(anArgumentRefLabel);
3035 TopoDS_Shape anArgumentShape = anArgumentObject->GetValue();
3037 TopTools_IndexedMapOfShape anArgumentIndices;
3038 TopExp::MapShapes(anArgumentShape, anArgumentIndices);
3040 if (anArgumentIndices.Contains(theWhat)) {
3041 isFound = Standard_True;
3042 Standard_Integer aWhatIndex = anArgumentIndices.FindIndex(theWhat);
3044 // Find corresponding label in history
3045 TDF_Label anArgumentHistoryLabel =
3046 theWhereFunction->GetArgumentHistoryEntry(anArgumentRefLabel, Standard_False);
3047 if (anArgumentHistoryLabel.IsNull()) {
3048 // Lost History of operation argument. Possibly, all its entities was removed.
3049 isGood = Standard_True;
3052 TDF_Label aWhatHistoryLabel = anArgumentHistoryLabel.FindChild(aWhatIndex, Standard_False);
3054 if (aWhatHistoryLabel.IsNull()) {
3055 // Removed entity ? Compound ? Compsolid ? Shell ? Wire
3056 isGood = Standard_False;
3058 Handle(TDataStd_IntegerArray) anIntegerArray;
3059 if (!aWhatHistoryLabel.FindAttribute(TDataStd_IntegerArray::GetID(), anIntegerArray)) {
3060 //Error: Empty modifications history for the sought shape.
3061 isGood = Standard_False;
3064 isGood = Standard_True;
3065 Standard_Integer imod, aModifLen = anIntegerArray->Array()->Length();
3066 for (imod = 1; imod <= aModifLen; imod++) {
3067 theModifiedList.Append(anIntegerArray->Array()->Value(imod));
3078 // try compound/compsolid/shell/wire element by element
3079 bool isFoundAny = false;
3080 TopTools_MapOfShape mapShape;
3082 if (theWhat.ShapeType() == TopAbs_COMPOUND ||
3083 theWhat.ShapeType() == TopAbs_COMPSOLID) {
3084 // recursive processing of compound/compsolid
3085 TopoDS_Iterator anIt (theWhat, Standard_True, Standard_True);
3086 for (; anIt.More(); anIt.Next()) {
3087 if (mapShape.Add(anIt.Value())) {
3088 TopoDS_Shape curWhat = anIt.Value();
3089 isFoundAny = GetInPlaceOfShape(theWhereFunction, theWhereIndices, curWhat, theModifiedList);
3090 if (isFoundAny) isFound = Standard_True;
3094 else if (theWhat.ShapeType() == TopAbs_SHELL) {
3095 // try to replace a shell by its faces images
3096 TopExp_Explorer anExp (theWhat, TopAbs_FACE);
3097 for (; anExp.More(); anExp.Next()) {
3098 if (mapShape.Add(anExp.Current())) {
3099 TopoDS_Shape curWhat = anExp.Current();
3100 isFoundAny = GetInPlaceOfShape(theWhereFunction, theWhereIndices, curWhat, theModifiedList);
3101 if (isFoundAny) isFound = Standard_True;
3105 else if (theWhat.ShapeType() == TopAbs_WIRE) {
3106 // try to replace a wire by its edges images
3107 TopExp_Explorer anExp (theWhat, TopAbs_EDGE);
3108 for (; anExp.More(); anExp.Next()) {
3109 if (mapShape.Add(anExp.Current())) {
3110 TopoDS_Shape curWhat = anExp.Current();
3111 isFoundAny = GetInPlaceOfShape(theWhereFunction, theWhereIndices, curWhat, theModifiedList);
3112 if (isFoundAny) isFound = Standard_True;
3124 //=============================================================================
3126 * GetShapeProperties
3128 //=============================================================================
3129 void GEOMImpl_IShapesOperations::GetShapeProperties( const TopoDS_Shape aShape, Standard_Real tab[],
3132 GProp_GProps theProps;
3134 //TopoDS_Shape aPntShape;
3135 Standard_Real aShapeSize;
3137 if (aShape.ShapeType() == TopAbs_VERTEX) aCenterMass = BRep_Tool::Pnt( TopoDS::Vertex( aShape ) );
3138 else if (aShape.ShapeType() == TopAbs_EDGE) BRepGProp::LinearProperties(aShape, theProps);
3139 else if (aShape.ShapeType() == TopAbs_FACE) BRepGProp::SurfaceProperties(aShape, theProps);
3140 else BRepGProp::VolumeProperties(aShape, theProps);
3142 if (aShape.ShapeType() == TopAbs_VERTEX)
3145 aCenterMass = theProps.CentreOfMass();
3146 aShapeSize = theProps.Mass();
3149 // aPntShape = BRepBuilderAPI_MakeVertex(aCenterMass).Shape();
3150 // aVertex = BRep_Tool::Pnt( TopoDS::Vertex( aPntShape ) );
3151 aVertex = aCenterMass;
3152 tab[0] = aVertex.X();
3153 tab[1] = aVertex.Y();
3154 tab[2] = aVertex.Z();
3155 tab[3] = aShapeSize;
3161 //================================================================================
3163 * \brief Return normal to face at extrema point
3165 //================================================================================
3167 gp_Vec GetNormal(const TopoDS_Face& face, const BRepExtrema_DistShapeShape& extrema)
3169 gp_Vec defaultNorm(1,0,0); // to have same normals on different faces
3171 // get UV at extrema point
3172 Standard_Real u,v, f,l;
3173 switch ( extrema.SupportTypeShape2(1) ) {
3174 case BRepExtrema_IsInFace: {
3175 extrema.ParOnFaceS2(1, u, v );
3178 case BRepExtrema_IsOnEdge: {
3179 TopoDS_Edge edge = TopoDS::Edge( extrema.SupportOnShape2(1));
3180 Handle(Geom2d_Curve) pcurve = BRep_Tool::CurveOnSurface( edge, face, f,l );
3181 extrema.ParOnEdgeS2( 1, u );
3182 gp_Pnt2d uv = pcurve->Value( u );
3187 case BRepExtrema_IsVertex: return defaultNorm;
3190 BRepAdaptor_Surface surface( face, false );
3191 gp_Vec du, dv; gp_Pnt p;
3192 surface.D1( u, v, p, du, dv );
3196 } catch (Standard_Failure ) {
3202 //=============================================================================
3207 //=============================================================================
3208 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlace (Handle(GEOM_Object) theShapeWhere,
3209 Handle(GEOM_Object) theShapeWhat)
3213 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
3215 TopoDS_Shape aWhere = theShapeWhere->GetValue();
3216 TopoDS_Shape aWhat = theShapeWhat->GetValue();
3217 TopoDS_Shape aPntShape;
3218 TopoDS_Vertex aVertex;
3220 if (aWhere.IsNull() || aWhat.IsNull()) {
3221 SetErrorCode("Error: aWhere and aWhat TopoDS_Shape are Null.");
3225 Handle(GEOM_Function) aWhereFunction = theShapeWhere->GetLastFunction();
3226 if (aWhereFunction.IsNull()) {
3227 SetErrorCode("Error: aWhereFunction is Null.");
3231 TopTools_IndexedMapOfShape aWhereIndices;
3232 TopExp::MapShapes(aWhere, aWhereIndices);
3234 TColStd_ListOfInteger aModifiedList;
3235 Standard_Integer aWhereIndex;
3236 Handle(TColStd_HArray1OfInteger) aModifiedArray;
3237 Handle(GEOM_Object) aResult;
3239 bool isFound = false;
3240 Standard_Integer iType = TopAbs_SOLID;
3241 Standard_Integer compType = TopAbs_SOLID;
3242 Standard_Real aWhat_Mass = 0., aWhere_Mass = 0.;
3243 Standard_Real tab_aWhat[4], tab_aWhere[4];
3244 Standard_Real dl_l = 1e-3;
3245 Standard_Real min_l, Tol_0D, Tol_1D, Tol_2D, Tol_3D, Tol_Mass;
3246 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
3247 Bnd_Box BoundingBox;
3248 gp_Pnt aPnt, aPnt_aWhat, tab_Pnt[2];
3249 GProp_GProps aProps;
3251 // Find the iType of the aWhat shape
3252 if ( aWhat.ShapeType() == TopAbs_VERTEX ) iType = TopAbs_VERTEX;
3253 else if ( aWhat.ShapeType() == TopAbs_EDGE || aWhat.ShapeType() == TopAbs_WIRE ) iType = TopAbs_EDGE;
3254 else if ( aWhat.ShapeType() == TopAbs_FACE || aWhat.ShapeType() == TopAbs_SHELL ) iType = TopAbs_FACE;
3255 else if ( aWhat.ShapeType() == TopAbs_SOLID || aWhat.ShapeType() == TopAbs_COMPSOLID ) iType = TopAbs_SOLID;
3256 else if ( aWhat.ShapeType() == TopAbs_COMPOUND ) {
3257 // Only the iType of the first shape in the compound is taken into account
3258 TopoDS_Iterator It (aWhat, Standard_False, Standard_False);
3260 SetErrorCode("Error: theShapeWhat is an empty COMPOUND.");
3263 compType = It.Value().ShapeType();
3264 if ( compType == TopAbs_VERTEX ) iType = TopAbs_VERTEX;
3265 else if ( compType == TopAbs_EDGE || compType == TopAbs_WIRE ) iType = TopAbs_EDGE;
3266 else if ( compType == TopAbs_FACE || compType == TopAbs_SHELL) iType = TopAbs_FACE;
3267 else if ( compType == TopAbs_SOLID || compType == TopAbs_COMPSOLID) iType = TopAbs_SOLID;
3270 SetErrorCode("Error: An attempt to extract a shape of not supported type.");
3274 TopExp_Explorer Exp_aWhat( aWhat, TopAbs_ShapeEnum( iType ) );
3275 TopExp_Explorer Exp_aWhere( aWhere, TopAbs_ShapeEnum( iType ) );
3276 TopExp_Explorer Exp_Edge( aWhere, TopAbs_EDGE );
3278 // Find the shortest edge in theShapeWhere shape
3279 BRepBndLib::Add(aWhere, BoundingBox);
3280 BoundingBox.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
3281 min_l = fabs(aXmax - aXmin);
3282 if( min_l < fabs(aYmax - aYmin) ) min_l = fabs(aYmax - aYmin);
3283 if( min_l < fabs(aZmax - aZmin) ) min_l = fabs(aZmax - aZmin);
3285 for ( Standard_Integer nbEdge = 0; Exp_Edge.More(); Exp_Edge.Next(), nbEdge++ ) {
3286 TopExp_Explorer Exp_Vertex( Exp_Edge.Current(), TopAbs_VERTEX);
3287 for ( Standard_Integer nbVertex = 0; Exp_Vertex.More(); Exp_Vertex.Next(), nbVertex++ ) {
3288 aPnt = BRep_Tool::Pnt( TopoDS::Vertex( Exp_Vertex.Current() ) );
3289 tab_Pnt[nbVertex] = aPnt;
3291 if ( ! tab_Pnt[0].IsEqual(tab_Pnt[1], dl_l) ) {
3292 BRepGProp::LinearProperties(Exp_Edge.Current(), aProps);
3293 if ( aProps.Mass() < min_l ) min_l = aProps.Mass();
3297 // Compute tolerances
3299 Tol_1D = dl_l * min_l;
3300 Tol_2D = dl_l * ( min_l * min_l) * ( 2. + dl_l);
3301 Tol_3D = dl_l * ( min_l * min_l * min_l ) * ( 3. + (3 * dl_l) + (dl_l * dl_l) );
3303 if (Tol_0D < Precision::Confusion()) Tol_0D = Precision::Confusion();
3304 if (Tol_1D < Precision::Confusion()) Tol_1D = Precision::Confusion();
3305 if (Tol_2D < Precision::Confusion()) Tol_2D = Precision::Confusion();
3306 if (Tol_3D < Precision::Confusion()) Tol_3D = Precision::Confusion();
3308 //if (Tol_1D > 1.0) Tol_1D = 1.0;
3309 //if (Tol_2D > 1.0) Tol_2D = 1.0;
3310 //if (Tol_3D > 1.0) Tol_3D = 1.0;
3313 if ( iType == TopAbs_VERTEX ) Tol_Mass = Tol_0D;
3314 else if ( iType == TopAbs_EDGE ) Tol_Mass = Tol_1D;
3315 else if ( iType == TopAbs_FACE ) Tol_Mass = Tol_2D;
3317 // Compute the ShapeWhat Mass
3318 for ( ; Exp_aWhat.More(); Exp_aWhat.Next() ) {
3319 if ( iType == TopAbs_VERTEX ) {
3323 else if ( iType == TopAbs_EDGE ) BRepGProp::LinearProperties(Exp_aWhat.Current(), aProps);
3324 else if ( iType == TopAbs_FACE ) BRepGProp::SurfaceProperties(Exp_aWhat.Current(), aProps);
3325 else BRepGProp::VolumeProperties(Exp_aWhat.Current(), aProps);
3326 aWhat_Mass += aProps.Mass();
3329 // Searching for the sub-shapes inside the ShapeWhere shape
3330 TopTools_MapOfShape map_aWhere;
3331 for ( Exp_aWhere.ReInit(); Exp_aWhere.More(); Exp_aWhere.Next() ) {
3332 if (!map_aWhere.Add(Exp_aWhere.Current()))
3333 continue; // skip repeated shape to avoid mass addition
3334 GetShapeProperties( Exp_aWhere.Current(), tab_aWhere, aPnt );
3335 for ( Exp_aWhat.ReInit(); Exp_aWhat.More(); Exp_aWhat.Next() ) {
3336 GetShapeProperties( Exp_aWhat.Current(), tab_aWhat, aPnt_aWhat );
3337 if ( fabs(tab_aWhat[3] - tab_aWhere[3]) <= Tol_Mass && aPnt_aWhat.Distance(aPnt) <= Tol_1D )
3340 if ( (tab_aWhat[3] - tab_aWhere[3]) > Tol_Mass ) {
3341 aPntShape = BRepBuilderAPI_MakeVertex( aPnt ).Shape();
3342 aVertex = TopoDS::Vertex( aPntShape );
3343 BRepExtrema_DistShapeShape aWhereDistance ( aVertex, Exp_aWhere.Current() );
3344 BRepExtrema_DistShapeShape aWhatDistance ( aVertex, Exp_aWhat.Current() );
3345 if ( aWhereDistance.IsDone() && aWhatDistance.IsDone() &&
3346 fabs(aWhereDistance.Value() - aWhatDistance.Value()) <= Tol_1D )
3348 // 0020162: "EDF 961 GEOM : Getinplace is getting additionnal orthogonal faces"
3349 // aVertex must be projected to the same point on Where and on What
3350 gp_Pnt pOnWhat = aWhatDistance.PointOnShape2(1);
3351 gp_Pnt pOnWhere = aWhereDistance.PointOnShape2(1);
3352 isFound = ( pOnWhat.Distance(pOnWhere) <= Tol_1D );
3353 if ( isFound && iType == TopAbs_FACE )
3355 // check normals at pOnWhat and pOnWhere
3356 const double angleTol = PI/180.;
3357 gp_Vec normToWhat = GetNormal( TopoDS::Face(Exp_aWhat.Current()), aWhatDistance);
3358 gp_Vec normToWhere = GetNormal( TopoDS::Face(Exp_aWhere.Current()), aWhereDistance);
3359 if ( normToWhat * normToWhere < 0 )
3360 normToWhat.Reverse();
3361 isFound = ( normToWhat.Angle( normToWhere ) < angleTol );
3367 aWhereIndex = aWhereIndices.FindIndex(Exp_aWhere.Current());
3368 aModifiedList.Append(aWhereIndex);
3369 aWhere_Mass += tab_aWhere[3];
3374 if ( fabs( aWhat_Mass - aWhere_Mass ) <= Tol_Mass ) break;
3377 if (aModifiedList.Extent() == 0) { // Not found any Results
3378 SetErrorCode(NOT_FOUND_ANY);
3382 aModifiedArray = new TColStd_HArray1OfInteger (1, aModifiedList.Extent());
3383 TColStd_ListIteratorOfListOfInteger anIterModif (aModifiedList);
3384 for (Standard_Integer imod = 1; anIterModif.More(); anIterModif.Next(), imod++)
3385 aModifiedArray->SetValue(imod, anIterModif.Value());
3388 aResult = GetEngine()->AddSubShape(theShapeWhere, aModifiedArray);
3389 if (aResult.IsNull()) {
3390 SetErrorCode("Error in algorithm: result found, but cannot be returned.");
3394 if (aModifiedArray->Length() > 1) {
3396 aResult->SetType(GEOM_GROUP);
3398 //Set a sub shape type
3399 TopoDS_Shape aFirstFound = aWhereIndices.FindKey(aModifiedArray->Value(1));
3400 TopAbs_ShapeEnum aShapeType = aFirstFound.ShapeType();
3402 TDF_Label aFreeLabel = aResult->GetFreeLabel();
3403 TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aShapeType);
3406 //Make a Python command
3407 Handle(GEOM_Function) aFunction = aResult->GetFunction(1);
3409 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetInPlace("
3410 << theShapeWhere << ", " << theShapeWhat << ")";
3416 //=======================================================================
3417 //function : GetInPlaceByHistory
3419 //=======================================================================
3420 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlaceByHistory
3421 (Handle(GEOM_Object) theShapeWhere,
3422 Handle(GEOM_Object) theShapeWhat)
3426 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
3428 TopoDS_Shape aWhere = theShapeWhere->GetValue();
3429 TopoDS_Shape aWhat = theShapeWhat->GetValue();
3431 if (aWhere.IsNull() || aWhat.IsNull()) return NULL;
3433 Handle(GEOM_Function) aWhereFunction = theShapeWhere->GetLastFunction();
3434 if (aWhereFunction.IsNull()) return NULL;
3436 //Fill array of indices
3437 TopTools_IndexedMapOfShape aWhereIndices;
3438 TopExp::MapShapes(aWhere, aWhereIndices);
3441 TColStd_ListOfInteger aModifiedList;
3442 bool isFound = GetInPlaceOfShape(aWhereFunction, aWhereIndices, aWhat, aModifiedList);
3444 if (!isFound || aModifiedList.Extent() < 1) {
3445 SetErrorCode("Error: No history found for the sought shape or its sub-shapes.");
3449 Handle(TColStd_HArray1OfInteger) aModifiedArray =
3450 new TColStd_HArray1OfInteger (1, aModifiedList.Extent());
3451 TColStd_ListIteratorOfListOfInteger anIterModif (aModifiedList);
3452 for (Standard_Integer imod = 1; anIterModif.More(); anIterModif.Next(), imod++) {
3453 aModifiedArray->SetValue(imod, anIterModif.Value());
3457 Handle(GEOM_Object) aResult = GetEngine()->AddSubShape(theShapeWhere, aModifiedArray);
3458 if (aResult.IsNull()) {
3459 SetErrorCode("Error in algorithm: result found, but cannot be returned.");
3463 if (aModifiedArray->Length() > 1) {
3465 aResult->SetType(GEOM_GROUP);
3467 //Set a sub shape type
3468 TopoDS_Shape aFirstFound = aWhereIndices.FindKey(aModifiedArray->Value(1));
3469 TopAbs_ShapeEnum aShapeType = aFirstFound.ShapeType();
3471 TDF_Label aFreeLabel = aResult->GetFreeLabel();
3472 TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aShapeType);
3475 //Make a Python command
3476 Handle(GEOM_Function) aFunction = aResult->GetFunction(1);
3478 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetInPlaceByHistory("
3479 << theShapeWhere << ", " << theShapeWhat << ")";
3485 //=======================================================================
3486 //function : SortShapes
3488 //=======================================================================
3489 void GEOMImpl_IShapesOperations::SortShapes(TopTools_ListOfShape& SL,
3490 const Standard_Boolean isOldSorting)
3492 Standard_Integer MaxShapes = SL.Extent();
3493 TopTools_Array1OfShape aShapes (1,MaxShapes);
3494 TColStd_Array1OfInteger OrderInd(1,MaxShapes);
3495 TColStd_Array1OfReal MidXYZ (1,MaxShapes); //X,Y,Z;
3496 TColStd_Array1OfReal Length (1,MaxShapes); //X,Y,Z;
3498 // Computing of CentreOfMass
3499 Standard_Integer Index;
3502 TopTools_ListIteratorOfListOfShape it(SL);
3503 for (Index=1; it.More(); Index++)
3505 TopoDS_Shape S = it.Value();
3506 SL.Remove( it ); // == it.Next()
3508 OrderInd.SetValue (Index, Index);
3509 if (S.ShapeType() == TopAbs_VERTEX) {
3510 GPoint = BRep_Tool::Pnt( TopoDS::Vertex( S ));
3511 Length.SetValue( Index, (Standard_Real) S.Orientation());
3514 // BEGIN: fix for Mantis issue 0020842
3516 BRepGProp::LinearProperties (S, GPr);
3519 if (S.ShapeType() == TopAbs_EDGE || S.ShapeType() == TopAbs_WIRE) {
3520 BRepGProp::LinearProperties (S, GPr);
3522 else if (S.ShapeType() == TopAbs_FACE || S.ShapeType() == TopAbs_SHELL) {
3523 BRepGProp::SurfaceProperties(S, GPr);
3526 BRepGProp::VolumeProperties(S, GPr);
3529 // END: fix for Mantis issue 0020842
3530 GPoint = GPr.CentreOfMass();
3531 Length.SetValue(Index, GPr.Mass());
3533 MidXYZ.SetValue(Index,
3534 GPoint.X()*999 + GPoint.Y()*99 + GPoint.Z()*0.9);
3535 //cout << Index << " L: " << Length(Index) << "CG: " << MidXYZ(Index) << endl;
3539 Standard_Integer aTemp;
3540 Standard_Boolean exchange, Sort = Standard_True;
3541 Standard_Real tol = Precision::Confusion();
3544 Sort = Standard_False;
3545 for (Index=1; Index < MaxShapes; Index++)
3547 exchange = Standard_False;
3548 Standard_Real dMidXYZ = MidXYZ(OrderInd(Index)) - MidXYZ(OrderInd(Index+1));
3549 Standard_Real dLength = Length(OrderInd(Index)) - Length(OrderInd(Index+1));
3550 if ( dMidXYZ >= tol ) {
3551 // cout << "MidXYZ: " << MidXYZ(OrderInd(Index))<< " > " <<MidXYZ(OrderInd(Index+1))
3552 // << " d: " << dMidXYZ << endl;
3553 exchange = Standard_True;
3555 else if ( Abs(dMidXYZ) < tol && dLength >= tol ) {
3556 // cout << "Length: " << Length(OrderInd(Index))<< " > " <<Length(OrderInd(Index+1))
3557 // << " d: " << dLength << endl;
3558 exchange = Standard_True;
3560 else if ( Abs(dMidXYZ) < tol && Abs(dLength) < tol &&
3561 aShapes(OrderInd(Index)).ShapeType() <= TopAbs_FACE) {
3563 // equal values possible on shapes such as two halves of a sphere and
3564 // a membrane inside the sphere
3566 BRepBndLib::Add( aShapes( OrderInd(Index) ), box1 );
3567 if ( box1.IsVoid() ) continue;
3568 BRepBndLib::Add( aShapes( OrderInd(Index+1) ), box2 );
3569 Standard_Real dSquareExtent = box1.SquareExtent() - box2.SquareExtent();
3570 if ( dSquareExtent >= tol ) {
3571 // cout << "SquareExtent: " << box1.SquareExtent()<<" > "<<box2.SquareExtent() << endl;
3572 exchange = Standard_True;
3574 else if ( Abs(dSquareExtent) < tol ) {
3575 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax, val1, val2;
3576 box1.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
3577 val1 = (aXmin+aXmax)*999 + (aYmin+aYmax)*99 + (aZmin+aZmax)*0.9;
3578 box2.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
3579 val2 = (aXmin+aXmax)*999 + (aYmin+aYmax)*99 + (aZmin+aZmax)*0.9;
3580 //exchange = val1 > val2;
3581 if ((val1 - val2) >= tol) {
3582 exchange = Standard_True;
3584 //cout << "box: " << val1<<" > "<<val2 << endl;
3590 // cout << "exchange " << Index << " & " << Index+1 << endl;
3591 aTemp = OrderInd(Index);
3592 OrderInd(Index) = OrderInd(Index+1);
3593 OrderInd(Index+1) = aTemp;
3594 Sort = Standard_True;
3599 for (Index=1; Index <= MaxShapes; Index++)
3600 SL.Append( aShapes( OrderInd(Index) ));
3603 //=======================================================================
3604 //function : CompsolidToCompound
3606 //=======================================================================
3607 TopoDS_Shape GEOMImpl_IShapesOperations::CompsolidToCompound (const TopoDS_Shape& theCompsolid)
3609 if (theCompsolid.ShapeType() != TopAbs_COMPSOLID) {
3610 return theCompsolid;
3613 TopoDS_Compound aCompound;
3615 B.MakeCompound(aCompound);
3617 TopTools_MapOfShape mapShape;
3618 TopoDS_Iterator It (theCompsolid, Standard_True, Standard_True);
3620 for (; It.More(); It.Next()) {
3621 TopoDS_Shape aShape_i = It.Value();
3622 if (mapShape.Add(aShape_i)) {
3623 B.Add(aCompound, aShape_i);
3630 //=======================================================================
3631 //function : CheckTriangulation
3633 //=======================================================================
3634 bool GEOMImpl_IShapesOperations::CheckTriangulation (const TopoDS_Shape& aShape)
3636 bool isTriangulation = true;
3638 TopExp_Explorer exp (aShape, TopAbs_FACE);
3641 TopLoc_Location aTopLoc;
3642 Handle(Poly_Triangulation) aTRF;
3643 aTRF = BRep_Tool::Triangulation(TopoDS::Face(exp.Current()), aTopLoc);
3644 if (aTRF.IsNull()) {
3645 isTriangulation = false;
3648 else // no faces, try edges
3650 TopExp_Explorer expe (aShape, TopAbs_EDGE);
3654 TopLoc_Location aLoc;
3655 Handle(Poly_Polygon3D) aPE = BRep_Tool::Polygon3D(TopoDS::Edge(expe.Current()), aLoc);
3657 isTriangulation = false;
3661 if (!isTriangulation) {
3662 // calculate deflection
3663 Standard_Real aDeviationCoefficient = 0.001;
3666 BRepBndLib::Add(aShape, B);
3667 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
3668 B.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
3670 Standard_Real dx = aXmax - aXmin, dy = aYmax - aYmin, dz = aZmax - aZmin;
3671 Standard_Real aDeflection = Max(Max(dx, dy), dz) * aDeviationCoefficient * 4;
3672 Standard_Real aHLRAngle = 0.349066;
3674 BRepMesh_IncrementalMesh Inc (aShape, aDeflection, Standard_False, aHLRAngle);
3680 #define MAX_TOLERANCE 1.e-7
3682 //=======================================================================
3683 //function : isSameEdge
3684 //purpose : Returns True if two edges coincide
3685 //=======================================================================
3686 static bool isSameEdge(const TopoDS_Edge& theEdge1, const TopoDS_Edge& theEdge2)
3688 TopoDS_Vertex V11, V12, V21, V22;
3689 TopExp::Vertices(theEdge1, V11, V12);
3690 TopExp::Vertices(theEdge2, V21, V22);
3691 gp_Pnt P11 = BRep_Tool::Pnt(V11);
3692 gp_Pnt P12 = BRep_Tool::Pnt(V12);
3693 gp_Pnt P21 = BRep_Tool::Pnt(V21);
3694 gp_Pnt P22 = BRep_Tool::Pnt(V22);
3695 bool coincide = false;
3697 //Check that ends of edges coincide
3698 if(P11.Distance(P21) <= MAX_TOLERANCE) {
3699 if(P12.Distance(P22) <= MAX_TOLERANCE) coincide = true;
3701 else if(P11.Distance(P22) <= MAX_TOLERANCE) {
3702 if(P12.Distance(P21) <= MAX_TOLERANCE) coincide = true;
3705 if(!coincide) return false;
3707 if (BRep_Tool::Degenerated(theEdge1))
3708 if (BRep_Tool::Degenerated(theEdge2)) return true;
3711 if (BRep_Tool::Degenerated(theEdge2)) return false;
3713 double U11, U12, U21, U22;
3714 Handle(Geom_Curve) C1 = BRep_Tool::Curve(theEdge1, U11, U12);
3715 Handle(Geom_Curve) C2 = BRep_Tool::Curve(theEdge2, U21, U22);
3716 if(C1->DynamicType() == C2->DynamicType()) return true;
3718 //Check that both edges has the same geometry
3719 double range = U12-U11;
3720 double U = U11+ range/3.0;
3721 gp_Pnt P1 = C1->Value(U); //Compute a point on one third of the edge's length
3722 U = U11+range*2.0/3.0;
3723 gp_Pnt P2 = C1->Value(U); //Compute a point on two thirds of the edge's length
3725 if(!GeomLib_Tool::Parameter(C2, P1, MAX_TOLERANCE, U) || U < U21 || U > U22)
3728 if(P1.Distance(C2->Value(U)) > MAX_TOLERANCE) return false;
3730 if(!GeomLib_Tool::Parameter(C2, P2, MAX_TOLERANCE, U) || U < U21 || U > U22)
3733 if(P2.Distance(C2->Value(U)) > MAX_TOLERANCE) return false;
3738 #include <TopoDS_TShape.hxx>
3739 //=======================================================================
3740 //function : isSameFace
3741 //purpose : Returns True if two faces coincide
3742 //=======================================================================
3743 static bool isSameFace(const TopoDS_Face& theFace1, const TopoDS_Face& theFace2)
3745 TopExp_Explorer E(theFace1, TopAbs_EDGE);
3746 TopTools_ListOfShape LS1, LS2;
3747 for(; E.More(); E.Next()) LS1.Append(E.Current());
3749 E.Init(theFace2, TopAbs_EDGE);
3750 for(; E.More(); E.Next()) LS2.Append(E.Current());
3752 //Compare the number of edges in the faces
3753 if(LS1.Extent() != LS2.Extent()) return false;
3755 double aMin = RealFirst(), aMax = RealLast();
3756 double xminB1=aMax, yminB1=aMax, zminB1=aMax, xminB2=aMax, yminB2=aMax, zminB2=aMax;
3757 double xmaxB1=aMin, ymaxB1=aMin, zmaxB1=aMin, xmaxB2=aMin, ymaxB2=aMin, zmaxB2=aMin;
3759 for(E.Init(theFace1, TopAbs_VERTEX); E.More(); E.Next()) {
3760 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
3761 if(P.X() < xminB1) xminB1 = P.X();
3762 if(P.Y() < yminB1) yminB1 = P.Y();
3763 if(P.Z() < zminB1) zminB1 = P.Z();
3764 if(P.X() > xmaxB1) xmaxB1 = P.X();
3765 if(P.Y() > ymaxB1) ymaxB1 = P.Y();
3766 if(P.Z() > zmaxB1) zmaxB1 = P.Z();
3769 for(E.Init(theFace2, TopAbs_VERTEX); E.More(); E.Next()) {
3770 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
3771 if(P.X() < xminB2) xminB2 = P.X();
3772 if(P.Y() < yminB2) yminB2 = P.Y();
3773 if(P.Z() < zminB2) zminB2 = P.Z();
3774 if(P.X() > xmaxB2) xmaxB2 = P.X();
3775 if(P.Y() > ymaxB2) ymaxB2 = P.Y();
3776 if(P.Z() > zmaxB2) zmaxB2 = P.Z();
3779 //Compare the bounding boxes of both faces
3780 if(gp_Pnt(xminB1, yminB1, zminB1).Distance(gp_Pnt(xminB2, yminB2, zminB2)) > MAX_TOLERANCE)
3783 if(gp_Pnt(xmaxB1, ymaxB1, zmaxB1).Distance(gp_Pnt(xmaxB2, ymaxB2, zmaxB2)) > MAX_TOLERANCE)
3786 Handle(Geom_Surface) S1 = BRep_Tool::Surface(theFace1);
3787 Handle(Geom_Surface) S2 = BRep_Tool::Surface(theFace2);
3789 //Check if there a coincidence of two surfaces at least in two points
3790 double U11, U12, V11, V12, U21, U22, V21, V22;
3791 BRepTools::UVBounds(theFace1, U11, U12, V11, V12);
3792 BRepTools::UVBounds(theFace2, U21, U22, V21, V22);
3794 double rangeU = U12-U11;
3795 double rangeV = V12-V11;
3796 double U = U11 + rangeU/3.0;
3797 double V = V11 + rangeV/3.0;
3798 gp_Pnt P1 = S1->Value(U, V);
3799 U = U11+rangeU*2.0/3.0;
3800 V = V11+rangeV*2.0/3.0;
3801 gp_Pnt P2 = S1->Value(U, V);
3803 if (!GeomLib_Tool::Parameters(S2, P1, MAX_TOLERANCE, U, V) || U < U21 || U > U22 || V < V21 || V > V22)
3806 if (P1.Distance(S2->Value(U,V)) > MAX_TOLERANCE) return false;
3808 if (!GeomLib_Tool::Parameters(S2, P2, MAX_TOLERANCE, U, V) || U < U21 || U > U22 || V < V21 || V > V22)
3811 if (P2.Distance(S2->Value(U, V)) > MAX_TOLERANCE) return false;
3813 //Check that each edge of the Face1 has a counterpart in the Face2
3814 TopTools_MapOfOrientedShape aMap;
3815 TopTools_ListIteratorOfListOfShape LSI1(LS1);
3816 for(; LSI1.More(); LSI1.Next()) {
3817 TopoDS_Edge E = TopoDS::Edge(LSI1.Value());
3818 bool isFound = false;
3819 TopTools_ListIteratorOfListOfShape LSI2(LS2);
3820 for(; LSI2.More(); LSI2.Next()) {
3821 TopoDS_Shape aValue = LSI2.Value();
3822 if(aMap.Contains(aValue)) continue; //To avoid checking already found edge several times
3823 if(isSameEdge(E, TopoDS::Edge(aValue))) {
3829 if(!isFound) return false;
3835 //=======================================================================
3836 //function : isSameSolid
3837 //purpose : Returns True if two solids coincide
3838 //=======================================================================
3839 bool isSameSolid(const TopoDS_Solid& theSolid1, const TopoDS_Solid& theSolid2)
3841 TopExp_Explorer E(theSolid1, TopAbs_FACE);
3842 TopTools_ListOfShape LS1, LS2;
3843 for(; E.More(); E.Next()) LS1.Append(E.Current());
3844 E.Init(theSolid2, TopAbs_FACE);
3845 for(; E.More(); E.Next()) LS2.Append(E.Current());
3847 if(LS1.Extent() != LS2.Extent()) return false;
3849 double aMin = RealFirst(), aMax = RealLast();
3850 double xminB1=aMax, yminB1=aMax, zminB1=aMax, xminB2=aMax, yminB2=aMax, zminB2=aMax;
3851 double xmaxB1=aMin, ymaxB1=aMin, zmaxB1=aMin, xmaxB2=aMin, ymaxB2=aMin, zmaxB2=aMin;
3853 for(E.Init(theSolid1, TopAbs_VERTEX); E.More(); E.Next()) {
3854 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
3855 if(P.X() < xminB1) xminB1 = P.X();
3856 if(P.Y() < yminB1) yminB1 = P.Y();
3857 if(P.Z() < zminB1) zminB1 = P.Z();
3858 if(P.X() > xmaxB1) xmaxB1 = P.X();
3859 if(P.Y() > ymaxB1) ymaxB1 = P.Y();
3860 if(P.Z() > zmaxB1) zmaxB1 = P.Z();
3863 for(E.Init(theSolid2, TopAbs_VERTEX); E.More(); E.Next()) {
3864 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
3865 if(P.X() < xminB2) xminB2 = P.X();
3866 if(P.Y() < yminB2) yminB2 = P.Y();
3867 if(P.Z() < zminB2) zminB2 = P.Z();
3868 if(P.X() > xmaxB2) xmaxB2 = P.X();
3869 if(P.Y() > ymaxB2) ymaxB2 = P.Y();
3870 if(P.Z() > zmaxB2) zmaxB2 = P.Z();
3873 //Compare the bounding boxes of both solids
3874 if(gp_Pnt(xminB1, yminB1, zminB1).Distance(gp_Pnt(xminB2, yminB2, zminB2)) > MAX_TOLERANCE)
3877 if(gp_Pnt(xmaxB1, ymaxB1, zmaxB1).Distance(gp_Pnt(xmaxB2, ymaxB2, zmaxB2)) > MAX_TOLERANCE)
3880 //Check that each face of the Solid1 has a counterpart in the Solid2
3881 TopTools_MapOfOrientedShape aMap;
3882 TopTools_ListIteratorOfListOfShape LSI1(LS1);
3883 for(; LSI1.More(); LSI1.Next()) {
3884 TopoDS_Face F = TopoDS::Face(LSI1.Value());
3885 bool isFound = false;
3886 TopTools_ListIteratorOfListOfShape LSI2(LS2);
3887 for(; LSI2.More(); LSI2.Next()) {
3888 if(aMap.Contains(LSI2.Value())) continue; //To avoid checking already found faces several times
3889 if(isSameFace(F, TopoDS::Face(LSI2.Value()))) {
3890 aMap.Add(LSI2.Value());
3895 if(!isFound) return false;
3901 //=======================================================================
3902 //function : GetSame
3904 //=======================================================================
3905 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetSame(const Handle(GEOM_Object)& theShapeWhere,
3906 const Handle(GEOM_Object)& theShapeWhat)
3909 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
3911 TopoDS_Shape aWhere = theShapeWhere->GetValue();
3912 TopoDS_Shape aWhat = theShapeWhat->GetValue();
3914 if (aWhere.IsNull() || aWhat.IsNull()) return NULL;
3917 bool isFound = false;
3918 TopoDS_Shape aSubShape;
3919 TopTools_MapOfShape aMap;
3921 switch(aWhat.ShapeType()) {
3922 case TopAbs_VERTEX: {
3923 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(aWhat));
3924 TopExp_Explorer E(aWhere, TopAbs_VERTEX);
3925 for(; E.More(); E.Next()) {
3926 if(!aMap.Add(E.Current())) continue;
3927 gp_Pnt P2 = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
3928 if(P.Distance(P2) <= MAX_TOLERANCE) {
3930 aSubShape = E.Current();
3937 TopoDS_Face aFace = TopoDS::Face(aWhat);
3938 TopExp_Explorer E(aWhere, TopAbs_FACE);
3939 for(; E.More(); E.Next()) {
3940 if(!aMap.Add(E.Current())) continue;
3941 if(isSameFace(aFace, TopoDS::Face(E.Current()))) {
3942 aSubShape = E.Current();
3950 TopoDS_Edge anEdge = TopoDS::Edge(aWhat);
3951 TopExp_Explorer E(aWhere, TopAbs_EDGE);
3952 for(; E.More(); E.Next()) {
3953 if(!aMap.Add(E.Current())) continue;
3954 if(isSameEdge(anEdge, TopoDS::Edge(E.Current()))) {
3955 aSubShape = E.Current();
3962 case TopAbs_SOLID: {
3963 TopoDS_Solid aSolid = TopoDS::Solid(aWhat);
3964 TopExp_Explorer E(aWhere, TopAbs_SOLID);
3965 for(; E.More(); E.Next()) {
3966 if(!aMap.Add(E.Current())) continue;
3967 if(isSameSolid(aSolid, TopoDS::Solid(E.Current()))) {
3968 aSubShape = E.Current();
3980 TopTools_IndexedMapOfShape anIndices;
3981 TopExp::MapShapes(aWhere, anIndices);
3982 if (anIndices.Contains(aSubShape))
3983 anIndex = anIndices.FindIndex(aSubShape);
3986 if(anIndex < 0) return NULL;
3988 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
3990 anArray->SetValue(1, anIndex);
3992 Handle(GEOM_Object) aResult = GetEngine()->AddSubShape(theShapeWhere, anArray);
3993 Handle(GEOM_Function) aFunction = aResult->GetLastFunction();
3995 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetSame("
3996 << theShapeWhere << ", " << theShapeWhat << ")";