1 // Copyright (C) 2007-2014 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 // File : GEOMImpl_IShapesOperations.cxx
25 // Author : modified by Lioka RAZAFINDRAZAKA (CEA) 22/06/2007
28 #include <Standard_Stream.hxx>
30 #include "GEOMImpl_IShapesOperations.hxx"
32 #include "GEOMImpl_Types.hxx"
34 #include "GEOMImpl_VectorDriver.hxx"
35 #include "GEOMImpl_ShapeDriver.hxx"
36 #include "GEOMImpl_GlueDriver.hxx"
38 #include "GEOMImpl_IVector.hxx"
39 #include "GEOMImpl_IShapes.hxx"
40 #include "GEOMImpl_IGlue.hxx"
42 #include "GEOMImpl_Block6Explorer.hxx"
43 #include "GEOMImpl_IHealingOperations.hxx"
45 #include "GEOMImpl_Gen.hxx"
47 #include "GEOM_Function.hxx"
48 #include "GEOM_ISubShape.hxx"
49 #include "GEOM_PythonDump.hxx"
51 #include "GEOMUtils.hxx"
53 #include "GEOMAlgo_ClsfBox.hxx"
54 #include "GEOMAlgo_ClsfSolid.hxx"
55 #include "GEOMAlgo_CoupleOfShapes.hxx"
56 #include "GEOMAlgo_FinderShapeOn1.hxx"
57 #include "GEOMAlgo_FinderShapeOnQuad.hxx"
58 #include "GEOMAlgo_FinderShapeOn2.hxx"
59 #include "GEOMAlgo_GetInPlace.hxx"
60 #include "GEOMAlgo_GlueDetector.hxx"
61 #include "GEOMAlgo_ListIteratorOfListOfCoupleOfShapes.hxx"
62 #include "GEOMAlgo_ListOfCoupleOfShapes.hxx"
64 #include <Basics_OCCTVersion.hxx>
66 #include <utilities.h>
68 #include <Utils_ExceptHandlers.hxx>
70 #include <BRepAdaptor_Curve.hxx>
71 #include <BRepAdaptor_Surface.hxx>
72 #include <BRepBndLib.hxx>
73 #include <BRepBuilderAPI_MakeVertex.hxx>
74 #include <BRepClass3d_SolidClassifier.hxx>
75 #include <BRepClass_FaceClassifier.hxx>
76 #include <BRepExtrema_DistShapeShape.hxx>
77 #include <BRepExtrema_ExtCF.hxx>
78 #include <BRepGProp.hxx>
79 #include <BRepMesh_IncrementalMesh.hxx>
80 #include <BRepTools.hxx>
81 #include <BRep_Builder.hxx>
82 #include <BRep_Tool.hxx>
83 #include <Bnd_Box.hxx>
84 #include <GEOMImpl_IMeasure.hxx>
85 #include <GEOMImpl_MeasureDriver.hxx>
86 #include <GProp_GProps.hxx>
87 #include <Geom2d_Curve.hxx>
88 #include <GeomAdaptor_Surface.hxx>
89 #include <GeomLib_Tool.hxx>
90 #include <Geom_CylindricalSurface.hxx>
91 #include <Geom_Plane.hxx>
92 #include <Geom_SphericalSurface.hxx>
93 #include <Geom_Surface.hxx>
94 #include <Precision.hxx>
95 #include <TColStd_Array1OfReal.hxx>
96 #include <TColStd_HArray1OfInteger.hxx>
97 #include <TColStd_ListIteratorOfListOfInteger.hxx>
98 #include <TColStd_ListOfInteger.hxx>
99 #include <TDF_Tool.hxx>
100 #include <TDataStd_Integer.hxx>
101 #include <TDataStd_IntegerArray.hxx>
102 #include <TDataStd_ListIteratorOfListOfExtendedString.hxx>
103 #include <TFunction_Driver.hxx>
104 #include <TFunction_DriverTable.hxx>
105 #include <TFunction_Logbook.hxx>
106 #include <TopAbs.hxx>
107 #include <TopExp.hxx>
108 #include <TopExp_Explorer.hxx>
109 #include <TopLoc_Location.hxx>
110 #include <TopTools_Array1OfShape.hxx>
111 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
112 #include <TopTools_IndexedMapOfShape.hxx>
113 #include <TopTools_ListIteratorOfListOfShape.hxx>
114 #include <TopTools_MapOfOrientedShape.hxx>
115 #include <TopTools_MapOfShape.hxx>
116 #include <TopTools_SequenceOfShape.hxx>
117 #include <TopoDS.hxx>
118 #include <TopoDS_Compound.hxx>
119 #include <TopoDS_Edge.hxx>
120 #include <TopoDS_Face.hxx>
121 #include <TopoDS_Iterator.hxx>
122 #include <TopoDS_Shape.hxx>
123 #include <TopoDS_Solid.hxx>
124 #include <TopoDS_Vertex.hxx>
125 #include <gp_Cylinder.hxx>
126 #include <gp_Lin.hxx>
127 #include <gp_Pnt.hxx>
131 #include <functional>
133 #include <Standard_NullObject.hxx>
134 #include <Standard_Failure.hxx>
135 #include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
138 //=============================================================================
142 //=============================================================================
143 GEOMImpl_IShapesOperations::GEOMImpl_IShapesOperations (GEOM_Engine* theEngine, int theDocID)
144 : GEOM_IOperations(theEngine, theDocID)
146 MESSAGE("GEOMImpl_IShapesOperations::GEOMImpl_IShapesOperations");
149 //=============================================================================
153 //=============================================================================
154 GEOMImpl_IShapesOperations::~GEOMImpl_IShapesOperations()
156 MESSAGE("GEOMImpl_IShapesOperations::~GEOMImpl_IShapesOperations");
159 //=============================================================================
163 //=============================================================================
164 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeEdge
165 (Handle(GEOM_Object) thePnt1, Handle(GEOM_Object) thePnt2)
169 if (thePnt1.IsNull() || thePnt2.IsNull()) return NULL;
171 //Add a new Edge object
172 Handle(GEOM_Object) anEdge = GetEngine()->AddObject(GetDocID(), GEOM_EDGE);
174 //Add a new Vector function
175 Handle(GEOM_Function) aFunction =
176 anEdge->AddFunction(GEOMImpl_VectorDriver::GetID(), VECTOR_TWO_PNT);
178 //Check if the function is set correctly
179 if (aFunction->GetDriverGUID() != GEOMImpl_VectorDriver::GetID()) return NULL;
181 GEOMImpl_IVector aPI (aFunction);
183 Handle(GEOM_Function) aRef1 = thePnt1->GetLastFunction();
184 Handle(GEOM_Function) aRef2 = thePnt2->GetLastFunction();
185 if (aRef1.IsNull() || aRef2.IsNull()) return NULL;
187 aPI.SetPoint1(aRef1);
188 aPI.SetPoint2(aRef2);
190 //Compute the Edge value
193 if (!GetSolver()->ComputeFunction(aFunction)) {
194 SetErrorCode("Vector driver failed");
198 catch (Standard_Failure) {
199 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
200 SetErrorCode(aFail->GetMessageString());
204 //Make a Python command
205 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdge("
206 << thePnt1 << ", " << thePnt2 << ")";
212 //=============================================================================
214 * MakeEdgeOnCurveByLength
216 //=============================================================================
217 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeEdgeOnCurveByLength
218 (Handle(GEOM_Object) theRefCurve,
219 const Standard_Real theLength,
220 Handle(GEOM_Object) theStartPoint)
224 if (theRefCurve.IsNull()) return NULL;
226 //Add a new Edge object
227 Handle(GEOM_Object) anEdge = GetEngine()->AddObject(GetDocID(), GEOM_EDGE);
229 //Add a new Vector function
230 Handle(GEOM_Function) aFunction =
231 anEdge->AddFunction(GEOMImpl_ShapeDriver::GetID(), EDGE_CURVE_LENGTH);
233 //Check if the function is set correctly
234 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
236 GEOMImpl_IVector aPI (aFunction);
238 Handle(GEOM_Function) aRef1 = theRefCurve->GetLastFunction();
239 if (aRef1.IsNull()) return NULL;
240 aPI.SetPoint1(aRef1);
242 if (!theStartPoint.IsNull()) {
243 Handle(GEOM_Function) aRef2 = theStartPoint->GetLastFunction();
244 aPI.SetPoint2(aRef2);
247 aPI.SetParameter(theLength);
249 //Compute the Edge value
252 if (!GetSolver()->ComputeFunction(aFunction)) {
253 SetErrorCode("Vector driver failed");
257 catch (Standard_Failure) {
258 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
259 SetErrorCode(aFail->GetMessageString());
263 //Make a Python command
264 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdgeOnCurveByLength("
265 << theRefCurve << ", " << theLength << ", " << theStartPoint << ")";
271 //=============================================================================
275 //=============================================================================
276 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeEdgeWire
277 (Handle(GEOM_Object) theWire,
278 const Standard_Real theLinearTolerance,
279 const Standard_Real theAngularTolerance)
283 if (theWire.IsNull()) return NULL;
285 //Add a new Edge object
286 Handle(GEOM_Object) anEdge = GetEngine()->AddObject(GetDocID(), GEOM_EDGE);
288 //Add a new Vector function
289 Handle(GEOM_Function) aFunction =
290 anEdge->AddFunction(GEOMImpl_ShapeDriver::GetID(), EDGE_WIRE);
292 //Check if the function is set correctly
293 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
295 GEOMImpl_IShapes aCI (aFunction);
297 Handle(GEOM_Function) aWire = theWire->GetLastFunction();
299 if (aWire.IsNull()) return NULL;
302 aCI.SetTolerance(theLinearTolerance);
303 aCI.SetAngularTolerance(theAngularTolerance);
305 //Compute the Edge value
308 if (!GetSolver()->ComputeFunction(aFunction)) {
309 SetErrorCode("Shape driver failed");
313 catch (Standard_Failure) {
314 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
315 SetErrorCode(aFail->GetMessageString());
319 const double DEF_LIN_TOL = Precision::Confusion();
320 const double DEF_ANG_TOL = Precision::Angular();
321 //Make a Python command
322 if ( theAngularTolerance == DEF_ANG_TOL ) {
323 if ( theLinearTolerance == DEF_LIN_TOL )
324 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdgeWire("
327 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdgeWire("
328 << theWire << ", " << theLinearTolerance << ")";
331 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdgeWire("
332 << theWire << ", " << theLinearTolerance << ", "
333 << theAngularTolerance << ")";
340 //=============================================================================
344 //=============================================================================
345 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeWire
346 (std::list<Handle(GEOM_Object)> theShapes,
347 const Standard_Real theTolerance)
352 Handle(GEOM_Object) aWire = GetEngine()->AddObject(GetDocID(), GEOM_WIRE);
355 Handle(GEOM_Function) aFunction =
356 aWire->AddFunction(GEOMImpl_ShapeDriver::GetID(), WIRE_EDGES);
357 if (aFunction.IsNull()) return NULL;
359 //Check if the function is set correctly
360 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
362 GEOMImpl_IShapes aCI (aFunction);
363 aCI.SetTolerance(theTolerance);
365 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
368 std::list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
369 for (; it != theShapes.end(); it++) {
370 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
371 if (aRefSh.IsNull()) {
372 SetErrorCode("NULL argument shape for the shape construction");
375 aShapesSeq->Append(aRefSh);
377 aCI.SetShapes(aShapesSeq);
382 if (!GetSolver()->ComputeFunction(aFunction)) {
383 SetErrorCode("Shape driver failed");
387 catch (Standard_Failure) {
388 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
389 SetErrorCode(aFail->GetMessageString());
393 //Make a Python command
394 GEOM::TPythonDump pd (aFunction);
395 pd << aWire << " = geompy.MakeWire([";
398 it = theShapes.begin();
399 if (it != theShapes.end()) {
401 while (it != theShapes.end()) {
402 pd << ", " << (*it++);
405 pd << "], " << theTolerance << ")";
411 //=============================================================================
415 //=============================================================================
416 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFace (Handle(GEOM_Object) theWire,
417 const bool isPlanarWanted)
421 if (theWire.IsNull()) return NULL;
423 //Add a new Face object
424 Handle(GEOM_Object) aFace = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
426 //Add a new Shape function for creation of a face from a wire
427 Handle(GEOM_Function) aFunction =
428 aFace->AddFunction(GEOMImpl_ShapeDriver::GetID(), FACE_WIRE);
429 if (aFunction.IsNull()) return NULL;
431 //Check if the function is set correctly
432 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
434 GEOMImpl_IShapes aCI (aFunction);
436 Handle(GEOM_Function) aRefWire = theWire->GetLastFunction();
438 if (aRefWire.IsNull()) return NULL;
440 aCI.SetBase(aRefWire);
441 aCI.SetIsPlanar(isPlanarWanted);
443 //Compute the Face value
444 Standard_Boolean isWarning = Standard_False;
447 if (!GetSolver()->ComputeFunction(aFunction)) {
448 SetErrorCode("Shape driver failed to compute a face");
452 catch (Standard_Failure) {
453 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
454 SetErrorCode(aFail->GetMessageString());
455 // to provide warning
456 if (!aFunction->GetValue().IsNull()) {
457 isWarning = Standard_True;
463 //Make a Python command
464 GEOM::TPythonDump(aFunction) << aFace << " = geompy.MakeFace("
465 << theWire << ", " << (int)isPlanarWanted << ")";
467 // to provide warning
468 if (!isWarning) SetErrorCode(OK);
472 //=============================================================================
476 //=============================================================================
477 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFaceWires
478 (std::list<Handle(GEOM_Object)> theShapes,
479 const bool isPlanarWanted)
484 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
487 Handle(GEOM_Function) aFunction =
488 aShape->AddFunction(GEOMImpl_ShapeDriver::GetID(), FACE_WIRES);
489 if (aFunction.IsNull()) return NULL;
491 //Check if the function is set correctly
492 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
494 GEOMImpl_IShapes aCI (aFunction);
496 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
499 std::list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
500 for (; it != theShapes.end(); it++) {
501 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
502 if (aRefSh.IsNull()) {
503 SetErrorCode("NULL argument shape for the face construction");
506 aShapesSeq->Append(aRefSh);
508 aCI.SetShapes(aShapesSeq);
510 aCI.SetIsPlanar(isPlanarWanted);
513 Standard_Boolean isWarning = Standard_False;
516 if (!GetSolver()->ComputeFunction(aFunction)) {
517 SetErrorCode("Shape driver failed");
521 catch (Standard_Failure) {
522 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
523 SetErrorCode(aFail->GetMessageString());
524 // to provide warning
525 if (!aFunction->GetValue().IsNull()) {
526 isWarning = Standard_True;
532 //Make a Python command
533 GEOM::TPythonDump pd (aFunction);
534 pd << aShape << " = geompy.MakeFaceWires([";
537 it = theShapes.begin();
538 if (it != theShapes.end()) {
540 while (it != theShapes.end()) {
541 pd << ", " << (*it++);
544 pd << "], " << (int)isPlanarWanted << ")";
546 // to provide warning
547 if (!isWarning) SetErrorCode(OK);
551 //=============================================================================
553 * MakeFaceFromSurface
555 //=============================================================================
556 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFaceFromSurface
557 (Handle(GEOM_Object) theFace,
558 Handle(GEOM_Object) theWire)
563 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
566 Handle(GEOM_Function) aFunction =
567 aShape->AddFunction(GEOMImpl_ShapeDriver::GetID(), FACE_FROM_SURFACE);
569 if (aFunction.IsNull()) {
573 //Check if the function is set correctly
574 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) {
578 GEOMImpl_IShapes aCI (aFunction);
579 Handle(TColStd_HSequenceOfTransient) aShapesSeq =
580 new TColStd_HSequenceOfTransient;
581 Handle(GEOM_Function) aRefFace = theFace->GetLastFunction();
582 Handle(GEOM_Function) aRefWire = theWire->GetLastFunction();
584 if (aRefFace.IsNull()) {
585 SetErrorCode("NULL argument face for the face construction");
589 if (aRefWire.IsNull()) {
590 SetErrorCode("NULL argument wire for the face construction");
594 aShapesSeq->Append(aRefFace);
595 aShapesSeq->Append(aRefWire);
597 aCI.SetShapes(aShapesSeq);
602 if (!GetSolver()->ComputeFunction(aFunction)) {
603 SetErrorCode("Shape driver failed");
607 catch (Standard_Failure) {
608 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
609 SetErrorCode(aFail->GetMessageString());
613 //Make a Python command
614 GEOM::TPythonDump (aFunction) << aShape
615 << " = geompy.MakeFaceFromSurface(" << theFace << ", " << theWire << ")";
622 //=============================================================================
626 //=============================================================================
627 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeShell
628 (std::list<Handle(GEOM_Object)> theShapes)
630 return MakeShape(theShapes, GEOM_SHELL, SHELL_FACES, "MakeShell");
633 //=============================================================================
637 //=============================================================================
638 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeSolidShells
639 (std::list<Handle(GEOM_Object)> theShapes)
641 return MakeShape(theShapes, GEOM_SOLID, SOLID_SHELLS, "MakeSolid");
644 //=============================================================================
648 //=============================================================================
649 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeCompound
650 (std::list<Handle(GEOM_Object)> theShapes)
652 return MakeShape(theShapes, GEOM_COMPOUND, COMPOUND_SHAPES, "MakeCompound");
655 //=============================================================================
659 //=============================================================================
660 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeShape
661 (std::list<Handle(GEOM_Object)> theShapes,
662 const Standard_Integer theObjectType,
663 const Standard_Integer theFunctionType,
664 const TCollection_AsciiString& theMethodName)
669 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), theObjectType);
672 Handle(GEOM_Function) aFunction =
673 aShape->AddFunction(GEOMImpl_ShapeDriver::GetID(), theFunctionType);
674 if (aFunction.IsNull()) return NULL;
676 //Check if the function is set correctly
677 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
679 GEOMImpl_IShapes aCI (aFunction);
681 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
684 std::list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
685 for (; it != theShapes.end(); it++) {
686 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
687 if (aRefSh.IsNull()) {
688 SetErrorCode("NULL argument shape for the shape construction");
691 aShapesSeq->Append(aRefSh);
693 aCI.SetShapes(aShapesSeq);
698 if (!GetSolver()->ComputeFunction(aFunction)) {
699 SetErrorCode("Shape driver failed");
703 catch (Standard_Failure) {
704 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
705 SetErrorCode(aFail->GetMessageString());
709 //Make a Python command
710 GEOM::TPythonDump pd (aFunction);
711 pd << aShape << " = geompy." << theMethodName.ToCString() << "([";
714 it = theShapes.begin();
715 if (it != theShapes.end()) {
717 while (it != theShapes.end()) {
718 pd << ", " << (*it++);
727 //=============================================================================
731 //=============================================================================
733 GEOMImpl_IShapesOperations::MakeGlueFaces (std::list< Handle(GEOM_Object) >& theShapes,
734 const Standard_Real theTolerance,
735 const Standard_Boolean doKeepNonSolids)
739 Handle(TColStd_HSequenceOfTransient) objects = GEOM_Object::GetLastFunctions( theShapes );
740 if ( objects.IsNull() || objects->IsEmpty() ) {
741 SetErrorCode("NULL argument shape");
745 //Add a new Glued object
746 Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
748 //Add a new Glue function
749 Handle(GEOM_Function) aFunction;
750 aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_FACES);
751 if (aFunction.IsNull()) return NULL;
753 //Check if the function is set correctly
754 if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
756 GEOMImpl_IGlue aCI (aFunction);
758 aCI.SetBase( objects );
759 aCI.SetTolerance(theTolerance);
760 aCI.SetKeepNonSolids(doKeepNonSolids);
762 //Compute the sub-shape value
763 Standard_Boolean isWarning = Standard_False;
766 if (!GetSolver()->ComputeFunction(aFunction)) {
767 SetErrorCode("Shape driver failed to glue faces");
771 catch (Standard_Failure) {
772 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
773 SetErrorCode(aFail->GetMessageString());
774 // to provide warning
775 if (!aFunction->GetValue().IsNull()) {
776 isWarning = Standard_True;
782 //Make a Python command
783 GEOM::TPythonDump(aFunction) << aGlued << " = geompy.MakeGlueFaces("
784 << theShapes << ", " << theTolerance << ")";
786 // to provide warning
787 if (!isWarning) SetErrorCode(OK);
791 //=============================================================================
795 //=============================================================================
797 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetGlueFaces
798 (Handle(GEOM_Object) theShape,
799 const Standard_Real theTolerance)
803 if (theShape.IsNull()) return NULL;
804 TopoDS_Shape aShape = theShape->GetValue();
805 if (aShape.IsNull()) return NULL;
807 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
809 Standard_Integer iErr;
811 GEOMAlgo_Gluer1 aGluer;
812 GEOMAlgo_ListIteratorOfListOfCoupleOfShapes aItCS;
813 GEOMAlgo_CoupleOfShapes aCS;
814 GEOMAlgo_ListOfCoupleOfShapes aLCS;
816 //aGluer = new GEOMAlgo_Gluer1;
817 aGluer.SetShape(aShape);
818 aGluer.SetTolerance(theTolerance);
820 iErr = aGluer.ErrorStatus();
821 if (iErr) return NULL;
823 TopTools_ListOfShape listShape;
824 const GEOMAlgo_ListOfCoupleOfShapes& aLCSG = aGluer.GluedFaces();
826 aItCS.Initialize(aLCSG);
827 for (; aItCS.More(); aItCS.Next()) {
828 const GEOMAlgo_CoupleOfShapes& aCSG = aItCS.Value();
829 listShape.Append(aCSG.Shape1());
832 TopTools_ListIteratorOfListOfShape itSub (listShape);
833 TCollection_AsciiString anAsciiList, anEntry;
834 TopTools_IndexedMapOfShape anIndices;
835 TopExp::MapShapes(aShape, anIndices);
836 Handle(TColStd_HArray1OfInteger) anArray;
837 Handle(GEOM_Object) anObj;
838 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
839 TopoDS_Shape aValue = itSub.Value();
840 anArray = new TColStd_HArray1OfInteger(1,1);
841 anArray->SetValue(1, anIndices.FindIndex(aValue));
842 anObj = GetEngine()->AddSubShape(theShape, anArray);
843 if (!anObj.IsNull()) {
846 // for python command
847 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
848 anAsciiList += anEntry;
853 //Make a Python command
854 if( anAsciiList.Length() > 0 ) {
855 anAsciiList.Trunc(anAsciiList.Length() - 1);
856 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
857 GEOM::TPythonDump pd (aFunction, true);
858 pd << "[" << anAsciiList.ToCString();
859 pd << "] = geompy.GetGlueFaces(" << theShape << ", " << theTolerance << ")";
868 //=============================================================================
870 * MakeGlueFacesByList
872 //=============================================================================
874 GEOMImpl_IShapesOperations::MakeGlueFacesByList(std::list< Handle(GEOM_Object) >& theShapes,
875 const Standard_Real theTolerance,
876 std::list<Handle(GEOM_Object)> & theFaces,
877 const Standard_Boolean doKeepNonSolids,
878 const Standard_Boolean doGlueAllEdges)
882 Handle(TColStd_HSequenceOfTransient) objects = GEOM_Object::GetLastFunctions( theShapes );
883 if ( objects.IsNull() || objects->IsEmpty() ) {
884 SetErrorCode("NULL argument shape");
887 Handle(TColStd_HSequenceOfTransient) aFaces = GEOM_Object::GetLastFunctions( theFaces );
888 if ( aFaces.IsNull() ) {
889 SetErrorCode("NULL argument shape for the shape construction");
893 //Add a new Glued object
894 Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
896 //Add a new Glue function
897 Handle(GEOM_Function) aFunction;
898 aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_FACES_BY_LIST);
899 if (aFunction.IsNull()) return NULL;
901 //Check if the function is set correctly
902 if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
904 GEOMImpl_IGlue aCI (aFunction);
906 aCI.SetBase( objects );
907 aCI.SetTolerance(theTolerance);
908 aCI.SetKeepNonSolids(doKeepNonSolids);
909 aCI.SetGlueAllEdges(doGlueAllEdges);
910 aCI.SetFaces(aFaces);
912 //Compute the sub-shape value
913 Standard_Boolean isWarning = Standard_False;
916 if (!GetSolver()->ComputeFunction(aFunction)) {
917 SetErrorCode("Shape driver failed to glue faces");
921 catch (Standard_Failure) {
922 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
923 SetErrorCode(aFail->GetMessageString());
924 // to provide warning
925 if (!aFunction->GetValue().IsNull()) {
926 isWarning = Standard_True;
932 //Make a Python command
934 GEOM::TPythonDump pd(aFunction);
935 pd << aGlued << " = geompy.MakeGlueFacesByList("
936 << theShapes << ", " << theTolerance << ", " << theFaces << ", "
937 << (bool)doKeepNonSolids << ", " << (bool)doGlueAllEdges << ")";
939 // to provide warning
940 if (!isWarning) SetErrorCode(OK);
944 //=============================================================================
948 //=============================================================================
950 GEOMImpl_IShapesOperations::MakeGlueEdges (std::list< Handle(GEOM_Object) >& theShapes,
951 const Standard_Real theTolerance)
955 Handle(TColStd_HSequenceOfTransient) objects = GEOM_Object::GetLastFunctions( theShapes );
956 if ( objects.IsNull() || objects->IsEmpty() ) {
957 SetErrorCode("NULL argument shape");
961 //Add a new Glued object
962 Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
964 //Add a new Glue function
965 Handle(GEOM_Function) aFunction;
966 aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_EDGES);
967 if (aFunction.IsNull()) return NULL;
969 //Check if the function is set correctly
970 if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
972 GEOMImpl_IGlue aCI (aFunction);
974 aCI.SetBase( objects );
975 aCI.SetTolerance(theTolerance);
976 aCI.SetKeepNonSolids(true);
978 //Compute the sub-shape value
979 Standard_Boolean isWarning = Standard_False;
982 if (!GetSolver()->ComputeFunction(aFunction)) {
983 SetErrorCode("Shape driver failed to glue edges");
987 catch (Standard_Failure) {
988 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
989 SetErrorCode(aFail->GetMessageString());
990 // to provide warning
991 if (!aFunction->GetValue().IsNull()) {
992 isWarning = Standard_True;
998 //Make a Python command
999 GEOM::TPythonDump(aFunction) << aGlued << " = geompy.MakeGlueEdges("
1000 << theShapes << ", " << theTolerance << ")";
1002 // to provide warning
1003 if (!isWarning) SetErrorCode(OK);
1007 //=============================================================================
1011 //=============================================================================
1012 Handle(TColStd_HSequenceOfTransient)
1013 GEOMImpl_IShapesOperations::GetGlueShapes (std::list< Handle(GEOM_Object) >& theShapes,
1014 const Standard_Real theTolerance,
1015 const TopAbs_ShapeEnum theType)
1019 TopoDS_Shape aShape;
1020 TopTools_SequenceOfShape shapes;
1021 std::list< Handle(GEOM_Object) >::iterator s = theShapes.begin();
1022 Handle(GEOM_Object) lastCreatedGO;
1023 for ( ; s != theShapes.end(); ++s )
1025 Handle(GEOM_Object) go = *s;
1026 if ( go.IsNull() ) return NULL;
1027 aShape = go->GetValue();
1028 if ( aShape.IsNull() ) return NULL;
1029 shapes.Append( aShape );
1030 lastCreatedGO = GEOM::GetCreatedLast( lastCreatedGO, go );
1032 if ( shapes.Length() > 1 )
1034 TopoDS_Compound compound;
1035 BRep_Builder builder;
1036 builder.MakeCompound( compound );
1037 for ( int i = 1; i <= shapes.Length(); ++i )
1038 builder.Add( compound, shapes( i ) );
1043 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1045 GEOMAlgo_GlueDetector aGluer;
1046 aGluer.SetArgument(aShape);
1047 aGluer.SetTolerance(theTolerance);
1049 Standard_Integer iErr = aGluer.ErrorStatus();
1050 if (iErr) return NULL;
1052 std::vector< TopTools_IndexedMapOfShape* > anIndices( shapes.Length(), NULL );
1053 Handle(TColStd_HArray1OfInteger) anArray;
1054 Handle(GEOM_Object) anObj;
1056 TopTools_ListOfShape listOnePerSet;
1058 const TopTools_DataMapOfShapeListOfShape& aImages = aGluer.Images();
1059 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape aItDMSLS (aImages);
1060 for (int index = 1; aItDMSLS.More(); aItDMSLS.Next(), ++index) {
1062 //const TopoDS_Shape& aSkey = aItDMSLS.Key();
1064 // list of shapes of the argument that can be glued
1065 const TopTools_ListOfShape& aLSD = aItDMSLS.Value();
1067 //listShape.Append(aLSD.First());
1068 TopoDS_Shape aValue = aLSD.First();
1070 if (aValue.ShapeType() == theType) {
1071 listOnePerSet.Append(aValue);
1075 // for stable order of returned entities
1076 GEOMUtils::SortShapes(listOnePerSet, Standard_False);
1078 TopTools_ListIteratorOfListOfShape aListIt (listOnePerSet);
1079 for (; aListIt.More(); aListIt.Next())
1081 TopoDS_Shape aValue = aListIt.Value();
1082 // find a shape to add aValue as a sub-shape
1084 s = theShapes.begin();
1085 for ( int i = 0; i < shapes.Length(); ++i, ++s )
1087 Handle(GEOM_Object) object = *s;
1088 if ( !anIndices[i] ) {
1089 anIndices[i] = new TopTools_IndexedMapOfShape;
1090 TopExp::MapShapes( object->GetValue(), *anIndices[i]);
1092 if (int index = anIndices[i]->FindIndex( aValue )) {
1093 anArray = new TColStd_HArray1OfInteger(1,1);
1094 anArray->SetValue(1, index);
1095 anObj = GetEngine()->AddSubShape( object, anArray);
1099 if (!anObj.IsNull())
1100 aSeq->Append(anObj);
1102 for ( size_t i = 0 ; i < anIndices.size(); ++i )
1103 delete anIndices[i];
1105 // Make a Python command
1106 if ( aSeq->Length() > 0)
1108 Handle(GEOM_Function) aFunction = lastCreatedGO->GetLastFunction();
1109 GEOM::TPythonDump pd (aFunction, /*append=*/true);
1111 << " = geompy." << (theType == TopAbs_FACE ? "GetGlueFaces" : "GetGlueEdges" )
1112 << "( " << theShapes << ", " << theTolerance << ")";
1120 //=============================================================================
1122 * MakeGlueEdgesByList
1124 //=============================================================================
1126 GEOMImpl_IShapesOperations::MakeGlueEdgesByList (std::list< Handle(GEOM_Object) >& theShapes,
1127 const Standard_Real theTolerance,
1128 std::list<Handle(GEOM_Object)>& theEdges)
1132 Handle(TColStd_HSequenceOfTransient) objects = GEOM_Object::GetLastFunctions( theShapes );
1133 if ( objects.IsNull() || objects->IsEmpty() ) {
1134 SetErrorCode("NULL argument shape");
1137 Handle(TColStd_HSequenceOfTransient) anEdges = GEOM_Object::GetLastFunctions( theEdges );
1138 if ( anEdges.IsNull() ) {
1139 SetErrorCode("NULL argument shape for the shape construction");
1142 //Add a new Glued object
1143 Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
1145 //Add a new Glue function
1146 Handle(GEOM_Function) aFunction;
1147 aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_EDGES_BY_LIST);
1148 if (aFunction.IsNull()) return NULL;
1150 //Check if the function is set correctly
1151 if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
1153 GEOMImpl_IGlue aCI (aFunction);
1155 aCI.SetBase( objects );
1156 aCI.SetTolerance(theTolerance);
1157 aCI.SetKeepNonSolids(true);
1158 aCI.SetFaces(anEdges);
1160 //Compute the sub-shape value
1161 Standard_Boolean isWarning = Standard_False;
1164 if (!GetSolver()->ComputeFunction(aFunction)) {
1165 SetErrorCode("Shape driver failed to glue edges");
1169 catch (Standard_Failure) {
1170 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1171 SetErrorCode(aFail->GetMessageString());
1172 // to provide warning
1173 if (!aFunction->GetValue().IsNull()) {
1174 isWarning = Standard_True;
1180 //Make a Python command
1182 GEOM::TPythonDump pd (aFunction);
1183 pd << aGlued << " = geompy.MakeGlueEdgesByList("
1184 << theShapes << ", " << theTolerance << ", " << theEdges << " )";
1186 // to provide warning
1187 if (!isWarning) SetErrorCode(OK);
1191 //=============================================================================
1193 * GetExistingSubObjects
1195 //=============================================================================
1196 Handle(TColStd_HSequenceOfTransient)
1197 GEOMImpl_IShapesOperations::GetExistingSubObjects(Handle(GEOM_Object) theShape,
1198 const Standard_Boolean theGroupsOnly)
1200 // note: this method does not return fields
1202 Standard_Integer types = theGroupsOnly ? Groups : Groups|SubShapes;
1203 Handle(TColStd_HSequenceOfTransient) results = GetExistingSubObjects(theShape, types);
1205 if (results->Length() > 0) {
1206 //Make a Python command
1207 TCollection_AsciiString anAsciiList;
1208 for (int i = 1; i <= results->Length(); i++)
1210 Handle(GEOM_BaseObject) obj = Handle(GEOM_BaseObject)::DownCast( results->Value(i));
1211 obj->GetEntryString();
1212 if ( i < results->Length() )
1216 GEOM::TPythonDump pd (theShape->GetLastFunction(), /*append=*/true);
1217 pd << "[" << anAsciiList.ToCString();
1218 pd << "] = geompy.GetExistingSubObjects(";
1219 pd << theShape << ", " << (bool)theGroupsOnly << ")";
1225 Handle(TColStd_HSequenceOfTransient)
1226 GEOMImpl_IShapesOperations::GetExistingSubObjects(Handle(GEOM_Object) theShape,
1227 const Standard_Integer theTypes)
1231 if (theShape.IsNull()) return NULL;
1233 Handle(GEOM_Function) aMainShape = theShape->GetLastFunction();
1234 if (aMainShape.IsNull()) return NULL;
1236 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1237 SetErrorCode(NOT_FOUND_ANY);
1239 if (!aMainShape->HasSubShapeReferences()) return aSeq;
1240 const TDataStd_ListOfExtendedString& aListEntries = aMainShape->GetSubShapeReferences();
1241 if (aListEntries.IsEmpty()) return aSeq;
1245 TDataStd_ListIteratorOfListOfExtendedString anIt (aListEntries);
1246 for (; anIt.More(); anIt.Next()) {
1247 TCollection_ExtendedString anEntry = anIt.Value();
1248 Standard_Integer aStrLen = anEntry.LengthOfCString();
1249 char* anEntryStr = new char[aStrLen+1];
1250 anEntry.ToUTF8CString(anEntryStr);
1251 Handle(GEOM_BaseObject) anObj = GetEngine()->GetObject(GetDocID(), anEntryStr, false);
1252 if (!anObj.IsNull() ) {
1253 bool isGroup = anObj->IsKind(STANDARD_TYPE(GEOM_Object)) && anObj->GetType() == GEOM_GROUP;
1254 bool isSubShape = anObj->IsKind(STANDARD_TYPE(GEOM_Object)) && anObj->GetType() != GEOM_GROUP;
1255 bool isField = anObj->IsKind(STANDARD_TYPE(GEOM_Field));
1256 if (theTypes & Groups && isGroup ||
1257 theTypes & SubShapes && isSubShape ||
1258 theTypes & Fields && isField) {
1259 aSeq->Append(anObj);
1262 delete [] anEntryStr;
1265 if (aSeq->Length() == 0) {
1266 SetErrorCode(NOT_FOUND_ANY);
1275 //=============================================================================
1279 //=============================================================================
1280 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::MakeExplode
1281 (Handle(GEOM_Object) theShape,
1282 const Standard_Integer theShapeType,
1283 const Standard_Boolean isSorted,
1284 const ExplodeType theExplodeType)
1288 if (theShape.IsNull()) return NULL;
1289 TopoDS_Shape aShape = theShape->GetValue();
1290 if (aShape.IsNull()) return NULL;
1292 Handle(GEOM_Function) aMainShape = theShape->GetLastFunction();
1294 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1295 Handle(GEOM_Object) anObj;
1296 TopTools_MapOfShape mapShape;
1297 TopTools_ListOfShape listShape;
1299 if (aShape.ShapeType() == TopAbs_COMPOUND &&
1300 (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
1301 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPSOLID ||
1302 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPOUND))
1304 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
1305 for (; It.More(); It.Next()) {
1306 if (mapShape.Add(It.Value())) {
1307 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
1308 TopAbs_ShapeEnum(theShapeType) == It.Value().ShapeType()) {
1309 listShape.Append(It.Value());
1314 else if (theExplodeType != EXPLODE_NEW_EXCLUDE_MAIN || aShape.ShapeType() != theShapeType) // issue 0021079
1316 TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
1317 for (; exp.More(); exp.Next())
1318 if (mapShape.Add(exp.Current()))
1319 listShape.Append(exp.Current());
1322 if (listShape.IsEmpty()) {
1323 //SetErrorCode("The given shape has no sub-shapes of the requested type");
1324 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
1329 bool isOldSorting = false;
1330 if (theExplodeType == EXPLODE_OLD_INCLUDE_MAIN)
1331 isOldSorting = true;
1332 GEOMUtils::SortShapes(listShape, isOldSorting);
1335 TopTools_IndexedMapOfShape anIndices;
1336 TopExp::MapShapes(aShape, anIndices);
1337 Handle(TColStd_HArray1OfInteger) anArray;
1339 TopTools_ListIteratorOfListOfShape itSub (listShape);
1340 TCollection_AsciiString anAsciiList, anEntry;
1341 for (int index = 1; itSub.More(); itSub.Next(), ++index)
1343 TopoDS_Shape aValue = itSub.Value();
1344 anArray = new TColStd_HArray1OfInteger(1,1);
1345 anArray->SetValue(1, anIndices.FindIndex(aValue));
1347 //anObj = GetEngine()->AddSubShape(theShape, anArray);
1349 anObj = GetEngine()->AddObject(GetDocID(), GEOM_SUBSHAPE);
1350 Handle(GEOM_Function) aFunction = anObj->AddFunction(GEOM_Object::GetSubShapeID(), 1);
1351 if (aFunction.IsNull()) return aSeq;
1353 GEOM_ISubShape aSSI (aFunction);
1354 aSSI.SetMainShape(aMainShape);
1355 aSSI.SetIndices(anArray);
1357 // Set function value directly, as we know it.
1358 // Usage of Solver here would lead to significant loss of time,
1359 // because GEOM_SubShapeDriver will build TopTools_IndexedMapOfShape
1360 // on the main shape for each being calculated sub-shape separately.
1361 aFunction->SetValue(aValue);
1363 // Put this subshape in the list of sub-shapes of theMainShape
1364 aMainShape->AddSubShapeReference(aFunction);
1367 if (!anObj.IsNull()) {
1368 aSeq->Append(anObj);
1370 // for python command
1371 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
1372 anAsciiList += anEntry;
1377 //Make a Python command
1378 anAsciiList.Trunc(anAsciiList.Length() - 1);
1380 GEOM::TPythonDump pd (aMainShape, /*append=*/true);
1381 pd << "[" << anAsciiList.ToCString() << "] = geompy.";
1382 switch (theExplodeType) {
1383 case EXPLODE_NEW_EXCLUDE_MAIN:
1384 pd << "ExtractShapes(" << theShape << ", "
1385 << TopAbs_ShapeEnum(theShapeType) << ", " << (isSorted ? "True" : "False") << ")";
1387 case EXPLODE_NEW_INCLUDE_MAIN:
1388 pd << "SubShapeAll" << (isSorted ? "SortedCentres(" : "(")
1389 << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
1391 case EXPLODE_OLD_INCLUDE_MAIN:
1392 pd << "SubShapeAll" << (isSorted ? "Sorted(" : "(")
1393 << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
1402 //=============================================================================
1406 //=============================================================================
1407 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::SubShapeAllIDs
1408 (Handle(GEOM_Object) theShape,
1409 const Standard_Integer theShapeType,
1410 const Standard_Boolean isSorted,
1411 const ExplodeType theExplodeType)
1415 if (theShape.IsNull()) return NULL;
1416 TopoDS_Shape aShape = theShape->GetValue();
1417 if (aShape.IsNull()) return NULL;
1419 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
1420 TopTools_MapOfShape mapShape;
1421 TopTools_ListOfShape listShape;
1423 if (aShape.ShapeType() == TopAbs_COMPOUND &&
1424 (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
1425 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPSOLID ||
1426 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPOUND))
1428 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
1429 for (; It.More(); It.Next()) {
1430 if (mapShape.Add(It.Value())) {
1431 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
1432 TopAbs_ShapeEnum(theShapeType) == It.Value().ShapeType()) {
1433 listShape.Append(It.Value());
1438 else if (theExplodeType != EXPLODE_NEW_EXCLUDE_MAIN || aShape.ShapeType() != theShapeType) // issue 0021079
1440 TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
1441 for (; exp.More(); exp.Next())
1442 if (mapShape.Add(exp.Current()))
1443 listShape.Append(exp.Current());
1446 if (listShape.IsEmpty()) {
1447 //SetErrorCode("The given shape has no sub-shapes of the requested type");
1448 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
1453 bool isOldSorting = false;
1454 if (theExplodeType == EXPLODE_OLD_INCLUDE_MAIN)
1455 isOldSorting = true;
1456 GEOMUtils::SortShapes(listShape, isOldSorting);
1459 TopTools_IndexedMapOfShape anIndices;
1460 TopExp::MapShapes(aShape, anIndices);
1461 Handle(TColStd_HArray1OfInteger) anArray;
1463 TopTools_ListIteratorOfListOfShape itSub (listShape);
1464 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
1465 TopoDS_Shape aValue = itSub.Value();
1466 aSeq->Append(anIndices.FindIndex(aValue));
1469 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
1471 //Make a Python command
1472 GEOM::TPythonDump pd (aFunction, /*append=*/true);
1473 pd << "listSubShapeIDs = geompy.SubShapeAll";
1474 switch (theExplodeType) {
1475 case EXPLODE_NEW_EXCLUDE_MAIN:
1477 case EXPLODE_NEW_INCLUDE_MAIN:
1478 pd << (isSorted ? "SortedCentresIDs(" : "IDs(")
1479 << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
1481 case EXPLODE_OLD_INCLUDE_MAIN:
1482 pd << (isSorted ? "SortedIDs(" : "IDs(")
1483 << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
1492 //=============================================================================
1496 //=============================================================================
1497 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetSubShape
1498 (Handle(GEOM_Object) theMainShape,
1499 const Standard_Integer theID)
1503 if (theMainShape.IsNull()) return NULL;
1505 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
1506 anArray->SetValue(1, theID);
1507 Handle(GEOM_Object) anObj = GetEngine()->AddSubShape(theMainShape, anArray,true);
1508 if (anObj.IsNull()) {
1509 SetErrorCode("Can not get a sub-shape with the given ID");
1513 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1515 //Make a Python command
1516 GEOM::TPythonDump(aFunction) << anObj << " = geompy.GetSubShape("
1517 << theMainShape << ", [" << theID << "])";
1523 //=============================================================================
1527 //=============================================================================
1528 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::MakeSubShapes
1529 (Handle(GEOM_Object) theMainShape,
1530 Handle(TColStd_HArray1OfInteger) theIndices)
1534 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1536 if (!theIndices->Length()) {
1537 SetErrorCode(NOT_FOUND_ANY);
1541 if (theMainShape.IsNull()) return NULL;
1542 TopoDS_Shape aShape = theMainShape->GetValue();
1543 if (aShape.IsNull()) return NULL;
1545 Handle(GEOM_Function) aMainShape = theMainShape->GetLastFunction();
1547 TopTools_IndexedMapOfShape anIndices;
1548 TopExp::MapShapes(aShape, anIndices);
1550 Handle(TColStd_HArray1OfInteger) anArray;
1551 Handle(GEOM_Object) anObj;
1553 TCollection_AsciiString anAsciiList, anEntry;
1554 Standard_Integer i, low = theIndices->Lower(), up = theIndices->Upper();
1555 for (i = low; i <= up; i++) {
1556 int id = theIndices->Value(i);
1557 if (1 <= id && id <= anIndices.Extent()) {
1558 TopoDS_Shape aValue = anIndices.FindKey(id);
1559 anArray = new TColStd_HArray1OfInteger(1,1);
1560 anArray->SetValue(1, id);
1562 anObj = GetEngine()->AddObject(GetDocID(), GEOM_SUBSHAPE);
1563 if (!anObj.IsNull()) {
1564 Handle(GEOM_Function) aFunction = anObj->AddFunction(GEOM_Object::GetSubShapeID(), 1);
1565 if (aFunction.IsNull()) return aSeq;
1567 GEOM_ISubShape aSSI (aFunction);
1568 aSSI.SetMainShape(aMainShape);
1569 aSSI.SetIndices(anArray);
1571 // Set function value directly, as we know it.
1572 // Usage of Solver here would lead to significant loss of time,
1573 // because GEOM_SubShapeDriver will build TopTools_IndexedMapOfShape
1574 // on the main shape for each being calculated sub-shape separately.
1575 aFunction->SetValue(aValue);
1577 // Put this sub-shape in the list of sub-shapes of theMainShape
1578 aMainShape->AddSubShapeReference(aFunction);
1580 aSeq->Append(anObj);
1582 // for python command
1583 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
1584 anAsciiList += anEntry;
1590 //Make a Python command
1591 anAsciiList.Trunc(anAsciiList.Length() - 1);
1593 GEOM::TPythonDump pd (aMainShape, /*append=*/true);
1594 pd << "[" << anAsciiList.ToCString() << "] = geompy.SubShapes("
1595 << theMainShape << ", [" ;
1596 for (i = low; i <= up - 1; i++) {
1597 pd << theIndices->Value(i) << ", ";
1599 pd << theIndices->Value(up) << "])";
1606 //=============================================================================
1610 //=============================================================================
1611 Standard_Integer GEOMImpl_IShapesOperations::GetSubShapeIndex (Handle(GEOM_Object) theMainShape,
1612 Handle(GEOM_Object) theSubShape)
1616 TopoDS_Shape aMainShape = theMainShape->GetValue();
1617 TopoDS_Shape aSubShape = theSubShape->GetValue();
1619 if (aMainShape.IsNull() || aSubShape.IsNull()) return -1;
1621 TopTools_IndexedMapOfShape anIndices;
1622 TopExp::MapShapes(aMainShape, anIndices);
1623 // if (anIndices.Contains(aSubShape)) {
1624 // SetErrorCode(OK);
1625 // return anIndices.FindIndex(aSubShape);
1627 int id = anIndices.FindIndex(aSubShape);
1638 //=============================================================================
1640 * GetSubShapeIndices
1642 //=============================================================================
1643 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetSubShapesIndices (Handle(GEOM_Object) theMainShape,
1644 std::list<Handle(GEOM_Object)> theSubShapes)
1646 MESSAGE("GEOMImpl_IShapesOperations::GetSubShapesIndices")
1649 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
1651 TopoDS_Shape aMainShape = theMainShape->GetValue();
1652 if (aMainShape.IsNull())
1654 MESSAGE("NULL main shape")
1658 TopTools_IndexedMapOfShape anIndices;
1659 TopExp::MapShapes(aMainShape, anIndices);
1661 std::list<Handle(GEOM_Object)>::iterator it;
1662 for (it=theSubShapes.begin(); it != theSubShapes.end(); ++it)
1664 TopoDS_Shape aSubShape = (*it)->GetValue();
1665 if (aSubShape.IsNull())
1667 MESSAGE("NULL subshape")
1670 int id = anIndices.FindIndex(aSubShape);
1679 //=============================================================================
1683 //=============================================================================
1684 Standard_Integer GEOMImpl_IShapesOperations::GetTopologyIndex (Handle(GEOM_Object) theMainShape,
1685 Handle(GEOM_Object) theSubShape)
1689 TopoDS_Shape aMainShape = theMainShape->GetValue();
1690 TopoDS_Shape aSubShape = theSubShape->GetValue();
1692 if (aMainShape.IsNull() || aSubShape.IsNull()) {
1693 SetErrorCode("Null argument shape given");
1698 if (aSubShape.ShapeType() == TopAbs_COMPOUND) {
1700 TopTools_ListOfShape CL;
1701 CL.Append(aMainShape);
1702 TopTools_ListIteratorOfListOfShape itC;
1703 for (itC.Initialize(CL); itC.More(); itC.Next()) {
1704 for (it.Initialize(itC.Value()); it.More(); it.Next()) {
1705 if (it.Value().ShapeType() == TopAbs_COMPOUND) {
1706 if (it.Value().IsSame(aSubShape))
1710 CL.Append(it.Value());
1715 TopExp_Explorer anExp (aMainShape, aSubShape.ShapeType());
1716 TopTools_MapOfShape M;
1717 for (; anExp.More(); anExp.Next()) {
1718 if (M.Add(anExp.Current())) {
1719 if (anExp.Current().IsSame(aSubShape))
1726 SetErrorCode("The sub-shape does not belong to the main shape");
1730 //=============================================================================
1732 * GetShapeTypeString
1734 //=============================================================================
1735 TCollection_AsciiString GEOMImpl_IShapesOperations::GetShapeTypeString (Handle(GEOM_Object) theShape)
1739 TCollection_AsciiString aTypeName ("Null Shape");
1741 TopoDS_Shape aShape = theShape->GetValue();
1742 if (aShape.IsNull())
1745 switch (aShape.ShapeType() )
1747 case TopAbs_COMPOUND:
1748 aTypeName = "Compound";
1750 case TopAbs_COMPSOLID:
1751 aTypeName = "Compound Solid";
1754 aTypeName = "Solid";
1757 aTypeName = "Shell";
1761 BRepAdaptor_Surface surf (TopoDS::Face(aShape));
1762 if (surf.GetType() == GeomAbs_Plane)
1763 aTypeName = "Plane";
1764 else if (surf.GetType() == GeomAbs_Cylinder)
1765 aTypeName = "Cylindrical Face";
1766 else if (surf.GetType() == GeomAbs_Sphere)
1767 aTypeName = "Spherical Face";
1768 else if (surf.GetType() == GeomAbs_Torus)
1769 aTypeName = "Toroidal Face";
1770 else if (surf.GetType() == GeomAbs_Cone)
1771 aTypeName = "Conical Face";
1773 aTypeName = "GEOM::FACE";
1781 BRepAdaptor_Curve curv (TopoDS::Edge(aShape));
1782 if (curv.GetType() == GeomAbs_Line) {
1783 if ((Abs(curv.FirstParameter()) >= 1E6) ||
1784 (Abs(curv.LastParameter()) >= 1E6))
1788 } else if (curv.GetType() == GeomAbs_Circle) {
1789 if (curv.IsClosed())
1790 aTypeName = "Circle";
1799 aTypeName = "Vertex";
1802 aTypeName = "Shape";
1805 aTypeName = "Shape of unknown type";
1811 //=============================================================================
1815 //=============================================================================
1816 Standard_Integer GEOMImpl_IShapesOperations::NumberOfSubShapes
1817 (Handle(GEOM_Object) theShape,
1818 const Standard_Integer theShapeType)
1821 Standard_Integer nbShapes = 0;
1823 if (theShape.IsNull()) return -1;
1824 TopoDS_Shape aShape = theShape->GetValue();
1825 if (aShape.IsNull()) return -1;
1828 TopTools_MapOfShape mapShape;
1830 if (aShape.ShapeType() == TopAbs_COMPOUND &&
1831 (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
1832 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPSOLID ||
1833 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPOUND)) {
1834 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
1835 for (; It.More(); It.Next()) {
1836 if (mapShape.Add(It.Value())) {
1837 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
1838 TopAbs_ShapeEnum(theShapeType) == It.Value().ShapeType()) {
1844 TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
1845 for (; exp.More(); exp.Next())
1846 if (mapShape.Add(exp.Current()))
1853 int iType, nbTypes [TopAbs_SHAPE];
1854 for (iType = 0; iType < TopAbs_SHAPE; ++iType)
1856 nbTypes[aShape.ShapeType()]++;
1858 TopTools_MapOfShape aMapOfShape;
1859 aMapOfShape.Add(aShape);
1860 TopTools_ListOfShape aListOfShape;
1861 aListOfShape.Append(aShape);
1863 TopTools_ListIteratorOfListOfShape itL (aListOfShape);
1864 for (; itL.More(); itL.Next()) {
1865 TopoDS_Iterator it (itL.Value());
1866 for (; it.More(); it.Next()) {
1867 TopoDS_Shape s = it.Value();
1868 if (aMapOfShape.Add(s)) {
1869 aListOfShape.Append(s);
1870 nbTypes[s.ShapeType()]++;
1875 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE)
1876 nbShapes = aMapOfShape.Extent();
1878 nbShapes = nbTypes[theShapeType];
1880 catch (Standard_Failure) {
1881 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1882 SetErrorCode(aFail->GetMessageString());
1890 //=============================================================================
1894 //=============================================================================
1895 Handle(GEOM_Object) GEOMImpl_IShapesOperations::ReverseShape(Handle(GEOM_Object) theShape)
1899 if (theShape.IsNull()) return NULL;
1902 //Add a new reversed object
1903 Handle(GEOM_Object) aReversed = GetEngine()->AddObject(GetDocID(), theShape->GetType());
1905 //Add a new Revese function
1906 Handle(GEOM_Function) aFunction;
1907 aFunction = aReversed->AddFunction(GEOMImpl_ShapeDriver::GetID(), REVERSE_ORIENTATION);
1908 if (aFunction.IsNull()) return NULL;
1910 //Check if the function is set correctly
1911 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
1913 GEOMImpl_IShapes aSI (aFunction);
1915 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
1916 if (aRefShape.IsNull()) return NULL;
1918 aSI.SetBase(aRefShape);
1920 //Compute the sub-shape value
1923 if (!GetSolver()->ComputeFunction(aFunction)) {
1924 SetErrorCode("Shape driver failed to reverse shape");
1928 catch (Standard_Failure) {
1929 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1930 SetErrorCode(aFail->GetMessageString());
1934 //Make a Python command
1935 GEOM::TPythonDump(aFunction) << aReversed
1936 << " = geompy.ChangeOrientation(" << theShape << ")";
1941 Handle(GEOM_Object) aReversed;
1943 GEOM_Engine* anEngine = GetEngine();
1944 //GEOMImpl_Gen* aGen = dynamic_cast<GEOMImpl_Gen*>(anEngine);
1945 GEOMImpl_Gen* aGen = (GEOMImpl_Gen*)anEngine;
1948 GEOMImpl_IHealingOperations* anIHealingOperations =
1949 aGen->GetIHealingOperations(GetDocID());
1950 aReversed = anIHealingOperations->ChangeOrientationCopy(theShape);
1951 SetErrorCode(anIHealingOperations->GetErrorCode());
1957 //=============================================================================
1961 //=============================================================================
1962 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetFreeFacesIDs
1963 (Handle(GEOM_Object) theShape)
1967 if (theShape.IsNull()) return NULL;
1968 TopoDS_Shape aShape = theShape->GetValue();
1969 if (aShape.IsNull()) return NULL;
1971 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
1973 TopTools_IndexedDataMapOfShapeListOfShape mapFaceBlocks;
1974 GEOMImpl_Block6Explorer::MapShapesAndAncestors
1975 (aShape, TopAbs_FACE, TopAbs_SOLID, mapFaceBlocks);
1977 Standard_Integer ind = 1, nbFaces = mapFaceBlocks.Extent();
1980 SetErrorCode("The given shape has no faces");
1984 TopTools_IndexedMapOfShape anIndices;
1985 TopExp::MapShapes(aShape, anIndices);
1987 Standard_Integer id;
1988 for (; ind <= nbFaces; ind++) {
1989 if (mapFaceBlocks.FindFromIndex(ind).Extent() != 2) {
1990 id = anIndices.FindIndex(mapFaceBlocks.FindKey(ind));
1995 //The explode doesn't change object so no new function is required.
1996 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
1998 //Make a Python command
1999 GEOM::TPythonDump(aFunction, /*append=*/true)
2000 << "listFreeFacesIDs = geompy.GetFreeFacesIDs(" << theShape << ")";
2006 //=======================================================================
2007 //function : GetSharedShapes
2009 //=======================================================================
2010 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetSharedShapes
2011 (Handle(GEOM_Object) theShape1,
2012 Handle(GEOM_Object) theShape2,
2013 const Standard_Integer theShapeType)
2017 if (theShape1.IsNull() || theShape2.IsNull()) return NULL;
2019 TopoDS_Shape aShape1 = theShape1->GetValue();
2020 TopoDS_Shape aShape2 = theShape2->GetValue();
2022 if (aShape1.IsNull() || aShape2.IsNull()) return NULL;
2024 TopTools_IndexedMapOfShape anIndices;
2025 TopExp::MapShapes(aShape1, anIndices);
2026 Handle(TColStd_HArray1OfInteger) anArray;
2028 TopTools_IndexedMapOfShape mapShape1;
2029 TopExp::MapShapes(aShape1, TopAbs_ShapeEnum(theShapeType), mapShape1);
2031 Handle(GEOM_Object) anObj;
2032 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
2033 TCollection_AsciiString anAsciiList, anEntry;
2035 TopTools_MapOfShape mapShape2;
2036 TopExp_Explorer exp (aShape2, TopAbs_ShapeEnum(theShapeType));
2037 for (; exp.More(); exp.Next()) {
2038 TopoDS_Shape aSS = exp.Current();
2039 if (mapShape2.Add(aSS) && mapShape1.Contains(aSS)) {
2040 anArray = new TColStd_HArray1OfInteger(1,1);
2041 anArray->SetValue(1, anIndices.FindIndex(aSS));
2042 anObj = GetEngine()->AddSubShape(theShape1, anArray);
2043 aSeq->Append(anObj);
2045 // for python command
2046 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
2047 anAsciiList += anEntry;
2052 if (aSeq->IsEmpty()) {
2053 SetErrorCode("The given shapes have no shared sub-shapes of the requested type");
2057 //Make a Python command
2058 anAsciiList.Trunc(anAsciiList.Length() - 1);
2060 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2062 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
2063 << "] = geompy.GetSharedShapes(" << theShape1 << ", "
2064 << theShape2 << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
2070 //=======================================================================
2071 //function : GetSharedShapes
2073 //=======================================================================
2074 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetSharedShapes
2075 (std::list<Handle(GEOM_Object)> & theShapes,
2076 const Standard_Integer theShapeType)
2080 int aLen = theShapes.size();
2081 if (aLen < 1) return NULL;
2084 std::list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
2086 Handle(GEOM_Object) aMainObj = *it;
2087 Handle(GEOM_Function) aMainShape = aMainObj->GetLastFunction();
2089 TopTools_SequenceOfShape shapeSeq;
2090 for (; it != theShapes.end(); it++, ind++) {
2091 Handle(GEOM_Function) aRefShape = (*it)->GetLastFunction();
2092 if (aRefShape.IsNull()) {
2093 SetErrorCode("NULL shape for GetSharedShapes");
2096 TopoDS_Shape aShape2 = aRefShape->GetValue();
2097 if (aShape2.IsNull()) return NULL;
2098 shapeSeq.Append( aShape2 );
2101 TopoDS_Shape aShape1 = shapeSeq.First();
2103 if ( shapeSeq.Length() == 1 )
2106 for ( TopoDS_Iterator it( aShape1); it.More(); it.Next() )
2107 shapeSeq.Append( it.Value() );
2108 aShape1 = shapeSeq.First();
2111 TopTools_IndexedMapOfShape anIndices;
2112 TopExp::MapShapes(aMainShape->GetValue(), anIndices);
2114 TopTools_IndexedMapOfShape mapSelected;
2115 TopExp::MapShapes(aShape1, TopAbs_ShapeEnum(theShapeType), mapSelected);
2117 // Find shared shapes
2119 TopoDS_Compound aCurrSelection;
2121 for ( ind = 2; ind <= shapeSeq.Length(); ind++) {
2123 TopoDS_Compound aCompound;
2124 B.MakeCompound(aCompound);
2126 const TopoDS_Shape& aShape2 = shapeSeq.Value( ind );
2128 TopTools_MapOfShape mapShape2;
2129 TopExp_Explorer exp (aShape2, TopAbs_ShapeEnum(theShapeType));
2130 for (; exp.More(); exp.Next()) {
2131 const TopoDS_Shape& aSS = exp.Current();
2132 if (mapShape2.Add(aSS) && mapSelected.Contains(aSS)) {
2133 B.Add(aCompound, aSS);
2137 mapSelected.Clear();
2138 TopExp::MapShapes(aCompound, TopAbs_ShapeEnum(theShapeType), mapSelected);
2139 aCurrSelection = aCompound;
2142 // Create GEOM_Object for each found shared shape (collected in aCurrSelection)
2143 Handle(GEOM_Object) anObj, aLastCreated;
2144 Handle(TColStd_HArray1OfInteger) anArray;
2145 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
2146 TCollection_AsciiString anAsciiList, anEntry;
2148 TopoDS_Iterator itSel (aCurrSelection, Standard_True, Standard_True);
2149 for (; itSel.More(); itSel.Next()) {
2150 anArray = new TColStd_HArray1OfInteger(1,1);
2151 anArray->SetValue(1, anIndices.FindIndex(itSel.Value()));
2152 anObj = GetEngine()->AddSubShape(aMainObj, anArray);
2153 aSeq->Append(anObj);
2155 aLastCreated = GEOM::GetCreatedLast( aLastCreated, anObj );
2157 // for python command
2158 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
2159 anAsciiList += anEntry;
2163 if (aSeq->IsEmpty()) {
2164 SetErrorCode("The given shapes have no shared sub-shapes of the requested type");
2168 // Make a Python command
2169 anAsciiList.Trunc(anAsciiList.Length() - 1);
2171 // IPAL22904: TC6.5.0: order of python commands is wrong after dump study
2172 // Get the function of the latest published object
2173 Handle(GEOM_Function) aFunction = aLastCreated->GetLastFunction();
2174 if( aFunction.IsNull() ) // just in case
2175 aFunction = aMainShape;
2177 GEOM::TPythonDump pd (aFunction, /*append=*/true);
2178 pd << "[" << anAsciiList.ToCString()
2179 << "] = geompy.GetSharedShapesMulti([";
2181 it = theShapes.begin();
2183 while (it != theShapes.end()) {
2184 pd << ", " << (*it++);
2187 pd << "], " << TopAbs_ShapeEnum(theShapeType) << ")";
2193 //=============================================================================
2197 //=============================================================================
2198 static GEOM::TPythonDump& operator<< (GEOM::TPythonDump& theDump,
2199 const GEOMAlgo_State theState)
2202 case GEOMAlgo_ST_IN:
2203 theDump << "GEOM.ST_IN";
2205 case GEOMAlgo_ST_OUT:
2206 theDump << "GEOM.ST_OUT";
2208 case GEOMAlgo_ST_ON:
2209 theDump << "GEOM.ST_ON";
2211 case GEOMAlgo_ST_ONIN:
2212 theDump << "GEOM.ST_ONIN";
2214 case GEOMAlgo_ST_ONOUT:
2215 theDump << "GEOM.ST_ONOUT";
2218 theDump << "GEOM.ST_UNKNOWN";
2224 //=======================================================================
2225 //function : checkTypeShapesOn
2227 * \brief Checks if theShapeType parameter of GetShapesOnXXX() is OK
2228 * \param theShapeType - the shape type to check
2229 * \retval bool - result of the check
2231 //=======================================================================
2232 bool GEOMImpl_IShapesOperations::checkTypeShapesOn(const Standard_Integer theShapeType)
2234 if (theShapeType != TopAbs_VERTEX &&
2235 theShapeType != TopAbs_EDGE &&
2236 theShapeType != TopAbs_FACE &&
2237 theShapeType != TopAbs_SOLID) {
2238 SetErrorCode("Only solids, vertices, edges or faces can be found by this method");
2244 //=======================================================================
2245 //function : makePlane
2247 * \brief Creates Geom_Plane
2248 * \param theAx1 - shape object defining plane parameters
2249 * \retval Handle(Geom_Surface) - resulting surface
2251 //=======================================================================
2252 Handle(Geom_Surface) GEOMImpl_IShapesOperations::makePlane(const TopoDS_Shape& anAx1)
2254 if (anAx1.ShapeType() != TopAbs_EDGE) return NULL;
2255 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
2256 TopoDS_Vertex V1, V2;
2257 TopExp::Vertices(anEdge, V1, V2, Standard_True);
2258 if (V1.IsNull() || V2.IsNull()) {
2259 SetErrorCode("Bad edge given for the plane normal vector");
2262 gp_Pnt aLoc = BRep_Tool::Pnt(V1);
2263 gp_Vec aVec (aLoc, BRep_Tool::Pnt(V2));
2264 if (aVec.Magnitude() < Precision::Confusion()) {
2265 SetErrorCode("Vector with null magnitude given");
2268 return new Geom_Plane(aLoc, aVec);
2271 //=======================================================================
2272 //function : makeCylinder
2274 * \brief Creates Geom_CylindricalSurface
2275 * \param theAx1 - edge defining cylinder axis
2276 * \param theRadius - cylinder radius
2277 * \retval Handle(Geom_Surface) - resulting surface
2279 //=======================================================================
2280 Handle(Geom_Surface) GEOMImpl_IShapesOperations::makeCylinder(const TopoDS_Shape& anAxis,
2281 const Standard_Real theRadius)
2283 //Axis of the cylinder
2284 if (anAxis.ShapeType() != TopAbs_EDGE) {
2285 SetErrorCode("Not an edge given for the axis");
2288 TopoDS_Edge anEdge = TopoDS::Edge(anAxis);
2289 TopoDS_Vertex V1, V2;
2290 TopExp::Vertices(anEdge, V1, V2, Standard_True);
2291 if (V1.IsNull() || V2.IsNull()) {
2292 SetErrorCode("Bad edge given for the axis");
2295 gp_Pnt aLoc = BRep_Tool::Pnt(V1);
2296 gp_Vec aVec (aLoc, BRep_Tool::Pnt(V2));
2297 if (aVec.Magnitude() < Precision::Confusion()) {
2298 SetErrorCode("Vector with null magnitude given");
2302 gp_Ax3 anAx3 (aLoc, aVec);
2303 return new Geom_CylindricalSurface(anAx3, theRadius);
2306 //=======================================================================
2307 //function : getShapesOnBoxIDs
2309 * \brief Find IDs of sub-shapes complying with given status about surface
2310 * \param theBox - the box to check state of sub-shapes against
2311 * \param theShape - the shape to explore
2312 * \param theShapeType - type of sub-shape of theShape
2313 * \param theState - required state
2314 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
2316 //=======================================================================
2317 Handle(TColStd_HSequenceOfInteger)
2318 GEOMImpl_IShapesOperations::getShapesOnBoxIDs(const Handle(GEOM_Object)& theBox,
2319 const Handle(GEOM_Object)& theShape,
2320 const Standard_Integer theShapeType,
2321 GEOMAlgo_State theState)
2323 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
2325 TopoDS_Shape aBox = theBox->GetValue();
2326 TopoDS_Shape aShape = theShape->GetValue();
2328 // Check presence of triangulation, build if need
2329 if (!GEOMUtils::CheckTriangulation(aShape)) {
2330 SetErrorCode("Cannot build triangulation on the shape");
2335 GEOMAlgo_FinderShapeOn2 aFinder;
2336 Standard_Real aTol = 0.0001; // default value
2338 Handle(GEOMAlgo_ClsfBox) aClsfBox = new GEOMAlgo_ClsfBox;
2339 aClsfBox->SetBox(aBox);
2341 aFinder.SetShape(aShape);
2342 aFinder.SetTolerance(aTol);
2343 aFinder.SetClsf(aClsfBox);
2344 aFinder.SetShapeType( (TopAbs_ShapeEnum)theShapeType );
2345 aFinder.SetState(theState);
2348 // Interprete results
2349 Standard_Integer iErr = aFinder.ErrorStatus();
2350 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
2352 MESSAGE(" iErr : " << iErr);
2353 TCollection_AsciiString aMsg (" iErr : ");
2354 aMsg += TCollection_AsciiString(iErr);
2358 Standard_Integer iWrn = aFinder.WarningStatus();
2359 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
2361 MESSAGE(" *** iWrn : " << iWrn);
2364 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
2366 if (listSS.Extent() < 1) {
2367 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
2368 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
2372 // Fill sequence of object IDs
2373 aSeqOfIDs = new TColStd_HSequenceOfInteger;
2375 TopTools_IndexedMapOfShape anIndices;
2376 TopExp::MapShapes(aShape, anIndices);
2378 TopTools_ListIteratorOfListOfShape itSub (listSS);
2379 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
2380 int id = anIndices.FindIndex(itSub.Value());
2381 aSeqOfIDs->Append(id);
2387 //=======================================================================
2388 //function : GetShapesOnBoxIDs
2390 * \brief Find sub-shapes complying with given status about surface
2391 * \param theBox - the box to check state of sub-shapes against
2392 * \param theShape - the shape to explore
2393 * \param theShapeType - type of sub-shape of theShape
2394 * \param theState - required state
2395 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
2397 //=======================================================================
2398 Handle(TColStd_HSequenceOfInteger)
2399 GEOMImpl_IShapesOperations::GetShapesOnBoxIDs(const Handle(GEOM_Object)& theBox,
2400 const Handle(GEOM_Object)& theShape,
2401 const Standard_Integer theShapeType,
2402 GEOMAlgo_State theState)
2404 // Find sub-shapes ids
2405 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2406 getShapesOnBoxIDs (theBox, theShape, theShapeType, theState);
2407 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2410 // The GetShapesOnBox() doesn't change object so no new function is required.
2411 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theBox)->GetLastFunction();
2413 // Make a Python command
2414 GEOM::TPythonDump(aFunction, /*append=*/true)
2415 << "listShapesOnBoxIDs = geompy.GetShapesOnBoxIDs("
2418 << TopAbs_ShapeEnum(theShapeType) << ", "
2425 //=======================================================================
2426 //function : GetShapesOnBox
2428 * \brief Find sub-shapes complying with given status about surface
2429 * \param theBox - the box to check state of sub-shapes against
2430 * \param theShape - the shape to explore
2431 * \param theShapeType - type of sub-shape of theShape
2432 * \param theState - required state
2433 * \retval Handle(TColStd_HSequenceOfTransient) - found sub-shapes
2435 //=======================================================================
2436 Handle(TColStd_HSequenceOfTransient)
2437 GEOMImpl_IShapesOperations::GetShapesOnBox(const Handle(GEOM_Object)& theBox,
2438 const Handle(GEOM_Object)& theShape,
2439 const Standard_Integer theShapeType,
2440 GEOMAlgo_State theState)
2442 // Find sub-shapes ids
2443 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2444 getShapesOnBoxIDs (theBox, theShape, theShapeType, theState);
2445 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2448 // Find objects by indices
2449 TCollection_AsciiString anAsciiList;
2450 Handle(TColStd_HSequenceOfTransient) aSeq;
2451 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
2452 if ( aSeq.IsNull() || aSeq->IsEmpty() )
2455 // Make a Python command
2457 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2458 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2460 GEOM::TPythonDump(aFunction)
2461 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnBox("
2464 << TopAbs_ShapeEnum(theShapeType) << ", "
2471 //=======================================================================
2472 //function : getShapesOnShapeIDs
2474 * \brief Find IDs of sub-shapes complying with given status about surface
2475 * \param theCheckShape - the shape to check state of sub-shapes against
2476 * \param theShape - the shape to explore
2477 * \param theShapeType - type of sub-shape of theShape
2478 * \param theState - required state
2479 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
2481 //=======================================================================
2482 Handle(TColStd_HSequenceOfInteger)
2483 GEOMImpl_IShapesOperations::getShapesOnShapeIDs
2484 (const Handle(GEOM_Object)& theCheckShape,
2485 const Handle(GEOM_Object)& theShape,
2486 const Standard_Integer theShapeType,
2487 GEOMAlgo_State theState)
2489 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
2491 TopoDS_Shape aCheckShape = theCheckShape->GetValue();
2492 TopoDS_Shape aShape = theShape->GetValue();
2493 TopTools_ListOfShape res;
2495 // Check presence of triangulation, build if need
2496 if (!GEOMUtils::CheckTriangulation(aShape)) {
2497 SetErrorCode("Cannot build triangulation on the shape");
2502 GEOMAlgo_FinderShapeOn2 aFinder;
2503 Standard_Real aTol = 0.0001; // default value
2505 Handle(GEOMAlgo_ClsfSolid) aClsfSolid = new GEOMAlgo_ClsfSolid;
2506 aClsfSolid->SetShape(aCheckShape);
2508 aFinder.SetShape(aShape);
2509 aFinder.SetTolerance(aTol);
2510 aFinder.SetClsf(aClsfSolid);
2511 aFinder.SetShapeType( (TopAbs_ShapeEnum)theShapeType );
2512 aFinder.SetState(theState);
2515 // Interprete results
2516 Standard_Integer iErr = aFinder.ErrorStatus();
2517 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
2520 SetErrorCode("theCheckShape must be a solid");
2523 MESSAGE(" iErr : " << iErr);
2524 TCollection_AsciiString aMsg (" iErr : ");
2525 aMsg += TCollection_AsciiString(iErr);
2530 Standard_Integer iWrn = aFinder.WarningStatus();
2531 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
2533 MESSAGE(" *** iWrn : " << iWrn);
2536 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
2538 if (listSS.Extent() < 1) {
2539 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
2540 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
2543 // Fill sequence of object IDs
2544 aSeqOfIDs = new TColStd_HSequenceOfInteger;
2546 TopTools_IndexedMapOfShape anIndices;
2547 TopExp::MapShapes(aShape, anIndices);
2549 TopTools_ListIteratorOfListOfShape itSub (listSS);
2550 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
2551 int id = anIndices.FindIndex(itSub.Value());
2552 aSeqOfIDs->Append(id);
2558 //=======================================================================
2559 //function : GetShapesOnShapeIDs
2561 * \brief Find sub-shapes complying with given status about surface
2562 * \param theCheckShape - the shape to check state of sub-shapes against
2563 * \param theShape - the shape to explore
2564 * \param theShapeType - type of sub-shape of theShape
2565 * \param theState - required state
2566 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
2568 //=======================================================================
2569 Handle(TColStd_HSequenceOfInteger)
2570 GEOMImpl_IShapesOperations::GetShapesOnShapeIDs
2571 (const Handle(GEOM_Object)& theCheckShape,
2572 const Handle(GEOM_Object)& theShape,
2573 const Standard_Integer theShapeType,
2574 GEOMAlgo_State theState)
2576 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2577 getShapesOnShapeIDs (theCheckShape, theShape, theShapeType, theState);
2579 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2582 // The GetShapesOnShape() doesn't change object so no new function is required.
2583 Handle(GEOM_Function) aFunction =
2584 GEOM::GetCreatedLast(theShape,theCheckShape)->GetLastFunction();
2586 // Make a Python command
2587 GEOM::TPythonDump(aFunction, /*append=*/true)
2588 << "listShapesOnBoxIDs = geompy.GetShapesOnShapeIDs("
2589 << theCheckShape << ", "
2591 << TopAbs_ShapeEnum(theShapeType) << ", "
2598 //=======================================================================
2599 //function : GetShapesOnShape
2601 * \brief Find sub-shapes complying with given status about surface
2602 * \param theCheckShape - the shape to check state of sub-shapes against
2603 * \param theShape - the shape to explore
2604 * \param theShapeType - type of sub-shape of theShape
2605 * \param theState - required state
2606 * \retval Handle(TColStd_HSequenceOfTransient) - found sub-shapes
2608 //=======================================================================
2609 Handle(TColStd_HSequenceOfTransient)
2610 GEOMImpl_IShapesOperations::GetShapesOnShape
2611 (const Handle(GEOM_Object)& theCheckShape,
2612 const Handle(GEOM_Object)& theShape,
2613 const Standard_Integer theShapeType,
2614 GEOMAlgo_State theState)
2616 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2617 getShapesOnShapeIDs (theCheckShape, theShape, theShapeType, theState);
2618 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2621 // Find objects by indices
2622 TCollection_AsciiString anAsciiList;
2623 Handle(TColStd_HSequenceOfTransient) aSeq;
2624 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
2626 if ( aSeq.IsNull() || aSeq->IsEmpty() )
2629 // Make a Python command
2631 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2632 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2634 GEOM::TPythonDump(aFunction)
2635 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnShape("
2636 << theCheckShape << ", "
2638 << TopAbs_ShapeEnum(theShapeType) << ", "
2645 //=======================================================================
2646 //function : GetShapesOnShapeAsCompound
2647 //=======================================================================
2648 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetShapesOnShapeAsCompound
2649 (const Handle(GEOM_Object)& theCheckShape,
2650 const Handle(GEOM_Object)& theShape,
2651 const Standard_Integer theShapeType,
2652 GEOMAlgo_State theState)
2654 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2655 getShapesOnShapeIDs (theCheckShape, theShape, theShapeType, theState);
2657 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2660 // Find objects by indices
2661 TCollection_AsciiString anAsciiList;
2662 Handle(TColStd_HSequenceOfTransient) aSeq;
2663 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
2665 if ( aSeq.IsNull() || aSeq->IsEmpty() )
2668 TopoDS_Compound aCompound;
2670 B.MakeCompound(aCompound);
2672 for(; i<=aSeq->Length(); i++) {
2673 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(aSeq->Value(i));
2674 TopoDS_Shape aShape_i = anObj->GetValue();
2675 B.Add(aCompound,aShape_i);
2678 //Add a new result object
2679 Handle(GEOM_Object) aRes = GetEngine()->AddObject(GetDocID(), GEOM_SHAPES_ON_SHAPE);
2680 Handle(GEOM_Function) aFunction =
2681 aRes->AddFunction(GEOMImpl_ShapeDriver::GetID(), SHAPES_ON_SHAPE);
2682 aFunction->SetValue(aCompound);
2685 aSeq->Append( theCheckShape->GetLastFunction() );
2686 aSeq->Append( theShape->GetLastFunction() );
2688 GEOMImpl_IShapes aCI( aFunction );
2689 aCI.SetShapes( aSeq );
2690 aCI.SetSubShapeType( theShapeType );
2691 aCI.SetTolerance( theState );
2693 GEOM::TPythonDump(aFunction)
2694 << aRes << " = geompy.GetShapesOnShapeAsCompound("
2695 << theCheckShape << ", "
2697 << TopAbs_ShapeEnum(theShapeType) << ", "
2705 //=======================================================================
2706 //function : getShapesOnSurfaceIDs
2708 * \brief Find IDs of sub-shapes complying with given status about surface
2709 * \param theSurface - the surface to check state of sub-shapes against
2710 * \param theShape - the shape to explore
2711 * \param theShapeType - type of sub-shape of theShape
2712 * \param theState - required state
2713 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
2715 //=======================================================================
2716 Handle(TColStd_HSequenceOfInteger)
2717 GEOMImpl_IShapesOperations::getShapesOnSurfaceIDs(const Handle(Geom_Surface)& theSurface,
2718 const TopoDS_Shape& theShape,
2719 TopAbs_ShapeEnum theShapeType,
2720 GEOMAlgo_State theState)
2722 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
2724 // Check presence of triangulation, build if need
2725 if (!GEOMUtils::CheckTriangulation(theShape)) {
2726 SetErrorCode("Cannot build triangulation on the shape");
2730 // BEGIN: Mantis issue 0020961: Error on a pipe T-Shape
2731 // Compute tolerance
2732 Standard_Real T, VertMax = -RealLast();
2735 for (TopExp_Explorer ExV (theShape, TopAbs_VERTEX); ExV.More(); ExV.Next()) {
2736 TopoDS_Vertex Vertex = TopoDS::Vertex(ExV.Current());
2737 T = BRep_Tool::Tolerance(Vertex);
2742 catch (Standard_Failure) {
2743 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2744 SetErrorCode(aFail->GetMessageString());
2747 // END: Mantis issue 0020961
2750 GEOMAlgo_FinderShapeOn1 aFinder;
2751 //Standard_Real aTol = 0.0001; // default value
2752 Standard_Real aTol = VertMax; // Mantis issue 0020961
2754 aFinder.SetShape(theShape);
2755 aFinder.SetTolerance(aTol);
2756 aFinder.SetSurface(theSurface);
2757 aFinder.SetShapeType(theShapeType);
2758 aFinder.SetState(theState);
2760 // Sets the minimal number of inner points for the faces that do not have own
2761 // inner points at all (for e.g. rectangular planar faces have just 2 triangles).
2763 aFinder.SetNbPntsMin(3);
2764 // Sets the maximal number of inner points for edges or faces.
2765 // It is usefull for the cases when this number is very big (e.g =2000) to improve
2766 // the performance. If this value =0, all inner points will be taken into account.
2768 aFinder.SetNbPntsMax(100);
2772 // Interprete results
2773 Standard_Integer iErr = aFinder.ErrorStatus();
2774 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
2776 MESSAGE(" iErr : " << iErr);
2777 TCollection_AsciiString aMsg (" iErr : ");
2778 aMsg += TCollection_AsciiString(iErr);
2782 Standard_Integer iWrn = aFinder.WarningStatus();
2783 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
2785 MESSAGE(" *** iWrn : " << iWrn);
2788 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
2790 if (listSS.Extent() < 1) {
2791 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
2792 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
2796 // Fill sequence of object IDs
2797 aSeqOfIDs = new TColStd_HSequenceOfInteger;
2799 TopTools_IndexedMapOfShape anIndices;
2800 TopExp::MapShapes(theShape, anIndices);
2802 TopTools_ListIteratorOfListOfShape itSub (listSS);
2803 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
2804 int id = anIndices.FindIndex(itSub.Value());
2805 aSeqOfIDs->Append(id);
2811 //=======================================================================
2812 //function : getObjectsShapesOn
2814 * \brief Find shape objects and their entries by their ids
2815 * \param theShapeIDs - incoming shape ids
2816 * \param theShapeEntries - outgoing entries like "entry1, entry2, ..."
2817 * \retval Handle(TColStd_HSequenceOfTransient) - found shape objects
2819 //=======================================================================
2820 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::
2821 getObjectsShapesOn(const Handle(GEOM_Object)& theShape,
2822 const Handle(TColStd_HSequenceOfInteger)& theShapeIDs,
2823 TCollection_AsciiString & theShapeEntries)
2825 Handle(TColStd_HSequenceOfTransient) aSeq;
2827 if ( !theShapeIDs.IsNull() && theShapeIDs->Length() > 0 )
2829 aSeq = new TColStd_HSequenceOfTransient;
2830 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
2831 TCollection_AsciiString anEntry;
2832 for ( int i = 1; i <= theShapeIDs->Length(); ++i )
2834 anArray->SetValue(1, theShapeIDs->Value( i ));
2835 Handle(GEOM_Object) anObj = GetEngine()->AddSubShape(theShape, anArray);
2836 aSeq->Append( anObj );
2838 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
2839 if ( i != 1 ) theShapeEntries += ",";
2840 theShapeEntries += anEntry;
2846 //=======================================================================
2847 //function : getShapesOnSurface
2849 * \brief Find sub-shapes complying with given status about surface
2850 * \param theSurface - the surface to check state of sub-shapes against
2851 * \param theShape - the shape to explore
2852 * \param theShapeType - type of sub-shape of theShape
2853 * \param theState - required state
2854 * \param theShapeEntries - outgoing entries like "entry1, entry2, ..."
2855 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
2857 //=======================================================================
2858 Handle(TColStd_HSequenceOfTransient)
2859 GEOMImpl_IShapesOperations::getShapesOnSurface(const Handle(Geom_Surface)& theSurface,
2860 const Handle(GEOM_Object)& theShape,
2861 TopAbs_ShapeEnum theShapeType,
2862 GEOMAlgo_State theState,
2863 TCollection_AsciiString & theShapeEntries)
2865 // Find sub-shapes ids
2866 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2867 getShapesOnSurfaceIDs (theSurface, theShape->GetValue(), theShapeType, theState);
2868 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2871 return getObjectsShapesOn( theShape, aSeqOfIDs, theShapeEntries );
2874 //=============================================================================
2878 //=============================================================================
2879 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnPlane
2880 (const Handle(GEOM_Object)& theShape,
2881 const Standard_Integer theShapeType,
2882 const Handle(GEOM_Object)& theAx1,
2883 const GEOMAlgo_State theState)
2887 if (theShape.IsNull() || theAx1.IsNull()) return NULL;
2889 TopoDS_Shape aShape = theShape->GetValue();
2890 TopoDS_Shape anAx1 = theAx1->GetValue();
2892 if (aShape.IsNull() || anAx1.IsNull()) return NULL;
2894 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2895 if ( !checkTypeShapesOn( theShapeType ))
2899 Handle(Geom_Surface) aPlane = makePlane( anAx1 );
2900 if ( aPlane.IsNull() )
2904 TCollection_AsciiString anAsciiList;
2905 Handle(TColStd_HSequenceOfTransient) aSeq;
2906 aSeq = getShapesOnSurface( aPlane, theShape, aShapeType, theState, anAsciiList );
2907 if ( aSeq.IsNull() || aSeq->Length() == 0 )
2910 // Make a Python command
2912 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2913 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2915 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
2916 << "] = geompy.GetShapesOnPlane(" << theShape << ", "
2917 << aShapeType << ", " << theAx1 << ", " << theState << ")";
2923 //=============================================================================
2925 * GetShapesOnPlaneWithLocation
2927 //=============================================================================
2928 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnPlaneWithLocation
2929 (const Handle(GEOM_Object)& theShape,
2930 const Standard_Integer theShapeType,
2931 const Handle(GEOM_Object)& theAx1,
2932 const Handle(GEOM_Object)& thePnt,
2933 const GEOMAlgo_State theState)
2937 if (theShape.IsNull() || theAx1.IsNull() || thePnt.IsNull()) return NULL;
2939 TopoDS_Shape aShape = theShape->GetValue();
2940 TopoDS_Shape anAx1 = theAx1->GetValue();
2941 TopoDS_Shape anPnt = thePnt->GetValue();
2943 if (aShape.IsNull() || anAx1.IsNull() || anPnt.IsNull()) return NULL;
2945 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2946 if ( !checkTypeShapesOn( theShapeType ))
2950 if ( anAx1.ShapeType() != TopAbs_EDGE || anPnt.ShapeType() != TopAbs_VERTEX ) return NULL;
2951 TopoDS_Vertex V1, V2, V3;
2952 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
2953 TopExp::Vertices(anEdge, V1, V2, Standard_True);
2955 if (V1.IsNull() || V2.IsNull()) {
2956 SetErrorCode("Bad edge given for the plane normal vector");
2959 V3 = TopoDS::Vertex(anPnt);
2962 SetErrorCode("Bad vertex given for the plane location");
2965 gp_Pnt aLoc = BRep_Tool::Pnt(V3);
2966 gp_Vec aVec(BRep_Tool::Pnt(V1),BRep_Tool::Pnt(V2));
2968 if (aVec.Magnitude() < Precision::Confusion()) {
2969 SetErrorCode("Vector with null magnitude given");
2972 Handle(Geom_Surface) aPlane = new Geom_Plane(aLoc, aVec);
2974 if ( aPlane.IsNull() )
2978 TCollection_AsciiString anAsciiList;
2979 Handle(TColStd_HSequenceOfTransient) aSeq;
2980 aSeq = getShapesOnSurface( aPlane, theShape, aShapeType, theState, anAsciiList );
2981 if ( aSeq.IsNull() || aSeq->Length() == 0 )
2984 // Make a Python command
2986 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2987 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2989 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
2990 << "] = geompy.GetShapesOnPlaneWithLocation(" << theShape << ", "
2991 << aShapeType << ", " << theAx1 << ", "<< thePnt <<", " << theState << ")";
2997 //=============================================================================
2999 * GetShapesOnCylinder
3001 //=============================================================================
3002 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnCylinder
3003 (const Handle(GEOM_Object)& theShape,
3004 const Standard_Integer theShapeType,
3005 const Handle(GEOM_Object)& theAxis,
3006 const Standard_Real theRadius,
3007 const GEOMAlgo_State theState)
3011 if (theShape.IsNull() || theAxis.IsNull()) return NULL;
3013 TopoDS_Shape aShape = theShape->GetValue();
3014 TopoDS_Shape anAxis = theAxis->GetValue();
3016 if (aShape.IsNull() || anAxis.IsNull()) return NULL;
3018 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3019 if ( !checkTypeShapesOn( aShapeType ))
3022 // Create a cylinder surface
3023 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
3024 if ( aCylinder.IsNull() )
3028 TCollection_AsciiString anAsciiList;
3029 Handle(TColStd_HSequenceOfTransient) aSeq;
3030 aSeq = getShapesOnSurface( aCylinder, theShape, aShapeType, theState, anAsciiList );
3031 if ( aSeq.IsNull() || aSeq->Length() == 0 )
3034 // Make a Python command
3036 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
3037 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
3039 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
3040 << "] = geompy.GetShapesOnCylinder(" << theShape << ", " << aShapeType
3041 << ", " << theAxis << ", " << theRadius << ", " << theState << ")";
3047 //=============================================================================
3049 * GetShapesOnCylinderWithLocation
3051 //=============================================================================
3052 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnCylinderWithLocation
3053 (const Handle(GEOM_Object)& theShape,
3054 const Standard_Integer theShapeType,
3055 const Handle(GEOM_Object)& theAxis,
3056 const Handle(GEOM_Object)& thePnt,
3057 const Standard_Real theRadius,
3058 const GEOMAlgo_State theState)
3062 if (theShape.IsNull() || theAxis.IsNull() || thePnt.IsNull()) return NULL;
3064 TopoDS_Shape aShape = theShape->GetValue();
3065 TopoDS_Shape anAxis = theAxis->GetValue();
3066 TopoDS_Shape aPnt = thePnt->GetValue();
3068 if (aShape.IsNull() || anAxis.IsNull() || aPnt.IsNull()) return NULL;
3070 if (aPnt.ShapeType() != TopAbs_VERTEX )
3072 SetErrorCode("Bottom location point must be vertex");
3076 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3077 if ( !checkTypeShapesOn( aShapeType ))
3080 // Create a cylinder surface
3081 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
3082 if ( aCylinder.IsNull() )
3085 // translate the surface
3086 Handle(Geom_CylindricalSurface) aCylSurface =
3087 Handle(Geom_CylindricalSurface)::DownCast( aCylinder );
3088 if ( aCylSurface.IsNull() )
3090 SetErrorCode("Unexpected surface type instead of Geom_CylindricalSurface");
3093 gp_Pnt fromLoc = aCylSurface->Cylinder().Location();
3094 gp_Pnt toLoc = BRep_Tool::Pnt( TopoDS::Vertex( aPnt ));
3095 aCylinder->Translate( fromLoc, toLoc );
3098 TCollection_AsciiString anAsciiList;
3099 Handle(TColStd_HSequenceOfTransient) aSeq;
3100 aSeq = getShapesOnSurface( aCylinder, theShape, aShapeType, theState, anAsciiList );
3101 if ( aSeq.IsNull() || aSeq->Length() == 0 )
3104 // Make a Python command
3106 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
3107 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
3109 GEOM::TPythonDump(aFunction)
3110 << "[" << anAsciiList.ToCString()
3111 << "] = geompy.GetShapesOnCylinderWithLocation(" << theShape << ", " << aShapeType << ", "
3112 << theAxis << ", " << thePnt << ", " << theRadius << ", " << theState << ")";
3118 //=============================================================================
3122 //=============================================================================
3123 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnSphere
3124 (const Handle(GEOM_Object)& theShape,
3125 const Standard_Integer theShapeType,
3126 const Handle(GEOM_Object)& theCenter,
3127 const Standard_Real theRadius,
3128 const GEOMAlgo_State theState)
3132 if (theShape.IsNull() || theCenter.IsNull()) return NULL;
3134 TopoDS_Shape aShape = theShape->GetValue();
3135 TopoDS_Shape aCenter = theCenter->GetValue();
3137 if (aShape.IsNull() || aCenter.IsNull()) return NULL;
3139 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3140 if ( !checkTypeShapesOn( aShapeType ))
3143 // Center of the sphere
3144 if (aCenter.ShapeType() != TopAbs_VERTEX) return NULL;
3145 gp_Pnt aLoc = BRep_Tool::Pnt(TopoDS::Vertex(aCenter));
3147 gp_Ax3 anAx3 (aLoc, gp::DZ());
3148 Handle(Geom_SphericalSurface) aSphere =
3149 new Geom_SphericalSurface(anAx3, theRadius);
3152 TCollection_AsciiString anAsciiList;
3153 Handle(TColStd_HSequenceOfTransient) aSeq;
3154 aSeq = getShapesOnSurface( aSphere, theShape, aShapeType, theState, anAsciiList );
3155 if ( aSeq.IsNull() || aSeq->Length() == 0 )
3158 // Make a Python command
3160 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
3161 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
3163 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
3164 << "] = geompy.GetShapesOnSphere(" << theShape << ", " << aShapeType
3165 << ", " << theCenter << ", " << theRadius << ", " << theState << ")";
3171 //=============================================================================
3173 * GetShapesOnPlaneIDs
3175 //=============================================================================
3176 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnPlaneIDs
3177 (const Handle(GEOM_Object)& theShape,
3178 const Standard_Integer theShapeType,
3179 const Handle(GEOM_Object)& theAx1,
3180 const GEOMAlgo_State theState)
3184 if (theShape.IsNull() || theAx1.IsNull()) return NULL;
3186 TopoDS_Shape aShape = theShape->GetValue();
3187 TopoDS_Shape anAx1 = theAx1->GetValue();
3189 if (aShape.IsNull() || anAx1.IsNull()) return NULL;
3191 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3192 if ( !checkTypeShapesOn( aShapeType ))
3196 Handle(Geom_Surface) aPlane = makePlane( anAx1 );
3197 if ( aPlane.IsNull() )
3201 Handle(TColStd_HSequenceOfInteger) aSeq;
3202 aSeq = getShapesOnSurfaceIDs( aPlane, aShape, aShapeType, theState );
3204 // The GetShapesOnPlaneIDs() doesn't change object so no new function is required.
3205 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAx1)->GetLastFunction();
3207 // Make a Python command
3208 GEOM::TPythonDump(aFunction, /*append=*/true)
3209 << "listShapesOnPlane = geompy.GetShapesOnPlaneIDs"
3210 << "(" << theShape << "," << aShapeType << "," << theAx1 << "," << theState << ")";
3216 //=============================================================================
3218 * GetShapesOnPlaneWithLocationIDs
3220 //=============================================================================
3221 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnPlaneWithLocationIDs
3222 (const Handle(GEOM_Object)& theShape,
3223 const Standard_Integer theShapeType,
3224 const Handle(GEOM_Object)& theAx1,
3225 const Handle(GEOM_Object)& thePnt,
3226 const GEOMAlgo_State theState)
3230 if (theShape.IsNull() || theAx1.IsNull() || thePnt.IsNull()) return NULL;
3232 TopoDS_Shape aShape = theShape->GetValue();
3233 TopoDS_Shape anAx1 = theAx1->GetValue();
3234 TopoDS_Shape anPnt = thePnt->GetValue();
3236 if (aShape.IsNull() || anAx1.IsNull() || anPnt.IsNull()) return NULL;
3238 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3239 if ( !checkTypeShapesOn( aShapeType ))
3243 if (anAx1.ShapeType() != TopAbs_EDGE || anPnt.ShapeType() != TopAbs_VERTEX) return NULL;
3244 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
3245 TopoDS_Vertex V1, V2, V3;
3246 TopExp::Vertices(anEdge, V1, V2, Standard_True);
3247 if (V1.IsNull() || V2.IsNull()) {
3248 SetErrorCode("Bad edge given for the plane normal vector");
3251 V3 = TopoDS::Vertex(anPnt);
3253 SetErrorCode("Bad vertex given for the plane location");
3256 gp_Pnt aLoc = BRep_Tool::Pnt(V3);
3257 gp_Vec aVec(BRep_Tool::Pnt(V1),BRep_Tool::Pnt(V2));
3258 if (aVec.Magnitude() < Precision::Confusion()) {
3259 SetErrorCode("Vector with null magnitude given");
3263 Handle(Geom_Surface) aPlane = new Geom_Plane(aLoc, aVec);
3264 if ( aPlane.IsNull() )
3268 Handle(TColStd_HSequenceOfInteger) aSeq;
3269 aSeq = getShapesOnSurfaceIDs( aPlane, aShape, aShapeType, theState );
3271 // The GetShapesOnPlaneIDs() doesn't change object so no new function is required.
3272 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAx1)->GetLastFunction();
3274 // Make a Python command
3275 GEOM::TPythonDump(aFunction, /*append=*/true)
3276 << "listShapesOnPlane = geompy.GetShapesOnPlaneWithLocationIDs"
3277 << "(" << theShape << ", " << aShapeType << ", " << theAx1 << ", "<< thePnt << ", " << theState << ")";
3283 //=============================================================================
3285 * GetShapesOnCylinderIDs
3287 //=============================================================================
3288 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnCylinderIDs
3289 (const Handle(GEOM_Object)& theShape,
3290 const Standard_Integer theShapeType,
3291 const Handle(GEOM_Object)& theAxis,
3292 const Standard_Real theRadius,
3293 const GEOMAlgo_State theState)
3297 if (theShape.IsNull() || theAxis.IsNull()) return NULL;
3299 TopoDS_Shape aShape = theShape->GetValue();
3300 TopoDS_Shape anAxis = theAxis->GetValue();
3302 if (aShape.IsNull() || anAxis.IsNull()) return NULL;
3304 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3305 if ( !checkTypeShapesOn( aShapeType ))
3308 // Create a cylinder surface
3309 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
3310 if ( aCylinder.IsNull() )
3314 Handle(TColStd_HSequenceOfInteger) aSeq;
3315 aSeq = getShapesOnSurfaceIDs( aCylinder, aShape, aShapeType, theState );
3317 // The GetShapesOnCylinder() doesn't change object so no new function is required.
3318 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAxis)->GetLastFunction();
3320 // Make a Python command
3321 GEOM::TPythonDump(aFunction, /*append=*/true)
3322 << "listShapesOnCylinder = geompy.GetShapesOnCylinderIDs"
3323 << "(" << theShape << ", " << aShapeType << ", " << theAxis << ", "
3324 << theRadius << ", " << theState << ")";
3330 //=============================================================================
3332 * GetShapesOnCylinderWithLocationIDs
3334 //=============================================================================
3335 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnCylinderWithLocationIDs
3336 (const Handle(GEOM_Object)& theShape,
3337 const Standard_Integer theShapeType,
3338 const Handle(GEOM_Object)& theAxis,
3339 const Handle(GEOM_Object)& thePnt,
3340 const Standard_Real theRadius,
3341 const GEOMAlgo_State theState)
3345 if (theShape.IsNull() || theAxis.IsNull() || thePnt.IsNull()) return NULL;
3347 TopoDS_Shape aShape = theShape->GetValue();
3348 TopoDS_Shape anAxis = theAxis->GetValue();
3349 TopoDS_Shape aPnt = thePnt->GetValue();
3351 if (aShape.IsNull() || anAxis.IsNull() || aPnt.IsNull()) return NULL;
3353 if (aPnt.ShapeType() != TopAbs_VERTEX )
3355 SetErrorCode("Bottom location point must be vertex");
3359 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3360 if ( !checkTypeShapesOn( aShapeType ))
3363 // Create a cylinder surface
3364 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
3365 if ( aCylinder.IsNull() )
3368 // translate the surface
3369 Handle(Geom_CylindricalSurface) aCylSurface =
3370 Handle(Geom_CylindricalSurface)::DownCast( aCylinder );
3371 if ( aCylSurface.IsNull() )
3373 SetErrorCode("Unexpected surface type instead of Geom_CylindricalSurface");
3376 gp_Pnt fromLoc = aCylSurface->Cylinder().Location();
3377 gp_Pnt toLoc = BRep_Tool::Pnt( TopoDS::Vertex( aPnt ));
3378 aCylinder->Translate( fromLoc, toLoc );
3381 Handle(TColStd_HSequenceOfInteger) aSeq;
3382 aSeq = getShapesOnSurfaceIDs( aCylinder, aShape, aShapeType, theState );
3384 // The GetShapesOnCylinder() doesn't change object so no new function is required.
3385 Handle(GEOM_Function) aFunction =
3386 GEOM::GetCreatedLast(theShape, GEOM::GetCreatedLast(thePnt,theAxis))->GetLastFunction();
3388 // Make a Python command
3389 GEOM::TPythonDump(aFunction, /*append=*/true)
3390 << "listShapesOnCylinder = geompy.GetShapesOnCylinderWithLocationIDs"
3391 << "(" << theShape << ", " << aShapeType << ", " << theAxis << ", "
3392 << thePnt << ", " << theRadius << ", " << theState << ")";
3398 //=============================================================================
3400 * GetShapesOnSphereIDs
3402 //=============================================================================
3403 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnSphereIDs
3404 (const Handle(GEOM_Object)& theShape,
3405 const Standard_Integer theShapeType,
3406 const Handle(GEOM_Object)& theCenter,
3407 const Standard_Real theRadius,
3408 const GEOMAlgo_State theState)
3412 if (theShape.IsNull() || theCenter.IsNull()) return NULL;
3414 TopoDS_Shape aShape = theShape->GetValue();
3415 TopoDS_Shape aCenter = theCenter->GetValue();
3417 if (aShape.IsNull() || aCenter.IsNull()) return NULL;
3419 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3420 if ( !checkTypeShapesOn( aShapeType ))
3423 // Center of the sphere
3424 if (aCenter.ShapeType() != TopAbs_VERTEX) return NULL;
3425 gp_Pnt aLoc = BRep_Tool::Pnt(TopoDS::Vertex(aCenter));
3427 gp_Ax3 anAx3 (aLoc, gp::DZ());
3428 Handle(Geom_SphericalSurface) aSphere =
3429 new Geom_SphericalSurface(anAx3, theRadius);
3432 Handle(TColStd_HSequenceOfInteger) aSeq;
3433 aSeq = getShapesOnSurfaceIDs( aSphere, aShape, aShapeType, theState );
3435 // The GetShapesOnSphere() doesn't change object so no new function is required.
3436 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theCenter)->GetLastFunction();
3438 // Make a Python command
3439 GEOM::TPythonDump(aFunction, /*append=*/true)
3440 << "listShapesOnCylinder = geompy.GetShapesOnSphereIDs"
3441 << "(" << theShape << ", " << aShapeType << ", " << theCenter << ", "
3442 << theRadius << ", " << theState << ")";
3448 //=======================================================================
3449 //function : getShapesOnQuadrangleIDs
3451 * \brief Find IDs of sub-shapes complying with given status about quadrangle
3452 * \param theShape - the shape to explore
3453 * \param theShapeType - type of sub-shape of theShape
3454 * \param theTopLeftPoint - top left quadrangle corner
3455 * \param theTopRigthPoint - top right quadrangle corner
3456 * \param theBottomLeftPoint - bottom left quadrangle corner
3457 * \param theBottomRigthPoint - bottom right quadrangle corner
3458 * \param theState - required state
3459 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
3461 //=======================================================================
3462 Handle(TColStd_HSequenceOfInteger)
3463 GEOMImpl_IShapesOperations::getShapesOnQuadrangleIDs (const Handle(GEOM_Object)& theShape,
3464 const Standard_Integer theShapeType,
3465 const Handle(GEOM_Object)& theTopLeftPoint,
3466 const Handle(GEOM_Object)& theTopRigthPoint,
3467 const Handle(GEOM_Object)& theBottomLeftPoint,
3468 const Handle(GEOM_Object)& theBottomRigthPoint,
3469 const GEOMAlgo_State theState)
3473 if ( theShape.IsNull() ||
3474 theTopLeftPoint.IsNull() ||
3475 theTopRigthPoint.IsNull() ||
3476 theBottomLeftPoint.IsNull() ||
3477 theBottomRigthPoint.IsNull() )
3480 TopoDS_Shape aShape = theShape->GetValue();
3481 TopoDS_Shape aTL = theTopLeftPoint->GetValue();
3482 TopoDS_Shape aTR = theTopRigthPoint->GetValue();
3483 TopoDS_Shape aBL = theBottomLeftPoint->GetValue();
3484 TopoDS_Shape aBR = theBottomRigthPoint->GetValue();
3486 if (aShape.IsNull() ||
3491 aTL.ShapeType() != TopAbs_VERTEX ||
3492 aTR.ShapeType() != TopAbs_VERTEX ||
3493 aBL.ShapeType() != TopAbs_VERTEX ||
3494 aBR.ShapeType() != TopAbs_VERTEX )
3497 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3498 if ( !checkTypeShapesOn( aShapeType ))
3501 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
3503 // Check presence of triangulation, build if need
3504 if (!GEOMUtils::CheckTriangulation(aShape)) {
3505 SetErrorCode("Cannot build triangulation on the shape");
3510 gp_Pnt aPntTL = BRep_Tool::Pnt(TopoDS::Vertex(aTL));
3511 gp_Pnt aPntTR = BRep_Tool::Pnt(TopoDS::Vertex(aTR));
3512 gp_Pnt aPntBL = BRep_Tool::Pnt(TopoDS::Vertex(aBL));
3513 gp_Pnt aPntBR = BRep_Tool::Pnt(TopoDS::Vertex(aBR));
3515 GEOMAlgo_FinderShapeOnQuad aFinder( aPntTL, aPntTR, aPntBL, aPntBR );
3516 Standard_Real aTol = 0.0001; // default value
3518 aFinder.SetShape(aShape);
3519 aFinder.SetTolerance(aTol);
3520 //aFinder.SetSurface(theSurface);
3521 aFinder.SetShapeType(aShapeType);
3522 aFinder.SetState(theState);
3524 // Sets the minimal number of inner points for the faces that do not have own
3525 // inner points at all (for e.g. rectangular planar faces have just 2 triangles).
3527 aFinder.SetNbPntsMin(3);
3528 // Sets the maximal number of inner points for edges or faces.
3529 // It is usefull for the cases when this number is very big (e.g =2000) to improve
3530 // the performance. If this value =0, all inner points will be taken into account.
3532 aFinder.SetNbPntsMax(100);
3536 // Interprete results
3537 Standard_Integer iErr = aFinder.ErrorStatus();
3538 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
3540 MESSAGE(" iErr : " << iErr);
3541 TCollection_AsciiString aMsg (" iErr : ");
3542 aMsg += TCollection_AsciiString(iErr);
3546 Standard_Integer iWrn = aFinder.WarningStatus();
3547 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
3549 MESSAGE(" *** iWrn : " << iWrn);
3552 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
3554 if (listSS.Extent() < 1) {
3555 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
3556 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
3560 // Fill sequence of object IDs
3561 aSeqOfIDs = new TColStd_HSequenceOfInteger;
3563 TopTools_IndexedMapOfShape anIndices;
3564 TopExp::MapShapes(aShape, anIndices);
3566 TopTools_ListIteratorOfListOfShape itSub (listSS);
3567 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
3568 int id = anIndices.FindIndex(itSub.Value());
3569 aSeqOfIDs->Append(id);
3574 //=======================================================================
3575 //function : GetShapesOnQuadrangle
3577 * \brief Find sub-shapes complying with given status about quadrangle
3578 * \param theShape - the shape to explore
3579 * \param theShapeType - type of sub-shape of theShape
3580 * \param theTopLeftPoint - top left quadrangle corner
3581 * \param theTopRigthPoint - top right quadrangle corner
3582 * \param theBottomLeftPoint - bottom left quadrangle corner
3583 * \param theBottomRigthPoint - bottom right quadrangle corner
3584 * \param theState - required state
3585 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
3587 //=======================================================================
3588 Handle(TColStd_HSequenceOfTransient)
3589 GEOMImpl_IShapesOperations::GetShapesOnQuadrangle (const Handle(GEOM_Object)& theShape,
3590 const Standard_Integer theShapeType,
3591 const Handle(GEOM_Object)& theTopLeftPoint,
3592 const Handle(GEOM_Object)& theTopRigthPoint,
3593 const Handle(GEOM_Object)& theBottomLeftPoint,
3594 const Handle(GEOM_Object)& theBottomRigthPoint,
3595 const GEOMAlgo_State theState)
3598 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
3599 getShapesOnQuadrangleIDs( theShape,
3604 theBottomRigthPoint,
3606 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->IsEmpty() )
3609 // Find objects by indices
3610 TCollection_AsciiString anAsciiList;
3611 Handle(TColStd_HSequenceOfTransient) aSeq;
3612 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
3613 if ( aSeq.IsNull() || aSeq->IsEmpty() )
3616 // Make a Python command
3618 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
3619 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
3621 GEOM::TPythonDump(aFunction)
3622 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnQuadrangle("
3624 << TopAbs_ShapeEnum(theShapeType) << ", "
3625 << theTopLeftPoint << ", "
3626 << theTopRigthPoint << ", "
3627 << theBottomLeftPoint << ", "
3628 << theBottomRigthPoint << ", "
3635 //=======================================================================
3636 //function : GetShapesOnQuadrangleIDs
3638 * \brief Find IDs of sub-shapes complying with given status about quadrangle
3639 * \param theShape - the shape to explore
3640 * \param theShapeType - type of sub-shape of theShape
3641 * \param theTopLeftPoint - top left quadrangle corner
3642 * \param theTopRigthPoint - top right quadrangle corner
3643 * \param theBottomLeftPoint - bottom left quadrangle corner
3644 * \param theBottomRigthPoint - bottom right quadrangle corner
3645 * \param theState - required state
3646 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
3648 //=======================================================================
3649 Handle(TColStd_HSequenceOfInteger)
3650 GEOMImpl_IShapesOperations::GetShapesOnQuadrangleIDs (const Handle(GEOM_Object)& theShape,
3651 const Standard_Integer theShapeType,
3652 const Handle(GEOM_Object)& theTopLeftPoint,
3653 const Handle(GEOM_Object)& theTopRigthPoint,
3654 const Handle(GEOM_Object)& theBottomLeftPoint,
3655 const Handle(GEOM_Object)& theBottomRigthPoint,
3656 const GEOMAlgo_State theState)
3659 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
3660 getShapesOnQuadrangleIDs( theShape,
3665 theBottomRigthPoint,
3667 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->IsEmpty() )
3670 // Make a Python command
3672 // The GetShapesOnCylinder() doesn't change object so no new function is required.
3673 Handle(GEOM_Object) lastObj = GEOM::GetCreatedLast(theShape,theTopLeftPoint);
3674 lastObj = GEOM::GetCreatedLast(lastObj,theTopRigthPoint);
3675 lastObj = GEOM::GetCreatedLast(lastObj,theBottomRigthPoint);
3676 lastObj = GEOM::GetCreatedLast(lastObj,theBottomLeftPoint);
3677 Handle(GEOM_Function) aFunction = lastObj->GetLastFunction();
3679 GEOM::TPythonDump(aFunction, /*append=*/true)
3680 << "listShapesOnQuadrangle = geompy.GetShapesOnQuadrangleIDs("
3682 << TopAbs_ShapeEnum(theShapeType) << ", "
3683 << theTopLeftPoint << ", "
3684 << theTopRigthPoint << ", "
3685 << theBottomLeftPoint << ", "
3686 << theBottomRigthPoint << ", "
3693 //=============================================================================
3697 //=============================================================================
3698 static bool GetInPlaceOfShape (const Handle(GEOM_Function)& theWhereFunction,
3699 const TopTools_IndexedMapOfShape& theWhereIndices,
3700 const TopoDS_Shape& theWhat,
3701 TColStd_ListOfInteger& theModifiedList)
3703 if (theWhereFunction.IsNull() || theWhat.IsNull()) return false;
3705 if (theWhereIndices.Contains(theWhat)) {
3706 // entity was not changed by the operation
3707 Standard_Integer aWhatIndex = theWhereIndices.FindIndex(theWhat);
3708 theModifiedList.Append(aWhatIndex);
3712 // try to find in history
3713 TDF_Label aHistoryLabel = theWhereFunction->GetHistoryEntry(Standard_False);
3715 // search in history for all argument shapes
3716 Standard_Boolean isFound = Standard_False;
3717 Standard_Boolean isGood = Standard_False;
3719 TDF_LabelSequence aLabelSeq;
3720 theWhereFunction->GetDependency(aLabelSeq);
3721 Standard_Integer nbArg = aLabelSeq.Length();
3723 for (Standard_Integer iarg = 1; iarg <= nbArg && !isFound; iarg++) {
3725 TDF_Label anArgumentRefLabel = aLabelSeq.Value(iarg);
3727 Handle(GEOM_Object) anArgumentObject = GEOM_Object::GetReferencedObject(anArgumentRefLabel);
3728 TopoDS_Shape anArgumentShape = anArgumentObject->GetValue();
3730 TopTools_IndexedMapOfShape anArgumentIndices;
3731 TopExp::MapShapes(anArgumentShape, anArgumentIndices);
3733 if (anArgumentIndices.Contains(theWhat)) {
3734 isFound = Standard_True;
3735 Standard_Integer aWhatIndex = anArgumentIndices.FindIndex(theWhat);
3737 // Find corresponding label in history
3738 TDF_Label anArgumentHistoryLabel =
3739 theWhereFunction->GetArgumentHistoryEntry(anArgumentRefLabel, Standard_False);
3740 if (anArgumentHistoryLabel.IsNull()) {
3741 // Lost History of operation argument. Possibly, all its entities was removed.
3742 isGood = Standard_True;
3745 TDF_Label aWhatHistoryLabel = anArgumentHistoryLabel.FindChild(aWhatIndex, Standard_False);
3747 if (aWhatHistoryLabel.IsNull()) {
3748 // Removed entity ? Compound ? Compsolid ? Shell ? Wire
3749 isGood = Standard_False;
3751 Handle(TDataStd_IntegerArray) anIntegerArray;
3752 if (!aWhatHistoryLabel.FindAttribute(TDataStd_IntegerArray::GetID(), anIntegerArray)) {
3753 //Error: Empty modifications history for the sought shape.
3754 isGood = Standard_False;
3757 isGood = Standard_True;
3758 Standard_Integer imod, aModifLen = anIntegerArray->Array()->Length();
3759 for (imod = 1; imod <= aModifLen; imod++) {
3760 theModifiedList.Append(anIntegerArray->Array()->Value(imod));
3771 // try compound/compsolid/shell/wire element by element
3772 bool isFoundAny = false;
3773 TopTools_MapOfShape mapShape;
3775 if (theWhat.ShapeType() == TopAbs_COMPOUND ||
3776 theWhat.ShapeType() == TopAbs_COMPSOLID) {
3777 // recursive processing of compound/compsolid
3778 TopoDS_Iterator anIt (theWhat, Standard_True, Standard_True);
3779 for (; anIt.More(); anIt.Next()) {
3780 if (mapShape.Add(anIt.Value())) {
3781 TopoDS_Shape curWhat = anIt.Value();
3782 isFoundAny = GetInPlaceOfShape(theWhereFunction, theWhereIndices, curWhat, theModifiedList);
3783 if (isFoundAny) isFound = Standard_True;
3787 else if (theWhat.ShapeType() == TopAbs_SHELL) {
3788 // try to replace a shell by its faces images
3789 TopExp_Explorer anExp (theWhat, TopAbs_FACE);
3790 for (; anExp.More(); anExp.Next()) {
3791 if (mapShape.Add(anExp.Current())) {
3792 TopoDS_Shape curWhat = anExp.Current();
3793 isFoundAny = GetInPlaceOfShape(theWhereFunction, theWhereIndices, curWhat, theModifiedList);
3794 if (isFoundAny) isFound = Standard_True;
3798 else if (theWhat.ShapeType() == TopAbs_WIRE) {
3799 // try to replace a wire by its edges images
3800 TopExp_Explorer anExp (theWhat, TopAbs_EDGE);
3801 for (; anExp.More(); anExp.Next()) {
3802 if (mapShape.Add(anExp.Current())) {
3803 TopoDS_Shape curWhat = anExp.Current();
3804 isFoundAny = GetInPlaceOfShape(theWhereFunction, theWhereIndices, curWhat, theModifiedList);
3805 if (isFoundAny) isFound = Standard_True;
3817 //=============================================================================
3819 * GetShapeProperties
3821 //=============================================================================
3822 void GEOMImpl_IShapesOperations::GetShapeProperties( const TopoDS_Shape aShape, Standard_Real tab[],
3825 GProp_GProps theProps;
3827 //TopoDS_Shape aPntShape;
3828 Standard_Real aShapeSize;
3830 if (aShape.ShapeType() == TopAbs_VERTEX) aCenterMass = BRep_Tool::Pnt( TopoDS::Vertex( aShape ) );
3831 else if (aShape.ShapeType() == TopAbs_EDGE) BRepGProp::LinearProperties(aShape, theProps);
3832 else if (aShape.ShapeType() == TopAbs_FACE) BRepGProp::SurfaceProperties(aShape, theProps);
3833 else BRepGProp::VolumeProperties(aShape, theProps);
3835 if (aShape.ShapeType() == TopAbs_VERTEX)
3838 aCenterMass = theProps.CentreOfMass();
3839 aShapeSize = theProps.Mass();
3842 // aPntShape = BRepBuilderAPI_MakeVertex(aCenterMass).Shape();
3843 // aVertex = BRep_Tool::Pnt( TopoDS::Vertex( aPntShape ) );
3844 aVertex = aCenterMass;
3845 tab[0] = aVertex.X();
3846 tab[1] = aVertex.Y();
3847 tab[2] = aVertex.Z();
3848 tab[3] = aShapeSize;
3854 //================================================================================
3856 * \brief Return normal to face at extrema point
3858 //================================================================================
3860 gp_Vec GetNormal (const TopoDS_Face& face, const BRepExtrema_DistShapeShape& extrema)
3862 gp_Vec defaultNorm(1,0,0); // to have same normals on different faces
3864 // get UV at extrema point
3865 Standard_Real u,v, f,l;
3866 switch ( extrema.SupportTypeShape2(1) ) {
3867 case BRepExtrema_IsInFace: {
3868 extrema.ParOnFaceS2(1, u, v );
3871 case BRepExtrema_IsOnEdge: {
3872 TopoDS_Edge edge = TopoDS::Edge( extrema.SupportOnShape2(1));
3873 Handle(Geom2d_Curve) pcurve = BRep_Tool::CurveOnSurface( edge, face, f,l );
3874 extrema.ParOnEdgeS2( 1, u );
3875 gp_Pnt2d uv = pcurve->Value( u );
3880 case BRepExtrema_IsVertex: return defaultNorm;
3883 BRepAdaptor_Surface surface( face, false );
3884 gp_Vec du, dv; gp_Pnt p;
3885 surface.D1( u, v, p, du, dv );
3889 } catch (Standard_Failure ) {
3895 //=============================================================================
3900 //=============================================================================
3901 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlace (Handle(GEOM_Object) theShapeWhere,
3902 Handle(GEOM_Object) theShapeWhat)
3906 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
3908 TopoDS_Shape aWhere = theShapeWhere->GetValue();
3909 TopoDS_Shape aWhat = theShapeWhat->GetValue();
3911 if (aWhere.IsNull() || aWhat.IsNull()) {
3912 SetErrorCode("Error: aWhere and aWhat TopoDS_Shape are Null.");
3916 // Compute confusion tolerance.
3917 Standard_Real aTolConf = Precision::Confusion();
3920 for (i = 0; i < 2; ++i) {
3921 TopExp_Explorer anExp(i == 0 ? aWhere : aWhat, TopAbs_VERTEX);
3923 for (; anExp.More(); anExp.Next()) {
3924 const TopoDS_Vertex aVtx = TopoDS::Vertex(anExp.Current());
3925 const Standard_Real aTolVtx = BRep_Tool::Tolerance(aVtx);
3927 if (aTolVtx > aTolConf) {
3933 // Compute mass tolerance.
3934 Bnd_Box aBoundingBox;
3935 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
3936 Standard_Real aMassTol;
3938 BRepBndLib::Add(aWhere, aBoundingBox);
3939 BRepBndLib::Add(aWhat, aBoundingBox);
3940 aBoundingBox.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
3941 aMassTol = Max(aXmax - aXmin, aYmax - aYmin);
3942 aMassTol = Max(aMassTol, aZmax - aZmin);
3943 aMassTol *= aTolConf;
3945 // Searching for the sub-shapes inside the ShapeWhere shape
3946 GEOMAlgo_GetInPlace aGIP;
3947 aGIP.SetTolerance(aTolConf);
3948 aGIP.SetTolMass(aMassTol);
3949 aGIP.SetTolCG(aTolConf);
3951 aGIP.SetArgument(aWhat);
3952 aGIP.SetShapeWhere(aWhere);
3955 int iErr = aGIP.ErrorStatus();
3957 SetErrorCode("Error in GEOMAlgo_GetInPlace");
3961 // Add direct result.
3962 TopTools_ListOfShape aLSA;
3963 const TopoDS_Shape &aShapeResult = aGIP.Result();
3964 TopTools_MapOfShape aMFence;
3965 TopTools_IndexedMapOfShape aWhereIndices;
3967 TopExp::MapShapes(aWhere, aWhereIndices);
3969 if (aShapeResult.IsNull() == Standard_False) {
3970 TopoDS_Iterator anIt(aShapeResult);
3972 for (; anIt.More(); anIt.Next()) {
3973 const TopoDS_Shape &aPart = anIt.Value();
3975 if(aWhereIndices.Contains(aPart) && aMFence.Add(aPart)) {
3981 if (aLSA.Extent() == 0) {
3982 SetErrorCode(NOT_FOUND_ANY); // Not found any Results
3986 Handle(TColStd_HArray1OfInteger) aModifiedArray = new TColStd_HArray1OfInteger (1, aLSA.Extent());
3987 TopTools_ListIteratorOfListOfShape anIterModif (aLSA);
3988 for (Standard_Integer imod = 1; anIterModif.More(); anIterModif.Next(), imod++) {
3989 if (aWhereIndices.Contains(anIterModif.Value())) {
3990 aModifiedArray->SetValue(imod, aWhereIndices.FindIndex(anIterModif.Value()));
3993 SetErrorCode("Error: wrong sub-shape returned");
3999 Handle(GEOM_Object) aResult = GetEngine()->AddSubShape(theShapeWhere, aModifiedArray);
4000 if (aResult.IsNull()) {
4001 SetErrorCode("Error in algorithm: result found, but cannot be returned.");
4005 if (aModifiedArray->Length() > 1 || theShapeWhat->GetType() == GEOM_GROUP) {
4007 aResult->SetType(GEOM_GROUP);
4009 //Set a sub-shape type
4010 TopoDS_Shape aFirstFound = aLSA.First();
4011 TopAbs_ShapeEnum aShapeType = aFirstFound.ShapeType();
4013 TDF_Label aFreeLabel = aResult->GetFreeLabel();
4014 TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aShapeType);
4017 //Make a Python command
4018 Handle(GEOM_Function) aFunction = aResult->GetFunction(1);
4020 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetInPlace("
4021 << theShapeWhere << ", " << theShapeWhat << ", True)";
4027 //=============================================================================
4029 * case GetInPlaceOld:
4032 //=============================================================================
4033 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlaceOld (Handle(GEOM_Object) theShapeWhere,
4034 Handle(GEOM_Object) theShapeWhat)
4038 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
4040 TopoDS_Shape aWhere = theShapeWhere->GetValue();
4041 TopoDS_Shape aWhat = theShapeWhat->GetValue();
4042 TopoDS_Shape aPntShape;
4043 TopoDS_Vertex aVertex;
4045 if (aWhere.IsNull() || aWhat.IsNull()) {
4046 SetErrorCode("Error: aWhere and aWhat TopoDS_Shape are Null.");
4050 Handle(GEOM_Function) aWhereFunction = theShapeWhere->GetLastFunction();
4051 if (aWhereFunction.IsNull()) {
4052 SetErrorCode("Error: aWhereFunction is Null.");
4056 TopTools_IndexedMapOfShape aWhereIndices;
4057 TopExp::MapShapes(aWhere, aWhereIndices);
4059 TColStd_ListOfInteger aModifiedList;
4060 Standard_Integer aWhereIndex;
4061 Handle(TColStd_HArray1OfInteger) aModifiedArray;
4062 Handle(GEOM_Object) aResult;
4064 bool isFound = false;
4065 TopAbs_ShapeEnum iType = TopAbs_SOLID;
4066 //Standard_Real aWhat_Mass = 0., aWhere_Mass = 0.;
4067 Standard_Real tab_aWhat[4], tab_aWhere[4];
4068 Standard_Real dl_l = 1e-3;
4069 Standard_Real min_l, Tol_0D, Tol_1D, Tol_2D, Tol_3D, Tol_Mass;
4070 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
4071 Bnd_Box BoundingBox;
4072 gp_Pnt aPnt, aPnt_aWhat, tab_Pnt[2];
4073 GProp_GProps aProps;
4075 // Find the iType of the aWhat shape
4077 if ( aWhat.ShapeType() == TopAbs_VERTEX ) iType = TopAbs_VERTEX;
4078 else if ( aWhat.ShapeType() == TopAbs_EDGE || aWhat.ShapeType() == TopAbs_WIRE ) iType = TopAbs_EDGE;
4079 else if ( aWhat.ShapeType() == TopAbs_FACE || aWhat.ShapeType() == TopAbs_SHELL ) iType = TopAbs_FACE;
4080 else if ( aWhat.ShapeType() == TopAbs_SOLID || aWhat.ShapeType() == TopAbs_COMPSOLID ) iType = TopAbs_SOLID;
4081 else if ( aWhat.ShapeType() == TopAbs_COMPOUND ) {
4082 // Only the iType of the first shape in the compound is taken into account
4083 TopoDS_Iterator It (aWhat, Standard_False, Standard_False);
4085 SetErrorCode("Error: theShapeWhat is an empty COMPOUND.");
4088 TopAbs_ShapeEnum compType = It.Value().ShapeType();
4089 if ( compType == TopAbs_VERTEX ) iType = TopAbs_VERTEX;
4090 else if ( compType == TopAbs_EDGE || compType == TopAbs_WIRE ) iType = TopAbs_EDGE;
4091 else if ( compType == TopAbs_FACE || compType == TopAbs_SHELL) iType = TopAbs_FACE;
4092 else if ( compType == TopAbs_SOLID || compType == TopAbs_COMPSOLID) iType = TopAbs_SOLID;
4095 SetErrorCode("Error: An attempt to extract a shape of not supported type.");
4099 iType = GEOMUtils::GetTypeOfSimplePart(aWhat);
4100 if (iType == TopAbs_SHAPE) {
4101 SetErrorCode("Error: An attempt to extract a shape of not supported type.");
4105 TopExp_Explorer Exp_aWhat ( aWhat, iType );
4106 TopExp_Explorer Exp_aWhere ( aWhere, iType );
4107 TopExp_Explorer Exp_Edge ( aWhere, TopAbs_EDGE );
4109 // Find the shortest edge in theShapeWhere shape
4110 BRepBndLib::Add(aWhere, BoundingBox);
4111 BoundingBox.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
4112 min_l = fabs(aXmax - aXmin);
4113 if( min_l < fabs(aYmax - aYmin) ) min_l = fabs(aYmax - aYmin);
4114 if( min_l < fabs(aZmax - aZmin) ) min_l = fabs(aZmax - aZmin);
4116 // Mantis issue 0020908 BEGIN
4117 if (!Exp_Edge.More()) {
4118 min_l = Precision::Confusion();
4120 // Mantis issue 0020908 END
4121 for ( Standard_Integer nbEdge = 0; Exp_Edge.More(); Exp_Edge.Next(), nbEdge++ ) {
4122 TopExp_Explorer Exp_Vertex( Exp_Edge.Current(), TopAbs_VERTEX);
4123 for ( Standard_Integer nbVertex = 0; Exp_Vertex.More(); Exp_Vertex.Next(), nbVertex++ ) {
4124 aPnt = BRep_Tool::Pnt( TopoDS::Vertex( Exp_Vertex.Current() ) );
4125 tab_Pnt[nbVertex] = aPnt;
4127 if ( ! tab_Pnt[0].IsEqual(tab_Pnt[1], dl_l) ) {
4128 BRepGProp::LinearProperties(Exp_Edge.Current(), aProps);
4129 if ( aProps.Mass() < min_l ) min_l = aProps.Mass();
4133 // Compute tolerances
4135 Tol_1D = dl_l * min_l;
4136 Tol_2D = dl_l * ( min_l * min_l) * ( 2. + dl_l);
4137 Tol_3D = dl_l * ( min_l * min_l * min_l ) * ( 3. + (3 * dl_l) + (dl_l * dl_l) );
4139 if (Tol_0D < Precision::Confusion()) Tol_0D = Precision::Confusion();
4140 if (Tol_1D < Precision::Confusion()) Tol_1D = Precision::Confusion();
4141 if (Tol_2D < Precision::Confusion()) Tol_2D = Precision::Confusion();
4142 if (Tol_3D < Precision::Confusion()) Tol_3D = Precision::Confusion();
4144 //if (Tol_1D > 1.0) Tol_1D = 1.0;
4145 //if (Tol_2D > 1.0) Tol_2D = 1.0;
4146 //if (Tol_3D > 1.0) Tol_3D = 1.0;
4149 if ( iType == TopAbs_VERTEX ) Tol_Mass = Tol_0D;
4150 else if ( iType == TopAbs_EDGE ) Tol_Mass = Tol_1D;
4151 else if ( iType == TopAbs_FACE ) Tol_Mass = Tol_2D;
4153 // Compute the ShapeWhat Mass
4155 for ( ; Exp_aWhat.More(); Exp_aWhat.Next() ) {
4156 if ( iType == TopAbs_VERTEX ) {
4160 else if ( iType == TopAbs_EDGE ) BRepGProp::LinearProperties(Exp_aWhat.Current(), aProps);
4161 else if ( iType == TopAbs_FACE ) BRepGProp::SurfaceProperties(Exp_aWhat.Current(), aProps);
4162 else BRepGProp::VolumeProperties(Exp_aWhat.Current(), aProps);
4163 aWhat_Mass += aProps.Mass();
4167 // Searching for the sub-shapes inside the ShapeWhere shape
4168 TopTools_MapOfShape map_aWhere;
4169 for ( Exp_aWhere.ReInit(); Exp_aWhere.More(); Exp_aWhere.Next() ) {
4170 if (!map_aWhere.Add(Exp_aWhere.Current()))
4171 continue; // skip repeated shape to avoid mass addition
4172 GetShapeProperties( Exp_aWhere.Current(), tab_aWhere, aPnt );
4173 for ( Exp_aWhat.ReInit(); Exp_aWhat.More(); Exp_aWhat.Next() ) {
4174 GetShapeProperties( Exp_aWhat.Current(), tab_aWhat, aPnt_aWhat );
4175 if ( fabs(tab_aWhat[3] - tab_aWhere[3]) <= Tol_Mass && aPnt_aWhat.Distance(aPnt) <= Tol_1D )
4178 if ( (tab_aWhat[3] - tab_aWhere[3]) > Tol_Mass ) {
4179 aPntShape = BRepBuilderAPI_MakeVertex( aPnt ).Shape();
4180 aVertex = TopoDS::Vertex( aPntShape );
4181 BRepExtrema_DistShapeShape aWhereDistance ( aVertex, Exp_aWhere.Current() );
4182 BRepExtrema_DistShapeShape aWhatDistance ( aVertex, Exp_aWhat.Current() );
4183 if ( aWhereDistance.IsDone() && aWhatDistance.IsDone() &&
4184 fabs(aWhereDistance.Value() - aWhatDistance.Value()) <= Tol_1D )
4186 // 0020162: "EDF 961 GEOM : Getinplace is getting additionnal orthogonal faces"
4187 // aVertex must be projected to the same point on Where and on What
4188 gp_Pnt pOnWhat = aWhatDistance.PointOnShape2(1);
4189 gp_Pnt pOnWhere = aWhereDistance.PointOnShape2(1);
4190 isFound = ( pOnWhat.Distance(pOnWhere) <= Tol_1D );
4191 if ( isFound && iType == TopAbs_FACE )
4193 // check normals at pOnWhat and pOnWhere
4194 const double angleTol = M_PI/180.;
4195 gp_Vec normToWhat = GetNormal( TopoDS::Face(Exp_aWhat.Current()), aWhatDistance);
4196 gp_Vec normToWhere = GetNormal( TopoDS::Face(Exp_aWhere.Current()), aWhereDistance);
4197 if ( normToWhat * normToWhere < 0 )
4198 normToWhat.Reverse();
4199 isFound = ( normToWhat.Angle( normToWhere ) < angleTol );
4205 aWhereIndex = aWhereIndices.FindIndex(Exp_aWhere.Current());
4206 aModifiedList.Append(aWhereIndex);
4207 //aWhere_Mass += tab_aWhere[3];
4212 //if ( fabs( aWhat_Mass - aWhere_Mass ) <= Tol_Mass )
4216 if (aModifiedList.Extent() == 0) { // Not found any Results
4217 SetErrorCode(NOT_FOUND_ANY);
4221 aModifiedArray = new TColStd_HArray1OfInteger (1, aModifiedList.Extent());
4222 TColStd_ListIteratorOfListOfInteger anIterModif (aModifiedList);
4223 for (Standard_Integer imod = 1; anIterModif.More(); anIterModif.Next(), imod++)
4224 aModifiedArray->SetValue(imod, anIterModif.Value());
4227 aResult = GetEngine()->AddSubShape(theShapeWhere, aModifiedArray);
4228 if (aResult.IsNull()) {
4229 SetErrorCode("Error in algorithm: result found, but cannot be returned.");
4233 if (aModifiedArray->Length() > 1 || theShapeWhat->GetType() == GEOM_GROUP) {
4235 aResult->SetType(GEOM_GROUP);
4237 //Set a sub-shape type
4238 TopoDS_Shape aFirstFound = aWhereIndices.FindKey(aModifiedArray->Value(1));
4239 TopAbs_ShapeEnum aShapeType = aFirstFound.ShapeType();
4241 TDF_Label aFreeLabel = aResult->GetFreeLabel();
4242 TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aShapeType);
4245 //Make a Python command
4246 Handle(GEOM_Function) aFunction = aResult->GetFunction(1);
4248 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetInPlace("
4249 << theShapeWhere << ", " << theShapeWhat << ", False)";
4255 //=======================================================================
4256 //function : GetInPlaceByHistory
4258 //=======================================================================
4259 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlaceByHistory
4260 (Handle(GEOM_Object) theShapeWhere,
4261 Handle(GEOM_Object) theShapeWhat)
4265 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
4267 TopoDS_Shape aWhere = theShapeWhere->GetValue();
4268 TopoDS_Shape aWhat = theShapeWhat->GetValue();
4270 if (aWhere.IsNull() || aWhat.IsNull()) return NULL;
4272 Handle(GEOM_Function) aWhereFunction = theShapeWhere->GetLastFunction();
4273 if (aWhereFunction.IsNull()) return NULL;
4275 //Fill array of indices
4276 TopTools_IndexedMapOfShape aWhereIndices;
4277 TopExp::MapShapes(aWhere, aWhereIndices);
4280 TColStd_ListOfInteger aModifiedList;
4281 bool isFound = GetInPlaceOfShape(aWhereFunction, aWhereIndices, aWhat, aModifiedList);
4283 if (!isFound || aModifiedList.Extent() < 1) {
4284 SetErrorCode("Error: No history found for the sought shape or its sub-shapes.");
4288 Standard_Integer nbFound = aModifiedList.Extent();
4289 TColStd_ListIteratorOfListOfInteger anIterModif (aModifiedList);
4292 // remove sub-shapes inappropriate for group creation
4293 TopAbs_ShapeEnum subType = TopAbs_SHAPE;
4294 while ( anIterModif.More() ) {
4295 TopAbs_ShapeEnum type = aWhereIndices( anIterModif.Value() ).ShapeType();
4296 bool okForGroup = ( type == TopAbs_VERTEX || type == TopAbs_EDGE ||
4297 type == TopAbs_FACE || type == TopAbs_SOLID );
4299 if ( subType == TopAbs_SHAPE )
4302 okForGroup = ( subType == type );
4307 aModifiedList.Remove( anIterModif );
4308 nbFound -= ( !okForGroup );
4310 if ( nbFound == 0 ) {
4311 SetErrorCode("Error: result found but it's type is inappropriate for group creation.");
4316 Handle(TColStd_HArray1OfInteger) aModifiedArray =
4317 new TColStd_HArray1OfInteger( 1, nbFound );
4318 anIterModif.Initialize(aModifiedList);
4319 for (Standard_Integer imod = 1; anIterModif.More(); anIterModif.Next(), imod++)
4320 aModifiedArray->SetValue(imod, anIterModif.Value());
4323 Handle(GEOM_Object) aResult = GetEngine()->AddSubShape(theShapeWhere, aModifiedArray);
4324 if (aResult.IsNull()) {
4325 SetErrorCode("Error in algorithm: result found, but cannot be returned.");
4329 if (aModifiedArray->Length() > 1) {
4331 aResult->SetType(GEOM_GROUP);
4333 //Set a sub-shape type
4334 TopoDS_Shape aFirstFound = aWhereIndices.FindKey(aModifiedArray->Value(1));
4335 TopAbs_ShapeEnum aShapeType = aFirstFound.ShapeType();
4337 TDF_Label aFreeLabel = aResult->GetFreeLabel();
4338 TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aShapeType);
4341 //Make a Python command
4342 Handle(GEOM_Function) aFunction = aResult->GetFunction(1);
4344 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetInPlaceByHistory("
4345 << theShapeWhere << ", " << theShapeWhat << ")";
4351 #define MAX_TOLERANCE 1.e-7
4353 //=======================================================================
4354 //function : isSameEdge
4355 //purpose : Returns True if two edges coincide
4356 //=======================================================================
4357 static bool isSameEdge(const TopoDS_Edge& theEdge1, const TopoDS_Edge& theEdge2)
4359 TopoDS_Vertex V11, V12, V21, V22;
4360 TopExp::Vertices(theEdge1, V11, V12);
4361 TopExp::Vertices(theEdge2, V21, V22);
4362 gp_Pnt P11 = BRep_Tool::Pnt(V11);
4363 gp_Pnt P12 = BRep_Tool::Pnt(V12);
4364 gp_Pnt P21 = BRep_Tool::Pnt(V21);
4365 gp_Pnt P22 = BRep_Tool::Pnt(V22);
4366 bool coincide = false;
4368 //Check that ends of edges coincide
4369 if(P11.Distance(P21) <= MAX_TOLERANCE) {
4370 if(P12.Distance(P22) <= MAX_TOLERANCE) coincide = true;
4372 else if(P11.Distance(P22) <= MAX_TOLERANCE) {
4373 if(P12.Distance(P21) <= MAX_TOLERANCE) coincide = true;
4376 if(!coincide) return false;
4378 if (BRep_Tool::Degenerated(theEdge1))
4379 if (BRep_Tool::Degenerated(theEdge2)) return true;
4382 if (BRep_Tool::Degenerated(theEdge2)) return false;
4384 double U11, U12, U21, U22;
4385 Handle(Geom_Curve) C1 = BRep_Tool::Curve(theEdge1, U11, U12);
4386 Handle(Geom_Curve) C2 = BRep_Tool::Curve(theEdge2, U21, U22);
4387 if(C1->DynamicType() == C2->DynamicType()) return true;
4389 //Check that both edges has the same geometry
4390 double range = U12-U11;
4391 double U = U11+ range/3.0;
4392 gp_Pnt P1 = C1->Value(U); //Compute a point on one third of the edge's length
4393 U = U11+range*2.0/3.0;
4394 gp_Pnt P2 = C1->Value(U); //Compute a point on two thirds of the edge's length
4396 if(!GeomLib_Tool::Parameter(C2, P1, MAX_TOLERANCE, U) || U < U21 || U > U22)
4399 if(P1.Distance(C2->Value(U)) > MAX_TOLERANCE) return false;
4401 if(!GeomLib_Tool::Parameter(C2, P2, MAX_TOLERANCE, U) || U < U21 || U > U22)
4404 if(P2.Distance(C2->Value(U)) > MAX_TOLERANCE) return false;
4409 #include <TopoDS_TShape.hxx>
4410 //=======================================================================
4411 //function : isSameFace
4412 //purpose : Returns True if two faces coincide
4413 //=======================================================================
4414 static bool isSameFace(const TopoDS_Face& theFace1, const TopoDS_Face& theFace2)
4416 TopExp_Explorer E(theFace1, TopAbs_EDGE);
4417 TopTools_ListOfShape LS1, LS2;
4418 for(; E.More(); E.Next()) LS1.Append(E.Current());
4420 E.Init(theFace2, TopAbs_EDGE);
4421 for(; E.More(); E.Next()) LS2.Append(E.Current());
4423 //Compare the number of edges in the faces
4424 if(LS1.Extent() != LS2.Extent()) return false;
4426 double aMin = RealFirst(), aMax = RealLast();
4427 double xminB1=aMax, yminB1=aMax, zminB1=aMax, xminB2=aMax, yminB2=aMax, zminB2=aMax;
4428 double xmaxB1=aMin, ymaxB1=aMin, zmaxB1=aMin, xmaxB2=aMin, ymaxB2=aMin, zmaxB2=aMin;
4430 for(E.Init(theFace1, TopAbs_VERTEX); E.More(); E.Next()) {
4431 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4432 if(P.X() < xminB1) xminB1 = P.X();
4433 if(P.Y() < yminB1) yminB1 = P.Y();
4434 if(P.Z() < zminB1) zminB1 = P.Z();
4435 if(P.X() > xmaxB1) xmaxB1 = P.X();
4436 if(P.Y() > ymaxB1) ymaxB1 = P.Y();
4437 if(P.Z() > zmaxB1) zmaxB1 = P.Z();
4440 for(E.Init(theFace2, TopAbs_VERTEX); E.More(); E.Next()) {
4441 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4442 if(P.X() < xminB2) xminB2 = P.X();
4443 if(P.Y() < yminB2) yminB2 = P.Y();
4444 if(P.Z() < zminB2) zminB2 = P.Z();
4445 if(P.X() > xmaxB2) xmaxB2 = P.X();
4446 if(P.Y() > ymaxB2) ymaxB2 = P.Y();
4447 if(P.Z() > zmaxB2) zmaxB2 = P.Z();
4450 //Compare the bounding boxes of both faces
4451 if(gp_Pnt(xminB1, yminB1, zminB1).Distance(gp_Pnt(xminB2, yminB2, zminB2)) > MAX_TOLERANCE)
4454 if(gp_Pnt(xmaxB1, ymaxB1, zmaxB1).Distance(gp_Pnt(xmaxB2, ymaxB2, zmaxB2)) > MAX_TOLERANCE)
4457 Handle(Geom_Surface) S1 = BRep_Tool::Surface(theFace1);
4458 Handle(Geom_Surface) S2 = BRep_Tool::Surface(theFace2);
4460 //Check if there a coincidence of two surfaces at least in two points
4461 double U11, U12, V11, V12, U21, U22, V21, V22;
4462 BRepTools::UVBounds(theFace1, U11, U12, V11, V12);
4463 BRepTools::UVBounds(theFace2, U21, U22, V21, V22);
4465 double rangeU = U12-U11;
4466 double rangeV = V12-V11;
4467 double U = U11 + rangeU/3.0;
4468 double V = V11 + rangeV/3.0;
4469 gp_Pnt P1 = S1->Value(U, V);
4470 U = U11+rangeU*2.0/3.0;
4471 V = V11+rangeV*2.0/3.0;
4472 gp_Pnt P2 = S1->Value(U, V);
4474 if (!GeomLib_Tool::Parameters(S2, P1, MAX_TOLERANCE, U, V) || U < U21 || U > U22 || V < V21 || V > V22)
4477 if (P1.Distance(S2->Value(U,V)) > MAX_TOLERANCE) return false;
4479 if (!GeomLib_Tool::Parameters(S2, P2, MAX_TOLERANCE, U, V) || U < U21 || U > U22 || V < V21 || V > V22)
4482 if (P2.Distance(S2->Value(U, V)) > MAX_TOLERANCE) return false;
4484 //Check that each edge of the Face1 has a counterpart in the Face2
4485 TopTools_MapOfOrientedShape aMap;
4486 TopTools_ListIteratorOfListOfShape LSI1(LS1);
4487 for(; LSI1.More(); LSI1.Next()) {
4488 TopoDS_Edge E = TopoDS::Edge(LSI1.Value());
4489 bool isFound = false;
4490 TopTools_ListIteratorOfListOfShape LSI2(LS2);
4491 for(; LSI2.More(); LSI2.Next()) {
4492 TopoDS_Shape aValue = LSI2.Value();
4493 if(aMap.Contains(aValue)) continue; //To avoid checking already found edge several times
4494 if(isSameEdge(E, TopoDS::Edge(aValue))) {
4500 if(!isFound) return false;
4506 //=======================================================================
4507 //function : isSameSolid
4508 //purpose : Returns True if two solids coincide
4509 //=======================================================================
4510 bool isSameSolid(const TopoDS_Solid& theSolid1, const TopoDS_Solid& theSolid2)
4512 TopExp_Explorer E(theSolid1, TopAbs_FACE);
4513 TopTools_ListOfShape LS1, LS2;
4514 for(; E.More(); E.Next()) LS1.Append(E.Current());
4515 E.Init(theSolid2, TopAbs_FACE);
4516 for(; E.More(); E.Next()) LS2.Append(E.Current());
4518 if(LS1.Extent() != LS2.Extent()) return false;
4520 double aMin = RealFirst(), aMax = RealLast();
4521 double xminB1=aMax, yminB1=aMax, zminB1=aMax, xminB2=aMax, yminB2=aMax, zminB2=aMax;
4522 double xmaxB1=aMin, ymaxB1=aMin, zmaxB1=aMin, xmaxB2=aMin, ymaxB2=aMin, zmaxB2=aMin;
4524 for(E.Init(theSolid1, TopAbs_VERTEX); E.More(); E.Next()) {
4525 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4526 if(P.X() < xminB1) xminB1 = P.X();
4527 if(P.Y() < yminB1) yminB1 = P.Y();
4528 if(P.Z() < zminB1) zminB1 = P.Z();
4529 if(P.X() > xmaxB1) xmaxB1 = P.X();
4530 if(P.Y() > ymaxB1) ymaxB1 = P.Y();
4531 if(P.Z() > zmaxB1) zmaxB1 = P.Z();
4534 for(E.Init(theSolid2, TopAbs_VERTEX); E.More(); E.Next()) {
4535 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4536 if(P.X() < xminB2) xminB2 = P.X();
4537 if(P.Y() < yminB2) yminB2 = P.Y();
4538 if(P.Z() < zminB2) zminB2 = P.Z();
4539 if(P.X() > xmaxB2) xmaxB2 = P.X();
4540 if(P.Y() > ymaxB2) ymaxB2 = P.Y();
4541 if(P.Z() > zmaxB2) zmaxB2 = P.Z();
4544 //Compare the bounding boxes of both solids
4545 if(gp_Pnt(xminB1, yminB1, zminB1).Distance(gp_Pnt(xminB2, yminB2, zminB2)) > MAX_TOLERANCE)
4548 if(gp_Pnt(xmaxB1, ymaxB1, zmaxB1).Distance(gp_Pnt(xmaxB2, ymaxB2, zmaxB2)) > MAX_TOLERANCE)
4551 //Check that each face of the Solid1 has a counterpart in the Solid2
4552 TopTools_MapOfOrientedShape aMap;
4553 TopTools_ListIteratorOfListOfShape LSI1(LS1);
4554 for(; LSI1.More(); LSI1.Next()) {
4555 TopoDS_Face F = TopoDS::Face(LSI1.Value());
4556 bool isFound = false;
4557 TopTools_ListIteratorOfListOfShape LSI2(LS2);
4558 for(; LSI2.More(); LSI2.Next()) {
4559 if(aMap.Contains(LSI2.Value())) continue; //To avoid checking already found faces several times
4560 if(isSameFace(F, TopoDS::Face(LSI2.Value()))) {
4561 aMap.Add(LSI2.Value());
4566 if(!isFound) return false;
4572 //=======================================================================
4573 //function : GetSame
4575 //=======================================================================
4576 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetSame(const Handle(GEOM_Object)& theShapeWhere,
4577 const Handle(GEOM_Object)& theShapeWhat)
4580 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
4582 TopoDS_Shape aWhere = theShapeWhere->GetValue();
4583 TopoDS_Shape aWhat = theShapeWhat->GetValue();
4585 if (aWhere.IsNull() || aWhat.IsNull()) return NULL;
4588 bool isFound = false;
4589 TopoDS_Shape aSubShape;
4590 TopTools_MapOfShape aMap;
4592 if (aWhat.ShapeType() == TopAbs_COMPOUND || aWhat.ShapeType() == TopAbs_COMPSOLID) {
4593 TopoDS_Iterator It (aWhat, Standard_True, Standard_True);
4594 if (It.More()) aWhat = It.Value();
4597 SetErrorCode("Compounds of two or more shapes are not allowed for aWhat argument");
4602 switch (aWhat.ShapeType()) {
4603 case TopAbs_VERTEX: {
4604 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(aWhat));
4605 TopExp_Explorer E(aWhere, TopAbs_VERTEX);
4606 for(; E.More(); E.Next()) {
4607 if(!aMap.Add(E.Current())) continue;
4608 gp_Pnt P2 = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4609 if(P.Distance(P2) <= MAX_TOLERANCE) {
4611 aSubShape = E.Current();
4618 TopoDS_Edge anEdge = TopoDS::Edge(aWhat);
4619 TopExp_Explorer E(aWhere, TopAbs_EDGE);
4620 for(; E.More(); E.Next()) {
4621 if(!aMap.Add(E.Current())) continue;
4622 if(isSameEdge(anEdge, TopoDS::Edge(E.Current()))) {
4623 aSubShape = E.Current();
4631 TopoDS_Face aFace = TopoDS::Face(aWhat);
4632 TopExp_Explorer E(aWhere, TopAbs_FACE);
4633 for(; E.More(); E.Next()) {
4634 if(!aMap.Add(E.Current())) continue;
4635 if(isSameFace(aFace, TopoDS::Face(E.Current()))) {
4636 aSubShape = E.Current();
4643 case TopAbs_SOLID: {
4644 TopoDS_Solid aSolid = TopoDS::Solid(aWhat);
4645 TopExp_Explorer E(aWhere, TopAbs_SOLID);
4646 for(; E.More(); E.Next()) {
4647 if(!aMap.Add(E.Current())) continue;
4648 if(isSameSolid(aSolid, TopoDS::Solid(E.Current()))) {
4649 aSubShape = E.Current();
4661 TopTools_IndexedMapOfShape anIndices;
4662 TopExp::MapShapes(aWhere, anIndices);
4663 if (anIndices.Contains(aSubShape))
4664 anIndex = anIndices.FindIndex(aSubShape);
4667 if (anIndex < 0) return NULL;
4669 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
4671 anArray->SetValue(1, anIndex);
4673 Handle(GEOM_Object) aResult = GetEngine()->AddSubShape(theShapeWhere, anArray);
4674 Handle(GEOM_Function) aFunction = aResult->GetLastFunction();
4676 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetSame("
4677 << theShapeWhere << ", " << theShapeWhat << ")";
4685 //=======================================================================
4686 //function : GetSameIDs
4688 //=======================================================================
4689 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetSameIDs
4690 (const Handle(GEOM_Object)& theShapeWhere,
4691 const Handle(GEOM_Object)& theShapeWhat)
4694 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
4696 TopoDS_Shape aWhere = theShapeWhere->GetValue();
4697 TopoDS_Shape aWhat = theShapeWhat->GetValue();
4699 if (aWhere.IsNull() || aWhat.IsNull()) return NULL;
4701 TopTools_ListOfShape listShape;
4702 TopTools_MapOfShape aMap;
4704 if (aWhat.ShapeType() == TopAbs_COMPOUND || aWhat.ShapeType() == TopAbs_COMPSOLID) {
4705 TopoDS_Iterator It (aWhat, Standard_True, Standard_True);
4706 if (It.More()) aWhat = It.Value();
4709 SetErrorCode("Compounds of two or more shapes are not allowed for aWhat argument");
4714 switch (aWhat.ShapeType()) {
4715 case TopAbs_VERTEX: {
4716 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(aWhat));
4717 TopExp_Explorer E(aWhere, TopAbs_VERTEX);
4718 for(; E.More(); E.Next()) {
4719 if(!aMap.Add(E.Current())) continue;
4720 gp_Pnt P2 = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4721 if(P.Distance(P2) <= MAX_TOLERANCE) {
4722 listShape.Append(E.Current());
4728 TopoDS_Edge anEdge = TopoDS::Edge(aWhat);
4729 TopExp_Explorer E(aWhere, TopAbs_EDGE);
4730 for(; E.More(); E.Next()) {
4731 if(!aMap.Add(E.Current())) continue;
4732 if(isSameEdge(anEdge, TopoDS::Edge(E.Current()))) {
4733 listShape.Append(E.Current());
4739 TopoDS_Face aFace = TopoDS::Face(aWhat);
4740 TopExp_Explorer E(aWhere, TopAbs_FACE);
4741 for(; E.More(); E.Next()) {
4742 if(!aMap.Add(E.Current())) continue;
4743 if(isSameFace(aFace, TopoDS::Face(E.Current()))) {
4744 listShape.Append(E.Current());
4749 case TopAbs_SOLID: {
4750 TopoDS_Solid aSolid = TopoDS::Solid(aWhat);
4751 TopExp_Explorer E(aWhere, TopAbs_SOLID);
4752 for(; E.More(); E.Next()) {
4753 if(!aMap.Add(E.Current())) continue;
4754 if(isSameSolid(aSolid, TopoDS::Solid(E.Current()))) {
4755 listShape.Append(E.Current());
4764 if ( !listShape.IsEmpty() ) {
4765 TopTools_IndexedMapOfShape anIndices;
4766 TopExp::MapShapes(aWhere, anIndices);
4767 TopTools_ListIteratorOfListOfShape itSub (listShape);
4768 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
4769 for (; itSub.More(); itSub.Next()) {
4770 if (anIndices.Contains(itSub.Value()))
4771 aSeq->Append(anIndices.FindIndex(itSub.Value()));
4774 // The GetSameIDs() doesn't change object so no new function is required.
4775 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShapeWhere,theShapeWhat)->GetLastFunction();
4777 // Make a Python command
4778 GEOM::TPythonDump(aFunction, /*append=*/true)
4779 << "listSameIDs = geompy.GetSameIDs("
4780 << theShapeWhere << ", "
4781 << theShapeWhat << ")";
4784 SetErrorCode(NOT_FOUND_ANY);