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) GEOMImpl_IShapesOperations::GetExistingSubObjects
1133 (Handle(GEOM_Object) theShape,
1134 const Standard_Boolean theGroupsOnly)
1138 if (theShape.IsNull()) return NULL;
1140 Handle(GEOM_Function) aMainShape = theShape->GetLastFunction();
1141 if (aMainShape.IsNull()) return NULL;
1143 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1144 SetErrorCode(NOT_FOUND_ANY);
1146 if (!aMainShape->HasSubShapeReferences()) return aSeq;
1147 const TDataStd_ListOfExtendedString& aListEntries = aMainShape->GetSubShapeReferences();
1148 if (aListEntries.IsEmpty()) return aSeq;
1152 TCollection_AsciiString anAsciiList;
1154 TDataStd_ListIteratorOfListOfExtendedString anIt (aListEntries);
1155 for (; anIt.More(); anIt.Next()) {
1156 TCollection_ExtendedString anEntry = anIt.Value();
1157 Standard_Integer aStrLen = anEntry.LengthOfCString();
1158 char* anEntryStr = new char[aStrLen+1];
1159 anEntry.ToUTF8CString(anEntryStr);
1160 Handle(GEOM_BaseObject) anObj = GetEngine()->GetObject(GetDocID(), anEntryStr, false);
1161 if (!anObj.IsNull() && anObj->IsKind(STANDARD_TYPE(GEOM_Object))) {
1162 if (!theGroupsOnly || anObj->GetType() == GEOM_GROUP) {
1163 aSeq->Append(anObj);
1165 // for python command
1166 anAsciiList += anEntryStr;
1170 delete [] anEntryStr;
1173 if (aSeq->Length() == 0) {
1174 SetErrorCode(NOT_FOUND_ANY);
1178 //Make a Python command
1179 anAsciiList.Trunc(anAsciiList.Length() - 1);
1181 GEOM::TPythonDump pd (aMainShape, /*append=*/true);
1182 pd << "[" << anAsciiList.ToCString();
1183 pd << "] = geompy.GetExistingSubObjects(";
1184 pd << theShape << ", " << (bool)theGroupsOnly << ")";
1191 //=============================================================================
1195 //=============================================================================
1196 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::MakeExplode
1197 (Handle(GEOM_Object) theShape,
1198 const Standard_Integer theShapeType,
1199 const Standard_Boolean isSorted,
1200 const ExplodeType theExplodeType)
1204 if (theShape.IsNull()) return NULL;
1205 TopoDS_Shape aShape = theShape->GetValue();
1206 if (aShape.IsNull()) return NULL;
1208 Handle(GEOM_Function) aMainShape = theShape->GetLastFunction();
1210 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1211 Handle(GEOM_Object) anObj;
1212 TopTools_MapOfShape mapShape;
1213 TopTools_ListOfShape listShape;
1215 if (aShape.ShapeType() == TopAbs_COMPOUND &&
1216 (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
1217 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPSOLID ||
1218 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPOUND))
1220 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
1221 for (; It.More(); It.Next()) {
1222 if (mapShape.Add(It.Value())) {
1223 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
1224 TopAbs_ShapeEnum(theShapeType) == It.Value().ShapeType()) {
1225 listShape.Append(It.Value());
1230 else if (theExplodeType != EXPLODE_NEW_EXCLUDE_MAIN || aShape.ShapeType() != theShapeType) // issue 0021079
1232 TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
1233 for (; exp.More(); exp.Next())
1234 if (mapShape.Add(exp.Current()))
1235 listShape.Append(exp.Current());
1238 if (listShape.IsEmpty()) {
1239 //SetErrorCode("The given shape has no sub-shapes of the requested type");
1240 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
1245 bool isOldSorting = false;
1246 if (theExplodeType == EXPLODE_OLD_INCLUDE_MAIN)
1247 isOldSorting = true;
1248 GEOMUtils::SortShapes(listShape, isOldSorting);
1251 TopTools_IndexedMapOfShape anIndices;
1252 TopExp::MapShapes(aShape, anIndices);
1253 Handle(TColStd_HArray1OfInteger) anArray;
1255 TopTools_ListIteratorOfListOfShape itSub (listShape);
1256 TCollection_AsciiString anAsciiList, anEntry;
1257 for (int index = 1; itSub.More(); itSub.Next(), ++index)
1259 TopoDS_Shape aValue = itSub.Value();
1260 anArray = new TColStd_HArray1OfInteger(1,1);
1261 anArray->SetValue(1, anIndices.FindIndex(aValue));
1263 //anObj = GetEngine()->AddSubShape(theShape, anArray);
1265 anObj = GetEngine()->AddObject(GetDocID(), GEOM_SUBSHAPE);
1266 Handle(GEOM_Function) aFunction = anObj->AddFunction(GEOM_Object::GetSubShapeID(), 1);
1267 if (aFunction.IsNull()) return aSeq;
1269 GEOM_ISubShape aSSI (aFunction);
1270 aSSI.SetMainShape(aMainShape);
1271 aSSI.SetIndices(anArray);
1273 // Set function value directly, as we know it.
1274 // Usage of Solver here would lead to significant loss of time,
1275 // because GEOM_SubShapeDriver will build TopTools_IndexedMapOfShape
1276 // on the main shape for each being calculated sub-shape separately.
1277 aFunction->SetValue(aValue);
1279 // Put this subshape in the list of sub-shapes of theMainShape
1280 aMainShape->AddSubShapeReference(aFunction);
1283 if (!anObj.IsNull()) {
1284 aSeq->Append(anObj);
1286 // for python command
1287 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
1288 anAsciiList += anEntry;
1293 //Make a Python command
1294 anAsciiList.Trunc(anAsciiList.Length() - 1);
1296 GEOM::TPythonDump pd (aMainShape, /*append=*/true);
1297 pd << "[" << anAsciiList.ToCString() << "] = geompy.";
1298 switch (theExplodeType) {
1299 case EXPLODE_NEW_EXCLUDE_MAIN:
1300 pd << "ExtractShapes(" << theShape << ", "
1301 << TopAbs_ShapeEnum(theShapeType) << ", " << (isSorted ? "True" : "False") << ")";
1303 case EXPLODE_NEW_INCLUDE_MAIN:
1304 pd << "SubShapeAll" << (isSorted ? "SortedCentres(" : "(")
1305 << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
1307 case EXPLODE_OLD_INCLUDE_MAIN:
1308 pd << "SubShapeAll" << (isSorted ? "Sorted(" : "(")
1309 << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
1318 //=============================================================================
1322 //=============================================================================
1323 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::SubShapeAllIDs
1324 (Handle(GEOM_Object) theShape,
1325 const Standard_Integer theShapeType,
1326 const Standard_Boolean isSorted,
1327 const ExplodeType theExplodeType)
1331 if (theShape.IsNull()) return NULL;
1332 TopoDS_Shape aShape = theShape->GetValue();
1333 if (aShape.IsNull()) return NULL;
1335 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
1336 TopTools_MapOfShape mapShape;
1337 TopTools_ListOfShape listShape;
1339 if (aShape.ShapeType() == TopAbs_COMPOUND &&
1340 (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
1341 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPSOLID ||
1342 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPOUND))
1344 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
1345 for (; It.More(); It.Next()) {
1346 if (mapShape.Add(It.Value())) {
1347 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
1348 TopAbs_ShapeEnum(theShapeType) == It.Value().ShapeType()) {
1349 listShape.Append(It.Value());
1354 else if (theExplodeType != EXPLODE_NEW_EXCLUDE_MAIN || aShape.ShapeType() != theShapeType) // issue 0021079
1356 TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
1357 for (; exp.More(); exp.Next())
1358 if (mapShape.Add(exp.Current()))
1359 listShape.Append(exp.Current());
1362 if (listShape.IsEmpty()) {
1363 //SetErrorCode("The given shape has no sub-shapes of the requested type");
1364 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
1369 bool isOldSorting = false;
1370 if (theExplodeType == EXPLODE_OLD_INCLUDE_MAIN)
1371 isOldSorting = true;
1372 GEOMUtils::SortShapes(listShape, isOldSorting);
1375 TopTools_IndexedMapOfShape anIndices;
1376 TopExp::MapShapes(aShape, anIndices);
1377 Handle(TColStd_HArray1OfInteger) anArray;
1379 TopTools_ListIteratorOfListOfShape itSub (listShape);
1380 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
1381 TopoDS_Shape aValue = itSub.Value();
1382 aSeq->Append(anIndices.FindIndex(aValue));
1385 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
1387 //Make a Python command
1388 GEOM::TPythonDump pd (aFunction, /*append=*/true);
1389 pd << "listSubShapeIDs = geompy.SubShapeAll";
1390 switch (theExplodeType) {
1391 case EXPLODE_NEW_EXCLUDE_MAIN:
1393 case EXPLODE_NEW_INCLUDE_MAIN:
1394 pd << (isSorted ? "SortedCentresIDs(" : "IDs(")
1395 << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
1397 case EXPLODE_OLD_INCLUDE_MAIN:
1398 pd << (isSorted ? "SortedIDs(" : "IDs(")
1399 << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
1408 //=============================================================================
1412 //=============================================================================
1413 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetSubShape
1414 (Handle(GEOM_Object) theMainShape,
1415 const Standard_Integer theID)
1419 if (theMainShape.IsNull()) return NULL;
1421 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
1422 anArray->SetValue(1, theID);
1423 Handle(GEOM_Object) anObj = GetEngine()->AddSubShape(theMainShape, anArray,true);
1424 if (anObj.IsNull()) {
1425 SetErrorCode("Can not get a sub-shape with the given ID");
1429 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1431 //Make a Python command
1432 GEOM::TPythonDump(aFunction) << anObj << " = geompy.GetSubShape("
1433 << theMainShape << ", [" << theID << "])";
1439 //=============================================================================
1443 //=============================================================================
1444 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::MakeSubShapes
1445 (Handle(GEOM_Object) theMainShape,
1446 Handle(TColStd_HArray1OfInteger) theIndices)
1450 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1452 if (!theIndices->Length()) {
1453 SetErrorCode(NOT_FOUND_ANY);
1457 if (theMainShape.IsNull()) return NULL;
1458 TopoDS_Shape aShape = theMainShape->GetValue();
1459 if (aShape.IsNull()) return NULL;
1461 Handle(GEOM_Function) aMainShape = theMainShape->GetLastFunction();
1463 TopTools_IndexedMapOfShape anIndices;
1464 TopExp::MapShapes(aShape, anIndices);
1466 Handle(TColStd_HArray1OfInteger) anArray;
1467 Handle(GEOM_Object) anObj;
1469 TCollection_AsciiString anAsciiList, anEntry;
1470 Standard_Integer i, low = theIndices->Lower(), up = theIndices->Upper();
1471 for (i = low; i <= up; i++) {
1472 int id = theIndices->Value(i);
1473 if (1 <= id && id <= anIndices.Extent()) {
1474 TopoDS_Shape aValue = anIndices.FindKey(id);
1475 anArray = new TColStd_HArray1OfInteger(1,1);
1476 anArray->SetValue(1, id);
1478 anObj = GetEngine()->AddObject(GetDocID(), GEOM_SUBSHAPE);
1479 if (!anObj.IsNull()) {
1480 Handle(GEOM_Function) aFunction = anObj->AddFunction(GEOM_Object::GetSubShapeID(), 1);
1481 if (aFunction.IsNull()) return aSeq;
1483 GEOM_ISubShape aSSI (aFunction);
1484 aSSI.SetMainShape(aMainShape);
1485 aSSI.SetIndices(anArray);
1487 // Set function value directly, as we know it.
1488 // Usage of Solver here would lead to significant loss of time,
1489 // because GEOM_SubShapeDriver will build TopTools_IndexedMapOfShape
1490 // on the main shape for each being calculated sub-shape separately.
1491 aFunction->SetValue(aValue);
1493 // Put this sub-shape in the list of sub-shapes of theMainShape
1494 aMainShape->AddSubShapeReference(aFunction);
1496 aSeq->Append(anObj);
1498 // for python command
1499 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
1500 anAsciiList += anEntry;
1506 //Make a Python command
1507 anAsciiList.Trunc(anAsciiList.Length() - 1);
1509 GEOM::TPythonDump pd (aMainShape, /*append=*/true);
1510 pd << "[" << anAsciiList.ToCString() << "] = geompy.SubShapes("
1511 << theMainShape << ", [" ;
1512 for (i = low; i <= up - 1; i++) {
1513 pd << theIndices->Value(i) << ", ";
1515 pd << theIndices->Value(up) << "])";
1522 //=============================================================================
1526 //=============================================================================
1527 Standard_Integer GEOMImpl_IShapesOperations::GetSubShapeIndex (Handle(GEOM_Object) theMainShape,
1528 Handle(GEOM_Object) theSubShape)
1532 TopoDS_Shape aMainShape = theMainShape->GetValue();
1533 TopoDS_Shape aSubShape = theSubShape->GetValue();
1535 if (aMainShape.IsNull() || aSubShape.IsNull()) return -1;
1537 TopTools_IndexedMapOfShape anIndices;
1538 TopExp::MapShapes(aMainShape, anIndices);
1539 // if (anIndices.Contains(aSubShape)) {
1540 // SetErrorCode(OK);
1541 // return anIndices.FindIndex(aSubShape);
1543 int id = anIndices.FindIndex(aSubShape);
1554 //=============================================================================
1556 * GetSubShapeIndices
1558 //=============================================================================
1559 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetSubShapesIndices (Handle(GEOM_Object) theMainShape,
1560 std::list<Handle(GEOM_Object)> theSubShapes)
1562 MESSAGE("GEOMImpl_IShapesOperations::GetSubShapesIndices")
1565 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
1567 TopoDS_Shape aMainShape = theMainShape->GetValue();
1568 if (aMainShape.IsNull())
1570 MESSAGE("NULL main shape")
1574 TopTools_IndexedMapOfShape anIndices;
1575 TopExp::MapShapes(aMainShape, anIndices);
1577 std::list<Handle(GEOM_Object)>::iterator it;
1578 for (it=theSubShapes.begin(); it != theSubShapes.end(); ++it)
1580 TopoDS_Shape aSubShape = (*it)->GetValue();
1581 if (aSubShape.IsNull())
1583 MESSAGE("NULL subshape")
1586 int id = anIndices.FindIndex(aSubShape);
1595 //=============================================================================
1599 //=============================================================================
1600 Standard_Integer GEOMImpl_IShapesOperations::GetTopologyIndex (Handle(GEOM_Object) theMainShape,
1601 Handle(GEOM_Object) theSubShape)
1605 TopoDS_Shape aMainShape = theMainShape->GetValue();
1606 TopoDS_Shape aSubShape = theSubShape->GetValue();
1608 if (aMainShape.IsNull() || aSubShape.IsNull()) {
1609 SetErrorCode("Null argument shape given");
1614 if (aSubShape.ShapeType() == TopAbs_COMPOUND) {
1616 TopTools_ListOfShape CL;
1617 CL.Append(aMainShape);
1618 TopTools_ListIteratorOfListOfShape itC;
1619 for (itC.Initialize(CL); itC.More(); itC.Next()) {
1620 for (it.Initialize(itC.Value()); it.More(); it.Next()) {
1621 if (it.Value().ShapeType() == TopAbs_COMPOUND) {
1622 if (it.Value().IsSame(aSubShape))
1626 CL.Append(it.Value());
1631 TopExp_Explorer anExp (aMainShape, aSubShape.ShapeType());
1632 TopTools_MapOfShape M;
1633 for (; anExp.More(); anExp.Next()) {
1634 if (M.Add(anExp.Current())) {
1635 if (anExp.Current().IsSame(aSubShape))
1642 SetErrorCode("The sub-shape does not belong to the main shape");
1646 //=============================================================================
1648 * GetShapeTypeString
1650 //=============================================================================
1651 TCollection_AsciiString GEOMImpl_IShapesOperations::GetShapeTypeString (Handle(GEOM_Object) theShape)
1655 TCollection_AsciiString aTypeName ("Null Shape");
1657 TopoDS_Shape aShape = theShape->GetValue();
1658 if (aShape.IsNull())
1661 switch (aShape.ShapeType() )
1663 case TopAbs_COMPOUND:
1664 aTypeName = "Compound";
1666 case TopAbs_COMPSOLID:
1667 aTypeName = "Compound Solid";
1670 aTypeName = "Solid";
1673 aTypeName = "Shell";
1677 BRepAdaptor_Surface surf (TopoDS::Face(aShape));
1678 if (surf.GetType() == GeomAbs_Plane)
1679 aTypeName = "Plane";
1680 else if (surf.GetType() == GeomAbs_Cylinder)
1681 aTypeName = "Cylindrical Face";
1682 else if (surf.GetType() == GeomAbs_Sphere)
1683 aTypeName = "Spherical Face";
1684 else if (surf.GetType() == GeomAbs_Torus)
1685 aTypeName = "Toroidal Face";
1686 else if (surf.GetType() == GeomAbs_Cone)
1687 aTypeName = "Conical Face";
1689 aTypeName = "GEOM::FACE";
1697 BRepAdaptor_Curve curv (TopoDS::Edge(aShape));
1698 if (curv.GetType() == GeomAbs_Line) {
1699 if ((Abs(curv.FirstParameter()) >= 1E6) ||
1700 (Abs(curv.LastParameter()) >= 1E6))
1704 } else if (curv.GetType() == GeomAbs_Circle) {
1705 if (curv.IsClosed())
1706 aTypeName = "Circle";
1715 aTypeName = "Vertex";
1718 aTypeName = "Shape";
1721 aTypeName = "Shape of unknown type";
1727 //=============================================================================
1731 //=============================================================================
1732 Standard_Integer GEOMImpl_IShapesOperations::NumberOfSubShapes
1733 (Handle(GEOM_Object) theShape,
1734 const Standard_Integer theShapeType)
1737 Standard_Integer nbShapes = 0;
1739 if (theShape.IsNull()) return -1;
1740 TopoDS_Shape aShape = theShape->GetValue();
1741 if (aShape.IsNull()) return -1;
1744 TopTools_MapOfShape mapShape;
1746 if (aShape.ShapeType() == TopAbs_COMPOUND &&
1747 (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
1748 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPSOLID ||
1749 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPOUND)) {
1750 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
1751 for (; It.More(); It.Next()) {
1752 if (mapShape.Add(It.Value())) {
1753 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
1754 TopAbs_ShapeEnum(theShapeType) == It.Value().ShapeType()) {
1760 TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
1761 for (; exp.More(); exp.Next())
1762 if (mapShape.Add(exp.Current()))
1769 int iType, nbTypes [TopAbs_SHAPE];
1770 for (iType = 0; iType < TopAbs_SHAPE; ++iType)
1772 nbTypes[aShape.ShapeType()]++;
1774 TopTools_MapOfShape aMapOfShape;
1775 aMapOfShape.Add(aShape);
1776 TopTools_ListOfShape aListOfShape;
1777 aListOfShape.Append(aShape);
1779 TopTools_ListIteratorOfListOfShape itL (aListOfShape);
1780 for (; itL.More(); itL.Next()) {
1781 TopoDS_Iterator it (itL.Value());
1782 for (; it.More(); it.Next()) {
1783 TopoDS_Shape s = it.Value();
1784 if (aMapOfShape.Add(s)) {
1785 aListOfShape.Append(s);
1786 nbTypes[s.ShapeType()]++;
1791 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE)
1792 nbShapes = aMapOfShape.Extent();
1794 nbShapes = nbTypes[theShapeType];
1796 catch (Standard_Failure) {
1797 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1798 SetErrorCode(aFail->GetMessageString());
1806 //=============================================================================
1810 //=============================================================================
1811 Handle(GEOM_Object) GEOMImpl_IShapesOperations::ReverseShape(Handle(GEOM_Object) theShape)
1815 if (theShape.IsNull()) return NULL;
1818 //Add a new reversed object
1819 Handle(GEOM_Object) aReversed = GetEngine()->AddObject(GetDocID(), theShape->GetType());
1821 //Add a new Revese function
1822 Handle(GEOM_Function) aFunction;
1823 aFunction = aReversed->AddFunction(GEOMImpl_ShapeDriver::GetID(), REVERSE_ORIENTATION);
1824 if (aFunction.IsNull()) return NULL;
1826 //Check if the function is set correctly
1827 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
1829 GEOMImpl_IShapes aSI (aFunction);
1831 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
1832 if (aRefShape.IsNull()) return NULL;
1834 aSI.SetBase(aRefShape);
1836 //Compute the sub-shape value
1839 if (!GetSolver()->ComputeFunction(aFunction)) {
1840 SetErrorCode("Shape driver failed to reverse shape");
1844 catch (Standard_Failure) {
1845 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1846 SetErrorCode(aFail->GetMessageString());
1850 //Make a Python command
1851 GEOM::TPythonDump(aFunction) << aReversed
1852 << " = geompy.ChangeOrientation(" << theShape << ")";
1857 Handle(GEOM_Object) aReversed;
1859 GEOM_Engine* anEngine = GetEngine();
1860 //GEOMImpl_Gen* aGen = dynamic_cast<GEOMImpl_Gen*>(anEngine);
1861 GEOMImpl_Gen* aGen = (GEOMImpl_Gen*)anEngine;
1864 GEOMImpl_IHealingOperations* anIHealingOperations =
1865 aGen->GetIHealingOperations(GetDocID());
1866 aReversed = anIHealingOperations->ChangeOrientationCopy(theShape);
1867 SetErrorCode(anIHealingOperations->GetErrorCode());
1873 //=============================================================================
1877 //=============================================================================
1878 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetFreeFacesIDs
1879 (Handle(GEOM_Object) theShape)
1883 if (theShape.IsNull()) return NULL;
1884 TopoDS_Shape aShape = theShape->GetValue();
1885 if (aShape.IsNull()) return NULL;
1887 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
1889 TopTools_IndexedDataMapOfShapeListOfShape mapFaceBlocks;
1890 GEOMImpl_Block6Explorer::MapShapesAndAncestors
1891 (aShape, TopAbs_FACE, TopAbs_SOLID, mapFaceBlocks);
1893 Standard_Integer ind = 1, nbFaces = mapFaceBlocks.Extent();
1896 SetErrorCode("The given shape has no faces");
1900 TopTools_IndexedMapOfShape anIndices;
1901 TopExp::MapShapes(aShape, anIndices);
1903 Standard_Integer id;
1904 for (; ind <= nbFaces; ind++) {
1905 if (mapFaceBlocks.FindFromIndex(ind).Extent() != 2) {
1906 id = anIndices.FindIndex(mapFaceBlocks.FindKey(ind));
1911 //The explode doesn't change object so no new function is required.
1912 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
1914 //Make a Python command
1915 GEOM::TPythonDump(aFunction, /*append=*/true)
1916 << "listFreeFacesIDs = geompy.GetFreeFacesIDs(" << theShape << ")";
1922 //=======================================================================
1923 //function : GetSharedShapes
1925 //=======================================================================
1926 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetSharedShapes
1927 (Handle(GEOM_Object) theShape1,
1928 Handle(GEOM_Object) theShape2,
1929 const Standard_Integer theShapeType)
1933 if (theShape1.IsNull() || theShape2.IsNull()) return NULL;
1935 TopoDS_Shape aShape1 = theShape1->GetValue();
1936 TopoDS_Shape aShape2 = theShape2->GetValue();
1938 if (aShape1.IsNull() || aShape2.IsNull()) return NULL;
1940 TopTools_IndexedMapOfShape anIndices;
1941 TopExp::MapShapes(aShape1, anIndices);
1942 Handle(TColStd_HArray1OfInteger) anArray;
1944 TopTools_IndexedMapOfShape mapShape1;
1945 TopExp::MapShapes(aShape1, TopAbs_ShapeEnum(theShapeType), mapShape1);
1947 Handle(GEOM_Object) anObj;
1948 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1949 TCollection_AsciiString anAsciiList, anEntry;
1951 TopTools_MapOfShape mapShape2;
1952 TopExp_Explorer exp (aShape2, TopAbs_ShapeEnum(theShapeType));
1953 for (; exp.More(); exp.Next()) {
1954 TopoDS_Shape aSS = exp.Current();
1955 if (mapShape2.Add(aSS) && mapShape1.Contains(aSS)) {
1956 anArray = new TColStd_HArray1OfInteger(1,1);
1957 anArray->SetValue(1, anIndices.FindIndex(aSS));
1958 anObj = GetEngine()->AddSubShape(theShape1, anArray);
1959 aSeq->Append(anObj);
1961 // for python command
1962 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
1963 anAsciiList += anEntry;
1968 if (aSeq->IsEmpty()) {
1969 SetErrorCode("The given shapes have no shared sub-shapes of the requested type");
1973 //Make a Python command
1974 anAsciiList.Trunc(anAsciiList.Length() - 1);
1976 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1978 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
1979 << "] = geompy.GetSharedShapes(" << theShape1 << ", "
1980 << theShape2 << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
1986 //=======================================================================
1987 //function : GetSharedShapes
1989 //=======================================================================
1990 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetSharedShapes
1991 (std::list<Handle(GEOM_Object)> theShapes,
1992 const Standard_Integer theShapeType)
1996 int aLen = theShapes.size();
1997 if (aLen < 1) return NULL;
2000 std::list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
2002 Handle(GEOM_Object) aMainObj = (*it++);
2003 Handle(GEOM_Function) aMainShape = aMainObj->GetLastFunction();
2004 if (aMainShape.IsNull()) {
2005 SetErrorCode("NULL shape for GetSharedShapes");
2009 TopoDS_Shape aShape1 = aMainShape->GetValue();
2010 if (aShape1.IsNull()) return NULL;
2012 TopTools_IndexedMapOfShape anIndices;
2013 TopExp::MapShapes(aShape1, anIndices);
2015 TopTools_IndexedMapOfShape mapSelected;
2016 TopExp::MapShapes(aShape1, TopAbs_ShapeEnum(theShapeType), mapSelected);
2018 // Find shared shapes
2020 TopoDS_Compound aCurrSelection;
2022 for (; it != theShapes.end(); it++, ind++) {
2023 Handle(GEOM_Function) aRefShape = (*it)->GetLastFunction();
2024 if (aRefShape.IsNull()) {
2025 SetErrorCode("NULL shape for GetSharedShapes");
2029 TopoDS_Compound aCompound;
2030 B.MakeCompound(aCompound);
2032 TopoDS_Shape aShape2 = aRefShape->GetValue();
2033 if (aShape2.IsNull()) return NULL;
2035 TopTools_MapOfShape mapShape2;
2036 TopExp_Explorer exp (aShape2, TopAbs_ShapeEnum(theShapeType));
2037 for (; exp.More(); exp.Next()) {
2038 TopoDS_Shape aSS = exp.Current();
2039 if (mapShape2.Add(aSS) && mapSelected.Contains(aSS)) {
2040 B.Add(aCompound, aSS);
2044 mapSelected.Clear();
2045 TopExp::MapShapes(aCompound, TopAbs_ShapeEnum(theShapeType), mapSelected);
2046 aCurrSelection = aCompound;
2049 // Create GEOM_Object for each found shared shape (collected in aCurrSelection)
2050 Handle(GEOM_Object) anObj;
2051 Handle(TColStd_HArray1OfInteger) anArray;
2052 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
2053 TCollection_AsciiString anAsciiList, anEntry;
2055 TopoDS_Iterator itSel (aCurrSelection, Standard_True, Standard_True);
2056 for (; itSel.More(); itSel.Next()) {
2057 anArray = new TColStd_HArray1OfInteger(1,1);
2058 anArray->SetValue(1, anIndices.FindIndex(itSel.Value()));
2059 anObj = GetEngine()->AddSubShape(aMainObj, anArray);
2060 aSeq->Append(anObj);
2062 // for python command
2063 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
2064 anAsciiList += anEntry;
2068 if (aSeq->IsEmpty()) {
2069 SetErrorCode("The given shapes have no shared sub-shapes of the requested type");
2073 // Make a Python command
2074 anAsciiList.Trunc(anAsciiList.Length() - 1);
2076 // IPAL22904: TC6.5.0: order of python commands is wrong after dump study
2077 Handle(TColStd_HSequenceOfTransient) anObjects = new TColStd_HSequenceOfTransient;
2078 for( it = theShapes.begin(); it != theShapes.end(); it++ )
2080 Handle(GEOM_Object) anObj = *it;
2081 if( !anObj.IsNull() )
2082 anObjects->Append( anObj );
2085 // Get the function of the latest published object
2086 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast( anObjects )->GetLastFunction();
2087 if( aFunction.IsNull() ) // just in case
2088 aFunction = aMainShape;
2090 GEOM::TPythonDump pd (aFunction, /*append=*/true);
2091 pd << "[" << anAsciiList.ToCString()
2092 << "] = geompy.GetSharedShapesMulti([";
2094 it = theShapes.begin();
2096 while (it != theShapes.end()) {
2097 pd << ", " << (*it++);
2100 pd << "], " << TopAbs_ShapeEnum(theShapeType) << ")";
2106 //=============================================================================
2110 //=============================================================================
2111 static GEOM::TPythonDump& operator<< (GEOM::TPythonDump& theDump,
2112 const GEOMAlgo_State theState)
2115 case GEOMAlgo_ST_IN:
2116 theDump << "GEOM.ST_IN";
2118 case GEOMAlgo_ST_OUT:
2119 theDump << "GEOM.ST_OUT";
2121 case GEOMAlgo_ST_ON:
2122 theDump << "GEOM.ST_ON";
2124 case GEOMAlgo_ST_ONIN:
2125 theDump << "GEOM.ST_ONIN";
2127 case GEOMAlgo_ST_ONOUT:
2128 theDump << "GEOM.ST_ONOUT";
2131 theDump << "GEOM.ST_UNKNOWN";
2137 //=======================================================================
2138 //function : checkTypeShapesOn
2140 * \brief Checks if theShapeType parameter of GetShapesOnXXX() is OK
2141 * \param theShapeType - the shape type to check
2142 * \retval bool - result of the check
2144 //=======================================================================
2145 bool GEOMImpl_IShapesOperations::checkTypeShapesOn(const Standard_Integer theShapeType)
2147 if (theShapeType != TopAbs_VERTEX &&
2148 theShapeType != TopAbs_EDGE &&
2149 theShapeType != TopAbs_FACE &&
2150 theShapeType != TopAbs_SOLID) {
2151 SetErrorCode("Only solids, vertices, edges or faces can be found by this method");
2157 //=======================================================================
2158 //function : makePlane
2160 * \brief Creates Geom_Plane
2161 * \param theAx1 - shape object defining plane parameters
2162 * \retval Handle(Geom_Surface) - resulting surface
2164 //=======================================================================
2165 Handle(Geom_Surface) GEOMImpl_IShapesOperations::makePlane(const TopoDS_Shape& anAx1)
2167 if (anAx1.ShapeType() != TopAbs_EDGE) return NULL;
2168 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
2169 TopoDS_Vertex V1, V2;
2170 TopExp::Vertices(anEdge, V1, V2, Standard_True);
2171 if (V1.IsNull() || V2.IsNull()) {
2172 SetErrorCode("Bad edge given for the plane normal vector");
2175 gp_Pnt aLoc = BRep_Tool::Pnt(V1);
2176 gp_Vec aVec (aLoc, BRep_Tool::Pnt(V2));
2177 if (aVec.Magnitude() < Precision::Confusion()) {
2178 SetErrorCode("Vector with null magnitude given");
2181 return new Geom_Plane(aLoc, aVec);
2184 //=======================================================================
2185 //function : makeCylinder
2187 * \brief Creates Geom_CylindricalSurface
2188 * \param theAx1 - edge defining cylinder axis
2189 * \param theRadius - cylinder radius
2190 * \retval Handle(Geom_Surface) - resulting surface
2192 //=======================================================================
2193 Handle(Geom_Surface) GEOMImpl_IShapesOperations::makeCylinder(const TopoDS_Shape& anAxis,
2194 const Standard_Real theRadius)
2196 //Axis of the cylinder
2197 if (anAxis.ShapeType() != TopAbs_EDGE) {
2198 SetErrorCode("Not an edge given for the axis");
2201 TopoDS_Edge anEdge = TopoDS::Edge(anAxis);
2202 TopoDS_Vertex V1, V2;
2203 TopExp::Vertices(anEdge, V1, V2, Standard_True);
2204 if (V1.IsNull() || V2.IsNull()) {
2205 SetErrorCode("Bad edge given for the axis");
2208 gp_Pnt aLoc = BRep_Tool::Pnt(V1);
2209 gp_Vec aVec (aLoc, BRep_Tool::Pnt(V2));
2210 if (aVec.Magnitude() < Precision::Confusion()) {
2211 SetErrorCode("Vector with null magnitude given");
2215 gp_Ax3 anAx3 (aLoc, aVec);
2216 return new Geom_CylindricalSurface(anAx3, theRadius);
2219 //=======================================================================
2220 //function : getShapesOnBoxIDs
2222 * \brief Find IDs of sub-shapes complying with given status about surface
2223 * \param theBox - the box to check state of sub-shapes against
2224 * \param theShape - the shape to explore
2225 * \param theShapeType - type of sub-shape of theShape
2226 * \param theState - required state
2227 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
2229 //=======================================================================
2230 Handle(TColStd_HSequenceOfInteger)
2231 GEOMImpl_IShapesOperations::getShapesOnBoxIDs(const Handle(GEOM_Object)& theBox,
2232 const Handle(GEOM_Object)& theShape,
2233 const Standard_Integer theShapeType,
2234 GEOMAlgo_State theState)
2236 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
2238 TopoDS_Shape aBox = theBox->GetValue();
2239 TopoDS_Shape aShape = theShape->GetValue();
2241 // Check presence of triangulation, build if need
2242 if (!GEOMUtils::CheckTriangulation(aShape)) {
2243 SetErrorCode("Cannot build triangulation on the shape");
2248 GEOMAlgo_FinderShapeOn2 aFinder;
2249 Standard_Real aTol = 0.0001; // default value
2251 Handle(GEOMAlgo_ClsfBox) aClsfBox = new GEOMAlgo_ClsfBox;
2252 aClsfBox->SetBox(aBox);
2254 aFinder.SetShape(aShape);
2255 aFinder.SetTolerance(aTol);
2256 aFinder.SetClsf(aClsfBox);
2257 aFinder.SetShapeType( (TopAbs_ShapeEnum)theShapeType );
2258 aFinder.SetState(theState);
2261 // Interprete results
2262 Standard_Integer iErr = aFinder.ErrorStatus();
2263 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
2265 MESSAGE(" iErr : " << iErr);
2266 TCollection_AsciiString aMsg (" iErr : ");
2267 aMsg += TCollection_AsciiString(iErr);
2271 Standard_Integer iWrn = aFinder.WarningStatus();
2272 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
2274 MESSAGE(" *** iWrn : " << iWrn);
2277 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
2279 if (listSS.Extent() < 1) {
2280 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
2281 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
2285 // Fill sequence of object IDs
2286 aSeqOfIDs = new TColStd_HSequenceOfInteger;
2288 TopTools_IndexedMapOfShape anIndices;
2289 TopExp::MapShapes(aShape, anIndices);
2291 TopTools_ListIteratorOfListOfShape itSub (listSS);
2292 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
2293 int id = anIndices.FindIndex(itSub.Value());
2294 aSeqOfIDs->Append(id);
2300 //=======================================================================
2301 //function : GetShapesOnBoxIDs
2303 * \brief Find sub-shapes complying with given status about surface
2304 * \param theBox - the box to check state of sub-shapes against
2305 * \param theShape - the shape to explore
2306 * \param theShapeType - type of sub-shape of theShape
2307 * \param theState - required state
2308 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
2310 //=======================================================================
2311 Handle(TColStd_HSequenceOfInteger)
2312 GEOMImpl_IShapesOperations::GetShapesOnBoxIDs(const Handle(GEOM_Object)& theBox,
2313 const Handle(GEOM_Object)& theShape,
2314 const Standard_Integer theShapeType,
2315 GEOMAlgo_State theState)
2317 // Find sub-shapes ids
2318 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2319 getShapesOnBoxIDs (theBox, theShape, theShapeType, theState);
2320 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2323 // The GetShapesOnBox() doesn't change object so no new function is required.
2324 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theBox)->GetLastFunction();
2326 // Make a Python command
2327 GEOM::TPythonDump(aFunction, /*append=*/true)
2328 << "listShapesOnBoxIDs = geompy.GetShapesOnBoxIDs("
2331 << TopAbs_ShapeEnum(theShapeType) << ", "
2338 //=======================================================================
2339 //function : GetShapesOnBox
2341 * \brief Find sub-shapes complying with given status about surface
2342 * \param theBox - the box to check state of sub-shapes against
2343 * \param theShape - the shape to explore
2344 * \param theShapeType - type of sub-shape of theShape
2345 * \param theState - required state
2346 * \retval Handle(TColStd_HSequenceOfTransient) - found sub-shapes
2348 //=======================================================================
2349 Handle(TColStd_HSequenceOfTransient)
2350 GEOMImpl_IShapesOperations::GetShapesOnBox(const Handle(GEOM_Object)& theBox,
2351 const Handle(GEOM_Object)& theShape,
2352 const Standard_Integer theShapeType,
2353 GEOMAlgo_State theState)
2355 // Find sub-shapes ids
2356 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2357 getShapesOnBoxIDs (theBox, theShape, theShapeType, theState);
2358 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2361 // Find objects by indices
2362 TCollection_AsciiString anAsciiList;
2363 Handle(TColStd_HSequenceOfTransient) aSeq;
2364 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
2365 if ( aSeq.IsNull() || aSeq->IsEmpty() )
2368 // Make a Python command
2370 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2371 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2373 GEOM::TPythonDump(aFunction)
2374 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnBox("
2377 << TopAbs_ShapeEnum(theShapeType) << ", "
2384 //=======================================================================
2385 //function : getShapesOnShapeIDs
2387 * \brief Find IDs of sub-shapes complying with given status about surface
2388 * \param theCheckShape - the shape to check state of sub-shapes against
2389 * \param theShape - the shape to explore
2390 * \param theShapeType - type of sub-shape of theShape
2391 * \param theState - required state
2392 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
2394 //=======================================================================
2395 Handle(TColStd_HSequenceOfInteger)
2396 GEOMImpl_IShapesOperations::getShapesOnShapeIDs
2397 (const Handle(GEOM_Object)& theCheckShape,
2398 const Handle(GEOM_Object)& theShape,
2399 const Standard_Integer theShapeType,
2400 GEOMAlgo_State theState)
2402 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
2404 TopoDS_Shape aCheckShape = theCheckShape->GetValue();
2405 TopoDS_Shape aShape = theShape->GetValue();
2406 TopTools_ListOfShape res;
2408 // Check presence of triangulation, build if need
2409 if (!GEOMUtils::CheckTriangulation(aShape)) {
2410 SetErrorCode("Cannot build triangulation on the shape");
2415 GEOMAlgo_FinderShapeOn2 aFinder;
2416 Standard_Real aTol = 0.0001; // default value
2418 Handle(GEOMAlgo_ClsfSolid) aClsfSolid = new GEOMAlgo_ClsfSolid;
2419 aClsfSolid->SetShape(aCheckShape);
2421 aFinder.SetShape(aShape);
2422 aFinder.SetTolerance(aTol);
2423 aFinder.SetClsf(aClsfSolid);
2424 aFinder.SetShapeType( (TopAbs_ShapeEnum)theShapeType );
2425 aFinder.SetState(theState);
2428 // Interprete results
2429 Standard_Integer iErr = aFinder.ErrorStatus();
2430 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
2433 SetErrorCode("theCheckShape must be a solid");
2436 MESSAGE(" iErr : " << iErr);
2437 TCollection_AsciiString aMsg (" iErr : ");
2438 aMsg += TCollection_AsciiString(iErr);
2443 Standard_Integer iWrn = aFinder.WarningStatus();
2444 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
2446 MESSAGE(" *** iWrn : " << iWrn);
2449 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
2451 if (listSS.Extent() < 1) {
2452 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
2453 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
2456 // Fill sequence of object IDs
2457 aSeqOfIDs = new TColStd_HSequenceOfInteger;
2459 TopTools_IndexedMapOfShape anIndices;
2460 TopExp::MapShapes(aShape, anIndices);
2462 TopTools_ListIteratorOfListOfShape itSub (listSS);
2463 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
2464 int id = anIndices.FindIndex(itSub.Value());
2465 aSeqOfIDs->Append(id);
2471 //=======================================================================
2472 //function : GetShapesOnShapeIDs
2474 * \brief Find sub-shapes complying with given status about surface
2475 * \param theCheckShape - the shape to check state of sub-shapes against
2476 * \param theShape - the shape to explore
2477 * \param theShapeType - type of sub-shape of theShape
2478 * \param theState - required state
2479 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
2481 //=======================================================================
2482 Handle(TColStd_HSequenceOfInteger)
2483 GEOMImpl_IShapesOperations::GetShapesOnShapeIDs
2484 (const Handle(GEOM_Object)& theCheckShape,
2485 const Handle(GEOM_Object)& theShape,
2486 const Standard_Integer theShapeType,
2487 GEOMAlgo_State theState)
2489 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2490 getShapesOnShapeIDs (theCheckShape, theShape, theShapeType, theState);
2492 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2495 // The GetShapesOnShape() doesn't change object so no new function is required.
2496 Handle(GEOM_Function) aFunction =
2497 GEOM::GetCreatedLast(theShape,theCheckShape)->GetLastFunction();
2499 // Make a Python command
2500 GEOM::TPythonDump(aFunction, /*append=*/true)
2501 << "listShapesOnBoxIDs = geompy.GetShapesOnShapeIDs("
2502 << theCheckShape << ", "
2504 << TopAbs_ShapeEnum(theShapeType) << ", "
2511 //=======================================================================
2512 //function : GetShapesOnShape
2514 * \brief Find sub-shapes complying with given status about surface
2515 * \param theCheckShape - the shape to check state of sub-shapes against
2516 * \param theShape - the shape to explore
2517 * \param theShapeType - type of sub-shape of theShape
2518 * \param theState - required state
2519 * \retval Handle(TColStd_HSequenceOfTransient) - found sub-shapes
2521 //=======================================================================
2522 Handle(TColStd_HSequenceOfTransient)
2523 GEOMImpl_IShapesOperations::GetShapesOnShape
2524 (const Handle(GEOM_Object)& theCheckShape,
2525 const Handle(GEOM_Object)& theShape,
2526 const Standard_Integer theShapeType,
2527 GEOMAlgo_State theState)
2529 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2530 getShapesOnShapeIDs (theCheckShape, theShape, theShapeType, theState);
2531 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2534 // Find objects by indices
2535 TCollection_AsciiString anAsciiList;
2536 Handle(TColStd_HSequenceOfTransient) aSeq;
2537 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
2539 if ( aSeq.IsNull() || aSeq->IsEmpty() )
2542 // Make a Python command
2544 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2545 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2547 GEOM::TPythonDump(aFunction)
2548 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnShape("
2549 << theCheckShape << ", "
2551 << TopAbs_ShapeEnum(theShapeType) << ", "
2558 //=======================================================================
2559 //function : GetShapesOnShapeAsCompound
2560 //=======================================================================
2561 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetShapesOnShapeAsCompound
2562 (const Handle(GEOM_Object)& theCheckShape,
2563 const Handle(GEOM_Object)& theShape,
2564 const Standard_Integer theShapeType,
2565 GEOMAlgo_State theState)
2567 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2568 getShapesOnShapeIDs (theCheckShape, theShape, theShapeType, theState);
2570 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2573 // Find objects by indices
2574 TCollection_AsciiString anAsciiList;
2575 Handle(TColStd_HSequenceOfTransient) aSeq;
2576 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
2578 if ( aSeq.IsNull() || aSeq->IsEmpty() )
2581 TopoDS_Compound aCompound;
2583 B.MakeCompound(aCompound);
2585 for(; i<=aSeq->Length(); i++) {
2586 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(aSeq->Value(i));
2587 TopoDS_Shape aShape_i = anObj->GetValue();
2588 B.Add(aCompound,aShape_i);
2591 //Add a new result object
2592 Handle(GEOM_Object) aRes = GetEngine()->AddObject(GetDocID(), GEOM_SHAPES_ON_SHAPE);
2593 Handle(GEOM_Function) aFunction =
2594 aRes->AddFunction(GEOMImpl_ShapeDriver::GetID(), SHAPES_ON_SHAPE);
2595 aFunction->SetValue(aCompound);
2598 aSeq->Append( theCheckShape->GetLastFunction() );
2599 aSeq->Append( theShape->GetLastFunction() );
2601 GEOMImpl_IShapes aCI( aFunction );
2602 aCI.SetShapes( aSeq );
2603 aCI.SetSubShapeType( theShapeType );
2604 aCI.SetTolerance( theState );
2606 GEOM::TPythonDump(aFunction)
2607 << aRes << " = geompy.GetShapesOnShapeAsCompound("
2608 << theCheckShape << ", "
2610 << TopAbs_ShapeEnum(theShapeType) << ", "
2618 //=======================================================================
2619 //function : getShapesOnSurfaceIDs
2621 * \brief Find IDs of sub-shapes complying with given status about surface
2622 * \param theSurface - the surface to check state of sub-shapes against
2623 * \param theShape - the shape to explore
2624 * \param theShapeType - type of sub-shape of theShape
2625 * \param theState - required state
2626 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
2628 //=======================================================================
2629 Handle(TColStd_HSequenceOfInteger)
2630 GEOMImpl_IShapesOperations::getShapesOnSurfaceIDs(const Handle(Geom_Surface)& theSurface,
2631 const TopoDS_Shape& theShape,
2632 TopAbs_ShapeEnum theShapeType,
2633 GEOMAlgo_State theState)
2635 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
2637 // Check presence of triangulation, build if need
2638 if (!GEOMUtils::CheckTriangulation(theShape)) {
2639 SetErrorCode("Cannot build triangulation on the shape");
2643 // BEGIN: Mantis issue 0020961: Error on a pipe T-Shape
2644 // Compute tolerance
2645 Standard_Real T, VertMax = -RealLast();
2648 for (TopExp_Explorer ExV (theShape, TopAbs_VERTEX); ExV.More(); ExV.Next()) {
2649 TopoDS_Vertex Vertex = TopoDS::Vertex(ExV.Current());
2650 T = BRep_Tool::Tolerance(Vertex);
2655 catch (Standard_Failure) {
2656 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2657 SetErrorCode(aFail->GetMessageString());
2660 // END: Mantis issue 0020961
2663 GEOMAlgo_FinderShapeOn1 aFinder;
2664 //Standard_Real aTol = 0.0001; // default value
2665 Standard_Real aTol = VertMax; // Mantis issue 0020961
2667 aFinder.SetShape(theShape);
2668 aFinder.SetTolerance(aTol);
2669 aFinder.SetSurface(theSurface);
2670 aFinder.SetShapeType(theShapeType);
2671 aFinder.SetState(theState);
2673 // Sets the minimal number of inner points for the faces that do not have own
2674 // inner points at all (for e.g. rectangular planar faces have just 2 triangles).
2676 aFinder.SetNbPntsMin(3);
2677 // Sets the maximal number of inner points for edges or faces.
2678 // It is usefull for the cases when this number is very big (e.g =2000) to improve
2679 // the performance. If this value =0, all inner points will be taken into account.
2681 aFinder.SetNbPntsMax(100);
2685 // Interprete results
2686 Standard_Integer iErr = aFinder.ErrorStatus();
2687 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
2689 MESSAGE(" iErr : " << iErr);
2690 TCollection_AsciiString aMsg (" iErr : ");
2691 aMsg += TCollection_AsciiString(iErr);
2695 Standard_Integer iWrn = aFinder.WarningStatus();
2696 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
2698 MESSAGE(" *** iWrn : " << iWrn);
2701 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
2703 if (listSS.Extent() < 1) {
2704 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
2705 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
2709 // Fill sequence of object IDs
2710 aSeqOfIDs = new TColStd_HSequenceOfInteger;
2712 TopTools_IndexedMapOfShape anIndices;
2713 TopExp::MapShapes(theShape, anIndices);
2715 TopTools_ListIteratorOfListOfShape itSub (listSS);
2716 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
2717 int id = anIndices.FindIndex(itSub.Value());
2718 aSeqOfIDs->Append(id);
2724 //=======================================================================
2725 //function : getObjectsShapesOn
2727 * \brief Find shape objects and their entries by their ids
2728 * \param theShapeIDs - incoming shape ids
2729 * \param theShapeEntries - outgoing entries like "entry1, entry2, ..."
2730 * \retval Handle(TColStd_HSequenceOfTransient) - found shape objects
2732 //=======================================================================
2733 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::
2734 getObjectsShapesOn(const Handle(GEOM_Object)& theShape,
2735 const Handle(TColStd_HSequenceOfInteger)& theShapeIDs,
2736 TCollection_AsciiString & theShapeEntries)
2738 Handle(TColStd_HSequenceOfTransient) aSeq;
2740 if ( !theShapeIDs.IsNull() && theShapeIDs->Length() > 0 )
2742 aSeq = new TColStd_HSequenceOfTransient;
2743 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
2744 TCollection_AsciiString anEntry;
2745 for ( int i = 1; i <= theShapeIDs->Length(); ++i )
2747 anArray->SetValue(1, theShapeIDs->Value( i ));
2748 Handle(GEOM_Object) anObj = GetEngine()->AddSubShape(theShape, anArray);
2749 aSeq->Append( anObj );
2751 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
2752 if ( i != 1 ) theShapeEntries += ",";
2753 theShapeEntries += anEntry;
2759 //=======================================================================
2760 //function : getShapesOnSurface
2762 * \brief Find sub-shapes complying with given status about surface
2763 * \param theSurface - the surface to check state of sub-shapes against
2764 * \param theShape - the shape to explore
2765 * \param theShapeType - type of sub-shape of theShape
2766 * \param theState - required state
2767 * \param theShapeEntries - outgoing entries like "entry1, entry2, ..."
2768 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
2770 //=======================================================================
2771 Handle(TColStd_HSequenceOfTransient)
2772 GEOMImpl_IShapesOperations::getShapesOnSurface(const Handle(Geom_Surface)& theSurface,
2773 const Handle(GEOM_Object)& theShape,
2774 TopAbs_ShapeEnum theShapeType,
2775 GEOMAlgo_State theState,
2776 TCollection_AsciiString & theShapeEntries)
2778 // Find sub-shapes ids
2779 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2780 getShapesOnSurfaceIDs (theSurface, theShape->GetValue(), theShapeType, theState);
2781 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2784 return getObjectsShapesOn( theShape, aSeqOfIDs, theShapeEntries );
2787 //=============================================================================
2791 //=============================================================================
2792 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnPlane
2793 (const Handle(GEOM_Object)& theShape,
2794 const Standard_Integer theShapeType,
2795 const Handle(GEOM_Object)& theAx1,
2796 const GEOMAlgo_State theState)
2800 if (theShape.IsNull() || theAx1.IsNull()) return NULL;
2802 TopoDS_Shape aShape = theShape->GetValue();
2803 TopoDS_Shape anAx1 = theAx1->GetValue();
2805 if (aShape.IsNull() || anAx1.IsNull()) return NULL;
2807 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2808 if ( !checkTypeShapesOn( theShapeType ))
2812 Handle(Geom_Surface) aPlane = makePlane( anAx1 );
2813 if ( aPlane.IsNull() )
2817 TCollection_AsciiString anAsciiList;
2818 Handle(TColStd_HSequenceOfTransient) aSeq;
2819 aSeq = getShapesOnSurface( aPlane, theShape, aShapeType, theState, anAsciiList );
2820 if ( aSeq.IsNull() || aSeq->Length() == 0 )
2823 // Make a Python command
2825 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2826 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2828 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
2829 << "] = geompy.GetShapesOnPlane(" << theShape << ", "
2830 << aShapeType << ", " << theAx1 << ", " << theState << ")";
2836 //=============================================================================
2838 * GetShapesOnPlaneWithLocation
2840 //=============================================================================
2841 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnPlaneWithLocation
2842 (const Handle(GEOM_Object)& theShape,
2843 const Standard_Integer theShapeType,
2844 const Handle(GEOM_Object)& theAx1,
2845 const Handle(GEOM_Object)& thePnt,
2846 const GEOMAlgo_State theState)
2850 if (theShape.IsNull() || theAx1.IsNull() || thePnt.IsNull()) return NULL;
2852 TopoDS_Shape aShape = theShape->GetValue();
2853 TopoDS_Shape anAx1 = theAx1->GetValue();
2854 TopoDS_Shape anPnt = thePnt->GetValue();
2856 if (aShape.IsNull() || anAx1.IsNull() || anPnt.IsNull()) return NULL;
2858 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2859 if ( !checkTypeShapesOn( theShapeType ))
2863 if ( anAx1.ShapeType() != TopAbs_EDGE || anPnt.ShapeType() != TopAbs_VERTEX ) return NULL;
2864 TopoDS_Vertex V1, V2, V3;
2865 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
2866 TopExp::Vertices(anEdge, V1, V2, Standard_True);
2868 if (V1.IsNull() || V2.IsNull()) {
2869 SetErrorCode("Bad edge given for the plane normal vector");
2872 V3 = TopoDS::Vertex(anPnt);
2875 SetErrorCode("Bad vertex given for the plane location");
2878 gp_Pnt aLoc = BRep_Tool::Pnt(V3);
2879 gp_Vec aVec(BRep_Tool::Pnt(V1),BRep_Tool::Pnt(V2));
2881 if (aVec.Magnitude() < Precision::Confusion()) {
2882 SetErrorCode("Vector with null magnitude given");
2885 Handle(Geom_Surface) aPlane = new Geom_Plane(aLoc, aVec);
2887 if ( aPlane.IsNull() )
2891 TCollection_AsciiString anAsciiList;
2892 Handle(TColStd_HSequenceOfTransient) aSeq;
2893 aSeq = getShapesOnSurface( aPlane, theShape, aShapeType, theState, anAsciiList );
2894 if ( aSeq.IsNull() || aSeq->Length() == 0 )
2897 // Make a Python command
2899 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2900 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2902 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
2903 << "] = geompy.GetShapesOnPlaneWithLocation(" << theShape << ", "
2904 << aShapeType << ", " << theAx1 << ", "<< thePnt <<", " << theState << ")";
2910 //=============================================================================
2912 * GetShapesOnCylinder
2914 //=============================================================================
2915 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnCylinder
2916 (const Handle(GEOM_Object)& theShape,
2917 const Standard_Integer theShapeType,
2918 const Handle(GEOM_Object)& theAxis,
2919 const Standard_Real theRadius,
2920 const GEOMAlgo_State theState)
2924 if (theShape.IsNull() || theAxis.IsNull()) return NULL;
2926 TopoDS_Shape aShape = theShape->GetValue();
2927 TopoDS_Shape anAxis = theAxis->GetValue();
2929 if (aShape.IsNull() || anAxis.IsNull()) return NULL;
2931 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2932 if ( !checkTypeShapesOn( aShapeType ))
2935 // Create a cylinder surface
2936 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
2937 if ( aCylinder.IsNull() )
2941 TCollection_AsciiString anAsciiList;
2942 Handle(TColStd_HSequenceOfTransient) aSeq;
2943 aSeq = getShapesOnSurface( aCylinder, theShape, aShapeType, theState, anAsciiList );
2944 if ( aSeq.IsNull() || aSeq->Length() == 0 )
2947 // Make a Python command
2949 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2950 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2952 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
2953 << "] = geompy.GetShapesOnCylinder(" << theShape << ", " << aShapeType
2954 << ", " << theAxis << ", " << theRadius << ", " << theState << ")";
2960 //=============================================================================
2962 * GetShapesOnCylinderWithLocation
2964 //=============================================================================
2965 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnCylinderWithLocation
2966 (const Handle(GEOM_Object)& theShape,
2967 const Standard_Integer theShapeType,
2968 const Handle(GEOM_Object)& theAxis,
2969 const Handle(GEOM_Object)& thePnt,
2970 const Standard_Real theRadius,
2971 const GEOMAlgo_State theState)
2975 if (theShape.IsNull() || theAxis.IsNull() || thePnt.IsNull()) return NULL;
2977 TopoDS_Shape aShape = theShape->GetValue();
2978 TopoDS_Shape anAxis = theAxis->GetValue();
2979 TopoDS_Shape aPnt = thePnt->GetValue();
2981 if (aShape.IsNull() || anAxis.IsNull() || aPnt.IsNull()) return NULL;
2983 if (aPnt.ShapeType() != TopAbs_VERTEX )
2985 SetErrorCode("Bottom location point must be vertex");
2989 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2990 if ( !checkTypeShapesOn( aShapeType ))
2993 // Create a cylinder surface
2994 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
2995 if ( aCylinder.IsNull() )
2998 // translate the surface
2999 Handle(Geom_CylindricalSurface) aCylSurface =
3000 Handle(Geom_CylindricalSurface)::DownCast( aCylinder );
3001 if ( aCylSurface.IsNull() )
3003 SetErrorCode("Unexpected surface type instead of Geom_CylindricalSurface");
3006 gp_Pnt fromLoc = aCylSurface->Cylinder().Location();
3007 gp_Pnt toLoc = BRep_Tool::Pnt( TopoDS::Vertex( aPnt ));
3008 aCylinder->Translate( fromLoc, toLoc );
3011 TCollection_AsciiString anAsciiList;
3012 Handle(TColStd_HSequenceOfTransient) aSeq;
3013 aSeq = getShapesOnSurface( aCylinder, theShape, aShapeType, theState, anAsciiList );
3014 if ( aSeq.IsNull() || aSeq->Length() == 0 )
3017 // Make a Python command
3019 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
3020 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
3022 GEOM::TPythonDump(aFunction)
3023 << "[" << anAsciiList.ToCString()
3024 << "] = geompy.GetShapesOnCylinderWithLocation(" << theShape << ", " << aShapeType << ", "
3025 << theAxis << ", " << thePnt << ", " << theRadius << ", " << theState << ")";
3031 //=============================================================================
3035 //=============================================================================
3036 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnSphere
3037 (const Handle(GEOM_Object)& theShape,
3038 const Standard_Integer theShapeType,
3039 const Handle(GEOM_Object)& theCenter,
3040 const Standard_Real theRadius,
3041 const GEOMAlgo_State theState)
3045 if (theShape.IsNull() || theCenter.IsNull()) return NULL;
3047 TopoDS_Shape aShape = theShape->GetValue();
3048 TopoDS_Shape aCenter = theCenter->GetValue();
3050 if (aShape.IsNull() || aCenter.IsNull()) return NULL;
3052 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3053 if ( !checkTypeShapesOn( aShapeType ))
3056 // Center of the sphere
3057 if (aCenter.ShapeType() != TopAbs_VERTEX) return NULL;
3058 gp_Pnt aLoc = BRep_Tool::Pnt(TopoDS::Vertex(aCenter));
3060 gp_Ax3 anAx3 (aLoc, gp::DZ());
3061 Handle(Geom_SphericalSurface) aSphere =
3062 new Geom_SphericalSurface(anAx3, theRadius);
3065 TCollection_AsciiString anAsciiList;
3066 Handle(TColStd_HSequenceOfTransient) aSeq;
3067 aSeq = getShapesOnSurface( aSphere, theShape, aShapeType, theState, anAsciiList );
3068 if ( aSeq.IsNull() || aSeq->Length() == 0 )
3071 // Make a Python command
3073 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
3074 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
3076 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
3077 << "] = geompy.GetShapesOnSphere(" << theShape << ", " << aShapeType
3078 << ", " << theCenter << ", " << theRadius << ", " << theState << ")";
3084 //=============================================================================
3086 * GetShapesOnPlaneIDs
3088 //=============================================================================
3089 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnPlaneIDs
3090 (const Handle(GEOM_Object)& theShape,
3091 const Standard_Integer theShapeType,
3092 const Handle(GEOM_Object)& theAx1,
3093 const GEOMAlgo_State theState)
3097 if (theShape.IsNull() || theAx1.IsNull()) return NULL;
3099 TopoDS_Shape aShape = theShape->GetValue();
3100 TopoDS_Shape anAx1 = theAx1->GetValue();
3102 if (aShape.IsNull() || anAx1.IsNull()) return NULL;
3104 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3105 if ( !checkTypeShapesOn( aShapeType ))
3109 Handle(Geom_Surface) aPlane = makePlane( anAx1 );
3110 if ( aPlane.IsNull() )
3114 Handle(TColStd_HSequenceOfInteger) aSeq;
3115 aSeq = getShapesOnSurfaceIDs( aPlane, aShape, aShapeType, theState );
3117 // The GetShapesOnPlaneIDs() doesn't change object so no new function is required.
3118 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAx1)->GetLastFunction();
3120 // Make a Python command
3121 GEOM::TPythonDump(aFunction, /*append=*/true)
3122 << "listShapesOnPlane = geompy.GetShapesOnPlaneIDs"
3123 << "(" << theShape << "," << aShapeType << "," << theAx1 << "," << theState << ")";
3129 //=============================================================================
3131 * GetShapesOnPlaneWithLocationIDs
3133 //=============================================================================
3134 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnPlaneWithLocationIDs
3135 (const Handle(GEOM_Object)& theShape,
3136 const Standard_Integer theShapeType,
3137 const Handle(GEOM_Object)& theAx1,
3138 const Handle(GEOM_Object)& thePnt,
3139 const GEOMAlgo_State theState)
3143 if (theShape.IsNull() || theAx1.IsNull() || thePnt.IsNull()) return NULL;
3145 TopoDS_Shape aShape = theShape->GetValue();
3146 TopoDS_Shape anAx1 = theAx1->GetValue();
3147 TopoDS_Shape anPnt = thePnt->GetValue();
3149 if (aShape.IsNull() || anAx1.IsNull() || anPnt.IsNull()) return NULL;
3151 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3152 if ( !checkTypeShapesOn( aShapeType ))
3156 if (anAx1.ShapeType() != TopAbs_EDGE || anPnt.ShapeType() != TopAbs_VERTEX) return NULL;
3157 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
3158 TopoDS_Vertex V1, V2, V3;
3159 TopExp::Vertices(anEdge, V1, V2, Standard_True);
3160 if (V1.IsNull() || V2.IsNull()) {
3161 SetErrorCode("Bad edge given for the plane normal vector");
3164 V3 = TopoDS::Vertex(anPnt);
3166 SetErrorCode("Bad vertex given for the plane location");
3169 gp_Pnt aLoc = BRep_Tool::Pnt(V3);
3170 gp_Vec aVec(BRep_Tool::Pnt(V1),BRep_Tool::Pnt(V2));
3171 if (aVec.Magnitude() < Precision::Confusion()) {
3172 SetErrorCode("Vector with null magnitude given");
3176 Handle(Geom_Surface) aPlane = new Geom_Plane(aLoc, aVec);
3177 if ( aPlane.IsNull() )
3181 Handle(TColStd_HSequenceOfInteger) aSeq;
3182 aSeq = getShapesOnSurfaceIDs( aPlane, aShape, aShapeType, theState );
3184 // The GetShapesOnPlaneIDs() doesn't change object so no new function is required.
3185 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAx1)->GetLastFunction();
3187 // Make a Python command
3188 GEOM::TPythonDump(aFunction, /*append=*/true)
3189 << "listShapesOnPlane = geompy.GetShapesOnPlaneWithLocationIDs"
3190 << "(" << theShape << ", " << aShapeType << ", " << theAx1 << ", "<< thePnt << ", " << theState << ")";
3196 //=============================================================================
3198 * GetShapesOnCylinderIDs
3200 //=============================================================================
3201 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnCylinderIDs
3202 (const Handle(GEOM_Object)& theShape,
3203 const Standard_Integer theShapeType,
3204 const Handle(GEOM_Object)& theAxis,
3205 const Standard_Real theRadius,
3206 const GEOMAlgo_State theState)
3210 if (theShape.IsNull() || theAxis.IsNull()) return NULL;
3212 TopoDS_Shape aShape = theShape->GetValue();
3213 TopoDS_Shape anAxis = theAxis->GetValue();
3215 if (aShape.IsNull() || anAxis.IsNull()) return NULL;
3217 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3218 if ( !checkTypeShapesOn( aShapeType ))
3221 // Create a cylinder surface
3222 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
3223 if ( aCylinder.IsNull() )
3227 Handle(TColStd_HSequenceOfInteger) aSeq;
3228 aSeq = getShapesOnSurfaceIDs( aCylinder, aShape, aShapeType, theState );
3230 // The GetShapesOnCylinder() doesn't change object so no new function is required.
3231 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAxis)->GetLastFunction();
3233 // Make a Python command
3234 GEOM::TPythonDump(aFunction, /*append=*/true)
3235 << "listShapesOnCylinder = geompy.GetShapesOnCylinderIDs"
3236 << "(" << theShape << ", " << aShapeType << ", " << theAxis << ", "
3237 << theRadius << ", " << theState << ")";
3243 //=============================================================================
3245 * GetShapesOnCylinderWithLocationIDs
3247 //=============================================================================
3248 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnCylinderWithLocationIDs
3249 (const Handle(GEOM_Object)& theShape,
3250 const Standard_Integer theShapeType,
3251 const Handle(GEOM_Object)& theAxis,
3252 const Handle(GEOM_Object)& thePnt,
3253 const Standard_Real theRadius,
3254 const GEOMAlgo_State theState)
3258 if (theShape.IsNull() || theAxis.IsNull() || thePnt.IsNull()) return NULL;
3260 TopoDS_Shape aShape = theShape->GetValue();
3261 TopoDS_Shape anAxis = theAxis->GetValue();
3262 TopoDS_Shape aPnt = thePnt->GetValue();
3264 if (aShape.IsNull() || anAxis.IsNull() || aPnt.IsNull()) return NULL;
3266 if (aPnt.ShapeType() != TopAbs_VERTEX )
3268 SetErrorCode("Bottom location point must be vertex");
3272 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3273 if ( !checkTypeShapesOn( aShapeType ))
3276 // Create a cylinder surface
3277 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
3278 if ( aCylinder.IsNull() )
3281 // translate the surface
3282 Handle(Geom_CylindricalSurface) aCylSurface =
3283 Handle(Geom_CylindricalSurface)::DownCast( aCylinder );
3284 if ( aCylSurface.IsNull() )
3286 SetErrorCode("Unexpected surface type instead of Geom_CylindricalSurface");
3289 gp_Pnt fromLoc = aCylSurface->Cylinder().Location();
3290 gp_Pnt toLoc = BRep_Tool::Pnt( TopoDS::Vertex( aPnt ));
3291 aCylinder->Translate( fromLoc, toLoc );
3294 Handle(TColStd_HSequenceOfInteger) aSeq;
3295 aSeq = getShapesOnSurfaceIDs( aCylinder, aShape, aShapeType, theState );
3297 // The GetShapesOnCylinder() doesn't change object so no new function is required.
3298 Handle(GEOM_Function) aFunction =
3299 GEOM::GetCreatedLast(theShape, GEOM::GetCreatedLast(thePnt,theAxis))->GetLastFunction();
3301 // Make a Python command
3302 GEOM::TPythonDump(aFunction, /*append=*/true)
3303 << "listShapesOnCylinder = geompy.GetShapesOnCylinderWithLocationIDs"
3304 << "(" << theShape << ", " << aShapeType << ", " << theAxis << ", "
3305 << thePnt << ", " << theRadius << ", " << theState << ")";
3311 //=============================================================================
3313 * GetShapesOnSphereIDs
3315 //=============================================================================
3316 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnSphereIDs
3317 (const Handle(GEOM_Object)& theShape,
3318 const Standard_Integer theShapeType,
3319 const Handle(GEOM_Object)& theCenter,
3320 const Standard_Real theRadius,
3321 const GEOMAlgo_State theState)
3325 if (theShape.IsNull() || theCenter.IsNull()) return NULL;
3327 TopoDS_Shape aShape = theShape->GetValue();
3328 TopoDS_Shape aCenter = theCenter->GetValue();
3330 if (aShape.IsNull() || aCenter.IsNull()) return NULL;
3332 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3333 if ( !checkTypeShapesOn( aShapeType ))
3336 // Center of the sphere
3337 if (aCenter.ShapeType() != TopAbs_VERTEX) return NULL;
3338 gp_Pnt aLoc = BRep_Tool::Pnt(TopoDS::Vertex(aCenter));
3340 gp_Ax3 anAx3 (aLoc, gp::DZ());
3341 Handle(Geom_SphericalSurface) aSphere =
3342 new Geom_SphericalSurface(anAx3, theRadius);
3345 Handle(TColStd_HSequenceOfInteger) aSeq;
3346 aSeq = getShapesOnSurfaceIDs( aSphere, aShape, aShapeType, theState );
3348 // The GetShapesOnSphere() doesn't change object so no new function is required.
3349 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theCenter)->GetLastFunction();
3351 // Make a Python command
3352 GEOM::TPythonDump(aFunction, /*append=*/true)
3353 << "listShapesOnCylinder = geompy.GetShapesOnSphereIDs"
3354 << "(" << theShape << ", " << aShapeType << ", " << theCenter << ", "
3355 << theRadius << ", " << theState << ")";
3361 //=======================================================================
3362 //function : getShapesOnQuadrangleIDs
3364 * \brief Find IDs of sub-shapes complying with given status about quadrangle
3365 * \param theShape - the shape to explore
3366 * \param theShapeType - type of sub-shape of theShape
3367 * \param theTopLeftPoint - top left quadrangle corner
3368 * \param theTopRigthPoint - top right quadrangle corner
3369 * \param theBottomLeftPoint - bottom left quadrangle corner
3370 * \param theBottomRigthPoint - bottom right quadrangle corner
3371 * \param theState - required state
3372 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
3374 //=======================================================================
3375 Handle(TColStd_HSequenceOfInteger)
3376 GEOMImpl_IShapesOperations::getShapesOnQuadrangleIDs (const Handle(GEOM_Object)& theShape,
3377 const Standard_Integer theShapeType,
3378 const Handle(GEOM_Object)& theTopLeftPoint,
3379 const Handle(GEOM_Object)& theTopRigthPoint,
3380 const Handle(GEOM_Object)& theBottomLeftPoint,
3381 const Handle(GEOM_Object)& theBottomRigthPoint,
3382 const GEOMAlgo_State theState)
3386 if ( theShape.IsNull() ||
3387 theTopLeftPoint.IsNull() ||
3388 theTopRigthPoint.IsNull() ||
3389 theBottomLeftPoint.IsNull() ||
3390 theBottomRigthPoint.IsNull() )
3393 TopoDS_Shape aShape = theShape->GetValue();
3394 TopoDS_Shape aTL = theTopLeftPoint->GetValue();
3395 TopoDS_Shape aTR = theTopRigthPoint->GetValue();
3396 TopoDS_Shape aBL = theBottomLeftPoint->GetValue();
3397 TopoDS_Shape aBR = theBottomRigthPoint->GetValue();
3399 if (aShape.IsNull() ||
3404 aTL.ShapeType() != TopAbs_VERTEX ||
3405 aTR.ShapeType() != TopAbs_VERTEX ||
3406 aBL.ShapeType() != TopAbs_VERTEX ||
3407 aBR.ShapeType() != TopAbs_VERTEX )
3410 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3411 if ( !checkTypeShapesOn( aShapeType ))
3414 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
3416 // Check presence of triangulation, build if need
3417 if (!GEOMUtils::CheckTriangulation(aShape)) {
3418 SetErrorCode("Cannot build triangulation on the shape");
3423 gp_Pnt aPntTL = BRep_Tool::Pnt(TopoDS::Vertex(aTL));
3424 gp_Pnt aPntTR = BRep_Tool::Pnt(TopoDS::Vertex(aTR));
3425 gp_Pnt aPntBL = BRep_Tool::Pnt(TopoDS::Vertex(aBL));
3426 gp_Pnt aPntBR = BRep_Tool::Pnt(TopoDS::Vertex(aBR));
3428 GEOMAlgo_FinderShapeOnQuad aFinder( aPntTL, aPntTR, aPntBL, aPntBR );
3429 Standard_Real aTol = 0.0001; // default value
3431 aFinder.SetShape(aShape);
3432 aFinder.SetTolerance(aTol);
3433 //aFinder.SetSurface(theSurface);
3434 aFinder.SetShapeType(aShapeType);
3435 aFinder.SetState(theState);
3437 // Sets the minimal number of inner points for the faces that do not have own
3438 // inner points at all (for e.g. rectangular planar faces have just 2 triangles).
3440 aFinder.SetNbPntsMin(3);
3441 // Sets the maximal number of inner points for edges or faces.
3442 // It is usefull for the cases when this number is very big (e.g =2000) to improve
3443 // the performance. If this value =0, all inner points will be taken into account.
3445 aFinder.SetNbPntsMax(100);
3449 // Interprete results
3450 Standard_Integer iErr = aFinder.ErrorStatus();
3451 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
3453 MESSAGE(" iErr : " << iErr);
3454 TCollection_AsciiString aMsg (" iErr : ");
3455 aMsg += TCollection_AsciiString(iErr);
3459 Standard_Integer iWrn = aFinder.WarningStatus();
3460 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
3462 MESSAGE(" *** iWrn : " << iWrn);
3465 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
3467 if (listSS.Extent() < 1) {
3468 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
3469 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
3473 // Fill sequence of object IDs
3474 aSeqOfIDs = new TColStd_HSequenceOfInteger;
3476 TopTools_IndexedMapOfShape anIndices;
3477 TopExp::MapShapes(aShape, anIndices);
3479 TopTools_ListIteratorOfListOfShape itSub (listSS);
3480 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
3481 int id = anIndices.FindIndex(itSub.Value());
3482 aSeqOfIDs->Append(id);
3487 //=======================================================================
3488 //function : GetShapesOnQuadrangle
3490 * \brief Find sub-shapes complying with given status about quadrangle
3491 * \param theShape - the shape to explore
3492 * \param theShapeType - type of sub-shape of theShape
3493 * \param theTopLeftPoint - top left quadrangle corner
3494 * \param theTopRigthPoint - top right quadrangle corner
3495 * \param theBottomLeftPoint - bottom left quadrangle corner
3496 * \param theBottomRigthPoint - bottom right quadrangle corner
3497 * \param theState - required state
3498 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
3500 //=======================================================================
3501 Handle(TColStd_HSequenceOfTransient)
3502 GEOMImpl_IShapesOperations::GetShapesOnQuadrangle (const Handle(GEOM_Object)& theShape,
3503 const Standard_Integer theShapeType,
3504 const Handle(GEOM_Object)& theTopLeftPoint,
3505 const Handle(GEOM_Object)& theTopRigthPoint,
3506 const Handle(GEOM_Object)& theBottomLeftPoint,
3507 const Handle(GEOM_Object)& theBottomRigthPoint,
3508 const GEOMAlgo_State theState)
3511 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
3512 getShapesOnQuadrangleIDs( theShape,
3517 theBottomRigthPoint,
3519 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->IsEmpty() )
3522 // Find objects by indices
3523 TCollection_AsciiString anAsciiList;
3524 Handle(TColStd_HSequenceOfTransient) aSeq;
3525 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
3526 if ( aSeq.IsNull() || aSeq->IsEmpty() )
3529 // Make a Python command
3531 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
3532 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
3534 GEOM::TPythonDump(aFunction)
3535 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnQuadrangle("
3537 << TopAbs_ShapeEnum(theShapeType) << ", "
3538 << theTopLeftPoint << ", "
3539 << theTopRigthPoint << ", "
3540 << theBottomLeftPoint << ", "
3541 << theBottomRigthPoint << ", "
3548 //=======================================================================
3549 //function : GetShapesOnQuadrangleIDs
3551 * \brief Find IDs of sub-shapes complying with given status about quadrangle
3552 * \param theShape - the shape to explore
3553 * \param theShapeType - type of sub-shape of theShape
3554 * \param theTopLeftPoint - top left quadrangle corner
3555 * \param theTopRigthPoint - top right quadrangle corner
3556 * \param theBottomLeftPoint - bottom left quadrangle corner
3557 * \param theBottomRigthPoint - bottom right quadrangle corner
3558 * \param theState - required state
3559 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
3561 //=======================================================================
3562 Handle(TColStd_HSequenceOfInteger)
3563 GEOMImpl_IShapesOperations::GetShapesOnQuadrangleIDs (const Handle(GEOM_Object)& theShape,
3564 const Standard_Integer theShapeType,
3565 const Handle(GEOM_Object)& theTopLeftPoint,
3566 const Handle(GEOM_Object)& theTopRigthPoint,
3567 const Handle(GEOM_Object)& theBottomLeftPoint,
3568 const Handle(GEOM_Object)& theBottomRigthPoint,
3569 const GEOMAlgo_State theState)
3572 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
3573 getShapesOnQuadrangleIDs( theShape,
3578 theBottomRigthPoint,
3580 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->IsEmpty() )
3583 // Make a Python command
3585 // The GetShapesOnCylinder() doesn't change object so no new function is required.
3586 Handle(GEOM_Object) lastObj = GEOM::GetCreatedLast(theShape,theTopLeftPoint);
3587 lastObj = GEOM::GetCreatedLast(lastObj,theTopRigthPoint);
3588 lastObj = GEOM::GetCreatedLast(lastObj,theBottomRigthPoint);
3589 lastObj = GEOM::GetCreatedLast(lastObj,theBottomLeftPoint);
3590 Handle(GEOM_Function) aFunction = lastObj->GetLastFunction();
3592 GEOM::TPythonDump(aFunction, /*append=*/true)
3593 << "listShapesOnQuadrangle = geompy.GetShapesOnQuadrangleIDs("
3595 << TopAbs_ShapeEnum(theShapeType) << ", "
3596 << theTopLeftPoint << ", "
3597 << theTopRigthPoint << ", "
3598 << theBottomLeftPoint << ", "
3599 << theBottomRigthPoint << ", "
3606 //=============================================================================
3610 //=============================================================================
3611 static bool GetInPlaceOfShape (const Handle(GEOM_Function)& theWhereFunction,
3612 const TopTools_IndexedMapOfShape& theWhereIndices,
3613 const TopoDS_Shape& theWhat,
3614 TColStd_ListOfInteger& theModifiedList)
3616 if (theWhereFunction.IsNull() || theWhat.IsNull()) return false;
3618 if (theWhereIndices.Contains(theWhat)) {
3619 // entity was not changed by the operation
3620 Standard_Integer aWhatIndex = theWhereIndices.FindIndex(theWhat);
3621 theModifiedList.Append(aWhatIndex);
3625 // try to find in history
3626 TDF_Label aHistoryLabel = theWhereFunction->GetHistoryEntry(Standard_False);
3628 // search in history for all argument shapes
3629 Standard_Boolean isFound = Standard_False;
3630 Standard_Boolean isGood = Standard_False;
3632 TDF_LabelSequence aLabelSeq;
3633 theWhereFunction->GetDependency(aLabelSeq);
3634 Standard_Integer nbArg = aLabelSeq.Length();
3636 for (Standard_Integer iarg = 1; iarg <= nbArg && !isFound; iarg++) {
3638 TDF_Label anArgumentRefLabel = aLabelSeq.Value(iarg);
3640 Handle(GEOM_Object) anArgumentObject = GEOM_Object::GetReferencedObject(anArgumentRefLabel);
3641 TopoDS_Shape anArgumentShape = anArgumentObject->GetValue();
3643 TopTools_IndexedMapOfShape anArgumentIndices;
3644 TopExp::MapShapes(anArgumentShape, anArgumentIndices);
3646 if (anArgumentIndices.Contains(theWhat)) {
3647 isFound = Standard_True;
3648 Standard_Integer aWhatIndex = anArgumentIndices.FindIndex(theWhat);
3650 // Find corresponding label in history
3651 TDF_Label anArgumentHistoryLabel =
3652 theWhereFunction->GetArgumentHistoryEntry(anArgumentRefLabel, Standard_False);
3653 if (anArgumentHistoryLabel.IsNull()) {
3654 // Lost History of operation argument. Possibly, all its entities was removed.
3655 isGood = Standard_True;
3658 TDF_Label aWhatHistoryLabel = anArgumentHistoryLabel.FindChild(aWhatIndex, Standard_False);
3660 if (aWhatHistoryLabel.IsNull()) {
3661 // Removed entity ? Compound ? Compsolid ? Shell ? Wire
3662 isGood = Standard_False;
3664 Handle(TDataStd_IntegerArray) anIntegerArray;
3665 if (!aWhatHistoryLabel.FindAttribute(TDataStd_IntegerArray::GetID(), anIntegerArray)) {
3666 //Error: Empty modifications history for the sought shape.
3667 isGood = Standard_False;
3670 isGood = Standard_True;
3671 Standard_Integer imod, aModifLen = anIntegerArray->Array()->Length();
3672 for (imod = 1; imod <= aModifLen; imod++) {
3673 theModifiedList.Append(anIntegerArray->Array()->Value(imod));
3684 // try compound/compsolid/shell/wire element by element
3685 bool isFoundAny = false;
3686 TopTools_MapOfShape mapShape;
3688 if (theWhat.ShapeType() == TopAbs_COMPOUND ||
3689 theWhat.ShapeType() == TopAbs_COMPSOLID) {
3690 // recursive processing of compound/compsolid
3691 TopoDS_Iterator anIt (theWhat, Standard_True, Standard_True);
3692 for (; anIt.More(); anIt.Next()) {
3693 if (mapShape.Add(anIt.Value())) {
3694 TopoDS_Shape curWhat = anIt.Value();
3695 isFoundAny = GetInPlaceOfShape(theWhereFunction, theWhereIndices, curWhat, theModifiedList);
3696 if (isFoundAny) isFound = Standard_True;
3700 else if (theWhat.ShapeType() == TopAbs_SHELL) {
3701 // try to replace a shell by its faces images
3702 TopExp_Explorer anExp (theWhat, TopAbs_FACE);
3703 for (; anExp.More(); anExp.Next()) {
3704 if (mapShape.Add(anExp.Current())) {
3705 TopoDS_Shape curWhat = anExp.Current();
3706 isFoundAny = GetInPlaceOfShape(theWhereFunction, theWhereIndices, curWhat, theModifiedList);
3707 if (isFoundAny) isFound = Standard_True;
3711 else if (theWhat.ShapeType() == TopAbs_WIRE) {
3712 // try to replace a wire by its edges images
3713 TopExp_Explorer anExp (theWhat, TopAbs_EDGE);
3714 for (; anExp.More(); anExp.Next()) {
3715 if (mapShape.Add(anExp.Current())) {
3716 TopoDS_Shape curWhat = anExp.Current();
3717 isFoundAny = GetInPlaceOfShape(theWhereFunction, theWhereIndices, curWhat, theModifiedList);
3718 if (isFoundAny) isFound = Standard_True;
3730 //=============================================================================
3732 * GetShapeProperties
3734 //=============================================================================
3735 void GEOMImpl_IShapesOperations::GetShapeProperties( const TopoDS_Shape aShape, Standard_Real tab[],
3738 GProp_GProps theProps;
3740 //TopoDS_Shape aPntShape;
3741 Standard_Real aShapeSize;
3743 if (aShape.ShapeType() == TopAbs_VERTEX) aCenterMass = BRep_Tool::Pnt( TopoDS::Vertex( aShape ) );
3744 else if (aShape.ShapeType() == TopAbs_EDGE) BRepGProp::LinearProperties(aShape, theProps);
3745 else if (aShape.ShapeType() == TopAbs_FACE) BRepGProp::SurfaceProperties(aShape, theProps);
3746 else BRepGProp::VolumeProperties(aShape, theProps);
3748 if (aShape.ShapeType() == TopAbs_VERTEX)
3751 aCenterMass = theProps.CentreOfMass();
3752 aShapeSize = theProps.Mass();
3755 // aPntShape = BRepBuilderAPI_MakeVertex(aCenterMass).Shape();
3756 // aVertex = BRep_Tool::Pnt( TopoDS::Vertex( aPntShape ) );
3757 aVertex = aCenterMass;
3758 tab[0] = aVertex.X();
3759 tab[1] = aVertex.Y();
3760 tab[2] = aVertex.Z();
3761 tab[3] = aShapeSize;
3767 //================================================================================
3769 * \brief Return normal to face at extrema point
3771 //================================================================================
3773 gp_Vec GetNormal (const TopoDS_Face& face, const BRepExtrema_DistShapeShape& extrema)
3775 gp_Vec defaultNorm(1,0,0); // to have same normals on different faces
3777 // get UV at extrema point
3778 Standard_Real u,v, f,l;
3779 switch ( extrema.SupportTypeShape2(1) ) {
3780 case BRepExtrema_IsInFace: {
3781 extrema.ParOnFaceS2(1, u, v );
3784 case BRepExtrema_IsOnEdge: {
3785 TopoDS_Edge edge = TopoDS::Edge( extrema.SupportOnShape2(1));
3786 Handle(Geom2d_Curve) pcurve = BRep_Tool::CurveOnSurface( edge, face, f,l );
3787 extrema.ParOnEdgeS2( 1, u );
3788 gp_Pnt2d uv = pcurve->Value( u );
3793 case BRepExtrema_IsVertex: return defaultNorm;
3796 BRepAdaptor_Surface surface( face, false );
3797 gp_Vec du, dv; gp_Pnt p;
3798 surface.D1( u, v, p, du, dv );
3802 } catch (Standard_Failure ) {
3808 //=============================================================================
3813 //=============================================================================
3814 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlace (Handle(GEOM_Object) theShapeWhere,
3815 Handle(GEOM_Object) theShapeWhat)
3819 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
3821 TopoDS_Shape aWhere = theShapeWhere->GetValue();
3822 TopoDS_Shape aWhat = theShapeWhat->GetValue();
3823 TopoDS_Shape aPntShape;
3824 TopoDS_Vertex aVertex;
3826 if (aWhere.IsNull() || aWhat.IsNull()) {
3827 SetErrorCode("Error: aWhere and aWhat TopoDS_Shape are Null.");
3831 Handle(GEOM_Function) aWhereFunction = theShapeWhere->GetLastFunction();
3832 if (aWhereFunction.IsNull()) {
3833 SetErrorCode("Error: aWhereFunction is Null.");
3837 TopTools_IndexedMapOfShape aWhereIndices;
3838 TopExp::MapShapes(aWhere, aWhereIndices);
3840 TopAbs_ShapeEnum iType = TopAbs_SOLID;
3841 Standard_Real dl_l = 1e-3;
3842 Standard_Real min_l, Tol_0D, Tol_1D, Tol_2D, Tol_3D, Tol_Mass;
3843 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
3844 Bnd_Box BoundingBox;
3845 gp_Pnt aPnt, aPnt_aWhat, tab_Pnt[2];
3846 GProp_GProps aProps;
3848 // Find the iType of the aWhat shape
3849 iType = GEOMUtils::GetTypeOfSimplePart(aWhat);
3850 if (iType == TopAbs_SHAPE) {
3851 SetErrorCode("Error: An attempt to extract a shape of not supported type.");
3855 TopExp_Explorer Exp_aWhat ( aWhat, iType );
3856 TopExp_Explorer Exp_aWhere ( aWhere, iType );
3857 TopExp_Explorer Exp_Edge ( aWhere, TopAbs_EDGE );
3859 // Find the shortest edge in theShapeWhere shape
3860 BRepBndLib::Add(aWhere, BoundingBox);
3861 BoundingBox.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
3862 min_l = fabs(aXmax - aXmin);
3863 if( min_l < fabs(aYmax - aYmin) ) min_l = fabs(aYmax - aYmin);
3864 if( min_l < fabs(aZmax - aZmin) ) min_l = fabs(aZmax - aZmin);
3866 // Mantis issue 0020908 BEGIN
3867 if (!Exp_Edge.More()) {
3868 min_l = Precision::Confusion();
3870 // Mantis issue 0020908 END
3871 for ( Standard_Integer nbEdge = 0; Exp_Edge.More(); Exp_Edge.Next(), nbEdge++ ) {
3872 TopExp_Explorer Exp_Vertex( Exp_Edge.Current(), TopAbs_VERTEX);
3873 for ( Standard_Integer nbVertex = 0; Exp_Vertex.More(); Exp_Vertex.Next(), nbVertex++ ) {
3874 aPnt = BRep_Tool::Pnt( TopoDS::Vertex( Exp_Vertex.Current() ) );
3875 tab_Pnt[nbVertex] = aPnt;
3877 if ( ! tab_Pnt[0].IsEqual(tab_Pnt[1], dl_l) ) {
3878 BRepGProp::LinearProperties(Exp_Edge.Current(), aProps);
3879 if ( aProps.Mass() < min_l ) min_l = aProps.Mass();
3884 // Compute tolerances
3886 Tol_1D = dl_l * min_l;
3887 Tol_2D = dl_l * ( min_l * min_l) * ( 2. + dl_l);
3888 Tol_3D = dl_l * ( min_l * min_l * min_l ) * ( 3. + (3 * dl_l) + (dl_l * dl_l) );
3890 if (Tol_0D < Precision::Confusion()) Tol_0D = Precision::Confusion();
3891 if (Tol_1D < Precision::Confusion()) Tol_1D = Precision::Confusion();
3892 if (Tol_2D < Precision::Confusion()) Tol_2D = Precision::Confusion();
3893 if (Tol_3D < Precision::Confusion()) Tol_3D = Precision::Confusion();
3896 if ( iType == TopAbs_VERTEX ) Tol_Mass = Tol_0D;
3897 else if ( iType == TopAbs_EDGE ) Tol_Mass = Tol_1D;
3898 else if ( iType == TopAbs_FACE ) Tol_Mass = Tol_2D;
3900 // Searching for the sub-shapes inside the ShapeWhere shape
3901 GEOMAlgo_GetInPlace aGIP;
3902 aGIP.SetTolerance(Tol_1D);
3903 aGIP.SetTolMass(Tol_Mass);
3904 aGIP.SetTolCG(Tol_1D);
3906 aGIP.SetArgument(aWhat);
3907 aGIP.SetShapeWhere(aWhere);
3910 int iErr = aGIP.ErrorStatus();
3912 SetErrorCode("Error in GEOMAlgo_GetInPlace");
3916 // aGIP.IsFound() returns true only when the whole theShapeWhat
3917 // is found (as one shape or several parts). But we are also interested
3918 // in the partial result, that is why this check is commented.
3919 //if (!aGIP.IsFound()) {
3920 // SetErrorCode(NOT_FOUND_ANY);
3924 // Add direct result.
3925 TopTools_ListOfShape aLSA;
3926 const TopoDS_Shape &aShapeResult = aGIP.Result();
3927 TopTools_MapOfShape aMFence;
3929 if (aShapeResult.IsNull() == Standard_False) {
3930 TopoDS_Iterator anIt(aShapeResult);
3932 for (; anIt.More(); anIt.Next()) {
3933 const TopoDS_Shape &aPart = anIt.Value();
3935 if(aWhereIndices.Contains(aPart) && aMFence.Add(aPart)) {
3941 if (aLSA.Extent() == 0) {
3942 SetErrorCode(NOT_FOUND_ANY); // Not found any Results
3946 Handle(TColStd_HArray1OfInteger) aModifiedArray = new TColStd_HArray1OfInteger (1, aLSA.Extent());
3947 TopTools_ListIteratorOfListOfShape anIterModif (aLSA);
3948 for (Standard_Integer imod = 1; anIterModif.More(); anIterModif.Next(), imod++) {
3949 if (aWhereIndices.Contains(anIterModif.Value())) {
3950 aModifiedArray->SetValue(imod, aWhereIndices.FindIndex(anIterModif.Value()));
3953 SetErrorCode("Error: wrong sub-shape returned");
3959 Handle(GEOM_Object) aResult = GetEngine()->AddSubShape(theShapeWhere, aModifiedArray);
3960 if (aResult.IsNull()) {
3961 SetErrorCode("Error in algorithm: result found, but cannot be returned.");
3965 if (aModifiedArray->Length() > 1 || theShapeWhat->GetType() == GEOM_GROUP) {
3967 aResult->SetType(GEOM_GROUP);
3969 //Set a sub-shape type
3970 TopoDS_Shape aFirstFound = aLSA.First();
3971 TopAbs_ShapeEnum aShapeType = aFirstFound.ShapeType();
3973 TDF_Label aFreeLabel = aResult->GetFreeLabel();
3974 TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aShapeType);
3977 //Make a Python command
3978 Handle(GEOM_Function) aFunction = aResult->GetFunction(1);
3980 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetInPlace("
3981 << theShapeWhere << ", " << theShapeWhat << ", True)";
3987 //=============================================================================
3989 * case GetInPlaceOld:
3992 //=============================================================================
3993 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlaceOld (Handle(GEOM_Object) theShapeWhere,
3994 Handle(GEOM_Object) theShapeWhat)
3998 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
4000 TopoDS_Shape aWhere = theShapeWhere->GetValue();
4001 TopoDS_Shape aWhat = theShapeWhat->GetValue();
4002 TopoDS_Shape aPntShape;
4003 TopoDS_Vertex aVertex;
4005 if (aWhere.IsNull() || aWhat.IsNull()) {
4006 SetErrorCode("Error: aWhere and aWhat TopoDS_Shape are Null.");
4010 Handle(GEOM_Function) aWhereFunction = theShapeWhere->GetLastFunction();
4011 if (aWhereFunction.IsNull()) {
4012 SetErrorCode("Error: aWhereFunction is Null.");
4016 TopTools_IndexedMapOfShape aWhereIndices;
4017 TopExp::MapShapes(aWhere, aWhereIndices);
4019 TColStd_ListOfInteger aModifiedList;
4020 Standard_Integer aWhereIndex;
4021 Handle(TColStd_HArray1OfInteger) aModifiedArray;
4022 Handle(GEOM_Object) aResult;
4024 bool isFound = false;
4025 TopAbs_ShapeEnum iType = TopAbs_SOLID;
4026 //Standard_Real aWhat_Mass = 0., aWhere_Mass = 0.;
4027 Standard_Real tab_aWhat[4], tab_aWhere[4];
4028 Standard_Real dl_l = 1e-3;
4029 Standard_Real min_l, Tol_0D, Tol_1D, Tol_2D, Tol_3D, Tol_Mass;
4030 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
4031 Bnd_Box BoundingBox;
4032 gp_Pnt aPnt, aPnt_aWhat, tab_Pnt[2];
4033 GProp_GProps aProps;
4035 // Find the iType of the aWhat shape
4037 if ( aWhat.ShapeType() == TopAbs_VERTEX ) iType = TopAbs_VERTEX;
4038 else if ( aWhat.ShapeType() == TopAbs_EDGE || aWhat.ShapeType() == TopAbs_WIRE ) iType = TopAbs_EDGE;
4039 else if ( aWhat.ShapeType() == TopAbs_FACE || aWhat.ShapeType() == TopAbs_SHELL ) iType = TopAbs_FACE;
4040 else if ( aWhat.ShapeType() == TopAbs_SOLID || aWhat.ShapeType() == TopAbs_COMPSOLID ) iType = TopAbs_SOLID;
4041 else if ( aWhat.ShapeType() == TopAbs_COMPOUND ) {
4042 // Only the iType of the first shape in the compound is taken into account
4043 TopoDS_Iterator It (aWhat, Standard_False, Standard_False);
4045 SetErrorCode("Error: theShapeWhat is an empty COMPOUND.");
4048 TopAbs_ShapeEnum compType = It.Value().ShapeType();
4049 if ( compType == TopAbs_VERTEX ) iType = TopAbs_VERTEX;
4050 else if ( compType == TopAbs_EDGE || compType == TopAbs_WIRE ) iType = TopAbs_EDGE;
4051 else if ( compType == TopAbs_FACE || compType == TopAbs_SHELL) iType = TopAbs_FACE;
4052 else if ( compType == TopAbs_SOLID || compType == TopAbs_COMPSOLID) iType = TopAbs_SOLID;
4055 SetErrorCode("Error: An attempt to extract a shape of not supported type.");
4059 iType = GEOMUtils::GetTypeOfSimplePart(aWhat);
4060 if (iType == TopAbs_SHAPE) {
4061 SetErrorCode("Error: An attempt to extract a shape of not supported type.");
4065 TopExp_Explorer Exp_aWhat ( aWhat, iType );
4066 TopExp_Explorer Exp_aWhere ( aWhere, iType );
4067 TopExp_Explorer Exp_Edge ( aWhere, TopAbs_EDGE );
4069 // Find the shortest edge in theShapeWhere shape
4070 BRepBndLib::Add(aWhere, BoundingBox);
4071 BoundingBox.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
4072 min_l = fabs(aXmax - aXmin);
4073 if( min_l < fabs(aYmax - aYmin) ) min_l = fabs(aYmax - aYmin);
4074 if( min_l < fabs(aZmax - aZmin) ) min_l = fabs(aZmax - aZmin);
4076 // Mantis issue 0020908 BEGIN
4077 if (!Exp_Edge.More()) {
4078 min_l = Precision::Confusion();
4080 // Mantis issue 0020908 END
4081 for ( Standard_Integer nbEdge = 0; Exp_Edge.More(); Exp_Edge.Next(), nbEdge++ ) {
4082 TopExp_Explorer Exp_Vertex( Exp_Edge.Current(), TopAbs_VERTEX);
4083 for ( Standard_Integer nbVertex = 0; Exp_Vertex.More(); Exp_Vertex.Next(), nbVertex++ ) {
4084 aPnt = BRep_Tool::Pnt( TopoDS::Vertex( Exp_Vertex.Current() ) );
4085 tab_Pnt[nbVertex] = aPnt;
4087 if ( ! tab_Pnt[0].IsEqual(tab_Pnt[1], dl_l) ) {
4088 BRepGProp::LinearProperties(Exp_Edge.Current(), aProps);
4089 if ( aProps.Mass() < min_l ) min_l = aProps.Mass();
4093 // Compute tolerances
4095 Tol_1D = dl_l * min_l;
4096 Tol_2D = dl_l * ( min_l * min_l) * ( 2. + dl_l);
4097 Tol_3D = dl_l * ( min_l * min_l * min_l ) * ( 3. + (3 * dl_l) + (dl_l * dl_l) );
4099 if (Tol_0D < Precision::Confusion()) Tol_0D = Precision::Confusion();
4100 if (Tol_1D < Precision::Confusion()) Tol_1D = Precision::Confusion();
4101 if (Tol_2D < Precision::Confusion()) Tol_2D = Precision::Confusion();
4102 if (Tol_3D < Precision::Confusion()) Tol_3D = Precision::Confusion();
4104 //if (Tol_1D > 1.0) Tol_1D = 1.0;
4105 //if (Tol_2D > 1.0) Tol_2D = 1.0;
4106 //if (Tol_3D > 1.0) Tol_3D = 1.0;
4109 if ( iType == TopAbs_VERTEX ) Tol_Mass = Tol_0D;
4110 else if ( iType == TopAbs_EDGE ) Tol_Mass = Tol_1D;
4111 else if ( iType == TopAbs_FACE ) Tol_Mass = Tol_2D;
4113 // Compute the ShapeWhat Mass
4115 for ( ; Exp_aWhat.More(); Exp_aWhat.Next() ) {
4116 if ( iType == TopAbs_VERTEX ) {
4120 else if ( iType == TopAbs_EDGE ) BRepGProp::LinearProperties(Exp_aWhat.Current(), aProps);
4121 else if ( iType == TopAbs_FACE ) BRepGProp::SurfaceProperties(Exp_aWhat.Current(), aProps);
4122 else BRepGProp::VolumeProperties(Exp_aWhat.Current(), aProps);
4123 aWhat_Mass += aProps.Mass();
4127 // Searching for the sub-shapes inside the ShapeWhere shape
4128 TopTools_MapOfShape map_aWhere;
4129 for ( Exp_aWhere.ReInit(); Exp_aWhere.More(); Exp_aWhere.Next() ) {
4130 if (!map_aWhere.Add(Exp_aWhere.Current()))
4131 continue; // skip repeated shape to avoid mass addition
4132 GetShapeProperties( Exp_aWhere.Current(), tab_aWhere, aPnt );
4133 for ( Exp_aWhat.ReInit(); Exp_aWhat.More(); Exp_aWhat.Next() ) {
4134 GetShapeProperties( Exp_aWhat.Current(), tab_aWhat, aPnt_aWhat );
4135 if ( fabs(tab_aWhat[3] - tab_aWhere[3]) <= Tol_Mass && aPnt_aWhat.Distance(aPnt) <= Tol_1D )
4138 if ( (tab_aWhat[3] - tab_aWhere[3]) > Tol_Mass ) {
4139 aPntShape = BRepBuilderAPI_MakeVertex( aPnt ).Shape();
4140 aVertex = TopoDS::Vertex( aPntShape );
4141 BRepExtrema_DistShapeShape aWhereDistance ( aVertex, Exp_aWhere.Current() );
4142 BRepExtrema_DistShapeShape aWhatDistance ( aVertex, Exp_aWhat.Current() );
4143 if ( aWhereDistance.IsDone() && aWhatDistance.IsDone() &&
4144 fabs(aWhereDistance.Value() - aWhatDistance.Value()) <= Tol_1D )
4146 // 0020162: "EDF 961 GEOM : Getinplace is getting additionnal orthogonal faces"
4147 // aVertex must be projected to the same point on Where and on What
4148 gp_Pnt pOnWhat = aWhatDistance.PointOnShape2(1);
4149 gp_Pnt pOnWhere = aWhereDistance.PointOnShape2(1);
4150 isFound = ( pOnWhat.Distance(pOnWhere) <= Tol_1D );
4151 if ( isFound && iType == TopAbs_FACE )
4153 // check normals at pOnWhat and pOnWhere
4154 const double angleTol = M_PI/180.;
4155 gp_Vec normToWhat = GetNormal( TopoDS::Face(Exp_aWhat.Current()), aWhatDistance);
4156 gp_Vec normToWhere = GetNormal( TopoDS::Face(Exp_aWhere.Current()), aWhereDistance);
4157 if ( normToWhat * normToWhere < 0 )
4158 normToWhat.Reverse();
4159 isFound = ( normToWhat.Angle( normToWhere ) < angleTol );
4165 aWhereIndex = aWhereIndices.FindIndex(Exp_aWhere.Current());
4166 aModifiedList.Append(aWhereIndex);
4167 //aWhere_Mass += tab_aWhere[3];
4172 //if ( fabs( aWhat_Mass - aWhere_Mass ) <= Tol_Mass )
4176 if (aModifiedList.Extent() == 0) { // Not found any Results
4177 SetErrorCode(NOT_FOUND_ANY);
4181 aModifiedArray = new TColStd_HArray1OfInteger (1, aModifiedList.Extent());
4182 TColStd_ListIteratorOfListOfInteger anIterModif (aModifiedList);
4183 for (Standard_Integer imod = 1; anIterModif.More(); anIterModif.Next(), imod++)
4184 aModifiedArray->SetValue(imod, anIterModif.Value());
4187 aResult = GetEngine()->AddSubShape(theShapeWhere, aModifiedArray);
4188 if (aResult.IsNull()) {
4189 SetErrorCode("Error in algorithm: result found, but cannot be returned.");
4193 if (aModifiedArray->Length() > 1 || theShapeWhat->GetType() == GEOM_GROUP) {
4195 aResult->SetType(GEOM_GROUP);
4197 //Set a sub-shape type
4198 TopoDS_Shape aFirstFound = aWhereIndices.FindKey(aModifiedArray->Value(1));
4199 TopAbs_ShapeEnum aShapeType = aFirstFound.ShapeType();
4201 TDF_Label aFreeLabel = aResult->GetFreeLabel();
4202 TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aShapeType);
4205 //Make a Python command
4206 Handle(GEOM_Function) aFunction = aResult->GetFunction(1);
4208 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetInPlace("
4209 << theShapeWhere << ", " << theShapeWhat << ", False)";
4215 //=======================================================================
4216 //function : GetInPlaceByHistory
4218 //=======================================================================
4219 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlaceByHistory
4220 (Handle(GEOM_Object) theShapeWhere,
4221 Handle(GEOM_Object) theShapeWhat)
4225 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
4227 TopoDS_Shape aWhere = theShapeWhere->GetValue();
4228 TopoDS_Shape aWhat = theShapeWhat->GetValue();
4230 if (aWhere.IsNull() || aWhat.IsNull()) return NULL;
4232 Handle(GEOM_Function) aWhereFunction = theShapeWhere->GetLastFunction();
4233 if (aWhereFunction.IsNull()) return NULL;
4235 //Fill array of indices
4236 TopTools_IndexedMapOfShape aWhereIndices;
4237 TopExp::MapShapes(aWhere, aWhereIndices);
4240 TColStd_ListOfInteger aModifiedList;
4241 bool isFound = GetInPlaceOfShape(aWhereFunction, aWhereIndices, aWhat, aModifiedList);
4243 if (!isFound || aModifiedList.Extent() < 1) {
4244 SetErrorCode("Error: No history found for the sought shape or its sub-shapes.");
4248 Standard_Integer nbFound = aModifiedList.Extent();
4249 TColStd_ListIteratorOfListOfInteger anIterModif (aModifiedList);
4252 // remove sub-shapes inappropriate for group creation
4253 TopAbs_ShapeEnum subType = TopAbs_SHAPE;
4254 while ( anIterModif.More() ) {
4255 TopAbs_ShapeEnum type = aWhereIndices( anIterModif.Value() ).ShapeType();
4256 bool okForGroup = ( type == TopAbs_VERTEX || type == TopAbs_EDGE ||
4257 type == TopAbs_FACE || type == TopAbs_SOLID );
4259 if ( subType == TopAbs_SHAPE )
4262 okForGroup = ( subType == type );
4267 aModifiedList.Remove( anIterModif );
4268 nbFound -= ( !okForGroup );
4270 if ( nbFound == 0 ) {
4271 SetErrorCode("Error: result found but it's type is inappropriate for group creation.");
4276 Handle(TColStd_HArray1OfInteger) aModifiedArray =
4277 new TColStd_HArray1OfInteger( 1, nbFound );
4278 anIterModif.Initialize(aModifiedList);
4279 for (Standard_Integer imod = 1; anIterModif.More(); anIterModif.Next(), imod++)
4280 aModifiedArray->SetValue(imod, anIterModif.Value());
4283 Handle(GEOM_Object) aResult = GetEngine()->AddSubShape(theShapeWhere, aModifiedArray);
4284 if (aResult.IsNull()) {
4285 SetErrorCode("Error in algorithm: result found, but cannot be returned.");
4289 if (aModifiedArray->Length() > 1) {
4291 aResult->SetType(GEOM_GROUP);
4293 //Set a sub-shape type
4294 TopoDS_Shape aFirstFound = aWhereIndices.FindKey(aModifiedArray->Value(1));
4295 TopAbs_ShapeEnum aShapeType = aFirstFound.ShapeType();
4297 TDF_Label aFreeLabel = aResult->GetFreeLabel();
4298 TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aShapeType);
4301 //Make a Python command
4302 Handle(GEOM_Function) aFunction = aResult->GetFunction(1);
4304 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetInPlaceByHistory("
4305 << theShapeWhere << ", " << theShapeWhat << ")";
4311 #define MAX_TOLERANCE 1.e-7
4313 //=======================================================================
4314 //function : isSameEdge
4315 //purpose : Returns True if two edges coincide
4316 //=======================================================================
4317 static bool isSameEdge(const TopoDS_Edge& theEdge1, const TopoDS_Edge& theEdge2)
4319 TopoDS_Vertex V11, V12, V21, V22;
4320 TopExp::Vertices(theEdge1, V11, V12);
4321 TopExp::Vertices(theEdge2, V21, V22);
4322 gp_Pnt P11 = BRep_Tool::Pnt(V11);
4323 gp_Pnt P12 = BRep_Tool::Pnt(V12);
4324 gp_Pnt P21 = BRep_Tool::Pnt(V21);
4325 gp_Pnt P22 = BRep_Tool::Pnt(V22);
4326 bool coincide = false;
4328 //Check that ends of edges coincide
4329 if(P11.Distance(P21) <= MAX_TOLERANCE) {
4330 if(P12.Distance(P22) <= MAX_TOLERANCE) coincide = true;
4332 else if(P11.Distance(P22) <= MAX_TOLERANCE) {
4333 if(P12.Distance(P21) <= MAX_TOLERANCE) coincide = true;
4336 if(!coincide) return false;
4338 if (BRep_Tool::Degenerated(theEdge1))
4339 if (BRep_Tool::Degenerated(theEdge2)) return true;
4342 if (BRep_Tool::Degenerated(theEdge2)) return false;
4344 double U11, U12, U21, U22;
4345 Handle(Geom_Curve) C1 = BRep_Tool::Curve(theEdge1, U11, U12);
4346 Handle(Geom_Curve) C2 = BRep_Tool::Curve(theEdge2, U21, U22);
4347 if(C1->DynamicType() == C2->DynamicType()) return true;
4349 //Check that both edges has the same geometry
4350 double range = U12-U11;
4351 double U = U11+ range/3.0;
4352 gp_Pnt P1 = C1->Value(U); //Compute a point on one third of the edge's length
4353 U = U11+range*2.0/3.0;
4354 gp_Pnt P2 = C1->Value(U); //Compute a point on two thirds of the edge's length
4356 if(!GeomLib_Tool::Parameter(C2, P1, MAX_TOLERANCE, U) || U < U21 || U > U22)
4359 if(P1.Distance(C2->Value(U)) > MAX_TOLERANCE) return false;
4361 if(!GeomLib_Tool::Parameter(C2, P2, MAX_TOLERANCE, U) || U < U21 || U > U22)
4364 if(P2.Distance(C2->Value(U)) > MAX_TOLERANCE) return false;
4369 #include <TopoDS_TShape.hxx>
4370 //=======================================================================
4371 //function : isSameFace
4372 //purpose : Returns True if two faces coincide
4373 //=======================================================================
4374 static bool isSameFace(const TopoDS_Face& theFace1, const TopoDS_Face& theFace2)
4376 TopExp_Explorer E(theFace1, TopAbs_EDGE);
4377 TopTools_ListOfShape LS1, LS2;
4378 for(; E.More(); E.Next()) LS1.Append(E.Current());
4380 E.Init(theFace2, TopAbs_EDGE);
4381 for(; E.More(); E.Next()) LS2.Append(E.Current());
4383 //Compare the number of edges in the faces
4384 if(LS1.Extent() != LS2.Extent()) return false;
4386 double aMin = RealFirst(), aMax = RealLast();
4387 double xminB1=aMax, yminB1=aMax, zminB1=aMax, xminB2=aMax, yminB2=aMax, zminB2=aMax;
4388 double xmaxB1=aMin, ymaxB1=aMin, zmaxB1=aMin, xmaxB2=aMin, ymaxB2=aMin, zmaxB2=aMin;
4390 for(E.Init(theFace1, TopAbs_VERTEX); E.More(); E.Next()) {
4391 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4392 if(P.X() < xminB1) xminB1 = P.X();
4393 if(P.Y() < yminB1) yminB1 = P.Y();
4394 if(P.Z() < zminB1) zminB1 = P.Z();
4395 if(P.X() > xmaxB1) xmaxB1 = P.X();
4396 if(P.Y() > ymaxB1) ymaxB1 = P.Y();
4397 if(P.Z() > zmaxB1) zmaxB1 = P.Z();
4400 for(E.Init(theFace2, TopAbs_VERTEX); E.More(); E.Next()) {
4401 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4402 if(P.X() < xminB2) xminB2 = P.X();
4403 if(P.Y() < yminB2) yminB2 = P.Y();
4404 if(P.Z() < zminB2) zminB2 = P.Z();
4405 if(P.X() > xmaxB2) xmaxB2 = P.X();
4406 if(P.Y() > ymaxB2) ymaxB2 = P.Y();
4407 if(P.Z() > zmaxB2) zmaxB2 = P.Z();
4410 //Compare the bounding boxes of both faces
4411 if(gp_Pnt(xminB1, yminB1, zminB1).Distance(gp_Pnt(xminB2, yminB2, zminB2)) > MAX_TOLERANCE)
4414 if(gp_Pnt(xmaxB1, ymaxB1, zmaxB1).Distance(gp_Pnt(xmaxB2, ymaxB2, zmaxB2)) > MAX_TOLERANCE)
4417 Handle(Geom_Surface) S1 = BRep_Tool::Surface(theFace1);
4418 Handle(Geom_Surface) S2 = BRep_Tool::Surface(theFace2);
4420 //Check if there a coincidence of two surfaces at least in two points
4421 double U11, U12, V11, V12, U21, U22, V21, V22;
4422 BRepTools::UVBounds(theFace1, U11, U12, V11, V12);
4423 BRepTools::UVBounds(theFace2, U21, U22, V21, V22);
4425 double rangeU = U12-U11;
4426 double rangeV = V12-V11;
4427 double U = U11 + rangeU/3.0;
4428 double V = V11 + rangeV/3.0;
4429 gp_Pnt P1 = S1->Value(U, V);
4430 U = U11+rangeU*2.0/3.0;
4431 V = V11+rangeV*2.0/3.0;
4432 gp_Pnt P2 = S1->Value(U, V);
4434 if (!GeomLib_Tool::Parameters(S2, P1, MAX_TOLERANCE, U, V) || U < U21 || U > U22 || V < V21 || V > V22)
4437 if (P1.Distance(S2->Value(U,V)) > MAX_TOLERANCE) return false;
4439 if (!GeomLib_Tool::Parameters(S2, P2, MAX_TOLERANCE, U, V) || U < U21 || U > U22 || V < V21 || V > V22)
4442 if (P2.Distance(S2->Value(U, V)) > MAX_TOLERANCE) return false;
4444 //Check that each edge of the Face1 has a counterpart in the Face2
4445 TopTools_MapOfOrientedShape aMap;
4446 TopTools_ListIteratorOfListOfShape LSI1(LS1);
4447 for(; LSI1.More(); LSI1.Next()) {
4448 TopoDS_Edge E = TopoDS::Edge(LSI1.Value());
4449 bool isFound = false;
4450 TopTools_ListIteratorOfListOfShape LSI2(LS2);
4451 for(; LSI2.More(); LSI2.Next()) {
4452 TopoDS_Shape aValue = LSI2.Value();
4453 if(aMap.Contains(aValue)) continue; //To avoid checking already found edge several times
4454 if(isSameEdge(E, TopoDS::Edge(aValue))) {
4460 if(!isFound) return false;
4466 //=======================================================================
4467 //function : isSameSolid
4468 //purpose : Returns True if two solids coincide
4469 //=======================================================================
4470 bool isSameSolid(const TopoDS_Solid& theSolid1, const TopoDS_Solid& theSolid2)
4472 TopExp_Explorer E(theSolid1, TopAbs_FACE);
4473 TopTools_ListOfShape LS1, LS2;
4474 for(; E.More(); E.Next()) LS1.Append(E.Current());
4475 E.Init(theSolid2, TopAbs_FACE);
4476 for(; E.More(); E.Next()) LS2.Append(E.Current());
4478 if(LS1.Extent() != LS2.Extent()) return false;
4480 double aMin = RealFirst(), aMax = RealLast();
4481 double xminB1=aMax, yminB1=aMax, zminB1=aMax, xminB2=aMax, yminB2=aMax, zminB2=aMax;
4482 double xmaxB1=aMin, ymaxB1=aMin, zmaxB1=aMin, xmaxB2=aMin, ymaxB2=aMin, zmaxB2=aMin;
4484 for(E.Init(theSolid1, TopAbs_VERTEX); E.More(); E.Next()) {
4485 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4486 if(P.X() < xminB1) xminB1 = P.X();
4487 if(P.Y() < yminB1) yminB1 = P.Y();
4488 if(P.Z() < zminB1) zminB1 = P.Z();
4489 if(P.X() > xmaxB1) xmaxB1 = P.X();
4490 if(P.Y() > ymaxB1) ymaxB1 = P.Y();
4491 if(P.Z() > zmaxB1) zmaxB1 = P.Z();
4494 for(E.Init(theSolid2, TopAbs_VERTEX); E.More(); E.Next()) {
4495 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4496 if(P.X() < xminB2) xminB2 = P.X();
4497 if(P.Y() < yminB2) yminB2 = P.Y();
4498 if(P.Z() < zminB2) zminB2 = P.Z();
4499 if(P.X() > xmaxB2) xmaxB2 = P.X();
4500 if(P.Y() > ymaxB2) ymaxB2 = P.Y();
4501 if(P.Z() > zmaxB2) zmaxB2 = P.Z();
4504 //Compare the bounding boxes of both solids
4505 if(gp_Pnt(xminB1, yminB1, zminB1).Distance(gp_Pnt(xminB2, yminB2, zminB2)) > MAX_TOLERANCE)
4508 if(gp_Pnt(xmaxB1, ymaxB1, zmaxB1).Distance(gp_Pnt(xmaxB2, ymaxB2, zmaxB2)) > MAX_TOLERANCE)
4511 //Check that each face of the Solid1 has a counterpart in the Solid2
4512 TopTools_MapOfOrientedShape aMap;
4513 TopTools_ListIteratorOfListOfShape LSI1(LS1);
4514 for(; LSI1.More(); LSI1.Next()) {
4515 TopoDS_Face F = TopoDS::Face(LSI1.Value());
4516 bool isFound = false;
4517 TopTools_ListIteratorOfListOfShape LSI2(LS2);
4518 for(; LSI2.More(); LSI2.Next()) {
4519 if(aMap.Contains(LSI2.Value())) continue; //To avoid checking already found faces several times
4520 if(isSameFace(F, TopoDS::Face(LSI2.Value()))) {
4521 aMap.Add(LSI2.Value());
4526 if(!isFound) return false;
4532 //=======================================================================
4533 //function : GetSame
4535 //=======================================================================
4536 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetSame(const Handle(GEOM_Object)& theShapeWhere,
4537 const Handle(GEOM_Object)& theShapeWhat)
4540 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
4542 TopoDS_Shape aWhere = theShapeWhere->GetValue();
4543 TopoDS_Shape aWhat = theShapeWhat->GetValue();
4545 if (aWhere.IsNull() || aWhat.IsNull()) return NULL;
4548 bool isFound = false;
4549 TopoDS_Shape aSubShape;
4550 TopTools_MapOfShape aMap;
4552 if (aWhat.ShapeType() == TopAbs_COMPOUND || aWhat.ShapeType() == TopAbs_COMPSOLID) {
4553 TopoDS_Iterator It (aWhat, Standard_True, Standard_True);
4554 if (It.More()) aWhat = It.Value();
4557 SetErrorCode("Compounds of two or more shapes are not allowed for aWhat argument");
4562 switch (aWhat.ShapeType()) {
4563 case TopAbs_VERTEX: {
4564 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(aWhat));
4565 TopExp_Explorer E(aWhere, TopAbs_VERTEX);
4566 for(; E.More(); E.Next()) {
4567 if(!aMap.Add(E.Current())) continue;
4568 gp_Pnt P2 = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4569 if(P.Distance(P2) <= MAX_TOLERANCE) {
4571 aSubShape = E.Current();
4578 TopoDS_Edge anEdge = TopoDS::Edge(aWhat);
4579 TopExp_Explorer E(aWhere, TopAbs_EDGE);
4580 for(; E.More(); E.Next()) {
4581 if(!aMap.Add(E.Current())) continue;
4582 if(isSameEdge(anEdge, TopoDS::Edge(E.Current()))) {
4583 aSubShape = E.Current();
4591 TopoDS_Face aFace = TopoDS::Face(aWhat);
4592 TopExp_Explorer E(aWhere, TopAbs_FACE);
4593 for(; E.More(); E.Next()) {
4594 if(!aMap.Add(E.Current())) continue;
4595 if(isSameFace(aFace, TopoDS::Face(E.Current()))) {
4596 aSubShape = E.Current();
4603 case TopAbs_SOLID: {
4604 TopoDS_Solid aSolid = TopoDS::Solid(aWhat);
4605 TopExp_Explorer E(aWhere, TopAbs_SOLID);
4606 for(; E.More(); E.Next()) {
4607 if(!aMap.Add(E.Current())) continue;
4608 if(isSameSolid(aSolid, TopoDS::Solid(E.Current()))) {
4609 aSubShape = E.Current();
4621 TopTools_IndexedMapOfShape anIndices;
4622 TopExp::MapShapes(aWhere, anIndices);
4623 if (anIndices.Contains(aSubShape))
4624 anIndex = anIndices.FindIndex(aSubShape);
4627 if (anIndex < 0) return NULL;
4629 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
4631 anArray->SetValue(1, anIndex);
4633 Handle(GEOM_Object) aResult = GetEngine()->AddSubShape(theShapeWhere, anArray);
4634 Handle(GEOM_Function) aFunction = aResult->GetLastFunction();
4636 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetSame("
4637 << theShapeWhere << ", " << theShapeWhat << ")";
4645 //=======================================================================
4646 //function : GetSameIDs
4648 //=======================================================================
4649 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetSameIDs
4650 (const Handle(GEOM_Object)& theShapeWhere,
4651 const Handle(GEOM_Object)& theShapeWhat)
4654 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
4656 TopoDS_Shape aWhere = theShapeWhere->GetValue();
4657 TopoDS_Shape aWhat = theShapeWhat->GetValue();
4659 if (aWhere.IsNull() || aWhat.IsNull()) return NULL;
4661 TopTools_ListOfShape listShape;
4662 TopTools_MapOfShape aMap;
4664 if (aWhat.ShapeType() == TopAbs_COMPOUND || aWhat.ShapeType() == TopAbs_COMPSOLID) {
4665 TopoDS_Iterator It (aWhat, Standard_True, Standard_True);
4666 if (It.More()) aWhat = It.Value();
4669 SetErrorCode("Compounds of two or more shapes are not allowed for aWhat argument");
4674 switch (aWhat.ShapeType()) {
4675 case TopAbs_VERTEX: {
4676 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(aWhat));
4677 TopExp_Explorer E(aWhere, TopAbs_VERTEX);
4678 for(; E.More(); E.Next()) {
4679 if(!aMap.Add(E.Current())) continue;
4680 gp_Pnt P2 = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4681 if(P.Distance(P2) <= MAX_TOLERANCE) {
4682 listShape.Append(E.Current());
4688 TopoDS_Edge anEdge = TopoDS::Edge(aWhat);
4689 TopExp_Explorer E(aWhere, TopAbs_EDGE);
4690 for(; E.More(); E.Next()) {
4691 if(!aMap.Add(E.Current())) continue;
4692 if(isSameEdge(anEdge, TopoDS::Edge(E.Current()))) {
4693 listShape.Append(E.Current());
4699 TopoDS_Face aFace = TopoDS::Face(aWhat);
4700 TopExp_Explorer E(aWhere, TopAbs_FACE);
4701 for(; E.More(); E.Next()) {
4702 if(!aMap.Add(E.Current())) continue;
4703 if(isSameFace(aFace, TopoDS::Face(E.Current()))) {
4704 listShape.Append(E.Current());
4709 case TopAbs_SOLID: {
4710 TopoDS_Solid aSolid = TopoDS::Solid(aWhat);
4711 TopExp_Explorer E(aWhere, TopAbs_SOLID);
4712 for(; E.More(); E.Next()) {
4713 if(!aMap.Add(E.Current())) continue;
4714 if(isSameSolid(aSolid, TopoDS::Solid(E.Current()))) {
4715 listShape.Append(E.Current());
4724 if ( !listShape.IsEmpty() ) {
4725 TopTools_IndexedMapOfShape anIndices;
4726 TopExp::MapShapes(aWhere, anIndices);
4727 TopTools_ListIteratorOfListOfShape itSub (listShape);
4728 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
4729 for (; itSub.More(); itSub.Next()) {
4730 if (anIndices.Contains(itSub.Value()))
4731 aSeq->Append(anIndices.FindIndex(itSub.Value()));
4734 // The GetSameIDs() doesn't change object so no new function is required.
4735 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShapeWhere,theShapeWhat)->GetLastFunction();
4737 // Make a Python command
4738 GEOM::TPythonDump(aFunction, /*append=*/true)
4739 << "listSameIDs = geompy.GetSameIDs("
4740 << theShapeWhere << ", "
4741 << theShapeWhat << ")";
4744 SetErrorCode(NOT_FOUND_ANY);