1 // Copyright (C) 2007-2011 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
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_CopyDriver.hxx"
37 #include "GEOMImpl_GlueDriver.hxx"
39 #include "GEOMImpl_IVector.hxx"
40 #include "GEOMImpl_IShapes.hxx"
41 #include "GEOMImpl_IGlue.hxx"
43 #include "GEOMImpl_Block6Explorer.hxx"
45 #include "GEOM_Function.hxx"
46 #include "GEOM_ISubShape.hxx"
47 #include "GEOM_PythonDump.hxx"
49 #include "GEOMAlgo_FinderShapeOn1.hxx"
50 #include "GEOMAlgo_FinderShapeOnQuad.hxx"
51 #include "GEOMAlgo_FinderShapeOn2.hxx"
52 #include "GEOMAlgo_ClsfBox.hxx"
53 #include "GEOMAlgo_ClsfSolid.hxx"
54 #include "GEOMAlgo_GlueDetector.hxx"
55 #include "GEOMAlgo_ListIteratorOfListOfCoupleOfShapes.hxx"
56 #include "GEOMAlgo_CoupleOfShapes.hxx"
57 #include "GEOMAlgo_ListOfCoupleOfShapes.hxx"
59 #include "utilities.h"
61 #include "Utils_ExceptHandlers.hxx"
63 #include <TFunction_DriverTable.hxx>
64 #include <TFunction_Driver.hxx>
65 #include <TFunction_Logbook.hxx>
66 #include <TDataStd_Integer.hxx>
67 #include <TDataStd_IntegerArray.hxx>
68 #include <TDataStd_ListIteratorOfListOfExtendedString.hxx>
69 #include <TDF_Tool.hxx>
71 #include <BRepExtrema_ExtCF.hxx>
72 #include <BRepExtrema_DistShapeShape.hxx>
74 #include <BRep_Tool.hxx>
75 #include <BRep_Builder.hxx>
76 #include <BRepTools.hxx>
77 #include <BRepGProp.hxx>
78 #include <BRepAdaptor_Curve.hxx>
79 #include <BRepAdaptor_Surface.hxx>
80 #include <BRepBndLib.hxx>
81 #include <BRepBuilderAPI_MakeFace.hxx>
82 #include <BRepMesh_IncrementalMesh.hxx>
86 #include <TopExp_Explorer.hxx>
87 #include <TopLoc_Location.hxx>
89 #include <TopoDS_Shape.hxx>
90 #include <TopoDS_Solid.hxx>
91 #include <TopoDS_Face.hxx>
92 #include <TopoDS_Edge.hxx>
93 #include <TopoDS_Vertex.hxx>
94 #include <TopoDS_Compound.hxx>
95 #include <TopoDS_Iterator.hxx>
96 #include <TopTools_Array1OfShape.hxx>
97 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
98 #include <TopTools_IndexedMapOfShape.hxx>
99 #include <TopTools_ListIteratorOfListOfShape.hxx>
100 #include <TopTools_MapOfShape.hxx>
101 #include <TopTools_MapOfOrientedShape.hxx>
103 #include <Geom_Surface.hxx>
104 #include <Geom_Plane.hxx>
105 #include <Geom_SphericalSurface.hxx>
106 #include <Geom_CylindricalSurface.hxx>
107 #include <GeomAdaptor_Surface.hxx>
109 #include <GeomLib_Tool.hxx>
110 #include <Geom2d_Curve.hxx>
112 #include <Bnd_Box.hxx>
113 #include <GProp_GProps.hxx>
114 #include <TColStd_Array1OfReal.hxx>
115 #include <TColStd_HArray1OfInteger.hxx>
116 #include <TColStd_ListIteratorOfListOfInteger.hxx>
117 #include <TColStd_ListOfInteger.hxx>
118 #include <gp_Cylinder.hxx>
119 #include <gp_Lin.hxx>
120 #include <gp_Pnt.hxx>
124 #include <functional>
126 #include <Standard_NullObject.hxx>
127 #include <Standard_Failure.hxx>
128 #include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
130 // Includes added for GetInPlace algorithm improvement
132 #include <GEOMImpl_MeasureDriver.hxx>
133 #include <GEOMImpl_IMeasure.hxx>
134 #include <BRepBuilderAPI_MakeVertex.hxx>
136 #include <BRepClass_FaceClassifier.hxx>
137 #include <BRepClass3d_SolidClassifier.hxx>
138 #include <Precision.hxx>
140 #define STD_SORT_ALGO 1
142 //=============================================================================
146 //=============================================================================
147 GEOMImpl_IShapesOperations::GEOMImpl_IShapesOperations (GEOM_Engine* theEngine, int theDocID)
148 : GEOM_IOperations(theEngine, theDocID)
150 MESSAGE("GEOMImpl_IShapesOperations::GEOMImpl_IShapesOperations");
153 //=============================================================================
157 //=============================================================================
158 GEOMImpl_IShapesOperations::~GEOMImpl_IShapesOperations()
160 MESSAGE("GEOMImpl_IShapesOperations::~GEOMImpl_IShapesOperations");
163 //=============================================================================
167 //=============================================================================
168 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeEdge
169 (Handle(GEOM_Object) thePnt1, Handle(GEOM_Object) thePnt2)
173 if (thePnt1.IsNull() || thePnt2.IsNull()) return NULL;
175 //Add a new Edge object
176 Handle(GEOM_Object) anEdge = GetEngine()->AddObject(GetDocID(), GEOM_EDGE);
178 //Add a new Vector function
179 Handle(GEOM_Function) aFunction =
180 anEdge->AddFunction(GEOMImpl_VectorDriver::GetID(), VECTOR_TWO_PNT);
182 //Check if the function is set correctly
183 if (aFunction->GetDriverGUID() != GEOMImpl_VectorDriver::GetID()) return NULL;
185 GEOMImpl_IVector aPI (aFunction);
187 Handle(GEOM_Function) aRef1 = thePnt1->GetLastFunction();
188 Handle(GEOM_Function) aRef2 = thePnt2->GetLastFunction();
189 if (aRef1.IsNull() || aRef2.IsNull()) return NULL;
191 aPI.SetPoint1(aRef1);
192 aPI.SetPoint2(aRef2);
194 //Compute the Edge value
196 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
199 if (!GetSolver()->ComputeFunction(aFunction)) {
200 SetErrorCode("Vector driver failed");
204 catch (Standard_Failure) {
205 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
206 SetErrorCode(aFail->GetMessageString());
210 //Make a Python command
211 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdge("
212 << thePnt1 << ", " << thePnt2 << ")";
218 //=============================================================================
220 * MakeEdgeOnCurveByLength
222 //=============================================================================
223 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeEdgeOnCurveByLength
224 (Handle(GEOM_Object) theRefCurve,
225 const Standard_Real theLength,
226 Handle(GEOM_Object) theStartPoint)
230 if (theRefCurve.IsNull()) return NULL;
232 //Add a new Edge object
233 Handle(GEOM_Object) anEdge = GetEngine()->AddObject(GetDocID(), GEOM_EDGE);
235 //Add a new Vector function
236 Handle(GEOM_Function) aFunction =
237 anEdge->AddFunction(GEOMImpl_ShapeDriver::GetID(), EDGE_CURVE_LENGTH);
239 //Check if the function is set correctly
240 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
242 GEOMImpl_IVector aPI (aFunction);
244 Handle(GEOM_Function) aRef1 = theRefCurve->GetLastFunction();
245 if (aRef1.IsNull()) return NULL;
246 aPI.SetPoint1(aRef1);
248 if (!theStartPoint.IsNull()) {
249 Handle(GEOM_Function) aRef2 = theStartPoint->GetLastFunction();
250 aPI.SetPoint2(aRef2);
253 aPI.SetParameter(theLength);
255 //Compute the Edge value
257 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
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
315 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
318 if (!GetSolver()->ComputeFunction(aFunction)) {
319 SetErrorCode("Shape driver failed");
323 catch (Standard_Failure) {
324 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
325 SetErrorCode(aFail->GetMessageString());
329 const double DEF_LIN_TOL = Precision::Confusion();
330 const double DEF_ANG_TOL = Precision::Angular();
331 //Make a Python command
332 if ( theAngularTolerance == DEF_ANG_TOL ) {
333 if ( theLinearTolerance == DEF_LIN_TOL )
334 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdgeWire("
337 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdgeWire("
338 << theWire << ", " << theLinearTolerance << ")";
341 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdgeWire("
342 << theWire << ", " << theLinearTolerance << ", "
343 << theAngularTolerance << ")";
350 //=============================================================================
354 //=============================================================================
355 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeWire
356 (std::list<Handle(GEOM_Object)> theShapes,
357 const Standard_Real theTolerance)
362 Handle(GEOM_Object) aWire = GetEngine()->AddObject(GetDocID(), GEOM_WIRE);
365 Handle(GEOM_Function) aFunction =
366 aWire->AddFunction(GEOMImpl_ShapeDriver::GetID(), WIRE_EDGES);
367 if (aFunction.IsNull()) return NULL;
369 //Check if the function is set correctly
370 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
372 GEOMImpl_IShapes aCI (aFunction);
373 aCI.SetTolerance(theTolerance);
375 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
378 std::list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
379 for (; it != theShapes.end(); it++) {
380 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
381 if (aRefSh.IsNull()) {
382 SetErrorCode("NULL argument shape for the shape construction");
385 aShapesSeq->Append(aRefSh);
387 aCI.SetShapes(aShapesSeq);
391 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
394 if (!GetSolver()->ComputeFunction(aFunction)) {
395 SetErrorCode("Shape driver failed");
399 catch (Standard_Failure) {
400 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
401 SetErrorCode(aFail->GetMessageString());
405 //Make a Python command
406 GEOM::TPythonDump pd (aFunction);
407 pd << aWire << " = geompy.MakeWire([";
410 it = theShapes.begin();
411 if (it != theShapes.end()) {
413 while (it != theShapes.end()) {
414 pd << ", " << (*it++);
417 pd << "], " << theTolerance << ")";
423 //=============================================================================
427 //=============================================================================
428 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFace (Handle(GEOM_Object) theWire,
429 const bool isPlanarWanted)
433 if (theWire.IsNull()) return NULL;
435 //Add a new Face object
436 Handle(GEOM_Object) aFace = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
438 //Add a new Shape function for creation of a face from a wire
439 Handle(GEOM_Function) aFunction =
440 aFace->AddFunction(GEOMImpl_ShapeDriver::GetID(), FACE_WIRE);
441 if (aFunction.IsNull()) return NULL;
443 //Check if the function is set correctly
444 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
446 GEOMImpl_IShapes aCI (aFunction);
448 Handle(GEOM_Function) aRefWire = theWire->GetLastFunction();
450 if (aRefWire.IsNull()) return NULL;
452 aCI.SetBase(aRefWire);
453 aCI.SetIsPlanar(isPlanarWanted);
455 //Compute the Face value
457 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
460 if (!GetSolver()->ComputeFunction(aFunction)) {
461 SetErrorCode("Shape driver failed to compute a face");
465 catch (Standard_Failure) {
466 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
467 SetErrorCode(aFail->GetMessageString());
471 //Make a Python command
472 GEOM::TPythonDump(aFunction) << aFace << " = geompy.MakeFace("
473 << theWire << ", " << (int)isPlanarWanted << ")";
479 //=============================================================================
483 //=============================================================================
484 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFaceWires
485 (std::list<Handle(GEOM_Object)> theShapes,
486 const bool isPlanarWanted)
491 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
494 Handle(GEOM_Function) aFunction =
495 aShape->AddFunction(GEOMImpl_ShapeDriver::GetID(), FACE_WIRES);
496 if (aFunction.IsNull()) return NULL;
498 //Check if the function is set correctly
499 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
501 GEOMImpl_IShapes aCI (aFunction);
503 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
506 std::list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
507 for (; it != theShapes.end(); it++) {
508 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
509 if (aRefSh.IsNull()) {
510 SetErrorCode("NULL argument shape for the face construction");
513 aShapesSeq->Append(aRefSh);
515 aCI.SetShapes(aShapesSeq);
517 aCI.SetIsPlanar(isPlanarWanted);
521 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
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());
535 //Make a Python command
536 GEOM::TPythonDump pd (aFunction);
537 pd << aShape << " = geompy.MakeFaceWires([";
540 it = theShapes.begin();
541 if (it != theShapes.end()) {
543 while (it != theShapes.end()) {
544 pd << ", " << (*it++);
547 pd << "], " << (int)isPlanarWanted << ")";
553 //=============================================================================
557 //=============================================================================
558 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeShell
559 (std::list<Handle(GEOM_Object)> theShapes)
561 return MakeShape(theShapes, GEOM_SHELL, SHELL_FACES, "MakeShell");
564 //=============================================================================
568 //=============================================================================
569 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeSolidShells
570 (std::list<Handle(GEOM_Object)> theShapes)
572 return MakeShape(theShapes, GEOM_SOLID, SOLID_SHELLS, "MakeSolid");
575 //=============================================================================
579 //=============================================================================
580 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeCompound
581 (std::list<Handle(GEOM_Object)> theShapes)
583 return MakeShape(theShapes, GEOM_COMPOUND, COMPOUND_SHAPES, "MakeCompound");
586 //=============================================================================
590 //=============================================================================
591 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeShape
592 (std::list<Handle(GEOM_Object)> theShapes,
593 const Standard_Integer theObjectType,
594 const Standard_Integer theFunctionType,
595 const TCollection_AsciiString& theMethodName)
600 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), theObjectType);
603 Handle(GEOM_Function) aFunction =
604 aShape->AddFunction(GEOMImpl_ShapeDriver::GetID(), theFunctionType);
605 if (aFunction.IsNull()) return NULL;
607 //Check if the function is set correctly
608 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
610 GEOMImpl_IShapes aCI (aFunction);
612 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
615 std::list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
616 for (; it != theShapes.end(); it++) {
617 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
618 if (aRefSh.IsNull()) {
619 SetErrorCode("NULL argument shape for the shape construction");
622 aShapesSeq->Append(aRefSh);
624 aCI.SetShapes(aShapesSeq);
628 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
631 if (!GetSolver()->ComputeFunction(aFunction)) {
632 SetErrorCode("Shape driver failed");
636 catch (Standard_Failure) {
637 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
638 SetErrorCode(aFail->GetMessageString());
642 //Make a Python command
643 GEOM::TPythonDump pd (aFunction);
644 pd << aShape << " = geompy." << theMethodName.ToCString() << "([";
647 it = theShapes.begin();
648 if (it != theShapes.end()) {
650 while (it != theShapes.end()) {
651 pd << ", " << (*it++);
660 //=============================================================================
664 //=============================================================================
665 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeGlueFaces
666 (Handle(GEOM_Object) theShape,
667 const Standard_Real theTolerance,
668 const Standard_Boolean doKeepNonSolids)
672 if (theShape.IsNull()) return NULL;
674 //Add a new Glued object
675 Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
677 //Add a new Glue function
678 Handle(GEOM_Function) aFunction;
679 aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_FACES);
680 if (aFunction.IsNull()) return NULL;
682 //Check if the function is set correctly
683 if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
685 GEOMImpl_IGlue aCI (aFunction);
687 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
688 if (aRefShape.IsNull()) return NULL;
690 aCI.SetBase(aRefShape);
691 aCI.SetTolerance(theTolerance);
692 aCI.SetKeepNonSolids(doKeepNonSolids);
694 //Compute the sub-shape value
695 Standard_Boolean isWarning = Standard_False;
697 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
700 if (!GetSolver()->ComputeFunction(aFunction)) {
701 SetErrorCode("Shape driver failed to glue faces");
705 catch (Standard_Failure) {
706 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
707 SetErrorCode(aFail->GetMessageString());
708 // to provide warning
709 if (!aFunction->GetValue().IsNull()) {
710 isWarning = Standard_True;
716 //Make a Python command
717 GEOM::TPythonDump(aFunction) << aGlued << " = geompy.MakeGlueFaces("
718 << theShape << ", " << theTolerance << ")";
720 // to provide warning
721 if (!isWarning) SetErrorCode(OK);
725 //=============================================================================
729 //=============================================================================
731 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetGlueFaces
732 (Handle(GEOM_Object) theShape,
733 const Standard_Real theTolerance)
737 if (theShape.IsNull()) return NULL;
738 TopoDS_Shape aShape = theShape->GetValue();
739 if (aShape.IsNull()) return NULL;
741 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
743 Standard_Integer iErr;
745 GEOMAlgo_Gluer1 aGluer;
746 GEOMAlgo_ListIteratorOfListOfCoupleOfShapes aItCS;
747 GEOMAlgo_CoupleOfShapes aCS;
748 GEOMAlgo_ListOfCoupleOfShapes aLCS;
750 //aGluer = new GEOMAlgo_Gluer1;
751 aGluer.SetShape(aShape);
752 aGluer.SetTolerance(theTolerance);
754 iErr = aGluer.ErrorStatus();
755 if (iErr) return NULL;
757 TopTools_ListOfShape listShape;
758 const GEOMAlgo_ListOfCoupleOfShapes& aLCSG = aGluer.GluedFaces();
760 aItCS.Initialize(aLCSG);
761 for (; aItCS.More(); aItCS.Next()) {
762 const GEOMAlgo_CoupleOfShapes& aCSG = aItCS.Value();
763 listShape.Append(aCSG.Shape1());
766 TopTools_ListIteratorOfListOfShape itSub (listShape);
767 TCollection_AsciiString anAsciiList, anEntry;
768 TopTools_IndexedMapOfShape anIndices;
769 TopExp::MapShapes(aShape, anIndices);
770 Handle(TColStd_HArray1OfInteger) anArray;
771 Handle(GEOM_Object) anObj;
772 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
773 TopoDS_Shape aValue = itSub.Value();
774 anArray = new TColStd_HArray1OfInteger(1,1);
775 anArray->SetValue(1, anIndices.FindIndex(aValue));
776 anObj = GetEngine()->AddSubShape(theShape, anArray);
777 if (!anObj.IsNull()) {
780 // for python command
781 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
782 anAsciiList += anEntry;
787 //Make a Python command
788 if( anAsciiList.Length() > 0 ) {
789 anAsciiList.Trunc(anAsciiList.Length() - 1);
790 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
791 GEOM::TPythonDump pd (aFunction, true);
792 pd << "[" << anAsciiList.ToCString();
793 pd << "] = geompy.GetGlueFaces(" << theShape << ", " << theTolerance << ")";
802 //=============================================================================
804 * MakeGlueFacesByList
806 //=============================================================================
807 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeGlueFacesByList
808 (Handle(GEOM_Object) theShape,
809 const Standard_Real theTolerance,
810 std::list<Handle(GEOM_Object)> theFaces,
811 const Standard_Boolean doKeepNonSolids,
812 const Standard_Boolean doGlueAllEdges)
816 if (theShape.IsNull()) return NULL;
818 //Add a new Glued object
819 Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
821 //Add a new Glue function
822 Handle(GEOM_Function) aFunction;
823 aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_FACES_BY_LIST);
824 if (aFunction.IsNull()) return NULL;
826 //Check if the function is set correctly
827 if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
829 GEOMImpl_IGlue aCI (aFunction);
831 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
832 if (aRefShape.IsNull()) return NULL;
834 aCI.SetBase(aRefShape);
835 aCI.SetTolerance(theTolerance);
836 aCI.SetKeepNonSolids(doKeepNonSolids);
837 aCI.SetGlueAllEdges(doGlueAllEdges);
839 Handle(TColStd_HSequenceOfTransient) aFaces = new TColStd_HSequenceOfTransient;
840 std::list<Handle(GEOM_Object)>::iterator it = theFaces.begin();
841 for (; it != theFaces.end(); it++) {
842 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
843 if (aRefSh.IsNull()) {
844 SetErrorCode("NULL argument shape for the shape construction");
847 aFaces->Append(aRefSh);
849 aCI.SetFaces(aFaces);
851 //Compute the sub-shape value
852 Standard_Boolean isWarning = Standard_False;
854 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
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;
929 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
932 if (!GetSolver()->ComputeFunction(aFunction)) {
933 SetErrorCode("Shape driver failed to glue edges");
937 catch (Standard_Failure) {
938 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
939 SetErrorCode(aFail->GetMessageString());
940 // to provide warning
941 if (!aFunction->GetValue().IsNull()) {
942 isWarning = Standard_True;
948 //Make a Python command
949 GEOM::TPythonDump(aFunction) << aGlued << " = geompy.MakeGlueEdges("
950 << theShape << ", " << theTolerance << ")";
952 // to provide warning
953 if (!isWarning) SetErrorCode(OK);
957 //=============================================================================
961 //=============================================================================
962 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetGlueShapes
963 (Handle(GEOM_Object) theShape,
964 const Standard_Real theTolerance,
965 const TopAbs_ShapeEnum theType)
969 if (theShape.IsNull()) return NULL;
970 TopoDS_Shape aShape = theShape->GetValue();
971 if (aShape.IsNull()) return NULL;
973 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
975 GEOMAlgo_GlueDetector aGluer;
976 aGluer.SetArgument(aShape);
977 aGluer.SetTolerance(theTolerance);
979 Standard_Integer iErr = aGluer.ErrorStatus();
980 if (iErr) return NULL;
982 TCollection_AsciiString anAsciiList, anEntry;
983 TopTools_IndexedMapOfShape anIndices;
984 TopExp::MapShapes(aShape, anIndices);
985 Handle(TColStd_HArray1OfInteger) anArray;
986 Handle(GEOM_Object) anObj;
988 TopTools_ListOfShape listOnePerSet;
990 const TopTools_DataMapOfShapeListOfShape& aImages = aGluer.Images();
991 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape aItDMSLS (aImages);
992 for (int index = 1; aItDMSLS.More(); aItDMSLS.Next(), ++index) {
994 //const TopoDS_Shape& aSkey = aItDMSLS.Key();
996 // list of shapes of the argument that can be glued
997 const TopTools_ListOfShape& aLSD = aItDMSLS.Value();
999 //listShape.Append(aLSD.First());
1000 TopoDS_Shape aValue = aLSD.First();
1002 if (aValue.ShapeType() == theType) {
1003 listOnePerSet.Append(aValue);
1007 // for stable order of returned entities
1008 GEOMImpl_IShapesOperations::SortShapes(listOnePerSet, Standard_False);
1010 TopTools_ListIteratorOfListOfShape aListIt (listOnePerSet);
1011 for (; aListIt.More(); aListIt.Next()) {
1012 TopoDS_Shape aValue = aListIt.Value();
1013 anArray = new TColStd_HArray1OfInteger(1,1);
1014 anArray->SetValue(1, anIndices.FindIndex(aValue));
1015 anObj = GetEngine()->AddSubShape(theShape, anArray);
1016 if (!anObj.IsNull()) {
1017 aSeq->Append(anObj);
1019 // for python command
1020 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
1021 anAsciiList += anEntry;
1026 // Make a Python command
1027 if (anAsciiList.Length() > 0) {
1028 anAsciiList.Trunc(anAsciiList.Length() - 1);
1029 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
1030 GEOM::TPythonDump pd (aFunction, /*append=*/true);
1031 pd << "[" << anAsciiList.ToCString();
1032 if (theType == TopAbs_FACE)
1033 pd << "] = geompy.GetGlueFaces(" << theShape << ", " << theTolerance << ")";
1034 else if (theType == TopAbs_EDGE)
1035 pd << "] = geompy.GetGlueEdges(" << theShape << ", " << theTolerance << ")";
1043 //=============================================================================
1045 * MakeGlueEdgesByList
1047 //=============================================================================
1048 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeGlueEdgesByList
1049 (Handle(GEOM_Object) theShape,
1050 const Standard_Real theTolerance,
1051 std::list<Handle(GEOM_Object)> theEdges)
1055 if (theShape.IsNull()) return NULL;
1057 //Add a new Glued object
1058 Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
1060 //Add a new Glue function
1061 Handle(GEOM_Function) aFunction;
1062 aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_EDGES_BY_LIST);
1063 if (aFunction.IsNull()) return NULL;
1065 //Check if the function is set correctly
1066 if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
1068 GEOMImpl_IGlue aCI (aFunction);
1070 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
1071 if (aRefShape.IsNull()) return NULL;
1073 aCI.SetBase(aRefShape);
1074 aCI.SetTolerance(theTolerance);
1075 aCI.SetKeepNonSolids(true);
1077 Handle(TColStd_HSequenceOfTransient) anEdges = new TColStd_HSequenceOfTransient;
1078 std::list<Handle(GEOM_Object)>::iterator it = theEdges.begin();
1079 for (; it != theEdges.end(); it++) {
1080 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
1081 if (aRefSh.IsNull()) {
1082 SetErrorCode("NULL argument shape for the shape construction");
1085 anEdges->Append(aRefSh);
1087 aCI.SetFaces(anEdges);
1089 //Compute the sub-shape value
1090 Standard_Boolean isWarning = Standard_False;
1092 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
1095 if (!GetSolver()->ComputeFunction(aFunction)) {
1096 SetErrorCode("Shape driver failed to glue edges");
1100 catch (Standard_Failure) {
1101 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1102 SetErrorCode(aFail->GetMessageString());
1103 // to provide warning
1104 if (!aFunction->GetValue().IsNull()) {
1105 isWarning = Standard_True;
1111 //Make a Python command
1113 GEOM::TPythonDump pd (aFunction);
1114 pd << aGlued << " = geompy.MakeGlueEdgesByList("
1115 << theShape << ", " << theTolerance << ", [";
1117 it = theEdges.begin();
1118 if (it != theEdges.end()) {
1120 while (it != theEdges.end()) {
1121 pd << ", " << (*it++);
1126 // to provide warning
1127 if (!isWarning) SetErrorCode(OK);
1131 //=============================================================================
1133 * GetExistingSubObjects
1135 //=============================================================================
1136 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetExistingSubObjects
1137 (Handle(GEOM_Object) theShape,
1138 const Standard_Boolean theGroupsOnly)
1142 if (theShape.IsNull()) return NULL;
1144 Handle(GEOM_Function) aMainShape = theShape->GetLastFunction();
1145 if (aMainShape.IsNull()) return NULL;
1147 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1148 SetErrorCode(NOT_FOUND_ANY);
1150 if (!aMainShape->HasSubShapeReferences()) return aSeq;
1151 const TDataStd_ListOfExtendedString& aListEntries = aMainShape->GetSubShapeReferences();
1152 if (aListEntries.IsEmpty()) return aSeq;
1156 TCollection_AsciiString anAsciiList;
1158 TDataStd_ListIteratorOfListOfExtendedString anIt (aListEntries);
1159 for (; anIt.More(); anIt.Next()) {
1160 TCollection_ExtendedString anEntry = anIt.Value();
1161 Standard_Integer aStrLen = anEntry.LengthOfCString();
1162 char* anEntryStr = new char[aStrLen];
1163 anEntry.ToUTF8CString(anEntryStr);
1164 Handle(GEOM_Object) anObj = GetEngine()->GetObject(GetDocID(), anEntryStr, false);
1165 if (!anObj.IsNull()) {
1166 if (!theGroupsOnly || anObj->GetType() == GEOM_GROUP) {
1167 aSeq->Append(anObj);
1169 // for python command
1170 anAsciiList += anEntryStr;
1174 delete [] anEntryStr;
1177 if (aSeq->Length() == 0) {
1178 SetErrorCode(NOT_FOUND_ANY);
1182 //Make a Python command
1183 anAsciiList.Trunc(anAsciiList.Length() - 1);
1185 GEOM::TPythonDump pd (aMainShape, /*append=*/true);
1186 pd << "[" << anAsciiList.ToCString();
1187 pd << "] = geompy.GetExistingSubObjects(";
1188 pd << theShape << ", " << (bool)theGroupsOnly << ")";
1195 //=============================================================================
1199 //=============================================================================
1200 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::MakeExplode
1201 (Handle(GEOM_Object) theShape,
1202 const Standard_Integer theShapeType,
1203 const Standard_Boolean isSorted,
1204 const ExplodeType theExplodeType)
1208 if (theShape.IsNull()) return NULL;
1209 TopoDS_Shape aShape = theShape->GetValue();
1210 if (aShape.IsNull()) return NULL;
1212 Handle(GEOM_Function) aMainShape = theShape->GetLastFunction();
1214 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1215 Handle(GEOM_Object) anObj;
1216 TopTools_MapOfShape mapShape;
1217 TopTools_ListOfShape listShape;
1219 if (aShape.ShapeType() == TopAbs_COMPOUND &&
1220 (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
1221 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPSOLID ||
1222 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPOUND))
1224 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
1225 for (; It.More(); It.Next()) {
1226 if (mapShape.Add(It.Value())) {
1227 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
1228 TopAbs_ShapeEnum(theShapeType) == It.Value().ShapeType()) {
1229 listShape.Append(It.Value());
1234 else if (theExplodeType != EXPLODE_NEW_EXCLUDE_MAIN || aShape.ShapeType() != theShapeType) // issue 0021079
1236 TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
1237 for (; exp.More(); exp.Next())
1238 if (mapShape.Add(exp.Current()))
1239 listShape.Append(exp.Current());
1242 if (listShape.IsEmpty()) {
1243 //SetErrorCode("The given shape has no sub-shapes of the requested type");
1244 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
1249 bool isOldSorting = false;
1250 if (theExplodeType == EXPLODE_OLD_INCLUDE_MAIN)
1251 isOldSorting = true;
1252 SortShapes(listShape, isOldSorting);
1255 TopTools_IndexedMapOfShape anIndices;
1256 TopExp::MapShapes(aShape, anIndices);
1257 Handle(TColStd_HArray1OfInteger) anArray;
1259 TopTools_ListIteratorOfListOfShape itSub (listShape);
1260 TCollection_AsciiString anAsciiList, anEntry;
1261 for (int index = 1; itSub.More(); itSub.Next(), ++index)
1263 TopoDS_Shape aValue = itSub.Value();
1264 anArray = new TColStd_HArray1OfInteger(1,1);
1265 anArray->SetValue(1, anIndices.FindIndex(aValue));
1267 //anObj = GetEngine()->AddSubShape(theShape, anArray);
1269 anObj = GetEngine()->AddObject(GetDocID(), GEOM_SUBSHAPE);
1270 Handle(GEOM_Function) aFunction = anObj->AddFunction(GEOM_Object::GetSubShapeID(), 1);
1271 if (aFunction.IsNull()) return aSeq;
1273 GEOM_ISubShape aSSI (aFunction);
1274 aSSI.SetMainShape(aMainShape);
1275 aSSI.SetIndices(anArray);
1277 // Set function value directly, as we know it.
1278 // Usage of Solver here would lead to significant loss of time,
1279 // because GEOM_SubShapeDriver will build TopTools_IndexedMapOfShape
1280 // on the main shape for each being calculated sub-shape separately.
1281 aFunction->SetValue(aValue);
1283 // Put this subshape in the list of subshapes of theMainShape
1284 aMainShape->AddSubShapeReference(aFunction);
1287 if (!anObj.IsNull()) {
1288 aSeq->Append(anObj);
1290 // for python command
1291 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
1292 anAsciiList += anEntry;
1297 //Make a Python command
1298 anAsciiList.Trunc(anAsciiList.Length() - 1);
1300 GEOM::TPythonDump pd (aMainShape, /*append=*/true);
1301 pd << "[" << anAsciiList.ToCString() << "] = geompy.";
1302 switch (theExplodeType) {
1303 case EXPLODE_NEW_EXCLUDE_MAIN:
1304 pd << "ExtractShapes(" << theShape << ", "
1305 << TopAbs_ShapeEnum(theShapeType) << ", " << (isSorted ? "True" : "False") << ")";
1307 case EXPLODE_NEW_INCLUDE_MAIN:
1308 pd << "SubShapeAll" << (isSorted ? "SortedCentres(" : "(")
1309 << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
1311 case EXPLODE_OLD_INCLUDE_MAIN:
1312 pd << "SubShapeAll" << (isSorted ? "Sorted(" : "(")
1313 << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
1322 //=============================================================================
1326 //=============================================================================
1327 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::SubShapeAllIDs
1328 (Handle(GEOM_Object) theShape,
1329 const Standard_Integer theShapeType,
1330 const Standard_Boolean isSorted,
1331 const ExplodeType theExplodeType)
1335 if (theShape.IsNull()) return NULL;
1336 TopoDS_Shape aShape = theShape->GetValue();
1337 if (aShape.IsNull()) return NULL;
1339 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
1340 TopTools_MapOfShape mapShape;
1341 TopTools_ListOfShape listShape;
1343 if (aShape.ShapeType() == TopAbs_COMPOUND &&
1344 (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
1345 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPSOLID ||
1346 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPOUND))
1348 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
1349 for (; It.More(); It.Next()) {
1350 if (mapShape.Add(It.Value())) {
1351 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
1352 TopAbs_ShapeEnum(theShapeType) == It.Value().ShapeType()) {
1353 listShape.Append(It.Value());
1358 else if (theExplodeType != EXPLODE_NEW_EXCLUDE_MAIN || aShape.ShapeType() != theShapeType) // issue 0021079
1360 TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
1361 for (; exp.More(); exp.Next())
1362 if (mapShape.Add(exp.Current()))
1363 listShape.Append(exp.Current());
1366 if (listShape.IsEmpty()) {
1367 //SetErrorCode("The given shape has no sub-shapes of the requested type");
1368 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
1373 bool isOldSorting = false;
1374 if (theExplodeType == EXPLODE_OLD_INCLUDE_MAIN)
1375 isOldSorting = true;
1376 SortShapes(listShape, isOldSorting);
1379 TopTools_IndexedMapOfShape anIndices;
1380 TopExp::MapShapes(aShape, anIndices);
1381 Handle(TColStd_HArray1OfInteger) anArray;
1383 TopTools_ListIteratorOfListOfShape itSub (listShape);
1384 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
1385 TopoDS_Shape aValue = itSub.Value();
1386 aSeq->Append(anIndices.FindIndex(aValue));
1389 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
1391 //Make a Python command
1392 GEOM::TPythonDump pd (aFunction, /*append=*/true);
1393 pd << "listSubShapeIDs = geompy.SubShapeAll";
1394 switch (theExplodeType) {
1395 case EXPLODE_NEW_EXCLUDE_MAIN:
1397 case EXPLODE_NEW_INCLUDE_MAIN:
1398 pd << (isSorted ? "SortedCentresIDs(" : "IDs(")
1399 << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
1401 case EXPLODE_OLD_INCLUDE_MAIN:
1402 pd << (isSorted ? "SortedIDs(" : "IDs(")
1403 << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
1412 //=============================================================================
1416 //=============================================================================
1417 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetSubShape
1418 (Handle(GEOM_Object) theMainShape,
1419 const Standard_Integer theID)
1423 if (theMainShape.IsNull()) return NULL;
1425 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
1426 anArray->SetValue(1, theID);
1427 Handle(GEOM_Object) anObj = GetEngine()->AddSubShape(theMainShape, anArray,true);
1428 if (anObj.IsNull()) {
1429 SetErrorCode("Can not get a sub-shape with the given ID");
1433 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1435 //Make a Python command
1436 GEOM::TPythonDump(aFunction) << anObj << " = geompy.GetSubShape("
1437 << theMainShape << ", [" << theID << "])";
1443 //=============================================================================
1447 //=============================================================================
1448 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::MakeSubShapes
1449 (Handle(GEOM_Object) theMainShape,
1450 Handle(TColStd_HArray1OfInteger) theIndices)
1454 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1456 if (!theIndices->Length()) {
1457 SetErrorCode(NOT_FOUND_ANY);
1461 if (theMainShape.IsNull()) return NULL;
1462 TopoDS_Shape aShape = theMainShape->GetValue();
1463 if (aShape.IsNull()) return NULL;
1465 Handle(GEOM_Function) aMainShape = theMainShape->GetLastFunction();
1467 TopTools_IndexedMapOfShape anIndices;
1468 TopExp::MapShapes(aShape, anIndices);
1470 Handle(TColStd_HArray1OfInteger) anArray;
1471 Handle(GEOM_Object) anObj;
1473 TCollection_AsciiString anAsciiList, anEntry;
1474 Standard_Integer i, low = theIndices->Lower(), up = theIndices->Upper();
1475 for (i = low; i <= up; i++) {
1476 int id = theIndices->Value(i);
1477 if (1 <= id && id <= anIndices.Extent()) {
1478 TopoDS_Shape aValue = anIndices.FindKey(id);
1479 anArray = new TColStd_HArray1OfInteger(1,1);
1480 anArray->SetValue(1, id);
1482 anObj = GetEngine()->AddObject(GetDocID(), GEOM_SUBSHAPE);
1483 if (!anObj.IsNull()) {
1484 Handle(GEOM_Function) aFunction = anObj->AddFunction(GEOM_Object::GetSubShapeID(), 1);
1485 if (aFunction.IsNull()) return aSeq;
1487 GEOM_ISubShape aSSI (aFunction);
1488 aSSI.SetMainShape(aMainShape);
1489 aSSI.SetIndices(anArray);
1491 // Set function value directly, as we know it.
1492 // Usage of Solver here would lead to significant loss of time,
1493 // because GEOM_SubShapeDriver will build TopTools_IndexedMapOfShape
1494 // on the main shape for each being calculated sub-shape separately.
1495 aFunction->SetValue(aValue);
1497 // Put this subshape in the list of subshapes of theMainShape
1498 aMainShape->AddSubShapeReference(aFunction);
1500 aSeq->Append(anObj);
1502 // for python command
1503 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
1504 anAsciiList += anEntry;
1510 //Make a Python command
1511 anAsciiList.Trunc(anAsciiList.Length() - 1);
1513 GEOM::TPythonDump pd (aMainShape, /*append=*/true);
1514 pd << "[" << anAsciiList.ToCString() << "] = geompy.SubShapes("
1515 << theMainShape << ", [" ;
1516 for (i = low; i <= up - 1; i++) {
1517 pd << theIndices->Value(i) << ", ";
1519 pd << theIndices->Value(up) << "])";
1526 //=============================================================================
1530 //=============================================================================
1531 Standard_Integer GEOMImpl_IShapesOperations::GetSubShapeIndex (Handle(GEOM_Object) theMainShape,
1532 Handle(GEOM_Object) theSubShape)
1536 TopoDS_Shape aMainShape = theMainShape->GetValue();
1537 TopoDS_Shape aSubShape = theSubShape->GetValue();
1539 if (aMainShape.IsNull() || aSubShape.IsNull()) return -1;
1541 TopTools_IndexedMapOfShape anIndices;
1542 TopExp::MapShapes(aMainShape, anIndices);
1543 if (anIndices.Contains(aSubShape)) {
1545 return anIndices.FindIndex(aSubShape);
1551 //=============================================================================
1555 //=============================================================================
1556 Standard_Integer GEOMImpl_IShapesOperations::GetTopologyIndex (Handle(GEOM_Object) theMainShape,
1557 Handle(GEOM_Object) theSubShape)
1561 TopoDS_Shape aMainShape = theMainShape->GetValue();
1562 TopoDS_Shape aSubShape = theSubShape->GetValue();
1564 if (aMainShape.IsNull() || aSubShape.IsNull()) {
1565 SetErrorCode("Null argument shape given");
1570 if (aSubShape.ShapeType() == TopAbs_COMPOUND) {
1572 TopTools_ListOfShape CL;
1573 CL.Append(aMainShape);
1574 TopTools_ListIteratorOfListOfShape itC;
1575 for (itC.Initialize(CL); itC.More(); itC.Next()) {
1576 for (it.Initialize(itC.Value()); it.More(); it.Next()) {
1577 if (it.Value().ShapeType() == TopAbs_COMPOUND) {
1578 if (it.Value().IsSame(aSubShape))
1582 CL.Append(it.Value());
1587 TopExp_Explorer anExp (aMainShape, aSubShape.ShapeType());
1588 TopTools_MapOfShape M;
1589 for (; anExp.More(); anExp.Next()) {
1590 if (M.Add(anExp.Current())) {
1591 if (anExp.Current().IsSame(aSubShape))
1598 SetErrorCode("The sub-shape does not belong to the main shape");
1602 //=============================================================================
1604 * GetShapeTypeString
1606 //=============================================================================
1607 TCollection_AsciiString GEOMImpl_IShapesOperations::GetShapeTypeString (Handle(GEOM_Object) theShape)
1611 TCollection_AsciiString aTypeName ("Null Shape");
1613 TopoDS_Shape aShape = theShape->GetValue();
1614 if (aShape.IsNull())
1617 switch (aShape.ShapeType() )
1619 case TopAbs_COMPOUND:
1620 aTypeName = "Compound";
1622 case TopAbs_COMPSOLID:
1623 aTypeName = "Compound Solid";
1626 aTypeName = "Solid";
1629 aTypeName = "Shell";
1633 BRepAdaptor_Surface surf (TopoDS::Face(aShape));
1634 if (surf.GetType() == GeomAbs_Plane)
1635 aTypeName = "Plane";
1636 else if (surf.GetType() == GeomAbs_Cylinder)
1637 aTypeName = "Cylindrical Face";
1638 else if (surf.GetType() == GeomAbs_Sphere)
1639 aTypeName = "Spherical Face";
1640 else if (surf.GetType() == GeomAbs_Torus)
1641 aTypeName = "Toroidal Face";
1642 else if (surf.GetType() == GeomAbs_Cone)
1643 aTypeName = "Conical Face";
1645 aTypeName = "GEOM::FACE";
1653 BRepAdaptor_Curve curv (TopoDS::Edge(aShape));
1654 if (curv.GetType() == GeomAbs_Line) {
1655 if ((Abs(curv.FirstParameter()) >= 1E6) ||
1656 (Abs(curv.LastParameter()) >= 1E6))
1660 } else if (curv.GetType() == GeomAbs_Circle) {
1661 if (curv.IsClosed())
1662 aTypeName = "Circle";
1671 aTypeName = "Vertex";
1674 aTypeName = "Shape";
1677 aTypeName = "Shape of unknown type";
1683 //=============================================================================
1687 //=============================================================================
1688 Standard_Integer GEOMImpl_IShapesOperations::NumberOfSubShapes
1689 (Handle(GEOM_Object) theShape,
1690 const Standard_Integer theShapeType)
1693 Standard_Integer nbShapes = 0;
1695 if (theShape.IsNull()) return -1;
1696 TopoDS_Shape aShape = theShape->GetValue();
1697 if (aShape.IsNull()) return -1;
1700 TopTools_MapOfShape mapShape;
1702 if (aShape.ShapeType() == TopAbs_COMPOUND &&
1703 (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
1704 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPSOLID ||
1705 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPOUND)) {
1706 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
1707 for (; It.More(); It.Next()) {
1708 if (mapShape.Add(It.Value())) {
1709 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
1710 TopAbs_ShapeEnum(theShapeType) == It.Value().ShapeType()) {
1716 TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
1717 for (; exp.More(); exp.Next())
1718 if (mapShape.Add(exp.Current()))
1724 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
1727 int iType, nbTypes [TopAbs_SHAPE];
1728 for (iType = 0; iType < TopAbs_SHAPE; ++iType)
1730 nbTypes[aShape.ShapeType()]++;
1732 TopTools_MapOfShape aMapOfShape;
1733 aMapOfShape.Add(aShape);
1734 TopTools_ListOfShape aListOfShape;
1735 aListOfShape.Append(aShape);
1737 TopTools_ListIteratorOfListOfShape itL (aListOfShape);
1738 for (; itL.More(); itL.Next()) {
1739 TopoDS_Iterator it (itL.Value());
1740 for (; it.More(); it.Next()) {
1741 TopoDS_Shape s = it.Value();
1742 if (aMapOfShape.Add(s)) {
1743 aListOfShape.Append(s);
1744 nbTypes[s.ShapeType()]++;
1749 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE)
1750 nbShapes = aMapOfShape.Extent();
1752 nbShapes = nbTypes[theShapeType];
1754 catch (Standard_Failure) {
1755 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1756 SetErrorCode(aFail->GetMessageString());
1764 //=============================================================================
1768 //=============================================================================
1769 Handle(GEOM_Object) GEOMImpl_IShapesOperations::ReverseShape(Handle(GEOM_Object) theShape)
1773 if (theShape.IsNull()) return NULL;
1775 //Add a new reversed object
1776 Handle(GEOM_Object) aReversed = GetEngine()->AddObject(GetDocID(), theShape->GetType());
1778 //Add a new Revese function
1779 Handle(GEOM_Function) aFunction;
1780 aFunction = aReversed->AddFunction(GEOMImpl_ShapeDriver::GetID(), REVERSE_ORIENTATION);
1781 if (aFunction.IsNull()) return NULL;
1783 //Check if the function is set correctly
1784 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
1786 GEOMImpl_IShapes aSI (aFunction);
1788 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
1789 if (aRefShape.IsNull()) return NULL;
1791 aSI.SetBase(aRefShape);
1793 //Compute the sub-shape value
1795 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
1798 if (!GetSolver()->ComputeFunction(aFunction)) {
1799 SetErrorCode("Shape driver failed to reverse shape");
1803 catch (Standard_Failure) {
1804 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1805 SetErrorCode(aFail->GetMessageString());
1809 //Make a Python command
1810 GEOM::TPythonDump(aFunction) << aReversed
1811 << " = geompy.ChangeOrientation(" << theShape << ")";
1817 //=============================================================================
1821 //=============================================================================
1822 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetFreeFacesIDs
1823 (Handle(GEOM_Object) theShape)
1827 if (theShape.IsNull()) return NULL;
1828 TopoDS_Shape aShape = theShape->GetValue();
1829 if (aShape.IsNull()) return NULL;
1831 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
1833 TopTools_IndexedDataMapOfShapeListOfShape mapFaceBlocks;
1834 GEOMImpl_Block6Explorer::MapShapesAndAncestors
1835 (aShape, TopAbs_FACE, TopAbs_SOLID, mapFaceBlocks);
1837 Standard_Integer ind = 1, nbFaces = mapFaceBlocks.Extent();
1840 SetErrorCode("The given shape has no faces");
1844 TopTools_IndexedMapOfShape anIndices;
1845 TopExp::MapShapes(aShape, anIndices);
1847 Standard_Integer id;
1848 for (; ind <= nbFaces; ind++) {
1849 if (mapFaceBlocks.FindFromIndex(ind).Extent() != 2) {
1850 id = anIndices.FindIndex(mapFaceBlocks.FindKey(ind));
1855 //The explode doesn't change object so no new function is required.
1856 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
1858 //Make a Python command
1859 GEOM::TPythonDump(aFunction, /*append=*/true)
1860 << "listFreeFacesIDs = geompy.GetFreeFacesIDs(" << theShape << ")";
1866 //=======================================================================
1867 //function : GetSharedShapes
1869 //=======================================================================
1870 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetSharedShapes
1871 (Handle(GEOM_Object) theShape1,
1872 Handle(GEOM_Object) theShape2,
1873 const Standard_Integer theShapeType)
1877 if (theShape1.IsNull() || theShape2.IsNull()) return NULL;
1879 TopoDS_Shape aShape1 = theShape1->GetValue();
1880 TopoDS_Shape aShape2 = theShape2->GetValue();
1882 if (aShape1.IsNull() || aShape2.IsNull()) return NULL;
1884 TopTools_IndexedMapOfShape anIndices;
1885 TopExp::MapShapes(aShape1, anIndices);
1886 Handle(TColStd_HArray1OfInteger) anArray;
1888 TopTools_IndexedMapOfShape mapShape1;
1889 TopExp::MapShapes(aShape1, TopAbs_ShapeEnum(theShapeType), mapShape1);
1891 Handle(GEOM_Object) anObj;
1892 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1893 TCollection_AsciiString anAsciiList, anEntry;
1895 TopTools_MapOfShape mapShape2;
1896 TopExp_Explorer exp (aShape2, TopAbs_ShapeEnum(theShapeType));
1897 for (; exp.More(); exp.Next()) {
1898 TopoDS_Shape aSS = exp.Current();
1899 if (mapShape2.Add(aSS) && mapShape1.Contains(aSS)) {
1900 anArray = new TColStd_HArray1OfInteger(1,1);
1901 anArray->SetValue(1, anIndices.FindIndex(aSS));
1902 anObj = GetEngine()->AddSubShape(theShape1, anArray);
1903 aSeq->Append(anObj);
1905 // for python command
1906 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
1907 anAsciiList += anEntry;
1912 if (aSeq->IsEmpty()) {
1913 SetErrorCode("The given shapes have no shared sub-shapes of the requested type");
1917 //Make a Python command
1918 anAsciiList.Trunc(anAsciiList.Length() - 1);
1920 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1922 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
1923 << "] = geompy.GetSharedShapes(" << theShape1 << ", "
1924 << theShape2 << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
1930 //=======================================================================
1931 //function : GetSharedShapes
1933 //=======================================================================
1934 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetSharedShapes
1935 (std::list<Handle(GEOM_Object)> theShapes,
1936 const Standard_Integer theShapeType)
1940 int aLen = theShapes.size();
1941 if (aLen < 1) return NULL;
1944 std::list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
1946 Handle(GEOM_Object) aMainObj = (*it++);
1947 Handle(GEOM_Function) aMainShape = aMainObj->GetLastFunction();
1948 if (aMainShape.IsNull()) {
1949 SetErrorCode("NULL shape for GetSharedShapes");
1953 TopoDS_Shape aShape1 = aMainShape->GetValue();
1954 if (aShape1.IsNull()) return NULL;
1956 TopTools_IndexedMapOfShape anIndices;
1957 TopExp::MapShapes(aShape1, anIndices);
1959 TopTools_IndexedMapOfShape mapSelected;
1960 TopExp::MapShapes(aShape1, TopAbs_ShapeEnum(theShapeType), mapSelected);
1962 // Find shared shapes
1964 TopoDS_Compound aCurrSelection;
1966 for (; it != theShapes.end(); it++, ind++) {
1967 Handle(GEOM_Function) aRefShape = (*it)->GetLastFunction();
1968 if (aRefShape.IsNull()) {
1969 SetErrorCode("NULL shape for GetSharedShapes");
1973 TopoDS_Compound aCompound;
1974 B.MakeCompound(aCompound);
1976 TopoDS_Shape aShape2 = aRefShape->GetValue();
1977 if (aShape2.IsNull()) return NULL;
1979 TopTools_MapOfShape mapShape2;
1980 TopExp_Explorer exp (aShape2, TopAbs_ShapeEnum(theShapeType));
1981 for (; exp.More(); exp.Next()) {
1982 TopoDS_Shape aSS = exp.Current();
1983 if (mapShape2.Add(aSS) && mapSelected.Contains(aSS)) {
1984 B.Add(aCompound, aSS);
1988 mapSelected.Clear();
1989 TopExp::MapShapes(aCompound, TopAbs_ShapeEnum(theShapeType), mapSelected);
1990 aCurrSelection = aCompound;
1993 // Create GEOM_Object for each found shared shape (collected in aCurrSelection)
1994 Handle(GEOM_Object) anObj;
1995 Handle(TColStd_HArray1OfInteger) anArray;
1996 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1997 TCollection_AsciiString anAsciiList, anEntry;
1999 TopoDS_Iterator itSel (aCurrSelection, Standard_True, Standard_True);
2000 for (; itSel.More(); itSel.Next()) {
2001 anArray = new TColStd_HArray1OfInteger(1,1);
2002 anArray->SetValue(1, anIndices.FindIndex(itSel.Value()));
2003 anObj = GetEngine()->AddSubShape(aMainObj, anArray);
2004 aSeq->Append(anObj);
2006 // for python command
2007 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
2008 anAsciiList += anEntry;
2012 if (aSeq->IsEmpty()) {
2013 SetErrorCode("The given shapes have no shared sub-shapes of the requested type");
2017 // Make a Python command
2018 anAsciiList.Trunc(anAsciiList.Length() - 1);
2020 GEOM::TPythonDump pd (aMainShape, /*append=*/true);
2021 pd << "[" << anAsciiList.ToCString()
2022 << "] = geompy.GetSharedShapesMulti([";
2024 it = theShapes.begin();
2026 while (it != theShapes.end()) {
2027 pd << ", " << (*it++);
2030 pd << "], " << TopAbs_ShapeEnum(theShapeType) << ")";
2036 //=============================================================================
2040 //=============================================================================
2041 static GEOM::TPythonDump& operator<< (GEOM::TPythonDump& theDump,
2042 const GEOMAlgo_State theState)
2045 case GEOMAlgo_ST_IN:
2046 theDump << "geompy.GEOM.ST_IN";
2048 case GEOMAlgo_ST_OUT:
2049 theDump << "geompy.GEOM.ST_OUT";
2051 case GEOMAlgo_ST_ON:
2052 theDump << "geompy.GEOM.ST_ON";
2054 case GEOMAlgo_ST_ONIN:
2055 theDump << "geompy.GEOM.ST_ONIN";
2057 case GEOMAlgo_ST_ONOUT:
2058 theDump << "geompy.GEOM.ST_ONOUT";
2061 theDump << "geompy.GEOM.ST_UNKNOWN";
2067 //=======================================================================
2068 //function : checkTypeShapesOn
2070 * \brief Checks if theShapeType parameter of GetShapesOnXXX() is OK
2071 * \param theShapeType - the shape type to check
2072 * \retval bool - result of the check
2074 //=======================================================================
2075 bool GEOMImpl_IShapesOperations::checkTypeShapesOn(const Standard_Integer theShapeType)
2077 if (theShapeType != TopAbs_VERTEX &&
2078 theShapeType != TopAbs_EDGE &&
2079 theShapeType != TopAbs_FACE &&
2080 theShapeType != TopAbs_SOLID) {
2081 SetErrorCode("Only solids, vertices, edges or faces can be found by this method");
2087 //=======================================================================
2088 //function : makePlane
2090 * \brief Creates Geom_Plane
2091 * \param theAx1 - shape object defining plane parameters
2092 * \retval Handle(Geom_Surface) - resulting surface
2094 //=======================================================================
2095 Handle(Geom_Surface) GEOMImpl_IShapesOperations::makePlane(const TopoDS_Shape& anAx1)
2097 if (anAx1.ShapeType() != TopAbs_EDGE) return NULL;
2098 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
2099 TopoDS_Vertex V1, V2;
2100 TopExp::Vertices(anEdge, V1, V2, Standard_True);
2101 if (V1.IsNull() || V2.IsNull()) {
2102 SetErrorCode("Bad edge given for the plane normal vector");
2105 gp_Pnt aLoc = BRep_Tool::Pnt(V1);
2106 gp_Vec aVec (aLoc, BRep_Tool::Pnt(V2));
2107 if (aVec.Magnitude() < Precision::Confusion()) {
2108 SetErrorCode("Vector with null magnitude given");
2111 return new Geom_Plane(aLoc, aVec);
2114 //=======================================================================
2115 //function : makeCylinder
2117 * \brief Creates Geom_CylindricalSurface
2118 * \param theAx1 - edge defining cylinder axis
2119 * \param theRadius - cylinder radius
2120 * \retval Handle(Geom_Surface) - resulting surface
2122 //=======================================================================
2123 Handle(Geom_Surface) GEOMImpl_IShapesOperations::makeCylinder(const TopoDS_Shape& anAxis,
2124 const Standard_Real theRadius)
2126 //Axis of the cylinder
2127 if (anAxis.ShapeType() != TopAbs_EDGE) {
2128 SetErrorCode("Not an edge given for the axis");
2131 TopoDS_Edge anEdge = TopoDS::Edge(anAxis);
2132 TopoDS_Vertex V1, V2;
2133 TopExp::Vertices(anEdge, V1, V2, Standard_True);
2134 if (V1.IsNull() || V2.IsNull()) {
2135 SetErrorCode("Bad edge given for the axis");
2138 gp_Pnt aLoc = BRep_Tool::Pnt(V1);
2139 gp_Vec aVec (aLoc, BRep_Tool::Pnt(V2));
2140 if (aVec.Magnitude() < Precision::Confusion()) {
2141 SetErrorCode("Vector with null magnitude given");
2145 gp_Ax3 anAx3 (aLoc, aVec);
2146 return new Geom_CylindricalSurface(anAx3, theRadius);
2149 //=======================================================================
2150 //function : getShapesOnBoxIDs
2152 * \brief Find IDs of subshapes complying with given status about surface
2153 * \param theBox - the box to check state of subshapes against
2154 * \param theShape - the shape to explore
2155 * \param theShapeType - type of subshape of theShape
2156 * \param theState - required state
2157 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
2159 //=======================================================================
2160 Handle(TColStd_HSequenceOfInteger)
2161 GEOMImpl_IShapesOperations::getShapesOnBoxIDs(const Handle(GEOM_Object)& theBox,
2162 const Handle(GEOM_Object)& theShape,
2163 const Standard_Integer theShapeType,
2164 GEOMAlgo_State theState)
2166 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
2168 TopoDS_Shape aBox = theBox->GetValue();
2169 TopoDS_Shape aShape = theShape->GetValue();
2171 // Check presence of triangulation, build if need
2172 if (!CheckTriangulation(aShape)) {
2173 SetErrorCode("Cannot build triangulation on the shape");
2178 GEOMAlgo_FinderShapeOn2 aFinder;
2179 Standard_Real aTol = 0.0001; // default value
2181 Handle(GEOMAlgo_ClsfBox) aClsfBox = new GEOMAlgo_ClsfBox;
2182 aClsfBox->SetBox(aBox);
2184 aFinder.SetShape(aShape);
2185 aFinder.SetTolerance(aTol);
2186 aFinder.SetClsf(aClsfBox);
2187 aFinder.SetShapeType( (TopAbs_ShapeEnum)theShapeType );
2188 aFinder.SetState(theState);
2191 // Interprete results
2192 Standard_Integer iErr = aFinder.ErrorStatus();
2193 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
2195 MESSAGE(" iErr : " << iErr);
2196 TCollection_AsciiString aMsg (" iErr : ");
2197 aMsg += TCollection_AsciiString(iErr);
2201 Standard_Integer iWrn = aFinder.WarningStatus();
2202 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
2204 MESSAGE(" *** iWrn : " << iWrn);
2207 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
2209 if (listSS.Extent() < 1) {
2210 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
2211 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
2215 // Fill sequence of object IDs
2216 aSeqOfIDs = new TColStd_HSequenceOfInteger;
2218 TopTools_IndexedMapOfShape anIndices;
2219 TopExp::MapShapes(aShape, anIndices);
2221 TopTools_ListIteratorOfListOfShape itSub (listSS);
2222 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
2223 int id = anIndices.FindIndex(itSub.Value());
2224 aSeqOfIDs->Append(id);
2230 //=======================================================================
2231 //function : GetShapesOnBoxIDs
2233 * \brief Find subshapes complying with given status about surface
2234 * \param theBox - the box to check state of subshapes against
2235 * \param theShape - the shape to explore
2236 * \param theShapeType - type of subshape of theShape
2237 * \param theState - required state
2238 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
2240 //=======================================================================
2241 Handle(TColStd_HSequenceOfInteger)
2242 GEOMImpl_IShapesOperations::GetShapesOnBoxIDs(const Handle(GEOM_Object)& theBox,
2243 const Handle(GEOM_Object)& theShape,
2244 const Standard_Integer theShapeType,
2245 GEOMAlgo_State theState)
2247 // Find subshapes ids
2248 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2249 getShapesOnBoxIDs (theBox, theShape, theShapeType, theState);
2250 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2253 // The GetShapesOnBox() doesn't change object so no new function is required.
2254 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theBox)->GetLastFunction();
2256 // Make a Python command
2257 GEOM::TPythonDump(aFunction)
2258 << "listShapesOnBoxIDs = geompy.GetShapesOnBoxIDs("
2261 << TopAbs_ShapeEnum(theShapeType) << ", "
2268 //=======================================================================
2269 //function : GetShapesOnBox
2271 * \brief Find subshapes complying with given status about surface
2272 * \param theBox - the box to check state of subshapes against
2273 * \param theShape - the shape to explore
2274 * \param theShapeType - type of subshape of theShape
2275 * \param theState - required state
2276 * \retval Handle(TColStd_HSequenceOfTransient) - found subshapes
2278 //=======================================================================
2279 Handle(TColStd_HSequenceOfTransient)
2280 GEOMImpl_IShapesOperations::GetShapesOnBox(const Handle(GEOM_Object)& theBox,
2281 const Handle(GEOM_Object)& theShape,
2282 const Standard_Integer theShapeType,
2283 GEOMAlgo_State theState)
2285 // Find subshapes ids
2286 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2287 getShapesOnBoxIDs (theBox, theShape, theShapeType, theState);
2288 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2291 // Find objects by indices
2292 TCollection_AsciiString anAsciiList;
2293 Handle(TColStd_HSequenceOfTransient) aSeq;
2294 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
2295 if ( aSeq.IsNull() || aSeq->IsEmpty() )
2298 // Make a Python command
2300 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2301 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2303 GEOM::TPythonDump(aFunction)
2304 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnBox("
2307 << TopAbs_ShapeEnum(theShapeType) << ", "
2314 //=======================================================================
2315 //function : getShapesOnShapeIDs
2317 * \brief Find IDs of subshapes complying with given status about surface
2318 * \param theCheckShape - the shape to check state of subshapes against
2319 * \param theShape - the shape to explore
2320 * \param theShapeType - type of subshape of theShape
2321 * \param theState - required state
2322 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
2324 //=======================================================================
2325 Handle(TColStd_HSequenceOfInteger)
2326 GEOMImpl_IShapesOperations::getShapesOnShapeIDs
2327 (const Handle(GEOM_Object)& theCheckShape,
2328 const Handle(GEOM_Object)& theShape,
2329 const Standard_Integer theShapeType,
2330 GEOMAlgo_State theState)
2332 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
2334 TopoDS_Shape aCheckShape = theCheckShape->GetValue();
2335 TopoDS_Shape aShape = theShape->GetValue();
2336 TopTools_ListOfShape res;
2338 // Check presence of triangulation, build if need
2339 if (!CheckTriangulation(aShape)) {
2340 SetErrorCode("Cannot build triangulation on the shape");
2345 GEOMAlgo_FinderShapeOn2 aFinder;
2346 Standard_Real aTol = 0.0001; // default value
2348 Handle(GEOMAlgo_ClsfSolid) aClsfSolid = new GEOMAlgo_ClsfSolid;
2349 aClsfSolid->SetShape(aCheckShape);
2351 aFinder.SetShape(aShape);
2352 aFinder.SetTolerance(aTol);
2353 aFinder.SetClsf(aClsfSolid);
2354 aFinder.SetShapeType( (TopAbs_ShapeEnum)theShapeType );
2355 aFinder.SetState(theState);
2358 // Interprete results
2359 Standard_Integer iErr = aFinder.ErrorStatus();
2360 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
2363 SetErrorCode("theCheckShape must be a solid");
2366 MESSAGE(" iErr : " << iErr);
2367 TCollection_AsciiString aMsg (" iErr : ");
2368 aMsg += TCollection_AsciiString(iErr);
2373 Standard_Integer iWrn = aFinder.WarningStatus();
2374 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
2376 MESSAGE(" *** iWrn : " << iWrn);
2379 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
2381 if (listSS.Extent() < 1) {
2382 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
2383 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
2386 // Fill sequence of object IDs
2387 aSeqOfIDs = new TColStd_HSequenceOfInteger;
2389 TopTools_IndexedMapOfShape anIndices;
2390 TopExp::MapShapes(aShape, anIndices);
2392 TopTools_ListIteratorOfListOfShape itSub (listSS);
2393 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
2394 int id = anIndices.FindIndex(itSub.Value());
2395 aSeqOfIDs->Append(id);
2401 //=======================================================================
2402 //function : GetShapesOnShapeIDs
2404 * \brief Find subshapes complying with given status about surface
2405 * \param theCheckShape - the shape to check state of subshapes against
2406 * \param theShape - the shape to explore
2407 * \param theShapeType - type of subshape of theShape
2408 * \param theState - required state
2409 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
2411 //=======================================================================
2412 Handle(TColStd_HSequenceOfInteger)
2413 GEOMImpl_IShapesOperations::GetShapesOnShapeIDs
2414 (const Handle(GEOM_Object)& theCheckShape,
2415 const Handle(GEOM_Object)& theShape,
2416 const Standard_Integer theShapeType,
2417 GEOMAlgo_State theState)
2419 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2420 getShapesOnShapeIDs (theCheckShape, theShape, theShapeType, theState);
2422 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2425 // The GetShapesOnShape() doesn't change object so no new function is required.
2426 Handle(GEOM_Function) aFunction =
2427 GEOM::GetCreatedLast(theShape,theCheckShape)->GetLastFunction();
2429 // Make a Python command
2430 GEOM::TPythonDump(aFunction)
2431 << "listShapesOnBoxIDs = geompy.GetShapesOnShapeIDs("
2432 << theCheckShape << ", "
2434 << TopAbs_ShapeEnum(theShapeType) << ", "
2441 //=======================================================================
2442 //function : GetShapesOnShape
2444 * \brief Find subshapes complying with given status about surface
2445 * \param theCheckShape - the shape to check state of subshapes against
2446 * \param theShape - the shape to explore
2447 * \param theShapeType - type of subshape of theShape
2448 * \param theState - required state
2449 * \retval Handle(TColStd_HSequenceOfTransient) - found subshapes
2451 //=======================================================================
2452 Handle(TColStd_HSequenceOfTransient)
2453 GEOMImpl_IShapesOperations::GetShapesOnShape
2454 (const Handle(GEOM_Object)& theCheckShape,
2455 const Handle(GEOM_Object)& theShape,
2456 const Standard_Integer theShapeType,
2457 GEOMAlgo_State theState)
2459 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2460 getShapesOnShapeIDs (theCheckShape, theShape, theShapeType, theState);
2461 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2464 // Find objects by indices
2465 TCollection_AsciiString anAsciiList;
2466 Handle(TColStd_HSequenceOfTransient) aSeq;
2467 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
2469 if ( aSeq.IsNull() || aSeq->IsEmpty() )
2472 // Make a Python command
2474 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2475 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2477 GEOM::TPythonDump(aFunction)
2478 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnShape("
2479 << theCheckShape << ", "
2481 << TopAbs_ShapeEnum(theShapeType) << ", "
2488 //=======================================================================
2489 //function : GetShapesOnShapeAsCompound
2490 //=======================================================================
2491 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetShapesOnShapeAsCompound
2492 (const Handle(GEOM_Object)& theCheckShape,
2493 const Handle(GEOM_Object)& theShape,
2494 const Standard_Integer theShapeType,
2495 GEOMAlgo_State theState)
2497 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2498 getShapesOnShapeIDs (theCheckShape, theShape, theShapeType, theState);
2500 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2503 // Find objects by indices
2504 TCollection_AsciiString anAsciiList;
2505 Handle(TColStd_HSequenceOfTransient) aSeq;
2506 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
2508 if ( aSeq.IsNull() || aSeq->IsEmpty() )
2511 TopoDS_Compound aCompound;
2513 B.MakeCompound(aCompound);
2515 for(; i<=aSeq->Length(); i++) {
2516 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(aSeq->Value(i));
2517 TopoDS_Shape aShape_i = anObj->GetValue();
2518 B.Add(aCompound,aShape_i);
2521 //Add a new result object
2522 Handle(GEOM_Object) aRes = GetEngine()->AddObject(GetDocID(), GEOM_SHAPES_ON_SHAPE);
2523 Handle(GEOM_Function) aFunction =
2524 aRes->AddFunction(GEOMImpl_ShapeDriver::GetID(), SHAPES_ON_SHAPE);
2525 aFunction->SetValue(aCompound);
2527 GEOM::TPythonDump(aFunction)
2528 << aRes << " = geompy.GetShapesOnShapeAsCompound("
2529 << theCheckShape << ", "
2531 << TopAbs_ShapeEnum(theShapeType) << ", "
2539 //=======================================================================
2540 //function : getShapesOnSurfaceIDs
2542 * \brief Find IDs of subshapes complying with given status about surface
2543 * \param theSurface - the surface to check state of subshapes against
2544 * \param theShape - the shape to explore
2545 * \param theShapeType - type of subshape of theShape
2546 * \param theState - required state
2547 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
2549 //=======================================================================
2550 Handle(TColStd_HSequenceOfInteger)
2551 GEOMImpl_IShapesOperations::getShapesOnSurfaceIDs(const Handle(Geom_Surface)& theSurface,
2552 const TopoDS_Shape& theShape,
2553 TopAbs_ShapeEnum theShapeType,
2554 GEOMAlgo_State theState)
2556 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
2558 // Check presence of triangulation, build if need
2559 if (!CheckTriangulation(theShape)) {
2560 SetErrorCode("Cannot build triangulation on the shape");
2564 // BEGIN: Mantis issue 0020961: Error on a pipe T-Shape
2565 // Compute tolerance
2566 Standard_Real T, VertMax = -RealLast();
2568 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
2571 for (TopExp_Explorer ExV (theShape, TopAbs_VERTEX); ExV.More(); ExV.Next()) {
2572 TopoDS_Vertex Vertex = TopoDS::Vertex(ExV.Current());
2573 T = BRep_Tool::Tolerance(Vertex);
2578 catch (Standard_Failure) {
2579 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2580 SetErrorCode(aFail->GetMessageString());
2583 // END: Mantis issue 0020961
2586 GEOMAlgo_FinderShapeOn1 aFinder;
2587 //Standard_Real aTol = 0.0001; // default value
2588 Standard_Real aTol = VertMax; // Mantis issue 0020961
2590 aFinder.SetShape(theShape);
2591 aFinder.SetTolerance(aTol);
2592 aFinder.SetSurface(theSurface);
2593 aFinder.SetShapeType(theShapeType);
2594 aFinder.SetState(theState);
2596 // Sets the minimal number of inner points for the faces that do not have own
2597 // inner points at all (for e.g. rectangular planar faces have just 2 triangles).
2599 aFinder.SetNbPntsMin(3);
2600 // Sets the maximal number of inner points for edges or faces.
2601 // It is usefull for the cases when this number is very big (e.g =2000) to improve
2602 // the performance. If this value =0, all inner points will be taken into account.
2604 aFinder.SetNbPntsMax(100);
2608 // Interprete results
2609 Standard_Integer iErr = aFinder.ErrorStatus();
2610 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
2612 MESSAGE(" iErr : " << iErr);
2613 TCollection_AsciiString aMsg (" iErr : ");
2614 aMsg += TCollection_AsciiString(iErr);
2618 Standard_Integer iWrn = aFinder.WarningStatus();
2619 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
2621 MESSAGE(" *** iWrn : " << iWrn);
2624 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
2626 if (listSS.Extent() < 1) {
2627 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
2628 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
2632 // Fill sequence of object IDs
2633 aSeqOfIDs = new TColStd_HSequenceOfInteger;
2635 TopTools_IndexedMapOfShape anIndices;
2636 TopExp::MapShapes(theShape, anIndices);
2638 TopTools_ListIteratorOfListOfShape itSub (listSS);
2639 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
2640 int id = anIndices.FindIndex(itSub.Value());
2641 aSeqOfIDs->Append(id);
2647 //=======================================================================
2648 //function : getObjectsShapesOn
2650 * \brief Find shape objects and their entries by their ids
2651 * \param theShapeIDs - incoming shape ids
2652 * \param theShapeEntries - outgoing entries like "entry1, entry2, ..."
2653 * \retval Handle(TColStd_HSequenceOfTransient) - found shape objects
2655 //=======================================================================
2656 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::
2657 getObjectsShapesOn(const Handle(GEOM_Object)& theShape,
2658 const Handle(TColStd_HSequenceOfInteger)& theShapeIDs,
2659 TCollection_AsciiString & theShapeEntries)
2661 Handle(TColStd_HSequenceOfTransient) aSeq;
2663 if ( !theShapeIDs.IsNull() && theShapeIDs->Length() > 0 )
2665 aSeq = new TColStd_HSequenceOfTransient;
2666 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
2667 TCollection_AsciiString anEntry;
2668 for ( int i = 1; i <= theShapeIDs->Length(); ++i )
2670 anArray->SetValue(1, theShapeIDs->Value( i ));
2671 Handle(GEOM_Object) anObj = GetEngine()->AddSubShape(theShape, anArray);
2672 aSeq->Append( anObj );
2674 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
2675 if ( i != 1 ) theShapeEntries += ",";
2676 theShapeEntries += anEntry;
2682 //=======================================================================
2683 //function : getShapesOnSurface
2685 * \brief Find subshapes complying with given status about surface
2686 * \param theSurface - the surface to check state of subshapes against
2687 * \param theShape - the shape to explore
2688 * \param theShapeType - type of subshape of theShape
2689 * \param theState - required state
2690 * \param theShapeEntries - outgoing entries like "entry1, entry2, ..."
2691 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
2693 //=======================================================================
2694 Handle(TColStd_HSequenceOfTransient)
2695 GEOMImpl_IShapesOperations::getShapesOnSurface(const Handle(Geom_Surface)& theSurface,
2696 const Handle(GEOM_Object)& theShape,
2697 TopAbs_ShapeEnum theShapeType,
2698 GEOMAlgo_State theState,
2699 TCollection_AsciiString & theShapeEntries)
2701 // Find subshapes ids
2702 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2703 getShapesOnSurfaceIDs (theSurface, theShape->GetValue(), theShapeType, theState);
2704 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2707 return getObjectsShapesOn( theShape, aSeqOfIDs, theShapeEntries );
2710 //=============================================================================
2714 //=============================================================================
2715 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnPlane
2716 (const Handle(GEOM_Object)& theShape,
2717 const Standard_Integer theShapeType,
2718 const Handle(GEOM_Object)& theAx1,
2719 const GEOMAlgo_State theState)
2723 if (theShape.IsNull() || theAx1.IsNull()) return NULL;
2725 TopoDS_Shape aShape = theShape->GetValue();
2726 TopoDS_Shape anAx1 = theAx1->GetValue();
2728 if (aShape.IsNull() || anAx1.IsNull()) return NULL;
2730 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2731 if ( !checkTypeShapesOn( theShapeType ))
2735 Handle(Geom_Surface) aPlane = makePlane( anAx1 );
2736 if ( aPlane.IsNull() )
2740 TCollection_AsciiString anAsciiList;
2741 Handle(TColStd_HSequenceOfTransient) aSeq;
2742 aSeq = getShapesOnSurface( aPlane, theShape, aShapeType, theState, anAsciiList );
2743 if ( aSeq.IsNull() || aSeq->Length() == 0 )
2746 // Make a Python command
2748 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2749 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2751 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
2752 << "] = geompy.GetShapesOnPlane(" << theShape << ", "
2753 << aShapeType << ", " << theAx1 << ", " << theState << ")";
2759 //=============================================================================
2761 * GetShapesOnPlaneWithLocation
2763 //=============================================================================
2764 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnPlaneWithLocation
2765 (const Handle(GEOM_Object)& theShape,
2766 const Standard_Integer theShapeType,
2767 const Handle(GEOM_Object)& theAx1,
2768 const Handle(GEOM_Object)& thePnt,
2769 const GEOMAlgo_State theState)
2773 if (theShape.IsNull() || theAx1.IsNull() || thePnt.IsNull()) return NULL;
2775 TopoDS_Shape aShape = theShape->GetValue();
2776 TopoDS_Shape anAx1 = theAx1->GetValue();
2777 TopoDS_Shape anPnt = thePnt->GetValue();
2779 if (aShape.IsNull() || anAx1.IsNull() || anPnt.IsNull()) return NULL;
2781 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2782 if ( !checkTypeShapesOn( theShapeType ))
2786 if ( anAx1.ShapeType() != TopAbs_EDGE || anPnt.ShapeType() != TopAbs_VERTEX ) return NULL;
2787 TopoDS_Vertex V1, V2, V3;
2788 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
2789 TopExp::Vertices(anEdge, V1, V2, Standard_True);
2791 if (V1.IsNull() || V2.IsNull()) {
2792 SetErrorCode("Bad edge given for the plane normal vector");
2795 V3 = TopoDS::Vertex(anPnt);
2798 SetErrorCode("Bad vertex given for the plane location");
2801 gp_Pnt aLoc = BRep_Tool::Pnt(V3);
2802 gp_Vec aVec(BRep_Tool::Pnt(V1),BRep_Tool::Pnt(V2));
2804 if (aVec.Magnitude() < Precision::Confusion()) {
2805 SetErrorCode("Vector with null magnitude given");
2808 Handle(Geom_Surface) aPlane = new Geom_Plane(aLoc, aVec);
2810 if ( aPlane.IsNull() )
2814 TCollection_AsciiString anAsciiList;
2815 Handle(TColStd_HSequenceOfTransient) aSeq;
2816 aSeq = getShapesOnSurface( aPlane, theShape, aShapeType, theState, anAsciiList );
2817 if ( aSeq.IsNull() || aSeq->Length() == 0 )
2820 // Make a Python command
2822 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2823 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2825 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
2826 << "] = geompy.GetShapesOnPlaneWithLocation(" << theShape << ", "
2827 << aShapeType << ", " << theAx1 << ", "<< thePnt <<", " << theState << ")";
2833 //=============================================================================
2835 * GetShapesOnCylinder
2837 //=============================================================================
2838 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnCylinder
2839 (const Handle(GEOM_Object)& theShape,
2840 const Standard_Integer theShapeType,
2841 const Handle(GEOM_Object)& theAxis,
2842 const Standard_Real theRadius,
2843 const GEOMAlgo_State theState)
2847 if (theShape.IsNull() || theAxis.IsNull()) return NULL;
2849 TopoDS_Shape aShape = theShape->GetValue();
2850 TopoDS_Shape anAxis = theAxis->GetValue();
2852 if (aShape.IsNull() || anAxis.IsNull()) return NULL;
2854 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2855 if ( !checkTypeShapesOn( aShapeType ))
2858 // Create a cylinder surface
2859 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
2860 if ( aCylinder.IsNull() )
2864 TCollection_AsciiString anAsciiList;
2865 Handle(TColStd_HSequenceOfTransient) aSeq;
2866 aSeq = getShapesOnSurface( aCylinder, theShape, aShapeType, theState, anAsciiList );
2867 if ( aSeq.IsNull() || aSeq->Length() == 0 )
2870 // Make a Python command
2872 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2873 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2875 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
2876 << "] = geompy.GetShapesOnCylinder(" << theShape << ", " << aShapeType
2877 << ", " << theAxis << ", " << theRadius << ", " << theState << ")";
2883 //=============================================================================
2885 * GetShapesOnCylinderWithLocation
2887 //=============================================================================
2888 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnCylinderWithLocation
2889 (const Handle(GEOM_Object)& theShape,
2890 const Standard_Integer theShapeType,
2891 const Handle(GEOM_Object)& theAxis,
2892 const Handle(GEOM_Object)& thePnt,
2893 const Standard_Real theRadius,
2894 const GEOMAlgo_State theState)
2898 if (theShape.IsNull() || theAxis.IsNull() || thePnt.IsNull()) return NULL;
2900 TopoDS_Shape aShape = theShape->GetValue();
2901 TopoDS_Shape anAxis = theAxis->GetValue();
2902 TopoDS_Shape aPnt = thePnt->GetValue();
2904 if (aShape.IsNull() || anAxis.IsNull() || aPnt.IsNull()) return NULL;
2906 if (aPnt.ShapeType() != TopAbs_VERTEX )
2908 SetErrorCode("Bottom location point must be vertex");
2912 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2913 if ( !checkTypeShapesOn( aShapeType ))
2916 // Create a cylinder surface
2917 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
2918 if ( aCylinder.IsNull() )
2921 // translate the surface
2922 Handle(Geom_CylindricalSurface) aCylSurface =
2923 Handle(Geom_CylindricalSurface)::DownCast( aCylinder );
2924 if ( aCylSurface.IsNull() )
2926 SetErrorCode("Unexpected surface type instead of Geom_CylindricalSurface");
2929 gp_Pnt fromLoc = aCylSurface->Cylinder().Location();
2930 gp_Pnt toLoc = BRep_Tool::Pnt( TopoDS::Vertex( aPnt ));
2931 aCylinder->Translate( fromLoc, toLoc );
2934 TCollection_AsciiString anAsciiList;
2935 Handle(TColStd_HSequenceOfTransient) aSeq;
2936 aSeq = getShapesOnSurface( aCylinder, theShape, aShapeType, theState, anAsciiList );
2937 if ( aSeq.IsNull() || aSeq->Length() == 0 )
2940 // Make a Python command
2942 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2943 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2945 GEOM::TPythonDump(aFunction)
2946 << "[" << anAsciiList.ToCString()
2947 << "] = geompy.GetShapesOnCylinderWithLocation(" << theShape << ", " << aShapeType << ", "
2948 << theAxis << ", " << thePnt << ", " << theRadius << ", " << theState << ")";
2954 //=============================================================================
2958 //=============================================================================
2959 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnSphere
2960 (const Handle(GEOM_Object)& theShape,
2961 const Standard_Integer theShapeType,
2962 const Handle(GEOM_Object)& theCenter,
2963 const Standard_Real theRadius,
2964 const GEOMAlgo_State theState)
2968 if (theShape.IsNull() || theCenter.IsNull()) return NULL;
2970 TopoDS_Shape aShape = theShape->GetValue();
2971 TopoDS_Shape aCenter = theCenter->GetValue();
2973 if (aShape.IsNull() || aCenter.IsNull()) return NULL;
2975 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2976 if ( !checkTypeShapesOn( aShapeType ))
2979 // Center of the sphere
2980 if (aCenter.ShapeType() != TopAbs_VERTEX) return NULL;
2981 gp_Pnt aLoc = BRep_Tool::Pnt(TopoDS::Vertex(aCenter));
2983 gp_Ax3 anAx3 (aLoc, gp::DZ());
2984 Handle(Geom_SphericalSurface) aSphere =
2985 new Geom_SphericalSurface(anAx3, theRadius);
2988 TCollection_AsciiString anAsciiList;
2989 Handle(TColStd_HSequenceOfTransient) aSeq;
2990 aSeq = getShapesOnSurface( aSphere, theShape, aShapeType, theState, anAsciiList );
2991 if ( aSeq.IsNull() || aSeq->Length() == 0 )
2994 // Make a Python command
2996 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2997 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2999 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
3000 << "] = geompy.GetShapesOnSphere(" << theShape << ", " << aShapeType
3001 << ", " << theCenter << ", " << theRadius << ", " << theState << ")";
3007 //=============================================================================
3009 * GetShapesOnPlaneIDs
3011 //=============================================================================
3012 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnPlaneIDs
3013 (const Handle(GEOM_Object)& theShape,
3014 const Standard_Integer theShapeType,
3015 const Handle(GEOM_Object)& theAx1,
3016 const GEOMAlgo_State theState)
3020 if (theShape.IsNull() || theAx1.IsNull()) return NULL;
3022 TopoDS_Shape aShape = theShape->GetValue();
3023 TopoDS_Shape anAx1 = theAx1->GetValue();
3025 if (aShape.IsNull() || anAx1.IsNull()) return NULL;
3027 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3028 if ( !checkTypeShapesOn( aShapeType ))
3032 Handle(Geom_Surface) aPlane = makePlane( anAx1 );
3033 if ( aPlane.IsNull() )
3037 Handle(TColStd_HSequenceOfInteger) aSeq;
3038 aSeq = getShapesOnSurfaceIDs( aPlane, aShape, aShapeType, theState );
3040 // The GetShapesOnPlaneIDs() doesn't change object so no new function is required.
3041 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAx1)->GetLastFunction();
3043 // Make a Python command
3044 GEOM::TPythonDump(aFunction, /*append=*/true)
3045 << "listShapesOnPlane = geompy.GetShapesOnPlaneIDs"
3046 << "(" << theShape << "," << aShapeType << "," << theAx1 << "," << theState << ")";
3052 //=============================================================================
3054 * GetShapesOnPlaneWithLocationIDs
3056 //=============================================================================
3057 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnPlaneWithLocationIDs
3058 (const Handle(GEOM_Object)& theShape,
3059 const Standard_Integer theShapeType,
3060 const Handle(GEOM_Object)& theAx1,
3061 const Handle(GEOM_Object)& thePnt,
3062 const GEOMAlgo_State theState)
3066 if (theShape.IsNull() || theAx1.IsNull() || thePnt.IsNull()) return NULL;
3068 TopoDS_Shape aShape = theShape->GetValue();
3069 TopoDS_Shape anAx1 = theAx1->GetValue();
3070 TopoDS_Shape anPnt = thePnt->GetValue();
3072 if (aShape.IsNull() || anAx1.IsNull() || anPnt.IsNull()) return NULL;
3074 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3075 if ( !checkTypeShapesOn( aShapeType ))
3079 if (anAx1.ShapeType() != TopAbs_EDGE || anPnt.ShapeType() != TopAbs_VERTEX) return NULL;
3080 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
3081 TopoDS_Vertex V1, V2, V3;
3082 TopExp::Vertices(anEdge, V1, V2, Standard_True);
3083 if (V1.IsNull() || V2.IsNull()) {
3084 SetErrorCode("Bad edge given for the plane normal vector");
3087 V3 = TopoDS::Vertex(anPnt);
3089 SetErrorCode("Bad vertex given for the plane location");
3092 gp_Pnt aLoc = BRep_Tool::Pnt(V3);
3093 gp_Vec aVec(BRep_Tool::Pnt(V1),BRep_Tool::Pnt(V2));
3094 if (aVec.Magnitude() < Precision::Confusion()) {
3095 SetErrorCode("Vector with null magnitude given");
3099 Handle(Geom_Surface) aPlane = new Geom_Plane(aLoc, aVec);
3100 if ( aPlane.IsNull() )
3104 Handle(TColStd_HSequenceOfInteger) aSeq;
3105 aSeq = getShapesOnSurfaceIDs( aPlane, aShape, aShapeType, theState );
3107 // The GetShapesOnPlaneIDs() doesn't change object so no new function is required.
3108 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAx1)->GetLastFunction();
3110 // Make a Python command
3111 GEOM::TPythonDump(aFunction, /*append=*/true)
3112 << "listShapesOnPlane = geompy.GetShapesOnPlaneWithLocationIDs"
3113 << "(" << theShape << ", " << aShapeType << ", " << theAx1 << ", "<< thePnt << ", " << theState << ")";
3119 //=============================================================================
3121 * GetShapesOnCylinderIDs
3123 //=============================================================================
3124 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnCylinderIDs
3125 (const Handle(GEOM_Object)& theShape,
3126 const Standard_Integer theShapeType,
3127 const Handle(GEOM_Object)& theAxis,
3128 const Standard_Real theRadius,
3129 const GEOMAlgo_State theState)
3133 if (theShape.IsNull() || theAxis.IsNull()) return NULL;
3135 TopoDS_Shape aShape = theShape->GetValue();
3136 TopoDS_Shape anAxis = theAxis->GetValue();
3138 if (aShape.IsNull() || anAxis.IsNull()) return NULL;
3140 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3141 if ( !checkTypeShapesOn( aShapeType ))
3144 // Create a cylinder surface
3145 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
3146 if ( aCylinder.IsNull() )
3150 Handle(TColStd_HSequenceOfInteger) aSeq;
3151 aSeq = getShapesOnSurfaceIDs( aCylinder, aShape, aShapeType, theState );
3153 // The GetShapesOnCylinder() doesn't change object so no new function is required.
3154 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAxis)->GetLastFunction();
3156 // Make a Python command
3157 GEOM::TPythonDump(aFunction, /*append=*/true)
3158 << "listShapesOnCylinder = geompy.GetShapesOnCylinderIDs"
3159 << "(" << theShape << ", " << aShapeType << ", " << theAxis << ", "
3160 << theRadius << ", " << theState << ")";
3166 //=============================================================================
3168 * GetShapesOnCylinderWithLocationIDs
3170 //=============================================================================
3171 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnCylinderWithLocationIDs
3172 (const Handle(GEOM_Object)& theShape,
3173 const Standard_Integer theShapeType,
3174 const Handle(GEOM_Object)& theAxis,
3175 const Handle(GEOM_Object)& thePnt,
3176 const Standard_Real theRadius,
3177 const GEOMAlgo_State theState)
3181 if (theShape.IsNull() || theAxis.IsNull() || thePnt.IsNull()) return NULL;
3183 TopoDS_Shape aShape = theShape->GetValue();
3184 TopoDS_Shape anAxis = theAxis->GetValue();
3185 TopoDS_Shape aPnt = thePnt->GetValue();
3187 if (aShape.IsNull() || anAxis.IsNull() || aPnt.IsNull()) return NULL;
3189 if (aPnt.ShapeType() != TopAbs_VERTEX )
3191 SetErrorCode("Bottom location point must be vertex");
3195 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3196 if ( !checkTypeShapesOn( aShapeType ))
3199 // Create a cylinder surface
3200 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
3201 if ( aCylinder.IsNull() )
3204 // translate the surface
3205 Handle(Geom_CylindricalSurface) aCylSurface =
3206 Handle(Geom_CylindricalSurface)::DownCast( aCylinder );
3207 if ( aCylSurface.IsNull() )
3209 SetErrorCode("Unexpected surface type instead of Geom_CylindricalSurface");
3212 gp_Pnt fromLoc = aCylSurface->Cylinder().Location();
3213 gp_Pnt toLoc = BRep_Tool::Pnt( TopoDS::Vertex( aPnt ));
3214 aCylinder->Translate( fromLoc, toLoc );
3217 Handle(TColStd_HSequenceOfInteger) aSeq;
3218 aSeq = getShapesOnSurfaceIDs( aCylinder, aShape, aShapeType, theState );
3220 // The GetShapesOnCylinder() doesn't change object so no new function is required.
3221 Handle(GEOM_Function) aFunction =
3222 GEOM::GetCreatedLast(theShape, GEOM::GetCreatedLast(thePnt,theAxis))->GetLastFunction();
3224 // Make a Python command
3225 GEOM::TPythonDump(aFunction, /*append=*/true)
3226 << "listShapesOnCylinder = geompy.GetShapesOnCylinderWithLocationIDs"
3227 << "(" << theShape << ", " << aShapeType << ", " << theAxis << ", "
3228 << thePnt << ", " << theRadius << ", " << theState << ")";
3234 //=============================================================================
3236 * GetShapesOnSphereIDs
3238 //=============================================================================
3239 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnSphereIDs
3240 (const Handle(GEOM_Object)& theShape,
3241 const Standard_Integer theShapeType,
3242 const Handle(GEOM_Object)& theCenter,
3243 const Standard_Real theRadius,
3244 const GEOMAlgo_State theState)
3248 if (theShape.IsNull() || theCenter.IsNull()) return NULL;
3250 TopoDS_Shape aShape = theShape->GetValue();
3251 TopoDS_Shape aCenter = theCenter->GetValue();
3253 if (aShape.IsNull() || aCenter.IsNull()) return NULL;
3255 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3256 if ( !checkTypeShapesOn( aShapeType ))
3259 // Center of the sphere
3260 if (aCenter.ShapeType() != TopAbs_VERTEX) return NULL;
3261 gp_Pnt aLoc = BRep_Tool::Pnt(TopoDS::Vertex(aCenter));
3263 gp_Ax3 anAx3 (aLoc, gp::DZ());
3264 Handle(Geom_SphericalSurface) aSphere =
3265 new Geom_SphericalSurface(anAx3, theRadius);
3268 Handle(TColStd_HSequenceOfInteger) aSeq;
3269 aSeq = getShapesOnSurfaceIDs( aSphere, aShape, aShapeType, theState );
3271 // The GetShapesOnSphere() doesn't change object so no new function is required.
3272 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theCenter)->GetLastFunction();
3274 // Make a Python command
3275 GEOM::TPythonDump(aFunction, /*append=*/true)
3276 << "listShapesOnCylinder = geompy.GetShapesOnCylinderIDs"
3277 << "(" << theShape << ", " << aShapeType << ", " << theCenter << ", "
3278 << theRadius << ", " << theState << ")";
3284 //=======================================================================
3285 //function : getShapesOnQuadrangleIDs
3287 * \brief Find IDs of subshapes complying with given status about quadrangle
3288 * \param theShape - the shape to explore
3289 * \param theShapeType - type of subshape of theShape
3290 * \param theTopLeftPoint - top left quadrangle corner
3291 * \param theTopRigthPoint - top right quadrangle corner
3292 * \param theBottomLeftPoint - bottom left quadrangle corner
3293 * \param theBottomRigthPoint - bottom right quadrangle corner
3294 * \param theState - required state
3295 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
3297 //=======================================================================
3298 Handle(TColStd_HSequenceOfInteger)
3299 GEOMImpl_IShapesOperations::getShapesOnQuadrangleIDs (const Handle(GEOM_Object)& theShape,
3300 const Standard_Integer theShapeType,
3301 const Handle(GEOM_Object)& theTopLeftPoint,
3302 const Handle(GEOM_Object)& theTopRigthPoint,
3303 const Handle(GEOM_Object)& theBottomLeftPoint,
3304 const Handle(GEOM_Object)& theBottomRigthPoint,
3305 const GEOMAlgo_State theState)
3309 if ( theShape.IsNull() ||
3310 theTopLeftPoint.IsNull() ||
3311 theTopRigthPoint.IsNull() ||
3312 theBottomLeftPoint.IsNull() ||
3313 theBottomRigthPoint.IsNull() )
3316 TopoDS_Shape aShape = theShape->GetValue();
3317 TopoDS_Shape aTL = theTopLeftPoint->GetValue();
3318 TopoDS_Shape aTR = theTopRigthPoint->GetValue();
3319 TopoDS_Shape aBL = theBottomLeftPoint->GetValue();
3320 TopoDS_Shape aBR = theBottomRigthPoint->GetValue();
3322 if (aShape.IsNull() ||
3327 aTL.ShapeType() != TopAbs_VERTEX ||
3328 aTR.ShapeType() != TopAbs_VERTEX ||
3329 aBL.ShapeType() != TopAbs_VERTEX ||
3330 aBR.ShapeType() != TopAbs_VERTEX )
3333 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3334 if ( !checkTypeShapesOn( aShapeType ))
3337 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
3339 // Check presence of triangulation, build if need
3340 if (!CheckTriangulation(aShape)) {
3341 SetErrorCode("Cannot build triangulation on the shape");
3346 gp_Pnt aPntTL = BRep_Tool::Pnt(TopoDS::Vertex(aTL));
3347 gp_Pnt aPntTR = BRep_Tool::Pnt(TopoDS::Vertex(aTR));
3348 gp_Pnt aPntBL = BRep_Tool::Pnt(TopoDS::Vertex(aBL));
3349 gp_Pnt aPntBR = BRep_Tool::Pnt(TopoDS::Vertex(aBR));
3351 GEOMAlgo_FinderShapeOnQuad aFinder( aPntTL, aPntTR, aPntBL, aPntBR );
3352 Standard_Real aTol = 0.0001; // default value
3354 aFinder.SetShape(aShape);
3355 aFinder.SetTolerance(aTol);
3356 //aFinder.SetSurface(theSurface);
3357 aFinder.SetShapeType(aShapeType);
3358 aFinder.SetState(theState);
3360 // Sets the minimal number of inner points for the faces that do not have own
3361 // inner points at all (for e.g. rectangular planar faces have just 2 triangles).
3363 aFinder.SetNbPntsMin(3);
3364 // Sets the maximal number of inner points for edges or faces.
3365 // It is usefull for the cases when this number is very big (e.g =2000) to improve
3366 // the performance. If this value =0, all inner points will be taken into account.
3368 aFinder.SetNbPntsMax(100);
3372 // Interprete results
3373 Standard_Integer iErr = aFinder.ErrorStatus();
3374 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
3376 MESSAGE(" iErr : " << iErr);
3377 TCollection_AsciiString aMsg (" iErr : ");
3378 aMsg += TCollection_AsciiString(iErr);
3382 Standard_Integer iWrn = aFinder.WarningStatus();
3383 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
3385 MESSAGE(" *** iWrn : " << iWrn);
3388 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
3390 if (listSS.Extent() < 1) {
3391 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
3392 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
3396 // Fill sequence of object IDs
3397 aSeqOfIDs = new TColStd_HSequenceOfInteger;
3399 TopTools_IndexedMapOfShape anIndices;
3400 TopExp::MapShapes(aShape, anIndices);
3402 TopTools_ListIteratorOfListOfShape itSub (listSS);
3403 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
3404 int id = anIndices.FindIndex(itSub.Value());
3405 aSeqOfIDs->Append(id);
3410 //=======================================================================
3411 //function : GetShapesOnQuadrangle
3413 * \brief Find subshapes complying with given status about quadrangle
3414 * \param theShape - the shape to explore
3415 * \param theShapeType - type of subshape of theShape
3416 * \param theTopLeftPoint - top left quadrangle corner
3417 * \param theTopRigthPoint - top right quadrangle corner
3418 * \param theBottomLeftPoint - bottom left quadrangle corner
3419 * \param theBottomRigthPoint - bottom right quadrangle corner
3420 * \param theState - required state
3421 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
3423 //=======================================================================
3424 Handle(TColStd_HSequenceOfTransient)
3425 GEOMImpl_IShapesOperations::GetShapesOnQuadrangle (const Handle(GEOM_Object)& theShape,
3426 const Standard_Integer theShapeType,
3427 const Handle(GEOM_Object)& theTopLeftPoint,
3428 const Handle(GEOM_Object)& theTopRigthPoint,
3429 const Handle(GEOM_Object)& theBottomLeftPoint,
3430 const Handle(GEOM_Object)& theBottomRigthPoint,
3431 const GEOMAlgo_State theState)
3434 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
3435 getShapesOnQuadrangleIDs( theShape,
3440 theBottomRigthPoint,
3442 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->IsEmpty() )
3445 // Find objects by indices
3446 TCollection_AsciiString anAsciiList;
3447 Handle(TColStd_HSequenceOfTransient) aSeq;
3448 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
3449 if ( aSeq.IsNull() || aSeq->IsEmpty() )
3452 // Make a Python command
3454 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
3455 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
3457 GEOM::TPythonDump(aFunction)
3458 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnQuadrangle("
3460 << TopAbs_ShapeEnum(theShapeType) << ", "
3461 << theTopLeftPoint << ", "
3462 << theTopRigthPoint << ", "
3463 << theBottomLeftPoint << ", "
3464 << theBottomRigthPoint << ", "
3471 //=======================================================================
3472 //function : GetShapesOnQuadrangleIDs
3474 * \brief Find IDs of subshapes complying with given status about quadrangle
3475 * \param theShape - the shape to explore
3476 * \param theShapeType - type of subshape of theShape
3477 * \param theTopLeftPoint - top left quadrangle corner
3478 * \param theTopRigthPoint - top right quadrangle corner
3479 * \param theBottomLeftPoint - bottom left quadrangle corner
3480 * \param theBottomRigthPoint - bottom right quadrangle corner
3481 * \param theState - required state
3482 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
3484 //=======================================================================
3485 Handle(TColStd_HSequenceOfInteger)
3486 GEOMImpl_IShapesOperations::GetShapesOnQuadrangleIDs (const Handle(GEOM_Object)& theShape,
3487 const Standard_Integer theShapeType,
3488 const Handle(GEOM_Object)& theTopLeftPoint,
3489 const Handle(GEOM_Object)& theTopRigthPoint,
3490 const Handle(GEOM_Object)& theBottomLeftPoint,
3491 const Handle(GEOM_Object)& theBottomRigthPoint,
3492 const GEOMAlgo_State theState)
3495 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
3496 getShapesOnQuadrangleIDs( theShape,
3501 theBottomRigthPoint,
3503 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->IsEmpty() )
3506 // Make a Python command
3508 // The GetShapesOnCylinder() doesn't change object so no new function is required.
3509 Handle(GEOM_Object) lastObj = GEOM::GetCreatedLast(theShape,theTopLeftPoint);
3510 lastObj = GEOM::GetCreatedLast(lastObj,theTopRigthPoint);
3511 lastObj = GEOM::GetCreatedLast(lastObj,theBottomRigthPoint);
3512 lastObj = GEOM::GetCreatedLast(lastObj,theBottomLeftPoint);
3513 Handle(GEOM_Function) aFunction = lastObj->GetLastFunction();
3515 GEOM::TPythonDump(aFunction, /*append=*/true)
3516 << "listShapesOnQuadrangle = geompy.GetShapesOnQuadrangleIDs("
3518 << TopAbs_ShapeEnum(theShapeType) << ", "
3519 << theTopLeftPoint << ", "
3520 << theTopRigthPoint << ", "
3521 << theBottomLeftPoint << ", "
3522 << theBottomRigthPoint << ", "
3529 //=============================================================================
3533 //=============================================================================
3534 static bool GetInPlaceOfShape (const Handle(GEOM_Function)& theWhereFunction,
3535 const TopTools_IndexedMapOfShape& theWhereIndices,
3536 const TopoDS_Shape& theWhat,
3537 TColStd_ListOfInteger& theModifiedList)
3539 if (theWhereFunction.IsNull() || theWhat.IsNull()) return false;
3541 if (theWhereIndices.Contains(theWhat)) {
3542 // entity was not changed by the operation
3543 Standard_Integer aWhatIndex = theWhereIndices.FindIndex(theWhat);
3544 theModifiedList.Append(aWhatIndex);
3548 // try to find in history
3549 TDF_Label aHistoryLabel = theWhereFunction->GetHistoryEntry(Standard_False);
3551 // search in history for all argument shapes
3552 Standard_Boolean isFound = Standard_False;
3553 Standard_Boolean isGood = Standard_False;
3555 TDF_LabelSequence aLabelSeq;
3556 theWhereFunction->GetDependency(aLabelSeq);
3557 Standard_Integer nbArg = aLabelSeq.Length();
3559 for (Standard_Integer iarg = 1; iarg <= nbArg && !isFound; iarg++) {
3561 TDF_Label anArgumentRefLabel = aLabelSeq.Value(iarg);
3563 Handle(GEOM_Object) anArgumentObject = GEOM_Object::GetReferencedObject(anArgumentRefLabel);
3564 TopoDS_Shape anArgumentShape = anArgumentObject->GetValue();
3566 TopTools_IndexedMapOfShape anArgumentIndices;
3567 TopExp::MapShapes(anArgumentShape, anArgumentIndices);
3569 if (anArgumentIndices.Contains(theWhat)) {
3570 isFound = Standard_True;
3571 Standard_Integer aWhatIndex = anArgumentIndices.FindIndex(theWhat);
3573 // Find corresponding label in history
3574 TDF_Label anArgumentHistoryLabel =
3575 theWhereFunction->GetArgumentHistoryEntry(anArgumentRefLabel, Standard_False);
3576 if (anArgumentHistoryLabel.IsNull()) {
3577 // Lost History of operation argument. Possibly, all its entities was removed.
3578 isGood = Standard_True;
3581 TDF_Label aWhatHistoryLabel = anArgumentHistoryLabel.FindChild(aWhatIndex, Standard_False);
3583 if (aWhatHistoryLabel.IsNull()) {
3584 // Removed entity ? Compound ? Compsolid ? Shell ? Wire
3585 isGood = Standard_False;
3587 Handle(TDataStd_IntegerArray) anIntegerArray;
3588 if (!aWhatHistoryLabel.FindAttribute(TDataStd_IntegerArray::GetID(), anIntegerArray)) {
3589 //Error: Empty modifications history for the sought shape.
3590 isGood = Standard_False;
3593 isGood = Standard_True;
3594 Standard_Integer imod, aModifLen = anIntegerArray->Array()->Length();
3595 for (imod = 1; imod <= aModifLen; imod++) {
3596 theModifiedList.Append(anIntegerArray->Array()->Value(imod));
3607 // try compound/compsolid/shell/wire element by element
3608 bool isFoundAny = false;
3609 TopTools_MapOfShape mapShape;
3611 if (theWhat.ShapeType() == TopAbs_COMPOUND ||
3612 theWhat.ShapeType() == TopAbs_COMPSOLID) {
3613 // recursive processing of compound/compsolid
3614 TopoDS_Iterator anIt (theWhat, Standard_True, Standard_True);
3615 for (; anIt.More(); anIt.Next()) {
3616 if (mapShape.Add(anIt.Value())) {
3617 TopoDS_Shape curWhat = anIt.Value();
3618 isFoundAny = GetInPlaceOfShape(theWhereFunction, theWhereIndices, curWhat, theModifiedList);
3619 if (isFoundAny) isFound = Standard_True;
3623 else if (theWhat.ShapeType() == TopAbs_SHELL) {
3624 // try to replace a shell by its faces images
3625 TopExp_Explorer anExp (theWhat, TopAbs_FACE);
3626 for (; anExp.More(); anExp.Next()) {
3627 if (mapShape.Add(anExp.Current())) {
3628 TopoDS_Shape curWhat = anExp.Current();
3629 isFoundAny = GetInPlaceOfShape(theWhereFunction, theWhereIndices, curWhat, theModifiedList);
3630 if (isFoundAny) isFound = Standard_True;
3634 else if (theWhat.ShapeType() == TopAbs_WIRE) {
3635 // try to replace a wire by its edges images
3636 TopExp_Explorer anExp (theWhat, TopAbs_EDGE);
3637 for (; anExp.More(); anExp.Next()) {
3638 if (mapShape.Add(anExp.Current())) {
3639 TopoDS_Shape curWhat = anExp.Current();
3640 isFoundAny = GetInPlaceOfShape(theWhereFunction, theWhereIndices, curWhat, theModifiedList);
3641 if (isFoundAny) isFound = Standard_True;
3653 //=============================================================================
3655 * GetShapeProperties
3657 //=============================================================================
3658 void GEOMImpl_IShapesOperations::GetShapeProperties( const TopoDS_Shape aShape, Standard_Real tab[],
3661 GProp_GProps theProps;
3663 //TopoDS_Shape aPntShape;
3664 Standard_Real aShapeSize;
3666 if (aShape.ShapeType() == TopAbs_VERTEX) aCenterMass = BRep_Tool::Pnt( TopoDS::Vertex( aShape ) );
3667 else if (aShape.ShapeType() == TopAbs_EDGE) BRepGProp::LinearProperties(aShape, theProps);
3668 else if (aShape.ShapeType() == TopAbs_FACE) BRepGProp::SurfaceProperties(aShape, theProps);
3669 else BRepGProp::VolumeProperties(aShape, theProps);
3671 if (aShape.ShapeType() == TopAbs_VERTEX)
3674 aCenterMass = theProps.CentreOfMass();
3675 aShapeSize = theProps.Mass();
3678 // aPntShape = BRepBuilderAPI_MakeVertex(aCenterMass).Shape();
3679 // aVertex = BRep_Tool::Pnt( TopoDS::Vertex( aPntShape ) );
3680 aVertex = aCenterMass;
3681 tab[0] = aVertex.X();
3682 tab[1] = aVertex.Y();
3683 tab[2] = aVertex.Z();
3684 tab[3] = aShapeSize;
3690 //================================================================================
3692 * \brief Return normal to face at extrema point
3694 //================================================================================
3696 gp_Vec GetNormal (const TopoDS_Face& face, const BRepExtrema_DistShapeShape& extrema)
3698 gp_Vec defaultNorm(1,0,0); // to have same normals on different faces
3700 // get UV at extrema point
3701 Standard_Real u,v, f,l;
3702 switch ( extrema.SupportTypeShape2(1) ) {
3703 case BRepExtrema_IsInFace: {
3704 extrema.ParOnFaceS2(1, u, v );
3707 case BRepExtrema_IsOnEdge: {
3708 TopoDS_Edge edge = TopoDS::Edge( extrema.SupportOnShape2(1));
3709 Handle(Geom2d_Curve) pcurve = BRep_Tool::CurveOnSurface( edge, face, f,l );
3710 extrema.ParOnEdgeS2( 1, u );
3711 gp_Pnt2d uv = pcurve->Value( u );
3716 case BRepExtrema_IsVertex: return defaultNorm;
3719 BRepAdaptor_Surface surface( face, false );
3720 gp_Vec du, dv; gp_Pnt p;
3721 surface.D1( u, v, p, du, dv );
3725 } catch (Standard_Failure ) {
3731 //================================================================================
3733 * \brief Return type of shape for explode. In case of compound it will be a type of sub shape.
3735 //================================================================================
3736 TopAbs_ShapeEnum GEOMImpl_IShapesOperations::GetTypeOfSimplePart (const TopoDS_Shape& theShape)
3738 TopAbs_ShapeEnum aType = theShape.ShapeType();
3739 if (aType == TopAbs_VERTEX) return TopAbs_VERTEX;
3740 else if (aType == TopAbs_EDGE || aType == TopAbs_WIRE) return TopAbs_EDGE;
3741 else if (aType == TopAbs_FACE || aType == TopAbs_SHELL) return TopAbs_FACE;
3742 else if (aType == TopAbs_SOLID || aType == TopAbs_COMPSOLID) return TopAbs_SOLID;
3743 else if (aType == TopAbs_COMPOUND) {
3744 // Only the iType of the first shape in the compound is taken into account
3745 TopoDS_Iterator It (theShape, Standard_False, Standard_False);
3747 return GetTypeOfSimplePart(It.Value());
3750 return TopAbs_SHAPE;
3753 //=============================================================================
3758 //=============================================================================
3759 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlace (Handle(GEOM_Object) theShapeWhere,
3760 Handle(GEOM_Object) theShapeWhat)
3764 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
3766 TopoDS_Shape aWhere = theShapeWhere->GetValue();
3767 TopoDS_Shape aWhat = theShapeWhat->GetValue();
3768 TopoDS_Shape aPntShape;
3769 TopoDS_Vertex aVertex;
3771 if (aWhere.IsNull() || aWhat.IsNull()) {
3772 SetErrorCode("Error: aWhere and aWhat TopoDS_Shape are Null.");
3776 Handle(GEOM_Function) aWhereFunction = theShapeWhere->GetLastFunction();
3777 if (aWhereFunction.IsNull()) {
3778 SetErrorCode("Error: aWhereFunction is Null.");
3782 TopTools_IndexedMapOfShape aWhereIndices;
3783 TopExp::MapShapes(aWhere, aWhereIndices);
3785 TColStd_ListOfInteger aModifiedList;
3786 Standard_Integer aWhereIndex;
3787 Handle(TColStd_HArray1OfInteger) aModifiedArray;
3788 Handle(GEOM_Object) aResult;
3790 bool isFound = false;
3791 TopAbs_ShapeEnum iType = TopAbs_SOLID;
3792 //Standard_Real aWhat_Mass = 0., aWhere_Mass = 0.;
3793 Standard_Real tab_aWhat[4], tab_aWhere[4];
3794 Standard_Real dl_l = 1e-3;
3795 Standard_Real min_l, Tol_0D, Tol_1D, Tol_2D, Tol_3D, Tol_Mass;
3796 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
3797 Bnd_Box BoundingBox;
3798 gp_Pnt aPnt, aPnt_aWhat, tab_Pnt[2];
3799 GProp_GProps aProps;
3801 // Find the iType of the aWhat shape
3803 if ( aWhat.ShapeType() == TopAbs_VERTEX ) iType = TopAbs_VERTEX;
3804 else if ( aWhat.ShapeType() == TopAbs_EDGE || aWhat.ShapeType() == TopAbs_WIRE ) iType = TopAbs_EDGE;
3805 else if ( aWhat.ShapeType() == TopAbs_FACE || aWhat.ShapeType() == TopAbs_SHELL ) iType = TopAbs_FACE;
3806 else if ( aWhat.ShapeType() == TopAbs_SOLID || aWhat.ShapeType() == TopAbs_COMPSOLID ) iType = TopAbs_SOLID;
3807 else if ( aWhat.ShapeType() == TopAbs_COMPOUND ) {
3808 // Only the iType of the first shape in the compound is taken into account
3809 TopoDS_Iterator It (aWhat, Standard_False, Standard_False);
3811 SetErrorCode("Error: theShapeWhat is an empty COMPOUND.");
3814 TopAbs_ShapeEnum compType = It.Value().ShapeType();
3815 if ( compType == TopAbs_VERTEX ) iType = TopAbs_VERTEX;
3816 else if ( compType == TopAbs_EDGE || compType == TopAbs_WIRE ) iType = TopAbs_EDGE;
3817 else if ( compType == TopAbs_FACE || compType == TopAbs_SHELL) iType = TopAbs_FACE;
3818 else if ( compType == TopAbs_SOLID || compType == TopAbs_COMPSOLID) iType = TopAbs_SOLID;
3821 SetErrorCode("Error: An attempt to extract a shape of not supported type.");
3825 iType = GetTypeOfSimplePart(aWhat);
3826 if (iType == TopAbs_SHAPE) {
3827 SetErrorCode("Error: An attempt to extract a shape of not supported type.");
3831 TopExp_Explorer Exp_aWhat ( aWhat, iType );
3832 TopExp_Explorer Exp_aWhere ( aWhere, iType );
3833 TopExp_Explorer Exp_Edge ( aWhere, TopAbs_EDGE );
3835 // Find the shortest edge in theShapeWhere shape
3836 BRepBndLib::Add(aWhere, BoundingBox);
3837 BoundingBox.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
3838 min_l = fabs(aXmax - aXmin);
3839 if( min_l < fabs(aYmax - aYmin) ) min_l = fabs(aYmax - aYmin);
3840 if( min_l < fabs(aZmax - aZmin) ) min_l = fabs(aZmax - aZmin);
3842 // Mantis issue 0020908 BEGIN
3843 if (!Exp_Edge.More()) {
3844 min_l = Precision::Confusion();
3846 // Mantis issue 0020908 END
3847 for ( Standard_Integer nbEdge = 0; Exp_Edge.More(); Exp_Edge.Next(), nbEdge++ ) {
3848 TopExp_Explorer Exp_Vertex( Exp_Edge.Current(), TopAbs_VERTEX);
3849 for ( Standard_Integer nbVertex = 0; Exp_Vertex.More(); Exp_Vertex.Next(), nbVertex++ ) {
3850 aPnt = BRep_Tool::Pnt( TopoDS::Vertex( Exp_Vertex.Current() ) );
3851 tab_Pnt[nbVertex] = aPnt;
3853 if ( ! tab_Pnt[0].IsEqual(tab_Pnt[1], dl_l) ) {
3854 BRepGProp::LinearProperties(Exp_Edge.Current(), aProps);
3855 if ( aProps.Mass() < min_l ) min_l = aProps.Mass();
3859 // Compute tolerances
3861 Tol_1D = dl_l * min_l;
3862 Tol_2D = dl_l * ( min_l * min_l) * ( 2. + dl_l);
3863 Tol_3D = dl_l * ( min_l * min_l * min_l ) * ( 3. + (3 * dl_l) + (dl_l * dl_l) );
3865 if (Tol_0D < Precision::Confusion()) Tol_0D = Precision::Confusion();
3866 if (Tol_1D < Precision::Confusion()) Tol_1D = Precision::Confusion();
3867 if (Tol_2D < Precision::Confusion()) Tol_2D = Precision::Confusion();
3868 if (Tol_3D < Precision::Confusion()) Tol_3D = Precision::Confusion();
3870 //if (Tol_1D > 1.0) Tol_1D = 1.0;
3871 //if (Tol_2D > 1.0) Tol_2D = 1.0;
3872 //if (Tol_3D > 1.0) Tol_3D = 1.0;
3875 if ( iType == TopAbs_VERTEX ) Tol_Mass = Tol_0D;
3876 else if ( iType == TopAbs_EDGE ) Tol_Mass = Tol_1D;
3877 else if ( iType == TopAbs_FACE ) Tol_Mass = Tol_2D;
3879 // Compute the ShapeWhat Mass
3881 for ( ; Exp_aWhat.More(); Exp_aWhat.Next() ) {
3882 if ( iType == TopAbs_VERTEX ) {
3886 else if ( iType == TopAbs_EDGE ) BRepGProp::LinearProperties(Exp_aWhat.Current(), aProps);
3887 else if ( iType == TopAbs_FACE ) BRepGProp::SurfaceProperties(Exp_aWhat.Current(), aProps);
3888 else BRepGProp::VolumeProperties(Exp_aWhat.Current(), aProps);
3889 aWhat_Mass += aProps.Mass();
3893 // Searching for the sub-shapes inside the ShapeWhere shape
3894 TopTools_MapOfShape map_aWhere;
3895 for ( Exp_aWhere.ReInit(); Exp_aWhere.More(); Exp_aWhere.Next() ) {
3896 if (!map_aWhere.Add(Exp_aWhere.Current()))
3897 continue; // skip repeated shape to avoid mass addition
3898 GetShapeProperties( Exp_aWhere.Current(), tab_aWhere, aPnt );
3899 for ( Exp_aWhat.ReInit(); Exp_aWhat.More(); Exp_aWhat.Next() ) {
3900 GetShapeProperties( Exp_aWhat.Current(), tab_aWhat, aPnt_aWhat );
3901 if ( fabs(tab_aWhat[3] - tab_aWhere[3]) <= Tol_Mass && aPnt_aWhat.Distance(aPnt) <= Tol_1D )
3904 if ( (tab_aWhat[3] - tab_aWhere[3]) > Tol_Mass ) {
3905 aPntShape = BRepBuilderAPI_MakeVertex( aPnt ).Shape();
3906 aVertex = TopoDS::Vertex( aPntShape );
3907 BRepExtrema_DistShapeShape aWhereDistance ( aVertex, Exp_aWhere.Current() );
3908 BRepExtrema_DistShapeShape aWhatDistance ( aVertex, Exp_aWhat.Current() );
3909 if ( aWhereDistance.IsDone() && aWhatDistance.IsDone() &&
3910 fabs(aWhereDistance.Value() - aWhatDistance.Value()) <= Tol_1D )
3912 // 0020162: "EDF 961 GEOM : Getinplace is getting additionnal orthogonal faces"
3913 // aVertex must be projected to the same point on Where and on What
3914 gp_Pnt pOnWhat = aWhatDistance.PointOnShape2(1);
3915 gp_Pnt pOnWhere = aWhereDistance.PointOnShape2(1);
3916 isFound = ( pOnWhat.Distance(pOnWhere) <= Tol_1D );
3917 if ( isFound && iType == TopAbs_FACE )
3919 // check normals at pOnWhat and pOnWhere
3920 const double angleTol = PI/180.;
3921 gp_Vec normToWhat = GetNormal( TopoDS::Face(Exp_aWhat.Current()), aWhatDistance);
3922 gp_Vec normToWhere = GetNormal( TopoDS::Face(Exp_aWhere.Current()), aWhereDistance);
3923 if ( normToWhat * normToWhere < 0 )
3924 normToWhat.Reverse();
3925 isFound = ( normToWhat.Angle( normToWhere ) < angleTol );
3931 aWhereIndex = aWhereIndices.FindIndex(Exp_aWhere.Current());
3932 aModifiedList.Append(aWhereIndex);
3933 //aWhere_Mass += tab_aWhere[3];
3938 //if ( fabs( aWhat_Mass - aWhere_Mass ) <= Tol_Mass )
3942 if (aModifiedList.Extent() == 0) { // Not found any Results
3943 SetErrorCode(NOT_FOUND_ANY);
3947 aModifiedArray = new TColStd_HArray1OfInteger (1, aModifiedList.Extent());
3948 TColStd_ListIteratorOfListOfInteger anIterModif (aModifiedList);
3949 for (Standard_Integer imod = 1; anIterModif.More(); anIterModif.Next(), imod++)
3950 aModifiedArray->SetValue(imod, anIterModif.Value());
3953 aResult = GetEngine()->AddSubShape(theShapeWhere, aModifiedArray);
3954 if (aResult.IsNull()) {
3955 SetErrorCode("Error in algorithm: result found, but cannot be returned.");
3959 if (aModifiedArray->Length() > 1) {
3961 aResult->SetType(GEOM_GROUP);
3963 //Set a sub shape type
3964 TopoDS_Shape aFirstFound = aWhereIndices.FindKey(aModifiedArray->Value(1));
3965 TopAbs_ShapeEnum aShapeType = aFirstFound.ShapeType();
3967 TDF_Label aFreeLabel = aResult->GetFreeLabel();
3968 TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aShapeType);
3971 //Make a Python command
3972 Handle(GEOM_Function) aFunction = aResult->GetFunction(1);
3974 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetInPlace("
3975 << theShapeWhere << ", " << theShapeWhat << ")";
3981 //=======================================================================
3982 //function : GetInPlaceByHistory
3984 //=======================================================================
3985 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlaceByHistory
3986 (Handle(GEOM_Object) theShapeWhere,
3987 Handle(GEOM_Object) theShapeWhat)
3991 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
3993 TopoDS_Shape aWhere = theShapeWhere->GetValue();
3994 TopoDS_Shape aWhat = theShapeWhat->GetValue();
3996 if (aWhere.IsNull() || aWhat.IsNull()) return NULL;
3998 Handle(GEOM_Function) aWhereFunction = theShapeWhere->GetLastFunction();
3999 if (aWhereFunction.IsNull()) return NULL;
4001 //Fill array of indices
4002 TopTools_IndexedMapOfShape aWhereIndices;
4003 TopExp::MapShapes(aWhere, aWhereIndices);
4006 TColStd_ListOfInteger aModifiedList;
4007 bool isFound = GetInPlaceOfShape(aWhereFunction, aWhereIndices, aWhat, aModifiedList);
4009 if (!isFound || aModifiedList.Extent() < 1) {
4010 SetErrorCode("Error: No history found for the sought shape or its sub-shapes.");
4014 Handle(TColStd_HArray1OfInteger) aModifiedArray =
4015 new TColStd_HArray1OfInteger (1, aModifiedList.Extent());
4016 TColStd_ListIteratorOfListOfInteger anIterModif (aModifiedList);
4017 for (Standard_Integer imod = 1; anIterModif.More(); anIterModif.Next(), imod++) {
4018 aModifiedArray->SetValue(imod, anIterModif.Value());
4022 Handle(GEOM_Object) aResult = GetEngine()->AddSubShape(theShapeWhere, aModifiedArray);
4023 if (aResult.IsNull()) {
4024 SetErrorCode("Error in algorithm: result found, but cannot be returned.");
4028 if (aModifiedArray->Length() > 1) {
4030 aResult->SetType(GEOM_GROUP);
4032 //Set a sub shape type
4033 TopoDS_Shape aFirstFound = aWhereIndices.FindKey(aModifiedArray->Value(1));
4034 TopAbs_ShapeEnum aShapeType = aFirstFound.ShapeType();
4036 TDF_Label aFreeLabel = aResult->GetFreeLabel();
4037 TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aShapeType);
4040 //Make a Python command
4041 Handle(GEOM_Function) aFunction = aResult->GetFunction(1);
4043 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetInPlaceByHistory("
4044 << theShapeWhere << ", " << theShapeWhat << ")";
4050 //=======================================================================
4051 //function : ShapeToDouble
4052 //purpose : used by CompareShapes::operator()
4053 //=======================================================================
4054 std::pair<double, double> ShapeToDouble (const TopoDS_Shape& S, bool isOldSorting)
4056 // Computing of CentreOfMass
4060 if (S.ShapeType() == TopAbs_VERTEX) {
4061 GPoint = BRep_Tool::Pnt(TopoDS::Vertex(S));
4062 Len = (double)S.Orientation();
4066 // BEGIN: fix for Mantis issue 0020842
4068 BRepGProp::LinearProperties(S, GPr);
4071 if (S.ShapeType() == TopAbs_EDGE || S.ShapeType() == TopAbs_WIRE) {
4072 BRepGProp::LinearProperties(S, GPr);
4074 else if (S.ShapeType() == TopAbs_FACE || S.ShapeType() == TopAbs_SHELL) {
4075 BRepGProp::SurfaceProperties(S, GPr);
4078 BRepGProp::VolumeProperties(S, GPr);
4081 // END: fix for Mantis issue 0020842
4082 GPoint = GPr.CentreOfMass();
4086 double dMidXYZ = GPoint.X() * 999.0 + GPoint.Y() * 99.0 + GPoint.Z() * 0.9;
4087 return std::make_pair(dMidXYZ, Len);
4090 //=======================================================================
4091 //function : CompareShapes::operator()
4092 //purpose : used by std::sort(), called from SortShapes()
4093 //=======================================================================
4094 bool GEOMImpl_IShapesOperations::CompareShapes::operator()(const TopoDS_Shape& theShape1,
4095 const TopoDS_Shape& theShape2)
4097 if (!myMap.IsBound(theShape1)) {
4098 myMap.Bind(theShape1, ShapeToDouble(theShape1, myIsOldSorting));
4101 if (!myMap.IsBound(theShape2)) {
4102 myMap.Bind(theShape2, ShapeToDouble(theShape2, myIsOldSorting));
4105 std::pair<double, double> val1 = myMap.Find(theShape1);
4106 std::pair<double, double> val2 = myMap.Find(theShape2);
4108 double tol = Precision::Confusion();
4109 bool exchange = Standard_False;
4111 double dMidXYZ = val1.first - val2.first;
4112 if (dMidXYZ >= tol) {
4113 exchange = Standard_True;
4115 else if (Abs(dMidXYZ) < tol) {
4116 double dLength = val1.second - val2.second;
4117 if (dLength >= tol) {
4118 exchange = Standard_True;
4120 else if (Abs(dLength) < tol && theShape1.ShapeType() <= TopAbs_FACE) {
4122 // equal values possible on shapes such as two halves of a sphere and
4123 // a membrane inside the sphere
4125 BRepBndLib::Add(theShape1, box1);
4126 if (!box1.IsVoid()) {
4127 BRepBndLib::Add(theShape2, box2);
4128 Standard_Real dSquareExtent = box1.SquareExtent() - box2.SquareExtent();
4129 if (dSquareExtent >= tol) {
4130 exchange = Standard_True;
4132 else if (Abs(dSquareExtent) < tol) {
4133 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax, val1, val2;
4134 box1.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
4135 val1 = (aXmin+aXmax)*999.0 + (aYmin+aYmax)*99.0 + (aZmin+aZmax)*0.9;
4136 box2.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
4137 val2 = (aXmin+aXmax)*999.0 + (aYmin+aYmax)*99.0 + (aZmin+aZmax)*0.9;
4138 if ((val1 - val2) >= tol) {
4139 exchange = Standard_True;
4146 //return val1 < val2;
4150 //=======================================================================
4151 //function : SortShapes
4153 //=======================================================================
4154 void GEOMImpl_IShapesOperations::SortShapes(TopTools_ListOfShape& SL,
4155 const Standard_Boolean isOldSorting)
4157 #ifdef STD_SORT_ALGO
4158 std::vector<TopoDS_Shape> aShapesVec;
4159 aShapesVec.reserve(SL.Extent());
4161 TopTools_ListIteratorOfListOfShape it (SL);
4162 for (; it.More(); it.Next()) {
4163 aShapesVec.push_back(it.Value());
4167 CompareShapes shComp (isOldSorting);
4168 std::stable_sort(aShapesVec.begin(), aShapesVec.end(), shComp);
4169 //std::sort(aShapesVec.begin(), aShapesVec.end(), shComp);
4171 std::vector<TopoDS_Shape>::const_iterator anIter = aShapesVec.begin();
4172 for (; anIter != aShapesVec.end(); ++anIter) {
4176 // old implementation
4177 Standard_Integer MaxShapes = SL.Extent();
4178 TopTools_Array1OfShape aShapes (1,MaxShapes);
4179 TColStd_Array1OfInteger OrderInd(1,MaxShapes);
4180 TColStd_Array1OfReal MidXYZ (1,MaxShapes); //X,Y,Z;
4181 TColStd_Array1OfReal Length (1,MaxShapes); //X,Y,Z;
4183 // Computing of CentreOfMass
4184 Standard_Integer Index;
4187 TopTools_ListIteratorOfListOfShape it(SL);
4188 for (Index=1; it.More(); Index++)
4190 TopoDS_Shape S = it.Value();
4191 SL.Remove( it ); // == it.Next()
4193 OrderInd.SetValue (Index, Index);
4194 if (S.ShapeType() == TopAbs_VERTEX) {
4195 GPoint = BRep_Tool::Pnt( TopoDS::Vertex( S ));
4196 Length.SetValue( Index, (Standard_Real) S.Orientation());
4199 // BEGIN: fix for Mantis issue 0020842
4201 BRepGProp::LinearProperties (S, GPr);
4204 if (S.ShapeType() == TopAbs_EDGE || S.ShapeType() == TopAbs_WIRE) {
4205 BRepGProp::LinearProperties (S, GPr);
4207 else if (S.ShapeType() == TopAbs_FACE || S.ShapeType() == TopAbs_SHELL) {
4208 BRepGProp::SurfaceProperties(S, GPr);
4211 BRepGProp::VolumeProperties(S, GPr);
4214 // END: fix for Mantis issue 0020842
4215 GPoint = GPr.CentreOfMass();
4216 Length.SetValue(Index, GPr.Mass());
4218 MidXYZ.SetValue(Index, GPoint.X()*999.0 + GPoint.Y()*99.0 + GPoint.Z()*0.9);
4219 //cout << Index << " L: " << Length(Index) << "CG: " << MidXYZ(Index) << endl;
4223 Standard_Integer aTemp;
4224 Standard_Boolean exchange, Sort = Standard_True;
4225 Standard_Real tol = Precision::Confusion();
4228 Sort = Standard_False;
4229 for (Index=1; Index < MaxShapes; Index++)
4231 exchange = Standard_False;
4232 Standard_Real dMidXYZ = MidXYZ(OrderInd(Index)) - MidXYZ(OrderInd(Index+1));
4233 Standard_Real dLength = Length(OrderInd(Index)) - Length(OrderInd(Index+1));
4234 if ( dMidXYZ >= tol ) {
4235 // cout << "MidXYZ: " << MidXYZ(OrderInd(Index))<< " > " <<MidXYZ(OrderInd(Index+1))
4236 // << " d: " << dMidXYZ << endl;
4237 exchange = Standard_True;
4239 else if ( Abs(dMidXYZ) < tol && dLength >= tol ) {
4240 // cout << "Length: " << Length(OrderInd(Index))<< " > " <<Length(OrderInd(Index+1))
4241 // << " d: " << dLength << endl;
4242 exchange = Standard_True;
4244 else if ( Abs(dMidXYZ) < tol && Abs(dLength) < tol &&
4245 aShapes(OrderInd(Index)).ShapeType() <= TopAbs_FACE) {
4247 // equal values possible on shapes such as two halves of a sphere and
4248 // a membrane inside the sphere
4250 BRepBndLib::Add( aShapes( OrderInd(Index) ), box1 );
4251 if ( box1.IsVoid() ) continue;
4252 BRepBndLib::Add( aShapes( OrderInd(Index+1) ), box2 );
4253 Standard_Real dSquareExtent = box1.SquareExtent() - box2.SquareExtent();
4254 if ( dSquareExtent >= tol ) {
4255 // cout << "SquareExtent: " << box1.SquareExtent()<<" > "<<box2.SquareExtent() << endl;
4256 exchange = Standard_True;
4258 else if ( Abs(dSquareExtent) < tol ) {
4259 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax, val1, val2;
4260 box1.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
4261 val1 = (aXmin+aXmax)*999 + (aYmin+aYmax)*99 + (aZmin+aZmax)*0.9;
4262 box2.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
4263 val2 = (aXmin+aXmax)*999 + (aYmin+aYmax)*99 + (aZmin+aZmax)*0.9;
4264 //exchange = val1 > val2;
4265 if ((val1 - val2) >= tol) {
4266 exchange = Standard_True;
4268 //cout << "box: " << val1<<" > "<<val2 << endl;
4274 // cout << "exchange " << Index << " & " << Index+1 << endl;
4275 aTemp = OrderInd(Index);
4276 OrderInd(Index) = OrderInd(Index+1);
4277 OrderInd(Index+1) = aTemp;
4278 Sort = Standard_True;
4283 for (Index=1; Index <= MaxShapes; Index++)
4284 SL.Append( aShapes( OrderInd(Index) ));
4288 //=======================================================================
4289 //function : CompsolidToCompound
4291 //=======================================================================
4292 TopoDS_Shape GEOMImpl_IShapesOperations::CompsolidToCompound (const TopoDS_Shape& theCompsolid)
4294 if (theCompsolid.ShapeType() != TopAbs_COMPSOLID) {
4295 return theCompsolid;
4298 TopoDS_Compound aCompound;
4300 B.MakeCompound(aCompound);
4302 TopTools_MapOfShape mapShape;
4303 TopoDS_Iterator It (theCompsolid, Standard_True, Standard_True);
4305 for (; It.More(); It.Next()) {
4306 TopoDS_Shape aShape_i = It.Value();
4307 if (mapShape.Add(aShape_i)) {
4308 B.Add(aCompound, aShape_i);
4315 //=======================================================================
4316 //function : CheckTriangulation
4318 //=======================================================================
4319 bool GEOMImpl_IShapesOperations::CheckTriangulation (const TopoDS_Shape& aShape)
4321 bool isTriangulation = true;
4323 TopExp_Explorer exp (aShape, TopAbs_FACE);
4326 TopLoc_Location aTopLoc;
4327 Handle(Poly_Triangulation) aTRF;
4328 aTRF = BRep_Tool::Triangulation(TopoDS::Face(exp.Current()), aTopLoc);
4329 if (aTRF.IsNull()) {
4330 isTriangulation = false;
4333 else // no faces, try edges
4335 TopExp_Explorer expe (aShape, TopAbs_EDGE);
4339 TopLoc_Location aLoc;
4340 Handle(Poly_Polygon3D) aPE = BRep_Tool::Polygon3D(TopoDS::Edge(expe.Current()), aLoc);
4342 isTriangulation = false;
4346 if (!isTriangulation) {
4347 // calculate deflection
4348 Standard_Real aDeviationCoefficient = 0.001;
4351 BRepBndLib::Add(aShape, B);
4352 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
4353 B.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
4355 Standard_Real dx = aXmax - aXmin, dy = aYmax - aYmin, dz = aZmax - aZmin;
4356 Standard_Real aDeflection = Max(Max(dx, dy), dz) * aDeviationCoefficient * 4;
4357 Standard_Real aHLRAngle = 0.349066;
4359 BRepMesh_IncrementalMesh Inc (aShape, aDeflection, Standard_False, aHLRAngle);
4365 #define MAX_TOLERANCE 1.e-7
4367 //=======================================================================
4368 //function : isSameEdge
4369 //purpose : Returns True if two edges coincide
4370 //=======================================================================
4371 static bool isSameEdge(const TopoDS_Edge& theEdge1, const TopoDS_Edge& theEdge2)
4373 TopoDS_Vertex V11, V12, V21, V22;
4374 TopExp::Vertices(theEdge1, V11, V12);
4375 TopExp::Vertices(theEdge2, V21, V22);
4376 gp_Pnt P11 = BRep_Tool::Pnt(V11);
4377 gp_Pnt P12 = BRep_Tool::Pnt(V12);
4378 gp_Pnt P21 = BRep_Tool::Pnt(V21);
4379 gp_Pnt P22 = BRep_Tool::Pnt(V22);
4380 bool coincide = false;
4382 //Check that ends of edges coincide
4383 if(P11.Distance(P21) <= MAX_TOLERANCE) {
4384 if(P12.Distance(P22) <= MAX_TOLERANCE) coincide = true;
4386 else if(P11.Distance(P22) <= MAX_TOLERANCE) {
4387 if(P12.Distance(P21) <= MAX_TOLERANCE) coincide = true;
4390 if(!coincide) return false;
4392 if (BRep_Tool::Degenerated(theEdge1))
4393 if (BRep_Tool::Degenerated(theEdge2)) return true;
4396 if (BRep_Tool::Degenerated(theEdge2)) return false;
4398 double U11, U12, U21, U22;
4399 Handle(Geom_Curve) C1 = BRep_Tool::Curve(theEdge1, U11, U12);
4400 Handle(Geom_Curve) C2 = BRep_Tool::Curve(theEdge2, U21, U22);
4401 if(C1->DynamicType() == C2->DynamicType()) return true;
4403 //Check that both edges has the same geometry
4404 double range = U12-U11;
4405 double U = U11+ range/3.0;
4406 gp_Pnt P1 = C1->Value(U); //Compute a point on one third of the edge's length
4407 U = U11+range*2.0/3.0;
4408 gp_Pnt P2 = C1->Value(U); //Compute a point on two thirds of the edge's length
4410 if(!GeomLib_Tool::Parameter(C2, P1, MAX_TOLERANCE, U) || U < U21 || U > U22)
4413 if(P1.Distance(C2->Value(U)) > MAX_TOLERANCE) return false;
4415 if(!GeomLib_Tool::Parameter(C2, P2, MAX_TOLERANCE, U) || U < U21 || U > U22)
4418 if(P2.Distance(C2->Value(U)) > MAX_TOLERANCE) return false;
4423 #include <TopoDS_TShape.hxx>
4424 //=======================================================================
4425 //function : isSameFace
4426 //purpose : Returns True if two faces coincide
4427 //=======================================================================
4428 static bool isSameFace(const TopoDS_Face& theFace1, const TopoDS_Face& theFace2)
4430 TopExp_Explorer E(theFace1, TopAbs_EDGE);
4431 TopTools_ListOfShape LS1, LS2;
4432 for(; E.More(); E.Next()) LS1.Append(E.Current());
4434 E.Init(theFace2, TopAbs_EDGE);
4435 for(; E.More(); E.Next()) LS2.Append(E.Current());
4437 //Compare the number of edges in the faces
4438 if(LS1.Extent() != LS2.Extent()) return false;
4440 double aMin = RealFirst(), aMax = RealLast();
4441 double xminB1=aMax, yminB1=aMax, zminB1=aMax, xminB2=aMax, yminB2=aMax, zminB2=aMax;
4442 double xmaxB1=aMin, ymaxB1=aMin, zmaxB1=aMin, xmaxB2=aMin, ymaxB2=aMin, zmaxB2=aMin;
4444 for(E.Init(theFace1, TopAbs_VERTEX); E.More(); E.Next()) {
4445 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4446 if(P.X() < xminB1) xminB1 = P.X();
4447 if(P.Y() < yminB1) yminB1 = P.Y();
4448 if(P.Z() < zminB1) zminB1 = P.Z();
4449 if(P.X() > xmaxB1) xmaxB1 = P.X();
4450 if(P.Y() > ymaxB1) ymaxB1 = P.Y();
4451 if(P.Z() > zmaxB1) zmaxB1 = P.Z();
4454 for(E.Init(theFace2, TopAbs_VERTEX); E.More(); E.Next()) {
4455 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4456 if(P.X() < xminB2) xminB2 = P.X();
4457 if(P.Y() < yminB2) yminB2 = P.Y();
4458 if(P.Z() < zminB2) zminB2 = P.Z();
4459 if(P.X() > xmaxB2) xmaxB2 = P.X();
4460 if(P.Y() > ymaxB2) ymaxB2 = P.Y();
4461 if(P.Z() > zmaxB2) zmaxB2 = P.Z();
4464 //Compare the bounding boxes of both faces
4465 if(gp_Pnt(xminB1, yminB1, zminB1).Distance(gp_Pnt(xminB2, yminB2, zminB2)) > MAX_TOLERANCE)
4468 if(gp_Pnt(xmaxB1, ymaxB1, zmaxB1).Distance(gp_Pnt(xmaxB2, ymaxB2, zmaxB2)) > MAX_TOLERANCE)
4471 Handle(Geom_Surface) S1 = BRep_Tool::Surface(theFace1);
4472 Handle(Geom_Surface) S2 = BRep_Tool::Surface(theFace2);
4474 //Check if there a coincidence of two surfaces at least in two points
4475 double U11, U12, V11, V12, U21, U22, V21, V22;
4476 BRepTools::UVBounds(theFace1, U11, U12, V11, V12);
4477 BRepTools::UVBounds(theFace2, U21, U22, V21, V22);
4479 double rangeU = U12-U11;
4480 double rangeV = V12-V11;
4481 double U = U11 + rangeU/3.0;
4482 double V = V11 + rangeV/3.0;
4483 gp_Pnt P1 = S1->Value(U, V);
4484 U = U11+rangeU*2.0/3.0;
4485 V = V11+rangeV*2.0/3.0;
4486 gp_Pnt P2 = S1->Value(U, V);
4488 if (!GeomLib_Tool::Parameters(S2, P1, MAX_TOLERANCE, U, V) || U < U21 || U > U22 || V < V21 || V > V22)
4491 if (P1.Distance(S2->Value(U,V)) > MAX_TOLERANCE) return false;
4493 if (!GeomLib_Tool::Parameters(S2, P2, MAX_TOLERANCE, U, V) || U < U21 || U > U22 || V < V21 || V > V22)
4496 if (P2.Distance(S2->Value(U, V)) > MAX_TOLERANCE) return false;
4498 //Check that each edge of the Face1 has a counterpart in the Face2
4499 TopTools_MapOfOrientedShape aMap;
4500 TopTools_ListIteratorOfListOfShape LSI1(LS1);
4501 for(; LSI1.More(); LSI1.Next()) {
4502 TopoDS_Edge E = TopoDS::Edge(LSI1.Value());
4503 bool isFound = false;
4504 TopTools_ListIteratorOfListOfShape LSI2(LS2);
4505 for(; LSI2.More(); LSI2.Next()) {
4506 TopoDS_Shape aValue = LSI2.Value();
4507 if(aMap.Contains(aValue)) continue; //To avoid checking already found edge several times
4508 if(isSameEdge(E, TopoDS::Edge(aValue))) {
4514 if(!isFound) return false;
4520 //=======================================================================
4521 //function : isSameSolid
4522 //purpose : Returns True if two solids coincide
4523 //=======================================================================
4524 bool isSameSolid(const TopoDS_Solid& theSolid1, const TopoDS_Solid& theSolid2)
4526 TopExp_Explorer E(theSolid1, TopAbs_FACE);
4527 TopTools_ListOfShape LS1, LS2;
4528 for(; E.More(); E.Next()) LS1.Append(E.Current());
4529 E.Init(theSolid2, TopAbs_FACE);
4530 for(; E.More(); E.Next()) LS2.Append(E.Current());
4532 if(LS1.Extent() != LS2.Extent()) return false;
4534 double aMin = RealFirst(), aMax = RealLast();
4535 double xminB1=aMax, yminB1=aMax, zminB1=aMax, xminB2=aMax, yminB2=aMax, zminB2=aMax;
4536 double xmaxB1=aMin, ymaxB1=aMin, zmaxB1=aMin, xmaxB2=aMin, ymaxB2=aMin, zmaxB2=aMin;
4538 for(E.Init(theSolid1, TopAbs_VERTEX); E.More(); E.Next()) {
4539 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4540 if(P.X() < xminB1) xminB1 = P.X();
4541 if(P.Y() < yminB1) yminB1 = P.Y();
4542 if(P.Z() < zminB1) zminB1 = P.Z();
4543 if(P.X() > xmaxB1) xmaxB1 = P.X();
4544 if(P.Y() > ymaxB1) ymaxB1 = P.Y();
4545 if(P.Z() > zmaxB1) zmaxB1 = P.Z();
4548 for(E.Init(theSolid2, TopAbs_VERTEX); E.More(); E.Next()) {
4549 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4550 if(P.X() < xminB2) xminB2 = P.X();
4551 if(P.Y() < yminB2) yminB2 = P.Y();
4552 if(P.Z() < zminB2) zminB2 = P.Z();
4553 if(P.X() > xmaxB2) xmaxB2 = P.X();
4554 if(P.Y() > ymaxB2) ymaxB2 = P.Y();
4555 if(P.Z() > zmaxB2) zmaxB2 = P.Z();
4558 //Compare the bounding boxes of both solids
4559 if(gp_Pnt(xminB1, yminB1, zminB1).Distance(gp_Pnt(xminB2, yminB2, zminB2)) > MAX_TOLERANCE)
4562 if(gp_Pnt(xmaxB1, ymaxB1, zmaxB1).Distance(gp_Pnt(xmaxB2, ymaxB2, zmaxB2)) > MAX_TOLERANCE)
4565 //Check that each face of the Solid1 has a counterpart in the Solid2
4566 TopTools_MapOfOrientedShape aMap;
4567 TopTools_ListIteratorOfListOfShape LSI1(LS1);
4568 for(; LSI1.More(); LSI1.Next()) {
4569 TopoDS_Face F = TopoDS::Face(LSI1.Value());
4570 bool isFound = false;
4571 TopTools_ListIteratorOfListOfShape LSI2(LS2);
4572 for(; LSI2.More(); LSI2.Next()) {
4573 if(aMap.Contains(LSI2.Value())) continue; //To avoid checking already found faces several times
4574 if(isSameFace(F, TopoDS::Face(LSI2.Value()))) {
4575 aMap.Add(LSI2.Value());
4580 if(!isFound) return false;
4586 //=======================================================================
4587 //function : GetSame
4589 //=======================================================================
4590 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetSame(const Handle(GEOM_Object)& theShapeWhere,
4591 const Handle(GEOM_Object)& theShapeWhat)
4594 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
4596 TopoDS_Shape aWhere = theShapeWhere->GetValue();
4597 TopoDS_Shape aWhat = theShapeWhat->GetValue();
4599 if (aWhere.IsNull() || aWhat.IsNull()) return NULL;
4602 bool isFound = false;
4603 TopoDS_Shape aSubShape;
4604 TopTools_MapOfShape aMap;
4606 if (aWhat.ShapeType() == TopAbs_COMPOUND || aWhat.ShapeType() == TopAbs_COMPSOLID) {
4607 TopoDS_Iterator It (aWhat, Standard_True, Standard_True);
4608 if (It.More()) aWhat = It.Value();
4611 SetErrorCode("Compounds of two or more shapes are not allowed for aWhat argument");
4616 switch (aWhat.ShapeType()) {
4617 case TopAbs_VERTEX: {
4618 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(aWhat));
4619 TopExp_Explorer E(aWhere, TopAbs_VERTEX);
4620 for(; E.More(); E.Next()) {
4621 if(!aMap.Add(E.Current())) continue;
4622 gp_Pnt P2 = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4623 if(P.Distance(P2) <= MAX_TOLERANCE) {
4625 aSubShape = E.Current();
4632 TopoDS_Edge anEdge = TopoDS::Edge(aWhat);
4633 TopExp_Explorer E(aWhere, TopAbs_EDGE);
4634 for(; E.More(); E.Next()) {
4635 if(!aMap.Add(E.Current())) continue;
4636 if(isSameEdge(anEdge, TopoDS::Edge(E.Current()))) {
4637 aSubShape = E.Current();
4645 TopoDS_Face aFace = TopoDS::Face(aWhat);
4646 TopExp_Explorer E(aWhere, TopAbs_FACE);
4647 for(; E.More(); E.Next()) {
4648 if(!aMap.Add(E.Current())) continue;
4649 if(isSameFace(aFace, TopoDS::Face(E.Current()))) {
4650 aSubShape = E.Current();
4657 case TopAbs_SOLID: {
4658 TopoDS_Solid aSolid = TopoDS::Solid(aWhat);
4659 TopExp_Explorer E(aWhere, TopAbs_SOLID);
4660 for(; E.More(); E.Next()) {
4661 if(!aMap.Add(E.Current())) continue;
4662 if(isSameSolid(aSolid, TopoDS::Solid(E.Current()))) {
4663 aSubShape = E.Current();
4675 TopTools_IndexedMapOfShape anIndices;
4676 TopExp::MapShapes(aWhere, anIndices);
4677 if (anIndices.Contains(aSubShape))
4678 anIndex = anIndices.FindIndex(aSubShape);
4681 if (anIndex < 0) return NULL;
4683 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
4685 anArray->SetValue(1, anIndex);
4687 Handle(GEOM_Object) aResult = GetEngine()->AddSubShape(theShapeWhere, anArray);
4688 Handle(GEOM_Function) aFunction = aResult->GetLastFunction();
4690 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetSame("
4691 << theShapeWhere << ", " << theShapeWhat << ")";