1 // Copyright (C) 2007-2014 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, or (at your option) any later version.
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
23 // File : GEOMImpl_IShapesOperations.cxx
25 // 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_GlueDriver.hxx"
38 #include "GEOMImpl_IVector.hxx"
39 #include "GEOMImpl_IShapes.hxx"
40 #include "GEOMImpl_IGlue.hxx"
42 #include "GEOMImpl_Block6Explorer.hxx"
43 #include "GEOMImpl_IHealingOperations.hxx"
45 #include "GEOMImpl_Gen.hxx"
47 #include "GEOM_Function.hxx"
48 #include "GEOM_ISubShape.hxx"
49 #include "GEOM_PythonDump.hxx"
51 #include "GEOMUtils.hxx"
53 #include "GEOMAlgo_ClsfBox.hxx"
54 #include "GEOMAlgo_ClsfSolid.hxx"
55 #include "GEOMAlgo_CoupleOfShapes.hxx"
56 #include "GEOMAlgo_FinderShapeOn1.hxx"
57 #include "GEOMAlgo_FinderShapeOnQuad.hxx"
58 #include "GEOMAlgo_FinderShapeOn2.hxx"
59 #include "GEOMAlgo_GetInPlace.hxx"
60 #include "GEOMAlgo_GlueDetector.hxx"
61 #include "GEOMAlgo_ListIteratorOfListOfCoupleOfShapes.hxx"
62 #include "GEOMAlgo_ListOfCoupleOfShapes.hxx"
64 #include <Basics_OCCTVersion.hxx>
66 #include <utilities.h>
68 #include <Utils_ExceptHandlers.hxx>
70 #include <BRepAdaptor_Curve.hxx>
71 #include <BRepAdaptor_Surface.hxx>
72 #include <BRepBndLib.hxx>
73 #include <BRepBuilderAPI_MakeVertex.hxx>
74 #include <BRepClass3d_SolidClassifier.hxx>
75 #include <BRepClass_FaceClassifier.hxx>
76 #include <BRepExtrema_DistShapeShape.hxx>
77 #include <BRepExtrema_ExtCF.hxx>
78 #include <BRepGProp.hxx>
79 #include <BRepMesh_IncrementalMesh.hxx>
80 #include <BRepTools.hxx>
81 #include <BRep_Builder.hxx>
82 #include <BRep_Tool.hxx>
83 #include <Bnd_Box.hxx>
84 #include <GEOMImpl_IMeasure.hxx>
85 #include <GEOMImpl_MeasureDriver.hxx>
86 #include <GProp_GProps.hxx>
87 #include <Geom2d_Curve.hxx>
88 #include <GeomAdaptor_Surface.hxx>
89 #include <GeomLib_Tool.hxx>
90 #include <Geom_CylindricalSurface.hxx>
91 #include <Geom_Plane.hxx>
92 #include <Geom_SphericalSurface.hxx>
93 #include <Geom_Surface.hxx>
94 #include <Precision.hxx>
95 #include <TColStd_Array1OfReal.hxx>
96 #include <TColStd_HArray1OfInteger.hxx>
97 #include <TColStd_ListIteratorOfListOfInteger.hxx>
98 #include <TColStd_ListOfInteger.hxx>
99 #include <TDF_Tool.hxx>
100 #include <TDataStd_Integer.hxx>
101 #include <TDataStd_IntegerArray.hxx>
102 #include <TDataStd_ListIteratorOfListOfExtendedString.hxx>
103 #include <TFunction_Driver.hxx>
104 #include <TFunction_DriverTable.hxx>
105 #include <TFunction_Logbook.hxx>
106 #include <TopAbs.hxx>
107 #include <TopExp.hxx>
108 #include <TopExp_Explorer.hxx>
109 #include <TopLoc_Location.hxx>
110 #include <TopTools_Array1OfShape.hxx>
111 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
112 #include <TopTools_IndexedMapOfShape.hxx>
113 #include <TopTools_ListIteratorOfListOfShape.hxx>
114 #include <TopTools_MapOfOrientedShape.hxx>
115 #include <TopTools_MapOfShape.hxx>
116 #include <TopTools_SequenceOfShape.hxx>
117 #include <TopoDS.hxx>
118 #include <TopoDS_Compound.hxx>
119 #include <TopoDS_Edge.hxx>
120 #include <TopoDS_Face.hxx>
121 #include <TopoDS_Iterator.hxx>
122 #include <TopoDS_Shape.hxx>
123 #include <TopoDS_Solid.hxx>
124 #include <TopoDS_Vertex.hxx>
125 #include <gp_Cylinder.hxx>
126 #include <gp_Lin.hxx>
127 #include <gp_Pnt.hxx>
131 #include <functional>
133 #include <Standard_NullObject.hxx>
134 #include <Standard_Failure.hxx>
135 #include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
138 //=============================================================================
142 //=============================================================================
143 GEOMImpl_IShapesOperations::GEOMImpl_IShapesOperations (GEOM_Engine* theEngine, int theDocID)
144 : GEOM_IOperations(theEngine, theDocID)
146 MESSAGE("GEOMImpl_IShapesOperations::GEOMImpl_IShapesOperations");
149 //=============================================================================
153 //=============================================================================
154 GEOMImpl_IShapesOperations::~GEOMImpl_IShapesOperations()
156 MESSAGE("GEOMImpl_IShapesOperations::~GEOMImpl_IShapesOperations");
159 //=============================================================================
163 //=============================================================================
164 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeEdge
165 (Handle(GEOM_Object) thePnt1, Handle(GEOM_Object) thePnt2)
169 if (thePnt1.IsNull() || thePnt2.IsNull()) return NULL;
171 //Add a new Edge object
172 Handle(GEOM_Object) anEdge = GetEngine()->AddObject(GetDocID(), GEOM_EDGE);
174 //Add a new Vector function
175 Handle(GEOM_Function) aFunction =
176 anEdge->AddFunction(GEOMImpl_VectorDriver::GetID(), VECTOR_TWO_PNT);
178 //Check if the function is set correctly
179 if (aFunction->GetDriverGUID() != GEOMImpl_VectorDriver::GetID()) return NULL;
181 GEOMImpl_IVector aPI (aFunction);
183 Handle(GEOM_Function) aRef1 = thePnt1->GetLastFunction();
184 Handle(GEOM_Function) aRef2 = thePnt2->GetLastFunction();
185 if (aRef1.IsNull() || aRef2.IsNull()) return NULL;
187 aPI.SetPoint1(aRef1);
188 aPI.SetPoint2(aRef2);
190 //Compute the Edge value
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 //=============================================================================
214 * MakeEdgeOnCurveByLength
216 //=============================================================================
217 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeEdgeOnCurveByLength
218 (Handle(GEOM_Object) theRefCurve,
219 const Standard_Real theLength,
220 Handle(GEOM_Object) theStartPoint)
224 if (theRefCurve.IsNull()) return NULL;
226 //Add a new Edge object
227 Handle(GEOM_Object) anEdge = GetEngine()->AddObject(GetDocID(), GEOM_EDGE);
229 //Add a new Vector function
230 Handle(GEOM_Function) aFunction =
231 anEdge->AddFunction(GEOMImpl_ShapeDriver::GetID(), EDGE_CURVE_LENGTH);
233 //Check if the function is set correctly
234 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
236 GEOMImpl_IVector aPI (aFunction);
238 Handle(GEOM_Function) aRef1 = theRefCurve->GetLastFunction();
239 if (aRef1.IsNull()) return NULL;
240 aPI.SetPoint1(aRef1);
242 if (!theStartPoint.IsNull()) {
243 Handle(GEOM_Function) aRef2 = theStartPoint->GetLastFunction();
244 aPI.SetPoint2(aRef2);
247 aPI.SetParameter(theLength);
249 //Compute the Edge value
252 if (!GetSolver()->ComputeFunction(aFunction)) {
253 SetErrorCode("Vector driver failed");
257 catch (Standard_Failure) {
258 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
259 SetErrorCode(aFail->GetMessageString());
263 //Make a Python command
264 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdgeOnCurveByLength("
265 << theRefCurve << ", " << theLength << ", " << theStartPoint << ")";
271 //=============================================================================
275 //=============================================================================
276 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeEdgeWire
277 (Handle(GEOM_Object) theWire,
278 const Standard_Real theLinearTolerance,
279 const Standard_Real theAngularTolerance)
283 if (theWire.IsNull()) return NULL;
285 //Add a new Edge object
286 Handle(GEOM_Object) anEdge = GetEngine()->AddObject(GetDocID(), GEOM_EDGE);
288 //Add a new Vector function
289 Handle(GEOM_Function) aFunction =
290 anEdge->AddFunction(GEOMImpl_ShapeDriver::GetID(), EDGE_WIRE);
292 //Check if the function is set correctly
293 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
295 GEOMImpl_IShapes aCI (aFunction);
297 Handle(GEOM_Function) aWire = theWire->GetLastFunction();
299 if (aWire.IsNull()) return NULL;
302 aCI.SetTolerance(theLinearTolerance);
303 aCI.SetAngularTolerance(theAngularTolerance);
305 //Compute the Edge value
308 if (!GetSolver()->ComputeFunction(aFunction)) {
309 SetErrorCode("Shape driver failed");
313 catch (Standard_Failure) {
314 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
315 SetErrorCode(aFail->GetMessageString());
319 const double DEF_LIN_TOL = Precision::Confusion();
320 const double DEF_ANG_TOL = Precision::Angular();
321 //Make a Python command
322 if ( theAngularTolerance == DEF_ANG_TOL ) {
323 if ( theLinearTolerance == DEF_LIN_TOL )
324 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdgeWire("
327 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdgeWire("
328 << theWire << ", " << theLinearTolerance << ")";
331 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdgeWire("
332 << theWire << ", " << theLinearTolerance << ", "
333 << theAngularTolerance << ")";
340 //=============================================================================
344 //=============================================================================
345 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeWire
346 (std::list<Handle(GEOM_Object)> theShapes,
347 const Standard_Real theTolerance)
352 Handle(GEOM_Object) aWire = GetEngine()->AddObject(GetDocID(), GEOM_WIRE);
355 Handle(GEOM_Function) aFunction =
356 aWire->AddFunction(GEOMImpl_ShapeDriver::GetID(), WIRE_EDGES);
357 if (aFunction.IsNull()) return NULL;
359 //Check if the function is set correctly
360 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
362 GEOMImpl_IShapes aCI (aFunction);
363 aCI.SetTolerance(theTolerance);
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 shape construction");
375 aShapesSeq->Append(aRefSh);
377 aCI.SetShapes(aShapesSeq);
382 if (!GetSolver()->ComputeFunction(aFunction)) {
383 SetErrorCode("Shape driver failed");
387 catch (Standard_Failure) {
388 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
389 SetErrorCode(aFail->GetMessageString());
393 //Make a Python command
394 GEOM::TPythonDump pd (aFunction);
395 pd << aWire << " = geompy.MakeWire([";
398 it = theShapes.begin();
399 if (it != theShapes.end()) {
401 while (it != theShapes.end()) {
402 pd << ", " << (*it++);
405 pd << "], " << theTolerance << ")";
411 //=============================================================================
415 //=============================================================================
416 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFace (Handle(GEOM_Object) theWire,
417 const bool isPlanarWanted)
421 if (theWire.IsNull()) return NULL;
423 //Add a new Face object
424 Handle(GEOM_Object) aFace = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
426 //Add a new Shape function for creation of a face from a wire
427 Handle(GEOM_Function) aFunction =
428 aFace->AddFunction(GEOMImpl_ShapeDriver::GetID(), FACE_WIRE);
429 if (aFunction.IsNull()) return NULL;
431 //Check if the function is set correctly
432 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
434 GEOMImpl_IShapes aCI (aFunction);
436 Handle(GEOM_Function) aRefWire = theWire->GetLastFunction();
438 if (aRefWire.IsNull()) return NULL;
440 aCI.SetBase(aRefWire);
441 aCI.SetIsPlanar(isPlanarWanted);
443 //Compute the Face value
444 Standard_Boolean isWarning = Standard_False;
447 if (!GetSolver()->ComputeFunction(aFunction)) {
448 SetErrorCode("Shape driver failed to compute a face");
452 catch (Standard_Failure) {
453 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
454 SetErrorCode(aFail->GetMessageString());
455 // to provide warning
456 if (!aFunction->GetValue().IsNull()) {
457 isWarning = Standard_True;
463 //Make a Python command
464 GEOM::TPythonDump(aFunction) << aFace << " = geompy.MakeFace("
465 << theWire << ", " << (int)isPlanarWanted << ")";
467 // to provide warning
468 if (!isWarning) SetErrorCode(OK);
472 //=============================================================================
476 //=============================================================================
477 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFaceWires
478 (std::list<Handle(GEOM_Object)> theShapes,
479 const bool isPlanarWanted)
484 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
487 Handle(GEOM_Function) aFunction =
488 aShape->AddFunction(GEOMImpl_ShapeDriver::GetID(), FACE_WIRES);
489 if (aFunction.IsNull()) return NULL;
491 //Check if the function is set correctly
492 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
494 GEOMImpl_IShapes aCI (aFunction);
496 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
499 std::list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
500 for (; it != theShapes.end(); it++) {
501 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
502 if (aRefSh.IsNull()) {
503 SetErrorCode("NULL argument shape for the face construction");
506 aShapesSeq->Append(aRefSh);
508 aCI.SetShapes(aShapesSeq);
510 aCI.SetIsPlanar(isPlanarWanted);
513 Standard_Boolean isWarning = Standard_False;
516 if (!GetSolver()->ComputeFunction(aFunction)) {
517 SetErrorCode("Shape driver failed");
521 catch (Standard_Failure) {
522 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
523 SetErrorCode(aFail->GetMessageString());
524 // to provide warning
525 if (!aFunction->GetValue().IsNull()) {
526 isWarning = Standard_True;
532 //Make a Python command
533 GEOM::TPythonDump pd (aFunction);
534 pd << aShape << " = geompy.MakeFaceWires([";
537 it = theShapes.begin();
538 if (it != theShapes.end()) {
540 while (it != theShapes.end()) {
541 pd << ", " << (*it++);
544 pd << "], " << (int)isPlanarWanted << ")";
546 // to provide warning
547 if (!isWarning) SetErrorCode(OK);
551 //=============================================================================
555 //=============================================================================
556 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeShell
557 (std::list<Handle(GEOM_Object)> theShapes)
559 return MakeShape(theShapes, GEOM_SHELL, SHELL_FACES, "MakeShell");
562 //=============================================================================
566 //=============================================================================
567 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeSolidShells
568 (std::list<Handle(GEOM_Object)> theShapes)
570 return MakeShape(theShapes, GEOM_SOLID, SOLID_SHELLS, "MakeSolid");
573 //=============================================================================
577 //=============================================================================
578 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeCompound
579 (std::list<Handle(GEOM_Object)> theShapes)
581 return MakeShape(theShapes, GEOM_COMPOUND, COMPOUND_SHAPES, "MakeCompound");
584 //=============================================================================
588 //=============================================================================
589 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeShape
590 (std::list<Handle(GEOM_Object)> theShapes,
591 const Standard_Integer theObjectType,
592 const Standard_Integer theFunctionType,
593 const TCollection_AsciiString& theMethodName)
598 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), theObjectType);
601 Handle(GEOM_Function) aFunction =
602 aShape->AddFunction(GEOMImpl_ShapeDriver::GetID(), theFunctionType);
603 if (aFunction.IsNull()) return NULL;
605 //Check if the function is set correctly
606 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
608 GEOMImpl_IShapes aCI (aFunction);
610 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
613 std::list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
614 for (; it != theShapes.end(); it++) {
615 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
616 if (aRefSh.IsNull()) {
617 SetErrorCode("NULL argument shape for the shape construction");
620 aShapesSeq->Append(aRefSh);
622 aCI.SetShapes(aShapesSeq);
627 if (!GetSolver()->ComputeFunction(aFunction)) {
628 SetErrorCode("Shape driver failed");
632 catch (Standard_Failure) {
633 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
634 SetErrorCode(aFail->GetMessageString());
638 //Make a Python command
639 GEOM::TPythonDump pd (aFunction);
640 pd << aShape << " = geompy." << theMethodName.ToCString() << "([";
643 it = theShapes.begin();
644 if (it != theShapes.end()) {
646 while (it != theShapes.end()) {
647 pd << ", " << (*it++);
656 //=============================================================================
660 //=============================================================================
662 GEOMImpl_IShapesOperations::MakeGlueFaces (std::list< Handle(GEOM_Object) >& theShapes,
663 const Standard_Real theTolerance,
664 const Standard_Boolean doKeepNonSolids)
668 Handle(TColStd_HSequenceOfTransient) objects = GEOM_Object::GetLastFunctions( theShapes );
669 if ( objects.IsNull() || objects->IsEmpty() ) {
670 SetErrorCode("NULL argument shape");
674 //Add a new Glued object
675 Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
677 //Add a new Glue function
678 Handle(GEOM_Function) aFunction;
679 aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_FACES);
680 if (aFunction.IsNull()) return NULL;
682 //Check if the function is set correctly
683 if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
685 GEOMImpl_IGlue aCI (aFunction);
687 aCI.SetBase( objects );
688 aCI.SetTolerance(theTolerance);
689 aCI.SetKeepNonSolids(doKeepNonSolids);
691 //Compute the sub-shape value
692 Standard_Boolean isWarning = Standard_False;
695 if (!GetSolver()->ComputeFunction(aFunction)) {
696 SetErrorCode("Shape driver failed to glue faces");
700 catch (Standard_Failure) {
701 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
702 SetErrorCode(aFail->GetMessageString());
703 // to provide warning
704 if (!aFunction->GetValue().IsNull()) {
705 isWarning = Standard_True;
711 //Make a Python command
712 GEOM::TPythonDump(aFunction) << aGlued << " = geompy.MakeGlueFaces("
713 << theShapes << ", " << theTolerance << ")";
715 // to provide warning
716 if (!isWarning) SetErrorCode(OK);
720 //=============================================================================
724 //=============================================================================
726 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetGlueFaces
727 (Handle(GEOM_Object) theShape,
728 const Standard_Real theTolerance)
732 if (theShape.IsNull()) return NULL;
733 TopoDS_Shape aShape = theShape->GetValue();
734 if (aShape.IsNull()) return NULL;
736 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
738 Standard_Integer iErr;
740 GEOMAlgo_Gluer1 aGluer;
741 GEOMAlgo_ListIteratorOfListOfCoupleOfShapes aItCS;
742 GEOMAlgo_CoupleOfShapes aCS;
743 GEOMAlgo_ListOfCoupleOfShapes aLCS;
745 //aGluer = new GEOMAlgo_Gluer1;
746 aGluer.SetShape(aShape);
747 aGluer.SetTolerance(theTolerance);
749 iErr = aGluer.ErrorStatus();
750 if (iErr) return NULL;
752 TopTools_ListOfShape listShape;
753 const GEOMAlgo_ListOfCoupleOfShapes& aLCSG = aGluer.GluedFaces();
755 aItCS.Initialize(aLCSG);
756 for (; aItCS.More(); aItCS.Next()) {
757 const GEOMAlgo_CoupleOfShapes& aCSG = aItCS.Value();
758 listShape.Append(aCSG.Shape1());
761 TopTools_ListIteratorOfListOfShape itSub (listShape);
762 TCollection_AsciiString anAsciiList, anEntry;
763 TopTools_IndexedMapOfShape anIndices;
764 TopExp::MapShapes(aShape, anIndices);
765 Handle(TColStd_HArray1OfInteger) anArray;
766 Handle(GEOM_Object) anObj;
767 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
768 TopoDS_Shape aValue = itSub.Value();
769 anArray = new TColStd_HArray1OfInteger(1,1);
770 anArray->SetValue(1, anIndices.FindIndex(aValue));
771 anObj = GetEngine()->AddSubShape(theShape, anArray);
772 if (!anObj.IsNull()) {
775 // for python command
776 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
777 anAsciiList += anEntry;
782 //Make a Python command
783 if( anAsciiList.Length() > 0 ) {
784 anAsciiList.Trunc(anAsciiList.Length() - 1);
785 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
786 GEOM::TPythonDump pd (aFunction, true);
787 pd << "[" << anAsciiList.ToCString();
788 pd << "] = geompy.GetGlueFaces(" << theShape << ", " << theTolerance << ")";
797 //=============================================================================
799 * MakeGlueFacesByList
801 //=============================================================================
803 GEOMImpl_IShapesOperations::MakeGlueFacesByList(std::list< Handle(GEOM_Object) >& theShapes,
804 const Standard_Real theTolerance,
805 std::list<Handle(GEOM_Object)> & theFaces,
806 const Standard_Boolean doKeepNonSolids,
807 const Standard_Boolean doGlueAllEdges)
811 Handle(TColStd_HSequenceOfTransient) objects = GEOM_Object::GetLastFunctions( theShapes );
812 if ( objects.IsNull() || objects->IsEmpty() ) {
813 SetErrorCode("NULL argument shape");
816 Handle(TColStd_HSequenceOfTransient) aFaces = GEOM_Object::GetLastFunctions( theFaces );
817 if ( aFaces.IsNull() ) {
818 SetErrorCode("NULL argument shape for the shape construction");
822 //Add a new Glued object
823 Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
825 //Add a new Glue function
826 Handle(GEOM_Function) aFunction;
827 aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_FACES_BY_LIST);
828 if (aFunction.IsNull()) return NULL;
830 //Check if the function is set correctly
831 if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
833 GEOMImpl_IGlue aCI (aFunction);
835 aCI.SetBase( objects );
836 aCI.SetTolerance(theTolerance);
837 aCI.SetKeepNonSolids(doKeepNonSolids);
838 aCI.SetGlueAllEdges(doGlueAllEdges);
839 aCI.SetFaces(aFaces);
841 //Compute the sub-shape value
842 Standard_Boolean isWarning = Standard_False;
845 if (!GetSolver()->ComputeFunction(aFunction)) {
846 SetErrorCode("Shape driver failed to glue faces");
850 catch (Standard_Failure) {
851 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
852 SetErrorCode(aFail->GetMessageString());
853 // to provide warning
854 if (!aFunction->GetValue().IsNull()) {
855 isWarning = Standard_True;
861 //Make a Python command
863 GEOM::TPythonDump pd(aFunction);
864 pd << aGlued << " = geompy.MakeGlueFacesByList("
865 << theShapes << ", " << theTolerance << ", " << theFaces << ", "
866 << (bool)doKeepNonSolids << ", " << (bool)doGlueAllEdges << ")";
868 // to provide warning
869 if (!isWarning) SetErrorCode(OK);
873 //=============================================================================
877 //=============================================================================
879 GEOMImpl_IShapesOperations::MakeGlueEdges (std::list< Handle(GEOM_Object) >& theShapes,
880 const Standard_Real theTolerance)
884 Handle(TColStd_HSequenceOfTransient) objects = GEOM_Object::GetLastFunctions( theShapes );
885 if ( objects.IsNull() || objects->IsEmpty() ) {
886 SetErrorCode("NULL argument shape");
890 //Add a new Glued object
891 Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
893 //Add a new Glue function
894 Handle(GEOM_Function) aFunction;
895 aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_EDGES);
896 if (aFunction.IsNull()) return NULL;
898 //Check if the function is set correctly
899 if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
901 GEOMImpl_IGlue aCI (aFunction);
903 aCI.SetBase( objects );
904 aCI.SetTolerance(theTolerance);
905 aCI.SetKeepNonSolids(true);
907 //Compute the sub-shape value
908 Standard_Boolean isWarning = Standard_False;
911 if (!GetSolver()->ComputeFunction(aFunction)) {
912 SetErrorCode("Shape driver failed to glue edges");
916 catch (Standard_Failure) {
917 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
918 SetErrorCode(aFail->GetMessageString());
919 // to provide warning
920 if (!aFunction->GetValue().IsNull()) {
921 isWarning = Standard_True;
927 //Make a Python command
928 GEOM::TPythonDump(aFunction) << aGlued << " = geompy.MakeGlueEdges("
929 << theShapes << ", " << theTolerance << ")";
931 // to provide warning
932 if (!isWarning) SetErrorCode(OK);
936 //=============================================================================
940 //=============================================================================
941 Handle(TColStd_HSequenceOfTransient)
942 GEOMImpl_IShapesOperations::GetGlueShapes (std::list< Handle(GEOM_Object) >& theShapes,
943 const Standard_Real theTolerance,
944 const TopAbs_ShapeEnum theType)
949 TopTools_SequenceOfShape shapes;
950 std::list< Handle(GEOM_Object) >::iterator s = theShapes.begin();
951 Handle(GEOM_Object) lastCreatedGO;
952 for ( ; s != theShapes.end(); ++s )
954 Handle(GEOM_Object) go = *s;
955 if ( go.IsNull() ) return NULL;
956 aShape = go->GetValue();
957 if ( aShape.IsNull() ) return NULL;
958 shapes.Append( aShape );
959 lastCreatedGO = GEOM::GetCreatedLast( lastCreatedGO, go );
961 if ( shapes.Length() > 1 )
963 TopoDS_Compound compound;
964 BRep_Builder builder;
965 builder.MakeCompound( compound );
966 for ( int i = 1; i <= shapes.Length(); ++i )
967 builder.Add( compound, shapes( i ) );
972 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
974 GEOMAlgo_GlueDetector aGluer;
975 aGluer.SetArgument(aShape);
976 aGluer.SetTolerance(theTolerance);
978 Standard_Integer iErr = aGluer.ErrorStatus();
979 if (iErr) return NULL;
981 std::vector< TopTools_IndexedMapOfShape* > anIndices( shapes.Length(), NULL );
982 Handle(TColStd_HArray1OfInteger) anArray;
983 Handle(GEOM_Object) anObj;
985 TopTools_ListOfShape listOnePerSet;
987 const TopTools_DataMapOfShapeListOfShape& aImages = aGluer.Images();
988 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape aItDMSLS (aImages);
989 for (int index = 1; aItDMSLS.More(); aItDMSLS.Next(), ++index) {
991 //const TopoDS_Shape& aSkey = aItDMSLS.Key();
993 // list of shapes of the argument that can be glued
994 const TopTools_ListOfShape& aLSD = aItDMSLS.Value();
996 //listShape.Append(aLSD.First());
997 TopoDS_Shape aValue = aLSD.First();
999 if (aValue.ShapeType() == theType) {
1000 listOnePerSet.Append(aValue);
1004 // for stable order of returned entities
1005 GEOMUtils::SortShapes(listOnePerSet, Standard_False);
1007 TopTools_ListIteratorOfListOfShape aListIt (listOnePerSet);
1008 for (; aListIt.More(); aListIt.Next())
1010 TopoDS_Shape aValue = aListIt.Value();
1011 // find a shape to add aValue as a sub-shape
1013 s = theShapes.begin();
1014 for ( int i = 0; i < shapes.Length(); ++i, ++s )
1016 Handle(GEOM_Object) object = *s;
1017 if ( !anIndices[i] ) {
1018 anIndices[i] = new TopTools_IndexedMapOfShape;
1019 TopExp::MapShapes( object->GetValue(), *anIndices[i]);
1021 if (int index = anIndices[i]->FindIndex( aValue )) {
1022 anArray = new TColStd_HArray1OfInteger(1,1);
1023 anArray->SetValue(1, index);
1024 anObj = GetEngine()->AddSubShape( object, anArray);
1028 if (!anObj.IsNull())
1029 aSeq->Append(anObj);
1031 for ( size_t i = 0 ; i < anIndices.size(); ++i )
1032 delete anIndices[i];
1034 // Make a Python command
1035 if ( aSeq->Length() > 0)
1037 Handle(GEOM_Function) aFunction = lastCreatedGO->GetLastFunction();
1038 GEOM::TPythonDump pd (aFunction, /*append=*/true);
1040 << " = geompy." << (theType == TopAbs_FACE ? "GetGlueFaces" : "GetGlueEdges" )
1041 << "( " << theShapes << ", " << theTolerance << ")";
1049 //=============================================================================
1051 * MakeGlueEdgesByList
1053 //=============================================================================
1055 GEOMImpl_IShapesOperations::MakeGlueEdgesByList (std::list< Handle(GEOM_Object) >& theShapes,
1056 const Standard_Real theTolerance,
1057 std::list<Handle(GEOM_Object)>& theEdges)
1061 Handle(TColStd_HSequenceOfTransient) objects = GEOM_Object::GetLastFunctions( theShapes );
1062 if ( objects.IsNull() || objects->IsEmpty() ) {
1063 SetErrorCode("NULL argument shape");
1066 Handle(TColStd_HSequenceOfTransient) anEdges = GEOM_Object::GetLastFunctions( theEdges );
1067 if ( anEdges.IsNull() ) {
1068 SetErrorCode("NULL argument shape for the shape construction");
1071 //Add a new Glued object
1072 Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
1074 //Add a new Glue function
1075 Handle(GEOM_Function) aFunction;
1076 aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_EDGES_BY_LIST);
1077 if (aFunction.IsNull()) return NULL;
1079 //Check if the function is set correctly
1080 if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
1082 GEOMImpl_IGlue aCI (aFunction);
1084 aCI.SetBase( objects );
1085 aCI.SetTolerance(theTolerance);
1086 aCI.SetKeepNonSolids(true);
1087 aCI.SetFaces(anEdges);
1089 //Compute the sub-shape value
1090 Standard_Boolean isWarning = Standard_False;
1093 if (!GetSolver()->ComputeFunction(aFunction)) {
1094 SetErrorCode("Shape driver failed to glue edges");
1098 catch (Standard_Failure) {
1099 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1100 SetErrorCode(aFail->GetMessageString());
1101 // to provide warning
1102 if (!aFunction->GetValue().IsNull()) {
1103 isWarning = Standard_True;
1109 //Make a Python command
1111 GEOM::TPythonDump pd (aFunction);
1112 pd << aGlued << " = geompy.MakeGlueEdgesByList("
1113 << theShapes << ", " << theTolerance << ", " << theEdges << " )";
1115 // to provide warning
1116 if (!isWarning) SetErrorCode(OK);
1120 //=============================================================================
1122 * GetExistingSubObjects
1124 //=============================================================================
1125 Handle(TColStd_HSequenceOfTransient)
1126 GEOMImpl_IShapesOperations::GetExistingSubObjects(Handle(GEOM_Object) theShape,
1127 const Standard_Boolean theGroupsOnly)
1129 // note: this method does not return fields
1131 Standard_Integer types = theGroupsOnly ? Groups : Groups|SubShapes;
1132 Handle(TColStd_HSequenceOfTransient) results = GetExistingSubObjects(theShape, types);
1134 if (results->Length() > 0) {
1135 //Make a Python command
1136 TCollection_AsciiString anAsciiList;
1137 for (int i = 1; i <= results->Length(); i++)
1139 Handle(GEOM_BaseObject) obj = Handle(GEOM_BaseObject)::DownCast( results->Value(i));
1140 obj->GetEntryString();
1141 if ( i < results->Length() )
1145 GEOM::TPythonDump pd (theShape->GetLastFunction(), /*append=*/true);
1146 pd << "[" << anAsciiList.ToCString();
1147 pd << "] = geompy.GetExistingSubObjects(";
1148 pd << theShape << ", " << (bool)theGroupsOnly << ")";
1154 Handle(TColStd_HSequenceOfTransient)
1155 GEOMImpl_IShapesOperations::GetExistingSubObjects(Handle(GEOM_Object) theShape,
1156 const Standard_Integer theTypes)
1160 if (theShape.IsNull()) return NULL;
1162 Handle(GEOM_Function) aMainShape = theShape->GetLastFunction();
1163 if (aMainShape.IsNull()) return NULL;
1165 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1166 SetErrorCode(NOT_FOUND_ANY);
1168 if (!aMainShape->HasSubShapeReferences()) return aSeq;
1169 const TDataStd_ListOfExtendedString& aListEntries = aMainShape->GetSubShapeReferences();
1170 if (aListEntries.IsEmpty()) return aSeq;
1174 TDataStd_ListIteratorOfListOfExtendedString anIt (aListEntries);
1175 for (; anIt.More(); anIt.Next()) {
1176 TCollection_ExtendedString anEntry = anIt.Value();
1177 Standard_Integer aStrLen = anEntry.LengthOfCString();
1178 char* anEntryStr = new char[aStrLen+1];
1179 anEntry.ToUTF8CString(anEntryStr);
1180 Handle(GEOM_BaseObject) anObj = GetEngine()->GetObject(GetDocID(), anEntryStr, false);
1181 if (!anObj.IsNull() ) {
1182 bool isGroup = anObj->IsKind(STANDARD_TYPE(GEOM_Object)) && anObj->GetType() == GEOM_GROUP;
1183 bool isSubShape = anObj->IsKind(STANDARD_TYPE(GEOM_Object)) && anObj->GetType() != GEOM_GROUP;
1184 bool isField = anObj->IsKind(STANDARD_TYPE(GEOM_Field));
1185 if (theTypes & Groups && isGroup ||
1186 theTypes & SubShapes && isSubShape ||
1187 theTypes & Fields && isField) {
1188 aSeq->Append(anObj);
1191 delete [] anEntryStr;
1194 if (aSeq->Length() == 0) {
1195 SetErrorCode(NOT_FOUND_ANY);
1204 //=============================================================================
1208 //=============================================================================
1209 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::MakeExplode
1210 (Handle(GEOM_Object) theShape,
1211 const Standard_Integer theShapeType,
1212 const Standard_Boolean isSorted,
1213 const ExplodeType theExplodeType)
1217 if (theShape.IsNull()) return NULL;
1218 TopoDS_Shape aShape = theShape->GetValue();
1219 if (aShape.IsNull()) return NULL;
1221 Handle(GEOM_Function) aMainShape = theShape->GetLastFunction();
1223 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1224 Handle(GEOM_Object) anObj;
1225 TopTools_MapOfShape mapShape;
1226 TopTools_ListOfShape listShape;
1228 if (aShape.ShapeType() == TopAbs_COMPOUND &&
1229 (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
1230 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPSOLID ||
1231 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPOUND))
1233 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
1234 for (; It.More(); It.Next()) {
1235 if (mapShape.Add(It.Value())) {
1236 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
1237 TopAbs_ShapeEnum(theShapeType) == It.Value().ShapeType()) {
1238 listShape.Append(It.Value());
1243 else if (theExplodeType != EXPLODE_NEW_EXCLUDE_MAIN || aShape.ShapeType() != theShapeType) // issue 0021079
1245 TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
1246 for (; exp.More(); exp.Next())
1247 if (mapShape.Add(exp.Current()))
1248 listShape.Append(exp.Current());
1251 if (listShape.IsEmpty()) {
1252 //SetErrorCode("The given shape has no sub-shapes of the requested type");
1253 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
1258 bool isOldSorting = false;
1259 if (theExplodeType == EXPLODE_OLD_INCLUDE_MAIN)
1260 isOldSorting = true;
1261 GEOMUtils::SortShapes(listShape, isOldSorting);
1264 TopTools_IndexedMapOfShape anIndices;
1265 TopExp::MapShapes(aShape, anIndices);
1266 Handle(TColStd_HArray1OfInteger) anArray;
1268 TopTools_ListIteratorOfListOfShape itSub (listShape);
1269 TCollection_AsciiString anAsciiList, anEntry;
1270 for (int index = 1; itSub.More(); itSub.Next(), ++index)
1272 TopoDS_Shape aValue = itSub.Value();
1273 anArray = new TColStd_HArray1OfInteger(1,1);
1274 anArray->SetValue(1, anIndices.FindIndex(aValue));
1276 //anObj = GetEngine()->AddSubShape(theShape, anArray);
1278 anObj = GetEngine()->AddObject(GetDocID(), GEOM_SUBSHAPE);
1279 Handle(GEOM_Function) aFunction = anObj->AddFunction(GEOM_Object::GetSubShapeID(), 1);
1280 if (aFunction.IsNull()) return aSeq;
1282 GEOM_ISubShape aSSI (aFunction);
1283 aSSI.SetMainShape(aMainShape);
1284 aSSI.SetIndices(anArray);
1286 // Set function value directly, as we know it.
1287 // Usage of Solver here would lead to significant loss of time,
1288 // because GEOM_SubShapeDriver will build TopTools_IndexedMapOfShape
1289 // on the main shape for each being calculated sub-shape separately.
1290 aFunction->SetValue(aValue);
1292 // Put this subshape in the list of sub-shapes of theMainShape
1293 aMainShape->AddSubShapeReference(aFunction);
1296 if (!anObj.IsNull()) {
1297 aSeq->Append(anObj);
1299 // for python command
1300 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
1301 anAsciiList += anEntry;
1306 //Make a Python command
1307 anAsciiList.Trunc(anAsciiList.Length() - 1);
1309 GEOM::TPythonDump pd (aMainShape, /*append=*/true);
1310 pd << "[" << anAsciiList.ToCString() << "] = geompy.";
1311 switch (theExplodeType) {
1312 case EXPLODE_NEW_EXCLUDE_MAIN:
1313 pd << "ExtractShapes(" << theShape << ", "
1314 << TopAbs_ShapeEnum(theShapeType) << ", " << (isSorted ? "True" : "False") << ")";
1316 case EXPLODE_NEW_INCLUDE_MAIN:
1317 pd << "SubShapeAll" << (isSorted ? "SortedCentres(" : "(")
1318 << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
1320 case EXPLODE_OLD_INCLUDE_MAIN:
1321 pd << "SubShapeAll" << (isSorted ? "Sorted(" : "(")
1322 << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
1331 //=============================================================================
1335 //=============================================================================
1336 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::SubShapeAllIDs
1337 (Handle(GEOM_Object) theShape,
1338 const Standard_Integer theShapeType,
1339 const Standard_Boolean isSorted,
1340 const ExplodeType theExplodeType)
1344 if (theShape.IsNull()) return NULL;
1345 TopoDS_Shape aShape = theShape->GetValue();
1346 if (aShape.IsNull()) return NULL;
1348 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
1349 TopTools_MapOfShape mapShape;
1350 TopTools_ListOfShape listShape;
1352 if (aShape.ShapeType() == TopAbs_COMPOUND &&
1353 (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
1354 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPSOLID ||
1355 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPOUND))
1357 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
1358 for (; It.More(); It.Next()) {
1359 if (mapShape.Add(It.Value())) {
1360 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
1361 TopAbs_ShapeEnum(theShapeType) == It.Value().ShapeType()) {
1362 listShape.Append(It.Value());
1367 else if (theExplodeType != EXPLODE_NEW_EXCLUDE_MAIN || aShape.ShapeType() != theShapeType) // issue 0021079
1369 TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
1370 for (; exp.More(); exp.Next())
1371 if (mapShape.Add(exp.Current()))
1372 listShape.Append(exp.Current());
1375 if (listShape.IsEmpty()) {
1376 //SetErrorCode("The given shape has no sub-shapes of the requested type");
1377 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
1382 bool isOldSorting = false;
1383 if (theExplodeType == EXPLODE_OLD_INCLUDE_MAIN)
1384 isOldSorting = true;
1385 GEOMUtils::SortShapes(listShape, isOldSorting);
1388 TopTools_IndexedMapOfShape anIndices;
1389 TopExp::MapShapes(aShape, anIndices);
1390 Handle(TColStd_HArray1OfInteger) anArray;
1392 TopTools_ListIteratorOfListOfShape itSub (listShape);
1393 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
1394 TopoDS_Shape aValue = itSub.Value();
1395 aSeq->Append(anIndices.FindIndex(aValue));
1398 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
1400 //Make a Python command
1401 GEOM::TPythonDump pd (aFunction, /*append=*/true);
1402 pd << "listSubShapeIDs = geompy.SubShapeAll";
1403 switch (theExplodeType) {
1404 case EXPLODE_NEW_EXCLUDE_MAIN:
1406 case EXPLODE_NEW_INCLUDE_MAIN:
1407 pd << (isSorted ? "SortedCentresIDs(" : "IDs(")
1408 << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
1410 case EXPLODE_OLD_INCLUDE_MAIN:
1411 pd << (isSorted ? "SortedIDs(" : "IDs(")
1412 << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
1421 //=============================================================================
1425 //=============================================================================
1426 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetSubShape
1427 (Handle(GEOM_Object) theMainShape,
1428 const Standard_Integer theID)
1432 if (theMainShape.IsNull()) return NULL;
1434 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
1435 anArray->SetValue(1, theID);
1436 Handle(GEOM_Object) anObj = GetEngine()->AddSubShape(theMainShape, anArray,true);
1437 if (anObj.IsNull()) {
1438 SetErrorCode("Can not get a sub-shape with the given ID");
1442 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1444 //Make a Python command
1445 GEOM::TPythonDump(aFunction) << anObj << " = geompy.GetSubShape("
1446 << theMainShape << ", [" << theID << "])";
1452 //=============================================================================
1456 //=============================================================================
1457 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::MakeSubShapes
1458 (Handle(GEOM_Object) theMainShape,
1459 Handle(TColStd_HArray1OfInteger) theIndices)
1463 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1465 if (!theIndices->Length()) {
1466 SetErrorCode(NOT_FOUND_ANY);
1470 if (theMainShape.IsNull()) return NULL;
1471 TopoDS_Shape aShape = theMainShape->GetValue();
1472 if (aShape.IsNull()) return NULL;
1474 Handle(GEOM_Function) aMainShape = theMainShape->GetLastFunction();
1476 TopTools_IndexedMapOfShape anIndices;
1477 TopExp::MapShapes(aShape, anIndices);
1479 Handle(TColStd_HArray1OfInteger) anArray;
1480 Handle(GEOM_Object) anObj;
1482 TCollection_AsciiString anAsciiList, anEntry;
1483 Standard_Integer i, low = theIndices->Lower(), up = theIndices->Upper();
1484 for (i = low; i <= up; i++) {
1485 int id = theIndices->Value(i);
1486 if (1 <= id && id <= anIndices.Extent()) {
1487 TopoDS_Shape aValue = anIndices.FindKey(id);
1488 anArray = new TColStd_HArray1OfInteger(1,1);
1489 anArray->SetValue(1, id);
1491 anObj = GetEngine()->AddObject(GetDocID(), GEOM_SUBSHAPE);
1492 if (!anObj.IsNull()) {
1493 Handle(GEOM_Function) aFunction = anObj->AddFunction(GEOM_Object::GetSubShapeID(), 1);
1494 if (aFunction.IsNull()) return aSeq;
1496 GEOM_ISubShape aSSI (aFunction);
1497 aSSI.SetMainShape(aMainShape);
1498 aSSI.SetIndices(anArray);
1500 // Set function value directly, as we know it.
1501 // Usage of Solver here would lead to significant loss of time,
1502 // because GEOM_SubShapeDriver will build TopTools_IndexedMapOfShape
1503 // on the main shape for each being calculated sub-shape separately.
1504 aFunction->SetValue(aValue);
1506 // Put this sub-shape in the list of sub-shapes of theMainShape
1507 aMainShape->AddSubShapeReference(aFunction);
1509 aSeq->Append(anObj);
1511 // for python command
1512 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
1513 anAsciiList += anEntry;
1519 //Make a Python command
1520 anAsciiList.Trunc(anAsciiList.Length() - 1);
1522 GEOM::TPythonDump pd (aMainShape, /*append=*/true);
1523 pd << "[" << anAsciiList.ToCString() << "] = geompy.SubShapes("
1524 << theMainShape << ", [" ;
1525 for (i = low; i <= up - 1; i++) {
1526 pd << theIndices->Value(i) << ", ";
1528 pd << theIndices->Value(up) << "])";
1535 //=============================================================================
1539 //=============================================================================
1540 Standard_Integer GEOMImpl_IShapesOperations::GetSubShapeIndex (Handle(GEOM_Object) theMainShape,
1541 Handle(GEOM_Object) theSubShape)
1545 TopoDS_Shape aMainShape = theMainShape->GetValue();
1546 TopoDS_Shape aSubShape = theSubShape->GetValue();
1548 if (aMainShape.IsNull() || aSubShape.IsNull()) return -1;
1550 TopTools_IndexedMapOfShape anIndices;
1551 TopExp::MapShapes(aMainShape, anIndices);
1552 // if (anIndices.Contains(aSubShape)) {
1553 // SetErrorCode(OK);
1554 // return anIndices.FindIndex(aSubShape);
1556 int id = anIndices.FindIndex(aSubShape);
1567 //=============================================================================
1569 * GetSubShapeIndices
1571 //=============================================================================
1572 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetSubShapesIndices (Handle(GEOM_Object) theMainShape,
1573 std::list<Handle(GEOM_Object)> theSubShapes)
1575 MESSAGE("GEOMImpl_IShapesOperations::GetSubShapesIndices")
1578 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
1580 TopoDS_Shape aMainShape = theMainShape->GetValue();
1581 if (aMainShape.IsNull())
1583 MESSAGE("NULL main shape")
1587 TopTools_IndexedMapOfShape anIndices;
1588 TopExp::MapShapes(aMainShape, anIndices);
1590 std::list<Handle(GEOM_Object)>::iterator it;
1591 for (it=theSubShapes.begin(); it != theSubShapes.end(); ++it)
1593 TopoDS_Shape aSubShape = (*it)->GetValue();
1594 if (aSubShape.IsNull())
1596 MESSAGE("NULL subshape")
1599 int id = anIndices.FindIndex(aSubShape);
1608 //=============================================================================
1612 //=============================================================================
1613 Standard_Integer GEOMImpl_IShapesOperations::GetTopologyIndex (Handle(GEOM_Object) theMainShape,
1614 Handle(GEOM_Object) theSubShape)
1618 TopoDS_Shape aMainShape = theMainShape->GetValue();
1619 TopoDS_Shape aSubShape = theSubShape->GetValue();
1621 if (aMainShape.IsNull() || aSubShape.IsNull()) {
1622 SetErrorCode("Null argument shape given");
1627 if (aSubShape.ShapeType() == TopAbs_COMPOUND) {
1629 TopTools_ListOfShape CL;
1630 CL.Append(aMainShape);
1631 TopTools_ListIteratorOfListOfShape itC;
1632 for (itC.Initialize(CL); itC.More(); itC.Next()) {
1633 for (it.Initialize(itC.Value()); it.More(); it.Next()) {
1634 if (it.Value().ShapeType() == TopAbs_COMPOUND) {
1635 if (it.Value().IsSame(aSubShape))
1639 CL.Append(it.Value());
1644 TopExp_Explorer anExp (aMainShape, aSubShape.ShapeType());
1645 TopTools_MapOfShape M;
1646 for (; anExp.More(); anExp.Next()) {
1647 if (M.Add(anExp.Current())) {
1648 if (anExp.Current().IsSame(aSubShape))
1655 SetErrorCode("The sub-shape does not belong to the main shape");
1659 //=============================================================================
1661 * GetShapeTypeString
1663 //=============================================================================
1664 TCollection_AsciiString GEOMImpl_IShapesOperations::GetShapeTypeString (Handle(GEOM_Object) theShape)
1668 TCollection_AsciiString aTypeName ("Null Shape");
1670 TopoDS_Shape aShape = theShape->GetValue();
1671 if (aShape.IsNull())
1674 switch (aShape.ShapeType() )
1676 case TopAbs_COMPOUND:
1677 aTypeName = "Compound";
1679 case TopAbs_COMPSOLID:
1680 aTypeName = "Compound Solid";
1683 aTypeName = "Solid";
1686 aTypeName = "Shell";
1690 BRepAdaptor_Surface surf (TopoDS::Face(aShape));
1691 if (surf.GetType() == GeomAbs_Plane)
1692 aTypeName = "Plane";
1693 else if (surf.GetType() == GeomAbs_Cylinder)
1694 aTypeName = "Cylindrical Face";
1695 else if (surf.GetType() == GeomAbs_Sphere)
1696 aTypeName = "Spherical Face";
1697 else if (surf.GetType() == GeomAbs_Torus)
1698 aTypeName = "Toroidal Face";
1699 else if (surf.GetType() == GeomAbs_Cone)
1700 aTypeName = "Conical Face";
1702 aTypeName = "GEOM::FACE";
1710 BRepAdaptor_Curve curv (TopoDS::Edge(aShape));
1711 if (curv.GetType() == GeomAbs_Line) {
1712 if ((Abs(curv.FirstParameter()) >= 1E6) ||
1713 (Abs(curv.LastParameter()) >= 1E6))
1717 } else if (curv.GetType() == GeomAbs_Circle) {
1718 if (curv.IsClosed())
1719 aTypeName = "Circle";
1728 aTypeName = "Vertex";
1731 aTypeName = "Shape";
1734 aTypeName = "Shape of unknown type";
1740 //=============================================================================
1744 //=============================================================================
1745 Standard_Integer GEOMImpl_IShapesOperations::NumberOfSubShapes
1746 (Handle(GEOM_Object) theShape,
1747 const Standard_Integer theShapeType)
1750 Standard_Integer nbShapes = 0;
1752 if (theShape.IsNull()) return -1;
1753 TopoDS_Shape aShape = theShape->GetValue();
1754 if (aShape.IsNull()) return -1;
1757 TopTools_MapOfShape mapShape;
1759 if (aShape.ShapeType() == TopAbs_COMPOUND &&
1760 (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
1761 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPSOLID ||
1762 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPOUND)) {
1763 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
1764 for (; It.More(); It.Next()) {
1765 if (mapShape.Add(It.Value())) {
1766 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
1767 TopAbs_ShapeEnum(theShapeType) == It.Value().ShapeType()) {
1773 TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
1774 for (; exp.More(); exp.Next())
1775 if (mapShape.Add(exp.Current()))
1782 int iType, nbTypes [TopAbs_SHAPE];
1783 for (iType = 0; iType < TopAbs_SHAPE; ++iType)
1785 nbTypes[aShape.ShapeType()]++;
1787 TopTools_MapOfShape aMapOfShape;
1788 aMapOfShape.Add(aShape);
1789 TopTools_ListOfShape aListOfShape;
1790 aListOfShape.Append(aShape);
1792 TopTools_ListIteratorOfListOfShape itL (aListOfShape);
1793 for (; itL.More(); itL.Next()) {
1794 TopoDS_Iterator it (itL.Value());
1795 for (; it.More(); it.Next()) {
1796 TopoDS_Shape s = it.Value();
1797 if (aMapOfShape.Add(s)) {
1798 aListOfShape.Append(s);
1799 nbTypes[s.ShapeType()]++;
1804 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE)
1805 nbShapes = aMapOfShape.Extent();
1807 nbShapes = nbTypes[theShapeType];
1809 catch (Standard_Failure) {
1810 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1811 SetErrorCode(aFail->GetMessageString());
1819 //=============================================================================
1823 //=============================================================================
1824 Handle(GEOM_Object) GEOMImpl_IShapesOperations::ReverseShape(Handle(GEOM_Object) theShape)
1828 if (theShape.IsNull()) return NULL;
1831 //Add a new reversed object
1832 Handle(GEOM_Object) aReversed = GetEngine()->AddObject(GetDocID(), theShape->GetType());
1834 //Add a new Revese function
1835 Handle(GEOM_Function) aFunction;
1836 aFunction = aReversed->AddFunction(GEOMImpl_ShapeDriver::GetID(), REVERSE_ORIENTATION);
1837 if (aFunction.IsNull()) return NULL;
1839 //Check if the function is set correctly
1840 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
1842 GEOMImpl_IShapes aSI (aFunction);
1844 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
1845 if (aRefShape.IsNull()) return NULL;
1847 aSI.SetBase(aRefShape);
1849 //Compute the sub-shape value
1852 if (!GetSolver()->ComputeFunction(aFunction)) {
1853 SetErrorCode("Shape driver failed to reverse shape");
1857 catch (Standard_Failure) {
1858 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1859 SetErrorCode(aFail->GetMessageString());
1863 //Make a Python command
1864 GEOM::TPythonDump(aFunction) << aReversed
1865 << " = geompy.ChangeOrientation(" << theShape << ")";
1870 Handle(GEOM_Object) aReversed;
1872 GEOM_Engine* anEngine = GetEngine();
1873 //GEOMImpl_Gen* aGen = dynamic_cast<GEOMImpl_Gen*>(anEngine);
1874 GEOMImpl_Gen* aGen = (GEOMImpl_Gen*)anEngine;
1877 GEOMImpl_IHealingOperations* anIHealingOperations =
1878 aGen->GetIHealingOperations(GetDocID());
1879 aReversed = anIHealingOperations->ChangeOrientationCopy(theShape);
1880 SetErrorCode(anIHealingOperations->GetErrorCode());
1886 //=============================================================================
1890 //=============================================================================
1891 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetFreeFacesIDs
1892 (Handle(GEOM_Object) theShape)
1896 if (theShape.IsNull()) return NULL;
1897 TopoDS_Shape aShape = theShape->GetValue();
1898 if (aShape.IsNull()) return NULL;
1900 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
1902 TopTools_IndexedDataMapOfShapeListOfShape mapFaceBlocks;
1903 GEOMImpl_Block6Explorer::MapShapesAndAncestors
1904 (aShape, TopAbs_FACE, TopAbs_SOLID, mapFaceBlocks);
1906 Standard_Integer ind = 1, nbFaces = mapFaceBlocks.Extent();
1909 SetErrorCode("The given shape has no faces");
1913 TopTools_IndexedMapOfShape anIndices;
1914 TopExp::MapShapes(aShape, anIndices);
1916 Standard_Integer id;
1917 for (; ind <= nbFaces; ind++) {
1918 if (mapFaceBlocks.FindFromIndex(ind).Extent() != 2) {
1919 id = anIndices.FindIndex(mapFaceBlocks.FindKey(ind));
1924 //The explode doesn't change object so no new function is required.
1925 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
1927 //Make a Python command
1928 GEOM::TPythonDump(aFunction, /*append=*/true)
1929 << "listFreeFacesIDs = geompy.GetFreeFacesIDs(" << theShape << ")";
1935 //=======================================================================
1936 //function : GetSharedShapes
1938 //=======================================================================
1939 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetSharedShapes
1940 (Handle(GEOM_Object) theShape1,
1941 Handle(GEOM_Object) theShape2,
1942 const Standard_Integer theShapeType)
1946 if (theShape1.IsNull() || theShape2.IsNull()) return NULL;
1948 TopoDS_Shape aShape1 = theShape1->GetValue();
1949 TopoDS_Shape aShape2 = theShape2->GetValue();
1951 if (aShape1.IsNull() || aShape2.IsNull()) return NULL;
1953 TopTools_IndexedMapOfShape anIndices;
1954 TopExp::MapShapes(aShape1, anIndices);
1955 Handle(TColStd_HArray1OfInteger) anArray;
1957 TopTools_IndexedMapOfShape mapShape1;
1958 TopExp::MapShapes(aShape1, TopAbs_ShapeEnum(theShapeType), mapShape1);
1960 Handle(GEOM_Object) anObj;
1961 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1962 TCollection_AsciiString anAsciiList, anEntry;
1964 TopTools_MapOfShape mapShape2;
1965 TopExp_Explorer exp (aShape2, TopAbs_ShapeEnum(theShapeType));
1966 for (; exp.More(); exp.Next()) {
1967 TopoDS_Shape aSS = exp.Current();
1968 if (mapShape2.Add(aSS) && mapShape1.Contains(aSS)) {
1969 anArray = new TColStd_HArray1OfInteger(1,1);
1970 anArray->SetValue(1, anIndices.FindIndex(aSS));
1971 anObj = GetEngine()->AddSubShape(theShape1, anArray);
1972 aSeq->Append(anObj);
1974 // for python command
1975 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
1976 anAsciiList += anEntry;
1981 if (aSeq->IsEmpty()) {
1982 SetErrorCode("The given shapes have no shared sub-shapes of the requested type");
1986 //Make a Python command
1987 anAsciiList.Trunc(anAsciiList.Length() - 1);
1989 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1991 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
1992 << "] = geompy.GetSharedShapes(" << theShape1 << ", "
1993 << theShape2 << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
1999 //=======================================================================
2000 //function : GetSharedShapes
2002 //=======================================================================
2003 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetSharedShapes
2004 (std::list<Handle(GEOM_Object)> & theShapes,
2005 const Standard_Integer theShapeType)
2009 int aLen = theShapes.size();
2010 if (aLen < 1) return NULL;
2013 std::list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
2015 Handle(GEOM_Object) aMainObj = *it;
2016 Handle(GEOM_Function) aMainShape = aMainObj->GetLastFunction();
2018 TopTools_SequenceOfShape shapeSeq;
2019 for (; it != theShapes.end(); it++, ind++) {
2020 Handle(GEOM_Function) aRefShape = (*it)->GetLastFunction();
2021 if (aRefShape.IsNull()) {
2022 SetErrorCode("NULL shape for GetSharedShapes");
2025 TopoDS_Shape aShape2 = aRefShape->GetValue();
2026 if (aShape2.IsNull()) return NULL;
2027 shapeSeq.Append( aShape2 );
2030 TopoDS_Shape aShape1 = shapeSeq.First();
2032 if ( shapeSeq.Length() == 1 )
2035 for ( TopoDS_Iterator it( aShape1); it.More(); it.Next() )
2036 shapeSeq.Append( it.Value() );
2037 aShape1 = shapeSeq.First();
2040 TopTools_IndexedMapOfShape anIndices;
2041 TopExp::MapShapes(aMainShape->GetValue(), anIndices);
2043 TopTools_IndexedMapOfShape mapSelected;
2044 TopExp::MapShapes(aShape1, TopAbs_ShapeEnum(theShapeType), mapSelected);
2046 // Find shared shapes
2048 TopoDS_Compound aCurrSelection;
2050 for ( ind = 2; ind <= shapeSeq.Length(); ind++) {
2052 TopoDS_Compound aCompound;
2053 B.MakeCompound(aCompound);
2055 const TopoDS_Shape& aShape2 = shapeSeq.Value( ind );
2057 TopTools_MapOfShape mapShape2;
2058 TopExp_Explorer exp (aShape2, TopAbs_ShapeEnum(theShapeType));
2059 for (; exp.More(); exp.Next()) {
2060 const TopoDS_Shape& aSS = exp.Current();
2061 if (mapShape2.Add(aSS) && mapSelected.Contains(aSS)) {
2062 B.Add(aCompound, aSS);
2066 mapSelected.Clear();
2067 TopExp::MapShapes(aCompound, TopAbs_ShapeEnum(theShapeType), mapSelected);
2068 aCurrSelection = aCompound;
2071 // Create GEOM_Object for each found shared shape (collected in aCurrSelection)
2072 Handle(GEOM_Object) anObj, aLastCreated;
2073 Handle(TColStd_HArray1OfInteger) anArray;
2074 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
2075 TCollection_AsciiString anAsciiList, anEntry;
2077 TopoDS_Iterator itSel (aCurrSelection, Standard_True, Standard_True);
2078 for (; itSel.More(); itSel.Next()) {
2079 anArray = new TColStd_HArray1OfInteger(1,1);
2080 anArray->SetValue(1, anIndices.FindIndex(itSel.Value()));
2081 anObj = GetEngine()->AddSubShape(aMainObj, anArray);
2082 aSeq->Append(anObj);
2084 aLastCreated = GEOM::GetCreatedLast( aLastCreated, anObj );
2086 // for python command
2087 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
2088 anAsciiList += anEntry;
2092 if (aSeq->IsEmpty()) {
2093 SetErrorCode("The given shapes have no shared sub-shapes of the requested type");
2097 // Make a Python command
2098 anAsciiList.Trunc(anAsciiList.Length() - 1);
2100 // IPAL22904: TC6.5.0: order of python commands is wrong after dump study
2101 // Get the function of the latest published object
2102 Handle(GEOM_Function) aFunction = aLastCreated->GetLastFunction();
2103 if( aFunction.IsNull() ) // just in case
2104 aFunction = aMainShape;
2106 GEOM::TPythonDump pd (aFunction, /*append=*/true);
2107 pd << "[" << anAsciiList.ToCString()
2108 << "] = geompy.GetSharedShapesMulti([";
2110 it = theShapes.begin();
2112 while (it != theShapes.end()) {
2113 pd << ", " << (*it++);
2116 pd << "], " << TopAbs_ShapeEnum(theShapeType) << ")";
2122 //=============================================================================
2126 //=============================================================================
2127 static GEOM::TPythonDump& operator<< (GEOM::TPythonDump& theDump,
2128 const GEOMAlgo_State theState)
2131 case GEOMAlgo_ST_IN:
2132 theDump << "GEOM.ST_IN";
2134 case GEOMAlgo_ST_OUT:
2135 theDump << "GEOM.ST_OUT";
2137 case GEOMAlgo_ST_ON:
2138 theDump << "GEOM.ST_ON";
2140 case GEOMAlgo_ST_ONIN:
2141 theDump << "GEOM.ST_ONIN";
2143 case GEOMAlgo_ST_ONOUT:
2144 theDump << "GEOM.ST_ONOUT";
2147 theDump << "GEOM.ST_UNKNOWN";
2153 //=======================================================================
2154 //function : checkTypeShapesOn
2156 * \brief Checks if theShapeType parameter of GetShapesOnXXX() is OK
2157 * \param theShapeType - the shape type to check
2158 * \retval bool - result of the check
2160 //=======================================================================
2161 bool GEOMImpl_IShapesOperations::checkTypeShapesOn(const Standard_Integer theShapeType)
2163 if (theShapeType != TopAbs_VERTEX &&
2164 theShapeType != TopAbs_EDGE &&
2165 theShapeType != TopAbs_FACE &&
2166 theShapeType != TopAbs_SOLID) {
2167 SetErrorCode("Only solids, vertices, edges or faces can be found by this method");
2173 //=======================================================================
2174 //function : makePlane
2176 * \brief Creates Geom_Plane
2177 * \param theAx1 - shape object defining plane parameters
2178 * \retval Handle(Geom_Surface) - resulting surface
2180 //=======================================================================
2181 Handle(Geom_Surface) GEOMImpl_IShapesOperations::makePlane(const TopoDS_Shape& anAx1)
2183 if (anAx1.ShapeType() != TopAbs_EDGE) return NULL;
2184 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
2185 TopoDS_Vertex V1, V2;
2186 TopExp::Vertices(anEdge, V1, V2, Standard_True);
2187 if (V1.IsNull() || V2.IsNull()) {
2188 SetErrorCode("Bad edge given for the plane normal vector");
2191 gp_Pnt aLoc = BRep_Tool::Pnt(V1);
2192 gp_Vec aVec (aLoc, BRep_Tool::Pnt(V2));
2193 if (aVec.Magnitude() < Precision::Confusion()) {
2194 SetErrorCode("Vector with null magnitude given");
2197 return new Geom_Plane(aLoc, aVec);
2200 //=======================================================================
2201 //function : makeCylinder
2203 * \brief Creates Geom_CylindricalSurface
2204 * \param theAx1 - edge defining cylinder axis
2205 * \param theRadius - cylinder radius
2206 * \retval Handle(Geom_Surface) - resulting surface
2208 //=======================================================================
2209 Handle(Geom_Surface) GEOMImpl_IShapesOperations::makeCylinder(const TopoDS_Shape& anAxis,
2210 const Standard_Real theRadius)
2212 //Axis of the cylinder
2213 if (anAxis.ShapeType() != TopAbs_EDGE) {
2214 SetErrorCode("Not an edge given for the axis");
2217 TopoDS_Edge anEdge = TopoDS::Edge(anAxis);
2218 TopoDS_Vertex V1, V2;
2219 TopExp::Vertices(anEdge, V1, V2, Standard_True);
2220 if (V1.IsNull() || V2.IsNull()) {
2221 SetErrorCode("Bad edge given for the axis");
2224 gp_Pnt aLoc = BRep_Tool::Pnt(V1);
2225 gp_Vec aVec (aLoc, BRep_Tool::Pnt(V2));
2226 if (aVec.Magnitude() < Precision::Confusion()) {
2227 SetErrorCode("Vector with null magnitude given");
2231 gp_Ax3 anAx3 (aLoc, aVec);
2232 return new Geom_CylindricalSurface(anAx3, theRadius);
2235 //=======================================================================
2236 //function : getShapesOnBoxIDs
2238 * \brief Find IDs of sub-shapes complying with given status about surface
2239 * \param theBox - the box to check state of sub-shapes against
2240 * \param theShape - the shape to explore
2241 * \param theShapeType - type of sub-shape of theShape
2242 * \param theState - required state
2243 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
2245 //=======================================================================
2246 Handle(TColStd_HSequenceOfInteger)
2247 GEOMImpl_IShapesOperations::getShapesOnBoxIDs(const Handle(GEOM_Object)& theBox,
2248 const Handle(GEOM_Object)& theShape,
2249 const Standard_Integer theShapeType,
2250 GEOMAlgo_State theState)
2252 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
2254 TopoDS_Shape aBox = theBox->GetValue();
2255 TopoDS_Shape aShape = theShape->GetValue();
2257 // Check presence of triangulation, build if need
2258 if (!GEOMUtils::CheckTriangulation(aShape)) {
2259 SetErrorCode("Cannot build triangulation on the shape");
2264 GEOMAlgo_FinderShapeOn2 aFinder;
2265 Standard_Real aTol = 0.0001; // default value
2267 Handle(GEOMAlgo_ClsfBox) aClsfBox = new GEOMAlgo_ClsfBox;
2268 aClsfBox->SetBox(aBox);
2270 aFinder.SetShape(aShape);
2271 aFinder.SetTolerance(aTol);
2272 aFinder.SetClsf(aClsfBox);
2273 aFinder.SetShapeType( (TopAbs_ShapeEnum)theShapeType );
2274 aFinder.SetState(theState);
2277 // Interprete results
2278 Standard_Integer iErr = aFinder.ErrorStatus();
2279 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
2281 MESSAGE(" iErr : " << iErr);
2282 TCollection_AsciiString aMsg (" iErr : ");
2283 aMsg += TCollection_AsciiString(iErr);
2287 Standard_Integer iWrn = aFinder.WarningStatus();
2288 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
2290 MESSAGE(" *** iWrn : " << iWrn);
2293 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
2295 if (listSS.Extent() < 1) {
2296 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
2297 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
2301 // Fill sequence of object IDs
2302 aSeqOfIDs = new TColStd_HSequenceOfInteger;
2304 TopTools_IndexedMapOfShape anIndices;
2305 TopExp::MapShapes(aShape, anIndices);
2307 TopTools_ListIteratorOfListOfShape itSub (listSS);
2308 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
2309 int id = anIndices.FindIndex(itSub.Value());
2310 aSeqOfIDs->Append(id);
2316 //=======================================================================
2317 //function : GetShapesOnBoxIDs
2319 * \brief Find sub-shapes complying with given status about surface
2320 * \param theBox - the box to check state of sub-shapes against
2321 * \param theShape - the shape to explore
2322 * \param theShapeType - type of sub-shape of theShape
2323 * \param theState - required state
2324 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
2326 //=======================================================================
2327 Handle(TColStd_HSequenceOfInteger)
2328 GEOMImpl_IShapesOperations::GetShapesOnBoxIDs(const Handle(GEOM_Object)& theBox,
2329 const Handle(GEOM_Object)& theShape,
2330 const Standard_Integer theShapeType,
2331 GEOMAlgo_State theState)
2333 // Find sub-shapes ids
2334 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2335 getShapesOnBoxIDs (theBox, theShape, theShapeType, theState);
2336 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2339 // The GetShapesOnBox() doesn't change object so no new function is required.
2340 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theBox)->GetLastFunction();
2342 // Make a Python command
2343 GEOM::TPythonDump(aFunction, /*append=*/true)
2344 << "listShapesOnBoxIDs = geompy.GetShapesOnBoxIDs("
2347 << TopAbs_ShapeEnum(theShapeType) << ", "
2354 //=======================================================================
2355 //function : GetShapesOnBox
2357 * \brief Find sub-shapes complying with given status about surface
2358 * \param theBox - the box to check state of sub-shapes against
2359 * \param theShape - the shape to explore
2360 * \param theShapeType - type of sub-shape of theShape
2361 * \param theState - required state
2362 * \retval Handle(TColStd_HSequenceOfTransient) - found sub-shapes
2364 //=======================================================================
2365 Handle(TColStd_HSequenceOfTransient)
2366 GEOMImpl_IShapesOperations::GetShapesOnBox(const Handle(GEOM_Object)& theBox,
2367 const Handle(GEOM_Object)& theShape,
2368 const Standard_Integer theShapeType,
2369 GEOMAlgo_State theState)
2371 // Find sub-shapes ids
2372 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2373 getShapesOnBoxIDs (theBox, theShape, theShapeType, theState);
2374 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2377 // Find objects by indices
2378 TCollection_AsciiString anAsciiList;
2379 Handle(TColStd_HSequenceOfTransient) aSeq;
2380 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
2381 if ( aSeq.IsNull() || aSeq->IsEmpty() )
2384 // Make a Python command
2386 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2387 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2389 GEOM::TPythonDump(aFunction)
2390 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnBox("
2393 << TopAbs_ShapeEnum(theShapeType) << ", "
2400 //=======================================================================
2401 //function : getShapesOnShapeIDs
2403 * \brief Find IDs of sub-shapes complying with given status about surface
2404 * \param theCheckShape - the shape to check state of sub-shapes against
2405 * \param theShape - the shape to explore
2406 * \param theShapeType - type of sub-shape of theShape
2407 * \param theState - required state
2408 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
2410 //=======================================================================
2411 Handle(TColStd_HSequenceOfInteger)
2412 GEOMImpl_IShapesOperations::getShapesOnShapeIDs
2413 (const Handle(GEOM_Object)& theCheckShape,
2414 const Handle(GEOM_Object)& theShape,
2415 const Standard_Integer theShapeType,
2416 GEOMAlgo_State theState)
2418 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
2420 TopoDS_Shape aCheckShape = theCheckShape->GetValue();
2421 TopoDS_Shape aShape = theShape->GetValue();
2422 TopTools_ListOfShape res;
2424 // Check presence of triangulation, build if need
2425 if (!GEOMUtils::CheckTriangulation(aShape)) {
2426 SetErrorCode("Cannot build triangulation on the shape");
2431 GEOMAlgo_FinderShapeOn2 aFinder;
2432 Standard_Real aTol = 0.0001; // default value
2434 Handle(GEOMAlgo_ClsfSolid) aClsfSolid = new GEOMAlgo_ClsfSolid;
2435 aClsfSolid->SetShape(aCheckShape);
2437 aFinder.SetShape(aShape);
2438 aFinder.SetTolerance(aTol);
2439 aFinder.SetClsf(aClsfSolid);
2440 aFinder.SetShapeType( (TopAbs_ShapeEnum)theShapeType );
2441 aFinder.SetState(theState);
2444 // Interprete results
2445 Standard_Integer iErr = aFinder.ErrorStatus();
2446 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
2449 SetErrorCode("theCheckShape must be a solid");
2452 MESSAGE(" iErr : " << iErr);
2453 TCollection_AsciiString aMsg (" iErr : ");
2454 aMsg += TCollection_AsciiString(iErr);
2459 Standard_Integer iWrn = aFinder.WarningStatus();
2460 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
2462 MESSAGE(" *** iWrn : " << iWrn);
2465 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
2467 if (listSS.Extent() < 1) {
2468 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
2469 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
2472 // Fill sequence of object IDs
2473 aSeqOfIDs = new TColStd_HSequenceOfInteger;
2475 TopTools_IndexedMapOfShape anIndices;
2476 TopExp::MapShapes(aShape, anIndices);
2478 TopTools_ListIteratorOfListOfShape itSub (listSS);
2479 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
2480 int id = anIndices.FindIndex(itSub.Value());
2481 aSeqOfIDs->Append(id);
2487 //=======================================================================
2488 //function : GetShapesOnShapeIDs
2490 * \brief Find sub-shapes complying with given status about surface
2491 * \param theCheckShape - the shape to check state of sub-shapes against
2492 * \param theShape - the shape to explore
2493 * \param theShapeType - type of sub-shape of theShape
2494 * \param theState - required state
2495 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
2497 //=======================================================================
2498 Handle(TColStd_HSequenceOfInteger)
2499 GEOMImpl_IShapesOperations::GetShapesOnShapeIDs
2500 (const Handle(GEOM_Object)& theCheckShape,
2501 const Handle(GEOM_Object)& theShape,
2502 const Standard_Integer theShapeType,
2503 GEOMAlgo_State theState)
2505 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2506 getShapesOnShapeIDs (theCheckShape, theShape, theShapeType, theState);
2508 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2511 // The GetShapesOnShape() doesn't change object so no new function is required.
2512 Handle(GEOM_Function) aFunction =
2513 GEOM::GetCreatedLast(theShape,theCheckShape)->GetLastFunction();
2515 // Make a Python command
2516 GEOM::TPythonDump(aFunction, /*append=*/true)
2517 << "listShapesOnBoxIDs = geompy.GetShapesOnShapeIDs("
2518 << theCheckShape << ", "
2520 << TopAbs_ShapeEnum(theShapeType) << ", "
2527 //=======================================================================
2528 //function : GetShapesOnShape
2530 * \brief Find sub-shapes complying with given status about surface
2531 * \param theCheckShape - the shape to check state of sub-shapes against
2532 * \param theShape - the shape to explore
2533 * \param theShapeType - type of sub-shape of theShape
2534 * \param theState - required state
2535 * \retval Handle(TColStd_HSequenceOfTransient) - found sub-shapes
2537 //=======================================================================
2538 Handle(TColStd_HSequenceOfTransient)
2539 GEOMImpl_IShapesOperations::GetShapesOnShape
2540 (const Handle(GEOM_Object)& theCheckShape,
2541 const Handle(GEOM_Object)& theShape,
2542 const Standard_Integer theShapeType,
2543 GEOMAlgo_State theState)
2545 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2546 getShapesOnShapeIDs (theCheckShape, theShape, theShapeType, theState);
2547 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2550 // Find objects by indices
2551 TCollection_AsciiString anAsciiList;
2552 Handle(TColStd_HSequenceOfTransient) aSeq;
2553 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
2555 if ( aSeq.IsNull() || aSeq->IsEmpty() )
2558 // Make a Python command
2560 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2561 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2563 GEOM::TPythonDump(aFunction)
2564 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnShape("
2565 << theCheckShape << ", "
2567 << TopAbs_ShapeEnum(theShapeType) << ", "
2574 //=======================================================================
2575 //function : GetShapesOnShapeAsCompound
2576 //=======================================================================
2577 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetShapesOnShapeAsCompound
2578 (const Handle(GEOM_Object)& theCheckShape,
2579 const Handle(GEOM_Object)& theShape,
2580 const Standard_Integer theShapeType,
2581 GEOMAlgo_State theState)
2583 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2584 getShapesOnShapeIDs (theCheckShape, theShape, theShapeType, theState);
2586 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2589 // Find objects by indices
2590 TCollection_AsciiString anAsciiList;
2591 Handle(TColStd_HSequenceOfTransient) aSeq;
2592 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
2594 if ( aSeq.IsNull() || aSeq->IsEmpty() )
2597 TopoDS_Compound aCompound;
2599 B.MakeCompound(aCompound);
2601 for(; i<=aSeq->Length(); i++) {
2602 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(aSeq->Value(i));
2603 TopoDS_Shape aShape_i = anObj->GetValue();
2604 B.Add(aCompound,aShape_i);
2607 //Add a new result object
2608 Handle(GEOM_Object) aRes = GetEngine()->AddObject(GetDocID(), GEOM_SHAPES_ON_SHAPE);
2609 Handle(GEOM_Function) aFunction =
2610 aRes->AddFunction(GEOMImpl_ShapeDriver::GetID(), SHAPES_ON_SHAPE);
2611 aFunction->SetValue(aCompound);
2614 aSeq->Append( theCheckShape->GetLastFunction() );
2615 aSeq->Append( theShape->GetLastFunction() );
2617 GEOMImpl_IShapes aCI( aFunction );
2618 aCI.SetShapes( aSeq );
2619 aCI.SetSubShapeType( theShapeType );
2620 aCI.SetTolerance( theState );
2622 GEOM::TPythonDump(aFunction)
2623 << aRes << " = geompy.GetShapesOnShapeAsCompound("
2624 << theCheckShape << ", "
2626 << TopAbs_ShapeEnum(theShapeType) << ", "
2634 //=======================================================================
2635 //function : getShapesOnSurfaceIDs
2637 * \brief Find IDs of sub-shapes complying with given status about surface
2638 * \param theSurface - the surface to check state of sub-shapes against
2639 * \param theShape - the shape to explore
2640 * \param theShapeType - type of sub-shape of theShape
2641 * \param theState - required state
2642 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
2644 //=======================================================================
2645 Handle(TColStd_HSequenceOfInteger)
2646 GEOMImpl_IShapesOperations::getShapesOnSurfaceIDs(const Handle(Geom_Surface)& theSurface,
2647 const TopoDS_Shape& theShape,
2648 TopAbs_ShapeEnum theShapeType,
2649 GEOMAlgo_State theState)
2651 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
2653 // Check presence of triangulation, build if need
2654 if (!GEOMUtils::CheckTriangulation(theShape)) {
2655 SetErrorCode("Cannot build triangulation on the shape");
2659 // BEGIN: Mantis issue 0020961: Error on a pipe T-Shape
2660 // Compute tolerance
2661 Standard_Real T, VertMax = -RealLast();
2664 for (TopExp_Explorer ExV (theShape, TopAbs_VERTEX); ExV.More(); ExV.Next()) {
2665 TopoDS_Vertex Vertex = TopoDS::Vertex(ExV.Current());
2666 T = BRep_Tool::Tolerance(Vertex);
2671 catch (Standard_Failure) {
2672 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2673 SetErrorCode(aFail->GetMessageString());
2676 // END: Mantis issue 0020961
2679 GEOMAlgo_FinderShapeOn1 aFinder;
2680 //Standard_Real aTol = 0.0001; // default value
2681 Standard_Real aTol = VertMax; // Mantis issue 0020961
2683 aFinder.SetShape(theShape);
2684 aFinder.SetTolerance(aTol);
2685 aFinder.SetSurface(theSurface);
2686 aFinder.SetShapeType(theShapeType);
2687 aFinder.SetState(theState);
2689 // Sets the minimal number of inner points for the faces that do not have own
2690 // inner points at all (for e.g. rectangular planar faces have just 2 triangles).
2692 aFinder.SetNbPntsMin(3);
2693 // Sets the maximal number of inner points for edges or faces.
2694 // It is usefull for the cases when this number is very big (e.g =2000) to improve
2695 // the performance. If this value =0, all inner points will be taken into account.
2697 aFinder.SetNbPntsMax(100);
2701 // Interprete results
2702 Standard_Integer iErr = aFinder.ErrorStatus();
2703 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
2705 MESSAGE(" iErr : " << iErr);
2706 TCollection_AsciiString aMsg (" iErr : ");
2707 aMsg += TCollection_AsciiString(iErr);
2711 Standard_Integer iWrn = aFinder.WarningStatus();
2712 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
2714 MESSAGE(" *** iWrn : " << iWrn);
2717 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
2719 if (listSS.Extent() < 1) {
2720 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
2721 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
2725 // Fill sequence of object IDs
2726 aSeqOfIDs = new TColStd_HSequenceOfInteger;
2728 TopTools_IndexedMapOfShape anIndices;
2729 TopExp::MapShapes(theShape, anIndices);
2731 TopTools_ListIteratorOfListOfShape itSub (listSS);
2732 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
2733 int id = anIndices.FindIndex(itSub.Value());
2734 aSeqOfIDs->Append(id);
2740 //=======================================================================
2741 //function : getObjectsShapesOn
2743 * \brief Find shape objects and their entries by their ids
2744 * \param theShapeIDs - incoming shape ids
2745 * \param theShapeEntries - outgoing entries like "entry1, entry2, ..."
2746 * \retval Handle(TColStd_HSequenceOfTransient) - found shape objects
2748 //=======================================================================
2749 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::
2750 getObjectsShapesOn(const Handle(GEOM_Object)& theShape,
2751 const Handle(TColStd_HSequenceOfInteger)& theShapeIDs,
2752 TCollection_AsciiString & theShapeEntries)
2754 Handle(TColStd_HSequenceOfTransient) aSeq;
2756 if ( !theShapeIDs.IsNull() && theShapeIDs->Length() > 0 )
2758 aSeq = new TColStd_HSequenceOfTransient;
2759 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
2760 TCollection_AsciiString anEntry;
2761 for ( int i = 1; i <= theShapeIDs->Length(); ++i )
2763 anArray->SetValue(1, theShapeIDs->Value( i ));
2764 Handle(GEOM_Object) anObj = GetEngine()->AddSubShape(theShape, anArray);
2765 aSeq->Append( anObj );
2767 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
2768 if ( i != 1 ) theShapeEntries += ",";
2769 theShapeEntries += anEntry;
2775 //=======================================================================
2776 //function : getShapesOnSurface
2778 * \brief Find sub-shapes complying with given status about surface
2779 * \param theSurface - the surface to check state of sub-shapes against
2780 * \param theShape - the shape to explore
2781 * \param theShapeType - type of sub-shape of theShape
2782 * \param theState - required state
2783 * \param theShapeEntries - outgoing entries like "entry1, entry2, ..."
2784 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
2786 //=======================================================================
2787 Handle(TColStd_HSequenceOfTransient)
2788 GEOMImpl_IShapesOperations::getShapesOnSurface(const Handle(Geom_Surface)& theSurface,
2789 const Handle(GEOM_Object)& theShape,
2790 TopAbs_ShapeEnum theShapeType,
2791 GEOMAlgo_State theState,
2792 TCollection_AsciiString & theShapeEntries)
2794 // Find sub-shapes ids
2795 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2796 getShapesOnSurfaceIDs (theSurface, theShape->GetValue(), theShapeType, theState);
2797 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2800 return getObjectsShapesOn( theShape, aSeqOfIDs, theShapeEntries );
2803 //=============================================================================
2807 //=============================================================================
2808 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnPlane
2809 (const Handle(GEOM_Object)& theShape,
2810 const Standard_Integer theShapeType,
2811 const Handle(GEOM_Object)& theAx1,
2812 const GEOMAlgo_State theState)
2816 if (theShape.IsNull() || theAx1.IsNull()) return NULL;
2818 TopoDS_Shape aShape = theShape->GetValue();
2819 TopoDS_Shape anAx1 = theAx1->GetValue();
2821 if (aShape.IsNull() || anAx1.IsNull()) return NULL;
2823 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2824 if ( !checkTypeShapesOn( theShapeType ))
2828 Handle(Geom_Surface) aPlane = makePlane( anAx1 );
2829 if ( aPlane.IsNull() )
2833 TCollection_AsciiString anAsciiList;
2834 Handle(TColStd_HSequenceOfTransient) aSeq;
2835 aSeq = getShapesOnSurface( aPlane, theShape, aShapeType, theState, anAsciiList );
2836 if ( aSeq.IsNull() || aSeq->Length() == 0 )
2839 // Make a Python command
2841 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2842 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2844 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
2845 << "] = geompy.GetShapesOnPlane(" << theShape << ", "
2846 << aShapeType << ", " << theAx1 << ", " << theState << ")";
2852 //=============================================================================
2854 * GetShapesOnPlaneWithLocation
2856 //=============================================================================
2857 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnPlaneWithLocation
2858 (const Handle(GEOM_Object)& theShape,
2859 const Standard_Integer theShapeType,
2860 const Handle(GEOM_Object)& theAx1,
2861 const Handle(GEOM_Object)& thePnt,
2862 const GEOMAlgo_State theState)
2866 if (theShape.IsNull() || theAx1.IsNull() || thePnt.IsNull()) return NULL;
2868 TopoDS_Shape aShape = theShape->GetValue();
2869 TopoDS_Shape anAx1 = theAx1->GetValue();
2870 TopoDS_Shape anPnt = thePnt->GetValue();
2872 if (aShape.IsNull() || anAx1.IsNull() || anPnt.IsNull()) return NULL;
2874 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2875 if ( !checkTypeShapesOn( theShapeType ))
2879 if ( anAx1.ShapeType() != TopAbs_EDGE || anPnt.ShapeType() != TopAbs_VERTEX ) return NULL;
2880 TopoDS_Vertex V1, V2, V3;
2881 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
2882 TopExp::Vertices(anEdge, V1, V2, Standard_True);
2884 if (V1.IsNull() || V2.IsNull()) {
2885 SetErrorCode("Bad edge given for the plane normal vector");
2888 V3 = TopoDS::Vertex(anPnt);
2891 SetErrorCode("Bad vertex given for the plane location");
2894 gp_Pnt aLoc = BRep_Tool::Pnt(V3);
2895 gp_Vec aVec(BRep_Tool::Pnt(V1),BRep_Tool::Pnt(V2));
2897 if (aVec.Magnitude() < Precision::Confusion()) {
2898 SetErrorCode("Vector with null magnitude given");
2901 Handle(Geom_Surface) aPlane = new Geom_Plane(aLoc, aVec);
2903 if ( aPlane.IsNull() )
2907 TCollection_AsciiString anAsciiList;
2908 Handle(TColStd_HSequenceOfTransient) aSeq;
2909 aSeq = getShapesOnSurface( aPlane, theShape, aShapeType, theState, anAsciiList );
2910 if ( aSeq.IsNull() || aSeq->Length() == 0 )
2913 // Make a Python command
2915 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2916 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2918 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
2919 << "] = geompy.GetShapesOnPlaneWithLocation(" << theShape << ", "
2920 << aShapeType << ", " << theAx1 << ", "<< thePnt <<", " << theState << ")";
2926 //=============================================================================
2928 * GetShapesOnCylinder
2930 //=============================================================================
2931 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnCylinder
2932 (const Handle(GEOM_Object)& theShape,
2933 const Standard_Integer theShapeType,
2934 const Handle(GEOM_Object)& theAxis,
2935 const Standard_Real theRadius,
2936 const GEOMAlgo_State theState)
2940 if (theShape.IsNull() || theAxis.IsNull()) return NULL;
2942 TopoDS_Shape aShape = theShape->GetValue();
2943 TopoDS_Shape anAxis = theAxis->GetValue();
2945 if (aShape.IsNull() || anAxis.IsNull()) return NULL;
2947 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2948 if ( !checkTypeShapesOn( aShapeType ))
2951 // Create a cylinder surface
2952 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
2953 if ( aCylinder.IsNull() )
2957 TCollection_AsciiString anAsciiList;
2958 Handle(TColStd_HSequenceOfTransient) aSeq;
2959 aSeq = getShapesOnSurface( aCylinder, theShape, aShapeType, theState, anAsciiList );
2960 if ( aSeq.IsNull() || aSeq->Length() == 0 )
2963 // Make a Python command
2965 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2966 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2968 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
2969 << "] = geompy.GetShapesOnCylinder(" << theShape << ", " << aShapeType
2970 << ", " << theAxis << ", " << theRadius << ", " << theState << ")";
2976 //=============================================================================
2978 * GetShapesOnCylinderWithLocation
2980 //=============================================================================
2981 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnCylinderWithLocation
2982 (const Handle(GEOM_Object)& theShape,
2983 const Standard_Integer theShapeType,
2984 const Handle(GEOM_Object)& theAxis,
2985 const Handle(GEOM_Object)& thePnt,
2986 const Standard_Real theRadius,
2987 const GEOMAlgo_State theState)
2991 if (theShape.IsNull() || theAxis.IsNull() || thePnt.IsNull()) return NULL;
2993 TopoDS_Shape aShape = theShape->GetValue();
2994 TopoDS_Shape anAxis = theAxis->GetValue();
2995 TopoDS_Shape aPnt = thePnt->GetValue();
2997 if (aShape.IsNull() || anAxis.IsNull() || aPnt.IsNull()) return NULL;
2999 if (aPnt.ShapeType() != TopAbs_VERTEX )
3001 SetErrorCode("Bottom location point must be vertex");
3005 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3006 if ( !checkTypeShapesOn( aShapeType ))
3009 // Create a cylinder surface
3010 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
3011 if ( aCylinder.IsNull() )
3014 // translate the surface
3015 Handle(Geom_CylindricalSurface) aCylSurface =
3016 Handle(Geom_CylindricalSurface)::DownCast( aCylinder );
3017 if ( aCylSurface.IsNull() )
3019 SetErrorCode("Unexpected surface type instead of Geom_CylindricalSurface");
3022 gp_Pnt fromLoc = aCylSurface->Cylinder().Location();
3023 gp_Pnt toLoc = BRep_Tool::Pnt( TopoDS::Vertex( aPnt ));
3024 aCylinder->Translate( fromLoc, toLoc );
3027 TCollection_AsciiString anAsciiList;
3028 Handle(TColStd_HSequenceOfTransient) aSeq;
3029 aSeq = getShapesOnSurface( aCylinder, theShape, aShapeType, theState, anAsciiList );
3030 if ( aSeq.IsNull() || aSeq->Length() == 0 )
3033 // Make a Python command
3035 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
3036 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
3038 GEOM::TPythonDump(aFunction)
3039 << "[" << anAsciiList.ToCString()
3040 << "] = geompy.GetShapesOnCylinderWithLocation(" << theShape << ", " << aShapeType << ", "
3041 << theAxis << ", " << thePnt << ", " << theRadius << ", " << theState << ")";
3047 //=============================================================================
3051 //=============================================================================
3052 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnSphere
3053 (const Handle(GEOM_Object)& theShape,
3054 const Standard_Integer theShapeType,
3055 const Handle(GEOM_Object)& theCenter,
3056 const Standard_Real theRadius,
3057 const GEOMAlgo_State theState)
3061 if (theShape.IsNull() || theCenter.IsNull()) return NULL;
3063 TopoDS_Shape aShape = theShape->GetValue();
3064 TopoDS_Shape aCenter = theCenter->GetValue();
3066 if (aShape.IsNull() || aCenter.IsNull()) return NULL;
3068 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3069 if ( !checkTypeShapesOn( aShapeType ))
3072 // Center of the sphere
3073 if (aCenter.ShapeType() != TopAbs_VERTEX) return NULL;
3074 gp_Pnt aLoc = BRep_Tool::Pnt(TopoDS::Vertex(aCenter));
3076 gp_Ax3 anAx3 (aLoc, gp::DZ());
3077 Handle(Geom_SphericalSurface) aSphere =
3078 new Geom_SphericalSurface(anAx3, theRadius);
3081 TCollection_AsciiString anAsciiList;
3082 Handle(TColStd_HSequenceOfTransient) aSeq;
3083 aSeq = getShapesOnSurface( aSphere, theShape, aShapeType, theState, anAsciiList );
3084 if ( aSeq.IsNull() || aSeq->Length() == 0 )
3087 // Make a Python command
3089 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
3090 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
3092 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
3093 << "] = geompy.GetShapesOnSphere(" << theShape << ", " << aShapeType
3094 << ", " << theCenter << ", " << theRadius << ", " << theState << ")";
3100 //=============================================================================
3102 * GetShapesOnPlaneIDs
3104 //=============================================================================
3105 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnPlaneIDs
3106 (const Handle(GEOM_Object)& theShape,
3107 const Standard_Integer theShapeType,
3108 const Handle(GEOM_Object)& theAx1,
3109 const GEOMAlgo_State theState)
3113 if (theShape.IsNull() || theAx1.IsNull()) return NULL;
3115 TopoDS_Shape aShape = theShape->GetValue();
3116 TopoDS_Shape anAx1 = theAx1->GetValue();
3118 if (aShape.IsNull() || anAx1.IsNull()) return NULL;
3120 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3121 if ( !checkTypeShapesOn( aShapeType ))
3125 Handle(Geom_Surface) aPlane = makePlane( anAx1 );
3126 if ( aPlane.IsNull() )
3130 Handle(TColStd_HSequenceOfInteger) aSeq;
3131 aSeq = getShapesOnSurfaceIDs( aPlane, aShape, aShapeType, theState );
3133 // The GetShapesOnPlaneIDs() doesn't change object so no new function is required.
3134 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAx1)->GetLastFunction();
3136 // Make a Python command
3137 GEOM::TPythonDump(aFunction, /*append=*/true)
3138 << "listShapesOnPlane = geompy.GetShapesOnPlaneIDs"
3139 << "(" << theShape << "," << aShapeType << "," << theAx1 << "," << theState << ")";
3145 //=============================================================================
3147 * GetShapesOnPlaneWithLocationIDs
3149 //=============================================================================
3150 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnPlaneWithLocationIDs
3151 (const Handle(GEOM_Object)& theShape,
3152 const Standard_Integer theShapeType,
3153 const Handle(GEOM_Object)& theAx1,
3154 const Handle(GEOM_Object)& thePnt,
3155 const GEOMAlgo_State theState)
3159 if (theShape.IsNull() || theAx1.IsNull() || thePnt.IsNull()) return NULL;
3161 TopoDS_Shape aShape = theShape->GetValue();
3162 TopoDS_Shape anAx1 = theAx1->GetValue();
3163 TopoDS_Shape anPnt = thePnt->GetValue();
3165 if (aShape.IsNull() || anAx1.IsNull() || anPnt.IsNull()) return NULL;
3167 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3168 if ( !checkTypeShapesOn( aShapeType ))
3172 if (anAx1.ShapeType() != TopAbs_EDGE || anPnt.ShapeType() != TopAbs_VERTEX) return NULL;
3173 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
3174 TopoDS_Vertex V1, V2, V3;
3175 TopExp::Vertices(anEdge, V1, V2, Standard_True);
3176 if (V1.IsNull() || V2.IsNull()) {
3177 SetErrorCode("Bad edge given for the plane normal vector");
3180 V3 = TopoDS::Vertex(anPnt);
3182 SetErrorCode("Bad vertex given for the plane location");
3185 gp_Pnt aLoc = BRep_Tool::Pnt(V3);
3186 gp_Vec aVec(BRep_Tool::Pnt(V1),BRep_Tool::Pnt(V2));
3187 if (aVec.Magnitude() < Precision::Confusion()) {
3188 SetErrorCode("Vector with null magnitude given");
3192 Handle(Geom_Surface) aPlane = new Geom_Plane(aLoc, aVec);
3193 if ( aPlane.IsNull() )
3197 Handle(TColStd_HSequenceOfInteger) aSeq;
3198 aSeq = getShapesOnSurfaceIDs( aPlane, aShape, aShapeType, theState );
3200 // The GetShapesOnPlaneIDs() doesn't change object so no new function is required.
3201 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAx1)->GetLastFunction();
3203 // Make a Python command
3204 GEOM::TPythonDump(aFunction, /*append=*/true)
3205 << "listShapesOnPlane = geompy.GetShapesOnPlaneWithLocationIDs"
3206 << "(" << theShape << ", " << aShapeType << ", " << theAx1 << ", "<< thePnt << ", " << theState << ")";
3212 //=============================================================================
3214 * GetShapesOnCylinderIDs
3216 //=============================================================================
3217 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnCylinderIDs
3218 (const Handle(GEOM_Object)& theShape,
3219 const Standard_Integer theShapeType,
3220 const Handle(GEOM_Object)& theAxis,
3221 const Standard_Real theRadius,
3222 const GEOMAlgo_State theState)
3226 if (theShape.IsNull() || theAxis.IsNull()) return NULL;
3228 TopoDS_Shape aShape = theShape->GetValue();
3229 TopoDS_Shape anAxis = theAxis->GetValue();
3231 if (aShape.IsNull() || anAxis.IsNull()) return NULL;
3233 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3234 if ( !checkTypeShapesOn( aShapeType ))
3237 // Create a cylinder surface
3238 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
3239 if ( aCylinder.IsNull() )
3243 Handle(TColStd_HSequenceOfInteger) aSeq;
3244 aSeq = getShapesOnSurfaceIDs( aCylinder, aShape, aShapeType, theState );
3246 // The GetShapesOnCylinder() doesn't change object so no new function is required.
3247 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAxis)->GetLastFunction();
3249 // Make a Python command
3250 GEOM::TPythonDump(aFunction, /*append=*/true)
3251 << "listShapesOnCylinder = geompy.GetShapesOnCylinderIDs"
3252 << "(" << theShape << ", " << aShapeType << ", " << theAxis << ", "
3253 << theRadius << ", " << theState << ")";
3259 //=============================================================================
3261 * GetShapesOnCylinderWithLocationIDs
3263 //=============================================================================
3264 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnCylinderWithLocationIDs
3265 (const Handle(GEOM_Object)& theShape,
3266 const Standard_Integer theShapeType,
3267 const Handle(GEOM_Object)& theAxis,
3268 const Handle(GEOM_Object)& thePnt,
3269 const Standard_Real theRadius,
3270 const GEOMAlgo_State theState)
3274 if (theShape.IsNull() || theAxis.IsNull() || thePnt.IsNull()) return NULL;
3276 TopoDS_Shape aShape = theShape->GetValue();
3277 TopoDS_Shape anAxis = theAxis->GetValue();
3278 TopoDS_Shape aPnt = thePnt->GetValue();
3280 if (aShape.IsNull() || anAxis.IsNull() || aPnt.IsNull()) return NULL;
3282 if (aPnt.ShapeType() != TopAbs_VERTEX )
3284 SetErrorCode("Bottom location point must be vertex");
3288 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3289 if ( !checkTypeShapesOn( aShapeType ))
3292 // Create a cylinder surface
3293 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
3294 if ( aCylinder.IsNull() )
3297 // translate the surface
3298 Handle(Geom_CylindricalSurface) aCylSurface =
3299 Handle(Geom_CylindricalSurface)::DownCast( aCylinder );
3300 if ( aCylSurface.IsNull() )
3302 SetErrorCode("Unexpected surface type instead of Geom_CylindricalSurface");
3305 gp_Pnt fromLoc = aCylSurface->Cylinder().Location();
3306 gp_Pnt toLoc = BRep_Tool::Pnt( TopoDS::Vertex( aPnt ));
3307 aCylinder->Translate( fromLoc, toLoc );
3310 Handle(TColStd_HSequenceOfInteger) aSeq;
3311 aSeq = getShapesOnSurfaceIDs( aCylinder, aShape, aShapeType, theState );
3313 // The GetShapesOnCylinder() doesn't change object so no new function is required.
3314 Handle(GEOM_Function) aFunction =
3315 GEOM::GetCreatedLast(theShape, GEOM::GetCreatedLast(thePnt,theAxis))->GetLastFunction();
3317 // Make a Python command
3318 GEOM::TPythonDump(aFunction, /*append=*/true)
3319 << "listShapesOnCylinder = geompy.GetShapesOnCylinderWithLocationIDs"
3320 << "(" << theShape << ", " << aShapeType << ", " << theAxis << ", "
3321 << thePnt << ", " << theRadius << ", " << theState << ")";
3327 //=============================================================================
3329 * GetShapesOnSphereIDs
3331 //=============================================================================
3332 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnSphereIDs
3333 (const Handle(GEOM_Object)& theShape,
3334 const Standard_Integer theShapeType,
3335 const Handle(GEOM_Object)& theCenter,
3336 const Standard_Real theRadius,
3337 const GEOMAlgo_State theState)
3341 if (theShape.IsNull() || theCenter.IsNull()) return NULL;
3343 TopoDS_Shape aShape = theShape->GetValue();
3344 TopoDS_Shape aCenter = theCenter->GetValue();
3346 if (aShape.IsNull() || aCenter.IsNull()) return NULL;
3348 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3349 if ( !checkTypeShapesOn( aShapeType ))
3352 // Center of the sphere
3353 if (aCenter.ShapeType() != TopAbs_VERTEX) return NULL;
3354 gp_Pnt aLoc = BRep_Tool::Pnt(TopoDS::Vertex(aCenter));
3356 gp_Ax3 anAx3 (aLoc, gp::DZ());
3357 Handle(Geom_SphericalSurface) aSphere =
3358 new Geom_SphericalSurface(anAx3, theRadius);
3361 Handle(TColStd_HSequenceOfInteger) aSeq;
3362 aSeq = getShapesOnSurfaceIDs( aSphere, aShape, aShapeType, theState );
3364 // The GetShapesOnSphere() doesn't change object so no new function is required.
3365 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theCenter)->GetLastFunction();
3367 // Make a Python command
3368 GEOM::TPythonDump(aFunction, /*append=*/true)
3369 << "listShapesOnCylinder = geompy.GetShapesOnSphereIDs"
3370 << "(" << theShape << ", " << aShapeType << ", " << theCenter << ", "
3371 << theRadius << ", " << theState << ")";
3377 //=======================================================================
3378 //function : getShapesOnQuadrangleIDs
3380 * \brief Find IDs of sub-shapes complying with given status about quadrangle
3381 * \param theShape - the shape to explore
3382 * \param theShapeType - type of sub-shape of theShape
3383 * \param theTopLeftPoint - top left quadrangle corner
3384 * \param theTopRigthPoint - top right quadrangle corner
3385 * \param theBottomLeftPoint - bottom left quadrangle corner
3386 * \param theBottomRigthPoint - bottom right quadrangle corner
3387 * \param theState - required state
3388 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
3390 //=======================================================================
3391 Handle(TColStd_HSequenceOfInteger)
3392 GEOMImpl_IShapesOperations::getShapesOnQuadrangleIDs (const Handle(GEOM_Object)& theShape,
3393 const Standard_Integer theShapeType,
3394 const Handle(GEOM_Object)& theTopLeftPoint,
3395 const Handle(GEOM_Object)& theTopRigthPoint,
3396 const Handle(GEOM_Object)& theBottomLeftPoint,
3397 const Handle(GEOM_Object)& theBottomRigthPoint,
3398 const GEOMAlgo_State theState)
3402 if ( theShape.IsNull() ||
3403 theTopLeftPoint.IsNull() ||
3404 theTopRigthPoint.IsNull() ||
3405 theBottomLeftPoint.IsNull() ||
3406 theBottomRigthPoint.IsNull() )
3409 TopoDS_Shape aShape = theShape->GetValue();
3410 TopoDS_Shape aTL = theTopLeftPoint->GetValue();
3411 TopoDS_Shape aTR = theTopRigthPoint->GetValue();
3412 TopoDS_Shape aBL = theBottomLeftPoint->GetValue();
3413 TopoDS_Shape aBR = theBottomRigthPoint->GetValue();
3415 if (aShape.IsNull() ||
3420 aTL.ShapeType() != TopAbs_VERTEX ||
3421 aTR.ShapeType() != TopAbs_VERTEX ||
3422 aBL.ShapeType() != TopAbs_VERTEX ||
3423 aBR.ShapeType() != TopAbs_VERTEX )
3426 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3427 if ( !checkTypeShapesOn( aShapeType ))
3430 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
3432 // Check presence of triangulation, build if need
3433 if (!GEOMUtils::CheckTriangulation(aShape)) {
3434 SetErrorCode("Cannot build triangulation on the shape");
3439 gp_Pnt aPntTL = BRep_Tool::Pnt(TopoDS::Vertex(aTL));
3440 gp_Pnt aPntTR = BRep_Tool::Pnt(TopoDS::Vertex(aTR));
3441 gp_Pnt aPntBL = BRep_Tool::Pnt(TopoDS::Vertex(aBL));
3442 gp_Pnt aPntBR = BRep_Tool::Pnt(TopoDS::Vertex(aBR));
3444 GEOMAlgo_FinderShapeOnQuad aFinder( aPntTL, aPntTR, aPntBL, aPntBR );
3445 Standard_Real aTol = 0.0001; // default value
3447 aFinder.SetShape(aShape);
3448 aFinder.SetTolerance(aTol);
3449 //aFinder.SetSurface(theSurface);
3450 aFinder.SetShapeType(aShapeType);
3451 aFinder.SetState(theState);
3453 // Sets the minimal number of inner points for the faces that do not have own
3454 // inner points at all (for e.g. rectangular planar faces have just 2 triangles).
3456 aFinder.SetNbPntsMin(3);
3457 // Sets the maximal number of inner points for edges or faces.
3458 // It is usefull for the cases when this number is very big (e.g =2000) to improve
3459 // the performance. If this value =0, all inner points will be taken into account.
3461 aFinder.SetNbPntsMax(100);
3465 // Interprete results
3466 Standard_Integer iErr = aFinder.ErrorStatus();
3467 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
3469 MESSAGE(" iErr : " << iErr);
3470 TCollection_AsciiString aMsg (" iErr : ");
3471 aMsg += TCollection_AsciiString(iErr);
3475 Standard_Integer iWrn = aFinder.WarningStatus();
3476 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
3478 MESSAGE(" *** iWrn : " << iWrn);
3481 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
3483 if (listSS.Extent() < 1) {
3484 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
3485 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
3489 // Fill sequence of object IDs
3490 aSeqOfIDs = new TColStd_HSequenceOfInteger;
3492 TopTools_IndexedMapOfShape anIndices;
3493 TopExp::MapShapes(aShape, anIndices);
3495 TopTools_ListIteratorOfListOfShape itSub (listSS);
3496 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
3497 int id = anIndices.FindIndex(itSub.Value());
3498 aSeqOfIDs->Append(id);
3503 //=======================================================================
3504 //function : GetShapesOnQuadrangle
3506 * \brief Find sub-shapes complying with given status about quadrangle
3507 * \param theShape - the shape to explore
3508 * \param theShapeType - type of sub-shape of theShape
3509 * \param theTopLeftPoint - top left quadrangle corner
3510 * \param theTopRigthPoint - top right quadrangle corner
3511 * \param theBottomLeftPoint - bottom left quadrangle corner
3512 * \param theBottomRigthPoint - bottom right quadrangle corner
3513 * \param theState - required state
3514 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
3516 //=======================================================================
3517 Handle(TColStd_HSequenceOfTransient)
3518 GEOMImpl_IShapesOperations::GetShapesOnQuadrangle (const Handle(GEOM_Object)& theShape,
3519 const Standard_Integer theShapeType,
3520 const Handle(GEOM_Object)& theTopLeftPoint,
3521 const Handle(GEOM_Object)& theTopRigthPoint,
3522 const Handle(GEOM_Object)& theBottomLeftPoint,
3523 const Handle(GEOM_Object)& theBottomRigthPoint,
3524 const GEOMAlgo_State theState)
3527 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
3528 getShapesOnQuadrangleIDs( theShape,
3533 theBottomRigthPoint,
3535 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->IsEmpty() )
3538 // Find objects by indices
3539 TCollection_AsciiString anAsciiList;
3540 Handle(TColStd_HSequenceOfTransient) aSeq;
3541 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
3542 if ( aSeq.IsNull() || aSeq->IsEmpty() )
3545 // Make a Python command
3547 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
3548 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
3550 GEOM::TPythonDump(aFunction)
3551 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnQuadrangle("
3553 << TopAbs_ShapeEnum(theShapeType) << ", "
3554 << theTopLeftPoint << ", "
3555 << theTopRigthPoint << ", "
3556 << theBottomLeftPoint << ", "
3557 << theBottomRigthPoint << ", "
3564 //=======================================================================
3565 //function : GetShapesOnQuadrangleIDs
3567 * \brief Find IDs of sub-shapes complying with given status about quadrangle
3568 * \param theShape - the shape to explore
3569 * \param theShapeType - type of sub-shape of theShape
3570 * \param theTopLeftPoint - top left quadrangle corner
3571 * \param theTopRigthPoint - top right quadrangle corner
3572 * \param theBottomLeftPoint - bottom left quadrangle corner
3573 * \param theBottomRigthPoint - bottom right quadrangle corner
3574 * \param theState - required state
3575 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
3577 //=======================================================================
3578 Handle(TColStd_HSequenceOfInteger)
3579 GEOMImpl_IShapesOperations::GetShapesOnQuadrangleIDs (const Handle(GEOM_Object)& theShape,
3580 const Standard_Integer theShapeType,
3581 const Handle(GEOM_Object)& theTopLeftPoint,
3582 const Handle(GEOM_Object)& theTopRigthPoint,
3583 const Handle(GEOM_Object)& theBottomLeftPoint,
3584 const Handle(GEOM_Object)& theBottomRigthPoint,
3585 const GEOMAlgo_State theState)
3588 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
3589 getShapesOnQuadrangleIDs( theShape,
3594 theBottomRigthPoint,
3596 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->IsEmpty() )
3599 // Make a Python command
3601 // The GetShapesOnCylinder() doesn't change object so no new function is required.
3602 Handle(GEOM_Object) lastObj = GEOM::GetCreatedLast(theShape,theTopLeftPoint);
3603 lastObj = GEOM::GetCreatedLast(lastObj,theTopRigthPoint);
3604 lastObj = GEOM::GetCreatedLast(lastObj,theBottomRigthPoint);
3605 lastObj = GEOM::GetCreatedLast(lastObj,theBottomLeftPoint);
3606 Handle(GEOM_Function) aFunction = lastObj->GetLastFunction();
3608 GEOM::TPythonDump(aFunction, /*append=*/true)
3609 << "listShapesOnQuadrangle = geompy.GetShapesOnQuadrangleIDs("
3611 << TopAbs_ShapeEnum(theShapeType) << ", "
3612 << theTopLeftPoint << ", "
3613 << theTopRigthPoint << ", "
3614 << theBottomLeftPoint << ", "
3615 << theBottomRigthPoint << ", "
3622 //=============================================================================
3626 //=============================================================================
3627 static bool GetInPlaceOfShape (const Handle(GEOM_Function)& theWhereFunction,
3628 const TopTools_IndexedMapOfShape& theWhereIndices,
3629 const TopoDS_Shape& theWhat,
3630 TColStd_ListOfInteger& theModifiedList)
3632 if (theWhereFunction.IsNull() || theWhat.IsNull()) return false;
3634 if (theWhereIndices.Contains(theWhat)) {
3635 // entity was not changed by the operation
3636 Standard_Integer aWhatIndex = theWhereIndices.FindIndex(theWhat);
3637 theModifiedList.Append(aWhatIndex);
3641 // try to find in history
3642 TDF_Label aHistoryLabel = theWhereFunction->GetHistoryEntry(Standard_False);
3644 // search in history for all argument shapes
3645 Standard_Boolean isFound = Standard_False;
3646 Standard_Boolean isGood = Standard_False;
3648 TDF_LabelSequence aLabelSeq;
3649 theWhereFunction->GetDependency(aLabelSeq);
3650 Standard_Integer nbArg = aLabelSeq.Length();
3652 for (Standard_Integer iarg = 1; iarg <= nbArg && !isFound; iarg++) {
3654 TDF_Label anArgumentRefLabel = aLabelSeq.Value(iarg);
3656 Handle(GEOM_Object) anArgumentObject = GEOM_Object::GetReferencedObject(anArgumentRefLabel);
3657 TopoDS_Shape anArgumentShape = anArgumentObject->GetValue();
3659 TopTools_IndexedMapOfShape anArgumentIndices;
3660 TopExp::MapShapes(anArgumentShape, anArgumentIndices);
3662 if (anArgumentIndices.Contains(theWhat)) {
3663 isFound = Standard_True;
3664 Standard_Integer aWhatIndex = anArgumentIndices.FindIndex(theWhat);
3666 // Find corresponding label in history
3667 TDF_Label anArgumentHistoryLabel =
3668 theWhereFunction->GetArgumentHistoryEntry(anArgumentRefLabel, Standard_False);
3669 if (anArgumentHistoryLabel.IsNull()) {
3670 // Lost History of operation argument. Possibly, all its entities was removed.
3671 isGood = Standard_True;
3674 TDF_Label aWhatHistoryLabel = anArgumentHistoryLabel.FindChild(aWhatIndex, Standard_False);
3676 if (aWhatHistoryLabel.IsNull()) {
3677 // Removed entity ? Compound ? Compsolid ? Shell ? Wire
3678 isGood = Standard_False;
3680 Handle(TDataStd_IntegerArray) anIntegerArray;
3681 if (!aWhatHistoryLabel.FindAttribute(TDataStd_IntegerArray::GetID(), anIntegerArray)) {
3682 //Error: Empty modifications history for the sought shape.
3683 isGood = Standard_False;
3686 isGood = Standard_True;
3687 Standard_Integer imod, aModifLen = anIntegerArray->Array()->Length();
3688 for (imod = 1; imod <= aModifLen; imod++) {
3689 theModifiedList.Append(anIntegerArray->Array()->Value(imod));
3700 // try compound/compsolid/shell/wire element by element
3701 bool isFoundAny = false;
3702 TopTools_MapOfShape mapShape;
3704 if (theWhat.ShapeType() == TopAbs_COMPOUND ||
3705 theWhat.ShapeType() == TopAbs_COMPSOLID) {
3706 // recursive processing of compound/compsolid
3707 TopoDS_Iterator anIt (theWhat, Standard_True, Standard_True);
3708 for (; anIt.More(); anIt.Next()) {
3709 if (mapShape.Add(anIt.Value())) {
3710 TopoDS_Shape curWhat = anIt.Value();
3711 isFoundAny = GetInPlaceOfShape(theWhereFunction, theWhereIndices, curWhat, theModifiedList);
3712 if (isFoundAny) isFound = Standard_True;
3716 else if (theWhat.ShapeType() == TopAbs_SHELL) {
3717 // try to replace a shell by its faces images
3718 TopExp_Explorer anExp (theWhat, TopAbs_FACE);
3719 for (; anExp.More(); anExp.Next()) {
3720 if (mapShape.Add(anExp.Current())) {
3721 TopoDS_Shape curWhat = anExp.Current();
3722 isFoundAny = GetInPlaceOfShape(theWhereFunction, theWhereIndices, curWhat, theModifiedList);
3723 if (isFoundAny) isFound = Standard_True;
3727 else if (theWhat.ShapeType() == TopAbs_WIRE) {
3728 // try to replace a wire by its edges images
3729 TopExp_Explorer anExp (theWhat, TopAbs_EDGE);
3730 for (; anExp.More(); anExp.Next()) {
3731 if (mapShape.Add(anExp.Current())) {
3732 TopoDS_Shape curWhat = anExp.Current();
3733 isFoundAny = GetInPlaceOfShape(theWhereFunction, theWhereIndices, curWhat, theModifiedList);
3734 if (isFoundAny) isFound = Standard_True;
3746 //=============================================================================
3748 * GetShapeProperties
3750 //=============================================================================
3751 void GEOMImpl_IShapesOperations::GetShapeProperties( const TopoDS_Shape aShape, Standard_Real tab[],
3754 GProp_GProps theProps;
3756 //TopoDS_Shape aPntShape;
3757 Standard_Real aShapeSize;
3759 if (aShape.ShapeType() == TopAbs_VERTEX) aCenterMass = BRep_Tool::Pnt( TopoDS::Vertex( aShape ) );
3760 else if (aShape.ShapeType() == TopAbs_EDGE) BRepGProp::LinearProperties(aShape, theProps);
3761 else if (aShape.ShapeType() == TopAbs_FACE) BRepGProp::SurfaceProperties(aShape, theProps);
3762 else BRepGProp::VolumeProperties(aShape, theProps);
3764 if (aShape.ShapeType() == TopAbs_VERTEX)
3767 aCenterMass = theProps.CentreOfMass();
3768 aShapeSize = theProps.Mass();
3771 // aPntShape = BRepBuilderAPI_MakeVertex(aCenterMass).Shape();
3772 // aVertex = BRep_Tool::Pnt( TopoDS::Vertex( aPntShape ) );
3773 aVertex = aCenterMass;
3774 tab[0] = aVertex.X();
3775 tab[1] = aVertex.Y();
3776 tab[2] = aVertex.Z();
3777 tab[3] = aShapeSize;
3783 //================================================================================
3785 * \brief Return normal to face at extrema point
3787 //================================================================================
3789 gp_Vec GetNormal (const TopoDS_Face& face, const BRepExtrema_DistShapeShape& extrema)
3791 gp_Vec defaultNorm(1,0,0); // to have same normals on different faces
3793 // get UV at extrema point
3794 Standard_Real u,v, f,l;
3795 switch ( extrema.SupportTypeShape2(1) ) {
3796 case BRepExtrema_IsInFace: {
3797 extrema.ParOnFaceS2(1, u, v );
3800 case BRepExtrema_IsOnEdge: {
3801 TopoDS_Edge edge = TopoDS::Edge( extrema.SupportOnShape2(1));
3802 Handle(Geom2d_Curve) pcurve = BRep_Tool::CurveOnSurface( edge, face, f,l );
3803 extrema.ParOnEdgeS2( 1, u );
3804 gp_Pnt2d uv = pcurve->Value( u );
3809 case BRepExtrema_IsVertex: return defaultNorm;
3812 BRepAdaptor_Surface surface( face, false );
3813 gp_Vec du, dv; gp_Pnt p;
3814 surface.D1( u, v, p, du, dv );
3818 } catch (Standard_Failure ) {
3824 //=============================================================================
3829 //=============================================================================
3830 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlace (Handle(GEOM_Object) theShapeWhere,
3831 Handle(GEOM_Object) theShapeWhat)
3835 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
3837 TopoDS_Shape aWhere = theShapeWhere->GetValue();
3838 TopoDS_Shape aWhat = theShapeWhat->GetValue();
3840 if (aWhere.IsNull() || aWhat.IsNull()) {
3841 SetErrorCode("Error: aWhere and aWhat TopoDS_Shape are Null.");
3845 // Compute confusion tolerance.
3846 Standard_Real aTolConf = Precision::Confusion();
3849 for (i = 0; i < 2; ++i) {
3850 TopExp_Explorer anExp(i == 0 ? aWhere : aWhat, TopAbs_VERTEX);
3852 for (; anExp.More(); anExp.Next()) {
3853 const TopoDS_Vertex aVtx = TopoDS::Vertex(anExp.Current());
3854 const Standard_Real aTolVtx = BRep_Tool::Tolerance(aVtx);
3856 if (aTolVtx > aTolConf) {
3862 // Compute mass tolerance.
3863 Bnd_Box aBoundingBox;
3864 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
3865 Standard_Real aMassTol;
3867 BRepBndLib::Add(aWhere, aBoundingBox);
3868 BRepBndLib::Add(aWhat, aBoundingBox);
3869 aBoundingBox.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
3870 aMassTol = Max(aXmax - aXmin, aYmax - aYmin);
3871 aMassTol = Max(aMassTol, aZmax - aZmin);
3872 aMassTol *= aTolConf;
3874 // Searching for the sub-shapes inside the ShapeWhere shape
3875 GEOMAlgo_GetInPlace aGIP;
3876 aGIP.SetTolerance(aTolConf);
3877 aGIP.SetTolMass(aMassTol);
3878 aGIP.SetTolCG(aTolConf);
3880 aGIP.SetArgument(aWhat);
3881 aGIP.SetShapeWhere(aWhere);
3884 int iErr = aGIP.ErrorStatus();
3886 SetErrorCode("Error in GEOMAlgo_GetInPlace");
3890 // Add direct result.
3891 TopTools_ListOfShape aLSA;
3892 const TopoDS_Shape &aShapeResult = aGIP.Result();
3893 TopTools_MapOfShape aMFence;
3894 TopTools_IndexedMapOfShape aWhereIndices;
3896 TopExp::MapShapes(aWhere, aWhereIndices);
3898 if (aShapeResult.IsNull() == Standard_False) {
3899 TopoDS_Iterator anIt(aShapeResult);
3901 for (; anIt.More(); anIt.Next()) {
3902 const TopoDS_Shape &aPart = anIt.Value();
3904 if(aWhereIndices.Contains(aPart) && aMFence.Add(aPart)) {
3910 if (aLSA.Extent() == 0) {
3911 SetErrorCode(NOT_FOUND_ANY); // Not found any Results
3915 Handle(TColStd_HArray1OfInteger) aModifiedArray = new TColStd_HArray1OfInteger (1, aLSA.Extent());
3916 TopTools_ListIteratorOfListOfShape anIterModif (aLSA);
3917 for (Standard_Integer imod = 1; anIterModif.More(); anIterModif.Next(), imod++) {
3918 if (aWhereIndices.Contains(anIterModif.Value())) {
3919 aModifiedArray->SetValue(imod, aWhereIndices.FindIndex(anIterModif.Value()));
3922 SetErrorCode("Error: wrong sub-shape returned");
3928 Handle(GEOM_Object) aResult = GetEngine()->AddSubShape(theShapeWhere, aModifiedArray);
3929 if (aResult.IsNull()) {
3930 SetErrorCode("Error in algorithm: result found, but cannot be returned.");
3934 if (aModifiedArray->Length() > 1 || theShapeWhat->GetType() == GEOM_GROUP) {
3936 aResult->SetType(GEOM_GROUP);
3938 //Set a sub-shape type
3939 TopoDS_Shape aFirstFound = aLSA.First();
3940 TopAbs_ShapeEnum aShapeType = aFirstFound.ShapeType();
3942 TDF_Label aFreeLabel = aResult->GetFreeLabel();
3943 TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aShapeType);
3946 //Make a Python command
3947 Handle(GEOM_Function) aFunction = aResult->GetFunction(1);
3949 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetInPlace("
3950 << theShapeWhere << ", " << theShapeWhat << ", True)";
3956 //=============================================================================
3958 * case GetInPlaceOld:
3961 //=============================================================================
3962 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlaceOld (Handle(GEOM_Object) theShapeWhere,
3963 Handle(GEOM_Object) theShapeWhat)
3967 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
3969 TopoDS_Shape aWhere = theShapeWhere->GetValue();
3970 TopoDS_Shape aWhat = theShapeWhat->GetValue();
3971 TopoDS_Shape aPntShape;
3972 TopoDS_Vertex aVertex;
3974 if (aWhere.IsNull() || aWhat.IsNull()) {
3975 SetErrorCode("Error: aWhere and aWhat TopoDS_Shape are Null.");
3979 Handle(GEOM_Function) aWhereFunction = theShapeWhere->GetLastFunction();
3980 if (aWhereFunction.IsNull()) {
3981 SetErrorCode("Error: aWhereFunction is Null.");
3985 TopTools_IndexedMapOfShape aWhereIndices;
3986 TopExp::MapShapes(aWhere, aWhereIndices);
3988 TColStd_ListOfInteger aModifiedList;
3989 Standard_Integer aWhereIndex;
3990 Handle(TColStd_HArray1OfInteger) aModifiedArray;
3991 Handle(GEOM_Object) aResult;
3993 bool isFound = false;
3994 TopAbs_ShapeEnum iType = TopAbs_SOLID;
3995 //Standard_Real aWhat_Mass = 0., aWhere_Mass = 0.;
3996 Standard_Real tab_aWhat[4], tab_aWhere[4];
3997 Standard_Real dl_l = 1e-3;
3998 Standard_Real min_l, Tol_0D, Tol_1D, Tol_2D, Tol_3D, Tol_Mass;
3999 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
4000 Bnd_Box BoundingBox;
4001 gp_Pnt aPnt, aPnt_aWhat, tab_Pnt[2];
4002 GProp_GProps aProps;
4004 // Find the iType of the aWhat shape
4006 if ( aWhat.ShapeType() == TopAbs_VERTEX ) iType = TopAbs_VERTEX;
4007 else if ( aWhat.ShapeType() == TopAbs_EDGE || aWhat.ShapeType() == TopAbs_WIRE ) iType = TopAbs_EDGE;
4008 else if ( aWhat.ShapeType() == TopAbs_FACE || aWhat.ShapeType() == TopAbs_SHELL ) iType = TopAbs_FACE;
4009 else if ( aWhat.ShapeType() == TopAbs_SOLID || aWhat.ShapeType() == TopAbs_COMPSOLID ) iType = TopAbs_SOLID;
4010 else if ( aWhat.ShapeType() == TopAbs_COMPOUND ) {
4011 // Only the iType of the first shape in the compound is taken into account
4012 TopoDS_Iterator It (aWhat, Standard_False, Standard_False);
4014 SetErrorCode("Error: theShapeWhat is an empty COMPOUND.");
4017 TopAbs_ShapeEnum compType = It.Value().ShapeType();
4018 if ( compType == TopAbs_VERTEX ) iType = TopAbs_VERTEX;
4019 else if ( compType == TopAbs_EDGE || compType == TopAbs_WIRE ) iType = TopAbs_EDGE;
4020 else if ( compType == TopAbs_FACE || compType == TopAbs_SHELL) iType = TopAbs_FACE;
4021 else if ( compType == TopAbs_SOLID || compType == TopAbs_COMPSOLID) iType = TopAbs_SOLID;
4024 SetErrorCode("Error: An attempt to extract a shape of not supported type.");
4028 iType = GEOMUtils::GetTypeOfSimplePart(aWhat);
4029 if (iType == TopAbs_SHAPE) {
4030 SetErrorCode("Error: An attempt to extract a shape of not supported type.");
4034 TopExp_Explorer Exp_aWhat ( aWhat, iType );
4035 TopExp_Explorer Exp_aWhere ( aWhere, iType );
4036 TopExp_Explorer Exp_Edge ( aWhere, TopAbs_EDGE );
4038 // Find the shortest edge in theShapeWhere shape
4039 BRepBndLib::Add(aWhere, BoundingBox);
4040 BoundingBox.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
4041 min_l = fabs(aXmax - aXmin);
4042 if( min_l < fabs(aYmax - aYmin) ) min_l = fabs(aYmax - aYmin);
4043 if( min_l < fabs(aZmax - aZmin) ) min_l = fabs(aZmax - aZmin);
4045 // Mantis issue 0020908 BEGIN
4046 if (!Exp_Edge.More()) {
4047 min_l = Precision::Confusion();
4049 // Mantis issue 0020908 END
4050 for ( Standard_Integer nbEdge = 0; Exp_Edge.More(); Exp_Edge.Next(), nbEdge++ ) {
4051 TopExp_Explorer Exp_Vertex( Exp_Edge.Current(), TopAbs_VERTEX);
4052 for ( Standard_Integer nbVertex = 0; Exp_Vertex.More(); Exp_Vertex.Next(), nbVertex++ ) {
4053 aPnt = BRep_Tool::Pnt( TopoDS::Vertex( Exp_Vertex.Current() ) );
4054 tab_Pnt[nbVertex] = aPnt;
4056 if ( ! tab_Pnt[0].IsEqual(tab_Pnt[1], dl_l) ) {
4057 BRepGProp::LinearProperties(Exp_Edge.Current(), aProps);
4058 if ( aProps.Mass() < min_l ) min_l = aProps.Mass();
4062 // Compute tolerances
4064 Tol_1D = dl_l * min_l;
4065 Tol_2D = dl_l * ( min_l * min_l) * ( 2. + dl_l);
4066 Tol_3D = dl_l * ( min_l * min_l * min_l ) * ( 3. + (3 * dl_l) + (dl_l * dl_l) );
4068 if (Tol_0D < Precision::Confusion()) Tol_0D = Precision::Confusion();
4069 if (Tol_1D < Precision::Confusion()) Tol_1D = Precision::Confusion();
4070 if (Tol_2D < Precision::Confusion()) Tol_2D = Precision::Confusion();
4071 if (Tol_3D < Precision::Confusion()) Tol_3D = Precision::Confusion();
4073 //if (Tol_1D > 1.0) Tol_1D = 1.0;
4074 //if (Tol_2D > 1.0) Tol_2D = 1.0;
4075 //if (Tol_3D > 1.0) Tol_3D = 1.0;
4078 if ( iType == TopAbs_VERTEX ) Tol_Mass = Tol_0D;
4079 else if ( iType == TopAbs_EDGE ) Tol_Mass = Tol_1D;
4080 else if ( iType == TopAbs_FACE ) Tol_Mass = Tol_2D;
4082 // Compute the ShapeWhat Mass
4084 for ( ; Exp_aWhat.More(); Exp_aWhat.Next() ) {
4085 if ( iType == TopAbs_VERTEX ) {
4089 else if ( iType == TopAbs_EDGE ) BRepGProp::LinearProperties(Exp_aWhat.Current(), aProps);
4090 else if ( iType == TopAbs_FACE ) BRepGProp::SurfaceProperties(Exp_aWhat.Current(), aProps);
4091 else BRepGProp::VolumeProperties(Exp_aWhat.Current(), aProps);
4092 aWhat_Mass += aProps.Mass();
4096 // Searching for the sub-shapes inside the ShapeWhere shape
4097 TopTools_MapOfShape map_aWhere;
4098 for ( Exp_aWhere.ReInit(); Exp_aWhere.More(); Exp_aWhere.Next() ) {
4099 if (!map_aWhere.Add(Exp_aWhere.Current()))
4100 continue; // skip repeated shape to avoid mass addition
4101 GetShapeProperties( Exp_aWhere.Current(), tab_aWhere, aPnt );
4102 for ( Exp_aWhat.ReInit(); Exp_aWhat.More(); Exp_aWhat.Next() ) {
4103 GetShapeProperties( Exp_aWhat.Current(), tab_aWhat, aPnt_aWhat );
4104 if ( fabs(tab_aWhat[3] - tab_aWhere[3]) <= Tol_Mass && aPnt_aWhat.Distance(aPnt) <= Tol_1D )
4107 if ( (tab_aWhat[3] - tab_aWhere[3]) > Tol_Mass ) {
4108 aPntShape = BRepBuilderAPI_MakeVertex( aPnt ).Shape();
4109 aVertex = TopoDS::Vertex( aPntShape );
4110 BRepExtrema_DistShapeShape aWhereDistance ( aVertex, Exp_aWhere.Current() );
4111 BRepExtrema_DistShapeShape aWhatDistance ( aVertex, Exp_aWhat.Current() );
4112 if ( aWhereDistance.IsDone() && aWhatDistance.IsDone() &&
4113 fabs(aWhereDistance.Value() - aWhatDistance.Value()) <= Tol_1D )
4115 // 0020162: "EDF 961 GEOM : Getinplace is getting additionnal orthogonal faces"
4116 // aVertex must be projected to the same point on Where and on What
4117 gp_Pnt pOnWhat = aWhatDistance.PointOnShape2(1);
4118 gp_Pnt pOnWhere = aWhereDistance.PointOnShape2(1);
4119 isFound = ( pOnWhat.Distance(pOnWhere) <= Tol_1D );
4120 if ( isFound && iType == TopAbs_FACE )
4122 // check normals at pOnWhat and pOnWhere
4123 const double angleTol = M_PI/180.;
4124 gp_Vec normToWhat = GetNormal( TopoDS::Face(Exp_aWhat.Current()), aWhatDistance);
4125 gp_Vec normToWhere = GetNormal( TopoDS::Face(Exp_aWhere.Current()), aWhereDistance);
4126 if ( normToWhat * normToWhere < 0 )
4127 normToWhat.Reverse();
4128 isFound = ( normToWhat.Angle( normToWhere ) < angleTol );
4134 aWhereIndex = aWhereIndices.FindIndex(Exp_aWhere.Current());
4135 aModifiedList.Append(aWhereIndex);
4136 //aWhere_Mass += tab_aWhere[3];
4141 //if ( fabs( aWhat_Mass - aWhere_Mass ) <= Tol_Mass )
4145 if (aModifiedList.Extent() == 0) { // Not found any Results
4146 SetErrorCode(NOT_FOUND_ANY);
4150 aModifiedArray = new TColStd_HArray1OfInteger (1, aModifiedList.Extent());
4151 TColStd_ListIteratorOfListOfInteger anIterModif (aModifiedList);
4152 for (Standard_Integer imod = 1; anIterModif.More(); anIterModif.Next(), imod++)
4153 aModifiedArray->SetValue(imod, anIterModif.Value());
4156 aResult = GetEngine()->AddSubShape(theShapeWhere, aModifiedArray);
4157 if (aResult.IsNull()) {
4158 SetErrorCode("Error in algorithm: result found, but cannot be returned.");
4162 if (aModifiedArray->Length() > 1 || theShapeWhat->GetType() == GEOM_GROUP) {
4164 aResult->SetType(GEOM_GROUP);
4166 //Set a sub-shape type
4167 TopoDS_Shape aFirstFound = aWhereIndices.FindKey(aModifiedArray->Value(1));
4168 TopAbs_ShapeEnum aShapeType = aFirstFound.ShapeType();
4170 TDF_Label aFreeLabel = aResult->GetFreeLabel();
4171 TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aShapeType);
4174 //Make a Python command
4175 Handle(GEOM_Function) aFunction = aResult->GetFunction(1);
4177 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetInPlace("
4178 << theShapeWhere << ", " << theShapeWhat << ", False)";
4184 //=======================================================================
4185 //function : GetInPlaceByHistory
4187 //=======================================================================
4188 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlaceByHistory
4189 (Handle(GEOM_Object) theShapeWhere,
4190 Handle(GEOM_Object) theShapeWhat)
4194 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
4196 TopoDS_Shape aWhere = theShapeWhere->GetValue();
4197 TopoDS_Shape aWhat = theShapeWhat->GetValue();
4199 if (aWhere.IsNull() || aWhat.IsNull()) return NULL;
4201 Handle(GEOM_Function) aWhereFunction = theShapeWhere->GetLastFunction();
4202 if (aWhereFunction.IsNull()) return NULL;
4204 //Fill array of indices
4205 TopTools_IndexedMapOfShape aWhereIndices;
4206 TopExp::MapShapes(aWhere, aWhereIndices);
4209 TColStd_ListOfInteger aModifiedList;
4210 bool isFound = GetInPlaceOfShape(aWhereFunction, aWhereIndices, aWhat, aModifiedList);
4212 if (!isFound || aModifiedList.Extent() < 1) {
4213 SetErrorCode("Error: No history found for the sought shape or its sub-shapes.");
4217 Standard_Integer nbFound = aModifiedList.Extent();
4218 TColStd_ListIteratorOfListOfInteger anIterModif (aModifiedList);
4221 // remove sub-shapes inappropriate for group creation
4222 TopAbs_ShapeEnum subType = TopAbs_SHAPE;
4223 while ( anIterModif.More() ) {
4224 TopAbs_ShapeEnum type = aWhereIndices( anIterModif.Value() ).ShapeType();
4225 bool okForGroup = ( type == TopAbs_VERTEX || type == TopAbs_EDGE ||
4226 type == TopAbs_FACE || type == TopAbs_SOLID );
4228 if ( subType == TopAbs_SHAPE )
4231 okForGroup = ( subType == type );
4236 aModifiedList.Remove( anIterModif );
4237 nbFound -= ( !okForGroup );
4239 if ( nbFound == 0 ) {
4240 SetErrorCode("Error: result found but it's type is inappropriate for group creation.");
4245 Handle(TColStd_HArray1OfInteger) aModifiedArray =
4246 new TColStd_HArray1OfInteger( 1, nbFound );
4247 anIterModif.Initialize(aModifiedList);
4248 for (Standard_Integer imod = 1; anIterModif.More(); anIterModif.Next(), imod++)
4249 aModifiedArray->SetValue(imod, anIterModif.Value());
4252 Handle(GEOM_Object) aResult = GetEngine()->AddSubShape(theShapeWhere, aModifiedArray);
4253 if (aResult.IsNull()) {
4254 SetErrorCode("Error in algorithm: result found, but cannot be returned.");
4258 if (aModifiedArray->Length() > 1) {
4260 aResult->SetType(GEOM_GROUP);
4262 //Set a sub-shape type
4263 TopoDS_Shape aFirstFound = aWhereIndices.FindKey(aModifiedArray->Value(1));
4264 TopAbs_ShapeEnum aShapeType = aFirstFound.ShapeType();
4266 TDF_Label aFreeLabel = aResult->GetFreeLabel();
4267 TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aShapeType);
4270 //Make a Python command
4271 Handle(GEOM_Function) aFunction = aResult->GetFunction(1);
4273 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetInPlaceByHistory("
4274 << theShapeWhere << ", " << theShapeWhat << ")";
4280 #define MAX_TOLERANCE 1.e-7
4282 //=======================================================================
4283 //function : isSameEdge
4284 //purpose : Returns True if two edges coincide
4285 //=======================================================================
4286 static bool isSameEdge(const TopoDS_Edge& theEdge1, const TopoDS_Edge& theEdge2)
4288 TopoDS_Vertex V11, V12, V21, V22;
4289 TopExp::Vertices(theEdge1, V11, V12);
4290 TopExp::Vertices(theEdge2, V21, V22);
4291 gp_Pnt P11 = BRep_Tool::Pnt(V11);
4292 gp_Pnt P12 = BRep_Tool::Pnt(V12);
4293 gp_Pnt P21 = BRep_Tool::Pnt(V21);
4294 gp_Pnt P22 = BRep_Tool::Pnt(V22);
4295 bool coincide = false;
4297 //Check that ends of edges coincide
4298 if(P11.Distance(P21) <= MAX_TOLERANCE) {
4299 if(P12.Distance(P22) <= MAX_TOLERANCE) coincide = true;
4301 else if(P11.Distance(P22) <= MAX_TOLERANCE) {
4302 if(P12.Distance(P21) <= MAX_TOLERANCE) coincide = true;
4305 if(!coincide) return false;
4307 if (BRep_Tool::Degenerated(theEdge1))
4308 if (BRep_Tool::Degenerated(theEdge2)) return true;
4311 if (BRep_Tool::Degenerated(theEdge2)) return false;
4313 double U11, U12, U21, U22;
4314 Handle(Geom_Curve) C1 = BRep_Tool::Curve(theEdge1, U11, U12);
4315 Handle(Geom_Curve) C2 = BRep_Tool::Curve(theEdge2, U21, U22);
4316 if(C1->DynamicType() == C2->DynamicType()) return true;
4318 //Check that both edges has the same geometry
4319 double range = U12-U11;
4320 double U = U11+ range/3.0;
4321 gp_Pnt P1 = C1->Value(U); //Compute a point on one third of the edge's length
4322 U = U11+range*2.0/3.0;
4323 gp_Pnt P2 = C1->Value(U); //Compute a point on two thirds of the edge's length
4325 if(!GeomLib_Tool::Parameter(C2, P1, MAX_TOLERANCE, U) || U < U21 || U > U22)
4328 if(P1.Distance(C2->Value(U)) > MAX_TOLERANCE) return false;
4330 if(!GeomLib_Tool::Parameter(C2, P2, MAX_TOLERANCE, U) || U < U21 || U > U22)
4333 if(P2.Distance(C2->Value(U)) > MAX_TOLERANCE) return false;
4338 #include <TopoDS_TShape.hxx>
4339 //=======================================================================
4340 //function : isSameFace
4341 //purpose : Returns True if two faces coincide
4342 //=======================================================================
4343 static bool isSameFace(const TopoDS_Face& theFace1, const TopoDS_Face& theFace2)
4345 TopExp_Explorer E(theFace1, TopAbs_EDGE);
4346 TopTools_ListOfShape LS1, LS2;
4347 for(; E.More(); E.Next()) LS1.Append(E.Current());
4349 E.Init(theFace2, TopAbs_EDGE);
4350 for(; E.More(); E.Next()) LS2.Append(E.Current());
4352 //Compare the number of edges in the faces
4353 if(LS1.Extent() != LS2.Extent()) return false;
4355 double aMin = RealFirst(), aMax = RealLast();
4356 double xminB1=aMax, yminB1=aMax, zminB1=aMax, xminB2=aMax, yminB2=aMax, zminB2=aMax;
4357 double xmaxB1=aMin, ymaxB1=aMin, zmaxB1=aMin, xmaxB2=aMin, ymaxB2=aMin, zmaxB2=aMin;
4359 for(E.Init(theFace1, TopAbs_VERTEX); E.More(); E.Next()) {
4360 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4361 if(P.X() < xminB1) xminB1 = P.X();
4362 if(P.Y() < yminB1) yminB1 = P.Y();
4363 if(P.Z() < zminB1) zminB1 = P.Z();
4364 if(P.X() > xmaxB1) xmaxB1 = P.X();
4365 if(P.Y() > ymaxB1) ymaxB1 = P.Y();
4366 if(P.Z() > zmaxB1) zmaxB1 = P.Z();
4369 for(E.Init(theFace2, TopAbs_VERTEX); E.More(); E.Next()) {
4370 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4371 if(P.X() < xminB2) xminB2 = P.X();
4372 if(P.Y() < yminB2) yminB2 = P.Y();
4373 if(P.Z() < zminB2) zminB2 = P.Z();
4374 if(P.X() > xmaxB2) xmaxB2 = P.X();
4375 if(P.Y() > ymaxB2) ymaxB2 = P.Y();
4376 if(P.Z() > zmaxB2) zmaxB2 = P.Z();
4379 //Compare the bounding boxes of both faces
4380 if(gp_Pnt(xminB1, yminB1, zminB1).Distance(gp_Pnt(xminB2, yminB2, zminB2)) > MAX_TOLERANCE)
4383 if(gp_Pnt(xmaxB1, ymaxB1, zmaxB1).Distance(gp_Pnt(xmaxB2, ymaxB2, zmaxB2)) > MAX_TOLERANCE)
4386 Handle(Geom_Surface) S1 = BRep_Tool::Surface(theFace1);
4387 Handle(Geom_Surface) S2 = BRep_Tool::Surface(theFace2);
4389 //Check if there a coincidence of two surfaces at least in two points
4390 double U11, U12, V11, V12, U21, U22, V21, V22;
4391 BRepTools::UVBounds(theFace1, U11, U12, V11, V12);
4392 BRepTools::UVBounds(theFace2, U21, U22, V21, V22);
4394 double rangeU = U12-U11;
4395 double rangeV = V12-V11;
4396 double U = U11 + rangeU/3.0;
4397 double V = V11 + rangeV/3.0;
4398 gp_Pnt P1 = S1->Value(U, V);
4399 U = U11+rangeU*2.0/3.0;
4400 V = V11+rangeV*2.0/3.0;
4401 gp_Pnt P2 = S1->Value(U, V);
4403 if (!GeomLib_Tool::Parameters(S2, P1, MAX_TOLERANCE, U, V) || U < U21 || U > U22 || V < V21 || V > V22)
4406 if (P1.Distance(S2->Value(U,V)) > MAX_TOLERANCE) return false;
4408 if (!GeomLib_Tool::Parameters(S2, P2, MAX_TOLERANCE, U, V) || U < U21 || U > U22 || V < V21 || V > V22)
4411 if (P2.Distance(S2->Value(U, V)) > MAX_TOLERANCE) return false;
4413 //Check that each edge of the Face1 has a counterpart in the Face2
4414 TopTools_MapOfOrientedShape aMap;
4415 TopTools_ListIteratorOfListOfShape LSI1(LS1);
4416 for(; LSI1.More(); LSI1.Next()) {
4417 TopoDS_Edge E = TopoDS::Edge(LSI1.Value());
4418 bool isFound = false;
4419 TopTools_ListIteratorOfListOfShape LSI2(LS2);
4420 for(; LSI2.More(); LSI2.Next()) {
4421 TopoDS_Shape aValue = LSI2.Value();
4422 if(aMap.Contains(aValue)) continue; //To avoid checking already found edge several times
4423 if(isSameEdge(E, TopoDS::Edge(aValue))) {
4429 if(!isFound) return false;
4435 //=======================================================================
4436 //function : isSameSolid
4437 //purpose : Returns True if two solids coincide
4438 //=======================================================================
4439 bool isSameSolid(const TopoDS_Solid& theSolid1, const TopoDS_Solid& theSolid2)
4441 TopExp_Explorer E(theSolid1, TopAbs_FACE);
4442 TopTools_ListOfShape LS1, LS2;
4443 for(; E.More(); E.Next()) LS1.Append(E.Current());
4444 E.Init(theSolid2, TopAbs_FACE);
4445 for(; E.More(); E.Next()) LS2.Append(E.Current());
4447 if(LS1.Extent() != LS2.Extent()) return false;
4449 double aMin = RealFirst(), aMax = RealLast();
4450 double xminB1=aMax, yminB1=aMax, zminB1=aMax, xminB2=aMax, yminB2=aMax, zminB2=aMax;
4451 double xmaxB1=aMin, ymaxB1=aMin, zmaxB1=aMin, xmaxB2=aMin, ymaxB2=aMin, zmaxB2=aMin;
4453 for(E.Init(theSolid1, TopAbs_VERTEX); E.More(); E.Next()) {
4454 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4455 if(P.X() < xminB1) xminB1 = P.X();
4456 if(P.Y() < yminB1) yminB1 = P.Y();
4457 if(P.Z() < zminB1) zminB1 = P.Z();
4458 if(P.X() > xmaxB1) xmaxB1 = P.X();
4459 if(P.Y() > ymaxB1) ymaxB1 = P.Y();
4460 if(P.Z() > zmaxB1) zmaxB1 = P.Z();
4463 for(E.Init(theSolid2, TopAbs_VERTEX); E.More(); E.Next()) {
4464 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4465 if(P.X() < xminB2) xminB2 = P.X();
4466 if(P.Y() < yminB2) yminB2 = P.Y();
4467 if(P.Z() < zminB2) zminB2 = P.Z();
4468 if(P.X() > xmaxB2) xmaxB2 = P.X();
4469 if(P.Y() > ymaxB2) ymaxB2 = P.Y();
4470 if(P.Z() > zmaxB2) zmaxB2 = P.Z();
4473 //Compare the bounding boxes of both solids
4474 if(gp_Pnt(xminB1, yminB1, zminB1).Distance(gp_Pnt(xminB2, yminB2, zminB2)) > MAX_TOLERANCE)
4477 if(gp_Pnt(xmaxB1, ymaxB1, zmaxB1).Distance(gp_Pnt(xmaxB2, ymaxB2, zmaxB2)) > MAX_TOLERANCE)
4480 //Check that each face of the Solid1 has a counterpart in the Solid2
4481 TopTools_MapOfOrientedShape aMap;
4482 TopTools_ListIteratorOfListOfShape LSI1(LS1);
4483 for(; LSI1.More(); LSI1.Next()) {
4484 TopoDS_Face F = TopoDS::Face(LSI1.Value());
4485 bool isFound = false;
4486 TopTools_ListIteratorOfListOfShape LSI2(LS2);
4487 for(; LSI2.More(); LSI2.Next()) {
4488 if(aMap.Contains(LSI2.Value())) continue; //To avoid checking already found faces several times
4489 if(isSameFace(F, TopoDS::Face(LSI2.Value()))) {
4490 aMap.Add(LSI2.Value());
4495 if(!isFound) return false;
4501 //=======================================================================
4502 //function : GetSame
4504 //=======================================================================
4505 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetSame(const Handle(GEOM_Object)& theShapeWhere,
4506 const Handle(GEOM_Object)& theShapeWhat)
4509 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
4511 TopoDS_Shape aWhere = theShapeWhere->GetValue();
4512 TopoDS_Shape aWhat = theShapeWhat->GetValue();
4514 if (aWhere.IsNull() || aWhat.IsNull()) return NULL;
4517 bool isFound = false;
4518 TopoDS_Shape aSubShape;
4519 TopTools_MapOfShape aMap;
4521 if (aWhat.ShapeType() == TopAbs_COMPOUND || aWhat.ShapeType() == TopAbs_COMPSOLID) {
4522 TopoDS_Iterator It (aWhat, Standard_True, Standard_True);
4523 if (It.More()) aWhat = It.Value();
4526 SetErrorCode("Compounds of two or more shapes are not allowed for aWhat argument");
4531 switch (aWhat.ShapeType()) {
4532 case TopAbs_VERTEX: {
4533 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(aWhat));
4534 TopExp_Explorer E(aWhere, TopAbs_VERTEX);
4535 for(; E.More(); E.Next()) {
4536 if(!aMap.Add(E.Current())) continue;
4537 gp_Pnt P2 = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4538 if(P.Distance(P2) <= MAX_TOLERANCE) {
4540 aSubShape = E.Current();
4547 TopoDS_Edge anEdge = TopoDS::Edge(aWhat);
4548 TopExp_Explorer E(aWhere, TopAbs_EDGE);
4549 for(; E.More(); E.Next()) {
4550 if(!aMap.Add(E.Current())) continue;
4551 if(isSameEdge(anEdge, TopoDS::Edge(E.Current()))) {
4552 aSubShape = E.Current();
4560 TopoDS_Face aFace = TopoDS::Face(aWhat);
4561 TopExp_Explorer E(aWhere, TopAbs_FACE);
4562 for(; E.More(); E.Next()) {
4563 if(!aMap.Add(E.Current())) continue;
4564 if(isSameFace(aFace, TopoDS::Face(E.Current()))) {
4565 aSubShape = E.Current();
4572 case TopAbs_SOLID: {
4573 TopoDS_Solid aSolid = TopoDS::Solid(aWhat);
4574 TopExp_Explorer E(aWhere, TopAbs_SOLID);
4575 for(; E.More(); E.Next()) {
4576 if(!aMap.Add(E.Current())) continue;
4577 if(isSameSolid(aSolid, TopoDS::Solid(E.Current()))) {
4578 aSubShape = E.Current();
4590 TopTools_IndexedMapOfShape anIndices;
4591 TopExp::MapShapes(aWhere, anIndices);
4592 if (anIndices.Contains(aSubShape))
4593 anIndex = anIndices.FindIndex(aSubShape);
4596 if (anIndex < 0) return NULL;
4598 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
4600 anArray->SetValue(1, anIndex);
4602 Handle(GEOM_Object) aResult = GetEngine()->AddSubShape(theShapeWhere, anArray);
4603 Handle(GEOM_Function) aFunction = aResult->GetLastFunction();
4605 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetSame("
4606 << theShapeWhere << ", " << theShapeWhat << ")";
4614 //=======================================================================
4615 //function : GetSameIDs
4617 //=======================================================================
4618 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetSameIDs
4619 (const Handle(GEOM_Object)& theShapeWhere,
4620 const Handle(GEOM_Object)& theShapeWhat)
4623 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
4625 TopoDS_Shape aWhere = theShapeWhere->GetValue();
4626 TopoDS_Shape aWhat = theShapeWhat->GetValue();
4628 if (aWhere.IsNull() || aWhat.IsNull()) return NULL;
4630 TopTools_ListOfShape listShape;
4631 TopTools_MapOfShape aMap;
4633 if (aWhat.ShapeType() == TopAbs_COMPOUND || aWhat.ShapeType() == TopAbs_COMPSOLID) {
4634 TopoDS_Iterator It (aWhat, Standard_True, Standard_True);
4635 if (It.More()) aWhat = It.Value();
4638 SetErrorCode("Compounds of two or more shapes are not allowed for aWhat argument");
4643 switch (aWhat.ShapeType()) {
4644 case TopAbs_VERTEX: {
4645 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(aWhat));
4646 TopExp_Explorer E(aWhere, TopAbs_VERTEX);
4647 for(; E.More(); E.Next()) {
4648 if(!aMap.Add(E.Current())) continue;
4649 gp_Pnt P2 = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4650 if(P.Distance(P2) <= MAX_TOLERANCE) {
4651 listShape.Append(E.Current());
4657 TopoDS_Edge anEdge = TopoDS::Edge(aWhat);
4658 TopExp_Explorer E(aWhere, TopAbs_EDGE);
4659 for(; E.More(); E.Next()) {
4660 if(!aMap.Add(E.Current())) continue;
4661 if(isSameEdge(anEdge, TopoDS::Edge(E.Current()))) {
4662 listShape.Append(E.Current());
4668 TopoDS_Face aFace = TopoDS::Face(aWhat);
4669 TopExp_Explorer E(aWhere, TopAbs_FACE);
4670 for(; E.More(); E.Next()) {
4671 if(!aMap.Add(E.Current())) continue;
4672 if(isSameFace(aFace, TopoDS::Face(E.Current()))) {
4673 listShape.Append(E.Current());
4678 case TopAbs_SOLID: {
4679 TopoDS_Solid aSolid = TopoDS::Solid(aWhat);
4680 TopExp_Explorer E(aWhere, TopAbs_SOLID);
4681 for(; E.More(); E.Next()) {
4682 if(!aMap.Add(E.Current())) continue;
4683 if(isSameSolid(aSolid, TopoDS::Solid(E.Current()))) {
4684 listShape.Append(E.Current());
4693 if ( !listShape.IsEmpty() ) {
4694 TopTools_IndexedMapOfShape anIndices;
4695 TopExp::MapShapes(aWhere, anIndices);
4696 TopTools_ListIteratorOfListOfShape itSub (listShape);
4697 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
4698 for (; itSub.More(); itSub.Next()) {
4699 if (anIndices.Contains(itSub.Value()))
4700 aSeq->Append(anIndices.FindIndex(itSub.Value()));
4703 // The GetSameIDs() doesn't change object so no new function is required.
4704 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShapeWhere,theShapeWhat)->GetLastFunction();
4706 // Make a Python command
4707 GEOM::TPythonDump(aFunction, /*append=*/true)
4708 << "listSameIDs = geompy.GetSameIDs("
4709 << theShapeWhere << ", "
4710 << theShapeWhat << ")";
4713 SetErrorCode(NOT_FOUND_ANY);