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 <TFunction_DriverTable.hxx>
71 #include <TFunction_Driver.hxx>
72 #include <TFunction_Logbook.hxx>
73 #include <TDataStd_Integer.hxx>
74 #include <TDataStd_IntegerArray.hxx>
75 #include <TDataStd_ListIteratorOfListOfExtendedString.hxx>
76 #include <TDF_Tool.hxx>
78 #include <BRepExtrema_ExtCF.hxx>
79 #include <BRepExtrema_DistShapeShape.hxx>
81 #include <BRep_Tool.hxx>
82 #include <BRep_Builder.hxx>
83 #include <BRepTools.hxx>
84 #include <BRepGProp.hxx>
85 #include <BRepAdaptor_Curve.hxx>
86 #include <BRepAdaptor_Surface.hxx>
87 #include <BRepBndLib.hxx>
88 #include <BRepMesh_IncrementalMesh.hxx>
92 #include <TopExp_Explorer.hxx>
93 #include <TopLoc_Location.hxx>
95 #include <TopoDS_Shape.hxx>
96 #include <TopoDS_Solid.hxx>
97 #include <TopoDS_Face.hxx>
98 #include <TopoDS_Edge.hxx>
99 #include <TopoDS_Vertex.hxx>
100 #include <TopoDS_Compound.hxx>
101 #include <TopoDS_Iterator.hxx>
102 #include <TopTools_Array1OfShape.hxx>
103 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
104 #include <TopTools_IndexedMapOfShape.hxx>
105 #include <TopTools_ListIteratorOfListOfShape.hxx>
106 #include <TopTools_MapOfShape.hxx>
107 #include <TopTools_MapOfOrientedShape.hxx>
109 #include <Geom_Surface.hxx>
110 #include <Geom_Plane.hxx>
111 #include <Geom_SphericalSurface.hxx>
112 #include <Geom_CylindricalSurface.hxx>
113 #include <GeomAdaptor_Surface.hxx>
115 #include <GeomLib_Tool.hxx>
116 #include <Geom2d_Curve.hxx>
118 #include <Bnd_Box.hxx>
119 #include <GProp_GProps.hxx>
120 #include <TColStd_Array1OfReal.hxx>
121 #include <TColStd_HArray1OfInteger.hxx>
122 #include <TColStd_ListIteratorOfListOfInteger.hxx>
123 #include <TColStd_ListOfInteger.hxx>
124 #include <gp_Cylinder.hxx>
125 #include <gp_Lin.hxx>
126 #include <gp_Pnt.hxx>
130 #include <functional>
132 #include <Standard_NullObject.hxx>
133 #include <Standard_Failure.hxx>
134 #include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
136 // Includes added for GetInPlace algorithm improvement
138 #include <GEOMImpl_MeasureDriver.hxx>
139 #include <GEOMImpl_IMeasure.hxx>
140 #include <BRepBuilderAPI_MakeVertex.hxx>
142 #include <BRepClass_FaceClassifier.hxx>
143 #include <BRepClass3d_SolidClassifier.hxx>
144 #include <Precision.hxx>
146 //=============================================================================
150 //=============================================================================
151 GEOMImpl_IShapesOperations::GEOMImpl_IShapesOperations (GEOM_Engine* theEngine, int theDocID)
152 : GEOM_IOperations(theEngine, theDocID)
154 MESSAGE("GEOMImpl_IShapesOperations::GEOMImpl_IShapesOperations");
157 //=============================================================================
161 //=============================================================================
162 GEOMImpl_IShapesOperations::~GEOMImpl_IShapesOperations()
164 MESSAGE("GEOMImpl_IShapesOperations::~GEOMImpl_IShapesOperations");
167 //=============================================================================
171 //=============================================================================
172 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeEdge
173 (Handle(GEOM_Object) thePnt1, Handle(GEOM_Object) thePnt2)
177 if (thePnt1.IsNull() || thePnt2.IsNull()) return NULL;
179 //Add a new Edge object
180 Handle(GEOM_Object) anEdge = GetEngine()->AddObject(GetDocID(), GEOM_EDGE);
182 //Add a new Vector function
183 Handle(GEOM_Function) aFunction =
184 anEdge->AddFunction(GEOMImpl_VectorDriver::GetID(), VECTOR_TWO_PNT);
186 //Check if the function is set correctly
187 if (aFunction->GetDriverGUID() != GEOMImpl_VectorDriver::GetID()) return NULL;
189 GEOMImpl_IVector aPI (aFunction);
191 Handle(GEOM_Function) aRef1 = thePnt1->GetLastFunction();
192 Handle(GEOM_Function) aRef2 = thePnt2->GetLastFunction();
193 if (aRef1.IsNull() || aRef2.IsNull()) return NULL;
195 aPI.SetPoint1(aRef1);
196 aPI.SetPoint2(aRef2);
198 //Compute the Edge value
201 if (!GetSolver()->ComputeFunction(aFunction)) {
202 SetErrorCode("Vector driver failed");
206 catch (Standard_Failure) {
207 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
208 SetErrorCode(aFail->GetMessageString());
212 //Make a Python command
213 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdge("
214 << thePnt1 << ", " << thePnt2 << ")";
220 //=============================================================================
222 * MakeEdgeOnCurveByLength
224 //=============================================================================
225 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeEdgeOnCurveByLength
226 (Handle(GEOM_Object) theRefCurve,
227 const Standard_Real theLength,
228 Handle(GEOM_Object) theStartPoint)
232 if (theRefCurve.IsNull()) return NULL;
234 //Add a new Edge object
235 Handle(GEOM_Object) anEdge = GetEngine()->AddObject(GetDocID(), GEOM_EDGE);
237 //Add a new Vector function
238 Handle(GEOM_Function) aFunction =
239 anEdge->AddFunction(GEOMImpl_ShapeDriver::GetID(), EDGE_CURVE_LENGTH);
241 //Check if the function is set correctly
242 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
244 GEOMImpl_IVector aPI (aFunction);
246 Handle(GEOM_Function) aRef1 = theRefCurve->GetLastFunction();
247 if (aRef1.IsNull()) return NULL;
248 aPI.SetPoint1(aRef1);
250 if (!theStartPoint.IsNull()) {
251 Handle(GEOM_Function) aRef2 = theStartPoint->GetLastFunction();
252 aPI.SetPoint2(aRef2);
255 aPI.SetParameter(theLength);
257 //Compute the Edge value
260 if (!GetSolver()->ComputeFunction(aFunction)) {
261 SetErrorCode("Vector driver failed");
265 catch (Standard_Failure) {
266 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
267 SetErrorCode(aFail->GetMessageString());
271 //Make a Python command
272 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdgeOnCurveByLength("
273 << theRefCurve << ", " << theLength << ", " << theStartPoint << ")";
279 //=============================================================================
283 //=============================================================================
284 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeEdgeWire
285 (Handle(GEOM_Object) theWire,
286 const Standard_Real theLinearTolerance,
287 const Standard_Real theAngularTolerance)
291 if (theWire.IsNull()) return NULL;
293 //Add a new Edge object
294 Handle(GEOM_Object) anEdge = GetEngine()->AddObject(GetDocID(), GEOM_EDGE);
296 //Add a new Vector function
297 Handle(GEOM_Function) aFunction =
298 anEdge->AddFunction(GEOMImpl_ShapeDriver::GetID(), EDGE_WIRE);
300 //Check if the function is set correctly
301 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
303 GEOMImpl_IShapes aCI (aFunction);
305 Handle(GEOM_Function) aWire = theWire->GetLastFunction();
307 if (aWire.IsNull()) return NULL;
310 aCI.SetTolerance(theLinearTolerance);
311 aCI.SetAngularTolerance(theAngularTolerance);
313 //Compute the Edge value
316 if (!GetSolver()->ComputeFunction(aFunction)) {
317 SetErrorCode("Shape driver failed");
321 catch (Standard_Failure) {
322 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
323 SetErrorCode(aFail->GetMessageString());
327 const double DEF_LIN_TOL = Precision::Confusion();
328 const double DEF_ANG_TOL = Precision::Angular();
329 //Make a Python command
330 if ( theAngularTolerance == DEF_ANG_TOL ) {
331 if ( theLinearTolerance == DEF_LIN_TOL )
332 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdgeWire("
335 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdgeWire("
336 << theWire << ", " << theLinearTolerance << ")";
339 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdgeWire("
340 << theWire << ", " << theLinearTolerance << ", "
341 << theAngularTolerance << ")";
348 //=============================================================================
352 //=============================================================================
353 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeWire
354 (std::list<Handle(GEOM_Object)> theShapes,
355 const Standard_Real theTolerance)
360 Handle(GEOM_Object) aWire = GetEngine()->AddObject(GetDocID(), GEOM_WIRE);
363 Handle(GEOM_Function) aFunction =
364 aWire->AddFunction(GEOMImpl_ShapeDriver::GetID(), WIRE_EDGES);
365 if (aFunction.IsNull()) return NULL;
367 //Check if the function is set correctly
368 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
370 GEOMImpl_IShapes aCI (aFunction);
371 aCI.SetTolerance(theTolerance);
373 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
376 std::list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
377 for (; it != theShapes.end(); it++) {
378 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
379 if (aRefSh.IsNull()) {
380 SetErrorCode("NULL argument shape for the shape construction");
383 aShapesSeq->Append(aRefSh);
385 aCI.SetShapes(aShapesSeq);
390 if (!GetSolver()->ComputeFunction(aFunction)) {
391 SetErrorCode("Shape driver failed");
395 catch (Standard_Failure) {
396 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
397 SetErrorCode(aFail->GetMessageString());
401 //Make a Python command
402 GEOM::TPythonDump pd (aFunction);
403 pd << aWire << " = geompy.MakeWire([";
406 it = theShapes.begin();
407 if (it != theShapes.end()) {
409 while (it != theShapes.end()) {
410 pd << ", " << (*it++);
413 pd << "], " << theTolerance << ")";
419 //=============================================================================
423 //=============================================================================
424 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFace (Handle(GEOM_Object) theWire,
425 const bool isPlanarWanted)
429 if (theWire.IsNull()) return NULL;
431 //Add a new Face object
432 Handle(GEOM_Object) aFace = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
434 //Add a new Shape function for creation of a face from a wire
435 Handle(GEOM_Function) aFunction =
436 aFace->AddFunction(GEOMImpl_ShapeDriver::GetID(), FACE_WIRE);
437 if (aFunction.IsNull()) return NULL;
439 //Check if the function is set correctly
440 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
442 GEOMImpl_IShapes aCI (aFunction);
444 Handle(GEOM_Function) aRefWire = theWire->GetLastFunction();
446 if (aRefWire.IsNull()) return NULL;
448 aCI.SetBase(aRefWire);
449 aCI.SetIsPlanar(isPlanarWanted);
451 //Compute the Face value
452 Standard_Boolean isWarning = Standard_False;
455 if (!GetSolver()->ComputeFunction(aFunction)) {
456 SetErrorCode("Shape driver failed to compute a face");
460 catch (Standard_Failure) {
461 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
462 SetErrorCode(aFail->GetMessageString());
463 // to provide warning
464 if (!aFunction->GetValue().IsNull()) {
465 isWarning = Standard_True;
471 //Make a Python command
472 GEOM::TPythonDump(aFunction) << aFace << " = geompy.MakeFace("
473 << theWire << ", " << (int)isPlanarWanted << ")";
475 // to provide warning
476 if (!isWarning) SetErrorCode(OK);
480 //=============================================================================
484 //=============================================================================
485 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFaceWires
486 (std::list<Handle(GEOM_Object)> theShapes,
487 const bool isPlanarWanted)
492 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
495 Handle(GEOM_Function) aFunction =
496 aShape->AddFunction(GEOMImpl_ShapeDriver::GetID(), FACE_WIRES);
497 if (aFunction.IsNull()) return NULL;
499 //Check if the function is set correctly
500 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
502 GEOMImpl_IShapes aCI (aFunction);
504 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
507 std::list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
508 for (; it != theShapes.end(); it++) {
509 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
510 if (aRefSh.IsNull()) {
511 SetErrorCode("NULL argument shape for the face construction");
514 aShapesSeq->Append(aRefSh);
516 aCI.SetShapes(aShapesSeq);
518 aCI.SetIsPlanar(isPlanarWanted);
521 Standard_Boolean isWarning = Standard_False;
524 if (!GetSolver()->ComputeFunction(aFunction)) {
525 SetErrorCode("Shape driver failed");
529 catch (Standard_Failure) {
530 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
531 SetErrorCode(aFail->GetMessageString());
532 // to provide warning
533 if (!aFunction->GetValue().IsNull()) {
534 isWarning = Standard_True;
540 //Make a Python command
541 GEOM::TPythonDump pd (aFunction);
542 pd << aShape << " = geompy.MakeFaceWires([";
545 it = theShapes.begin();
546 if (it != theShapes.end()) {
548 while (it != theShapes.end()) {
549 pd << ", " << (*it++);
552 pd << "], " << (int)isPlanarWanted << ")";
554 // to provide warning
555 if (!isWarning) SetErrorCode(OK);
559 //=============================================================================
563 //=============================================================================
564 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeShell
565 (std::list<Handle(GEOM_Object)> theShapes)
567 return MakeShape(theShapes, GEOM_SHELL, SHELL_FACES, "MakeShell");
570 //=============================================================================
574 //=============================================================================
575 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeSolidShells
576 (std::list<Handle(GEOM_Object)> theShapes)
578 return MakeShape(theShapes, GEOM_SOLID, SOLID_SHELLS, "MakeSolid");
581 //=============================================================================
585 //=============================================================================
586 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeCompound
587 (std::list<Handle(GEOM_Object)> theShapes)
589 return MakeShape(theShapes, GEOM_COMPOUND, COMPOUND_SHAPES, "MakeCompound");
592 //=============================================================================
596 //=============================================================================
597 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeShape
598 (std::list<Handle(GEOM_Object)> theShapes,
599 const Standard_Integer theObjectType,
600 const Standard_Integer theFunctionType,
601 const TCollection_AsciiString& theMethodName)
606 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), theObjectType);
609 Handle(GEOM_Function) aFunction =
610 aShape->AddFunction(GEOMImpl_ShapeDriver::GetID(), theFunctionType);
611 if (aFunction.IsNull()) return NULL;
613 //Check if the function is set correctly
614 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
616 GEOMImpl_IShapes aCI (aFunction);
618 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
621 std::list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
622 for (; it != theShapes.end(); it++) {
623 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
624 if (aRefSh.IsNull()) {
625 SetErrorCode("NULL argument shape for the shape construction");
628 aShapesSeq->Append(aRefSh);
630 aCI.SetShapes(aShapesSeq);
635 if (!GetSolver()->ComputeFunction(aFunction)) {
636 SetErrorCode("Shape driver failed");
640 catch (Standard_Failure) {
641 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
642 SetErrorCode(aFail->GetMessageString());
646 //Make a Python command
647 GEOM::TPythonDump pd (aFunction);
648 pd << aShape << " = geompy." << theMethodName.ToCString() << "([";
651 it = theShapes.begin();
652 if (it != theShapes.end()) {
654 while (it != theShapes.end()) {
655 pd << ", " << (*it++);
664 //=============================================================================
668 //=============================================================================
669 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeGlueFaces
670 (Handle(GEOM_Object) theShape,
671 const Standard_Real theTolerance,
672 const Standard_Boolean doKeepNonSolids)
676 if (theShape.IsNull()) return NULL;
678 //Add a new Glued object
679 Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
681 //Add a new Glue function
682 Handle(GEOM_Function) aFunction;
683 aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_FACES);
684 if (aFunction.IsNull()) return NULL;
686 //Check if the function is set correctly
687 if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
689 GEOMImpl_IGlue aCI (aFunction);
691 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
692 if (aRefShape.IsNull()) return NULL;
694 aCI.SetBase(aRefShape);
695 aCI.SetTolerance(theTolerance);
696 aCI.SetKeepNonSolids(doKeepNonSolids);
698 //Compute the sub-shape value
699 Standard_Boolean isWarning = Standard_False;
702 if (!GetSolver()->ComputeFunction(aFunction)) {
703 SetErrorCode("Shape driver failed to glue faces");
707 catch (Standard_Failure) {
708 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
709 SetErrorCode(aFail->GetMessageString());
710 // to provide warning
711 if (!aFunction->GetValue().IsNull()) {
712 isWarning = Standard_True;
718 //Make a Python command
719 GEOM::TPythonDump(aFunction) << aGlued << " = geompy.MakeGlueFaces("
720 << theShape << ", " << theTolerance << ")";
722 // to provide warning
723 if (!isWarning) SetErrorCode(OK);
727 //=============================================================================
731 //=============================================================================
733 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetGlueFaces
734 (Handle(GEOM_Object) theShape,
735 const Standard_Real theTolerance)
739 if (theShape.IsNull()) return NULL;
740 TopoDS_Shape aShape = theShape->GetValue();
741 if (aShape.IsNull()) return NULL;
743 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
745 Standard_Integer iErr;
747 GEOMAlgo_Gluer1 aGluer;
748 GEOMAlgo_ListIteratorOfListOfCoupleOfShapes aItCS;
749 GEOMAlgo_CoupleOfShapes aCS;
750 GEOMAlgo_ListOfCoupleOfShapes aLCS;
752 //aGluer = new GEOMAlgo_Gluer1;
753 aGluer.SetShape(aShape);
754 aGluer.SetTolerance(theTolerance);
756 iErr = aGluer.ErrorStatus();
757 if (iErr) return NULL;
759 TopTools_ListOfShape listShape;
760 const GEOMAlgo_ListOfCoupleOfShapes& aLCSG = aGluer.GluedFaces();
762 aItCS.Initialize(aLCSG);
763 for (; aItCS.More(); aItCS.Next()) {
764 const GEOMAlgo_CoupleOfShapes& aCSG = aItCS.Value();
765 listShape.Append(aCSG.Shape1());
768 TopTools_ListIteratorOfListOfShape itSub (listShape);
769 TCollection_AsciiString anAsciiList, anEntry;
770 TopTools_IndexedMapOfShape anIndices;
771 TopExp::MapShapes(aShape, anIndices);
772 Handle(TColStd_HArray1OfInteger) anArray;
773 Handle(GEOM_Object) anObj;
774 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
775 TopoDS_Shape aValue = itSub.Value();
776 anArray = new TColStd_HArray1OfInteger(1,1);
777 anArray->SetValue(1, anIndices.FindIndex(aValue));
778 anObj = GetEngine()->AddSubShape(theShape, anArray);
779 if (!anObj.IsNull()) {
782 // for python command
783 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
784 anAsciiList += anEntry;
789 //Make a Python command
790 if( anAsciiList.Length() > 0 ) {
791 anAsciiList.Trunc(anAsciiList.Length() - 1);
792 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
793 GEOM::TPythonDump pd (aFunction, true);
794 pd << "[" << anAsciiList.ToCString();
795 pd << "] = geompy.GetGlueFaces(" << theShape << ", " << theTolerance << ")";
804 //=============================================================================
806 * MakeGlueFacesByList
808 //=============================================================================
809 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeGlueFacesByList
810 (Handle(GEOM_Object) theShape,
811 const Standard_Real theTolerance,
812 std::list<Handle(GEOM_Object)> theFaces,
813 const Standard_Boolean doKeepNonSolids,
814 const Standard_Boolean doGlueAllEdges)
818 if (theShape.IsNull()) return NULL;
820 //Add a new Glued object
821 Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
823 //Add a new Glue function
824 Handle(GEOM_Function) aFunction;
825 aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_FACES_BY_LIST);
826 if (aFunction.IsNull()) return NULL;
828 //Check if the function is set correctly
829 if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
831 GEOMImpl_IGlue aCI (aFunction);
833 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
834 if (aRefShape.IsNull()) return NULL;
836 aCI.SetBase(aRefShape);
837 aCI.SetTolerance(theTolerance);
838 aCI.SetKeepNonSolids(doKeepNonSolids);
839 aCI.SetGlueAllEdges(doGlueAllEdges);
841 Handle(TColStd_HSequenceOfTransient) aFaces = new TColStd_HSequenceOfTransient;
842 std::list<Handle(GEOM_Object)>::iterator it = theFaces.begin();
843 for (; it != theFaces.end(); it++) {
844 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
845 if (aRefSh.IsNull()) {
846 SetErrorCode("NULL argument shape for the shape construction");
849 aFaces->Append(aRefSh);
851 aCI.SetFaces(aFaces);
853 //Compute the sub-shape value
854 Standard_Boolean isWarning = Standard_False;
857 if (!GetSolver()->ComputeFunction(aFunction)) {
858 SetErrorCode("Shape driver failed to glue faces");
862 catch (Standard_Failure) {
863 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
864 SetErrorCode(aFail->GetMessageString());
865 // to provide warning
866 if (!aFunction->GetValue().IsNull()) {
867 isWarning = Standard_True;
873 //Make a Python command
875 GEOM::TPythonDump pd(aFunction);
876 pd << aGlued << " = geompy.MakeGlueFacesByList("
877 << theShape << ", " << theTolerance << ", [";
879 it = theFaces.begin();
880 if (it != theFaces.end()) {
882 while (it != theFaces.end()) {
883 pd << ", " << (*it++);
886 pd << "], " << (bool)doKeepNonSolids << ", " << (bool)doGlueAllEdges << ")";
888 // to provide warning
889 if (!isWarning) SetErrorCode(OK);
893 //=============================================================================
897 //=============================================================================
898 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeGlueEdges
899 (Handle(GEOM_Object) theShape,
900 const Standard_Real theTolerance)
904 if (theShape.IsNull()) return NULL;
906 //Add a new Glued object
907 Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
909 //Add a new Glue function
910 Handle(GEOM_Function) aFunction;
911 aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_EDGES);
912 if (aFunction.IsNull()) return NULL;
914 //Check if the function is set correctly
915 if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
917 GEOMImpl_IGlue aCI (aFunction);
919 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
920 if (aRefShape.IsNull()) return NULL;
922 aCI.SetBase(aRefShape);
923 aCI.SetTolerance(theTolerance);
924 aCI.SetKeepNonSolids(true);
926 //Compute the sub-shape value
927 Standard_Boolean isWarning = Standard_False;
930 if (!GetSolver()->ComputeFunction(aFunction)) {
931 SetErrorCode("Shape driver failed to glue edges");
935 catch (Standard_Failure) {
936 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
937 SetErrorCode(aFail->GetMessageString());
938 // to provide warning
939 if (!aFunction->GetValue().IsNull()) {
940 isWarning = Standard_True;
946 //Make a Python command
947 GEOM::TPythonDump(aFunction) << aGlued << " = geompy.MakeGlueEdges("
948 << theShape << ", " << theTolerance << ")";
950 // to provide warning
951 if (!isWarning) SetErrorCode(OK);
955 //=============================================================================
959 //=============================================================================
960 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetGlueShapes
961 (Handle(GEOM_Object) theShape,
962 const Standard_Real theTolerance,
963 const TopAbs_ShapeEnum theType)
967 if (theShape.IsNull()) return NULL;
968 TopoDS_Shape aShape = theShape->GetValue();
969 if (aShape.IsNull()) return NULL;
971 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
973 GEOMAlgo_GlueDetector aGluer;
974 aGluer.SetArgument(aShape);
975 aGluer.SetTolerance(theTolerance);
977 Standard_Integer iErr = aGluer.ErrorStatus();
978 if (iErr) return NULL;
980 TCollection_AsciiString anAsciiList, anEntry;
981 TopTools_IndexedMapOfShape anIndices;
982 TopExp::MapShapes(aShape, anIndices);
983 Handle(TColStd_HArray1OfInteger) anArray;
984 Handle(GEOM_Object) anObj;
986 TopTools_ListOfShape listOnePerSet;
988 const TopTools_DataMapOfShapeListOfShape& aImages = aGluer.Images();
989 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape aItDMSLS (aImages);
990 for (int index = 1; aItDMSLS.More(); aItDMSLS.Next(), ++index) {
992 //const TopoDS_Shape& aSkey = aItDMSLS.Key();
994 // list of shapes of the argument that can be glued
995 const TopTools_ListOfShape& aLSD = aItDMSLS.Value();
997 //listShape.Append(aLSD.First());
998 TopoDS_Shape aValue = aLSD.First();
1000 if (aValue.ShapeType() == theType) {
1001 listOnePerSet.Append(aValue);
1005 // for stable order of returned entities
1006 GEOMUtils::SortShapes(listOnePerSet, Standard_False);
1008 TopTools_ListIteratorOfListOfShape aListIt (listOnePerSet);
1009 for (; aListIt.More(); aListIt.Next()) {
1010 TopoDS_Shape aValue = aListIt.Value();
1011 anArray = new TColStd_HArray1OfInteger(1,1);
1012 anArray->SetValue(1, anIndices.FindIndex(aValue));
1013 anObj = GetEngine()->AddSubShape(theShape, anArray);
1014 if (!anObj.IsNull()) {
1015 aSeq->Append(anObj);
1017 // for python command
1018 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
1019 anAsciiList += anEntry;
1024 // Make a Python command
1025 if (anAsciiList.Length() > 0) {
1026 anAsciiList.Trunc(anAsciiList.Length() - 1);
1027 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
1028 GEOM::TPythonDump pd (aFunction, /*append=*/true);
1029 pd << "[" << anAsciiList.ToCString();
1030 if (theType == TopAbs_FACE)
1031 pd << "] = geompy.GetGlueFaces(" << theShape << ", " << theTolerance << ")";
1032 else if (theType == TopAbs_EDGE)
1033 pd << "] = geompy.GetGlueEdges(" << theShape << ", " << theTolerance << ")";
1041 //=============================================================================
1043 * MakeGlueEdgesByList
1045 //=============================================================================
1046 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeGlueEdgesByList
1047 (Handle(GEOM_Object) theShape,
1048 const Standard_Real theTolerance,
1049 std::list<Handle(GEOM_Object)> theEdges)
1053 if (theShape.IsNull()) return NULL;
1055 //Add a new Glued object
1056 Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
1058 //Add a new Glue function
1059 Handle(GEOM_Function) aFunction;
1060 aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_EDGES_BY_LIST);
1061 if (aFunction.IsNull()) return NULL;
1063 //Check if the function is set correctly
1064 if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
1066 GEOMImpl_IGlue aCI (aFunction);
1068 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
1069 if (aRefShape.IsNull()) return NULL;
1071 aCI.SetBase(aRefShape);
1072 aCI.SetTolerance(theTolerance);
1073 aCI.SetKeepNonSolids(true);
1075 Handle(TColStd_HSequenceOfTransient) anEdges = new TColStd_HSequenceOfTransient;
1076 std::list<Handle(GEOM_Object)>::iterator it = theEdges.begin();
1077 for (; it != theEdges.end(); it++) {
1078 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
1079 if (aRefSh.IsNull()) {
1080 SetErrorCode("NULL argument shape for the shape construction");
1083 anEdges->Append(aRefSh);
1085 aCI.SetFaces(anEdges);
1087 //Compute the sub-shape value
1088 Standard_Boolean isWarning = Standard_False;
1091 if (!GetSolver()->ComputeFunction(aFunction)) {
1092 SetErrorCode("Shape driver failed to glue edges");
1096 catch (Standard_Failure) {
1097 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1098 SetErrorCode(aFail->GetMessageString());
1099 // to provide warning
1100 if (!aFunction->GetValue().IsNull()) {
1101 isWarning = Standard_True;
1107 //Make a Python command
1109 GEOM::TPythonDump pd (aFunction);
1110 pd << aGlued << " = geompy.MakeGlueEdgesByList("
1111 << theShape << ", " << theTolerance << ", [";
1113 it = theEdges.begin();
1114 if (it != theEdges.end()) {
1116 while (it != theEdges.end()) {
1117 pd << ", " << (*it++);
1122 // to provide warning
1123 if (!isWarning) SetErrorCode(OK);
1127 //=============================================================================
1129 * GetExistingSubObjects
1131 //=============================================================================
1132 Handle(TColStd_HSequenceOfTransient)
1133 GEOMImpl_IShapesOperations::GetExistingSubObjects(Handle(GEOM_Object) theShape,
1134 const Standard_Boolean theGroupsOnly)
1136 // note: this method does not return fields
1138 Standard_Integer types = theGroupsOnly ? Groups : Groups|SubShapes;
1139 Handle(TColStd_HSequenceOfTransient) results = GetExistingSubObjects(theShape, types);
1141 if (results->Length() > 0) {
1142 //Make a Python command
1143 TCollection_AsciiString anAsciiList;
1144 for (int i = 1; i <= results->Length(); i++)
1146 Handle(GEOM_BaseObject) obj = Handle(GEOM_BaseObject)::DownCast( results->Value(i));
1147 obj->GetEntryString();
1148 if ( i < results->Length() )
1152 GEOM::TPythonDump pd (theShape->GetLastFunction(), /*append=*/true);
1153 pd << "[" << anAsciiList.ToCString();
1154 pd << "] = geompy.GetExistingSubObjects(";
1155 pd << theShape << ", " << (bool)theGroupsOnly << ")";
1161 Handle(TColStd_HSequenceOfTransient)
1162 GEOMImpl_IShapesOperations::GetExistingSubObjects(Handle(GEOM_Object) theShape,
1163 const Standard_Integer theTypes)
1167 if (theShape.IsNull()) return NULL;
1169 Handle(GEOM_Function) aMainShape = theShape->GetLastFunction();
1170 if (aMainShape.IsNull()) return NULL;
1172 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1173 SetErrorCode(NOT_FOUND_ANY);
1175 if (!aMainShape->HasSubShapeReferences()) return aSeq;
1176 const TDataStd_ListOfExtendedString& aListEntries = aMainShape->GetSubShapeReferences();
1177 if (aListEntries.IsEmpty()) return aSeq;
1181 TDataStd_ListIteratorOfListOfExtendedString anIt (aListEntries);
1182 for (; anIt.More(); anIt.Next()) {
1183 TCollection_ExtendedString anEntry = anIt.Value();
1184 Standard_Integer aStrLen = anEntry.LengthOfCString();
1185 char* anEntryStr = new char[aStrLen+1];
1186 anEntry.ToUTF8CString(anEntryStr);
1187 Handle(GEOM_BaseObject) anObj = GetEngine()->GetObject(GetDocID(), anEntryStr, false);
1188 if (!anObj.IsNull() ) {
1189 bool isGroup = anObj->IsKind(STANDARD_TYPE(GEOM_Object)) && anObj->GetType() == GEOM_GROUP;
1190 bool isSubShape = anObj->IsKind(STANDARD_TYPE(GEOM_Object)) && anObj->GetType() != GEOM_GROUP;
1191 bool isField = anObj->IsKind(STANDARD_TYPE(GEOM_Field));
1192 if (theTypes & Groups && isGroup ||
1193 theTypes & SubShapes && isSubShape ||
1194 theTypes & Fields && isField) {
1195 aSeq->Append(anObj);
1198 delete [] anEntryStr;
1201 if (aSeq->Length() == 0) {
1202 SetErrorCode(NOT_FOUND_ANY);
1211 //=============================================================================
1215 //=============================================================================
1216 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::MakeExplode
1217 (Handle(GEOM_Object) theShape,
1218 const Standard_Integer theShapeType,
1219 const Standard_Boolean isSorted,
1220 const ExplodeType theExplodeType)
1224 if (theShape.IsNull()) return NULL;
1225 TopoDS_Shape aShape = theShape->GetValue();
1226 if (aShape.IsNull()) return NULL;
1228 Handle(GEOM_Function) aMainShape = theShape->GetLastFunction();
1230 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1231 Handle(GEOM_Object) anObj;
1232 TopTools_MapOfShape mapShape;
1233 TopTools_ListOfShape listShape;
1235 if (aShape.ShapeType() == TopAbs_COMPOUND &&
1236 (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
1237 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPSOLID ||
1238 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPOUND))
1240 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
1241 for (; It.More(); It.Next()) {
1242 if (mapShape.Add(It.Value())) {
1243 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
1244 TopAbs_ShapeEnum(theShapeType) == It.Value().ShapeType()) {
1245 listShape.Append(It.Value());
1250 else if (theExplodeType != EXPLODE_NEW_EXCLUDE_MAIN || aShape.ShapeType() != theShapeType) // issue 0021079
1252 TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
1253 for (; exp.More(); exp.Next())
1254 if (mapShape.Add(exp.Current()))
1255 listShape.Append(exp.Current());
1258 if (listShape.IsEmpty()) {
1259 //SetErrorCode("The given shape has no sub-shapes of the requested type");
1260 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
1265 bool isOldSorting = false;
1266 if (theExplodeType == EXPLODE_OLD_INCLUDE_MAIN)
1267 isOldSorting = true;
1268 GEOMUtils::SortShapes(listShape, isOldSorting);
1271 TopTools_IndexedMapOfShape anIndices;
1272 TopExp::MapShapes(aShape, anIndices);
1273 Handle(TColStd_HArray1OfInteger) anArray;
1275 TopTools_ListIteratorOfListOfShape itSub (listShape);
1276 TCollection_AsciiString anAsciiList, anEntry;
1277 for (int index = 1; itSub.More(); itSub.Next(), ++index)
1279 TopoDS_Shape aValue = itSub.Value();
1280 anArray = new TColStd_HArray1OfInteger(1,1);
1281 anArray->SetValue(1, anIndices.FindIndex(aValue));
1283 //anObj = GetEngine()->AddSubShape(theShape, anArray);
1285 anObj = GetEngine()->AddObject(GetDocID(), GEOM_SUBSHAPE);
1286 Handle(GEOM_Function) aFunction = anObj->AddFunction(GEOM_Object::GetSubShapeID(), 1);
1287 if (aFunction.IsNull()) return aSeq;
1289 GEOM_ISubShape aSSI (aFunction);
1290 aSSI.SetMainShape(aMainShape);
1291 aSSI.SetIndices(anArray);
1293 // Set function value directly, as we know it.
1294 // Usage of Solver here would lead to significant loss of time,
1295 // because GEOM_SubShapeDriver will build TopTools_IndexedMapOfShape
1296 // on the main shape for each being calculated sub-shape separately.
1297 aFunction->SetValue(aValue);
1299 // Put this subshape in the list of sub-shapes of theMainShape
1300 aMainShape->AddSubShapeReference(aFunction);
1303 if (!anObj.IsNull()) {
1304 aSeq->Append(anObj);
1306 // for python command
1307 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
1308 anAsciiList += anEntry;
1313 //Make a Python command
1314 anAsciiList.Trunc(anAsciiList.Length() - 1);
1316 GEOM::TPythonDump pd (aMainShape, /*append=*/true);
1317 pd << "[" << anAsciiList.ToCString() << "] = geompy.";
1318 switch (theExplodeType) {
1319 case EXPLODE_NEW_EXCLUDE_MAIN:
1320 pd << "ExtractShapes(" << theShape << ", "
1321 << TopAbs_ShapeEnum(theShapeType) << ", " << (isSorted ? "True" : "False") << ")";
1323 case EXPLODE_NEW_INCLUDE_MAIN:
1324 pd << "SubShapeAll" << (isSorted ? "SortedCentres(" : "(")
1325 << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
1327 case EXPLODE_OLD_INCLUDE_MAIN:
1328 pd << "SubShapeAll" << (isSorted ? "Sorted(" : "(")
1329 << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
1338 //=============================================================================
1342 //=============================================================================
1343 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::SubShapeAllIDs
1344 (Handle(GEOM_Object) theShape,
1345 const Standard_Integer theShapeType,
1346 const Standard_Boolean isSorted,
1347 const ExplodeType theExplodeType)
1351 if (theShape.IsNull()) return NULL;
1352 TopoDS_Shape aShape = theShape->GetValue();
1353 if (aShape.IsNull()) return NULL;
1355 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
1356 TopTools_MapOfShape mapShape;
1357 TopTools_ListOfShape listShape;
1359 if (aShape.ShapeType() == TopAbs_COMPOUND &&
1360 (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
1361 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPSOLID ||
1362 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPOUND))
1364 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
1365 for (; It.More(); It.Next()) {
1366 if (mapShape.Add(It.Value())) {
1367 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
1368 TopAbs_ShapeEnum(theShapeType) == It.Value().ShapeType()) {
1369 listShape.Append(It.Value());
1374 else if (theExplodeType != EXPLODE_NEW_EXCLUDE_MAIN || aShape.ShapeType() != theShapeType) // issue 0021079
1376 TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
1377 for (; exp.More(); exp.Next())
1378 if (mapShape.Add(exp.Current()))
1379 listShape.Append(exp.Current());
1382 if (listShape.IsEmpty()) {
1383 //SetErrorCode("The given shape has no sub-shapes of the requested type");
1384 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
1389 bool isOldSorting = false;
1390 if (theExplodeType == EXPLODE_OLD_INCLUDE_MAIN)
1391 isOldSorting = true;
1392 GEOMUtils::SortShapes(listShape, isOldSorting);
1395 TopTools_IndexedMapOfShape anIndices;
1396 TopExp::MapShapes(aShape, anIndices);
1397 Handle(TColStd_HArray1OfInteger) anArray;
1399 TopTools_ListIteratorOfListOfShape itSub (listShape);
1400 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
1401 TopoDS_Shape aValue = itSub.Value();
1402 aSeq->Append(anIndices.FindIndex(aValue));
1405 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
1407 //Make a Python command
1408 GEOM::TPythonDump pd (aFunction, /*append=*/true);
1409 pd << "listSubShapeIDs = geompy.SubShapeAll";
1410 switch (theExplodeType) {
1411 case EXPLODE_NEW_EXCLUDE_MAIN:
1413 case EXPLODE_NEW_INCLUDE_MAIN:
1414 pd << (isSorted ? "SortedCentresIDs(" : "IDs(")
1415 << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
1417 case EXPLODE_OLD_INCLUDE_MAIN:
1418 pd << (isSorted ? "SortedIDs(" : "IDs(")
1419 << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
1428 //=============================================================================
1432 //=============================================================================
1433 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetSubShape
1434 (Handle(GEOM_Object) theMainShape,
1435 const Standard_Integer theID)
1439 if (theMainShape.IsNull()) return NULL;
1441 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
1442 anArray->SetValue(1, theID);
1443 Handle(GEOM_Object) anObj = GetEngine()->AddSubShape(theMainShape, anArray,true);
1444 if (anObj.IsNull()) {
1445 SetErrorCode("Can not get a sub-shape with the given ID");
1449 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1451 //Make a Python command
1452 GEOM::TPythonDump(aFunction) << anObj << " = geompy.GetSubShape("
1453 << theMainShape << ", [" << theID << "])";
1459 //=============================================================================
1463 //=============================================================================
1464 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::MakeSubShapes
1465 (Handle(GEOM_Object) theMainShape,
1466 Handle(TColStd_HArray1OfInteger) theIndices)
1470 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1472 if (!theIndices->Length()) {
1473 SetErrorCode(NOT_FOUND_ANY);
1477 if (theMainShape.IsNull()) return NULL;
1478 TopoDS_Shape aShape = theMainShape->GetValue();
1479 if (aShape.IsNull()) return NULL;
1481 Handle(GEOM_Function) aMainShape = theMainShape->GetLastFunction();
1483 TopTools_IndexedMapOfShape anIndices;
1484 TopExp::MapShapes(aShape, anIndices);
1486 Handle(TColStd_HArray1OfInteger) anArray;
1487 Handle(GEOM_Object) anObj;
1489 TCollection_AsciiString anAsciiList, anEntry;
1490 Standard_Integer i, low = theIndices->Lower(), up = theIndices->Upper();
1491 for (i = low; i <= up; i++) {
1492 int id = theIndices->Value(i);
1493 if (1 <= id && id <= anIndices.Extent()) {
1494 TopoDS_Shape aValue = anIndices.FindKey(id);
1495 anArray = new TColStd_HArray1OfInteger(1,1);
1496 anArray->SetValue(1, id);
1498 anObj = GetEngine()->AddObject(GetDocID(), GEOM_SUBSHAPE);
1499 if (!anObj.IsNull()) {
1500 Handle(GEOM_Function) aFunction = anObj->AddFunction(GEOM_Object::GetSubShapeID(), 1);
1501 if (aFunction.IsNull()) return aSeq;
1503 GEOM_ISubShape aSSI (aFunction);
1504 aSSI.SetMainShape(aMainShape);
1505 aSSI.SetIndices(anArray);
1507 // Set function value directly, as we know it.
1508 // Usage of Solver here would lead to significant loss of time,
1509 // because GEOM_SubShapeDriver will build TopTools_IndexedMapOfShape
1510 // on the main shape for each being calculated sub-shape separately.
1511 aFunction->SetValue(aValue);
1513 // Put this sub-shape in the list of sub-shapes of theMainShape
1514 aMainShape->AddSubShapeReference(aFunction);
1516 aSeq->Append(anObj);
1518 // for python command
1519 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
1520 anAsciiList += anEntry;
1526 //Make a Python command
1527 anAsciiList.Trunc(anAsciiList.Length() - 1);
1529 GEOM::TPythonDump pd (aMainShape, /*append=*/true);
1530 pd << "[" << anAsciiList.ToCString() << "] = geompy.SubShapes("
1531 << theMainShape << ", [" ;
1532 for (i = low; i <= up - 1; i++) {
1533 pd << theIndices->Value(i) << ", ";
1535 pd << theIndices->Value(up) << "])";
1542 //=============================================================================
1546 //=============================================================================
1547 Standard_Integer GEOMImpl_IShapesOperations::GetSubShapeIndex (Handle(GEOM_Object) theMainShape,
1548 Handle(GEOM_Object) theSubShape)
1552 TopoDS_Shape aMainShape = theMainShape->GetValue();
1553 TopoDS_Shape aSubShape = theSubShape->GetValue();
1555 if (aMainShape.IsNull() || aSubShape.IsNull()) return -1;
1557 TopTools_IndexedMapOfShape anIndices;
1558 TopExp::MapShapes(aMainShape, anIndices);
1559 // if (anIndices.Contains(aSubShape)) {
1560 // SetErrorCode(OK);
1561 // return anIndices.FindIndex(aSubShape);
1563 int id = anIndices.FindIndex(aSubShape);
1574 //=============================================================================
1576 * GetSubShapeIndices
1578 //=============================================================================
1579 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetSubShapesIndices (Handle(GEOM_Object) theMainShape,
1580 std::list<Handle(GEOM_Object)> theSubShapes)
1582 MESSAGE("GEOMImpl_IShapesOperations::GetSubShapesIndices")
1585 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
1587 TopoDS_Shape aMainShape = theMainShape->GetValue();
1588 if (aMainShape.IsNull())
1590 MESSAGE("NULL main shape")
1594 TopTools_IndexedMapOfShape anIndices;
1595 TopExp::MapShapes(aMainShape, anIndices);
1597 std::list<Handle(GEOM_Object)>::iterator it;
1598 for (it=theSubShapes.begin(); it != theSubShapes.end(); ++it)
1600 TopoDS_Shape aSubShape = (*it)->GetValue();
1601 if (aSubShape.IsNull())
1603 MESSAGE("NULL subshape")
1606 int id = anIndices.FindIndex(aSubShape);
1615 //=============================================================================
1619 //=============================================================================
1620 Standard_Integer GEOMImpl_IShapesOperations::GetTopologyIndex (Handle(GEOM_Object) theMainShape,
1621 Handle(GEOM_Object) theSubShape)
1625 TopoDS_Shape aMainShape = theMainShape->GetValue();
1626 TopoDS_Shape aSubShape = theSubShape->GetValue();
1628 if (aMainShape.IsNull() || aSubShape.IsNull()) {
1629 SetErrorCode("Null argument shape given");
1634 if (aSubShape.ShapeType() == TopAbs_COMPOUND) {
1636 TopTools_ListOfShape CL;
1637 CL.Append(aMainShape);
1638 TopTools_ListIteratorOfListOfShape itC;
1639 for (itC.Initialize(CL); itC.More(); itC.Next()) {
1640 for (it.Initialize(itC.Value()); it.More(); it.Next()) {
1641 if (it.Value().ShapeType() == TopAbs_COMPOUND) {
1642 if (it.Value().IsSame(aSubShape))
1646 CL.Append(it.Value());
1651 TopExp_Explorer anExp (aMainShape, aSubShape.ShapeType());
1652 TopTools_MapOfShape M;
1653 for (; anExp.More(); anExp.Next()) {
1654 if (M.Add(anExp.Current())) {
1655 if (anExp.Current().IsSame(aSubShape))
1662 SetErrorCode("The sub-shape does not belong to the main shape");
1666 //=============================================================================
1668 * GetShapeTypeString
1670 //=============================================================================
1671 TCollection_AsciiString GEOMImpl_IShapesOperations::GetShapeTypeString (Handle(GEOM_Object) theShape)
1675 TCollection_AsciiString aTypeName ("Null Shape");
1677 TopoDS_Shape aShape = theShape->GetValue();
1678 if (aShape.IsNull())
1681 switch (aShape.ShapeType() )
1683 case TopAbs_COMPOUND:
1684 aTypeName = "Compound";
1686 case TopAbs_COMPSOLID:
1687 aTypeName = "Compound Solid";
1690 aTypeName = "Solid";
1693 aTypeName = "Shell";
1697 BRepAdaptor_Surface surf (TopoDS::Face(aShape));
1698 if (surf.GetType() == GeomAbs_Plane)
1699 aTypeName = "Plane";
1700 else if (surf.GetType() == GeomAbs_Cylinder)
1701 aTypeName = "Cylindrical Face";
1702 else if (surf.GetType() == GeomAbs_Sphere)
1703 aTypeName = "Spherical Face";
1704 else if (surf.GetType() == GeomAbs_Torus)
1705 aTypeName = "Toroidal Face";
1706 else if (surf.GetType() == GeomAbs_Cone)
1707 aTypeName = "Conical Face";
1709 aTypeName = "GEOM::FACE";
1717 BRepAdaptor_Curve curv (TopoDS::Edge(aShape));
1718 if (curv.GetType() == GeomAbs_Line) {
1719 if ((Abs(curv.FirstParameter()) >= 1E6) ||
1720 (Abs(curv.LastParameter()) >= 1E6))
1724 } else if (curv.GetType() == GeomAbs_Circle) {
1725 if (curv.IsClosed())
1726 aTypeName = "Circle";
1735 aTypeName = "Vertex";
1738 aTypeName = "Shape";
1741 aTypeName = "Shape of unknown type";
1747 //=============================================================================
1751 //=============================================================================
1752 Standard_Integer GEOMImpl_IShapesOperations::NumberOfSubShapes
1753 (Handle(GEOM_Object) theShape,
1754 const Standard_Integer theShapeType)
1757 Standard_Integer nbShapes = 0;
1759 if (theShape.IsNull()) return -1;
1760 TopoDS_Shape aShape = theShape->GetValue();
1761 if (aShape.IsNull()) return -1;
1764 TopTools_MapOfShape mapShape;
1766 if (aShape.ShapeType() == TopAbs_COMPOUND &&
1767 (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
1768 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPSOLID ||
1769 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPOUND)) {
1770 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
1771 for (; It.More(); It.Next()) {
1772 if (mapShape.Add(It.Value())) {
1773 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
1774 TopAbs_ShapeEnum(theShapeType) == It.Value().ShapeType()) {
1780 TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
1781 for (; exp.More(); exp.Next())
1782 if (mapShape.Add(exp.Current()))
1789 int iType, nbTypes [TopAbs_SHAPE];
1790 for (iType = 0; iType < TopAbs_SHAPE; ++iType)
1792 nbTypes[aShape.ShapeType()]++;
1794 TopTools_MapOfShape aMapOfShape;
1795 aMapOfShape.Add(aShape);
1796 TopTools_ListOfShape aListOfShape;
1797 aListOfShape.Append(aShape);
1799 TopTools_ListIteratorOfListOfShape itL (aListOfShape);
1800 for (; itL.More(); itL.Next()) {
1801 TopoDS_Iterator it (itL.Value());
1802 for (; it.More(); it.Next()) {
1803 TopoDS_Shape s = it.Value();
1804 if (aMapOfShape.Add(s)) {
1805 aListOfShape.Append(s);
1806 nbTypes[s.ShapeType()]++;
1811 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE)
1812 nbShapes = aMapOfShape.Extent();
1814 nbShapes = nbTypes[theShapeType];
1816 catch (Standard_Failure) {
1817 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1818 SetErrorCode(aFail->GetMessageString());
1826 //=============================================================================
1830 //=============================================================================
1831 Handle(GEOM_Object) GEOMImpl_IShapesOperations::ReverseShape(Handle(GEOM_Object) theShape)
1835 if (theShape.IsNull()) return NULL;
1838 //Add a new reversed object
1839 Handle(GEOM_Object) aReversed = GetEngine()->AddObject(GetDocID(), theShape->GetType());
1841 //Add a new Revese function
1842 Handle(GEOM_Function) aFunction;
1843 aFunction = aReversed->AddFunction(GEOMImpl_ShapeDriver::GetID(), REVERSE_ORIENTATION);
1844 if (aFunction.IsNull()) return NULL;
1846 //Check if the function is set correctly
1847 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
1849 GEOMImpl_IShapes aSI (aFunction);
1851 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
1852 if (aRefShape.IsNull()) return NULL;
1854 aSI.SetBase(aRefShape);
1856 //Compute the sub-shape value
1859 if (!GetSolver()->ComputeFunction(aFunction)) {
1860 SetErrorCode("Shape driver failed to reverse shape");
1864 catch (Standard_Failure) {
1865 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1866 SetErrorCode(aFail->GetMessageString());
1870 //Make a Python command
1871 GEOM::TPythonDump(aFunction) << aReversed
1872 << " = geompy.ChangeOrientation(" << theShape << ")";
1877 Handle(GEOM_Object) aReversed;
1879 GEOM_Engine* anEngine = GetEngine();
1880 //GEOMImpl_Gen* aGen = dynamic_cast<GEOMImpl_Gen*>(anEngine);
1881 GEOMImpl_Gen* aGen = (GEOMImpl_Gen*)anEngine;
1884 GEOMImpl_IHealingOperations* anIHealingOperations =
1885 aGen->GetIHealingOperations(GetDocID());
1886 aReversed = anIHealingOperations->ChangeOrientationCopy(theShape);
1887 SetErrorCode(anIHealingOperations->GetErrorCode());
1893 //=============================================================================
1897 //=============================================================================
1898 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetFreeFacesIDs
1899 (Handle(GEOM_Object) theShape)
1903 if (theShape.IsNull()) return NULL;
1904 TopoDS_Shape aShape = theShape->GetValue();
1905 if (aShape.IsNull()) return NULL;
1907 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
1909 TopTools_IndexedDataMapOfShapeListOfShape mapFaceBlocks;
1910 GEOMImpl_Block6Explorer::MapShapesAndAncestors
1911 (aShape, TopAbs_FACE, TopAbs_SOLID, mapFaceBlocks);
1913 Standard_Integer ind = 1, nbFaces = mapFaceBlocks.Extent();
1916 SetErrorCode("The given shape has no faces");
1920 TopTools_IndexedMapOfShape anIndices;
1921 TopExp::MapShapes(aShape, anIndices);
1923 Standard_Integer id;
1924 for (; ind <= nbFaces; ind++) {
1925 if (mapFaceBlocks.FindFromIndex(ind).Extent() != 2) {
1926 id = anIndices.FindIndex(mapFaceBlocks.FindKey(ind));
1931 //The explode doesn't change object so no new function is required.
1932 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
1934 //Make a Python command
1935 GEOM::TPythonDump(aFunction, /*append=*/true)
1936 << "listFreeFacesIDs = geompy.GetFreeFacesIDs(" << theShape << ")";
1942 //=======================================================================
1943 //function : GetSharedShapes
1945 //=======================================================================
1946 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetSharedShapes
1947 (Handle(GEOM_Object) theShape1,
1948 Handle(GEOM_Object) theShape2,
1949 const Standard_Integer theShapeType)
1953 if (theShape1.IsNull() || theShape2.IsNull()) return NULL;
1955 TopoDS_Shape aShape1 = theShape1->GetValue();
1956 TopoDS_Shape aShape2 = theShape2->GetValue();
1958 if (aShape1.IsNull() || aShape2.IsNull()) return NULL;
1960 TopTools_IndexedMapOfShape anIndices;
1961 TopExp::MapShapes(aShape1, anIndices);
1962 Handle(TColStd_HArray1OfInteger) anArray;
1964 TopTools_IndexedMapOfShape mapShape1;
1965 TopExp::MapShapes(aShape1, TopAbs_ShapeEnum(theShapeType), mapShape1);
1967 Handle(GEOM_Object) anObj;
1968 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1969 TCollection_AsciiString anAsciiList, anEntry;
1971 TopTools_MapOfShape mapShape2;
1972 TopExp_Explorer exp (aShape2, TopAbs_ShapeEnum(theShapeType));
1973 for (; exp.More(); exp.Next()) {
1974 TopoDS_Shape aSS = exp.Current();
1975 if (mapShape2.Add(aSS) && mapShape1.Contains(aSS)) {
1976 anArray = new TColStd_HArray1OfInteger(1,1);
1977 anArray->SetValue(1, anIndices.FindIndex(aSS));
1978 anObj = GetEngine()->AddSubShape(theShape1, anArray);
1979 aSeq->Append(anObj);
1981 // for python command
1982 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
1983 anAsciiList += anEntry;
1988 if (aSeq->IsEmpty()) {
1989 SetErrorCode("The given shapes have no shared sub-shapes of the requested type");
1993 //Make a Python command
1994 anAsciiList.Trunc(anAsciiList.Length() - 1);
1996 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1998 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
1999 << "] = geompy.GetSharedShapes(" << theShape1 << ", "
2000 << theShape2 << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
2006 //=======================================================================
2007 //function : GetSharedShapes
2009 //=======================================================================
2010 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetSharedShapes
2011 (std::list<Handle(GEOM_Object)> theShapes,
2012 const Standard_Integer theShapeType)
2016 int aLen = theShapes.size();
2017 if (aLen < 1) return NULL;
2020 std::list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
2022 Handle(GEOM_Object) aMainObj = (*it++);
2023 Handle(GEOM_Function) aMainShape = aMainObj->GetLastFunction();
2024 if (aMainShape.IsNull()) {
2025 SetErrorCode("NULL shape for GetSharedShapes");
2029 TopoDS_Shape aShape1 = aMainShape->GetValue();
2030 if (aShape1.IsNull()) return NULL;
2032 TopTools_IndexedMapOfShape anIndices;
2033 TopExp::MapShapes(aShape1, anIndices);
2035 TopTools_IndexedMapOfShape mapSelected;
2036 TopExp::MapShapes(aShape1, TopAbs_ShapeEnum(theShapeType), mapSelected);
2038 // Find shared shapes
2040 TopoDS_Compound aCurrSelection;
2042 for (; it != theShapes.end(); it++, ind++) {
2043 Handle(GEOM_Function) aRefShape = (*it)->GetLastFunction();
2044 if (aRefShape.IsNull()) {
2045 SetErrorCode("NULL shape for GetSharedShapes");
2049 TopoDS_Compound aCompound;
2050 B.MakeCompound(aCompound);
2052 TopoDS_Shape aShape2 = aRefShape->GetValue();
2053 if (aShape2.IsNull()) return NULL;
2055 TopTools_MapOfShape mapShape2;
2056 TopExp_Explorer exp (aShape2, TopAbs_ShapeEnum(theShapeType));
2057 for (; exp.More(); exp.Next()) {
2058 TopoDS_Shape aSS = exp.Current();
2059 if (mapShape2.Add(aSS) && mapSelected.Contains(aSS)) {
2060 B.Add(aCompound, aSS);
2064 mapSelected.Clear();
2065 TopExp::MapShapes(aCompound, TopAbs_ShapeEnum(theShapeType), mapSelected);
2066 aCurrSelection = aCompound;
2069 // Create GEOM_Object for each found shared shape (collected in aCurrSelection)
2070 Handle(GEOM_Object) anObj;
2071 Handle(TColStd_HArray1OfInteger) anArray;
2072 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
2073 TCollection_AsciiString anAsciiList, anEntry;
2075 TopoDS_Iterator itSel (aCurrSelection, Standard_True, Standard_True);
2076 for (; itSel.More(); itSel.Next()) {
2077 anArray = new TColStd_HArray1OfInteger(1,1);
2078 anArray->SetValue(1, anIndices.FindIndex(itSel.Value()));
2079 anObj = GetEngine()->AddSubShape(aMainObj, anArray);
2080 aSeq->Append(anObj);
2082 // for python command
2083 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
2084 anAsciiList += anEntry;
2088 if (aSeq->IsEmpty()) {
2089 SetErrorCode("The given shapes have no shared sub-shapes of the requested type");
2093 // Make a Python command
2094 anAsciiList.Trunc(anAsciiList.Length() - 1);
2096 // IPAL22904: TC6.5.0: order of python commands is wrong after dump study
2097 Handle(TColStd_HSequenceOfTransient) anObjects = new TColStd_HSequenceOfTransient;
2098 for( it = theShapes.begin(); it != theShapes.end(); it++ )
2100 Handle(GEOM_Object) anObj = *it;
2101 if( !anObj.IsNull() )
2102 anObjects->Append( anObj );
2105 // Get the function of the latest published object
2106 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast( anObjects )->GetLastFunction();
2107 if( aFunction.IsNull() ) // just in case
2108 aFunction = aMainShape;
2110 GEOM::TPythonDump pd (aFunction, /*append=*/true);
2111 pd << "[" << anAsciiList.ToCString()
2112 << "] = geompy.GetSharedShapesMulti([";
2114 it = theShapes.begin();
2116 while (it != theShapes.end()) {
2117 pd << ", " << (*it++);
2120 pd << "], " << TopAbs_ShapeEnum(theShapeType) << ")";
2126 //=============================================================================
2130 //=============================================================================
2131 static GEOM::TPythonDump& operator<< (GEOM::TPythonDump& theDump,
2132 const GEOMAlgo_State theState)
2135 case GEOMAlgo_ST_IN:
2136 theDump << "GEOM.ST_IN";
2138 case GEOMAlgo_ST_OUT:
2139 theDump << "GEOM.ST_OUT";
2141 case GEOMAlgo_ST_ON:
2142 theDump << "GEOM.ST_ON";
2144 case GEOMAlgo_ST_ONIN:
2145 theDump << "GEOM.ST_ONIN";
2147 case GEOMAlgo_ST_ONOUT:
2148 theDump << "GEOM.ST_ONOUT";
2151 theDump << "GEOM.ST_UNKNOWN";
2157 //=======================================================================
2158 //function : checkTypeShapesOn
2160 * \brief Checks if theShapeType parameter of GetShapesOnXXX() is OK
2161 * \param theShapeType - the shape type to check
2162 * \retval bool - result of the check
2164 //=======================================================================
2165 bool GEOMImpl_IShapesOperations::checkTypeShapesOn(const Standard_Integer theShapeType)
2167 if (theShapeType != TopAbs_VERTEX &&
2168 theShapeType != TopAbs_EDGE &&
2169 theShapeType != TopAbs_FACE &&
2170 theShapeType != TopAbs_SOLID) {
2171 SetErrorCode("Only solids, vertices, edges or faces can be found by this method");
2177 //=======================================================================
2178 //function : makePlane
2180 * \brief Creates Geom_Plane
2181 * \param theAx1 - shape object defining plane parameters
2182 * \retval Handle(Geom_Surface) - resulting surface
2184 //=======================================================================
2185 Handle(Geom_Surface) GEOMImpl_IShapesOperations::makePlane(const TopoDS_Shape& anAx1)
2187 if (anAx1.ShapeType() != TopAbs_EDGE) return NULL;
2188 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
2189 TopoDS_Vertex V1, V2;
2190 TopExp::Vertices(anEdge, V1, V2, Standard_True);
2191 if (V1.IsNull() || V2.IsNull()) {
2192 SetErrorCode("Bad edge given for the plane normal vector");
2195 gp_Pnt aLoc = BRep_Tool::Pnt(V1);
2196 gp_Vec aVec (aLoc, BRep_Tool::Pnt(V2));
2197 if (aVec.Magnitude() < Precision::Confusion()) {
2198 SetErrorCode("Vector with null magnitude given");
2201 return new Geom_Plane(aLoc, aVec);
2204 //=======================================================================
2205 //function : makeCylinder
2207 * \brief Creates Geom_CylindricalSurface
2208 * \param theAx1 - edge defining cylinder axis
2209 * \param theRadius - cylinder radius
2210 * \retval Handle(Geom_Surface) - resulting surface
2212 //=======================================================================
2213 Handle(Geom_Surface) GEOMImpl_IShapesOperations::makeCylinder(const TopoDS_Shape& anAxis,
2214 const Standard_Real theRadius)
2216 //Axis of the cylinder
2217 if (anAxis.ShapeType() != TopAbs_EDGE) {
2218 SetErrorCode("Not an edge given for the axis");
2221 TopoDS_Edge anEdge = TopoDS::Edge(anAxis);
2222 TopoDS_Vertex V1, V2;
2223 TopExp::Vertices(anEdge, V1, V2, Standard_True);
2224 if (V1.IsNull() || V2.IsNull()) {
2225 SetErrorCode("Bad edge given for the axis");
2228 gp_Pnt aLoc = BRep_Tool::Pnt(V1);
2229 gp_Vec aVec (aLoc, BRep_Tool::Pnt(V2));
2230 if (aVec.Magnitude() < Precision::Confusion()) {
2231 SetErrorCode("Vector with null magnitude given");
2235 gp_Ax3 anAx3 (aLoc, aVec);
2236 return new Geom_CylindricalSurface(anAx3, theRadius);
2239 //=======================================================================
2240 //function : getShapesOnBoxIDs
2242 * \brief Find IDs of sub-shapes complying with given status about surface
2243 * \param theBox - the box to check state of sub-shapes against
2244 * \param theShape - the shape to explore
2245 * \param theShapeType - type of sub-shape of theShape
2246 * \param theState - required state
2247 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
2249 //=======================================================================
2250 Handle(TColStd_HSequenceOfInteger)
2251 GEOMImpl_IShapesOperations::getShapesOnBoxIDs(const Handle(GEOM_Object)& theBox,
2252 const Handle(GEOM_Object)& theShape,
2253 const Standard_Integer theShapeType,
2254 GEOMAlgo_State theState)
2256 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
2258 TopoDS_Shape aBox = theBox->GetValue();
2259 TopoDS_Shape aShape = theShape->GetValue();
2261 // Check presence of triangulation, build if need
2262 if (!GEOMUtils::CheckTriangulation(aShape)) {
2263 SetErrorCode("Cannot build triangulation on the shape");
2268 GEOMAlgo_FinderShapeOn2 aFinder;
2269 Standard_Real aTol = 0.0001; // default value
2271 Handle(GEOMAlgo_ClsfBox) aClsfBox = new GEOMAlgo_ClsfBox;
2272 aClsfBox->SetBox(aBox);
2274 aFinder.SetShape(aShape);
2275 aFinder.SetTolerance(aTol);
2276 aFinder.SetClsf(aClsfBox);
2277 aFinder.SetShapeType( (TopAbs_ShapeEnum)theShapeType );
2278 aFinder.SetState(theState);
2281 // Interprete results
2282 Standard_Integer iErr = aFinder.ErrorStatus();
2283 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
2285 MESSAGE(" iErr : " << iErr);
2286 TCollection_AsciiString aMsg (" iErr : ");
2287 aMsg += TCollection_AsciiString(iErr);
2291 Standard_Integer iWrn = aFinder.WarningStatus();
2292 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
2294 MESSAGE(" *** iWrn : " << iWrn);
2297 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
2299 if (listSS.Extent() < 1) {
2300 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
2301 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
2305 // Fill sequence of object IDs
2306 aSeqOfIDs = new TColStd_HSequenceOfInteger;
2308 TopTools_IndexedMapOfShape anIndices;
2309 TopExp::MapShapes(aShape, anIndices);
2311 TopTools_ListIteratorOfListOfShape itSub (listSS);
2312 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
2313 int id = anIndices.FindIndex(itSub.Value());
2314 aSeqOfIDs->Append(id);
2320 //=======================================================================
2321 //function : GetShapesOnBoxIDs
2323 * \brief Find sub-shapes complying with given status about surface
2324 * \param theBox - the box to check state of sub-shapes against
2325 * \param theShape - the shape to explore
2326 * \param theShapeType - type of sub-shape of theShape
2327 * \param theState - required state
2328 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
2330 //=======================================================================
2331 Handle(TColStd_HSequenceOfInteger)
2332 GEOMImpl_IShapesOperations::GetShapesOnBoxIDs(const Handle(GEOM_Object)& theBox,
2333 const Handle(GEOM_Object)& theShape,
2334 const Standard_Integer theShapeType,
2335 GEOMAlgo_State theState)
2337 // Find sub-shapes ids
2338 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2339 getShapesOnBoxIDs (theBox, theShape, theShapeType, theState);
2340 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2343 // The GetShapesOnBox() doesn't change object so no new function is required.
2344 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theBox)->GetLastFunction();
2346 // Make a Python command
2347 GEOM::TPythonDump(aFunction, /*append=*/true)
2348 << "listShapesOnBoxIDs = geompy.GetShapesOnBoxIDs("
2351 << TopAbs_ShapeEnum(theShapeType) << ", "
2358 //=======================================================================
2359 //function : GetShapesOnBox
2361 * \brief Find sub-shapes complying with given status about surface
2362 * \param theBox - the box to check state of sub-shapes against
2363 * \param theShape - the shape to explore
2364 * \param theShapeType - type of sub-shape of theShape
2365 * \param theState - required state
2366 * \retval Handle(TColStd_HSequenceOfTransient) - found sub-shapes
2368 //=======================================================================
2369 Handle(TColStd_HSequenceOfTransient)
2370 GEOMImpl_IShapesOperations::GetShapesOnBox(const Handle(GEOM_Object)& theBox,
2371 const Handle(GEOM_Object)& theShape,
2372 const Standard_Integer theShapeType,
2373 GEOMAlgo_State theState)
2375 // Find sub-shapes ids
2376 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2377 getShapesOnBoxIDs (theBox, theShape, theShapeType, theState);
2378 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2381 // Find objects by indices
2382 TCollection_AsciiString anAsciiList;
2383 Handle(TColStd_HSequenceOfTransient) aSeq;
2384 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
2385 if ( aSeq.IsNull() || aSeq->IsEmpty() )
2388 // Make a Python command
2390 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2391 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2393 GEOM::TPythonDump(aFunction)
2394 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnBox("
2397 << TopAbs_ShapeEnum(theShapeType) << ", "
2404 //=======================================================================
2405 //function : getShapesOnShapeIDs
2407 * \brief Find IDs of sub-shapes complying with given status about surface
2408 * \param theCheckShape - the shape to check state of sub-shapes against
2409 * \param theShape - the shape to explore
2410 * \param theShapeType - type of sub-shape of theShape
2411 * \param theState - required state
2412 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
2414 //=======================================================================
2415 Handle(TColStd_HSequenceOfInteger)
2416 GEOMImpl_IShapesOperations::getShapesOnShapeIDs
2417 (const Handle(GEOM_Object)& theCheckShape,
2418 const Handle(GEOM_Object)& theShape,
2419 const Standard_Integer theShapeType,
2420 GEOMAlgo_State theState)
2422 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
2424 TopoDS_Shape aCheckShape = theCheckShape->GetValue();
2425 TopoDS_Shape aShape = theShape->GetValue();
2426 TopTools_ListOfShape res;
2428 // Check presence of triangulation, build if need
2429 if (!GEOMUtils::CheckTriangulation(aShape)) {
2430 SetErrorCode("Cannot build triangulation on the shape");
2435 GEOMAlgo_FinderShapeOn2 aFinder;
2436 Standard_Real aTol = 0.0001; // default value
2438 Handle(GEOMAlgo_ClsfSolid) aClsfSolid = new GEOMAlgo_ClsfSolid;
2439 aClsfSolid->SetShape(aCheckShape);
2441 aFinder.SetShape(aShape);
2442 aFinder.SetTolerance(aTol);
2443 aFinder.SetClsf(aClsfSolid);
2444 aFinder.SetShapeType( (TopAbs_ShapeEnum)theShapeType );
2445 aFinder.SetState(theState);
2448 // Interprete results
2449 Standard_Integer iErr = aFinder.ErrorStatus();
2450 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
2453 SetErrorCode("theCheckShape must be a solid");
2456 MESSAGE(" iErr : " << iErr);
2457 TCollection_AsciiString aMsg (" iErr : ");
2458 aMsg += TCollection_AsciiString(iErr);
2463 Standard_Integer iWrn = aFinder.WarningStatus();
2464 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
2466 MESSAGE(" *** iWrn : " << iWrn);
2469 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
2471 if (listSS.Extent() < 1) {
2472 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
2473 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
2476 // Fill sequence of object IDs
2477 aSeqOfIDs = new TColStd_HSequenceOfInteger;
2479 TopTools_IndexedMapOfShape anIndices;
2480 TopExp::MapShapes(aShape, anIndices);
2482 TopTools_ListIteratorOfListOfShape itSub (listSS);
2483 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
2484 int id = anIndices.FindIndex(itSub.Value());
2485 aSeqOfIDs->Append(id);
2491 //=======================================================================
2492 //function : GetShapesOnShapeIDs
2494 * \brief Find sub-shapes complying with given status about surface
2495 * \param theCheckShape - the shape to check state of sub-shapes against
2496 * \param theShape - the shape to explore
2497 * \param theShapeType - type of sub-shape of theShape
2498 * \param theState - required state
2499 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
2501 //=======================================================================
2502 Handle(TColStd_HSequenceOfInteger)
2503 GEOMImpl_IShapesOperations::GetShapesOnShapeIDs
2504 (const Handle(GEOM_Object)& theCheckShape,
2505 const Handle(GEOM_Object)& theShape,
2506 const Standard_Integer theShapeType,
2507 GEOMAlgo_State theState)
2509 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2510 getShapesOnShapeIDs (theCheckShape, theShape, theShapeType, theState);
2512 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2515 // The GetShapesOnShape() doesn't change object so no new function is required.
2516 Handle(GEOM_Function) aFunction =
2517 GEOM::GetCreatedLast(theShape,theCheckShape)->GetLastFunction();
2519 // Make a Python command
2520 GEOM::TPythonDump(aFunction, /*append=*/true)
2521 << "listShapesOnBoxIDs = geompy.GetShapesOnShapeIDs("
2522 << theCheckShape << ", "
2524 << TopAbs_ShapeEnum(theShapeType) << ", "
2531 //=======================================================================
2532 //function : GetShapesOnShape
2534 * \brief Find sub-shapes complying with given status about surface
2535 * \param theCheckShape - the shape to check state of sub-shapes against
2536 * \param theShape - the shape to explore
2537 * \param theShapeType - type of sub-shape of theShape
2538 * \param theState - required state
2539 * \retval Handle(TColStd_HSequenceOfTransient) - found sub-shapes
2541 //=======================================================================
2542 Handle(TColStd_HSequenceOfTransient)
2543 GEOMImpl_IShapesOperations::GetShapesOnShape
2544 (const Handle(GEOM_Object)& theCheckShape,
2545 const Handle(GEOM_Object)& theShape,
2546 const Standard_Integer theShapeType,
2547 GEOMAlgo_State theState)
2549 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2550 getShapesOnShapeIDs (theCheckShape, theShape, theShapeType, theState);
2551 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2554 // Find objects by indices
2555 TCollection_AsciiString anAsciiList;
2556 Handle(TColStd_HSequenceOfTransient) aSeq;
2557 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
2559 if ( aSeq.IsNull() || aSeq->IsEmpty() )
2562 // Make a Python command
2564 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2565 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2567 GEOM::TPythonDump(aFunction)
2568 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnShape("
2569 << theCheckShape << ", "
2571 << TopAbs_ShapeEnum(theShapeType) << ", "
2578 //=======================================================================
2579 //function : GetShapesOnShapeAsCompound
2580 //=======================================================================
2581 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetShapesOnShapeAsCompound
2582 (const Handle(GEOM_Object)& theCheckShape,
2583 const Handle(GEOM_Object)& theShape,
2584 const Standard_Integer theShapeType,
2585 GEOMAlgo_State theState)
2587 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2588 getShapesOnShapeIDs (theCheckShape, theShape, theShapeType, theState);
2590 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2593 // Find objects by indices
2594 TCollection_AsciiString anAsciiList;
2595 Handle(TColStd_HSequenceOfTransient) aSeq;
2596 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
2598 if ( aSeq.IsNull() || aSeq->IsEmpty() )
2601 TopoDS_Compound aCompound;
2603 B.MakeCompound(aCompound);
2605 for(; i<=aSeq->Length(); i++) {
2606 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(aSeq->Value(i));
2607 TopoDS_Shape aShape_i = anObj->GetValue();
2608 B.Add(aCompound,aShape_i);
2611 //Add a new result object
2612 Handle(GEOM_Object) aRes = GetEngine()->AddObject(GetDocID(), GEOM_SHAPES_ON_SHAPE);
2613 Handle(GEOM_Function) aFunction =
2614 aRes->AddFunction(GEOMImpl_ShapeDriver::GetID(), SHAPES_ON_SHAPE);
2615 aFunction->SetValue(aCompound);
2618 aSeq->Append( theCheckShape->GetLastFunction() );
2619 aSeq->Append( theShape->GetLastFunction() );
2621 GEOMImpl_IShapes aCI( aFunction );
2622 aCI.SetShapes( aSeq );
2623 aCI.SetSubShapeType( theShapeType );
2624 aCI.SetTolerance( theState );
2626 GEOM::TPythonDump(aFunction)
2627 << aRes << " = geompy.GetShapesOnShapeAsCompound("
2628 << theCheckShape << ", "
2630 << TopAbs_ShapeEnum(theShapeType) << ", "
2638 //=======================================================================
2639 //function : getShapesOnSurfaceIDs
2641 * \brief Find IDs of sub-shapes complying with given status about surface
2642 * \param theSurface - the surface to check state of sub-shapes against
2643 * \param theShape - the shape to explore
2644 * \param theShapeType - type of sub-shape of theShape
2645 * \param theState - required state
2646 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
2648 //=======================================================================
2649 Handle(TColStd_HSequenceOfInteger)
2650 GEOMImpl_IShapesOperations::getShapesOnSurfaceIDs(const Handle(Geom_Surface)& theSurface,
2651 const TopoDS_Shape& theShape,
2652 TopAbs_ShapeEnum theShapeType,
2653 GEOMAlgo_State theState)
2655 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
2657 // Check presence of triangulation, build if need
2658 if (!GEOMUtils::CheckTriangulation(theShape)) {
2659 SetErrorCode("Cannot build triangulation on the shape");
2663 // BEGIN: Mantis issue 0020961: Error on a pipe T-Shape
2664 // Compute tolerance
2665 Standard_Real T, VertMax = -RealLast();
2668 for (TopExp_Explorer ExV (theShape, TopAbs_VERTEX); ExV.More(); ExV.Next()) {
2669 TopoDS_Vertex Vertex = TopoDS::Vertex(ExV.Current());
2670 T = BRep_Tool::Tolerance(Vertex);
2675 catch (Standard_Failure) {
2676 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2677 SetErrorCode(aFail->GetMessageString());
2680 // END: Mantis issue 0020961
2683 GEOMAlgo_FinderShapeOn1 aFinder;
2684 //Standard_Real aTol = 0.0001; // default value
2685 Standard_Real aTol = VertMax; // Mantis issue 0020961
2687 aFinder.SetShape(theShape);
2688 aFinder.SetTolerance(aTol);
2689 aFinder.SetSurface(theSurface);
2690 aFinder.SetShapeType(theShapeType);
2691 aFinder.SetState(theState);
2693 // Sets the minimal number of inner points for the faces that do not have own
2694 // inner points at all (for e.g. rectangular planar faces have just 2 triangles).
2696 aFinder.SetNbPntsMin(3);
2697 // Sets the maximal number of inner points for edges or faces.
2698 // It is usefull for the cases when this number is very big (e.g =2000) to improve
2699 // the performance. If this value =0, all inner points will be taken into account.
2701 aFinder.SetNbPntsMax(100);
2705 // Interprete results
2706 Standard_Integer iErr = aFinder.ErrorStatus();
2707 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
2709 MESSAGE(" iErr : " << iErr);
2710 TCollection_AsciiString aMsg (" iErr : ");
2711 aMsg += TCollection_AsciiString(iErr);
2715 Standard_Integer iWrn = aFinder.WarningStatus();
2716 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
2718 MESSAGE(" *** iWrn : " << iWrn);
2721 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
2723 if (listSS.Extent() < 1) {
2724 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
2725 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
2729 // Fill sequence of object IDs
2730 aSeqOfIDs = new TColStd_HSequenceOfInteger;
2732 TopTools_IndexedMapOfShape anIndices;
2733 TopExp::MapShapes(theShape, anIndices);
2735 TopTools_ListIteratorOfListOfShape itSub (listSS);
2736 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
2737 int id = anIndices.FindIndex(itSub.Value());
2738 aSeqOfIDs->Append(id);
2744 //=======================================================================
2745 //function : getObjectsShapesOn
2747 * \brief Find shape objects and their entries by their ids
2748 * \param theShapeIDs - incoming shape ids
2749 * \param theShapeEntries - outgoing entries like "entry1, entry2, ..."
2750 * \retval Handle(TColStd_HSequenceOfTransient) - found shape objects
2752 //=======================================================================
2753 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::
2754 getObjectsShapesOn(const Handle(GEOM_Object)& theShape,
2755 const Handle(TColStd_HSequenceOfInteger)& theShapeIDs,
2756 TCollection_AsciiString & theShapeEntries)
2758 Handle(TColStd_HSequenceOfTransient) aSeq;
2760 if ( !theShapeIDs.IsNull() && theShapeIDs->Length() > 0 )
2762 aSeq = new TColStd_HSequenceOfTransient;
2763 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
2764 TCollection_AsciiString anEntry;
2765 for ( int i = 1; i <= theShapeIDs->Length(); ++i )
2767 anArray->SetValue(1, theShapeIDs->Value( i ));
2768 Handle(GEOM_Object) anObj = GetEngine()->AddSubShape(theShape, anArray);
2769 aSeq->Append( anObj );
2771 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
2772 if ( i != 1 ) theShapeEntries += ",";
2773 theShapeEntries += anEntry;
2779 //=======================================================================
2780 //function : getShapesOnSurface
2782 * \brief Find sub-shapes complying with given status about surface
2783 * \param theSurface - the surface to check state of sub-shapes against
2784 * \param theShape - the shape to explore
2785 * \param theShapeType - type of sub-shape of theShape
2786 * \param theState - required state
2787 * \param theShapeEntries - outgoing entries like "entry1, entry2, ..."
2788 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
2790 //=======================================================================
2791 Handle(TColStd_HSequenceOfTransient)
2792 GEOMImpl_IShapesOperations::getShapesOnSurface(const Handle(Geom_Surface)& theSurface,
2793 const Handle(GEOM_Object)& theShape,
2794 TopAbs_ShapeEnum theShapeType,
2795 GEOMAlgo_State theState,
2796 TCollection_AsciiString & theShapeEntries)
2798 // Find sub-shapes ids
2799 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2800 getShapesOnSurfaceIDs (theSurface, theShape->GetValue(), theShapeType, theState);
2801 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2804 return getObjectsShapesOn( theShape, aSeqOfIDs, theShapeEntries );
2807 //=============================================================================
2811 //=============================================================================
2812 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnPlane
2813 (const Handle(GEOM_Object)& theShape,
2814 const Standard_Integer theShapeType,
2815 const Handle(GEOM_Object)& theAx1,
2816 const GEOMAlgo_State theState)
2820 if (theShape.IsNull() || theAx1.IsNull()) return NULL;
2822 TopoDS_Shape aShape = theShape->GetValue();
2823 TopoDS_Shape anAx1 = theAx1->GetValue();
2825 if (aShape.IsNull() || anAx1.IsNull()) return NULL;
2827 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2828 if ( !checkTypeShapesOn( theShapeType ))
2832 Handle(Geom_Surface) aPlane = makePlane( anAx1 );
2833 if ( aPlane.IsNull() )
2837 TCollection_AsciiString anAsciiList;
2838 Handle(TColStd_HSequenceOfTransient) aSeq;
2839 aSeq = getShapesOnSurface( aPlane, theShape, aShapeType, theState, anAsciiList );
2840 if ( aSeq.IsNull() || aSeq->Length() == 0 )
2843 // Make a Python command
2845 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2846 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2848 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
2849 << "] = geompy.GetShapesOnPlane(" << theShape << ", "
2850 << aShapeType << ", " << theAx1 << ", " << theState << ")";
2856 //=============================================================================
2858 * GetShapesOnPlaneWithLocation
2860 //=============================================================================
2861 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnPlaneWithLocation
2862 (const Handle(GEOM_Object)& theShape,
2863 const Standard_Integer theShapeType,
2864 const Handle(GEOM_Object)& theAx1,
2865 const Handle(GEOM_Object)& thePnt,
2866 const GEOMAlgo_State theState)
2870 if (theShape.IsNull() || theAx1.IsNull() || thePnt.IsNull()) return NULL;
2872 TopoDS_Shape aShape = theShape->GetValue();
2873 TopoDS_Shape anAx1 = theAx1->GetValue();
2874 TopoDS_Shape anPnt = thePnt->GetValue();
2876 if (aShape.IsNull() || anAx1.IsNull() || anPnt.IsNull()) return NULL;
2878 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2879 if ( !checkTypeShapesOn( theShapeType ))
2883 if ( anAx1.ShapeType() != TopAbs_EDGE || anPnt.ShapeType() != TopAbs_VERTEX ) return NULL;
2884 TopoDS_Vertex V1, V2, V3;
2885 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
2886 TopExp::Vertices(anEdge, V1, V2, Standard_True);
2888 if (V1.IsNull() || V2.IsNull()) {
2889 SetErrorCode("Bad edge given for the plane normal vector");
2892 V3 = TopoDS::Vertex(anPnt);
2895 SetErrorCode("Bad vertex given for the plane location");
2898 gp_Pnt aLoc = BRep_Tool::Pnt(V3);
2899 gp_Vec aVec(BRep_Tool::Pnt(V1),BRep_Tool::Pnt(V2));
2901 if (aVec.Magnitude() < Precision::Confusion()) {
2902 SetErrorCode("Vector with null magnitude given");
2905 Handle(Geom_Surface) aPlane = new Geom_Plane(aLoc, aVec);
2907 if ( aPlane.IsNull() )
2911 TCollection_AsciiString anAsciiList;
2912 Handle(TColStd_HSequenceOfTransient) aSeq;
2913 aSeq = getShapesOnSurface( aPlane, theShape, aShapeType, theState, anAsciiList );
2914 if ( aSeq.IsNull() || aSeq->Length() == 0 )
2917 // Make a Python command
2919 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2920 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2922 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
2923 << "] = geompy.GetShapesOnPlaneWithLocation(" << theShape << ", "
2924 << aShapeType << ", " << theAx1 << ", "<< thePnt <<", " << theState << ")";
2930 //=============================================================================
2932 * GetShapesOnCylinder
2934 //=============================================================================
2935 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnCylinder
2936 (const Handle(GEOM_Object)& theShape,
2937 const Standard_Integer theShapeType,
2938 const Handle(GEOM_Object)& theAxis,
2939 const Standard_Real theRadius,
2940 const GEOMAlgo_State theState)
2944 if (theShape.IsNull() || theAxis.IsNull()) return NULL;
2946 TopoDS_Shape aShape = theShape->GetValue();
2947 TopoDS_Shape anAxis = theAxis->GetValue();
2949 if (aShape.IsNull() || anAxis.IsNull()) return NULL;
2951 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2952 if ( !checkTypeShapesOn( aShapeType ))
2955 // Create a cylinder surface
2956 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
2957 if ( aCylinder.IsNull() )
2961 TCollection_AsciiString anAsciiList;
2962 Handle(TColStd_HSequenceOfTransient) aSeq;
2963 aSeq = getShapesOnSurface( aCylinder, theShape, aShapeType, theState, anAsciiList );
2964 if ( aSeq.IsNull() || aSeq->Length() == 0 )
2967 // Make a Python command
2969 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2970 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2972 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
2973 << "] = geompy.GetShapesOnCylinder(" << theShape << ", " << aShapeType
2974 << ", " << theAxis << ", " << theRadius << ", " << theState << ")";
2980 //=============================================================================
2982 * GetShapesOnCylinderWithLocation
2984 //=============================================================================
2985 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnCylinderWithLocation
2986 (const Handle(GEOM_Object)& theShape,
2987 const Standard_Integer theShapeType,
2988 const Handle(GEOM_Object)& theAxis,
2989 const Handle(GEOM_Object)& thePnt,
2990 const Standard_Real theRadius,
2991 const GEOMAlgo_State theState)
2995 if (theShape.IsNull() || theAxis.IsNull() || thePnt.IsNull()) return NULL;
2997 TopoDS_Shape aShape = theShape->GetValue();
2998 TopoDS_Shape anAxis = theAxis->GetValue();
2999 TopoDS_Shape aPnt = thePnt->GetValue();
3001 if (aShape.IsNull() || anAxis.IsNull() || aPnt.IsNull()) return NULL;
3003 if (aPnt.ShapeType() != TopAbs_VERTEX )
3005 SetErrorCode("Bottom location point must be vertex");
3009 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3010 if ( !checkTypeShapesOn( aShapeType ))
3013 // Create a cylinder surface
3014 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
3015 if ( aCylinder.IsNull() )
3018 // translate the surface
3019 Handle(Geom_CylindricalSurface) aCylSurface =
3020 Handle(Geom_CylindricalSurface)::DownCast( aCylinder );
3021 if ( aCylSurface.IsNull() )
3023 SetErrorCode("Unexpected surface type instead of Geom_CylindricalSurface");
3026 gp_Pnt fromLoc = aCylSurface->Cylinder().Location();
3027 gp_Pnt toLoc = BRep_Tool::Pnt( TopoDS::Vertex( aPnt ));
3028 aCylinder->Translate( fromLoc, toLoc );
3031 TCollection_AsciiString anAsciiList;
3032 Handle(TColStd_HSequenceOfTransient) aSeq;
3033 aSeq = getShapesOnSurface( aCylinder, theShape, aShapeType, theState, anAsciiList );
3034 if ( aSeq.IsNull() || aSeq->Length() == 0 )
3037 // Make a Python command
3039 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
3040 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
3042 GEOM::TPythonDump(aFunction)
3043 << "[" << anAsciiList.ToCString()
3044 << "] = geompy.GetShapesOnCylinderWithLocation(" << theShape << ", " << aShapeType << ", "
3045 << theAxis << ", " << thePnt << ", " << theRadius << ", " << theState << ")";
3051 //=============================================================================
3055 //=============================================================================
3056 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnSphere
3057 (const Handle(GEOM_Object)& theShape,
3058 const Standard_Integer theShapeType,
3059 const Handle(GEOM_Object)& theCenter,
3060 const Standard_Real theRadius,
3061 const GEOMAlgo_State theState)
3065 if (theShape.IsNull() || theCenter.IsNull()) return NULL;
3067 TopoDS_Shape aShape = theShape->GetValue();
3068 TopoDS_Shape aCenter = theCenter->GetValue();
3070 if (aShape.IsNull() || aCenter.IsNull()) return NULL;
3072 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3073 if ( !checkTypeShapesOn( aShapeType ))
3076 // Center of the sphere
3077 if (aCenter.ShapeType() != TopAbs_VERTEX) return NULL;
3078 gp_Pnt aLoc = BRep_Tool::Pnt(TopoDS::Vertex(aCenter));
3080 gp_Ax3 anAx3 (aLoc, gp::DZ());
3081 Handle(Geom_SphericalSurface) aSphere =
3082 new Geom_SphericalSurface(anAx3, theRadius);
3085 TCollection_AsciiString anAsciiList;
3086 Handle(TColStd_HSequenceOfTransient) aSeq;
3087 aSeq = getShapesOnSurface( aSphere, theShape, aShapeType, theState, anAsciiList );
3088 if ( aSeq.IsNull() || aSeq->Length() == 0 )
3091 // Make a Python command
3093 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
3094 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
3096 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
3097 << "] = geompy.GetShapesOnSphere(" << theShape << ", " << aShapeType
3098 << ", " << theCenter << ", " << theRadius << ", " << theState << ")";
3104 //=============================================================================
3106 * GetShapesOnPlaneIDs
3108 //=============================================================================
3109 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnPlaneIDs
3110 (const Handle(GEOM_Object)& theShape,
3111 const Standard_Integer theShapeType,
3112 const Handle(GEOM_Object)& theAx1,
3113 const GEOMAlgo_State theState)
3117 if (theShape.IsNull() || theAx1.IsNull()) return NULL;
3119 TopoDS_Shape aShape = theShape->GetValue();
3120 TopoDS_Shape anAx1 = theAx1->GetValue();
3122 if (aShape.IsNull() || anAx1.IsNull()) return NULL;
3124 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3125 if ( !checkTypeShapesOn( aShapeType ))
3129 Handle(Geom_Surface) aPlane = makePlane( anAx1 );
3130 if ( aPlane.IsNull() )
3134 Handle(TColStd_HSequenceOfInteger) aSeq;
3135 aSeq = getShapesOnSurfaceIDs( aPlane, aShape, aShapeType, theState );
3137 // The GetShapesOnPlaneIDs() doesn't change object so no new function is required.
3138 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAx1)->GetLastFunction();
3140 // Make a Python command
3141 GEOM::TPythonDump(aFunction, /*append=*/true)
3142 << "listShapesOnPlane = geompy.GetShapesOnPlaneIDs"
3143 << "(" << theShape << "," << aShapeType << "," << theAx1 << "," << theState << ")";
3149 //=============================================================================
3151 * GetShapesOnPlaneWithLocationIDs
3153 //=============================================================================
3154 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnPlaneWithLocationIDs
3155 (const Handle(GEOM_Object)& theShape,
3156 const Standard_Integer theShapeType,
3157 const Handle(GEOM_Object)& theAx1,
3158 const Handle(GEOM_Object)& thePnt,
3159 const GEOMAlgo_State theState)
3163 if (theShape.IsNull() || theAx1.IsNull() || thePnt.IsNull()) return NULL;
3165 TopoDS_Shape aShape = theShape->GetValue();
3166 TopoDS_Shape anAx1 = theAx1->GetValue();
3167 TopoDS_Shape anPnt = thePnt->GetValue();
3169 if (aShape.IsNull() || anAx1.IsNull() || anPnt.IsNull()) return NULL;
3171 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3172 if ( !checkTypeShapesOn( aShapeType ))
3176 if (anAx1.ShapeType() != TopAbs_EDGE || anPnt.ShapeType() != TopAbs_VERTEX) return NULL;
3177 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
3178 TopoDS_Vertex V1, V2, V3;
3179 TopExp::Vertices(anEdge, V1, V2, Standard_True);
3180 if (V1.IsNull() || V2.IsNull()) {
3181 SetErrorCode("Bad edge given for the plane normal vector");
3184 V3 = TopoDS::Vertex(anPnt);
3186 SetErrorCode("Bad vertex given for the plane location");
3189 gp_Pnt aLoc = BRep_Tool::Pnt(V3);
3190 gp_Vec aVec(BRep_Tool::Pnt(V1),BRep_Tool::Pnt(V2));
3191 if (aVec.Magnitude() < Precision::Confusion()) {
3192 SetErrorCode("Vector with null magnitude given");
3196 Handle(Geom_Surface) aPlane = new Geom_Plane(aLoc, aVec);
3197 if ( aPlane.IsNull() )
3201 Handle(TColStd_HSequenceOfInteger) aSeq;
3202 aSeq = getShapesOnSurfaceIDs( aPlane, aShape, aShapeType, theState );
3204 // The GetShapesOnPlaneIDs() doesn't change object so no new function is required.
3205 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAx1)->GetLastFunction();
3207 // Make a Python command
3208 GEOM::TPythonDump(aFunction, /*append=*/true)
3209 << "listShapesOnPlane = geompy.GetShapesOnPlaneWithLocationIDs"
3210 << "(" << theShape << ", " << aShapeType << ", " << theAx1 << ", "<< thePnt << ", " << theState << ")";
3216 //=============================================================================
3218 * GetShapesOnCylinderIDs
3220 //=============================================================================
3221 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnCylinderIDs
3222 (const Handle(GEOM_Object)& theShape,
3223 const Standard_Integer theShapeType,
3224 const Handle(GEOM_Object)& theAxis,
3225 const Standard_Real theRadius,
3226 const GEOMAlgo_State theState)
3230 if (theShape.IsNull() || theAxis.IsNull()) return NULL;
3232 TopoDS_Shape aShape = theShape->GetValue();
3233 TopoDS_Shape anAxis = theAxis->GetValue();
3235 if (aShape.IsNull() || anAxis.IsNull()) return NULL;
3237 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3238 if ( !checkTypeShapesOn( aShapeType ))
3241 // Create a cylinder surface
3242 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
3243 if ( aCylinder.IsNull() )
3247 Handle(TColStd_HSequenceOfInteger) aSeq;
3248 aSeq = getShapesOnSurfaceIDs( aCylinder, aShape, aShapeType, theState );
3250 // The GetShapesOnCylinder() doesn't change object so no new function is required.
3251 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAxis)->GetLastFunction();
3253 // Make a Python command
3254 GEOM::TPythonDump(aFunction, /*append=*/true)
3255 << "listShapesOnCylinder = geompy.GetShapesOnCylinderIDs"
3256 << "(" << theShape << ", " << aShapeType << ", " << theAxis << ", "
3257 << theRadius << ", " << theState << ")";
3263 //=============================================================================
3265 * GetShapesOnCylinderWithLocationIDs
3267 //=============================================================================
3268 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnCylinderWithLocationIDs
3269 (const Handle(GEOM_Object)& theShape,
3270 const Standard_Integer theShapeType,
3271 const Handle(GEOM_Object)& theAxis,
3272 const Handle(GEOM_Object)& thePnt,
3273 const Standard_Real theRadius,
3274 const GEOMAlgo_State theState)
3278 if (theShape.IsNull() || theAxis.IsNull() || thePnt.IsNull()) return NULL;
3280 TopoDS_Shape aShape = theShape->GetValue();
3281 TopoDS_Shape anAxis = theAxis->GetValue();
3282 TopoDS_Shape aPnt = thePnt->GetValue();
3284 if (aShape.IsNull() || anAxis.IsNull() || aPnt.IsNull()) return NULL;
3286 if (aPnt.ShapeType() != TopAbs_VERTEX )
3288 SetErrorCode("Bottom location point must be vertex");
3292 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3293 if ( !checkTypeShapesOn( aShapeType ))
3296 // Create a cylinder surface
3297 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
3298 if ( aCylinder.IsNull() )
3301 // translate the surface
3302 Handle(Geom_CylindricalSurface) aCylSurface =
3303 Handle(Geom_CylindricalSurface)::DownCast( aCylinder );
3304 if ( aCylSurface.IsNull() )
3306 SetErrorCode("Unexpected surface type instead of Geom_CylindricalSurface");
3309 gp_Pnt fromLoc = aCylSurface->Cylinder().Location();
3310 gp_Pnt toLoc = BRep_Tool::Pnt( TopoDS::Vertex( aPnt ));
3311 aCylinder->Translate( fromLoc, toLoc );
3314 Handle(TColStd_HSequenceOfInteger) aSeq;
3315 aSeq = getShapesOnSurfaceIDs( aCylinder, aShape, aShapeType, theState );
3317 // The GetShapesOnCylinder() doesn't change object so no new function is required.
3318 Handle(GEOM_Function) aFunction =
3319 GEOM::GetCreatedLast(theShape, GEOM::GetCreatedLast(thePnt,theAxis))->GetLastFunction();
3321 // Make a Python command
3322 GEOM::TPythonDump(aFunction, /*append=*/true)
3323 << "listShapesOnCylinder = geompy.GetShapesOnCylinderWithLocationIDs"
3324 << "(" << theShape << ", " << aShapeType << ", " << theAxis << ", "
3325 << thePnt << ", " << theRadius << ", " << theState << ")";
3331 //=============================================================================
3333 * GetShapesOnSphereIDs
3335 //=============================================================================
3336 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnSphereIDs
3337 (const Handle(GEOM_Object)& theShape,
3338 const Standard_Integer theShapeType,
3339 const Handle(GEOM_Object)& theCenter,
3340 const Standard_Real theRadius,
3341 const GEOMAlgo_State theState)
3345 if (theShape.IsNull() || theCenter.IsNull()) return NULL;
3347 TopoDS_Shape aShape = theShape->GetValue();
3348 TopoDS_Shape aCenter = theCenter->GetValue();
3350 if (aShape.IsNull() || aCenter.IsNull()) return NULL;
3352 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3353 if ( !checkTypeShapesOn( aShapeType ))
3356 // Center of the sphere
3357 if (aCenter.ShapeType() != TopAbs_VERTEX) return NULL;
3358 gp_Pnt aLoc = BRep_Tool::Pnt(TopoDS::Vertex(aCenter));
3360 gp_Ax3 anAx3 (aLoc, gp::DZ());
3361 Handle(Geom_SphericalSurface) aSphere =
3362 new Geom_SphericalSurface(anAx3, theRadius);
3365 Handle(TColStd_HSequenceOfInteger) aSeq;
3366 aSeq = getShapesOnSurfaceIDs( aSphere, aShape, aShapeType, theState );
3368 // The GetShapesOnSphere() doesn't change object so no new function is required.
3369 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theCenter)->GetLastFunction();
3371 // Make a Python command
3372 GEOM::TPythonDump(aFunction, /*append=*/true)
3373 << "listShapesOnCylinder = geompy.GetShapesOnSphereIDs"
3374 << "(" << theShape << ", " << aShapeType << ", " << theCenter << ", "
3375 << theRadius << ", " << theState << ")";
3381 //=======================================================================
3382 //function : getShapesOnQuadrangleIDs
3384 * \brief Find IDs of sub-shapes complying with given status about quadrangle
3385 * \param theShape - the shape to explore
3386 * \param theShapeType - type of sub-shape of theShape
3387 * \param theTopLeftPoint - top left quadrangle corner
3388 * \param theTopRigthPoint - top right quadrangle corner
3389 * \param theBottomLeftPoint - bottom left quadrangle corner
3390 * \param theBottomRigthPoint - bottom right quadrangle corner
3391 * \param theState - required state
3392 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
3394 //=======================================================================
3395 Handle(TColStd_HSequenceOfInteger)
3396 GEOMImpl_IShapesOperations::getShapesOnQuadrangleIDs (const Handle(GEOM_Object)& theShape,
3397 const Standard_Integer theShapeType,
3398 const Handle(GEOM_Object)& theTopLeftPoint,
3399 const Handle(GEOM_Object)& theTopRigthPoint,
3400 const Handle(GEOM_Object)& theBottomLeftPoint,
3401 const Handle(GEOM_Object)& theBottomRigthPoint,
3402 const GEOMAlgo_State theState)
3406 if ( theShape.IsNull() ||
3407 theTopLeftPoint.IsNull() ||
3408 theTopRigthPoint.IsNull() ||
3409 theBottomLeftPoint.IsNull() ||
3410 theBottomRigthPoint.IsNull() )
3413 TopoDS_Shape aShape = theShape->GetValue();
3414 TopoDS_Shape aTL = theTopLeftPoint->GetValue();
3415 TopoDS_Shape aTR = theTopRigthPoint->GetValue();
3416 TopoDS_Shape aBL = theBottomLeftPoint->GetValue();
3417 TopoDS_Shape aBR = theBottomRigthPoint->GetValue();
3419 if (aShape.IsNull() ||
3424 aTL.ShapeType() != TopAbs_VERTEX ||
3425 aTR.ShapeType() != TopAbs_VERTEX ||
3426 aBL.ShapeType() != TopAbs_VERTEX ||
3427 aBR.ShapeType() != TopAbs_VERTEX )
3430 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3431 if ( !checkTypeShapesOn( aShapeType ))
3434 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
3436 // Check presence of triangulation, build if need
3437 if (!GEOMUtils::CheckTriangulation(aShape)) {
3438 SetErrorCode("Cannot build triangulation on the shape");
3443 gp_Pnt aPntTL = BRep_Tool::Pnt(TopoDS::Vertex(aTL));
3444 gp_Pnt aPntTR = BRep_Tool::Pnt(TopoDS::Vertex(aTR));
3445 gp_Pnt aPntBL = BRep_Tool::Pnt(TopoDS::Vertex(aBL));
3446 gp_Pnt aPntBR = BRep_Tool::Pnt(TopoDS::Vertex(aBR));
3448 GEOMAlgo_FinderShapeOnQuad aFinder( aPntTL, aPntTR, aPntBL, aPntBR );
3449 Standard_Real aTol = 0.0001; // default value
3451 aFinder.SetShape(aShape);
3452 aFinder.SetTolerance(aTol);
3453 //aFinder.SetSurface(theSurface);
3454 aFinder.SetShapeType(aShapeType);
3455 aFinder.SetState(theState);
3457 // Sets the minimal number of inner points for the faces that do not have own
3458 // inner points at all (for e.g. rectangular planar faces have just 2 triangles).
3460 aFinder.SetNbPntsMin(3);
3461 // Sets the maximal number of inner points for edges or faces.
3462 // It is usefull for the cases when this number is very big (e.g =2000) to improve
3463 // the performance. If this value =0, all inner points will be taken into account.
3465 aFinder.SetNbPntsMax(100);
3469 // Interprete results
3470 Standard_Integer iErr = aFinder.ErrorStatus();
3471 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
3473 MESSAGE(" iErr : " << iErr);
3474 TCollection_AsciiString aMsg (" iErr : ");
3475 aMsg += TCollection_AsciiString(iErr);
3479 Standard_Integer iWrn = aFinder.WarningStatus();
3480 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
3482 MESSAGE(" *** iWrn : " << iWrn);
3485 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
3487 if (listSS.Extent() < 1) {
3488 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
3489 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
3493 // Fill sequence of object IDs
3494 aSeqOfIDs = new TColStd_HSequenceOfInteger;
3496 TopTools_IndexedMapOfShape anIndices;
3497 TopExp::MapShapes(aShape, anIndices);
3499 TopTools_ListIteratorOfListOfShape itSub (listSS);
3500 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
3501 int id = anIndices.FindIndex(itSub.Value());
3502 aSeqOfIDs->Append(id);
3507 //=======================================================================
3508 //function : GetShapesOnQuadrangle
3510 * \brief Find sub-shapes complying with given status about quadrangle
3511 * \param theShape - the shape to explore
3512 * \param theShapeType - type of sub-shape of theShape
3513 * \param theTopLeftPoint - top left quadrangle corner
3514 * \param theTopRigthPoint - top right quadrangle corner
3515 * \param theBottomLeftPoint - bottom left quadrangle corner
3516 * \param theBottomRigthPoint - bottom right quadrangle corner
3517 * \param theState - required state
3518 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
3520 //=======================================================================
3521 Handle(TColStd_HSequenceOfTransient)
3522 GEOMImpl_IShapesOperations::GetShapesOnQuadrangle (const Handle(GEOM_Object)& theShape,
3523 const Standard_Integer theShapeType,
3524 const Handle(GEOM_Object)& theTopLeftPoint,
3525 const Handle(GEOM_Object)& theTopRigthPoint,
3526 const Handle(GEOM_Object)& theBottomLeftPoint,
3527 const Handle(GEOM_Object)& theBottomRigthPoint,
3528 const GEOMAlgo_State theState)
3531 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
3532 getShapesOnQuadrangleIDs( theShape,
3537 theBottomRigthPoint,
3539 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->IsEmpty() )
3542 // Find objects by indices
3543 TCollection_AsciiString anAsciiList;
3544 Handle(TColStd_HSequenceOfTransient) aSeq;
3545 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
3546 if ( aSeq.IsNull() || aSeq->IsEmpty() )
3549 // Make a Python command
3551 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
3552 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
3554 GEOM::TPythonDump(aFunction)
3555 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnQuadrangle("
3557 << TopAbs_ShapeEnum(theShapeType) << ", "
3558 << theTopLeftPoint << ", "
3559 << theTopRigthPoint << ", "
3560 << theBottomLeftPoint << ", "
3561 << theBottomRigthPoint << ", "
3568 //=======================================================================
3569 //function : GetShapesOnQuadrangleIDs
3571 * \brief Find IDs of sub-shapes complying with given status about quadrangle
3572 * \param theShape - the shape to explore
3573 * \param theShapeType - type of sub-shape of theShape
3574 * \param theTopLeftPoint - top left quadrangle corner
3575 * \param theTopRigthPoint - top right quadrangle corner
3576 * \param theBottomLeftPoint - bottom left quadrangle corner
3577 * \param theBottomRigthPoint - bottom right quadrangle corner
3578 * \param theState - required state
3579 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
3581 //=======================================================================
3582 Handle(TColStd_HSequenceOfInteger)
3583 GEOMImpl_IShapesOperations::GetShapesOnQuadrangleIDs (const Handle(GEOM_Object)& theShape,
3584 const Standard_Integer theShapeType,
3585 const Handle(GEOM_Object)& theTopLeftPoint,
3586 const Handle(GEOM_Object)& theTopRigthPoint,
3587 const Handle(GEOM_Object)& theBottomLeftPoint,
3588 const Handle(GEOM_Object)& theBottomRigthPoint,
3589 const GEOMAlgo_State theState)
3592 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
3593 getShapesOnQuadrangleIDs( theShape,
3598 theBottomRigthPoint,
3600 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->IsEmpty() )
3603 // Make a Python command
3605 // The GetShapesOnCylinder() doesn't change object so no new function is required.
3606 Handle(GEOM_Object) lastObj = GEOM::GetCreatedLast(theShape,theTopLeftPoint);
3607 lastObj = GEOM::GetCreatedLast(lastObj,theTopRigthPoint);
3608 lastObj = GEOM::GetCreatedLast(lastObj,theBottomRigthPoint);
3609 lastObj = GEOM::GetCreatedLast(lastObj,theBottomLeftPoint);
3610 Handle(GEOM_Function) aFunction = lastObj->GetLastFunction();
3612 GEOM::TPythonDump(aFunction, /*append=*/true)
3613 << "listShapesOnQuadrangle = geompy.GetShapesOnQuadrangleIDs("
3615 << TopAbs_ShapeEnum(theShapeType) << ", "
3616 << theTopLeftPoint << ", "
3617 << theTopRigthPoint << ", "
3618 << theBottomLeftPoint << ", "
3619 << theBottomRigthPoint << ", "
3626 //=============================================================================
3630 //=============================================================================
3631 static bool GetInPlaceOfShape (const Handle(GEOM_Function)& theWhereFunction,
3632 const TopTools_IndexedMapOfShape& theWhereIndices,
3633 const TopoDS_Shape& theWhat,
3634 TColStd_ListOfInteger& theModifiedList)
3636 if (theWhereFunction.IsNull() || theWhat.IsNull()) return false;
3638 if (theWhereIndices.Contains(theWhat)) {
3639 // entity was not changed by the operation
3640 Standard_Integer aWhatIndex = theWhereIndices.FindIndex(theWhat);
3641 theModifiedList.Append(aWhatIndex);
3645 // try to find in history
3646 TDF_Label aHistoryLabel = theWhereFunction->GetHistoryEntry(Standard_False);
3648 // search in history for all argument shapes
3649 Standard_Boolean isFound = Standard_False;
3650 Standard_Boolean isGood = Standard_False;
3652 TDF_LabelSequence aLabelSeq;
3653 theWhereFunction->GetDependency(aLabelSeq);
3654 Standard_Integer nbArg = aLabelSeq.Length();
3656 for (Standard_Integer iarg = 1; iarg <= nbArg && !isFound; iarg++) {
3658 TDF_Label anArgumentRefLabel = aLabelSeq.Value(iarg);
3660 Handle(GEOM_Object) anArgumentObject = GEOM_Object::GetReferencedObject(anArgumentRefLabel);
3661 TopoDS_Shape anArgumentShape = anArgumentObject->GetValue();
3663 TopTools_IndexedMapOfShape anArgumentIndices;
3664 TopExp::MapShapes(anArgumentShape, anArgumentIndices);
3666 if (anArgumentIndices.Contains(theWhat)) {
3667 isFound = Standard_True;
3668 Standard_Integer aWhatIndex = anArgumentIndices.FindIndex(theWhat);
3670 // Find corresponding label in history
3671 TDF_Label anArgumentHistoryLabel =
3672 theWhereFunction->GetArgumentHistoryEntry(anArgumentRefLabel, Standard_False);
3673 if (anArgumentHistoryLabel.IsNull()) {
3674 // Lost History of operation argument. Possibly, all its entities was removed.
3675 isGood = Standard_True;
3678 TDF_Label aWhatHistoryLabel = anArgumentHistoryLabel.FindChild(aWhatIndex, Standard_False);
3680 if (aWhatHistoryLabel.IsNull()) {
3681 // Removed entity ? Compound ? Compsolid ? Shell ? Wire
3682 isGood = Standard_False;
3684 Handle(TDataStd_IntegerArray) anIntegerArray;
3685 if (!aWhatHistoryLabel.FindAttribute(TDataStd_IntegerArray::GetID(), anIntegerArray)) {
3686 //Error: Empty modifications history for the sought shape.
3687 isGood = Standard_False;
3690 isGood = Standard_True;
3691 Standard_Integer imod, aModifLen = anIntegerArray->Array()->Length();
3692 for (imod = 1; imod <= aModifLen; imod++) {
3693 theModifiedList.Append(anIntegerArray->Array()->Value(imod));
3704 // try compound/compsolid/shell/wire element by element
3705 bool isFoundAny = false;
3706 TopTools_MapOfShape mapShape;
3708 if (theWhat.ShapeType() == TopAbs_COMPOUND ||
3709 theWhat.ShapeType() == TopAbs_COMPSOLID) {
3710 // recursive processing of compound/compsolid
3711 TopoDS_Iterator anIt (theWhat, Standard_True, Standard_True);
3712 for (; anIt.More(); anIt.Next()) {
3713 if (mapShape.Add(anIt.Value())) {
3714 TopoDS_Shape curWhat = anIt.Value();
3715 isFoundAny = GetInPlaceOfShape(theWhereFunction, theWhereIndices, curWhat, theModifiedList);
3716 if (isFoundAny) isFound = Standard_True;
3720 else if (theWhat.ShapeType() == TopAbs_SHELL) {
3721 // try to replace a shell by its faces images
3722 TopExp_Explorer anExp (theWhat, TopAbs_FACE);
3723 for (; anExp.More(); anExp.Next()) {
3724 if (mapShape.Add(anExp.Current())) {
3725 TopoDS_Shape curWhat = anExp.Current();
3726 isFoundAny = GetInPlaceOfShape(theWhereFunction, theWhereIndices, curWhat, theModifiedList);
3727 if (isFoundAny) isFound = Standard_True;
3731 else if (theWhat.ShapeType() == TopAbs_WIRE) {
3732 // try to replace a wire by its edges images
3733 TopExp_Explorer anExp (theWhat, TopAbs_EDGE);
3734 for (; anExp.More(); anExp.Next()) {
3735 if (mapShape.Add(anExp.Current())) {
3736 TopoDS_Shape curWhat = anExp.Current();
3737 isFoundAny = GetInPlaceOfShape(theWhereFunction, theWhereIndices, curWhat, theModifiedList);
3738 if (isFoundAny) isFound = Standard_True;
3750 //=============================================================================
3752 * GetShapeProperties
3754 //=============================================================================
3755 void GEOMImpl_IShapesOperations::GetShapeProperties( const TopoDS_Shape aShape, Standard_Real tab[],
3758 GProp_GProps theProps;
3760 //TopoDS_Shape aPntShape;
3761 Standard_Real aShapeSize;
3763 if (aShape.ShapeType() == TopAbs_VERTEX) aCenterMass = BRep_Tool::Pnt( TopoDS::Vertex( aShape ) );
3764 else if (aShape.ShapeType() == TopAbs_EDGE) BRepGProp::LinearProperties(aShape, theProps);
3765 else if (aShape.ShapeType() == TopAbs_FACE) BRepGProp::SurfaceProperties(aShape, theProps);
3766 else BRepGProp::VolumeProperties(aShape, theProps);
3768 if (aShape.ShapeType() == TopAbs_VERTEX)
3771 aCenterMass = theProps.CentreOfMass();
3772 aShapeSize = theProps.Mass();
3775 // aPntShape = BRepBuilderAPI_MakeVertex(aCenterMass).Shape();
3776 // aVertex = BRep_Tool::Pnt( TopoDS::Vertex( aPntShape ) );
3777 aVertex = aCenterMass;
3778 tab[0] = aVertex.X();
3779 tab[1] = aVertex.Y();
3780 tab[2] = aVertex.Z();
3781 tab[3] = aShapeSize;
3787 //================================================================================
3789 * \brief Return normal to face at extrema point
3791 //================================================================================
3793 gp_Vec GetNormal (const TopoDS_Face& face, const BRepExtrema_DistShapeShape& extrema)
3795 gp_Vec defaultNorm(1,0,0); // to have same normals on different faces
3797 // get UV at extrema point
3798 Standard_Real u,v, f,l;
3799 switch ( extrema.SupportTypeShape2(1) ) {
3800 case BRepExtrema_IsInFace: {
3801 extrema.ParOnFaceS2(1, u, v );
3804 case BRepExtrema_IsOnEdge: {
3805 TopoDS_Edge edge = TopoDS::Edge( extrema.SupportOnShape2(1));
3806 Handle(Geom2d_Curve) pcurve = BRep_Tool::CurveOnSurface( edge, face, f,l );
3807 extrema.ParOnEdgeS2( 1, u );
3808 gp_Pnt2d uv = pcurve->Value( u );
3813 case BRepExtrema_IsVertex: return defaultNorm;
3816 BRepAdaptor_Surface surface( face, false );
3817 gp_Vec du, dv; gp_Pnt p;
3818 surface.D1( u, v, p, du, dv );
3822 } catch (Standard_Failure ) {
3828 //=============================================================================
3833 //=============================================================================
3834 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlace (Handle(GEOM_Object) theShapeWhere,
3835 Handle(GEOM_Object) theShapeWhat)
3839 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
3841 TopoDS_Shape aWhere = theShapeWhere->GetValue();
3842 TopoDS_Shape aWhat = theShapeWhat->GetValue();
3844 if (aWhere.IsNull() || aWhat.IsNull()) {
3845 SetErrorCode("Error: aWhere and aWhat TopoDS_Shape are Null.");
3849 // Compute confusion tolerance.
3850 Standard_Real aTolConf = Precision::Confusion();
3853 for (i = 0; i < 2; ++i) {
3854 TopExp_Explorer anExp(i == 0 ? aWhere : aWhat, TopAbs_VERTEX);
3856 for (; anExp.More(); anExp.Next()) {
3857 const TopoDS_Vertex aVtx = TopoDS::Vertex(anExp.Current());
3858 const Standard_Real aTolVtx = BRep_Tool::Tolerance(aVtx);
3860 if (aTolVtx > aTolConf) {
3866 // Compute mass tolerance.
3867 Bnd_Box aBoundingBox;
3868 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
3869 Standard_Real aMassTol;
3871 BRepBndLib::Add(aWhere, aBoundingBox);
3872 BRepBndLib::Add(aWhat, aBoundingBox);
3873 aBoundingBox.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
3874 aMassTol = Max(aXmax - aXmin, aYmax - aYmin);
3875 aMassTol = Max(aMassTol, aZmax - aZmin);
3876 aMassTol *= aTolConf;
3878 // Searching for the sub-shapes inside the ShapeWhere shape
3879 GEOMAlgo_GetInPlace aGIP;
3880 aGIP.SetTolerance(aTolConf);
3881 aGIP.SetTolMass(aMassTol);
3882 aGIP.SetTolCG(aTolConf);
3884 aGIP.SetArgument(aWhat);
3885 aGIP.SetShapeWhere(aWhere);
3888 int iErr = aGIP.ErrorStatus();
3890 SetErrorCode("Error in GEOMAlgo_GetInPlace");
3894 // Add direct result.
3895 TopTools_ListOfShape aLSA;
3896 const TopoDS_Shape &aShapeResult = aGIP.Result();
3897 TopTools_MapOfShape aMFence;
3898 TopTools_IndexedMapOfShape aWhereIndices;
3900 TopExp::MapShapes(aWhere, aWhereIndices);
3902 if (aShapeResult.IsNull() == Standard_False) {
3903 TopoDS_Iterator anIt(aShapeResult);
3905 for (; anIt.More(); anIt.Next()) {
3906 const TopoDS_Shape &aPart = anIt.Value();
3908 if(aWhereIndices.Contains(aPart) && aMFence.Add(aPart)) {
3914 if (aLSA.Extent() == 0) {
3915 SetErrorCode(NOT_FOUND_ANY); // Not found any Results
3919 Handle(TColStd_HArray1OfInteger) aModifiedArray = new TColStd_HArray1OfInteger (1, aLSA.Extent());
3920 TopTools_ListIteratorOfListOfShape anIterModif (aLSA);
3921 for (Standard_Integer imod = 1; anIterModif.More(); anIterModif.Next(), imod++) {
3922 if (aWhereIndices.Contains(anIterModif.Value())) {
3923 aModifiedArray->SetValue(imod, aWhereIndices.FindIndex(anIterModif.Value()));
3926 SetErrorCode("Error: wrong sub-shape returned");
3932 Handle(GEOM_Object) aResult = GetEngine()->AddSubShape(theShapeWhere, aModifiedArray);
3933 if (aResult.IsNull()) {
3934 SetErrorCode("Error in algorithm: result found, but cannot be returned.");
3938 if (aModifiedArray->Length() > 1 || theShapeWhat->GetType() == GEOM_GROUP) {
3940 aResult->SetType(GEOM_GROUP);
3942 //Set a sub-shape type
3943 TopoDS_Shape aFirstFound = aLSA.First();
3944 TopAbs_ShapeEnum aShapeType = aFirstFound.ShapeType();
3946 TDF_Label aFreeLabel = aResult->GetFreeLabel();
3947 TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aShapeType);
3950 //Make a Python command
3951 Handle(GEOM_Function) aFunction = aResult->GetFunction(1);
3953 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetInPlace("
3954 << theShapeWhere << ", " << theShapeWhat << ", True)";
3960 //=============================================================================
3962 * case GetInPlaceOld:
3965 //=============================================================================
3966 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlaceOld (Handle(GEOM_Object) theShapeWhere,
3967 Handle(GEOM_Object) theShapeWhat)
3971 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
3973 TopoDS_Shape aWhere = theShapeWhere->GetValue();
3974 TopoDS_Shape aWhat = theShapeWhat->GetValue();
3975 TopoDS_Shape aPntShape;
3976 TopoDS_Vertex aVertex;
3978 if (aWhere.IsNull() || aWhat.IsNull()) {
3979 SetErrorCode("Error: aWhere and aWhat TopoDS_Shape are Null.");
3983 Handle(GEOM_Function) aWhereFunction = theShapeWhere->GetLastFunction();
3984 if (aWhereFunction.IsNull()) {
3985 SetErrorCode("Error: aWhereFunction is Null.");
3989 TopTools_IndexedMapOfShape aWhereIndices;
3990 TopExp::MapShapes(aWhere, aWhereIndices);
3992 TColStd_ListOfInteger aModifiedList;
3993 Standard_Integer aWhereIndex;
3994 Handle(TColStd_HArray1OfInteger) aModifiedArray;
3995 Handle(GEOM_Object) aResult;
3997 bool isFound = false;
3998 TopAbs_ShapeEnum iType = TopAbs_SOLID;
3999 //Standard_Real aWhat_Mass = 0., aWhere_Mass = 0.;
4000 Standard_Real tab_aWhat[4], tab_aWhere[4];
4001 Standard_Real dl_l = 1e-3;
4002 Standard_Real min_l, Tol_0D, Tol_1D, Tol_2D, Tol_3D, Tol_Mass;
4003 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
4004 Bnd_Box BoundingBox;
4005 gp_Pnt aPnt, aPnt_aWhat, tab_Pnt[2];
4006 GProp_GProps aProps;
4008 // Find the iType of the aWhat shape
4010 if ( aWhat.ShapeType() == TopAbs_VERTEX ) iType = TopAbs_VERTEX;
4011 else if ( aWhat.ShapeType() == TopAbs_EDGE || aWhat.ShapeType() == TopAbs_WIRE ) iType = TopAbs_EDGE;
4012 else if ( aWhat.ShapeType() == TopAbs_FACE || aWhat.ShapeType() == TopAbs_SHELL ) iType = TopAbs_FACE;
4013 else if ( aWhat.ShapeType() == TopAbs_SOLID || aWhat.ShapeType() == TopAbs_COMPSOLID ) iType = TopAbs_SOLID;
4014 else if ( aWhat.ShapeType() == TopAbs_COMPOUND ) {
4015 // Only the iType of the first shape in the compound is taken into account
4016 TopoDS_Iterator It (aWhat, Standard_False, Standard_False);
4018 SetErrorCode("Error: theShapeWhat is an empty COMPOUND.");
4021 TopAbs_ShapeEnum compType = It.Value().ShapeType();
4022 if ( compType == TopAbs_VERTEX ) iType = TopAbs_VERTEX;
4023 else if ( compType == TopAbs_EDGE || compType == TopAbs_WIRE ) iType = TopAbs_EDGE;
4024 else if ( compType == TopAbs_FACE || compType == TopAbs_SHELL) iType = TopAbs_FACE;
4025 else if ( compType == TopAbs_SOLID || compType == TopAbs_COMPSOLID) iType = TopAbs_SOLID;
4028 SetErrorCode("Error: An attempt to extract a shape of not supported type.");
4032 iType = GEOMUtils::GetTypeOfSimplePart(aWhat);
4033 if (iType == TopAbs_SHAPE) {
4034 SetErrorCode("Error: An attempt to extract a shape of not supported type.");
4038 TopExp_Explorer Exp_aWhat ( aWhat, iType );
4039 TopExp_Explorer Exp_aWhere ( aWhere, iType );
4040 TopExp_Explorer Exp_Edge ( aWhere, TopAbs_EDGE );
4042 // Find the shortest edge in theShapeWhere shape
4043 BRepBndLib::Add(aWhere, BoundingBox);
4044 BoundingBox.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
4045 min_l = fabs(aXmax - aXmin);
4046 if( min_l < fabs(aYmax - aYmin) ) min_l = fabs(aYmax - aYmin);
4047 if( min_l < fabs(aZmax - aZmin) ) min_l = fabs(aZmax - aZmin);
4049 // Mantis issue 0020908 BEGIN
4050 if (!Exp_Edge.More()) {
4051 min_l = Precision::Confusion();
4053 // Mantis issue 0020908 END
4054 for ( Standard_Integer nbEdge = 0; Exp_Edge.More(); Exp_Edge.Next(), nbEdge++ ) {
4055 TopExp_Explorer Exp_Vertex( Exp_Edge.Current(), TopAbs_VERTEX);
4056 for ( Standard_Integer nbVertex = 0; Exp_Vertex.More(); Exp_Vertex.Next(), nbVertex++ ) {
4057 aPnt = BRep_Tool::Pnt( TopoDS::Vertex( Exp_Vertex.Current() ) );
4058 tab_Pnt[nbVertex] = aPnt;
4060 if ( ! tab_Pnt[0].IsEqual(tab_Pnt[1], dl_l) ) {
4061 BRepGProp::LinearProperties(Exp_Edge.Current(), aProps);
4062 if ( aProps.Mass() < min_l ) min_l = aProps.Mass();
4066 // Compute tolerances
4068 Tol_1D = dl_l * min_l;
4069 Tol_2D = dl_l * ( min_l * min_l) * ( 2. + dl_l);
4070 Tol_3D = dl_l * ( min_l * min_l * min_l ) * ( 3. + (3 * dl_l) + (dl_l * dl_l) );
4072 if (Tol_0D < Precision::Confusion()) Tol_0D = Precision::Confusion();
4073 if (Tol_1D < Precision::Confusion()) Tol_1D = Precision::Confusion();
4074 if (Tol_2D < Precision::Confusion()) Tol_2D = Precision::Confusion();
4075 if (Tol_3D < Precision::Confusion()) Tol_3D = Precision::Confusion();
4077 //if (Tol_1D > 1.0) Tol_1D = 1.0;
4078 //if (Tol_2D > 1.0) Tol_2D = 1.0;
4079 //if (Tol_3D > 1.0) Tol_3D = 1.0;
4082 if ( iType == TopAbs_VERTEX ) Tol_Mass = Tol_0D;
4083 else if ( iType == TopAbs_EDGE ) Tol_Mass = Tol_1D;
4084 else if ( iType == TopAbs_FACE ) Tol_Mass = Tol_2D;
4086 // Compute the ShapeWhat Mass
4088 for ( ; Exp_aWhat.More(); Exp_aWhat.Next() ) {
4089 if ( iType == TopAbs_VERTEX ) {
4093 else if ( iType == TopAbs_EDGE ) BRepGProp::LinearProperties(Exp_aWhat.Current(), aProps);
4094 else if ( iType == TopAbs_FACE ) BRepGProp::SurfaceProperties(Exp_aWhat.Current(), aProps);
4095 else BRepGProp::VolumeProperties(Exp_aWhat.Current(), aProps);
4096 aWhat_Mass += aProps.Mass();
4100 // Searching for the sub-shapes inside the ShapeWhere shape
4101 TopTools_MapOfShape map_aWhere;
4102 for ( Exp_aWhere.ReInit(); Exp_aWhere.More(); Exp_aWhere.Next() ) {
4103 if (!map_aWhere.Add(Exp_aWhere.Current()))
4104 continue; // skip repeated shape to avoid mass addition
4105 GetShapeProperties( Exp_aWhere.Current(), tab_aWhere, aPnt );
4106 for ( Exp_aWhat.ReInit(); Exp_aWhat.More(); Exp_aWhat.Next() ) {
4107 GetShapeProperties( Exp_aWhat.Current(), tab_aWhat, aPnt_aWhat );
4108 if ( fabs(tab_aWhat[3] - tab_aWhere[3]) <= Tol_Mass && aPnt_aWhat.Distance(aPnt) <= Tol_1D )
4111 if ( (tab_aWhat[3] - tab_aWhere[3]) > Tol_Mass ) {
4112 aPntShape = BRepBuilderAPI_MakeVertex( aPnt ).Shape();
4113 aVertex = TopoDS::Vertex( aPntShape );
4114 BRepExtrema_DistShapeShape aWhereDistance ( aVertex, Exp_aWhere.Current() );
4115 BRepExtrema_DistShapeShape aWhatDistance ( aVertex, Exp_aWhat.Current() );
4116 if ( aWhereDistance.IsDone() && aWhatDistance.IsDone() &&
4117 fabs(aWhereDistance.Value() - aWhatDistance.Value()) <= Tol_1D )
4119 // 0020162: "EDF 961 GEOM : Getinplace is getting additionnal orthogonal faces"
4120 // aVertex must be projected to the same point on Where and on What
4121 gp_Pnt pOnWhat = aWhatDistance.PointOnShape2(1);
4122 gp_Pnt pOnWhere = aWhereDistance.PointOnShape2(1);
4123 isFound = ( pOnWhat.Distance(pOnWhere) <= Tol_1D );
4124 if ( isFound && iType == TopAbs_FACE )
4126 // check normals at pOnWhat and pOnWhere
4127 const double angleTol = M_PI/180.;
4128 gp_Vec normToWhat = GetNormal( TopoDS::Face(Exp_aWhat.Current()), aWhatDistance);
4129 gp_Vec normToWhere = GetNormal( TopoDS::Face(Exp_aWhere.Current()), aWhereDistance);
4130 if ( normToWhat * normToWhere < 0 )
4131 normToWhat.Reverse();
4132 isFound = ( normToWhat.Angle( normToWhere ) < angleTol );
4138 aWhereIndex = aWhereIndices.FindIndex(Exp_aWhere.Current());
4139 aModifiedList.Append(aWhereIndex);
4140 //aWhere_Mass += tab_aWhere[3];
4145 //if ( fabs( aWhat_Mass - aWhere_Mass ) <= Tol_Mass )
4149 if (aModifiedList.Extent() == 0) { // Not found any Results
4150 SetErrorCode(NOT_FOUND_ANY);
4154 aModifiedArray = new TColStd_HArray1OfInteger (1, aModifiedList.Extent());
4155 TColStd_ListIteratorOfListOfInteger anIterModif (aModifiedList);
4156 for (Standard_Integer imod = 1; anIterModif.More(); anIterModif.Next(), imod++)
4157 aModifiedArray->SetValue(imod, anIterModif.Value());
4160 aResult = GetEngine()->AddSubShape(theShapeWhere, aModifiedArray);
4161 if (aResult.IsNull()) {
4162 SetErrorCode("Error in algorithm: result found, but cannot be returned.");
4166 if (aModifiedArray->Length() > 1 || theShapeWhat->GetType() == GEOM_GROUP) {
4168 aResult->SetType(GEOM_GROUP);
4170 //Set a sub-shape type
4171 TopoDS_Shape aFirstFound = aWhereIndices.FindKey(aModifiedArray->Value(1));
4172 TopAbs_ShapeEnum aShapeType = aFirstFound.ShapeType();
4174 TDF_Label aFreeLabel = aResult->GetFreeLabel();
4175 TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aShapeType);
4178 //Make a Python command
4179 Handle(GEOM_Function) aFunction = aResult->GetFunction(1);
4181 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetInPlace("
4182 << theShapeWhere << ", " << theShapeWhat << ", False)";
4188 //=======================================================================
4189 //function : GetInPlaceByHistory
4191 //=======================================================================
4192 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlaceByHistory
4193 (Handle(GEOM_Object) theShapeWhere,
4194 Handle(GEOM_Object) theShapeWhat)
4198 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
4200 TopoDS_Shape aWhere = theShapeWhere->GetValue();
4201 TopoDS_Shape aWhat = theShapeWhat->GetValue();
4203 if (aWhere.IsNull() || aWhat.IsNull()) return NULL;
4205 Handle(GEOM_Function) aWhereFunction = theShapeWhere->GetLastFunction();
4206 if (aWhereFunction.IsNull()) return NULL;
4208 //Fill array of indices
4209 TopTools_IndexedMapOfShape aWhereIndices;
4210 TopExp::MapShapes(aWhere, aWhereIndices);
4213 TColStd_ListOfInteger aModifiedList;
4214 bool isFound = GetInPlaceOfShape(aWhereFunction, aWhereIndices, aWhat, aModifiedList);
4216 if (!isFound || aModifiedList.Extent() < 1) {
4217 SetErrorCode("Error: No history found for the sought shape or its sub-shapes.");
4221 Standard_Integer nbFound = aModifiedList.Extent();
4222 TColStd_ListIteratorOfListOfInteger anIterModif (aModifiedList);
4225 // remove sub-shapes inappropriate for group creation
4226 TopAbs_ShapeEnum subType = TopAbs_SHAPE;
4227 while ( anIterModif.More() ) {
4228 TopAbs_ShapeEnum type = aWhereIndices( anIterModif.Value() ).ShapeType();
4229 bool okForGroup = ( type == TopAbs_VERTEX || type == TopAbs_EDGE ||
4230 type == TopAbs_FACE || type == TopAbs_SOLID );
4232 if ( subType == TopAbs_SHAPE )
4235 okForGroup = ( subType == type );
4240 aModifiedList.Remove( anIterModif );
4241 nbFound -= ( !okForGroup );
4243 if ( nbFound == 0 ) {
4244 SetErrorCode("Error: result found but it's type is inappropriate for group creation.");
4249 Handle(TColStd_HArray1OfInteger) aModifiedArray =
4250 new TColStd_HArray1OfInteger( 1, nbFound );
4251 anIterModif.Initialize(aModifiedList);
4252 for (Standard_Integer imod = 1; anIterModif.More(); anIterModif.Next(), imod++)
4253 aModifiedArray->SetValue(imod, anIterModif.Value());
4256 Handle(GEOM_Object) aResult = GetEngine()->AddSubShape(theShapeWhere, aModifiedArray);
4257 if (aResult.IsNull()) {
4258 SetErrorCode("Error in algorithm: result found, but cannot be returned.");
4262 if (aModifiedArray->Length() > 1) {
4264 aResult->SetType(GEOM_GROUP);
4266 //Set a sub-shape type
4267 TopoDS_Shape aFirstFound = aWhereIndices.FindKey(aModifiedArray->Value(1));
4268 TopAbs_ShapeEnum aShapeType = aFirstFound.ShapeType();
4270 TDF_Label aFreeLabel = aResult->GetFreeLabel();
4271 TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aShapeType);
4274 //Make a Python command
4275 Handle(GEOM_Function) aFunction = aResult->GetFunction(1);
4277 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetInPlaceByHistory("
4278 << theShapeWhere << ", " << theShapeWhat << ")";
4284 #define MAX_TOLERANCE 1.e-7
4286 //=======================================================================
4287 //function : isSameEdge
4288 //purpose : Returns True if two edges coincide
4289 //=======================================================================
4290 static bool isSameEdge(const TopoDS_Edge& theEdge1, const TopoDS_Edge& theEdge2)
4292 TopoDS_Vertex V11, V12, V21, V22;
4293 TopExp::Vertices(theEdge1, V11, V12);
4294 TopExp::Vertices(theEdge2, V21, V22);
4295 gp_Pnt P11 = BRep_Tool::Pnt(V11);
4296 gp_Pnt P12 = BRep_Tool::Pnt(V12);
4297 gp_Pnt P21 = BRep_Tool::Pnt(V21);
4298 gp_Pnt P22 = BRep_Tool::Pnt(V22);
4299 bool coincide = false;
4301 //Check that ends of edges coincide
4302 if(P11.Distance(P21) <= MAX_TOLERANCE) {
4303 if(P12.Distance(P22) <= MAX_TOLERANCE) coincide = true;
4305 else if(P11.Distance(P22) <= MAX_TOLERANCE) {
4306 if(P12.Distance(P21) <= MAX_TOLERANCE) coincide = true;
4309 if(!coincide) return false;
4311 if (BRep_Tool::Degenerated(theEdge1))
4312 if (BRep_Tool::Degenerated(theEdge2)) return true;
4315 if (BRep_Tool::Degenerated(theEdge2)) return false;
4317 double U11, U12, U21, U22;
4318 Handle(Geom_Curve) C1 = BRep_Tool::Curve(theEdge1, U11, U12);
4319 Handle(Geom_Curve) C2 = BRep_Tool::Curve(theEdge2, U21, U22);
4320 if(C1->DynamicType() == C2->DynamicType()) return true;
4322 //Check that both edges has the same geometry
4323 double range = U12-U11;
4324 double U = U11+ range/3.0;
4325 gp_Pnt P1 = C1->Value(U); //Compute a point on one third of the edge's length
4326 U = U11+range*2.0/3.0;
4327 gp_Pnt P2 = C1->Value(U); //Compute a point on two thirds of the edge's length
4329 if(!GeomLib_Tool::Parameter(C2, P1, MAX_TOLERANCE, U) || U < U21 || U > U22)
4332 if(P1.Distance(C2->Value(U)) > MAX_TOLERANCE) return false;
4334 if(!GeomLib_Tool::Parameter(C2, P2, MAX_TOLERANCE, U) || U < U21 || U > U22)
4337 if(P2.Distance(C2->Value(U)) > MAX_TOLERANCE) return false;
4342 #include <TopoDS_TShape.hxx>
4343 //=======================================================================
4344 //function : isSameFace
4345 //purpose : Returns True if two faces coincide
4346 //=======================================================================
4347 static bool isSameFace(const TopoDS_Face& theFace1, const TopoDS_Face& theFace2)
4349 TopExp_Explorer E(theFace1, TopAbs_EDGE);
4350 TopTools_ListOfShape LS1, LS2;
4351 for(; E.More(); E.Next()) LS1.Append(E.Current());
4353 E.Init(theFace2, TopAbs_EDGE);
4354 for(; E.More(); E.Next()) LS2.Append(E.Current());
4356 //Compare the number of edges in the faces
4357 if(LS1.Extent() != LS2.Extent()) return false;
4359 double aMin = RealFirst(), aMax = RealLast();
4360 double xminB1=aMax, yminB1=aMax, zminB1=aMax, xminB2=aMax, yminB2=aMax, zminB2=aMax;
4361 double xmaxB1=aMin, ymaxB1=aMin, zmaxB1=aMin, xmaxB2=aMin, ymaxB2=aMin, zmaxB2=aMin;
4363 for(E.Init(theFace1, TopAbs_VERTEX); E.More(); E.Next()) {
4364 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4365 if(P.X() < xminB1) xminB1 = P.X();
4366 if(P.Y() < yminB1) yminB1 = P.Y();
4367 if(P.Z() < zminB1) zminB1 = P.Z();
4368 if(P.X() > xmaxB1) xmaxB1 = P.X();
4369 if(P.Y() > ymaxB1) ymaxB1 = P.Y();
4370 if(P.Z() > zmaxB1) zmaxB1 = P.Z();
4373 for(E.Init(theFace2, TopAbs_VERTEX); E.More(); E.Next()) {
4374 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4375 if(P.X() < xminB2) xminB2 = P.X();
4376 if(P.Y() < yminB2) yminB2 = P.Y();
4377 if(P.Z() < zminB2) zminB2 = P.Z();
4378 if(P.X() > xmaxB2) xmaxB2 = P.X();
4379 if(P.Y() > ymaxB2) ymaxB2 = P.Y();
4380 if(P.Z() > zmaxB2) zmaxB2 = P.Z();
4383 //Compare the bounding boxes of both faces
4384 if(gp_Pnt(xminB1, yminB1, zminB1).Distance(gp_Pnt(xminB2, yminB2, zminB2)) > MAX_TOLERANCE)
4387 if(gp_Pnt(xmaxB1, ymaxB1, zmaxB1).Distance(gp_Pnt(xmaxB2, ymaxB2, zmaxB2)) > MAX_TOLERANCE)
4390 Handle(Geom_Surface) S1 = BRep_Tool::Surface(theFace1);
4391 Handle(Geom_Surface) S2 = BRep_Tool::Surface(theFace2);
4393 //Check if there a coincidence of two surfaces at least in two points
4394 double U11, U12, V11, V12, U21, U22, V21, V22;
4395 BRepTools::UVBounds(theFace1, U11, U12, V11, V12);
4396 BRepTools::UVBounds(theFace2, U21, U22, V21, V22);
4398 double rangeU = U12-U11;
4399 double rangeV = V12-V11;
4400 double U = U11 + rangeU/3.0;
4401 double V = V11 + rangeV/3.0;
4402 gp_Pnt P1 = S1->Value(U, V);
4403 U = U11+rangeU*2.0/3.0;
4404 V = V11+rangeV*2.0/3.0;
4405 gp_Pnt P2 = S1->Value(U, V);
4407 if (!GeomLib_Tool::Parameters(S2, P1, MAX_TOLERANCE, U, V) || U < U21 || U > U22 || V < V21 || V > V22)
4410 if (P1.Distance(S2->Value(U,V)) > MAX_TOLERANCE) return false;
4412 if (!GeomLib_Tool::Parameters(S2, P2, MAX_TOLERANCE, U, V) || U < U21 || U > U22 || V < V21 || V > V22)
4415 if (P2.Distance(S2->Value(U, V)) > MAX_TOLERANCE) return false;
4417 //Check that each edge of the Face1 has a counterpart in the Face2
4418 TopTools_MapOfOrientedShape aMap;
4419 TopTools_ListIteratorOfListOfShape LSI1(LS1);
4420 for(; LSI1.More(); LSI1.Next()) {
4421 TopoDS_Edge E = TopoDS::Edge(LSI1.Value());
4422 bool isFound = false;
4423 TopTools_ListIteratorOfListOfShape LSI2(LS2);
4424 for(; LSI2.More(); LSI2.Next()) {
4425 TopoDS_Shape aValue = LSI2.Value();
4426 if(aMap.Contains(aValue)) continue; //To avoid checking already found edge several times
4427 if(isSameEdge(E, TopoDS::Edge(aValue))) {
4433 if(!isFound) return false;
4439 //=======================================================================
4440 //function : isSameSolid
4441 //purpose : Returns True if two solids coincide
4442 //=======================================================================
4443 bool isSameSolid(const TopoDS_Solid& theSolid1, const TopoDS_Solid& theSolid2)
4445 TopExp_Explorer E(theSolid1, TopAbs_FACE);
4446 TopTools_ListOfShape LS1, LS2;
4447 for(; E.More(); E.Next()) LS1.Append(E.Current());
4448 E.Init(theSolid2, TopAbs_FACE);
4449 for(; E.More(); E.Next()) LS2.Append(E.Current());
4451 if(LS1.Extent() != LS2.Extent()) return false;
4453 double aMin = RealFirst(), aMax = RealLast();
4454 double xminB1=aMax, yminB1=aMax, zminB1=aMax, xminB2=aMax, yminB2=aMax, zminB2=aMax;
4455 double xmaxB1=aMin, ymaxB1=aMin, zmaxB1=aMin, xmaxB2=aMin, ymaxB2=aMin, zmaxB2=aMin;
4457 for(E.Init(theSolid1, TopAbs_VERTEX); E.More(); E.Next()) {
4458 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4459 if(P.X() < xminB1) xminB1 = P.X();
4460 if(P.Y() < yminB1) yminB1 = P.Y();
4461 if(P.Z() < zminB1) zminB1 = P.Z();
4462 if(P.X() > xmaxB1) xmaxB1 = P.X();
4463 if(P.Y() > ymaxB1) ymaxB1 = P.Y();
4464 if(P.Z() > zmaxB1) zmaxB1 = P.Z();
4467 for(E.Init(theSolid2, TopAbs_VERTEX); E.More(); E.Next()) {
4468 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4469 if(P.X() < xminB2) xminB2 = P.X();
4470 if(P.Y() < yminB2) yminB2 = P.Y();
4471 if(P.Z() < zminB2) zminB2 = P.Z();
4472 if(P.X() > xmaxB2) xmaxB2 = P.X();
4473 if(P.Y() > ymaxB2) ymaxB2 = P.Y();
4474 if(P.Z() > zmaxB2) zmaxB2 = P.Z();
4477 //Compare the bounding boxes of both solids
4478 if(gp_Pnt(xminB1, yminB1, zminB1).Distance(gp_Pnt(xminB2, yminB2, zminB2)) > MAX_TOLERANCE)
4481 if(gp_Pnt(xmaxB1, ymaxB1, zmaxB1).Distance(gp_Pnt(xmaxB2, ymaxB2, zmaxB2)) > MAX_TOLERANCE)
4484 //Check that each face of the Solid1 has a counterpart in the Solid2
4485 TopTools_MapOfOrientedShape aMap;
4486 TopTools_ListIteratorOfListOfShape LSI1(LS1);
4487 for(; LSI1.More(); LSI1.Next()) {
4488 TopoDS_Face F = TopoDS::Face(LSI1.Value());
4489 bool isFound = false;
4490 TopTools_ListIteratorOfListOfShape LSI2(LS2);
4491 for(; LSI2.More(); LSI2.Next()) {
4492 if(aMap.Contains(LSI2.Value())) continue; //To avoid checking already found faces several times
4493 if(isSameFace(F, TopoDS::Face(LSI2.Value()))) {
4494 aMap.Add(LSI2.Value());
4499 if(!isFound) return false;
4505 //=======================================================================
4506 //function : GetSame
4508 //=======================================================================
4509 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetSame(const Handle(GEOM_Object)& theShapeWhere,
4510 const Handle(GEOM_Object)& theShapeWhat)
4513 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
4515 TopoDS_Shape aWhere = theShapeWhere->GetValue();
4516 TopoDS_Shape aWhat = theShapeWhat->GetValue();
4518 if (aWhere.IsNull() || aWhat.IsNull()) return NULL;
4521 bool isFound = false;
4522 TopoDS_Shape aSubShape;
4523 TopTools_MapOfShape aMap;
4525 if (aWhat.ShapeType() == TopAbs_COMPOUND || aWhat.ShapeType() == TopAbs_COMPSOLID) {
4526 TopoDS_Iterator It (aWhat, Standard_True, Standard_True);
4527 if (It.More()) aWhat = It.Value();
4530 SetErrorCode("Compounds of two or more shapes are not allowed for aWhat argument");
4535 switch (aWhat.ShapeType()) {
4536 case TopAbs_VERTEX: {
4537 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(aWhat));
4538 TopExp_Explorer E(aWhere, TopAbs_VERTEX);
4539 for(; E.More(); E.Next()) {
4540 if(!aMap.Add(E.Current())) continue;
4541 gp_Pnt P2 = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4542 if(P.Distance(P2) <= MAX_TOLERANCE) {
4544 aSubShape = E.Current();
4551 TopoDS_Edge anEdge = TopoDS::Edge(aWhat);
4552 TopExp_Explorer E(aWhere, TopAbs_EDGE);
4553 for(; E.More(); E.Next()) {
4554 if(!aMap.Add(E.Current())) continue;
4555 if(isSameEdge(anEdge, TopoDS::Edge(E.Current()))) {
4556 aSubShape = E.Current();
4564 TopoDS_Face aFace = TopoDS::Face(aWhat);
4565 TopExp_Explorer E(aWhere, TopAbs_FACE);
4566 for(; E.More(); E.Next()) {
4567 if(!aMap.Add(E.Current())) continue;
4568 if(isSameFace(aFace, TopoDS::Face(E.Current()))) {
4569 aSubShape = E.Current();
4576 case TopAbs_SOLID: {
4577 TopoDS_Solid aSolid = TopoDS::Solid(aWhat);
4578 TopExp_Explorer E(aWhere, TopAbs_SOLID);
4579 for(; E.More(); E.Next()) {
4580 if(!aMap.Add(E.Current())) continue;
4581 if(isSameSolid(aSolid, TopoDS::Solid(E.Current()))) {
4582 aSubShape = E.Current();
4594 TopTools_IndexedMapOfShape anIndices;
4595 TopExp::MapShapes(aWhere, anIndices);
4596 if (anIndices.Contains(aSubShape))
4597 anIndex = anIndices.FindIndex(aSubShape);
4600 if (anIndex < 0) return NULL;
4602 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
4604 anArray->SetValue(1, anIndex);
4606 Handle(GEOM_Object) aResult = GetEngine()->AddSubShape(theShapeWhere, anArray);
4607 Handle(GEOM_Function) aFunction = aResult->GetLastFunction();
4609 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetSame("
4610 << theShapeWhere << ", " << theShapeWhat << ")";
4618 //=======================================================================
4619 //function : GetSameIDs
4621 //=======================================================================
4622 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetSameIDs
4623 (const Handle(GEOM_Object)& theShapeWhere,
4624 const Handle(GEOM_Object)& theShapeWhat)
4627 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
4629 TopoDS_Shape aWhere = theShapeWhere->GetValue();
4630 TopoDS_Shape aWhat = theShapeWhat->GetValue();
4632 if (aWhere.IsNull() || aWhat.IsNull()) return NULL;
4634 TopTools_ListOfShape listShape;
4635 TopTools_MapOfShape aMap;
4637 if (aWhat.ShapeType() == TopAbs_COMPOUND || aWhat.ShapeType() == TopAbs_COMPSOLID) {
4638 TopoDS_Iterator It (aWhat, Standard_True, Standard_True);
4639 if (It.More()) aWhat = It.Value();
4642 SetErrorCode("Compounds of two or more shapes are not allowed for aWhat argument");
4647 switch (aWhat.ShapeType()) {
4648 case TopAbs_VERTEX: {
4649 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(aWhat));
4650 TopExp_Explorer E(aWhere, TopAbs_VERTEX);
4651 for(; E.More(); E.Next()) {
4652 if(!aMap.Add(E.Current())) continue;
4653 gp_Pnt P2 = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4654 if(P.Distance(P2) <= MAX_TOLERANCE) {
4655 listShape.Append(E.Current());
4661 TopoDS_Edge anEdge = TopoDS::Edge(aWhat);
4662 TopExp_Explorer E(aWhere, TopAbs_EDGE);
4663 for(; E.More(); E.Next()) {
4664 if(!aMap.Add(E.Current())) continue;
4665 if(isSameEdge(anEdge, TopoDS::Edge(E.Current()))) {
4666 listShape.Append(E.Current());
4672 TopoDS_Face aFace = TopoDS::Face(aWhat);
4673 TopExp_Explorer E(aWhere, TopAbs_FACE);
4674 for(; E.More(); E.Next()) {
4675 if(!aMap.Add(E.Current())) continue;
4676 if(isSameFace(aFace, TopoDS::Face(E.Current()))) {
4677 listShape.Append(E.Current());
4682 case TopAbs_SOLID: {
4683 TopoDS_Solid aSolid = TopoDS::Solid(aWhat);
4684 TopExp_Explorer E(aWhere, TopAbs_SOLID);
4685 for(; E.More(); E.Next()) {
4686 if(!aMap.Add(E.Current())) continue;
4687 if(isSameSolid(aSolid, TopoDS::Solid(E.Current()))) {
4688 listShape.Append(E.Current());
4697 if ( !listShape.IsEmpty() ) {
4698 TopTools_IndexedMapOfShape anIndices;
4699 TopExp::MapShapes(aWhere, anIndices);
4700 TopTools_ListIteratorOfListOfShape itSub (listShape);
4701 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
4702 for (; itSub.More(); itSub.Next()) {
4703 if (anIndices.Contains(itSub.Value()))
4704 aSeq->Append(anIndices.FindIndex(itSub.Value()));
4707 // The GetSameIDs() doesn't change object so no new function is required.
4708 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShapeWhere,theShapeWhat)->GetLastFunction();
4710 // Make a Python command
4711 GEOM::TPythonDump(aFunction, /*append=*/true)
4712 << "listSameIDs = geompy.GetSameIDs("
4713 << theShapeWhere << ", "
4714 << theShapeWhat << ")";
4717 SetErrorCode(NOT_FOUND_ANY);