1 // Copyright (C) 2007-2014 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 // File : GEOMImpl_IShapesOperations.cxx
25 // Author : modified by Lioka RAZAFINDRAZAKA (CEA) 22/06/2007
28 #include <Standard_Stream.hxx>
30 #include "GEOMImpl_IShapesOperations.hxx"
32 #include "GEOMImpl_Types.hxx"
34 #include "GEOMImpl_VectorDriver.hxx"
35 #include "GEOMImpl_ShapeDriver.hxx"
36 #include "GEOMImpl_GlueDriver.hxx"
38 #include "GEOMImpl_IVector.hxx"
39 #include "GEOMImpl_IShapes.hxx"
40 #include "GEOMImpl_IGlue.hxx"
42 #include "GEOMImpl_Block6Explorer.hxx"
43 #include "GEOMImpl_IHealingOperations.hxx"
45 #include "GEOMImpl_Gen.hxx"
47 #include "GEOM_Function.hxx"
48 #include "GEOM_ISubShape.hxx"
49 #include "GEOM_PythonDump.hxx"
51 #include "GEOMUtils.hxx"
53 #include "GEOMAlgo_ClsfBox.hxx"
54 #include "GEOMAlgo_ClsfSolid.hxx"
55 #include "GEOMAlgo_CoupleOfShapes.hxx"
56 #include "GEOMAlgo_FinderShapeOn1.hxx"
57 #include "GEOMAlgo_FinderShapeOnQuad.hxx"
58 #include "GEOMAlgo_FinderShapeOn2.hxx"
59 #include "GEOMAlgo_GetInPlace.hxx"
60 #include "GEOMAlgo_GlueDetector.hxx"
61 #include "GEOMAlgo_ListIteratorOfListOfCoupleOfShapes.hxx"
62 #include "GEOMAlgo_ListOfCoupleOfShapes.hxx"
64 #include <Basics_OCCTVersion.hxx>
66 #include <utilities.h>
68 #include <Utils_ExceptHandlers.hxx>
70 #include <TFunction_DriverTable.hxx>
71 #include <TFunction_Driver.hxx>
72 #include <TFunction_Logbook.hxx>
73 #include <TDataStd_Integer.hxx>
74 #include <TDataStd_IntegerArray.hxx>
75 #include <TDataStd_ListIteratorOfListOfExtendedString.hxx>
76 #include <TDF_Tool.hxx>
78 #include <BRepExtrema_ExtCF.hxx>
79 #include <BRepExtrema_DistShapeShape.hxx>
81 #include <BRep_Tool.hxx>
82 #include <BRep_Builder.hxx>
83 #include <BRepTools.hxx>
84 #include <BRepGProp.hxx>
85 #include <BRepAdaptor_Curve.hxx>
86 #include <BRepAdaptor_Surface.hxx>
87 #include <BRepBndLib.hxx>
88 #include <BRepMesh_IncrementalMesh.hxx>
92 #include <TopExp_Explorer.hxx>
93 #include <TopLoc_Location.hxx>
95 #include <TopoDS_Shape.hxx>
96 #include <TopoDS_Solid.hxx>
97 #include <TopoDS_Face.hxx>
98 #include <TopoDS_Edge.hxx>
99 #include <TopoDS_Vertex.hxx>
100 #include <TopoDS_Compound.hxx>
101 #include <TopoDS_Iterator.hxx>
102 #include <TopTools_Array1OfShape.hxx>
103 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
104 #include <TopTools_IndexedMapOfShape.hxx>
105 #include <TopTools_ListIteratorOfListOfShape.hxx>
106 #include <TopTools_MapOfShape.hxx>
107 #include <TopTools_MapOfOrientedShape.hxx>
109 #include <Geom_Surface.hxx>
110 #include <Geom_Plane.hxx>
111 #include <Geom_SphericalSurface.hxx>
112 #include <Geom_CylindricalSurface.hxx>
113 #include <GeomAdaptor_Surface.hxx>
115 #include <GeomLib_Tool.hxx>
116 #include <Geom2d_Curve.hxx>
118 #include <Bnd_Box.hxx>
119 #include <GProp_GProps.hxx>
120 #include <TColStd_Array1OfReal.hxx>
121 #include <TColStd_HArray1OfInteger.hxx>
122 #include <TColStd_ListIteratorOfListOfInteger.hxx>
123 #include <TColStd_ListOfInteger.hxx>
124 #include <gp_Cylinder.hxx>
125 #include <gp_Lin.hxx>
126 #include <gp_Pnt.hxx>
130 #include <functional>
132 #include <Standard_NullObject.hxx>
133 #include <Standard_Failure.hxx>
134 #include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
136 // Includes added for GetInPlace algorithm improvement
138 #include <GEOMImpl_MeasureDriver.hxx>
139 #include <GEOMImpl_IMeasure.hxx>
140 #include <BRepBuilderAPI_MakeVertex.hxx>
142 #include <BRepClass_FaceClassifier.hxx>
143 #include <BRepClass3d_SolidClassifier.hxx>
144 #include <Precision.hxx>
146 //=============================================================================
150 //=============================================================================
151 GEOMImpl_IShapesOperations::GEOMImpl_IShapesOperations (GEOM_Engine* theEngine, int theDocID)
152 : GEOM_IOperations(theEngine, theDocID)
154 MESSAGE("GEOMImpl_IShapesOperations::GEOMImpl_IShapesOperations");
157 //=============================================================================
161 //=============================================================================
162 GEOMImpl_IShapesOperations::~GEOMImpl_IShapesOperations()
164 MESSAGE("GEOMImpl_IShapesOperations::~GEOMImpl_IShapesOperations");
167 //=============================================================================
171 //=============================================================================
172 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeEdge
173 (Handle(GEOM_Object) thePnt1, Handle(GEOM_Object) thePnt2)
177 if (thePnt1.IsNull() || thePnt2.IsNull()) return NULL;
179 //Add a new Edge object
180 Handle(GEOM_Object) anEdge = GetEngine()->AddObject(GetDocID(), GEOM_EDGE);
182 //Add a new Vector function
183 Handle(GEOM_Function) aFunction =
184 anEdge->AddFunction(GEOMImpl_VectorDriver::GetID(), VECTOR_TWO_PNT);
186 //Check if the function is set correctly
187 if (aFunction->GetDriverGUID() != GEOMImpl_VectorDriver::GetID()) return NULL;
189 GEOMImpl_IVector aPI (aFunction);
191 Handle(GEOM_Function) aRef1 = thePnt1->GetLastFunction();
192 Handle(GEOM_Function) aRef2 = thePnt2->GetLastFunction();
193 if (aRef1.IsNull() || aRef2.IsNull()) return NULL;
195 aPI.SetPoint1(aRef1);
196 aPI.SetPoint2(aRef2);
198 //Compute the Edge value
200 #if OCC_VERSION_LARGE > 0x06010000
203 if (!GetSolver()->ComputeFunction(aFunction)) {
204 SetErrorCode("Vector driver failed");
208 catch (Standard_Failure) {
209 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
210 SetErrorCode(aFail->GetMessageString());
214 //Make a Python command
215 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdge("
216 << thePnt1 << ", " << thePnt2 << ")";
222 //=============================================================================
224 * MakeEdgeOnCurveByLength
226 //=============================================================================
227 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeEdgeOnCurveByLength
228 (Handle(GEOM_Object) theRefCurve,
229 const Standard_Real theLength,
230 Handle(GEOM_Object) theStartPoint)
234 if (theRefCurve.IsNull()) return NULL;
236 //Add a new Edge object
237 Handle(GEOM_Object) anEdge = GetEngine()->AddObject(GetDocID(), GEOM_EDGE);
239 //Add a new Vector function
240 Handle(GEOM_Function) aFunction =
241 anEdge->AddFunction(GEOMImpl_ShapeDriver::GetID(), EDGE_CURVE_LENGTH);
243 //Check if the function is set correctly
244 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
246 GEOMImpl_IVector aPI (aFunction);
248 Handle(GEOM_Function) aRef1 = theRefCurve->GetLastFunction();
249 if (aRef1.IsNull()) return NULL;
250 aPI.SetPoint1(aRef1);
252 if (!theStartPoint.IsNull()) {
253 Handle(GEOM_Function) aRef2 = theStartPoint->GetLastFunction();
254 aPI.SetPoint2(aRef2);
257 aPI.SetParameter(theLength);
259 //Compute the Edge value
261 #if OCC_VERSION_LARGE > 0x06010000
264 if (!GetSolver()->ComputeFunction(aFunction)) {
265 SetErrorCode("Vector driver failed");
269 catch (Standard_Failure) {
270 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
271 SetErrorCode(aFail->GetMessageString());
275 //Make a Python command
276 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdgeOnCurveByLength("
277 << theRefCurve << ", " << theLength << ", " << theStartPoint << ")";
283 //=============================================================================
287 //=============================================================================
288 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeEdgeWire
289 (Handle(GEOM_Object) theWire,
290 const Standard_Real theLinearTolerance,
291 const Standard_Real theAngularTolerance)
295 if (theWire.IsNull()) return NULL;
297 //Add a new Edge object
298 Handle(GEOM_Object) anEdge = GetEngine()->AddObject(GetDocID(), GEOM_EDGE);
300 //Add a new Vector function
301 Handle(GEOM_Function) aFunction =
302 anEdge->AddFunction(GEOMImpl_ShapeDriver::GetID(), EDGE_WIRE);
304 //Check if the function is set correctly
305 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
307 GEOMImpl_IShapes aCI (aFunction);
309 Handle(GEOM_Function) aWire = theWire->GetLastFunction();
311 if (aWire.IsNull()) return NULL;
314 aCI.SetTolerance(theLinearTolerance);
315 aCI.SetAngularTolerance(theAngularTolerance);
317 //Compute the Edge value
319 #if OCC_VERSION_LARGE > 0x06010000
322 if (!GetSolver()->ComputeFunction(aFunction)) {
323 SetErrorCode("Shape driver failed");
327 catch (Standard_Failure) {
328 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
329 SetErrorCode(aFail->GetMessageString());
333 const double DEF_LIN_TOL = Precision::Confusion();
334 const double DEF_ANG_TOL = Precision::Angular();
335 //Make a Python command
336 if ( theAngularTolerance == DEF_ANG_TOL ) {
337 if ( theLinearTolerance == DEF_LIN_TOL )
338 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdgeWire("
341 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdgeWire("
342 << theWire << ", " << theLinearTolerance << ")";
345 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdgeWire("
346 << theWire << ", " << theLinearTolerance << ", "
347 << theAngularTolerance << ")";
354 //=============================================================================
358 //=============================================================================
359 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeWire
360 (std::list<Handle(GEOM_Object)> theShapes,
361 const Standard_Real theTolerance)
366 Handle(GEOM_Object) aWire = GetEngine()->AddObject(GetDocID(), GEOM_WIRE);
369 Handle(GEOM_Function) aFunction =
370 aWire->AddFunction(GEOMImpl_ShapeDriver::GetID(), WIRE_EDGES);
371 if (aFunction.IsNull()) return NULL;
373 //Check if the function is set correctly
374 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
376 GEOMImpl_IShapes aCI (aFunction);
377 aCI.SetTolerance(theTolerance);
379 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
382 std::list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
383 for (; it != theShapes.end(); it++) {
384 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
385 if (aRefSh.IsNull()) {
386 SetErrorCode("NULL argument shape for the shape construction");
389 aShapesSeq->Append(aRefSh);
391 aCI.SetShapes(aShapesSeq);
395 #if OCC_VERSION_LARGE > 0x06010000
398 if (!GetSolver()->ComputeFunction(aFunction)) {
399 SetErrorCode("Shape driver failed");
403 catch (Standard_Failure) {
404 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
405 SetErrorCode(aFail->GetMessageString());
409 //Make a Python command
410 GEOM::TPythonDump pd (aFunction);
411 pd << aWire << " = geompy.MakeWire([";
414 it = theShapes.begin();
415 if (it != theShapes.end()) {
417 while (it != theShapes.end()) {
418 pd << ", " << (*it++);
421 pd << "], " << theTolerance << ")";
427 //=============================================================================
431 //=============================================================================
432 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFace (Handle(GEOM_Object) theWire,
433 const bool isPlanarWanted)
437 if (theWire.IsNull()) return NULL;
439 //Add a new Face object
440 Handle(GEOM_Object) aFace = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
442 //Add a new Shape function for creation of a face from a wire
443 Handle(GEOM_Function) aFunction =
444 aFace->AddFunction(GEOMImpl_ShapeDriver::GetID(), FACE_WIRE);
445 if (aFunction.IsNull()) return NULL;
447 //Check if the function is set correctly
448 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
450 GEOMImpl_IShapes aCI (aFunction);
452 Handle(GEOM_Function) aRefWire = theWire->GetLastFunction();
454 if (aRefWire.IsNull()) return NULL;
456 aCI.SetBase(aRefWire);
457 aCI.SetIsPlanar(isPlanarWanted);
459 //Compute the Face value
460 Standard_Boolean isWarning = Standard_False;
462 #if OCC_VERSION_LARGE > 0x06010000
465 if (!GetSolver()->ComputeFunction(aFunction)) {
466 SetErrorCode("Shape driver failed to compute a face");
470 catch (Standard_Failure) {
471 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
472 SetErrorCode(aFail->GetMessageString());
473 // to provide warning
474 if (!aFunction->GetValue().IsNull()) {
475 isWarning = Standard_True;
481 //Make a Python command
482 GEOM::TPythonDump(aFunction) << aFace << " = geompy.MakeFace("
483 << theWire << ", " << (int)isPlanarWanted << ")";
485 // to provide warning
486 if (!isWarning) SetErrorCode(OK);
490 //=============================================================================
494 //=============================================================================
495 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFaceWires
496 (std::list<Handle(GEOM_Object)> theShapes,
497 const bool isPlanarWanted)
502 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
505 Handle(GEOM_Function) aFunction =
506 aShape->AddFunction(GEOMImpl_ShapeDriver::GetID(), FACE_WIRES);
507 if (aFunction.IsNull()) return NULL;
509 //Check if the function is set correctly
510 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
512 GEOMImpl_IShapes aCI (aFunction);
514 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
517 std::list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
518 for (; it != theShapes.end(); it++) {
519 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
520 if (aRefSh.IsNull()) {
521 SetErrorCode("NULL argument shape for the face construction");
524 aShapesSeq->Append(aRefSh);
526 aCI.SetShapes(aShapesSeq);
528 aCI.SetIsPlanar(isPlanarWanted);
531 Standard_Boolean isWarning = Standard_False;
533 #if OCC_VERSION_LARGE > 0x06010000
536 if (!GetSolver()->ComputeFunction(aFunction)) {
537 SetErrorCode("Shape driver failed");
541 catch (Standard_Failure) {
542 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
543 SetErrorCode(aFail->GetMessageString());
544 // to provide warning
545 if (!aFunction->GetValue().IsNull()) {
546 isWarning = Standard_True;
552 //Make a Python command
553 GEOM::TPythonDump pd (aFunction);
554 pd << aShape << " = geompy.MakeFaceWires([";
557 it = theShapes.begin();
558 if (it != theShapes.end()) {
560 while (it != theShapes.end()) {
561 pd << ", " << (*it++);
564 pd << "], " << (int)isPlanarWanted << ")";
566 // to provide warning
567 if (!isWarning) SetErrorCode(OK);
571 //=============================================================================
575 //=============================================================================
576 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeShell
577 (std::list<Handle(GEOM_Object)> theShapes)
579 return MakeShape(theShapes, GEOM_SHELL, SHELL_FACES, "MakeShell");
582 //=============================================================================
586 //=============================================================================
587 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeSolidShells
588 (std::list<Handle(GEOM_Object)> theShapes)
590 return MakeShape(theShapes, GEOM_SOLID, SOLID_SHELLS, "MakeSolid");
593 //=============================================================================
597 //=============================================================================
598 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeCompound
599 (std::list<Handle(GEOM_Object)> theShapes)
601 return MakeShape(theShapes, GEOM_COMPOUND, COMPOUND_SHAPES, "MakeCompound");
604 //=============================================================================
608 //=============================================================================
609 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeShape
610 (std::list<Handle(GEOM_Object)> theShapes,
611 const Standard_Integer theObjectType,
612 const Standard_Integer theFunctionType,
613 const TCollection_AsciiString& theMethodName)
618 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), theObjectType);
621 Handle(GEOM_Function) aFunction =
622 aShape->AddFunction(GEOMImpl_ShapeDriver::GetID(), theFunctionType);
623 if (aFunction.IsNull()) return NULL;
625 //Check if the function is set correctly
626 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
628 GEOMImpl_IShapes aCI (aFunction);
630 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
633 std::list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
634 for (; it != theShapes.end(); it++) {
635 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
636 if (aRefSh.IsNull()) {
637 SetErrorCode("NULL argument shape for the shape construction");
640 aShapesSeq->Append(aRefSh);
642 aCI.SetShapes(aShapesSeq);
646 #if OCC_VERSION_LARGE > 0x06010000
649 if (!GetSolver()->ComputeFunction(aFunction)) {
650 SetErrorCode("Shape driver failed");
654 catch (Standard_Failure) {
655 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
656 SetErrorCode(aFail->GetMessageString());
660 //Make a Python command
661 GEOM::TPythonDump pd (aFunction);
662 pd << aShape << " = geompy." << theMethodName.ToCString() << "([";
665 it = theShapes.begin();
666 if (it != theShapes.end()) {
668 while (it != theShapes.end()) {
669 pd << ", " << (*it++);
678 //=============================================================================
682 //=============================================================================
683 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeGlueFaces
684 (Handle(GEOM_Object) theShape,
685 const Standard_Real theTolerance,
686 const Standard_Boolean doKeepNonSolids)
690 if (theShape.IsNull()) return NULL;
692 //Add a new Glued object
693 Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
695 //Add a new Glue function
696 Handle(GEOM_Function) aFunction;
697 aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_FACES);
698 if (aFunction.IsNull()) return NULL;
700 //Check if the function is set correctly
701 if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
703 GEOMImpl_IGlue aCI (aFunction);
705 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
706 if (aRefShape.IsNull()) return NULL;
708 aCI.SetBase(aRefShape);
709 aCI.SetTolerance(theTolerance);
710 aCI.SetKeepNonSolids(doKeepNonSolids);
712 //Compute the sub-shape value
713 Standard_Boolean isWarning = Standard_False;
715 #if OCC_VERSION_LARGE > 0x06010000
718 if (!GetSolver()->ComputeFunction(aFunction)) {
719 SetErrorCode("Shape driver failed to glue faces");
723 catch (Standard_Failure) {
724 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
725 SetErrorCode(aFail->GetMessageString());
726 // to provide warning
727 if (!aFunction->GetValue().IsNull()) {
728 isWarning = Standard_True;
734 //Make a Python command
735 GEOM::TPythonDump(aFunction) << aGlued << " = geompy.MakeGlueFaces("
736 << theShape << ", " << theTolerance << ")";
738 // to provide warning
739 if (!isWarning) SetErrorCode(OK);
743 //=============================================================================
747 //=============================================================================
749 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetGlueFaces
750 (Handle(GEOM_Object) theShape,
751 const Standard_Real theTolerance)
755 if (theShape.IsNull()) return NULL;
756 TopoDS_Shape aShape = theShape->GetValue();
757 if (aShape.IsNull()) return NULL;
759 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
761 Standard_Integer iErr;
763 GEOMAlgo_Gluer1 aGluer;
764 GEOMAlgo_ListIteratorOfListOfCoupleOfShapes aItCS;
765 GEOMAlgo_CoupleOfShapes aCS;
766 GEOMAlgo_ListOfCoupleOfShapes aLCS;
768 //aGluer = new GEOMAlgo_Gluer1;
769 aGluer.SetShape(aShape);
770 aGluer.SetTolerance(theTolerance);
772 iErr = aGluer.ErrorStatus();
773 if (iErr) return NULL;
775 TopTools_ListOfShape listShape;
776 const GEOMAlgo_ListOfCoupleOfShapes& aLCSG = aGluer.GluedFaces();
778 aItCS.Initialize(aLCSG);
779 for (; aItCS.More(); aItCS.Next()) {
780 const GEOMAlgo_CoupleOfShapes& aCSG = aItCS.Value();
781 listShape.Append(aCSG.Shape1());
784 TopTools_ListIteratorOfListOfShape itSub (listShape);
785 TCollection_AsciiString anAsciiList, anEntry;
786 TopTools_IndexedMapOfShape anIndices;
787 TopExp::MapShapes(aShape, anIndices);
788 Handle(TColStd_HArray1OfInteger) anArray;
789 Handle(GEOM_Object) anObj;
790 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
791 TopoDS_Shape aValue = itSub.Value();
792 anArray = new TColStd_HArray1OfInteger(1,1);
793 anArray->SetValue(1, anIndices.FindIndex(aValue));
794 anObj = GetEngine()->AddSubShape(theShape, anArray);
795 if (!anObj.IsNull()) {
798 // for python command
799 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
800 anAsciiList += anEntry;
805 //Make a Python command
806 if( anAsciiList.Length() > 0 ) {
807 anAsciiList.Trunc(anAsciiList.Length() - 1);
808 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
809 GEOM::TPythonDump pd (aFunction, true);
810 pd << "[" << anAsciiList.ToCString();
811 pd << "] = geompy.GetGlueFaces(" << theShape << ", " << theTolerance << ")";
820 //=============================================================================
822 * MakeGlueFacesByList
824 //=============================================================================
825 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeGlueFacesByList
826 (Handle(GEOM_Object) theShape,
827 const Standard_Real theTolerance,
828 std::list<Handle(GEOM_Object)> theFaces,
829 const Standard_Boolean doKeepNonSolids,
830 const Standard_Boolean doGlueAllEdges)
834 if (theShape.IsNull()) return NULL;
836 //Add a new Glued object
837 Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
839 //Add a new Glue function
840 Handle(GEOM_Function) aFunction;
841 aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_FACES_BY_LIST);
842 if (aFunction.IsNull()) return NULL;
844 //Check if the function is set correctly
845 if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
847 GEOMImpl_IGlue aCI (aFunction);
849 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
850 if (aRefShape.IsNull()) return NULL;
852 aCI.SetBase(aRefShape);
853 aCI.SetTolerance(theTolerance);
854 aCI.SetKeepNonSolids(doKeepNonSolids);
855 aCI.SetGlueAllEdges(doGlueAllEdges);
857 Handle(TColStd_HSequenceOfTransient) aFaces = new TColStd_HSequenceOfTransient;
858 std::list<Handle(GEOM_Object)>::iterator it = theFaces.begin();
859 for (; it != theFaces.end(); it++) {
860 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
861 if (aRefSh.IsNull()) {
862 SetErrorCode("NULL argument shape for the shape construction");
865 aFaces->Append(aRefSh);
867 aCI.SetFaces(aFaces);
869 //Compute the sub-shape value
870 Standard_Boolean isWarning = Standard_False;
872 #if OCC_VERSION_LARGE > 0x06010000
875 if (!GetSolver()->ComputeFunction(aFunction)) {
876 SetErrorCode("Shape driver failed to glue faces");
880 catch (Standard_Failure) {
881 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
882 SetErrorCode(aFail->GetMessageString());
883 // to provide warning
884 if (!aFunction->GetValue().IsNull()) {
885 isWarning = Standard_True;
891 //Make a Python command
893 GEOM::TPythonDump pd(aFunction);
894 pd << aGlued << " = geompy.MakeGlueFacesByList("
895 << theShape << ", " << theTolerance << ", [";
897 it = theFaces.begin();
898 if (it != theFaces.end()) {
900 while (it != theFaces.end()) {
901 pd << ", " << (*it++);
904 pd << "], " << (bool)doKeepNonSolids << ", " << (bool)doGlueAllEdges << ")";
906 // to provide warning
907 if (!isWarning) SetErrorCode(OK);
911 //=============================================================================
915 //=============================================================================
916 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeGlueEdges
917 (Handle(GEOM_Object) theShape,
918 const Standard_Real theTolerance)
922 if (theShape.IsNull()) return NULL;
924 //Add a new Glued object
925 Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
927 //Add a new Glue function
928 Handle(GEOM_Function) aFunction;
929 aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_EDGES);
930 if (aFunction.IsNull()) return NULL;
932 //Check if the function is set correctly
933 if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
935 GEOMImpl_IGlue aCI (aFunction);
937 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
938 if (aRefShape.IsNull()) return NULL;
940 aCI.SetBase(aRefShape);
941 aCI.SetTolerance(theTolerance);
942 aCI.SetKeepNonSolids(true);
944 //Compute the sub-shape value
945 Standard_Boolean isWarning = Standard_False;
947 #if OCC_VERSION_LARGE > 0x06010000
950 if (!GetSolver()->ComputeFunction(aFunction)) {
951 SetErrorCode("Shape driver failed to glue edges");
955 catch (Standard_Failure) {
956 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
957 SetErrorCode(aFail->GetMessageString());
958 // to provide warning
959 if (!aFunction->GetValue().IsNull()) {
960 isWarning = Standard_True;
966 //Make a Python command
967 GEOM::TPythonDump(aFunction) << aGlued << " = geompy.MakeGlueEdges("
968 << theShape << ", " << theTolerance << ")";
970 // to provide warning
971 if (!isWarning) SetErrorCode(OK);
975 //=============================================================================
979 //=============================================================================
980 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetGlueShapes
981 (Handle(GEOM_Object) theShape,
982 const Standard_Real theTolerance,
983 const TopAbs_ShapeEnum theType)
987 if (theShape.IsNull()) return NULL;
988 TopoDS_Shape aShape = theShape->GetValue();
989 if (aShape.IsNull()) return NULL;
991 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
993 GEOMAlgo_GlueDetector aGluer;
994 aGluer.SetArgument(aShape);
995 aGluer.SetTolerance(theTolerance);
997 Standard_Integer iErr = aGluer.ErrorStatus();
998 if (iErr) return NULL;
1000 TCollection_AsciiString anAsciiList, anEntry;
1001 TopTools_IndexedMapOfShape anIndices;
1002 TopExp::MapShapes(aShape, anIndices);
1003 Handle(TColStd_HArray1OfInteger) anArray;
1004 Handle(GEOM_Object) anObj;
1006 TopTools_ListOfShape listOnePerSet;
1008 const TopTools_DataMapOfShapeListOfShape& aImages = aGluer.Images();
1009 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape aItDMSLS (aImages);
1010 for (int index = 1; aItDMSLS.More(); aItDMSLS.Next(), ++index) {
1012 //const TopoDS_Shape& aSkey = aItDMSLS.Key();
1014 // list of shapes of the argument that can be glued
1015 const TopTools_ListOfShape& aLSD = aItDMSLS.Value();
1017 //listShape.Append(aLSD.First());
1018 TopoDS_Shape aValue = aLSD.First();
1020 if (aValue.ShapeType() == theType) {
1021 listOnePerSet.Append(aValue);
1025 // for stable order of returned entities
1026 GEOMUtils::SortShapes(listOnePerSet, Standard_False);
1028 TopTools_ListIteratorOfListOfShape aListIt (listOnePerSet);
1029 for (; aListIt.More(); aListIt.Next()) {
1030 TopoDS_Shape aValue = aListIt.Value();
1031 anArray = new TColStd_HArray1OfInteger(1,1);
1032 anArray->SetValue(1, anIndices.FindIndex(aValue));
1033 anObj = GetEngine()->AddSubShape(theShape, anArray);
1034 if (!anObj.IsNull()) {
1035 aSeq->Append(anObj);
1037 // for python command
1038 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
1039 anAsciiList += anEntry;
1044 // Make a Python command
1045 if (anAsciiList.Length() > 0) {
1046 anAsciiList.Trunc(anAsciiList.Length() - 1);
1047 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
1048 GEOM::TPythonDump pd (aFunction, /*append=*/true);
1049 pd << "[" << anAsciiList.ToCString();
1050 if (theType == TopAbs_FACE)
1051 pd << "] = geompy.GetGlueFaces(" << theShape << ", " << theTolerance << ")";
1052 else if (theType == TopAbs_EDGE)
1053 pd << "] = geompy.GetGlueEdges(" << theShape << ", " << theTolerance << ")";
1061 //=============================================================================
1063 * MakeGlueEdgesByList
1065 //=============================================================================
1066 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeGlueEdgesByList
1067 (Handle(GEOM_Object) theShape,
1068 const Standard_Real theTolerance,
1069 std::list<Handle(GEOM_Object)> theEdges)
1073 if (theShape.IsNull()) return NULL;
1075 //Add a new Glued object
1076 Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
1078 //Add a new Glue function
1079 Handle(GEOM_Function) aFunction;
1080 aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_EDGES_BY_LIST);
1081 if (aFunction.IsNull()) return NULL;
1083 //Check if the function is set correctly
1084 if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
1086 GEOMImpl_IGlue aCI (aFunction);
1088 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
1089 if (aRefShape.IsNull()) return NULL;
1091 aCI.SetBase(aRefShape);
1092 aCI.SetTolerance(theTolerance);
1093 aCI.SetKeepNonSolids(true);
1095 Handle(TColStd_HSequenceOfTransient) anEdges = new TColStd_HSequenceOfTransient;
1096 std::list<Handle(GEOM_Object)>::iterator it = theEdges.begin();
1097 for (; it != theEdges.end(); it++) {
1098 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
1099 if (aRefSh.IsNull()) {
1100 SetErrorCode("NULL argument shape for the shape construction");
1103 anEdges->Append(aRefSh);
1105 aCI.SetFaces(anEdges);
1107 //Compute the sub-shape value
1108 Standard_Boolean isWarning = Standard_False;
1110 #if OCC_VERSION_LARGE > 0x06010000
1113 if (!GetSolver()->ComputeFunction(aFunction)) {
1114 SetErrorCode("Shape driver failed to glue edges");
1118 catch (Standard_Failure) {
1119 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1120 SetErrorCode(aFail->GetMessageString());
1121 // to provide warning
1122 if (!aFunction->GetValue().IsNull()) {
1123 isWarning = Standard_True;
1129 //Make a Python command
1131 GEOM::TPythonDump pd (aFunction);
1132 pd << aGlued << " = geompy.MakeGlueEdgesByList("
1133 << theShape << ", " << theTolerance << ", [";
1135 it = theEdges.begin();
1136 if (it != theEdges.end()) {
1138 while (it != theEdges.end()) {
1139 pd << ", " << (*it++);
1144 // to provide warning
1145 if (!isWarning) SetErrorCode(OK);
1149 //=============================================================================
1151 * GetExistingSubObjects
1153 //=============================================================================
1154 Handle(TColStd_HSequenceOfTransient)
1155 GEOMImpl_IShapesOperations::GetExistingSubObjects(Handle(GEOM_Object) theShape,
1156 const Standard_Boolean theGroupsOnly)
1158 // note: this method does not return fields
1160 Standard_Integer types = theGroupsOnly ? Groups : Groups|SubShapes;
1161 Handle(TColStd_HSequenceOfTransient) results = GetExistingSubObjects(theShape, types);
1163 if (results->Length() > 0) {
1164 //Make a Python command
1165 TCollection_AsciiString anAsciiList;
1166 for (int i = 1; i <= results->Length(); i++)
1168 Handle(GEOM_BaseObject) obj = Handle(GEOM_BaseObject)::DownCast( results->Value(i));
1169 obj->GetEntryString();
1170 if ( i < results->Length() )
1174 GEOM::TPythonDump pd (theShape->GetLastFunction(), /*append=*/true);
1175 pd << "[" << anAsciiList.ToCString();
1176 pd << "] = geompy.GetExistingSubObjects(";
1177 pd << theShape << ", " << (bool)theGroupsOnly << ")";
1183 Handle(TColStd_HSequenceOfTransient)
1184 GEOMImpl_IShapesOperations::GetExistingSubObjects(Handle(GEOM_Object) theShape,
1185 const Standard_Integer theTypes)
1189 if (theShape.IsNull()) return NULL;
1191 Handle(GEOM_Function) aMainShape = theShape->GetLastFunction();
1192 if (aMainShape.IsNull()) return NULL;
1194 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1195 SetErrorCode(NOT_FOUND_ANY);
1197 if (!aMainShape->HasSubShapeReferences()) return aSeq;
1198 const TDataStd_ListOfExtendedString& aListEntries = aMainShape->GetSubShapeReferences();
1199 if (aListEntries.IsEmpty()) return aSeq;
1203 TDataStd_ListIteratorOfListOfExtendedString anIt (aListEntries);
1204 for (; anIt.More(); anIt.Next()) {
1205 TCollection_ExtendedString anEntry = anIt.Value();
1206 Standard_Integer aStrLen = anEntry.LengthOfCString();
1207 char* anEntryStr = new char[aStrLen+1];
1208 anEntry.ToUTF8CString(anEntryStr);
1209 Handle(GEOM_BaseObject) anObj = GetEngine()->GetObject(GetDocID(), anEntryStr, false);
1210 if (!anObj.IsNull() ) {
1211 bool isGroup = anObj->IsKind(STANDARD_TYPE(GEOM_Object)) && anObj->GetType() == GEOM_GROUP;
1212 bool isSubShape = anObj->IsKind(STANDARD_TYPE(GEOM_Object)) && anObj->GetType() != GEOM_GROUP;
1213 bool isField = anObj->IsKind(STANDARD_TYPE(GEOM_Field));
1214 if (theTypes & Groups && isGroup ||
1215 theTypes & SubShapes && isSubShape ||
1216 theTypes & Fields && isField) {
1217 aSeq->Append(anObj);
1220 delete [] anEntryStr;
1223 if (aSeq->Length() == 0) {
1224 SetErrorCode(NOT_FOUND_ANY);
1233 //=============================================================================
1237 //=============================================================================
1238 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::MakeExplode
1239 (Handle(GEOM_Object) theShape,
1240 const Standard_Integer theShapeType,
1241 const Standard_Boolean isSorted,
1242 const ExplodeType theExplodeType)
1246 if (theShape.IsNull()) return NULL;
1247 TopoDS_Shape aShape = theShape->GetValue();
1248 if (aShape.IsNull()) return NULL;
1250 Handle(GEOM_Function) aMainShape = theShape->GetLastFunction();
1252 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1253 Handle(GEOM_Object) anObj;
1254 TopTools_MapOfShape mapShape;
1255 TopTools_ListOfShape listShape;
1257 if (aShape.ShapeType() == TopAbs_COMPOUND &&
1258 (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
1259 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPSOLID ||
1260 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPOUND))
1262 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
1263 for (; It.More(); It.Next()) {
1264 if (mapShape.Add(It.Value())) {
1265 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
1266 TopAbs_ShapeEnum(theShapeType) == It.Value().ShapeType()) {
1267 listShape.Append(It.Value());
1272 else if (theExplodeType != EXPLODE_NEW_EXCLUDE_MAIN || aShape.ShapeType() != theShapeType) // issue 0021079
1274 TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
1275 for (; exp.More(); exp.Next())
1276 if (mapShape.Add(exp.Current()))
1277 listShape.Append(exp.Current());
1280 if (listShape.IsEmpty()) {
1281 //SetErrorCode("The given shape has no sub-shapes of the requested type");
1282 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
1287 bool isOldSorting = false;
1288 if (theExplodeType == EXPLODE_OLD_INCLUDE_MAIN)
1289 isOldSorting = true;
1290 GEOMUtils::SortShapes(listShape, isOldSorting);
1293 TopTools_IndexedMapOfShape anIndices;
1294 TopExp::MapShapes(aShape, anIndices);
1295 Handle(TColStd_HArray1OfInteger) anArray;
1297 TopTools_ListIteratorOfListOfShape itSub (listShape);
1298 TCollection_AsciiString anAsciiList, anEntry;
1299 for (int index = 1; itSub.More(); itSub.Next(), ++index)
1301 TopoDS_Shape aValue = itSub.Value();
1302 anArray = new TColStd_HArray1OfInteger(1,1);
1303 anArray->SetValue(1, anIndices.FindIndex(aValue));
1305 //anObj = GetEngine()->AddSubShape(theShape, anArray);
1307 anObj = GetEngine()->AddObject(GetDocID(), GEOM_SUBSHAPE);
1308 Handle(GEOM_Function) aFunction = anObj->AddFunction(GEOM_Object::GetSubShapeID(), 1);
1309 if (aFunction.IsNull()) return aSeq;
1311 GEOM_ISubShape aSSI (aFunction);
1312 aSSI.SetMainShape(aMainShape);
1313 aSSI.SetIndices(anArray);
1315 // Set function value directly, as we know it.
1316 // Usage of Solver here would lead to significant loss of time,
1317 // because GEOM_SubShapeDriver will build TopTools_IndexedMapOfShape
1318 // on the main shape for each being calculated sub-shape separately.
1319 aFunction->SetValue(aValue);
1321 // Put this subshape in the list of sub-shapes of theMainShape
1322 aMainShape->AddSubShapeReference(aFunction);
1325 if (!anObj.IsNull()) {
1326 aSeq->Append(anObj);
1328 // for python command
1329 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
1330 anAsciiList += anEntry;
1335 //Make a Python command
1336 anAsciiList.Trunc(anAsciiList.Length() - 1);
1338 GEOM::TPythonDump pd (aMainShape, /*append=*/true);
1339 pd << "[" << anAsciiList.ToCString() << "] = geompy.";
1340 switch (theExplodeType) {
1341 case EXPLODE_NEW_EXCLUDE_MAIN:
1342 pd << "ExtractShapes(" << theShape << ", "
1343 << TopAbs_ShapeEnum(theShapeType) << ", " << (isSorted ? "True" : "False") << ")";
1345 case EXPLODE_NEW_INCLUDE_MAIN:
1346 pd << "SubShapeAll" << (isSorted ? "SortedCentres(" : "(")
1347 << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
1349 case EXPLODE_OLD_INCLUDE_MAIN:
1350 pd << "SubShapeAll" << (isSorted ? "Sorted(" : "(")
1351 << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
1360 //=============================================================================
1364 //=============================================================================
1365 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::SubShapeAllIDs
1366 (Handle(GEOM_Object) theShape,
1367 const Standard_Integer theShapeType,
1368 const Standard_Boolean isSorted,
1369 const ExplodeType theExplodeType)
1373 if (theShape.IsNull()) return NULL;
1374 TopoDS_Shape aShape = theShape->GetValue();
1375 if (aShape.IsNull()) return NULL;
1377 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
1378 TopTools_MapOfShape mapShape;
1379 TopTools_ListOfShape listShape;
1381 if (aShape.ShapeType() == TopAbs_COMPOUND &&
1382 (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
1383 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPSOLID ||
1384 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPOUND))
1386 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
1387 for (; It.More(); It.Next()) {
1388 if (mapShape.Add(It.Value())) {
1389 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
1390 TopAbs_ShapeEnum(theShapeType) == It.Value().ShapeType()) {
1391 listShape.Append(It.Value());
1396 else if (theExplodeType != EXPLODE_NEW_EXCLUDE_MAIN || aShape.ShapeType() != theShapeType) // issue 0021079
1398 TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
1399 for (; exp.More(); exp.Next())
1400 if (mapShape.Add(exp.Current()))
1401 listShape.Append(exp.Current());
1404 if (listShape.IsEmpty()) {
1405 //SetErrorCode("The given shape has no sub-shapes of the requested type");
1406 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
1411 bool isOldSorting = false;
1412 if (theExplodeType == EXPLODE_OLD_INCLUDE_MAIN)
1413 isOldSorting = true;
1414 GEOMUtils::SortShapes(listShape, isOldSorting);
1417 TopTools_IndexedMapOfShape anIndices;
1418 TopExp::MapShapes(aShape, anIndices);
1419 Handle(TColStd_HArray1OfInteger) anArray;
1421 TopTools_ListIteratorOfListOfShape itSub (listShape);
1422 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
1423 TopoDS_Shape aValue = itSub.Value();
1424 aSeq->Append(anIndices.FindIndex(aValue));
1427 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
1429 //Make a Python command
1430 GEOM::TPythonDump pd (aFunction, /*append=*/true);
1431 pd << "listSubShapeIDs = geompy.SubShapeAll";
1432 switch (theExplodeType) {
1433 case EXPLODE_NEW_EXCLUDE_MAIN:
1435 case EXPLODE_NEW_INCLUDE_MAIN:
1436 pd << (isSorted ? "SortedCentresIDs(" : "IDs(")
1437 << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
1439 case EXPLODE_OLD_INCLUDE_MAIN:
1440 pd << (isSorted ? "SortedIDs(" : "IDs(")
1441 << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
1450 //=============================================================================
1454 //=============================================================================
1455 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetSubShape
1456 (Handle(GEOM_Object) theMainShape,
1457 const Standard_Integer theID)
1461 if (theMainShape.IsNull()) return NULL;
1463 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
1464 anArray->SetValue(1, theID);
1465 Handle(GEOM_Object) anObj = GetEngine()->AddSubShape(theMainShape, anArray,true);
1466 if (anObj.IsNull()) {
1467 SetErrorCode("Can not get a sub-shape with the given ID");
1471 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1473 //Make a Python command
1474 GEOM::TPythonDump(aFunction) << anObj << " = geompy.GetSubShape("
1475 << theMainShape << ", [" << theID << "])";
1481 //=============================================================================
1485 //=============================================================================
1486 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::MakeSubShapes
1487 (Handle(GEOM_Object) theMainShape,
1488 Handle(TColStd_HArray1OfInteger) theIndices)
1492 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1494 if (!theIndices->Length()) {
1495 SetErrorCode(NOT_FOUND_ANY);
1499 if (theMainShape.IsNull()) return NULL;
1500 TopoDS_Shape aShape = theMainShape->GetValue();
1501 if (aShape.IsNull()) return NULL;
1503 Handle(GEOM_Function) aMainShape = theMainShape->GetLastFunction();
1505 TopTools_IndexedMapOfShape anIndices;
1506 TopExp::MapShapes(aShape, anIndices);
1508 Handle(TColStd_HArray1OfInteger) anArray;
1509 Handle(GEOM_Object) anObj;
1511 TCollection_AsciiString anAsciiList, anEntry;
1512 Standard_Integer i, low = theIndices->Lower(), up = theIndices->Upper();
1513 for (i = low; i <= up; i++) {
1514 int id = theIndices->Value(i);
1515 if (1 <= id && id <= anIndices.Extent()) {
1516 TopoDS_Shape aValue = anIndices.FindKey(id);
1517 anArray = new TColStd_HArray1OfInteger(1,1);
1518 anArray->SetValue(1, id);
1520 anObj = GetEngine()->AddObject(GetDocID(), GEOM_SUBSHAPE);
1521 if (!anObj.IsNull()) {
1522 Handle(GEOM_Function) aFunction = anObj->AddFunction(GEOM_Object::GetSubShapeID(), 1);
1523 if (aFunction.IsNull()) return aSeq;
1525 GEOM_ISubShape aSSI (aFunction);
1526 aSSI.SetMainShape(aMainShape);
1527 aSSI.SetIndices(anArray);
1529 // Set function value directly, as we know it.
1530 // Usage of Solver here would lead to significant loss of time,
1531 // because GEOM_SubShapeDriver will build TopTools_IndexedMapOfShape
1532 // on the main shape for each being calculated sub-shape separately.
1533 aFunction->SetValue(aValue);
1535 // Put this sub-shape in the list of sub-shapes of theMainShape
1536 aMainShape->AddSubShapeReference(aFunction);
1538 aSeq->Append(anObj);
1540 // for python command
1541 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
1542 anAsciiList += anEntry;
1548 //Make a Python command
1549 anAsciiList.Trunc(anAsciiList.Length() - 1);
1551 GEOM::TPythonDump pd (aMainShape, /*append=*/true);
1552 pd << "[" << anAsciiList.ToCString() << "] = geompy.SubShapes("
1553 << theMainShape << ", [" ;
1554 for (i = low; i <= up - 1; i++) {
1555 pd << theIndices->Value(i) << ", ";
1557 pd << theIndices->Value(up) << "])";
1564 //=============================================================================
1568 //=============================================================================
1569 Standard_Integer GEOMImpl_IShapesOperations::GetSubShapeIndex (Handle(GEOM_Object) theMainShape,
1570 Handle(GEOM_Object) theSubShape)
1574 TopoDS_Shape aMainShape = theMainShape->GetValue();
1575 TopoDS_Shape aSubShape = theSubShape->GetValue();
1577 if (aMainShape.IsNull() || aSubShape.IsNull()) return -1;
1579 TopTools_IndexedMapOfShape anIndices;
1580 TopExp::MapShapes(aMainShape, anIndices);
1581 // if (anIndices.Contains(aSubShape)) {
1582 // SetErrorCode(OK);
1583 // return anIndices.FindIndex(aSubShape);
1585 int id = anIndices.FindIndex(aSubShape);
1596 //=============================================================================
1598 * GetSubShapeIndices
1600 //=============================================================================
1601 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetSubShapesIndices (Handle(GEOM_Object) theMainShape,
1602 std::list<Handle(GEOM_Object)> theSubShapes)
1604 MESSAGE("GEOMImpl_IShapesOperations::GetSubShapesIndices")
1607 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
1609 TopoDS_Shape aMainShape = theMainShape->GetValue();
1610 if (aMainShape.IsNull())
1612 MESSAGE("NULL main shape")
1616 TopTools_IndexedMapOfShape anIndices;
1617 TopExp::MapShapes(aMainShape, anIndices);
1619 std::list<Handle(GEOM_Object)>::iterator it;
1620 for (it=theSubShapes.begin(); it != theSubShapes.end(); ++it)
1622 TopoDS_Shape aSubShape = (*it)->GetValue();
1623 if (aSubShape.IsNull())
1625 MESSAGE("NULL subshape")
1628 int id = anIndices.FindIndex(aSubShape);
1637 //=============================================================================
1641 //=============================================================================
1642 Standard_Integer GEOMImpl_IShapesOperations::GetTopologyIndex (Handle(GEOM_Object) theMainShape,
1643 Handle(GEOM_Object) theSubShape)
1647 TopoDS_Shape aMainShape = theMainShape->GetValue();
1648 TopoDS_Shape aSubShape = theSubShape->GetValue();
1650 if (aMainShape.IsNull() || aSubShape.IsNull()) {
1651 SetErrorCode("Null argument shape given");
1656 if (aSubShape.ShapeType() == TopAbs_COMPOUND) {
1658 TopTools_ListOfShape CL;
1659 CL.Append(aMainShape);
1660 TopTools_ListIteratorOfListOfShape itC;
1661 for (itC.Initialize(CL); itC.More(); itC.Next()) {
1662 for (it.Initialize(itC.Value()); it.More(); it.Next()) {
1663 if (it.Value().ShapeType() == TopAbs_COMPOUND) {
1664 if (it.Value().IsSame(aSubShape))
1668 CL.Append(it.Value());
1673 TopExp_Explorer anExp (aMainShape, aSubShape.ShapeType());
1674 TopTools_MapOfShape M;
1675 for (; anExp.More(); anExp.Next()) {
1676 if (M.Add(anExp.Current())) {
1677 if (anExp.Current().IsSame(aSubShape))
1684 SetErrorCode("The sub-shape does not belong to the main shape");
1688 //=============================================================================
1690 * GetShapeTypeString
1692 //=============================================================================
1693 TCollection_AsciiString GEOMImpl_IShapesOperations::GetShapeTypeString (Handle(GEOM_Object) theShape)
1697 TCollection_AsciiString aTypeName ("Null Shape");
1699 TopoDS_Shape aShape = theShape->GetValue();
1700 if (aShape.IsNull())
1703 switch (aShape.ShapeType() )
1705 case TopAbs_COMPOUND:
1706 aTypeName = "Compound";
1708 case TopAbs_COMPSOLID:
1709 aTypeName = "Compound Solid";
1712 aTypeName = "Solid";
1715 aTypeName = "Shell";
1719 BRepAdaptor_Surface surf (TopoDS::Face(aShape));
1720 if (surf.GetType() == GeomAbs_Plane)
1721 aTypeName = "Plane";
1722 else if (surf.GetType() == GeomAbs_Cylinder)
1723 aTypeName = "Cylindrical Face";
1724 else if (surf.GetType() == GeomAbs_Sphere)
1725 aTypeName = "Spherical Face";
1726 else if (surf.GetType() == GeomAbs_Torus)
1727 aTypeName = "Toroidal Face";
1728 else if (surf.GetType() == GeomAbs_Cone)
1729 aTypeName = "Conical Face";
1731 aTypeName = "GEOM::FACE";
1739 BRepAdaptor_Curve curv (TopoDS::Edge(aShape));
1740 if (curv.GetType() == GeomAbs_Line) {
1741 if ((Abs(curv.FirstParameter()) >= 1E6) ||
1742 (Abs(curv.LastParameter()) >= 1E6))
1746 } else if (curv.GetType() == GeomAbs_Circle) {
1747 if (curv.IsClosed())
1748 aTypeName = "Circle";
1757 aTypeName = "Vertex";
1760 aTypeName = "Shape";
1763 aTypeName = "Shape of unknown type";
1769 //=============================================================================
1773 //=============================================================================
1774 Standard_Integer GEOMImpl_IShapesOperations::NumberOfSubShapes
1775 (Handle(GEOM_Object) theShape,
1776 const Standard_Integer theShapeType)
1779 Standard_Integer nbShapes = 0;
1781 if (theShape.IsNull()) return -1;
1782 TopoDS_Shape aShape = theShape->GetValue();
1783 if (aShape.IsNull()) return -1;
1786 TopTools_MapOfShape mapShape;
1788 if (aShape.ShapeType() == TopAbs_COMPOUND &&
1789 (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
1790 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPSOLID ||
1791 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPOUND)) {
1792 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
1793 for (; It.More(); It.Next()) {
1794 if (mapShape.Add(It.Value())) {
1795 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
1796 TopAbs_ShapeEnum(theShapeType) == It.Value().ShapeType()) {
1802 TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
1803 for (; exp.More(); exp.Next())
1804 if (mapShape.Add(exp.Current()))
1810 #if OCC_VERSION_LARGE > 0x06010000
1813 int iType, nbTypes [TopAbs_SHAPE];
1814 for (iType = 0; iType < TopAbs_SHAPE; ++iType)
1816 nbTypes[aShape.ShapeType()]++;
1818 TopTools_MapOfShape aMapOfShape;
1819 aMapOfShape.Add(aShape);
1820 TopTools_ListOfShape aListOfShape;
1821 aListOfShape.Append(aShape);
1823 TopTools_ListIteratorOfListOfShape itL (aListOfShape);
1824 for (; itL.More(); itL.Next()) {
1825 TopoDS_Iterator it (itL.Value());
1826 for (; it.More(); it.Next()) {
1827 TopoDS_Shape s = it.Value();
1828 if (aMapOfShape.Add(s)) {
1829 aListOfShape.Append(s);
1830 nbTypes[s.ShapeType()]++;
1835 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE)
1836 nbShapes = aMapOfShape.Extent();
1838 nbShapes = nbTypes[theShapeType];
1840 catch (Standard_Failure) {
1841 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1842 SetErrorCode(aFail->GetMessageString());
1850 //=============================================================================
1854 //=============================================================================
1855 Handle(GEOM_Object) GEOMImpl_IShapesOperations::ReverseShape(Handle(GEOM_Object) theShape)
1859 if (theShape.IsNull()) return NULL;
1862 //Add a new reversed object
1863 Handle(GEOM_Object) aReversed = GetEngine()->AddObject(GetDocID(), theShape->GetType());
1865 //Add a new Revese function
1866 Handle(GEOM_Function) aFunction;
1867 aFunction = aReversed->AddFunction(GEOMImpl_ShapeDriver::GetID(), REVERSE_ORIENTATION);
1868 if (aFunction.IsNull()) return NULL;
1870 //Check if the function is set correctly
1871 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
1873 GEOMImpl_IShapes aSI (aFunction);
1875 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
1876 if (aRefShape.IsNull()) return NULL;
1878 aSI.SetBase(aRefShape);
1880 //Compute the sub-shape value
1882 #if OCC_VERSION_LARGE > 0x06010000
1885 if (!GetSolver()->ComputeFunction(aFunction)) {
1886 SetErrorCode("Shape driver failed to reverse shape");
1890 catch (Standard_Failure) {
1891 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1892 SetErrorCode(aFail->GetMessageString());
1896 //Make a Python command
1897 GEOM::TPythonDump(aFunction) << aReversed
1898 << " = geompy.ChangeOrientation(" << theShape << ")";
1903 Handle(GEOM_Object) aReversed;
1905 GEOM_Engine* anEngine = GetEngine();
1906 //GEOMImpl_Gen* aGen = dynamic_cast<GEOMImpl_Gen*>(anEngine);
1907 GEOMImpl_Gen* aGen = (GEOMImpl_Gen*)anEngine;
1910 GEOMImpl_IHealingOperations* anIHealingOperations =
1911 aGen->GetIHealingOperations(GetDocID());
1912 aReversed = anIHealingOperations->ChangeOrientationCopy(theShape);
1913 SetErrorCode(anIHealingOperations->GetErrorCode());
1919 //=============================================================================
1923 //=============================================================================
1924 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetFreeFacesIDs
1925 (Handle(GEOM_Object) theShape)
1929 if (theShape.IsNull()) return NULL;
1930 TopoDS_Shape aShape = theShape->GetValue();
1931 if (aShape.IsNull()) return NULL;
1933 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
1935 TopTools_IndexedDataMapOfShapeListOfShape mapFaceBlocks;
1936 GEOMImpl_Block6Explorer::MapShapesAndAncestors
1937 (aShape, TopAbs_FACE, TopAbs_SOLID, mapFaceBlocks);
1939 Standard_Integer ind = 1, nbFaces = mapFaceBlocks.Extent();
1942 SetErrorCode("The given shape has no faces");
1946 TopTools_IndexedMapOfShape anIndices;
1947 TopExp::MapShapes(aShape, anIndices);
1949 Standard_Integer id;
1950 for (; ind <= nbFaces; ind++) {
1951 if (mapFaceBlocks.FindFromIndex(ind).Extent() != 2) {
1952 id = anIndices.FindIndex(mapFaceBlocks.FindKey(ind));
1957 //The explode doesn't change object so no new function is required.
1958 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
1960 //Make a Python command
1961 GEOM::TPythonDump(aFunction, /*append=*/true)
1962 << "listFreeFacesIDs = geompy.GetFreeFacesIDs(" << theShape << ")";
1968 //=======================================================================
1969 //function : GetSharedShapes
1971 //=======================================================================
1972 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetSharedShapes
1973 (Handle(GEOM_Object) theShape1,
1974 Handle(GEOM_Object) theShape2,
1975 const Standard_Integer theShapeType)
1979 if (theShape1.IsNull() || theShape2.IsNull()) return NULL;
1981 TopoDS_Shape aShape1 = theShape1->GetValue();
1982 TopoDS_Shape aShape2 = theShape2->GetValue();
1984 if (aShape1.IsNull() || aShape2.IsNull()) return NULL;
1986 TopTools_IndexedMapOfShape anIndices;
1987 TopExp::MapShapes(aShape1, anIndices);
1988 Handle(TColStd_HArray1OfInteger) anArray;
1990 TopTools_IndexedMapOfShape mapShape1;
1991 TopExp::MapShapes(aShape1, TopAbs_ShapeEnum(theShapeType), mapShape1);
1993 Handle(GEOM_Object) anObj;
1994 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1995 TCollection_AsciiString anAsciiList, anEntry;
1997 TopTools_MapOfShape mapShape2;
1998 TopExp_Explorer exp (aShape2, TopAbs_ShapeEnum(theShapeType));
1999 for (; exp.More(); exp.Next()) {
2000 TopoDS_Shape aSS = exp.Current();
2001 if (mapShape2.Add(aSS) && mapShape1.Contains(aSS)) {
2002 anArray = new TColStd_HArray1OfInteger(1,1);
2003 anArray->SetValue(1, anIndices.FindIndex(aSS));
2004 anObj = GetEngine()->AddSubShape(theShape1, anArray);
2005 aSeq->Append(anObj);
2007 // for python command
2008 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
2009 anAsciiList += anEntry;
2014 if (aSeq->IsEmpty()) {
2015 SetErrorCode("The given shapes have no shared sub-shapes of the requested type");
2019 //Make a Python command
2020 anAsciiList.Trunc(anAsciiList.Length() - 1);
2022 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2024 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
2025 << "] = geompy.GetSharedShapes(" << theShape1 << ", "
2026 << theShape2 << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
2032 //=======================================================================
2033 //function : GetSharedShapes
2035 //=======================================================================
2036 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetSharedShapes
2037 (std::list<Handle(GEOM_Object)> theShapes,
2038 const Standard_Integer theShapeType)
2042 int aLen = theShapes.size();
2043 if (aLen < 1) return NULL;
2046 std::list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
2048 Handle(GEOM_Object) aMainObj = (*it++);
2049 Handle(GEOM_Function) aMainShape = aMainObj->GetLastFunction();
2050 if (aMainShape.IsNull()) {
2051 SetErrorCode("NULL shape for GetSharedShapes");
2055 TopoDS_Shape aShape1 = aMainShape->GetValue();
2056 if (aShape1.IsNull()) return NULL;
2058 TopTools_IndexedMapOfShape anIndices;
2059 TopExp::MapShapes(aShape1, anIndices);
2061 TopTools_IndexedMapOfShape mapSelected;
2062 TopExp::MapShapes(aShape1, TopAbs_ShapeEnum(theShapeType), mapSelected);
2064 // Find shared shapes
2066 TopoDS_Compound aCurrSelection;
2068 for (; it != theShapes.end(); it++, ind++) {
2069 Handle(GEOM_Function) aRefShape = (*it)->GetLastFunction();
2070 if (aRefShape.IsNull()) {
2071 SetErrorCode("NULL shape for GetSharedShapes");
2075 TopoDS_Compound aCompound;
2076 B.MakeCompound(aCompound);
2078 TopoDS_Shape aShape2 = aRefShape->GetValue();
2079 if (aShape2.IsNull()) return NULL;
2081 TopTools_MapOfShape mapShape2;
2082 TopExp_Explorer exp (aShape2, TopAbs_ShapeEnum(theShapeType));
2083 for (; exp.More(); exp.Next()) {
2084 TopoDS_Shape aSS = exp.Current();
2085 if (mapShape2.Add(aSS) && mapSelected.Contains(aSS)) {
2086 B.Add(aCompound, aSS);
2090 mapSelected.Clear();
2091 TopExp::MapShapes(aCompound, TopAbs_ShapeEnum(theShapeType), mapSelected);
2092 aCurrSelection = aCompound;
2095 // Create GEOM_Object for each found shared shape (collected in aCurrSelection)
2096 Handle(GEOM_Object) anObj;
2097 Handle(TColStd_HArray1OfInteger) anArray;
2098 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
2099 TCollection_AsciiString anAsciiList, anEntry;
2101 TopoDS_Iterator itSel (aCurrSelection, Standard_True, Standard_True);
2102 for (; itSel.More(); itSel.Next()) {
2103 anArray = new TColStd_HArray1OfInteger(1,1);
2104 anArray->SetValue(1, anIndices.FindIndex(itSel.Value()));
2105 anObj = GetEngine()->AddSubShape(aMainObj, anArray);
2106 aSeq->Append(anObj);
2108 // for python command
2109 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
2110 anAsciiList += anEntry;
2114 if (aSeq->IsEmpty()) {
2115 SetErrorCode("The given shapes have no shared sub-shapes of the requested type");
2119 // Make a Python command
2120 anAsciiList.Trunc(anAsciiList.Length() - 1);
2122 // IPAL22904: TC6.5.0: order of python commands is wrong after dump study
2123 Handle(TColStd_HSequenceOfTransient) anObjects = new TColStd_HSequenceOfTransient;
2124 for( it = theShapes.begin(); it != theShapes.end(); it++ )
2126 Handle(GEOM_Object) anObj = *it;
2127 if( !anObj.IsNull() )
2128 anObjects->Append( anObj );
2131 // Get the function of the latest published object
2132 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast( anObjects )->GetLastFunction();
2133 if( aFunction.IsNull() ) // just in case
2134 aFunction = aMainShape;
2136 GEOM::TPythonDump pd (aFunction, /*append=*/true);
2137 pd << "[" << anAsciiList.ToCString()
2138 << "] = geompy.GetSharedShapesMulti([";
2140 it = theShapes.begin();
2142 while (it != theShapes.end()) {
2143 pd << ", " << (*it++);
2146 pd << "], " << TopAbs_ShapeEnum(theShapeType) << ")";
2152 //=============================================================================
2156 //=============================================================================
2157 static GEOM::TPythonDump& operator<< (GEOM::TPythonDump& theDump,
2158 const GEOMAlgo_State theState)
2161 case GEOMAlgo_ST_IN:
2162 theDump << "GEOM.ST_IN";
2164 case GEOMAlgo_ST_OUT:
2165 theDump << "GEOM.ST_OUT";
2167 case GEOMAlgo_ST_ON:
2168 theDump << "GEOM.ST_ON";
2170 case GEOMAlgo_ST_ONIN:
2171 theDump << "GEOM.ST_ONIN";
2173 case GEOMAlgo_ST_ONOUT:
2174 theDump << "GEOM.ST_ONOUT";
2177 theDump << "GEOM.ST_UNKNOWN";
2183 //=======================================================================
2184 //function : checkTypeShapesOn
2186 * \brief Checks if theShapeType parameter of GetShapesOnXXX() is OK
2187 * \param theShapeType - the shape type to check
2188 * \retval bool - result of the check
2190 //=======================================================================
2191 bool GEOMImpl_IShapesOperations::checkTypeShapesOn(const Standard_Integer theShapeType)
2193 if (theShapeType != TopAbs_VERTEX &&
2194 theShapeType != TopAbs_EDGE &&
2195 theShapeType != TopAbs_FACE &&
2196 theShapeType != TopAbs_SOLID) {
2197 SetErrorCode("Only solids, vertices, edges or faces can be found by this method");
2203 //=======================================================================
2204 //function : makePlane
2206 * \brief Creates Geom_Plane
2207 * \param theAx1 - shape object defining plane parameters
2208 * \retval Handle(Geom_Surface) - resulting surface
2210 //=======================================================================
2211 Handle(Geom_Surface) GEOMImpl_IShapesOperations::makePlane(const TopoDS_Shape& anAx1)
2213 if (anAx1.ShapeType() != TopAbs_EDGE) return NULL;
2214 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
2215 TopoDS_Vertex V1, V2;
2216 TopExp::Vertices(anEdge, V1, V2, Standard_True);
2217 if (V1.IsNull() || V2.IsNull()) {
2218 SetErrorCode("Bad edge given for the plane normal vector");
2221 gp_Pnt aLoc = BRep_Tool::Pnt(V1);
2222 gp_Vec aVec (aLoc, BRep_Tool::Pnt(V2));
2223 if (aVec.Magnitude() < Precision::Confusion()) {
2224 SetErrorCode("Vector with null magnitude given");
2227 return new Geom_Plane(aLoc, aVec);
2230 //=======================================================================
2231 //function : makeCylinder
2233 * \brief Creates Geom_CylindricalSurface
2234 * \param theAx1 - edge defining cylinder axis
2235 * \param theRadius - cylinder radius
2236 * \retval Handle(Geom_Surface) - resulting surface
2238 //=======================================================================
2239 Handle(Geom_Surface) GEOMImpl_IShapesOperations::makeCylinder(const TopoDS_Shape& anAxis,
2240 const Standard_Real theRadius)
2242 //Axis of the cylinder
2243 if (anAxis.ShapeType() != TopAbs_EDGE) {
2244 SetErrorCode("Not an edge given for the axis");
2247 TopoDS_Edge anEdge = TopoDS::Edge(anAxis);
2248 TopoDS_Vertex V1, V2;
2249 TopExp::Vertices(anEdge, V1, V2, Standard_True);
2250 if (V1.IsNull() || V2.IsNull()) {
2251 SetErrorCode("Bad edge given for the axis");
2254 gp_Pnt aLoc = BRep_Tool::Pnt(V1);
2255 gp_Vec aVec (aLoc, BRep_Tool::Pnt(V2));
2256 if (aVec.Magnitude() < Precision::Confusion()) {
2257 SetErrorCode("Vector with null magnitude given");
2261 gp_Ax3 anAx3 (aLoc, aVec);
2262 return new Geom_CylindricalSurface(anAx3, theRadius);
2265 //=======================================================================
2266 //function : getShapesOnBoxIDs
2268 * \brief Find IDs of sub-shapes complying with given status about surface
2269 * \param theBox - the box to check state of sub-shapes against
2270 * \param theShape - the shape to explore
2271 * \param theShapeType - type of sub-shape of theShape
2272 * \param theState - required state
2273 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
2275 //=======================================================================
2276 Handle(TColStd_HSequenceOfInteger)
2277 GEOMImpl_IShapesOperations::getShapesOnBoxIDs(const Handle(GEOM_Object)& theBox,
2278 const Handle(GEOM_Object)& theShape,
2279 const Standard_Integer theShapeType,
2280 GEOMAlgo_State theState)
2282 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
2284 TopoDS_Shape aBox = theBox->GetValue();
2285 TopoDS_Shape aShape = theShape->GetValue();
2287 // Check presence of triangulation, build if need
2288 if (!GEOMUtils::CheckTriangulation(aShape)) {
2289 SetErrorCode("Cannot build triangulation on the shape");
2294 GEOMAlgo_FinderShapeOn2 aFinder;
2295 Standard_Real aTol = 0.0001; // default value
2297 Handle(GEOMAlgo_ClsfBox) aClsfBox = new GEOMAlgo_ClsfBox;
2298 aClsfBox->SetBox(aBox);
2300 aFinder.SetShape(aShape);
2301 aFinder.SetTolerance(aTol);
2302 aFinder.SetClsf(aClsfBox);
2303 aFinder.SetShapeType( (TopAbs_ShapeEnum)theShapeType );
2304 aFinder.SetState(theState);
2307 // Interprete results
2308 Standard_Integer iErr = aFinder.ErrorStatus();
2309 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
2311 MESSAGE(" iErr : " << iErr);
2312 TCollection_AsciiString aMsg (" iErr : ");
2313 aMsg += TCollection_AsciiString(iErr);
2317 Standard_Integer iWrn = aFinder.WarningStatus();
2318 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
2320 MESSAGE(" *** iWrn : " << iWrn);
2323 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
2325 if (listSS.Extent() < 1) {
2326 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
2327 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
2331 // Fill sequence of object IDs
2332 aSeqOfIDs = new TColStd_HSequenceOfInteger;
2334 TopTools_IndexedMapOfShape anIndices;
2335 TopExp::MapShapes(aShape, anIndices);
2337 TopTools_ListIteratorOfListOfShape itSub (listSS);
2338 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
2339 int id = anIndices.FindIndex(itSub.Value());
2340 aSeqOfIDs->Append(id);
2346 //=======================================================================
2347 //function : GetShapesOnBoxIDs
2349 * \brief Find sub-shapes complying with given status about surface
2350 * \param theBox - the box to check state of sub-shapes against
2351 * \param theShape - the shape to explore
2352 * \param theShapeType - type of sub-shape of theShape
2353 * \param theState - required state
2354 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
2356 //=======================================================================
2357 Handle(TColStd_HSequenceOfInteger)
2358 GEOMImpl_IShapesOperations::GetShapesOnBoxIDs(const Handle(GEOM_Object)& theBox,
2359 const Handle(GEOM_Object)& theShape,
2360 const Standard_Integer theShapeType,
2361 GEOMAlgo_State theState)
2363 // Find sub-shapes ids
2364 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2365 getShapesOnBoxIDs (theBox, theShape, theShapeType, theState);
2366 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2369 // The GetShapesOnBox() doesn't change object so no new function is required.
2370 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theBox)->GetLastFunction();
2372 // Make a Python command
2373 GEOM::TPythonDump(aFunction, /*append=*/true)
2374 << "listShapesOnBoxIDs = geompy.GetShapesOnBoxIDs("
2377 << TopAbs_ShapeEnum(theShapeType) << ", "
2384 //=======================================================================
2385 //function : GetShapesOnBox
2387 * \brief Find sub-shapes complying with given status about surface
2388 * \param theBox - the box to check state of sub-shapes against
2389 * \param theShape - the shape to explore
2390 * \param theShapeType - type of sub-shape of theShape
2391 * \param theState - required state
2392 * \retval Handle(TColStd_HSequenceOfTransient) - found sub-shapes
2394 //=======================================================================
2395 Handle(TColStd_HSequenceOfTransient)
2396 GEOMImpl_IShapesOperations::GetShapesOnBox(const Handle(GEOM_Object)& theBox,
2397 const Handle(GEOM_Object)& theShape,
2398 const Standard_Integer theShapeType,
2399 GEOMAlgo_State theState)
2401 // Find sub-shapes ids
2402 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2403 getShapesOnBoxIDs (theBox, theShape, theShapeType, theState);
2404 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2407 // Find objects by indices
2408 TCollection_AsciiString anAsciiList;
2409 Handle(TColStd_HSequenceOfTransient) aSeq;
2410 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
2411 if ( aSeq.IsNull() || aSeq->IsEmpty() )
2414 // Make a Python command
2416 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2417 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2419 GEOM::TPythonDump(aFunction)
2420 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnBox("
2423 << TopAbs_ShapeEnum(theShapeType) << ", "
2430 //=======================================================================
2431 //function : getShapesOnShapeIDs
2433 * \brief Find IDs of sub-shapes complying with given status about surface
2434 * \param theCheckShape - the shape to check state of sub-shapes against
2435 * \param theShape - the shape to explore
2436 * \param theShapeType - type of sub-shape of theShape
2437 * \param theState - required state
2438 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
2440 //=======================================================================
2441 Handle(TColStd_HSequenceOfInteger)
2442 GEOMImpl_IShapesOperations::getShapesOnShapeIDs
2443 (const Handle(GEOM_Object)& theCheckShape,
2444 const Handle(GEOM_Object)& theShape,
2445 const Standard_Integer theShapeType,
2446 GEOMAlgo_State theState)
2448 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
2450 TopoDS_Shape aCheckShape = theCheckShape->GetValue();
2451 TopoDS_Shape aShape = theShape->GetValue();
2452 TopTools_ListOfShape res;
2454 // Check presence of triangulation, build if need
2455 if (!GEOMUtils::CheckTriangulation(aShape)) {
2456 SetErrorCode("Cannot build triangulation on the shape");
2461 GEOMAlgo_FinderShapeOn2 aFinder;
2462 Standard_Real aTol = 0.0001; // default value
2464 Handle(GEOMAlgo_ClsfSolid) aClsfSolid = new GEOMAlgo_ClsfSolid;
2465 aClsfSolid->SetShape(aCheckShape);
2467 aFinder.SetShape(aShape);
2468 aFinder.SetTolerance(aTol);
2469 aFinder.SetClsf(aClsfSolid);
2470 aFinder.SetShapeType( (TopAbs_ShapeEnum)theShapeType );
2471 aFinder.SetState(theState);
2474 // Interprete results
2475 Standard_Integer iErr = aFinder.ErrorStatus();
2476 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
2479 SetErrorCode("theCheckShape must be a solid");
2482 MESSAGE(" iErr : " << iErr);
2483 TCollection_AsciiString aMsg (" iErr : ");
2484 aMsg += TCollection_AsciiString(iErr);
2489 Standard_Integer iWrn = aFinder.WarningStatus();
2490 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
2492 MESSAGE(" *** iWrn : " << iWrn);
2495 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
2497 if (listSS.Extent() < 1) {
2498 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
2499 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
2502 // Fill sequence of object IDs
2503 aSeqOfIDs = new TColStd_HSequenceOfInteger;
2505 TopTools_IndexedMapOfShape anIndices;
2506 TopExp::MapShapes(aShape, anIndices);
2508 TopTools_ListIteratorOfListOfShape itSub (listSS);
2509 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
2510 int id = anIndices.FindIndex(itSub.Value());
2511 aSeqOfIDs->Append(id);
2517 //=======================================================================
2518 //function : GetShapesOnShapeIDs
2520 * \brief Find sub-shapes complying with given status about surface
2521 * \param theCheckShape - the shape to check state of sub-shapes against
2522 * \param theShape - the shape to explore
2523 * \param theShapeType - type of sub-shape of theShape
2524 * \param theState - required state
2525 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
2527 //=======================================================================
2528 Handle(TColStd_HSequenceOfInteger)
2529 GEOMImpl_IShapesOperations::GetShapesOnShapeIDs
2530 (const Handle(GEOM_Object)& theCheckShape,
2531 const Handle(GEOM_Object)& theShape,
2532 const Standard_Integer theShapeType,
2533 GEOMAlgo_State theState)
2535 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2536 getShapesOnShapeIDs (theCheckShape, theShape, theShapeType, theState);
2538 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2541 // The GetShapesOnShape() doesn't change object so no new function is required.
2542 Handle(GEOM_Function) aFunction =
2543 GEOM::GetCreatedLast(theShape,theCheckShape)->GetLastFunction();
2545 // Make a Python command
2546 GEOM::TPythonDump(aFunction, /*append=*/true)
2547 << "listShapesOnBoxIDs = geompy.GetShapesOnShapeIDs("
2548 << theCheckShape << ", "
2550 << TopAbs_ShapeEnum(theShapeType) << ", "
2557 //=======================================================================
2558 //function : GetShapesOnShape
2560 * \brief Find sub-shapes complying with given status about surface
2561 * \param theCheckShape - the shape to check state of sub-shapes against
2562 * \param theShape - the shape to explore
2563 * \param theShapeType - type of sub-shape of theShape
2564 * \param theState - required state
2565 * \retval Handle(TColStd_HSequenceOfTransient) - found sub-shapes
2567 //=======================================================================
2568 Handle(TColStd_HSequenceOfTransient)
2569 GEOMImpl_IShapesOperations::GetShapesOnShape
2570 (const Handle(GEOM_Object)& theCheckShape,
2571 const Handle(GEOM_Object)& theShape,
2572 const Standard_Integer theShapeType,
2573 GEOMAlgo_State theState)
2575 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2576 getShapesOnShapeIDs (theCheckShape, theShape, theShapeType, theState);
2577 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2580 // Find objects by indices
2581 TCollection_AsciiString anAsciiList;
2582 Handle(TColStd_HSequenceOfTransient) aSeq;
2583 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
2585 if ( aSeq.IsNull() || aSeq->IsEmpty() )
2588 // Make a Python command
2590 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2591 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2593 GEOM::TPythonDump(aFunction)
2594 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnShape("
2595 << theCheckShape << ", "
2597 << TopAbs_ShapeEnum(theShapeType) << ", "
2604 //=======================================================================
2605 //function : GetShapesOnShapeAsCompound
2606 //=======================================================================
2607 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetShapesOnShapeAsCompound
2608 (const Handle(GEOM_Object)& theCheckShape,
2609 const Handle(GEOM_Object)& theShape,
2610 const Standard_Integer theShapeType,
2611 GEOMAlgo_State theState)
2613 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2614 getShapesOnShapeIDs (theCheckShape, theShape, theShapeType, theState);
2616 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2619 // Find objects by indices
2620 TCollection_AsciiString anAsciiList;
2621 Handle(TColStd_HSequenceOfTransient) aSeq;
2622 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
2624 if ( aSeq.IsNull() || aSeq->IsEmpty() )
2627 TopoDS_Compound aCompound;
2629 B.MakeCompound(aCompound);
2631 for(; i<=aSeq->Length(); i++) {
2632 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(aSeq->Value(i));
2633 TopoDS_Shape aShape_i = anObj->GetValue();
2634 B.Add(aCompound,aShape_i);
2637 //Add a new result object
2638 Handle(GEOM_Object) aRes = GetEngine()->AddObject(GetDocID(), GEOM_SHAPES_ON_SHAPE);
2639 Handle(GEOM_Function) aFunction =
2640 aRes->AddFunction(GEOMImpl_ShapeDriver::GetID(), SHAPES_ON_SHAPE);
2641 aFunction->SetValue(aCompound);
2644 aSeq->Append( theCheckShape->GetLastFunction() );
2645 aSeq->Append( theShape->GetLastFunction() );
2647 GEOMImpl_IShapes aCI( aFunction );
2648 aCI.SetShapes( aSeq );
2649 aCI.SetSubShapeType( theShapeType );
2650 aCI.SetTolerance( theState );
2652 GEOM::TPythonDump(aFunction)
2653 << aRes << " = geompy.GetShapesOnShapeAsCompound("
2654 << theCheckShape << ", "
2656 << TopAbs_ShapeEnum(theShapeType) << ", "
2664 //=======================================================================
2665 //function : getShapesOnSurfaceIDs
2667 * \brief Find IDs of sub-shapes complying with given status about surface
2668 * \param theSurface - the surface to check state of sub-shapes against
2669 * \param theShape - the shape to explore
2670 * \param theShapeType - type of sub-shape of theShape
2671 * \param theState - required state
2672 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
2674 //=======================================================================
2675 Handle(TColStd_HSequenceOfInteger)
2676 GEOMImpl_IShapesOperations::getShapesOnSurfaceIDs(const Handle(Geom_Surface)& theSurface,
2677 const TopoDS_Shape& theShape,
2678 TopAbs_ShapeEnum theShapeType,
2679 GEOMAlgo_State theState)
2681 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
2683 // Check presence of triangulation, build if need
2684 if (!GEOMUtils::CheckTriangulation(theShape)) {
2685 SetErrorCode("Cannot build triangulation on the shape");
2689 // BEGIN: Mantis issue 0020961: Error on a pipe T-Shape
2690 // Compute tolerance
2691 Standard_Real T, VertMax = -RealLast();
2693 #if OCC_VERSION_LARGE > 0x06010000
2696 for (TopExp_Explorer ExV (theShape, TopAbs_VERTEX); ExV.More(); ExV.Next()) {
2697 TopoDS_Vertex Vertex = TopoDS::Vertex(ExV.Current());
2698 T = BRep_Tool::Tolerance(Vertex);
2703 catch (Standard_Failure) {
2704 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2705 SetErrorCode(aFail->GetMessageString());
2708 // END: Mantis issue 0020961
2711 GEOMAlgo_FinderShapeOn1 aFinder;
2712 //Standard_Real aTol = 0.0001; // default value
2713 Standard_Real aTol = VertMax; // Mantis issue 0020961
2715 aFinder.SetShape(theShape);
2716 aFinder.SetTolerance(aTol);
2717 aFinder.SetSurface(theSurface);
2718 aFinder.SetShapeType(theShapeType);
2719 aFinder.SetState(theState);
2721 // Sets the minimal number of inner points for the faces that do not have own
2722 // inner points at all (for e.g. rectangular planar faces have just 2 triangles).
2724 aFinder.SetNbPntsMin(3);
2725 // Sets the maximal number of inner points for edges or faces.
2726 // It is usefull for the cases when this number is very big (e.g =2000) to improve
2727 // the performance. If this value =0, all inner points will be taken into account.
2729 aFinder.SetNbPntsMax(100);
2733 // Interprete results
2734 Standard_Integer iErr = aFinder.ErrorStatus();
2735 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
2737 MESSAGE(" iErr : " << iErr);
2738 TCollection_AsciiString aMsg (" iErr : ");
2739 aMsg += TCollection_AsciiString(iErr);
2743 Standard_Integer iWrn = aFinder.WarningStatus();
2744 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
2746 MESSAGE(" *** iWrn : " << iWrn);
2749 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
2751 if (listSS.Extent() < 1) {
2752 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
2753 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
2757 // Fill sequence of object IDs
2758 aSeqOfIDs = new TColStd_HSequenceOfInteger;
2760 TopTools_IndexedMapOfShape anIndices;
2761 TopExp::MapShapes(theShape, anIndices);
2763 TopTools_ListIteratorOfListOfShape itSub (listSS);
2764 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
2765 int id = anIndices.FindIndex(itSub.Value());
2766 aSeqOfIDs->Append(id);
2772 //=======================================================================
2773 //function : getObjectsShapesOn
2775 * \brief Find shape objects and their entries by their ids
2776 * \param theShapeIDs - incoming shape ids
2777 * \param theShapeEntries - outgoing entries like "entry1, entry2, ..."
2778 * \retval Handle(TColStd_HSequenceOfTransient) - found shape objects
2780 //=======================================================================
2781 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::
2782 getObjectsShapesOn(const Handle(GEOM_Object)& theShape,
2783 const Handle(TColStd_HSequenceOfInteger)& theShapeIDs,
2784 TCollection_AsciiString & theShapeEntries)
2786 Handle(TColStd_HSequenceOfTransient) aSeq;
2788 if ( !theShapeIDs.IsNull() && theShapeIDs->Length() > 0 )
2790 aSeq = new TColStd_HSequenceOfTransient;
2791 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
2792 TCollection_AsciiString anEntry;
2793 for ( int i = 1; i <= theShapeIDs->Length(); ++i )
2795 anArray->SetValue(1, theShapeIDs->Value( i ));
2796 Handle(GEOM_Object) anObj = GetEngine()->AddSubShape(theShape, anArray);
2797 aSeq->Append( anObj );
2799 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
2800 if ( i != 1 ) theShapeEntries += ",";
2801 theShapeEntries += anEntry;
2807 //=======================================================================
2808 //function : getShapesOnSurface
2810 * \brief Find sub-shapes complying with given status about surface
2811 * \param theSurface - the surface to check state of sub-shapes against
2812 * \param theShape - the shape to explore
2813 * \param theShapeType - type of sub-shape of theShape
2814 * \param theState - required state
2815 * \param theShapeEntries - outgoing entries like "entry1, entry2, ..."
2816 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
2818 //=======================================================================
2819 Handle(TColStd_HSequenceOfTransient)
2820 GEOMImpl_IShapesOperations::getShapesOnSurface(const Handle(Geom_Surface)& theSurface,
2821 const Handle(GEOM_Object)& theShape,
2822 TopAbs_ShapeEnum theShapeType,
2823 GEOMAlgo_State theState,
2824 TCollection_AsciiString & theShapeEntries)
2826 // Find sub-shapes ids
2827 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2828 getShapesOnSurfaceIDs (theSurface, theShape->GetValue(), theShapeType, theState);
2829 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2832 return getObjectsShapesOn( theShape, aSeqOfIDs, theShapeEntries );
2835 //=============================================================================
2839 //=============================================================================
2840 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnPlane
2841 (const Handle(GEOM_Object)& theShape,
2842 const Standard_Integer theShapeType,
2843 const Handle(GEOM_Object)& theAx1,
2844 const GEOMAlgo_State theState)
2848 if (theShape.IsNull() || theAx1.IsNull()) return NULL;
2850 TopoDS_Shape aShape = theShape->GetValue();
2851 TopoDS_Shape anAx1 = theAx1->GetValue();
2853 if (aShape.IsNull() || anAx1.IsNull()) return NULL;
2855 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2856 if ( !checkTypeShapesOn( theShapeType ))
2860 Handle(Geom_Surface) aPlane = makePlane( anAx1 );
2861 if ( aPlane.IsNull() )
2865 TCollection_AsciiString anAsciiList;
2866 Handle(TColStd_HSequenceOfTransient) aSeq;
2867 aSeq = getShapesOnSurface( aPlane, theShape, aShapeType, theState, anAsciiList );
2868 if ( aSeq.IsNull() || aSeq->Length() == 0 )
2871 // Make a Python command
2873 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2874 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2876 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
2877 << "] = geompy.GetShapesOnPlane(" << theShape << ", "
2878 << aShapeType << ", " << theAx1 << ", " << theState << ")";
2884 //=============================================================================
2886 * GetShapesOnPlaneWithLocation
2888 //=============================================================================
2889 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnPlaneWithLocation
2890 (const Handle(GEOM_Object)& theShape,
2891 const Standard_Integer theShapeType,
2892 const Handle(GEOM_Object)& theAx1,
2893 const Handle(GEOM_Object)& thePnt,
2894 const GEOMAlgo_State theState)
2898 if (theShape.IsNull() || theAx1.IsNull() || thePnt.IsNull()) return NULL;
2900 TopoDS_Shape aShape = theShape->GetValue();
2901 TopoDS_Shape anAx1 = theAx1->GetValue();
2902 TopoDS_Shape anPnt = thePnt->GetValue();
2904 if (aShape.IsNull() || anAx1.IsNull() || anPnt.IsNull()) return NULL;
2906 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2907 if ( !checkTypeShapesOn( theShapeType ))
2911 if ( anAx1.ShapeType() != TopAbs_EDGE || anPnt.ShapeType() != TopAbs_VERTEX ) return NULL;
2912 TopoDS_Vertex V1, V2, V3;
2913 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
2914 TopExp::Vertices(anEdge, V1, V2, Standard_True);
2916 if (V1.IsNull() || V2.IsNull()) {
2917 SetErrorCode("Bad edge given for the plane normal vector");
2920 V3 = TopoDS::Vertex(anPnt);
2923 SetErrorCode("Bad vertex given for the plane location");
2926 gp_Pnt aLoc = BRep_Tool::Pnt(V3);
2927 gp_Vec aVec(BRep_Tool::Pnt(V1),BRep_Tool::Pnt(V2));
2929 if (aVec.Magnitude() < Precision::Confusion()) {
2930 SetErrorCode("Vector with null magnitude given");
2933 Handle(Geom_Surface) aPlane = new Geom_Plane(aLoc, aVec);
2935 if ( aPlane.IsNull() )
2939 TCollection_AsciiString anAsciiList;
2940 Handle(TColStd_HSequenceOfTransient) aSeq;
2941 aSeq = getShapesOnSurface( aPlane, theShape, aShapeType, theState, anAsciiList );
2942 if ( aSeq.IsNull() || aSeq->Length() == 0 )
2945 // Make a Python command
2947 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2948 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2950 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
2951 << "] = geompy.GetShapesOnPlaneWithLocation(" << theShape << ", "
2952 << aShapeType << ", " << theAx1 << ", "<< thePnt <<", " << theState << ")";
2958 //=============================================================================
2960 * GetShapesOnCylinder
2962 //=============================================================================
2963 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnCylinder
2964 (const Handle(GEOM_Object)& theShape,
2965 const Standard_Integer theShapeType,
2966 const Handle(GEOM_Object)& theAxis,
2967 const Standard_Real theRadius,
2968 const GEOMAlgo_State theState)
2972 if (theShape.IsNull() || theAxis.IsNull()) return NULL;
2974 TopoDS_Shape aShape = theShape->GetValue();
2975 TopoDS_Shape anAxis = theAxis->GetValue();
2977 if (aShape.IsNull() || anAxis.IsNull()) return NULL;
2979 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2980 if ( !checkTypeShapesOn( aShapeType ))
2983 // Create a cylinder surface
2984 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
2985 if ( aCylinder.IsNull() )
2989 TCollection_AsciiString anAsciiList;
2990 Handle(TColStd_HSequenceOfTransient) aSeq;
2991 aSeq = getShapesOnSurface( aCylinder, theShape, aShapeType, theState, anAsciiList );
2992 if ( aSeq.IsNull() || aSeq->Length() == 0 )
2995 // Make a Python command
2997 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2998 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
3000 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
3001 << "] = geompy.GetShapesOnCylinder(" << theShape << ", " << aShapeType
3002 << ", " << theAxis << ", " << theRadius << ", " << theState << ")";
3008 //=============================================================================
3010 * GetShapesOnCylinderWithLocation
3012 //=============================================================================
3013 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnCylinderWithLocation
3014 (const Handle(GEOM_Object)& theShape,
3015 const Standard_Integer theShapeType,
3016 const Handle(GEOM_Object)& theAxis,
3017 const Handle(GEOM_Object)& thePnt,
3018 const Standard_Real theRadius,
3019 const GEOMAlgo_State theState)
3023 if (theShape.IsNull() || theAxis.IsNull() || thePnt.IsNull()) return NULL;
3025 TopoDS_Shape aShape = theShape->GetValue();
3026 TopoDS_Shape anAxis = theAxis->GetValue();
3027 TopoDS_Shape aPnt = thePnt->GetValue();
3029 if (aShape.IsNull() || anAxis.IsNull() || aPnt.IsNull()) return NULL;
3031 if (aPnt.ShapeType() != TopAbs_VERTEX )
3033 SetErrorCode("Bottom location point must be vertex");
3037 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3038 if ( !checkTypeShapesOn( aShapeType ))
3041 // Create a cylinder surface
3042 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
3043 if ( aCylinder.IsNull() )
3046 // translate the surface
3047 Handle(Geom_CylindricalSurface) aCylSurface =
3048 Handle(Geom_CylindricalSurface)::DownCast( aCylinder );
3049 if ( aCylSurface.IsNull() )
3051 SetErrorCode("Unexpected surface type instead of Geom_CylindricalSurface");
3054 gp_Pnt fromLoc = aCylSurface->Cylinder().Location();
3055 gp_Pnt toLoc = BRep_Tool::Pnt( TopoDS::Vertex( aPnt ));
3056 aCylinder->Translate( fromLoc, toLoc );
3059 TCollection_AsciiString anAsciiList;
3060 Handle(TColStd_HSequenceOfTransient) aSeq;
3061 aSeq = getShapesOnSurface( aCylinder, theShape, aShapeType, theState, anAsciiList );
3062 if ( aSeq.IsNull() || aSeq->Length() == 0 )
3065 // Make a Python command
3067 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
3068 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
3070 GEOM::TPythonDump(aFunction)
3071 << "[" << anAsciiList.ToCString()
3072 << "] = geompy.GetShapesOnCylinderWithLocation(" << theShape << ", " << aShapeType << ", "
3073 << theAxis << ", " << thePnt << ", " << theRadius << ", " << theState << ")";
3079 //=============================================================================
3083 //=============================================================================
3084 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnSphere
3085 (const Handle(GEOM_Object)& theShape,
3086 const Standard_Integer theShapeType,
3087 const Handle(GEOM_Object)& theCenter,
3088 const Standard_Real theRadius,
3089 const GEOMAlgo_State theState)
3093 if (theShape.IsNull() || theCenter.IsNull()) return NULL;
3095 TopoDS_Shape aShape = theShape->GetValue();
3096 TopoDS_Shape aCenter = theCenter->GetValue();
3098 if (aShape.IsNull() || aCenter.IsNull()) return NULL;
3100 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3101 if ( !checkTypeShapesOn( aShapeType ))
3104 // Center of the sphere
3105 if (aCenter.ShapeType() != TopAbs_VERTEX) return NULL;
3106 gp_Pnt aLoc = BRep_Tool::Pnt(TopoDS::Vertex(aCenter));
3108 gp_Ax3 anAx3 (aLoc, gp::DZ());
3109 Handle(Geom_SphericalSurface) aSphere =
3110 new Geom_SphericalSurface(anAx3, theRadius);
3113 TCollection_AsciiString anAsciiList;
3114 Handle(TColStd_HSequenceOfTransient) aSeq;
3115 aSeq = getShapesOnSurface( aSphere, theShape, aShapeType, theState, anAsciiList );
3116 if ( aSeq.IsNull() || aSeq->Length() == 0 )
3119 // Make a Python command
3121 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
3122 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
3124 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
3125 << "] = geompy.GetShapesOnSphere(" << theShape << ", " << aShapeType
3126 << ", " << theCenter << ", " << theRadius << ", " << theState << ")";
3132 //=============================================================================
3134 * GetShapesOnPlaneIDs
3136 //=============================================================================
3137 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnPlaneIDs
3138 (const Handle(GEOM_Object)& theShape,
3139 const Standard_Integer theShapeType,
3140 const Handle(GEOM_Object)& theAx1,
3141 const GEOMAlgo_State theState)
3145 if (theShape.IsNull() || theAx1.IsNull()) return NULL;
3147 TopoDS_Shape aShape = theShape->GetValue();
3148 TopoDS_Shape anAx1 = theAx1->GetValue();
3150 if (aShape.IsNull() || anAx1.IsNull()) return NULL;
3152 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3153 if ( !checkTypeShapesOn( aShapeType ))
3157 Handle(Geom_Surface) aPlane = makePlane( anAx1 );
3158 if ( aPlane.IsNull() )
3162 Handle(TColStd_HSequenceOfInteger) aSeq;
3163 aSeq = getShapesOnSurfaceIDs( aPlane, aShape, aShapeType, theState );
3165 // The GetShapesOnPlaneIDs() doesn't change object so no new function is required.
3166 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAx1)->GetLastFunction();
3168 // Make a Python command
3169 GEOM::TPythonDump(aFunction, /*append=*/true)
3170 << "listShapesOnPlane = geompy.GetShapesOnPlaneIDs"
3171 << "(" << theShape << "," << aShapeType << "," << theAx1 << "," << theState << ")";
3177 //=============================================================================
3179 * GetShapesOnPlaneWithLocationIDs
3181 //=============================================================================
3182 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnPlaneWithLocationIDs
3183 (const Handle(GEOM_Object)& theShape,
3184 const Standard_Integer theShapeType,
3185 const Handle(GEOM_Object)& theAx1,
3186 const Handle(GEOM_Object)& thePnt,
3187 const GEOMAlgo_State theState)
3191 if (theShape.IsNull() || theAx1.IsNull() || thePnt.IsNull()) return NULL;
3193 TopoDS_Shape aShape = theShape->GetValue();
3194 TopoDS_Shape anAx1 = theAx1->GetValue();
3195 TopoDS_Shape anPnt = thePnt->GetValue();
3197 if (aShape.IsNull() || anAx1.IsNull() || anPnt.IsNull()) return NULL;
3199 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3200 if ( !checkTypeShapesOn( aShapeType ))
3204 if (anAx1.ShapeType() != TopAbs_EDGE || anPnt.ShapeType() != TopAbs_VERTEX) return NULL;
3205 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
3206 TopoDS_Vertex V1, V2, V3;
3207 TopExp::Vertices(anEdge, V1, V2, Standard_True);
3208 if (V1.IsNull() || V2.IsNull()) {
3209 SetErrorCode("Bad edge given for the plane normal vector");
3212 V3 = TopoDS::Vertex(anPnt);
3214 SetErrorCode("Bad vertex given for the plane location");
3217 gp_Pnt aLoc = BRep_Tool::Pnt(V3);
3218 gp_Vec aVec(BRep_Tool::Pnt(V1),BRep_Tool::Pnt(V2));
3219 if (aVec.Magnitude() < Precision::Confusion()) {
3220 SetErrorCode("Vector with null magnitude given");
3224 Handle(Geom_Surface) aPlane = new Geom_Plane(aLoc, aVec);
3225 if ( aPlane.IsNull() )
3229 Handle(TColStd_HSequenceOfInteger) aSeq;
3230 aSeq = getShapesOnSurfaceIDs( aPlane, aShape, aShapeType, theState );
3232 // The GetShapesOnPlaneIDs() doesn't change object so no new function is required.
3233 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAx1)->GetLastFunction();
3235 // Make a Python command
3236 GEOM::TPythonDump(aFunction, /*append=*/true)
3237 << "listShapesOnPlane = geompy.GetShapesOnPlaneWithLocationIDs"
3238 << "(" << theShape << ", " << aShapeType << ", " << theAx1 << ", "<< thePnt << ", " << theState << ")";
3244 //=============================================================================
3246 * GetShapesOnCylinderIDs
3248 //=============================================================================
3249 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnCylinderIDs
3250 (const Handle(GEOM_Object)& theShape,
3251 const Standard_Integer theShapeType,
3252 const Handle(GEOM_Object)& theAxis,
3253 const Standard_Real theRadius,
3254 const GEOMAlgo_State theState)
3258 if (theShape.IsNull() || theAxis.IsNull()) return NULL;
3260 TopoDS_Shape aShape = theShape->GetValue();
3261 TopoDS_Shape anAxis = theAxis->GetValue();
3263 if (aShape.IsNull() || anAxis.IsNull()) return NULL;
3265 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3266 if ( !checkTypeShapesOn( aShapeType ))
3269 // Create a cylinder surface
3270 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
3271 if ( aCylinder.IsNull() )
3275 Handle(TColStd_HSequenceOfInteger) aSeq;
3276 aSeq = getShapesOnSurfaceIDs( aCylinder, aShape, aShapeType, theState );
3278 // The GetShapesOnCylinder() doesn't change object so no new function is required.
3279 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAxis)->GetLastFunction();
3281 // Make a Python command
3282 GEOM::TPythonDump(aFunction, /*append=*/true)
3283 << "listShapesOnCylinder = geompy.GetShapesOnCylinderIDs"
3284 << "(" << theShape << ", " << aShapeType << ", " << theAxis << ", "
3285 << theRadius << ", " << theState << ")";
3291 //=============================================================================
3293 * GetShapesOnCylinderWithLocationIDs
3295 //=============================================================================
3296 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnCylinderWithLocationIDs
3297 (const Handle(GEOM_Object)& theShape,
3298 const Standard_Integer theShapeType,
3299 const Handle(GEOM_Object)& theAxis,
3300 const Handle(GEOM_Object)& thePnt,
3301 const Standard_Real theRadius,
3302 const GEOMAlgo_State theState)
3306 if (theShape.IsNull() || theAxis.IsNull() || thePnt.IsNull()) return NULL;
3308 TopoDS_Shape aShape = theShape->GetValue();
3309 TopoDS_Shape anAxis = theAxis->GetValue();
3310 TopoDS_Shape aPnt = thePnt->GetValue();
3312 if (aShape.IsNull() || anAxis.IsNull() || aPnt.IsNull()) return NULL;
3314 if (aPnt.ShapeType() != TopAbs_VERTEX )
3316 SetErrorCode("Bottom location point must be vertex");
3320 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3321 if ( !checkTypeShapesOn( aShapeType ))
3324 // Create a cylinder surface
3325 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
3326 if ( aCylinder.IsNull() )
3329 // translate the surface
3330 Handle(Geom_CylindricalSurface) aCylSurface =
3331 Handle(Geom_CylindricalSurface)::DownCast( aCylinder );
3332 if ( aCylSurface.IsNull() )
3334 SetErrorCode("Unexpected surface type instead of Geom_CylindricalSurface");
3337 gp_Pnt fromLoc = aCylSurface->Cylinder().Location();
3338 gp_Pnt toLoc = BRep_Tool::Pnt( TopoDS::Vertex( aPnt ));
3339 aCylinder->Translate( fromLoc, toLoc );
3342 Handle(TColStd_HSequenceOfInteger) aSeq;
3343 aSeq = getShapesOnSurfaceIDs( aCylinder, aShape, aShapeType, theState );
3345 // The GetShapesOnCylinder() doesn't change object so no new function is required.
3346 Handle(GEOM_Function) aFunction =
3347 GEOM::GetCreatedLast(theShape, GEOM::GetCreatedLast(thePnt,theAxis))->GetLastFunction();
3349 // Make a Python command
3350 GEOM::TPythonDump(aFunction, /*append=*/true)
3351 << "listShapesOnCylinder = geompy.GetShapesOnCylinderWithLocationIDs"
3352 << "(" << theShape << ", " << aShapeType << ", " << theAxis << ", "
3353 << thePnt << ", " << theRadius << ", " << theState << ")";
3359 //=============================================================================
3361 * GetShapesOnSphereIDs
3363 //=============================================================================
3364 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnSphereIDs
3365 (const Handle(GEOM_Object)& theShape,
3366 const Standard_Integer theShapeType,
3367 const Handle(GEOM_Object)& theCenter,
3368 const Standard_Real theRadius,
3369 const GEOMAlgo_State theState)
3373 if (theShape.IsNull() || theCenter.IsNull()) return NULL;
3375 TopoDS_Shape aShape = theShape->GetValue();
3376 TopoDS_Shape aCenter = theCenter->GetValue();
3378 if (aShape.IsNull() || aCenter.IsNull()) return NULL;
3380 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3381 if ( !checkTypeShapesOn( aShapeType ))
3384 // Center of the sphere
3385 if (aCenter.ShapeType() != TopAbs_VERTEX) return NULL;
3386 gp_Pnt aLoc = BRep_Tool::Pnt(TopoDS::Vertex(aCenter));
3388 gp_Ax3 anAx3 (aLoc, gp::DZ());
3389 Handle(Geom_SphericalSurface) aSphere =
3390 new Geom_SphericalSurface(anAx3, theRadius);
3393 Handle(TColStd_HSequenceOfInteger) aSeq;
3394 aSeq = getShapesOnSurfaceIDs( aSphere, aShape, aShapeType, theState );
3396 // The GetShapesOnSphere() doesn't change object so no new function is required.
3397 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theCenter)->GetLastFunction();
3399 // Make a Python command
3400 GEOM::TPythonDump(aFunction, /*append=*/true)
3401 << "listShapesOnCylinder = geompy.GetShapesOnSphereIDs"
3402 << "(" << theShape << ", " << aShapeType << ", " << theCenter << ", "
3403 << theRadius << ", " << theState << ")";
3409 //=======================================================================
3410 //function : getShapesOnQuadrangleIDs
3412 * \brief Find IDs of sub-shapes complying with given status about quadrangle
3413 * \param theShape - the shape to explore
3414 * \param theShapeType - type of sub-shape of theShape
3415 * \param theTopLeftPoint - top left quadrangle corner
3416 * \param theTopRigthPoint - top right quadrangle corner
3417 * \param theBottomLeftPoint - bottom left quadrangle corner
3418 * \param theBottomRigthPoint - bottom right quadrangle corner
3419 * \param theState - required state
3420 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
3422 //=======================================================================
3423 Handle(TColStd_HSequenceOfInteger)
3424 GEOMImpl_IShapesOperations::getShapesOnQuadrangleIDs (const Handle(GEOM_Object)& theShape,
3425 const Standard_Integer theShapeType,
3426 const Handle(GEOM_Object)& theTopLeftPoint,
3427 const Handle(GEOM_Object)& theTopRigthPoint,
3428 const Handle(GEOM_Object)& theBottomLeftPoint,
3429 const Handle(GEOM_Object)& theBottomRigthPoint,
3430 const GEOMAlgo_State theState)
3434 if ( theShape.IsNull() ||
3435 theTopLeftPoint.IsNull() ||
3436 theTopRigthPoint.IsNull() ||
3437 theBottomLeftPoint.IsNull() ||
3438 theBottomRigthPoint.IsNull() )
3441 TopoDS_Shape aShape = theShape->GetValue();
3442 TopoDS_Shape aTL = theTopLeftPoint->GetValue();
3443 TopoDS_Shape aTR = theTopRigthPoint->GetValue();
3444 TopoDS_Shape aBL = theBottomLeftPoint->GetValue();
3445 TopoDS_Shape aBR = theBottomRigthPoint->GetValue();
3447 if (aShape.IsNull() ||
3452 aTL.ShapeType() != TopAbs_VERTEX ||
3453 aTR.ShapeType() != TopAbs_VERTEX ||
3454 aBL.ShapeType() != TopAbs_VERTEX ||
3455 aBR.ShapeType() != TopAbs_VERTEX )
3458 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3459 if ( !checkTypeShapesOn( aShapeType ))
3462 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
3464 // Check presence of triangulation, build if need
3465 if (!GEOMUtils::CheckTriangulation(aShape)) {
3466 SetErrorCode("Cannot build triangulation on the shape");
3471 gp_Pnt aPntTL = BRep_Tool::Pnt(TopoDS::Vertex(aTL));
3472 gp_Pnt aPntTR = BRep_Tool::Pnt(TopoDS::Vertex(aTR));
3473 gp_Pnt aPntBL = BRep_Tool::Pnt(TopoDS::Vertex(aBL));
3474 gp_Pnt aPntBR = BRep_Tool::Pnt(TopoDS::Vertex(aBR));
3476 GEOMAlgo_FinderShapeOnQuad aFinder( aPntTL, aPntTR, aPntBL, aPntBR );
3477 Standard_Real aTol = 0.0001; // default value
3479 aFinder.SetShape(aShape);
3480 aFinder.SetTolerance(aTol);
3481 //aFinder.SetSurface(theSurface);
3482 aFinder.SetShapeType(aShapeType);
3483 aFinder.SetState(theState);
3485 // Sets the minimal number of inner points for the faces that do not have own
3486 // inner points at all (for e.g. rectangular planar faces have just 2 triangles).
3488 aFinder.SetNbPntsMin(3);
3489 // Sets the maximal number of inner points for edges or faces.
3490 // It is usefull for the cases when this number is very big (e.g =2000) to improve
3491 // the performance. If this value =0, all inner points will be taken into account.
3493 aFinder.SetNbPntsMax(100);
3497 // Interprete results
3498 Standard_Integer iErr = aFinder.ErrorStatus();
3499 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
3501 MESSAGE(" iErr : " << iErr);
3502 TCollection_AsciiString aMsg (" iErr : ");
3503 aMsg += TCollection_AsciiString(iErr);
3507 Standard_Integer iWrn = aFinder.WarningStatus();
3508 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
3510 MESSAGE(" *** iWrn : " << iWrn);
3513 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
3515 if (listSS.Extent() < 1) {
3516 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
3517 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
3521 // Fill sequence of object IDs
3522 aSeqOfIDs = new TColStd_HSequenceOfInteger;
3524 TopTools_IndexedMapOfShape anIndices;
3525 TopExp::MapShapes(aShape, anIndices);
3527 TopTools_ListIteratorOfListOfShape itSub (listSS);
3528 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
3529 int id = anIndices.FindIndex(itSub.Value());
3530 aSeqOfIDs->Append(id);
3535 //=======================================================================
3536 //function : GetShapesOnQuadrangle
3538 * \brief Find sub-shapes complying with given status about quadrangle
3539 * \param theShape - the shape to explore
3540 * \param theShapeType - type of sub-shape of theShape
3541 * \param theTopLeftPoint - top left quadrangle corner
3542 * \param theTopRigthPoint - top right quadrangle corner
3543 * \param theBottomLeftPoint - bottom left quadrangle corner
3544 * \param theBottomRigthPoint - bottom right quadrangle corner
3545 * \param theState - required state
3546 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
3548 //=======================================================================
3549 Handle(TColStd_HSequenceOfTransient)
3550 GEOMImpl_IShapesOperations::GetShapesOnQuadrangle (const Handle(GEOM_Object)& theShape,
3551 const Standard_Integer theShapeType,
3552 const Handle(GEOM_Object)& theTopLeftPoint,
3553 const Handle(GEOM_Object)& theTopRigthPoint,
3554 const Handle(GEOM_Object)& theBottomLeftPoint,
3555 const Handle(GEOM_Object)& theBottomRigthPoint,
3556 const GEOMAlgo_State theState)
3559 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
3560 getShapesOnQuadrangleIDs( theShape,
3565 theBottomRigthPoint,
3567 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->IsEmpty() )
3570 // Find objects by indices
3571 TCollection_AsciiString anAsciiList;
3572 Handle(TColStd_HSequenceOfTransient) aSeq;
3573 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
3574 if ( aSeq.IsNull() || aSeq->IsEmpty() )
3577 // Make a Python command
3579 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
3580 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
3582 GEOM::TPythonDump(aFunction)
3583 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnQuadrangle("
3585 << TopAbs_ShapeEnum(theShapeType) << ", "
3586 << theTopLeftPoint << ", "
3587 << theTopRigthPoint << ", "
3588 << theBottomLeftPoint << ", "
3589 << theBottomRigthPoint << ", "
3596 //=======================================================================
3597 //function : GetShapesOnQuadrangleIDs
3599 * \brief Find IDs of sub-shapes complying with given status about quadrangle
3600 * \param theShape - the shape to explore
3601 * \param theShapeType - type of sub-shape of theShape
3602 * \param theTopLeftPoint - top left quadrangle corner
3603 * \param theTopRigthPoint - top right quadrangle corner
3604 * \param theBottomLeftPoint - bottom left quadrangle corner
3605 * \param theBottomRigthPoint - bottom right quadrangle corner
3606 * \param theState - required state
3607 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
3609 //=======================================================================
3610 Handle(TColStd_HSequenceOfInteger)
3611 GEOMImpl_IShapesOperations::GetShapesOnQuadrangleIDs (const Handle(GEOM_Object)& theShape,
3612 const Standard_Integer theShapeType,
3613 const Handle(GEOM_Object)& theTopLeftPoint,
3614 const Handle(GEOM_Object)& theTopRigthPoint,
3615 const Handle(GEOM_Object)& theBottomLeftPoint,
3616 const Handle(GEOM_Object)& theBottomRigthPoint,
3617 const GEOMAlgo_State theState)
3620 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
3621 getShapesOnQuadrangleIDs( theShape,
3626 theBottomRigthPoint,
3628 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->IsEmpty() )
3631 // Make a Python command
3633 // The GetShapesOnCylinder() doesn't change object so no new function is required.
3634 Handle(GEOM_Object) lastObj = GEOM::GetCreatedLast(theShape,theTopLeftPoint);
3635 lastObj = GEOM::GetCreatedLast(lastObj,theTopRigthPoint);
3636 lastObj = GEOM::GetCreatedLast(lastObj,theBottomRigthPoint);
3637 lastObj = GEOM::GetCreatedLast(lastObj,theBottomLeftPoint);
3638 Handle(GEOM_Function) aFunction = lastObj->GetLastFunction();
3640 GEOM::TPythonDump(aFunction, /*append=*/true)
3641 << "listShapesOnQuadrangle = geompy.GetShapesOnQuadrangleIDs("
3643 << TopAbs_ShapeEnum(theShapeType) << ", "
3644 << theTopLeftPoint << ", "
3645 << theTopRigthPoint << ", "
3646 << theBottomLeftPoint << ", "
3647 << theBottomRigthPoint << ", "
3654 //=============================================================================
3658 //=============================================================================
3659 static bool GetInPlaceOfShape (const Handle(GEOM_Function)& theWhereFunction,
3660 const TopTools_IndexedMapOfShape& theWhereIndices,
3661 const TopoDS_Shape& theWhat,
3662 TColStd_ListOfInteger& theModifiedList)
3664 if (theWhereFunction.IsNull() || theWhat.IsNull()) return false;
3666 if (theWhereIndices.Contains(theWhat)) {
3667 // entity was not changed by the operation
3668 Standard_Integer aWhatIndex = theWhereIndices.FindIndex(theWhat);
3669 theModifiedList.Append(aWhatIndex);
3673 // try to find in history
3674 TDF_Label aHistoryLabel = theWhereFunction->GetHistoryEntry(Standard_False);
3676 // search in history for all argument shapes
3677 Standard_Boolean isFound = Standard_False;
3678 Standard_Boolean isGood = Standard_False;
3680 TDF_LabelSequence aLabelSeq;
3681 theWhereFunction->GetDependency(aLabelSeq);
3682 Standard_Integer nbArg = aLabelSeq.Length();
3684 for (Standard_Integer iarg = 1; iarg <= nbArg && !isFound; iarg++) {
3686 TDF_Label anArgumentRefLabel = aLabelSeq.Value(iarg);
3688 Handle(GEOM_Object) anArgumentObject = GEOM_Object::GetReferencedObject(anArgumentRefLabel);
3689 TopoDS_Shape anArgumentShape = anArgumentObject->GetValue();
3691 TopTools_IndexedMapOfShape anArgumentIndices;
3692 TopExp::MapShapes(anArgumentShape, anArgumentIndices);
3694 if (anArgumentIndices.Contains(theWhat)) {
3695 isFound = Standard_True;
3696 Standard_Integer aWhatIndex = anArgumentIndices.FindIndex(theWhat);
3698 // Find corresponding label in history
3699 TDF_Label anArgumentHistoryLabel =
3700 theWhereFunction->GetArgumentHistoryEntry(anArgumentRefLabel, Standard_False);
3701 if (anArgumentHistoryLabel.IsNull()) {
3702 // Lost History of operation argument. Possibly, all its entities was removed.
3703 isGood = Standard_True;
3706 TDF_Label aWhatHistoryLabel = anArgumentHistoryLabel.FindChild(aWhatIndex, Standard_False);
3708 if (aWhatHistoryLabel.IsNull()) {
3709 // Removed entity ? Compound ? Compsolid ? Shell ? Wire
3710 isGood = Standard_False;
3712 Handle(TDataStd_IntegerArray) anIntegerArray;
3713 if (!aWhatHistoryLabel.FindAttribute(TDataStd_IntegerArray::GetID(), anIntegerArray)) {
3714 //Error: Empty modifications history for the sought shape.
3715 isGood = Standard_False;
3718 isGood = Standard_True;
3719 Standard_Integer imod, aModifLen = anIntegerArray->Array()->Length();
3720 for (imod = 1; imod <= aModifLen; imod++) {
3721 theModifiedList.Append(anIntegerArray->Array()->Value(imod));
3732 // try compound/compsolid/shell/wire element by element
3733 bool isFoundAny = false;
3734 TopTools_MapOfShape mapShape;
3736 if (theWhat.ShapeType() == TopAbs_COMPOUND ||
3737 theWhat.ShapeType() == TopAbs_COMPSOLID) {
3738 // recursive processing of compound/compsolid
3739 TopoDS_Iterator anIt (theWhat, Standard_True, Standard_True);
3740 for (; anIt.More(); anIt.Next()) {
3741 if (mapShape.Add(anIt.Value())) {
3742 TopoDS_Shape curWhat = anIt.Value();
3743 isFoundAny = GetInPlaceOfShape(theWhereFunction, theWhereIndices, curWhat, theModifiedList);
3744 if (isFoundAny) isFound = Standard_True;
3748 else if (theWhat.ShapeType() == TopAbs_SHELL) {
3749 // try to replace a shell by its faces images
3750 TopExp_Explorer anExp (theWhat, TopAbs_FACE);
3751 for (; anExp.More(); anExp.Next()) {
3752 if (mapShape.Add(anExp.Current())) {
3753 TopoDS_Shape curWhat = anExp.Current();
3754 isFoundAny = GetInPlaceOfShape(theWhereFunction, theWhereIndices, curWhat, theModifiedList);
3755 if (isFoundAny) isFound = Standard_True;
3759 else if (theWhat.ShapeType() == TopAbs_WIRE) {
3760 // try to replace a wire by its edges images
3761 TopExp_Explorer anExp (theWhat, TopAbs_EDGE);
3762 for (; anExp.More(); anExp.Next()) {
3763 if (mapShape.Add(anExp.Current())) {
3764 TopoDS_Shape curWhat = anExp.Current();
3765 isFoundAny = GetInPlaceOfShape(theWhereFunction, theWhereIndices, curWhat, theModifiedList);
3766 if (isFoundAny) isFound = Standard_True;
3778 //=============================================================================
3780 * GetShapeProperties
3782 //=============================================================================
3783 void GEOMImpl_IShapesOperations::GetShapeProperties( const TopoDS_Shape aShape, Standard_Real tab[],
3786 GProp_GProps theProps;
3788 //TopoDS_Shape aPntShape;
3789 Standard_Real aShapeSize;
3791 if (aShape.ShapeType() == TopAbs_VERTEX) aCenterMass = BRep_Tool::Pnt( TopoDS::Vertex( aShape ) );
3792 else if (aShape.ShapeType() == TopAbs_EDGE) BRepGProp::LinearProperties(aShape, theProps);
3793 else if (aShape.ShapeType() == TopAbs_FACE) BRepGProp::SurfaceProperties(aShape, theProps);
3794 else BRepGProp::VolumeProperties(aShape, theProps);
3796 if (aShape.ShapeType() == TopAbs_VERTEX)
3799 aCenterMass = theProps.CentreOfMass();
3800 aShapeSize = theProps.Mass();
3803 // aPntShape = BRepBuilderAPI_MakeVertex(aCenterMass).Shape();
3804 // aVertex = BRep_Tool::Pnt( TopoDS::Vertex( aPntShape ) );
3805 aVertex = aCenterMass;
3806 tab[0] = aVertex.X();
3807 tab[1] = aVertex.Y();
3808 tab[2] = aVertex.Z();
3809 tab[3] = aShapeSize;
3815 //================================================================================
3817 * \brief Return normal to face at extrema point
3819 //================================================================================
3821 gp_Vec GetNormal (const TopoDS_Face& face, const BRepExtrema_DistShapeShape& extrema)
3823 gp_Vec defaultNorm(1,0,0); // to have same normals on different faces
3825 // get UV at extrema point
3826 Standard_Real u,v, f,l;
3827 switch ( extrema.SupportTypeShape2(1) ) {
3828 case BRepExtrema_IsInFace: {
3829 extrema.ParOnFaceS2(1, u, v );
3832 case BRepExtrema_IsOnEdge: {
3833 TopoDS_Edge edge = TopoDS::Edge( extrema.SupportOnShape2(1));
3834 Handle(Geom2d_Curve) pcurve = BRep_Tool::CurveOnSurface( edge, face, f,l );
3835 extrema.ParOnEdgeS2( 1, u );
3836 gp_Pnt2d uv = pcurve->Value( u );
3841 case BRepExtrema_IsVertex: return defaultNorm;
3844 BRepAdaptor_Surface surface( face, false );
3845 gp_Vec du, dv; gp_Pnt p;
3846 surface.D1( u, v, p, du, dv );
3850 } catch (Standard_Failure ) {
3856 //=============================================================================
3861 //=============================================================================
3862 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlace (Handle(GEOM_Object) theShapeWhere,
3863 Handle(GEOM_Object) theShapeWhat)
3867 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
3869 TopoDS_Shape aWhere = theShapeWhere->GetValue();
3870 TopoDS_Shape aWhat = theShapeWhat->GetValue();
3871 TopoDS_Shape aPntShape;
3872 TopoDS_Vertex aVertex;
3874 if (aWhere.IsNull() || aWhat.IsNull()) {
3875 SetErrorCode("Error: aWhere and aWhat TopoDS_Shape are Null.");
3879 Handle(GEOM_Function) aWhereFunction = theShapeWhere->GetLastFunction();
3880 if (aWhereFunction.IsNull()) {
3881 SetErrorCode("Error: aWhereFunction is Null.");
3885 TopTools_IndexedMapOfShape aWhereIndices;
3886 TopExp::MapShapes(aWhere, aWhereIndices);
3888 TopAbs_ShapeEnum iType = TopAbs_SOLID;
3889 Standard_Real dl_l = 1e-3;
3890 Standard_Real min_l, Tol_0D, Tol_1D, Tol_2D, Tol_3D, Tol_Mass;
3891 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
3892 Bnd_Box BoundingBox;
3893 gp_Pnt aPnt, aPnt_aWhat, tab_Pnt[2];
3894 GProp_GProps aProps;
3896 // Find the iType of the aWhat shape
3897 iType = GEOMUtils::GetTypeOfSimplePart(aWhat);
3898 if (iType == TopAbs_SHAPE) {
3899 SetErrorCode("Error: An attempt to extract a shape of not supported type.");
3903 TopExp_Explorer Exp_aWhat ( aWhat, iType );
3904 TopExp_Explorer Exp_aWhere ( aWhere, iType );
3905 TopExp_Explorer Exp_Edge ( aWhere, TopAbs_EDGE );
3907 // Find the shortest edge in theShapeWhere shape
3908 BRepBndLib::Add(aWhere, BoundingBox);
3909 BoundingBox.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
3910 min_l = fabs(aXmax - aXmin);
3911 if( min_l < fabs(aYmax - aYmin) ) min_l = fabs(aYmax - aYmin);
3912 if( min_l < fabs(aZmax - aZmin) ) min_l = fabs(aZmax - aZmin);
3914 // Mantis issue 0020908 BEGIN
3915 if (!Exp_Edge.More()) {
3916 min_l = Precision::Confusion();
3918 // Mantis issue 0020908 END
3919 for ( Standard_Integer nbEdge = 0; Exp_Edge.More(); Exp_Edge.Next(), nbEdge++ ) {
3920 TopExp_Explorer Exp_Vertex( Exp_Edge.Current(), TopAbs_VERTEX);
3921 for ( Standard_Integer nbVertex = 0; Exp_Vertex.More(); Exp_Vertex.Next(), nbVertex++ ) {
3922 aPnt = BRep_Tool::Pnt( TopoDS::Vertex( Exp_Vertex.Current() ) );
3923 tab_Pnt[nbVertex] = aPnt;
3925 if ( ! tab_Pnt[0].IsEqual(tab_Pnt[1], dl_l) ) {
3926 BRepGProp::LinearProperties(Exp_Edge.Current(), aProps);
3927 if ( aProps.Mass() < min_l ) min_l = aProps.Mass();
3932 // Compute tolerances
3934 Tol_1D = dl_l * min_l;
3935 Tol_2D = dl_l * ( min_l * min_l) * ( 2. + dl_l);
3936 Tol_3D = dl_l * ( min_l * min_l * min_l ) * ( 3. + (3 * dl_l) + (dl_l * dl_l) );
3938 if (Tol_0D < Precision::Confusion()) Tol_0D = Precision::Confusion();
3939 if (Tol_1D < Precision::Confusion()) Tol_1D = Precision::Confusion();
3940 if (Tol_2D < Precision::Confusion()) Tol_2D = Precision::Confusion();
3941 if (Tol_3D < Precision::Confusion()) Tol_3D = Precision::Confusion();
3944 if ( iType == TopAbs_VERTEX ) Tol_Mass = Tol_0D;
3945 else if ( iType == TopAbs_EDGE ) Tol_Mass = Tol_1D;
3946 else if ( iType == TopAbs_FACE ) Tol_Mass = Tol_2D;
3948 // Searching for the sub-shapes inside the ShapeWhere shape
3949 GEOMAlgo_GetInPlace aGIP;
3950 aGIP.SetTolerance(Tol_1D);
3951 aGIP.SetTolMass(Tol_Mass);
3952 aGIP.SetTolCG(Tol_1D);
3954 aGIP.SetArgument(aWhat);
3955 aGIP.SetShapeWhere(aWhere);
3958 int iErr = aGIP.ErrorStatus();
3960 SetErrorCode("Error in GEOMAlgo_GetInPlace");
3964 // aGIP.IsFound() returns true only when the whole theShapeWhat
3965 // is found (as one shape or several parts). But we are also interested
3966 // in the partial result, that is why this check is commented.
3967 //if (!aGIP.IsFound()) {
3968 // SetErrorCode(NOT_FOUND_ANY);
3972 // Add direct result.
3973 TopTools_ListOfShape aLSA;
3974 const TopoDS_Shape &aShapeResult = aGIP.Result();
3975 TopTools_MapOfShape aMFence;
3977 if (aShapeResult.IsNull() == Standard_False) {
3978 TopoDS_Iterator anIt(aShapeResult);
3980 for (; anIt.More(); anIt.Next()) {
3981 const TopoDS_Shape &aPart = anIt.Value();
3983 if(aWhereIndices.Contains(aPart) && aMFence.Add(aPart)) {
3989 if (aLSA.Extent() == 0) {
3990 SetErrorCode(NOT_FOUND_ANY); // Not found any Results
3994 Handle(TColStd_HArray1OfInteger) aModifiedArray = new TColStd_HArray1OfInteger (1, aLSA.Extent());
3995 TopTools_ListIteratorOfListOfShape anIterModif (aLSA);
3996 for (Standard_Integer imod = 1; anIterModif.More(); anIterModif.Next(), imod++) {
3997 if (aWhereIndices.Contains(anIterModif.Value())) {
3998 aModifiedArray->SetValue(imod, aWhereIndices.FindIndex(anIterModif.Value()));
4001 SetErrorCode("Error: wrong sub-shape returned");
4007 Handle(GEOM_Object) aResult = GetEngine()->AddSubShape(theShapeWhere, aModifiedArray);
4008 if (aResult.IsNull()) {
4009 SetErrorCode("Error in algorithm: result found, but cannot be returned.");
4013 if (aModifiedArray->Length() > 1 || theShapeWhat->GetType() == GEOM_GROUP) {
4015 aResult->SetType(GEOM_GROUP);
4017 //Set a sub-shape type
4018 TopoDS_Shape aFirstFound = aLSA.First();
4019 TopAbs_ShapeEnum aShapeType = aFirstFound.ShapeType();
4021 TDF_Label aFreeLabel = aResult->GetFreeLabel();
4022 TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aShapeType);
4025 //Make a Python command
4026 Handle(GEOM_Function) aFunction = aResult->GetFunction(1);
4028 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetInPlace("
4029 << theShapeWhere << ", " << theShapeWhat << ", True)";
4035 //=============================================================================
4037 * case GetInPlaceOld:
4040 //=============================================================================
4041 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlaceOld (Handle(GEOM_Object) theShapeWhere,
4042 Handle(GEOM_Object) theShapeWhat)
4046 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
4048 TopoDS_Shape aWhere = theShapeWhere->GetValue();
4049 TopoDS_Shape aWhat = theShapeWhat->GetValue();
4050 TopoDS_Shape aPntShape;
4051 TopoDS_Vertex aVertex;
4053 if (aWhere.IsNull() || aWhat.IsNull()) {
4054 SetErrorCode("Error: aWhere and aWhat TopoDS_Shape are Null.");
4058 Handle(GEOM_Function) aWhereFunction = theShapeWhere->GetLastFunction();
4059 if (aWhereFunction.IsNull()) {
4060 SetErrorCode("Error: aWhereFunction is Null.");
4064 TopTools_IndexedMapOfShape aWhereIndices;
4065 TopExp::MapShapes(aWhere, aWhereIndices);
4067 TColStd_ListOfInteger aModifiedList;
4068 Standard_Integer aWhereIndex;
4069 Handle(TColStd_HArray1OfInteger) aModifiedArray;
4070 Handle(GEOM_Object) aResult;
4072 bool isFound = false;
4073 TopAbs_ShapeEnum iType = TopAbs_SOLID;
4074 //Standard_Real aWhat_Mass = 0., aWhere_Mass = 0.;
4075 Standard_Real tab_aWhat[4], tab_aWhere[4];
4076 Standard_Real dl_l = 1e-3;
4077 Standard_Real min_l, Tol_0D, Tol_1D, Tol_2D, Tol_3D, Tol_Mass;
4078 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
4079 Bnd_Box BoundingBox;
4080 gp_Pnt aPnt, aPnt_aWhat, tab_Pnt[2];
4081 GProp_GProps aProps;
4083 // Find the iType of the aWhat shape
4085 if ( aWhat.ShapeType() == TopAbs_VERTEX ) iType = TopAbs_VERTEX;
4086 else if ( aWhat.ShapeType() == TopAbs_EDGE || aWhat.ShapeType() == TopAbs_WIRE ) iType = TopAbs_EDGE;
4087 else if ( aWhat.ShapeType() == TopAbs_FACE || aWhat.ShapeType() == TopAbs_SHELL ) iType = TopAbs_FACE;
4088 else if ( aWhat.ShapeType() == TopAbs_SOLID || aWhat.ShapeType() == TopAbs_COMPSOLID ) iType = TopAbs_SOLID;
4089 else if ( aWhat.ShapeType() == TopAbs_COMPOUND ) {
4090 // Only the iType of the first shape in the compound is taken into account
4091 TopoDS_Iterator It (aWhat, Standard_False, Standard_False);
4093 SetErrorCode("Error: theShapeWhat is an empty COMPOUND.");
4096 TopAbs_ShapeEnum compType = It.Value().ShapeType();
4097 if ( compType == TopAbs_VERTEX ) iType = TopAbs_VERTEX;
4098 else if ( compType == TopAbs_EDGE || compType == TopAbs_WIRE ) iType = TopAbs_EDGE;
4099 else if ( compType == TopAbs_FACE || compType == TopAbs_SHELL) iType = TopAbs_FACE;
4100 else if ( compType == TopAbs_SOLID || compType == TopAbs_COMPSOLID) iType = TopAbs_SOLID;
4103 SetErrorCode("Error: An attempt to extract a shape of not supported type.");
4107 iType = GEOMUtils::GetTypeOfSimplePart(aWhat);
4108 if (iType == TopAbs_SHAPE) {
4109 SetErrorCode("Error: An attempt to extract a shape of not supported type.");
4113 TopExp_Explorer Exp_aWhat ( aWhat, iType );
4114 TopExp_Explorer Exp_aWhere ( aWhere, iType );
4115 TopExp_Explorer Exp_Edge ( aWhere, TopAbs_EDGE );
4117 // Find the shortest edge in theShapeWhere shape
4118 BRepBndLib::Add(aWhere, BoundingBox);
4119 BoundingBox.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
4120 min_l = fabs(aXmax - aXmin);
4121 if( min_l < fabs(aYmax - aYmin) ) min_l = fabs(aYmax - aYmin);
4122 if( min_l < fabs(aZmax - aZmin) ) min_l = fabs(aZmax - aZmin);
4124 // Mantis issue 0020908 BEGIN
4125 if (!Exp_Edge.More()) {
4126 min_l = Precision::Confusion();
4128 // Mantis issue 0020908 END
4129 for ( Standard_Integer nbEdge = 0; Exp_Edge.More(); Exp_Edge.Next(), nbEdge++ ) {
4130 TopExp_Explorer Exp_Vertex( Exp_Edge.Current(), TopAbs_VERTEX);
4131 for ( Standard_Integer nbVertex = 0; Exp_Vertex.More(); Exp_Vertex.Next(), nbVertex++ ) {
4132 aPnt = BRep_Tool::Pnt( TopoDS::Vertex( Exp_Vertex.Current() ) );
4133 tab_Pnt[nbVertex] = aPnt;
4135 if ( ! tab_Pnt[0].IsEqual(tab_Pnt[1], dl_l) ) {
4136 BRepGProp::LinearProperties(Exp_Edge.Current(), aProps);
4137 if ( aProps.Mass() < min_l ) min_l = aProps.Mass();
4141 // Compute tolerances
4143 Tol_1D = dl_l * min_l;
4144 Tol_2D = dl_l * ( min_l * min_l) * ( 2. + dl_l);
4145 Tol_3D = dl_l * ( min_l * min_l * min_l ) * ( 3. + (3 * dl_l) + (dl_l * dl_l) );
4147 if (Tol_0D < Precision::Confusion()) Tol_0D = Precision::Confusion();
4148 if (Tol_1D < Precision::Confusion()) Tol_1D = Precision::Confusion();
4149 if (Tol_2D < Precision::Confusion()) Tol_2D = Precision::Confusion();
4150 if (Tol_3D < Precision::Confusion()) Tol_3D = Precision::Confusion();
4152 //if (Tol_1D > 1.0) Tol_1D = 1.0;
4153 //if (Tol_2D > 1.0) Tol_2D = 1.0;
4154 //if (Tol_3D > 1.0) Tol_3D = 1.0;
4157 if ( iType == TopAbs_VERTEX ) Tol_Mass = Tol_0D;
4158 else if ( iType == TopAbs_EDGE ) Tol_Mass = Tol_1D;
4159 else if ( iType == TopAbs_FACE ) Tol_Mass = Tol_2D;
4161 // Compute the ShapeWhat Mass
4163 for ( ; Exp_aWhat.More(); Exp_aWhat.Next() ) {
4164 if ( iType == TopAbs_VERTEX ) {
4168 else if ( iType == TopAbs_EDGE ) BRepGProp::LinearProperties(Exp_aWhat.Current(), aProps);
4169 else if ( iType == TopAbs_FACE ) BRepGProp::SurfaceProperties(Exp_aWhat.Current(), aProps);
4170 else BRepGProp::VolumeProperties(Exp_aWhat.Current(), aProps);
4171 aWhat_Mass += aProps.Mass();
4175 // Searching for the sub-shapes inside the ShapeWhere shape
4176 TopTools_MapOfShape map_aWhere;
4177 for ( Exp_aWhere.ReInit(); Exp_aWhere.More(); Exp_aWhere.Next() ) {
4178 if (!map_aWhere.Add(Exp_aWhere.Current()))
4179 continue; // skip repeated shape to avoid mass addition
4180 GetShapeProperties( Exp_aWhere.Current(), tab_aWhere, aPnt );
4181 for ( Exp_aWhat.ReInit(); Exp_aWhat.More(); Exp_aWhat.Next() ) {
4182 GetShapeProperties( Exp_aWhat.Current(), tab_aWhat, aPnt_aWhat );
4183 if ( fabs(tab_aWhat[3] - tab_aWhere[3]) <= Tol_Mass && aPnt_aWhat.Distance(aPnt) <= Tol_1D )
4186 if ( (tab_aWhat[3] - tab_aWhere[3]) > Tol_Mass ) {
4187 aPntShape = BRepBuilderAPI_MakeVertex( aPnt ).Shape();
4188 aVertex = TopoDS::Vertex( aPntShape );
4189 BRepExtrema_DistShapeShape aWhereDistance ( aVertex, Exp_aWhere.Current() );
4190 BRepExtrema_DistShapeShape aWhatDistance ( aVertex, Exp_aWhat.Current() );
4191 if ( aWhereDistance.IsDone() && aWhatDistance.IsDone() &&
4192 fabs(aWhereDistance.Value() - aWhatDistance.Value()) <= Tol_1D )
4194 // 0020162: "EDF 961 GEOM : Getinplace is getting additionnal orthogonal faces"
4195 // aVertex must be projected to the same point on Where and on What
4196 gp_Pnt pOnWhat = aWhatDistance.PointOnShape2(1);
4197 gp_Pnt pOnWhere = aWhereDistance.PointOnShape2(1);
4198 isFound = ( pOnWhat.Distance(pOnWhere) <= Tol_1D );
4199 if ( isFound && iType == TopAbs_FACE )
4201 // check normals at pOnWhat and pOnWhere
4202 const double angleTol = M_PI/180.;
4203 gp_Vec normToWhat = GetNormal( TopoDS::Face(Exp_aWhat.Current()), aWhatDistance);
4204 gp_Vec normToWhere = GetNormal( TopoDS::Face(Exp_aWhere.Current()), aWhereDistance);
4205 if ( normToWhat * normToWhere < 0 )
4206 normToWhat.Reverse();
4207 isFound = ( normToWhat.Angle( normToWhere ) < angleTol );
4213 aWhereIndex = aWhereIndices.FindIndex(Exp_aWhere.Current());
4214 aModifiedList.Append(aWhereIndex);
4215 //aWhere_Mass += tab_aWhere[3];
4220 //if ( fabs( aWhat_Mass - aWhere_Mass ) <= Tol_Mass )
4224 if (aModifiedList.Extent() == 0) { // Not found any Results
4225 SetErrorCode(NOT_FOUND_ANY);
4229 aModifiedArray = new TColStd_HArray1OfInteger (1, aModifiedList.Extent());
4230 TColStd_ListIteratorOfListOfInteger anIterModif (aModifiedList);
4231 for (Standard_Integer imod = 1; anIterModif.More(); anIterModif.Next(), imod++)
4232 aModifiedArray->SetValue(imod, anIterModif.Value());
4235 aResult = GetEngine()->AddSubShape(theShapeWhere, aModifiedArray);
4236 if (aResult.IsNull()) {
4237 SetErrorCode("Error in algorithm: result found, but cannot be returned.");
4241 if (aModifiedArray->Length() > 1 || theShapeWhat->GetType() == GEOM_GROUP) {
4243 aResult->SetType(GEOM_GROUP);
4245 //Set a sub-shape type
4246 TopoDS_Shape aFirstFound = aWhereIndices.FindKey(aModifiedArray->Value(1));
4247 TopAbs_ShapeEnum aShapeType = aFirstFound.ShapeType();
4249 TDF_Label aFreeLabel = aResult->GetFreeLabel();
4250 TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aShapeType);
4253 //Make a Python command
4254 Handle(GEOM_Function) aFunction = aResult->GetFunction(1);
4256 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetInPlace("
4257 << theShapeWhere << ", " << theShapeWhat << ", False)";
4263 //=======================================================================
4264 //function : GetInPlaceByHistory
4266 //=======================================================================
4267 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlaceByHistory
4268 (Handle(GEOM_Object) theShapeWhere,
4269 Handle(GEOM_Object) theShapeWhat)
4273 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
4275 TopoDS_Shape aWhere = theShapeWhere->GetValue();
4276 TopoDS_Shape aWhat = theShapeWhat->GetValue();
4278 if (aWhere.IsNull() || aWhat.IsNull()) return NULL;
4280 Handle(GEOM_Function) aWhereFunction = theShapeWhere->GetLastFunction();
4281 if (aWhereFunction.IsNull()) return NULL;
4283 //Fill array of indices
4284 TopTools_IndexedMapOfShape aWhereIndices;
4285 TopExp::MapShapes(aWhere, aWhereIndices);
4288 TColStd_ListOfInteger aModifiedList;
4289 bool isFound = GetInPlaceOfShape(aWhereFunction, aWhereIndices, aWhat, aModifiedList);
4291 if (!isFound || aModifiedList.Extent() < 1) {
4292 SetErrorCode("Error: No history found for the sought shape or its sub-shapes.");
4296 Standard_Integer nbFound = aModifiedList.Extent();
4297 TColStd_ListIteratorOfListOfInteger anIterModif (aModifiedList);
4300 // remove sub-shapes inappropriate for group creation
4301 TopAbs_ShapeEnum subType = TopAbs_SHAPE;
4302 while ( anIterModif.More() ) {
4303 TopAbs_ShapeEnum type = aWhereIndices( anIterModif.Value() ).ShapeType();
4304 bool okForGroup = ( type == TopAbs_VERTEX || type == TopAbs_EDGE ||
4305 type == TopAbs_FACE || type == TopAbs_SOLID );
4307 if ( subType == TopAbs_SHAPE )
4310 okForGroup = ( subType == type );
4315 aModifiedList.Remove( anIterModif );
4316 nbFound -= ( !okForGroup );
4318 if ( nbFound == 0 ) {
4319 SetErrorCode("Error: result found but it's type is inappropriate for group creation.");
4324 Handle(TColStd_HArray1OfInteger) aModifiedArray =
4325 new TColStd_HArray1OfInteger( 1, nbFound );
4326 anIterModif.Initialize(aModifiedList);
4327 for (Standard_Integer imod = 1; anIterModif.More(); anIterModif.Next(), imod++)
4328 aModifiedArray->SetValue(imod, anIterModif.Value());
4331 Handle(GEOM_Object) aResult = GetEngine()->AddSubShape(theShapeWhere, aModifiedArray);
4332 if (aResult.IsNull()) {
4333 SetErrorCode("Error in algorithm: result found, but cannot be returned.");
4337 if (aModifiedArray->Length() > 1) {
4339 aResult->SetType(GEOM_GROUP);
4341 //Set a sub-shape type
4342 TopoDS_Shape aFirstFound = aWhereIndices.FindKey(aModifiedArray->Value(1));
4343 TopAbs_ShapeEnum aShapeType = aFirstFound.ShapeType();
4345 TDF_Label aFreeLabel = aResult->GetFreeLabel();
4346 TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aShapeType);
4349 //Make a Python command
4350 Handle(GEOM_Function) aFunction = aResult->GetFunction(1);
4352 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetInPlaceByHistory("
4353 << theShapeWhere << ", " << theShapeWhat << ")";
4359 #define MAX_TOLERANCE 1.e-7
4361 //=======================================================================
4362 //function : isSameEdge
4363 //purpose : Returns True if two edges coincide
4364 //=======================================================================
4365 static bool isSameEdge(const TopoDS_Edge& theEdge1, const TopoDS_Edge& theEdge2)
4367 TopoDS_Vertex V11, V12, V21, V22;
4368 TopExp::Vertices(theEdge1, V11, V12);
4369 TopExp::Vertices(theEdge2, V21, V22);
4370 gp_Pnt P11 = BRep_Tool::Pnt(V11);
4371 gp_Pnt P12 = BRep_Tool::Pnt(V12);
4372 gp_Pnt P21 = BRep_Tool::Pnt(V21);
4373 gp_Pnt P22 = BRep_Tool::Pnt(V22);
4374 bool coincide = false;
4376 //Check that ends of edges coincide
4377 if(P11.Distance(P21) <= MAX_TOLERANCE) {
4378 if(P12.Distance(P22) <= MAX_TOLERANCE) coincide = true;
4380 else if(P11.Distance(P22) <= MAX_TOLERANCE) {
4381 if(P12.Distance(P21) <= MAX_TOLERANCE) coincide = true;
4384 if(!coincide) return false;
4386 if (BRep_Tool::Degenerated(theEdge1))
4387 if (BRep_Tool::Degenerated(theEdge2)) return true;
4390 if (BRep_Tool::Degenerated(theEdge2)) return false;
4392 double U11, U12, U21, U22;
4393 Handle(Geom_Curve) C1 = BRep_Tool::Curve(theEdge1, U11, U12);
4394 Handle(Geom_Curve) C2 = BRep_Tool::Curve(theEdge2, U21, U22);
4395 if(C1->DynamicType() == C2->DynamicType()) return true;
4397 //Check that both edges has the same geometry
4398 double range = U12-U11;
4399 double U = U11+ range/3.0;
4400 gp_Pnt P1 = C1->Value(U); //Compute a point on one third of the edge's length
4401 U = U11+range*2.0/3.0;
4402 gp_Pnt P2 = C1->Value(U); //Compute a point on two thirds of the edge's length
4404 if(!GeomLib_Tool::Parameter(C2, P1, MAX_TOLERANCE, U) || U < U21 || U > U22)
4407 if(P1.Distance(C2->Value(U)) > MAX_TOLERANCE) return false;
4409 if(!GeomLib_Tool::Parameter(C2, P2, MAX_TOLERANCE, U) || U < U21 || U > U22)
4412 if(P2.Distance(C2->Value(U)) > MAX_TOLERANCE) return false;
4417 #include <TopoDS_TShape.hxx>
4418 //=======================================================================
4419 //function : isSameFace
4420 //purpose : Returns True if two faces coincide
4421 //=======================================================================
4422 static bool isSameFace(const TopoDS_Face& theFace1, const TopoDS_Face& theFace2)
4424 TopExp_Explorer E(theFace1, TopAbs_EDGE);
4425 TopTools_ListOfShape LS1, LS2;
4426 for(; E.More(); E.Next()) LS1.Append(E.Current());
4428 E.Init(theFace2, TopAbs_EDGE);
4429 for(; E.More(); E.Next()) LS2.Append(E.Current());
4431 //Compare the number of edges in the faces
4432 if(LS1.Extent() != LS2.Extent()) return false;
4434 double aMin = RealFirst(), aMax = RealLast();
4435 double xminB1=aMax, yminB1=aMax, zminB1=aMax, xminB2=aMax, yminB2=aMax, zminB2=aMax;
4436 double xmaxB1=aMin, ymaxB1=aMin, zmaxB1=aMin, xmaxB2=aMin, ymaxB2=aMin, zmaxB2=aMin;
4438 for(E.Init(theFace1, TopAbs_VERTEX); E.More(); E.Next()) {
4439 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4440 if(P.X() < xminB1) xminB1 = P.X();
4441 if(P.Y() < yminB1) yminB1 = P.Y();
4442 if(P.Z() < zminB1) zminB1 = P.Z();
4443 if(P.X() > xmaxB1) xmaxB1 = P.X();
4444 if(P.Y() > ymaxB1) ymaxB1 = P.Y();
4445 if(P.Z() > zmaxB1) zmaxB1 = P.Z();
4448 for(E.Init(theFace2, TopAbs_VERTEX); E.More(); E.Next()) {
4449 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4450 if(P.X() < xminB2) xminB2 = P.X();
4451 if(P.Y() < yminB2) yminB2 = P.Y();
4452 if(P.Z() < zminB2) zminB2 = P.Z();
4453 if(P.X() > xmaxB2) xmaxB2 = P.X();
4454 if(P.Y() > ymaxB2) ymaxB2 = P.Y();
4455 if(P.Z() > zmaxB2) zmaxB2 = P.Z();
4458 //Compare the bounding boxes of both faces
4459 if(gp_Pnt(xminB1, yminB1, zminB1).Distance(gp_Pnt(xminB2, yminB2, zminB2)) > MAX_TOLERANCE)
4462 if(gp_Pnt(xmaxB1, ymaxB1, zmaxB1).Distance(gp_Pnt(xmaxB2, ymaxB2, zmaxB2)) > MAX_TOLERANCE)
4465 Handle(Geom_Surface) S1 = BRep_Tool::Surface(theFace1);
4466 Handle(Geom_Surface) S2 = BRep_Tool::Surface(theFace2);
4468 //Check if there a coincidence of two surfaces at least in two points
4469 double U11, U12, V11, V12, U21, U22, V21, V22;
4470 BRepTools::UVBounds(theFace1, U11, U12, V11, V12);
4471 BRepTools::UVBounds(theFace2, U21, U22, V21, V22);
4473 double rangeU = U12-U11;
4474 double rangeV = V12-V11;
4475 double U = U11 + rangeU/3.0;
4476 double V = V11 + rangeV/3.0;
4477 gp_Pnt P1 = S1->Value(U, V);
4478 U = U11+rangeU*2.0/3.0;
4479 V = V11+rangeV*2.0/3.0;
4480 gp_Pnt P2 = S1->Value(U, V);
4482 if (!GeomLib_Tool::Parameters(S2, P1, MAX_TOLERANCE, U, V) || U < U21 || U > U22 || V < V21 || V > V22)
4485 if (P1.Distance(S2->Value(U,V)) > MAX_TOLERANCE) return false;
4487 if (!GeomLib_Tool::Parameters(S2, P2, MAX_TOLERANCE, U, V) || U < U21 || U > U22 || V < V21 || V > V22)
4490 if (P2.Distance(S2->Value(U, V)) > MAX_TOLERANCE) return false;
4492 //Check that each edge of the Face1 has a counterpart in the Face2
4493 TopTools_MapOfOrientedShape aMap;
4494 TopTools_ListIteratorOfListOfShape LSI1(LS1);
4495 for(; LSI1.More(); LSI1.Next()) {
4496 TopoDS_Edge E = TopoDS::Edge(LSI1.Value());
4497 bool isFound = false;
4498 TopTools_ListIteratorOfListOfShape LSI2(LS2);
4499 for(; LSI2.More(); LSI2.Next()) {
4500 TopoDS_Shape aValue = LSI2.Value();
4501 if(aMap.Contains(aValue)) continue; //To avoid checking already found edge several times
4502 if(isSameEdge(E, TopoDS::Edge(aValue))) {
4508 if(!isFound) return false;
4514 //=======================================================================
4515 //function : isSameSolid
4516 //purpose : Returns True if two solids coincide
4517 //=======================================================================
4518 bool isSameSolid(const TopoDS_Solid& theSolid1, const TopoDS_Solid& theSolid2)
4520 TopExp_Explorer E(theSolid1, TopAbs_FACE);
4521 TopTools_ListOfShape LS1, LS2;
4522 for(; E.More(); E.Next()) LS1.Append(E.Current());
4523 E.Init(theSolid2, TopAbs_FACE);
4524 for(; E.More(); E.Next()) LS2.Append(E.Current());
4526 if(LS1.Extent() != LS2.Extent()) return false;
4528 double aMin = RealFirst(), aMax = RealLast();
4529 double xminB1=aMax, yminB1=aMax, zminB1=aMax, xminB2=aMax, yminB2=aMax, zminB2=aMax;
4530 double xmaxB1=aMin, ymaxB1=aMin, zmaxB1=aMin, xmaxB2=aMin, ymaxB2=aMin, zmaxB2=aMin;
4532 for(E.Init(theSolid1, TopAbs_VERTEX); E.More(); E.Next()) {
4533 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4534 if(P.X() < xminB1) xminB1 = P.X();
4535 if(P.Y() < yminB1) yminB1 = P.Y();
4536 if(P.Z() < zminB1) zminB1 = P.Z();
4537 if(P.X() > xmaxB1) xmaxB1 = P.X();
4538 if(P.Y() > ymaxB1) ymaxB1 = P.Y();
4539 if(P.Z() > zmaxB1) zmaxB1 = P.Z();
4542 for(E.Init(theSolid2, TopAbs_VERTEX); E.More(); E.Next()) {
4543 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4544 if(P.X() < xminB2) xminB2 = P.X();
4545 if(P.Y() < yminB2) yminB2 = P.Y();
4546 if(P.Z() < zminB2) zminB2 = P.Z();
4547 if(P.X() > xmaxB2) xmaxB2 = P.X();
4548 if(P.Y() > ymaxB2) ymaxB2 = P.Y();
4549 if(P.Z() > zmaxB2) zmaxB2 = P.Z();
4552 //Compare the bounding boxes of both solids
4553 if(gp_Pnt(xminB1, yminB1, zminB1).Distance(gp_Pnt(xminB2, yminB2, zminB2)) > MAX_TOLERANCE)
4556 if(gp_Pnt(xmaxB1, ymaxB1, zmaxB1).Distance(gp_Pnt(xmaxB2, ymaxB2, zmaxB2)) > MAX_TOLERANCE)
4559 //Check that each face of the Solid1 has a counterpart in the Solid2
4560 TopTools_MapOfOrientedShape aMap;
4561 TopTools_ListIteratorOfListOfShape LSI1(LS1);
4562 for(; LSI1.More(); LSI1.Next()) {
4563 TopoDS_Face F = TopoDS::Face(LSI1.Value());
4564 bool isFound = false;
4565 TopTools_ListIteratorOfListOfShape LSI2(LS2);
4566 for(; LSI2.More(); LSI2.Next()) {
4567 if(aMap.Contains(LSI2.Value())) continue; //To avoid checking already found faces several times
4568 if(isSameFace(F, TopoDS::Face(LSI2.Value()))) {
4569 aMap.Add(LSI2.Value());
4574 if(!isFound) return false;
4580 //=======================================================================
4581 //function : GetSame
4583 //=======================================================================
4584 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetSame(const Handle(GEOM_Object)& theShapeWhere,
4585 const Handle(GEOM_Object)& theShapeWhat)
4588 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
4590 TopoDS_Shape aWhere = theShapeWhere->GetValue();
4591 TopoDS_Shape aWhat = theShapeWhat->GetValue();
4593 if (aWhere.IsNull() || aWhat.IsNull()) return NULL;
4596 bool isFound = false;
4597 TopoDS_Shape aSubShape;
4598 TopTools_MapOfShape aMap;
4600 if (aWhat.ShapeType() == TopAbs_COMPOUND || aWhat.ShapeType() == TopAbs_COMPSOLID) {
4601 TopoDS_Iterator It (aWhat, Standard_True, Standard_True);
4602 if (It.More()) aWhat = It.Value();
4605 SetErrorCode("Compounds of two or more shapes are not allowed for aWhat argument");
4610 switch (aWhat.ShapeType()) {
4611 case TopAbs_VERTEX: {
4612 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(aWhat));
4613 TopExp_Explorer E(aWhere, TopAbs_VERTEX);
4614 for(; E.More(); E.Next()) {
4615 if(!aMap.Add(E.Current())) continue;
4616 gp_Pnt P2 = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4617 if(P.Distance(P2) <= MAX_TOLERANCE) {
4619 aSubShape = E.Current();
4626 TopoDS_Edge anEdge = TopoDS::Edge(aWhat);
4627 TopExp_Explorer E(aWhere, TopAbs_EDGE);
4628 for(; E.More(); E.Next()) {
4629 if(!aMap.Add(E.Current())) continue;
4630 if(isSameEdge(anEdge, TopoDS::Edge(E.Current()))) {
4631 aSubShape = E.Current();
4639 TopoDS_Face aFace = TopoDS::Face(aWhat);
4640 TopExp_Explorer E(aWhere, TopAbs_FACE);
4641 for(; E.More(); E.Next()) {
4642 if(!aMap.Add(E.Current())) continue;
4643 if(isSameFace(aFace, TopoDS::Face(E.Current()))) {
4644 aSubShape = E.Current();
4651 case TopAbs_SOLID: {
4652 TopoDS_Solid aSolid = TopoDS::Solid(aWhat);
4653 TopExp_Explorer E(aWhere, TopAbs_SOLID);
4654 for(; E.More(); E.Next()) {
4655 if(!aMap.Add(E.Current())) continue;
4656 if(isSameSolid(aSolid, TopoDS::Solid(E.Current()))) {
4657 aSubShape = E.Current();
4669 TopTools_IndexedMapOfShape anIndices;
4670 TopExp::MapShapes(aWhere, anIndices);
4671 if (anIndices.Contains(aSubShape))
4672 anIndex = anIndices.FindIndex(aSubShape);
4675 if (anIndex < 0) return NULL;
4677 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
4679 anArray->SetValue(1, anIndex);
4681 Handle(GEOM_Object) aResult = GetEngine()->AddSubShape(theShapeWhere, anArray);
4682 Handle(GEOM_Function) aFunction = aResult->GetLastFunction();
4684 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetSame("
4685 << theShapeWhere << ", " << theShapeWhat << ")";
4693 //=======================================================================
4694 //function : GetSameIDs
4696 //=======================================================================
4697 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetSameIDs
4698 (const Handle(GEOM_Object)& theShapeWhere,
4699 const Handle(GEOM_Object)& theShapeWhat)
4702 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
4704 TopoDS_Shape aWhere = theShapeWhere->GetValue();
4705 TopoDS_Shape aWhat = theShapeWhat->GetValue();
4707 if (aWhere.IsNull() || aWhat.IsNull()) return NULL;
4709 TopTools_ListOfShape listShape;
4710 TopTools_MapOfShape aMap;
4712 if (aWhat.ShapeType() == TopAbs_COMPOUND || aWhat.ShapeType() == TopAbs_COMPSOLID) {
4713 TopoDS_Iterator It (aWhat, Standard_True, Standard_True);
4714 if (It.More()) aWhat = It.Value();
4717 SetErrorCode("Compounds of two or more shapes are not allowed for aWhat argument");
4722 switch (aWhat.ShapeType()) {
4723 case TopAbs_VERTEX: {
4724 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(aWhat));
4725 TopExp_Explorer E(aWhere, TopAbs_VERTEX);
4726 for(; E.More(); E.Next()) {
4727 if(!aMap.Add(E.Current())) continue;
4728 gp_Pnt P2 = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4729 if(P.Distance(P2) <= MAX_TOLERANCE) {
4730 listShape.Append(E.Current());
4736 TopoDS_Edge anEdge = TopoDS::Edge(aWhat);
4737 TopExp_Explorer E(aWhere, TopAbs_EDGE);
4738 for(; E.More(); E.Next()) {
4739 if(!aMap.Add(E.Current())) continue;
4740 if(isSameEdge(anEdge, TopoDS::Edge(E.Current()))) {
4741 listShape.Append(E.Current());
4747 TopoDS_Face aFace = TopoDS::Face(aWhat);
4748 TopExp_Explorer E(aWhere, TopAbs_FACE);
4749 for(; E.More(); E.Next()) {
4750 if(!aMap.Add(E.Current())) continue;
4751 if(isSameFace(aFace, TopoDS::Face(E.Current()))) {
4752 listShape.Append(E.Current());
4757 case TopAbs_SOLID: {
4758 TopoDS_Solid aSolid = TopoDS::Solid(aWhat);
4759 TopExp_Explorer E(aWhere, TopAbs_SOLID);
4760 for(; E.More(); E.Next()) {
4761 if(!aMap.Add(E.Current())) continue;
4762 if(isSameSolid(aSolid, TopoDS::Solid(E.Current()))) {
4763 listShape.Append(E.Current());
4772 if ( !listShape.IsEmpty() ) {
4773 TopTools_IndexedMapOfShape anIndices;
4774 TopExp::MapShapes(aWhere, anIndices);
4775 TopTools_ListIteratorOfListOfShape itSub (listShape);
4776 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
4777 for (; itSub.More(); itSub.Next()) {
4778 if (anIndices.Contains(itSub.Value()))
4779 aSeq->Append(anIndices.FindIndex(itSub.Value()));
4782 // The GetSameIDs() doesn't change object so no new function is required.
4783 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShapeWhere,theShapeWhat)->GetLastFunction();
4785 // Make a Python command
4786 GEOM::TPythonDump(aFunction, /*append=*/true)
4787 << "listSameIDs = geompy.GetSameIDs("
4788 << theShapeWhere << ", "
4789 << theShapeWhat << ")";
4792 SetErrorCode(NOT_FOUND_ANY);