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_IShapeExtend.hxx"
41 #include "GEOMImpl_IGlue.hxx"
43 #include "GEOMImpl_Block6Explorer.hxx"
44 #include "GEOMImpl_IHealingOperations.hxx"
46 #include "GEOMImpl_Gen.hxx"
48 #include "GEOM_Function.hxx"
49 #include "GEOM_ISubShape.hxx"
50 #include "GEOM_PythonDump.hxx"
52 #include "GEOMUtils.hxx"
54 #include "GEOMAlgo_ClsfBox.hxx"
55 #include "GEOMAlgo_ClsfSolid.hxx"
56 #include "GEOMAlgo_CoupleOfShapes.hxx"
57 #include "GEOMAlgo_FinderShapeOn1.hxx"
58 #include "GEOMAlgo_FinderShapeOnQuad.hxx"
59 #include "GEOMAlgo_FinderShapeOn2.hxx"
60 #include "GEOMAlgo_GetInPlace.hxx"
61 #include "GEOMAlgo_GlueDetector.hxx"
62 #include "GEOMAlgo_ListIteratorOfListOfCoupleOfShapes.hxx"
63 #include "GEOMAlgo_ListOfCoupleOfShapes.hxx"
65 #include <Basics_OCCTVersion.hxx>
67 #include <utilities.h>
69 #include <Utils_ExceptHandlers.hxx>
71 #include <BRepAdaptor_Curve.hxx>
72 #include <BRepAdaptor_Surface.hxx>
73 #include <BRepBndLib.hxx>
74 #include <BRepBuilderAPI_MakeVertex.hxx>
75 #include <BRepClass3d_SolidClassifier.hxx>
76 #include <BRepClass_FaceClassifier.hxx>
77 #include <BRepExtrema_DistShapeShape.hxx>
78 #include <BRepExtrema_ExtCF.hxx>
79 #include <BRepGProp.hxx>
80 #include <BRepMesh_IncrementalMesh.hxx>
81 #include <BRepTools.hxx>
82 #include <BRep_Builder.hxx>
83 #include <BRep_Tool.hxx>
84 #include <Bnd_Box.hxx>
85 #include <GEOMImpl_IMeasure.hxx>
86 #include <GEOMImpl_MeasureDriver.hxx>
87 #include <GProp_GProps.hxx>
88 #include <Geom2d_Curve.hxx>
89 #include <GeomAdaptor_Surface.hxx>
90 #include <GeomLib_Tool.hxx>
91 #include <Geom_CylindricalSurface.hxx>
92 #include <Geom_Plane.hxx>
93 #include <Geom_SphericalSurface.hxx>
94 #include <Geom_Surface.hxx>
95 #include <Precision.hxx>
96 #include <TColStd_Array1OfReal.hxx>
97 #include <TColStd_HArray1OfInteger.hxx>
98 #include <TColStd_ListIteratorOfListOfInteger.hxx>
99 #include <TColStd_ListOfInteger.hxx>
100 #include <TDF_Tool.hxx>
101 #include <TDataStd_Integer.hxx>
102 #include <TDataStd_IntegerArray.hxx>
103 #include <TDataStd_ListIteratorOfListOfExtendedString.hxx>
104 #include <TFunction_Driver.hxx>
105 #include <TFunction_DriverTable.hxx>
106 #include <TFunction_Logbook.hxx>
107 #include <TopAbs.hxx>
108 #include <TopExp.hxx>
109 #include <TopExp_Explorer.hxx>
110 #include <TopLoc_Location.hxx>
111 #include <TopTools_Array1OfShape.hxx>
112 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
113 #include <TopTools_IndexedMapOfShape.hxx>
114 #include <TopTools_ListIteratorOfListOfShape.hxx>
115 #include <TopTools_MapOfOrientedShape.hxx>
116 #include <TopTools_MapOfShape.hxx>
117 #include <TopTools_SequenceOfShape.hxx>
118 #include <TopoDS.hxx>
119 #include <TopoDS_Compound.hxx>
120 #include <TopoDS_Edge.hxx>
121 #include <TopoDS_Face.hxx>
122 #include <TopoDS_Iterator.hxx>
123 #include <TopoDS_Shape.hxx>
124 #include <TopoDS_Solid.hxx>
125 #include <TopoDS_Vertex.hxx>
126 #include <gp_Cylinder.hxx>
127 #include <gp_Lin.hxx>
128 #include <gp_Pnt.hxx>
132 #include <functional>
134 #include <Standard_NullObject.hxx>
135 #include <Standard_Failure.hxx>
136 #include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
140 //================================================================================
142 * \brief Return normal to face at extrema point
144 //================================================================================
146 gp_Vec GetNormal (const TopoDS_Face& face, const BRepExtrema_DistShapeShape& extrema)
148 gp_Vec defaultNorm(1,0,0); // to have same normals on different faces
150 // get UV at extrema point
151 Standard_Real u,v, f,l;
152 switch ( extrema.SupportTypeShape2(1) ) {
153 case BRepExtrema_IsInFace: {
154 extrema.ParOnFaceS2(1, u, v );
157 case BRepExtrema_IsOnEdge: {
158 TopoDS_Edge edge = TopoDS::Edge( extrema.SupportOnShape2(1));
159 Handle(Geom2d_Curve) pcurve = BRep_Tool::CurveOnSurface( edge, face, f,l );
160 extrema.ParOnEdgeS2( 1, u );
161 gp_Pnt2d uv = pcurve->Value( u );
166 case BRepExtrema_IsVertex: return defaultNorm;
169 BRepAdaptor_Surface surface( face, false );
170 gp_Vec du, dv; gp_Pnt p;
171 surface.D1( u, v, p, du, dv );
175 } catch (Standard_Failure ) {
180 void AddFlatSubShapes(const TopoDS_Shape& S, TopTools_ListOfShape& L, TopTools_MapOfShape& M)
182 if (S.ShapeType() != TopAbs_COMPOUND) {
186 TopoDS_Iterator It(S, Standard_True, Standard_True);
187 for (; It.More(); It.Next()) {
188 TopoDS_Shape SS = It.Value();
190 AddFlatSubShapes(SS, L, M);
196 //=============================================================================
200 //=============================================================================
201 GEOMImpl_IShapesOperations::GEOMImpl_IShapesOperations (GEOM_Engine* theEngine, int theDocID)
202 : GEOM_IOperations(theEngine, theDocID)
204 MESSAGE("GEOMImpl_IShapesOperations::GEOMImpl_IShapesOperations");
207 //=============================================================================
211 //=============================================================================
212 GEOMImpl_IShapesOperations::~GEOMImpl_IShapesOperations()
214 MESSAGE("GEOMImpl_IShapesOperations::~GEOMImpl_IShapesOperations");
217 //=============================================================================
221 //=============================================================================
222 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeEdge
223 (Handle(GEOM_Object) thePnt1, Handle(GEOM_Object) thePnt2)
227 if (thePnt1.IsNull() || thePnt2.IsNull()) return NULL;
229 //Add a new Edge object
230 Handle(GEOM_Object) anEdge = GetEngine()->AddObject(GetDocID(), GEOM_EDGE);
232 //Add a new Vector function
233 Handle(GEOM_Function) aFunction =
234 anEdge->AddFunction(GEOMImpl_VectorDriver::GetID(), VECTOR_TWO_PNT);
236 //Check if the function is set correctly
237 if (aFunction->GetDriverGUID() != GEOMImpl_VectorDriver::GetID()) return NULL;
239 GEOMImpl_IVector aPI (aFunction);
241 Handle(GEOM_Function) aRef1 = thePnt1->GetLastFunction();
242 Handle(GEOM_Function) aRef2 = thePnt2->GetLastFunction();
243 if (aRef1.IsNull() || aRef2.IsNull()) return NULL;
245 aPI.SetPoint1(aRef1);
246 aPI.SetPoint2(aRef2);
248 //Compute the Edge value
251 if (!GetSolver()->ComputeFunction(aFunction)) {
252 SetErrorCode("Vector driver failed");
256 catch (Standard_Failure) {
257 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
258 SetErrorCode(aFail->GetMessageString());
262 //Make a Python command
263 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdge("
264 << thePnt1 << ", " << thePnt2 << ")";
270 //=============================================================================
272 * MakeEdgeOnCurveByLength
274 //=============================================================================
275 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeEdgeOnCurveByLength
276 (Handle(GEOM_Object) theRefCurve,
277 const Standard_Real theLength,
278 Handle(GEOM_Object) theStartPoint)
282 if (theRefCurve.IsNull()) return NULL;
284 //Add a new Edge object
285 Handle(GEOM_Object) anEdge = GetEngine()->AddObject(GetDocID(), GEOM_EDGE);
287 //Add a new Vector function
288 Handle(GEOM_Function) aFunction =
289 anEdge->AddFunction(GEOMImpl_ShapeDriver::GetID(), EDGE_CURVE_LENGTH);
291 //Check if the function is set correctly
292 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
294 GEOMImpl_IVector aPI (aFunction);
296 Handle(GEOM_Function) aRef1 = theRefCurve->GetLastFunction();
297 if (aRef1.IsNull()) return NULL;
298 aPI.SetPoint1(aRef1);
300 if (!theStartPoint.IsNull()) {
301 Handle(GEOM_Function) aRef2 = theStartPoint->GetLastFunction();
302 aPI.SetPoint2(aRef2);
305 aPI.SetParameter(theLength);
307 //Compute the Edge value
310 if (!GetSolver()->ComputeFunction(aFunction)) {
311 SetErrorCode("Vector driver failed");
315 catch (Standard_Failure) {
316 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
317 SetErrorCode(aFail->GetMessageString());
321 //Make a Python command
322 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdgeOnCurveByLength("
323 << theRefCurve << ", " << theLength << ", " << theStartPoint << ")";
329 //=============================================================================
333 //=============================================================================
334 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeEdgeWire
335 (Handle(GEOM_Object) theWire,
336 const Standard_Real theLinearTolerance,
337 const Standard_Real theAngularTolerance)
341 if (theWire.IsNull()) return NULL;
343 //Add a new Edge object
344 Handle(GEOM_Object) anEdge = GetEngine()->AddObject(GetDocID(), GEOM_EDGE);
346 //Add a new Vector function
347 Handle(GEOM_Function) aFunction =
348 anEdge->AddFunction(GEOMImpl_ShapeDriver::GetID(), EDGE_WIRE);
350 //Check if the function is set correctly
351 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
353 GEOMImpl_IShapes aCI (aFunction);
355 Handle(GEOM_Function) aWire = theWire->GetLastFunction();
357 if (aWire.IsNull()) return NULL;
360 aCI.SetTolerance(theLinearTolerance);
361 aCI.SetAngularTolerance(theAngularTolerance);
363 //Compute the Edge value
366 if (!GetSolver()->ComputeFunction(aFunction)) {
367 SetErrorCode("Shape driver failed");
371 catch (Standard_Failure) {
372 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
373 SetErrorCode(aFail->GetMessageString());
377 const double DEF_LIN_TOL = Precision::Confusion();
378 const double DEF_ANG_TOL = Precision::Angular();
379 //Make a Python command
380 if ( theAngularTolerance == DEF_ANG_TOL ) {
381 if ( theLinearTolerance == DEF_LIN_TOL )
382 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdgeWire("
385 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdgeWire("
386 << theWire << ", " << theLinearTolerance << ")";
389 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdgeWire("
390 << theWire << ", " << theLinearTolerance << ", "
391 << theAngularTolerance << ")";
398 //=============================================================================
402 //=============================================================================
403 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeWire
404 (std::list<Handle(GEOM_Object)> theShapes,
405 const Standard_Real theTolerance)
410 Handle(GEOM_Object) aWire = GetEngine()->AddObject(GetDocID(), GEOM_WIRE);
413 Handle(GEOM_Function) aFunction =
414 aWire->AddFunction(GEOMImpl_ShapeDriver::GetID(), WIRE_EDGES);
415 if (aFunction.IsNull()) return NULL;
417 //Check if the function is set correctly
418 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
420 GEOMImpl_IShapes aCI (aFunction);
421 aCI.SetTolerance(theTolerance);
423 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
426 std::list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
427 for (; it != theShapes.end(); it++) {
428 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
429 if (aRefSh.IsNull()) {
430 SetErrorCode("NULL argument shape for the shape construction");
433 aShapesSeq->Append(aRefSh);
435 aCI.SetShapes(aShapesSeq);
440 if (!GetSolver()->ComputeFunction(aFunction)) {
441 SetErrorCode("Shape driver failed");
445 catch (Standard_Failure) {
446 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
447 SetErrorCode(aFail->GetMessageString());
451 //Make a Python command
452 GEOM::TPythonDump pd (aFunction);
453 pd << aWire << " = geompy.MakeWire([";
456 it = theShapes.begin();
457 if (it != theShapes.end()) {
459 while (it != theShapes.end()) {
460 pd << ", " << (*it++);
463 pd << "], " << theTolerance << ")";
469 //=============================================================================
473 //=============================================================================
474 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFace (Handle(GEOM_Object) theWire,
475 const bool isPlanarWanted)
479 if (theWire.IsNull()) return NULL;
481 //Add a new Face object
482 Handle(GEOM_Object) aFace = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
484 //Add a new Shape function for creation of a face from a wire
485 Handle(GEOM_Function) aFunction =
486 aFace->AddFunction(GEOMImpl_ShapeDriver::GetID(), FACE_WIRE);
487 if (aFunction.IsNull()) return NULL;
489 //Check if the function is set correctly
490 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
492 GEOMImpl_IShapes aCI (aFunction);
494 Handle(GEOM_Function) aRefWire = theWire->GetLastFunction();
496 if (aRefWire.IsNull()) return NULL;
498 aCI.SetBase(aRefWire);
499 aCI.SetIsPlanar(isPlanarWanted);
501 //Compute the Face value
502 Standard_Boolean isWarning = Standard_False;
505 if (!GetSolver()->ComputeFunction(aFunction)) {
506 SetErrorCode("Shape driver failed to compute a face");
510 catch (Standard_Failure) {
511 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
512 SetErrorCode(aFail->GetMessageString());
513 // to provide warning
514 if (!aFunction->GetValue().IsNull()) {
515 isWarning = Standard_True;
521 //Make a Python command
522 GEOM::TPythonDump(aFunction) << aFace << " = geompy.MakeFace("
523 << theWire << ", " << (int)isPlanarWanted << ")";
525 // to provide warning
526 if (!isWarning) SetErrorCode(OK);
530 //=============================================================================
534 //=============================================================================
535 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFaceWires
536 (std::list<Handle(GEOM_Object)> theShapes,
537 const bool isPlanarWanted)
542 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
545 Handle(GEOM_Function) aFunction =
546 aShape->AddFunction(GEOMImpl_ShapeDriver::GetID(), FACE_WIRES);
547 if (aFunction.IsNull()) return NULL;
549 //Check if the function is set correctly
550 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
552 GEOMImpl_IShapes aCI (aFunction);
554 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
557 std::list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
558 for (; it != theShapes.end(); it++) {
559 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
560 if (aRefSh.IsNull()) {
561 SetErrorCode("NULL argument shape for the face construction");
564 aShapesSeq->Append(aRefSh);
566 aCI.SetShapes(aShapesSeq);
568 aCI.SetIsPlanar(isPlanarWanted);
571 Standard_Boolean isWarning = Standard_False;
574 if (!GetSolver()->ComputeFunction(aFunction)) {
575 SetErrorCode("Shape driver failed");
579 catch (Standard_Failure) {
580 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
581 SetErrorCode(aFail->GetMessageString());
582 // to provide warning
583 if (!aFunction->GetValue().IsNull()) {
584 isWarning = Standard_True;
590 //Make a Python command
591 GEOM::TPythonDump pd (aFunction);
592 pd << aShape << " = geompy.MakeFaceWires([";
595 it = theShapes.begin();
596 if (it != theShapes.end()) {
598 while (it != theShapes.end()) {
599 pd << ", " << (*it++);
602 pd << "], " << (int)isPlanarWanted << ")";
604 // to provide warning
605 if (!isWarning) SetErrorCode(OK);
609 //=============================================================================
611 * MakeFaceFromSurface
613 //=============================================================================
614 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFaceFromSurface
615 (Handle(GEOM_Object) theFace,
616 Handle(GEOM_Object) theWire)
621 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
624 Handle(GEOM_Function) aFunction =
625 aShape->AddFunction(GEOMImpl_ShapeDriver::GetID(), FACE_FROM_SURFACE);
627 if (aFunction.IsNull()) {
631 //Check if the function is set correctly
632 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) {
636 GEOMImpl_IShapes aCI (aFunction);
637 Handle(TColStd_HSequenceOfTransient) aShapesSeq =
638 new TColStd_HSequenceOfTransient;
639 Handle(GEOM_Function) aRefFace = theFace->GetLastFunction();
640 Handle(GEOM_Function) aRefWire = theWire->GetLastFunction();
642 if (aRefFace.IsNull()) {
643 SetErrorCode("NULL argument face for the face construction");
647 if (aRefWire.IsNull()) {
648 SetErrorCode("NULL argument wire for the face construction");
652 aShapesSeq->Append(aRefFace);
653 aShapesSeq->Append(aRefWire);
655 aCI.SetShapes(aShapesSeq);
660 if (!GetSolver()->ComputeFunction(aFunction)) {
661 SetErrorCode("Shape driver failed");
665 catch (Standard_Failure) {
666 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
667 SetErrorCode(aFail->GetMessageString());
671 //Make a Python command
672 GEOM::TPythonDump (aFunction) << aShape
673 << " = geompy.MakeFaceFromSurface(" << theFace << ", " << theWire << ")";
680 //=============================================================================
684 //=============================================================================
685 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeShell
686 (std::list<Handle(GEOM_Object)> theShapes)
688 return MakeShape(theShapes, GEOM_SHELL, SHELL_FACES, "MakeShell");
691 //=============================================================================
695 //=============================================================================
696 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeSolidShells
697 (std::list<Handle(GEOM_Object)> theShapes)
699 return MakeShape(theShapes, GEOM_SOLID, SOLID_SHELLS, "MakeSolid");
702 //=============================================================================
706 //=============================================================================
707 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeCompound
708 (std::list<Handle(GEOM_Object)> theShapes)
710 return MakeShape(theShapes, GEOM_COMPOUND, COMPOUND_SHAPES, "MakeCompound");
713 //=============================================================================
717 //=============================================================================
718 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeShape
719 (std::list<Handle(GEOM_Object)> theShapes,
720 const Standard_Integer theObjectType,
721 const Standard_Integer theFunctionType,
722 const TCollection_AsciiString& theMethodName)
727 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), theObjectType);
730 Handle(GEOM_Function) aFunction =
731 aShape->AddFunction(GEOMImpl_ShapeDriver::GetID(), theFunctionType);
732 if (aFunction.IsNull()) return NULL;
734 //Check if the function is set correctly
735 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
737 GEOMImpl_IShapes aCI (aFunction);
739 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
742 std::list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
743 for (; it != theShapes.end(); it++) {
744 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
745 if (aRefSh.IsNull()) {
746 SetErrorCode("NULL argument shape for the shape construction");
749 aShapesSeq->Append(aRefSh);
751 aCI.SetShapes(aShapesSeq);
756 if (!GetSolver()->ComputeFunction(aFunction)) {
757 SetErrorCode("Shape driver failed");
761 catch (Standard_Failure) {
762 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
763 SetErrorCode(aFail->GetMessageString());
767 //Make a Python command
768 GEOM::TPythonDump pd (aFunction);
769 pd << aShape << " = geompy." << theMethodName.ToCString() << "([";
772 it = theShapes.begin();
773 if (it != theShapes.end()) {
775 while (it != theShapes.end()) {
776 pd << ", " << (*it++);
785 //=============================================================================
789 //=============================================================================
791 GEOMImpl_IShapesOperations::MakeGlueFaces (std::list< Handle(GEOM_Object) >& theShapes,
792 const Standard_Real theTolerance,
793 const Standard_Boolean doKeepNonSolids)
797 Handle(TColStd_HSequenceOfTransient) objects = GEOM_Object::GetLastFunctions( theShapes );
798 if ( objects.IsNull() || objects->IsEmpty() ) {
799 SetErrorCode("NULL argument shape");
803 //Add a new Glued object
804 Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
806 //Add a new Glue function
807 Handle(GEOM_Function) aFunction;
808 aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_FACES);
809 if (aFunction.IsNull()) return NULL;
811 //Check if the function is set correctly
812 if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
814 GEOMImpl_IGlue aCI (aFunction);
816 aCI.SetBase( objects );
817 aCI.SetTolerance(theTolerance);
818 aCI.SetKeepNonSolids(doKeepNonSolids);
820 //Compute the sub-shape value
821 Standard_Boolean isWarning = Standard_False;
824 if (!GetSolver()->ComputeFunction(aFunction)) {
825 SetErrorCode("Shape driver failed to glue faces");
829 catch (Standard_Failure) {
830 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
831 SetErrorCode(aFail->GetMessageString());
832 // to provide warning
833 if (!aFunction->GetValue().IsNull()) {
834 isWarning = Standard_True;
840 //Make a Python command
841 GEOM::TPythonDump(aFunction) << aGlued << " = geompy.MakeGlueFaces("
842 << theShapes << ", " << theTolerance << ")";
844 // to provide warning
845 if (!isWarning) SetErrorCode(OK);
849 //=============================================================================
853 //=============================================================================
855 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetGlueFaces
856 (Handle(GEOM_Object) theShape,
857 const Standard_Real theTolerance)
861 if (theShape.IsNull()) return NULL;
862 TopoDS_Shape aShape = theShape->GetValue();
863 if (aShape.IsNull()) return NULL;
865 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
867 Standard_Integer iErr;
869 GEOMAlgo_Gluer1 aGluer;
870 GEOMAlgo_ListIteratorOfListOfCoupleOfShapes aItCS;
871 GEOMAlgo_CoupleOfShapes aCS;
872 GEOMAlgo_ListOfCoupleOfShapes aLCS;
874 //aGluer = new GEOMAlgo_Gluer1;
875 aGluer.SetShape(aShape);
876 aGluer.SetTolerance(theTolerance);
878 iErr = aGluer.ErrorStatus();
879 if (iErr) return NULL;
881 TopTools_ListOfShape listShape;
882 const GEOMAlgo_ListOfCoupleOfShapes& aLCSG = aGluer.GluedFaces();
884 aItCS.Initialize(aLCSG);
885 for (; aItCS.More(); aItCS.Next()) {
886 const GEOMAlgo_CoupleOfShapes& aCSG = aItCS.Value();
887 listShape.Append(aCSG.Shape1());
890 TopTools_ListIteratorOfListOfShape itSub (listShape);
891 TCollection_AsciiString anAsciiList, anEntry;
892 TopTools_IndexedMapOfShape anIndices;
893 TopExp::MapShapes(aShape, anIndices);
894 Handle(TColStd_HArray1OfInteger) anArray;
895 Handle(GEOM_Object) anObj;
896 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
897 TopoDS_Shape aValue = itSub.Value();
898 anArray = new TColStd_HArray1OfInteger(1,1);
899 anArray->SetValue(1, anIndices.FindIndex(aValue));
900 anObj = GetEngine()->AddSubShape(theShape, anArray);
901 if (!anObj.IsNull()) {
904 // for python command
905 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
906 anAsciiList += anEntry;
911 //Make a Python command
912 if( anAsciiList.Length() > 0 ) {
913 anAsciiList.Trunc(anAsciiList.Length() - 1);
914 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
915 GEOM::TPythonDump pd (aFunction, true);
916 pd << "[" << anAsciiList.ToCString();
917 pd << "] = geompy.GetGlueFaces(" << theShape << ", " << theTolerance << ")";
926 //=============================================================================
928 * MakeGlueFacesByList
930 //=============================================================================
932 GEOMImpl_IShapesOperations::MakeGlueFacesByList(std::list< Handle(GEOM_Object) >& theShapes,
933 const Standard_Real theTolerance,
934 std::list<Handle(GEOM_Object)> & theFaces,
935 const Standard_Boolean doKeepNonSolids,
936 const Standard_Boolean doGlueAllEdges)
940 Handle(TColStd_HSequenceOfTransient) objects = GEOM_Object::GetLastFunctions( theShapes );
941 if ( objects.IsNull() || objects->IsEmpty() ) {
942 SetErrorCode("NULL argument shape");
945 Handle(TColStd_HSequenceOfTransient) aFaces = GEOM_Object::GetLastFunctions( theFaces );
946 if ( aFaces.IsNull() ) {
947 SetErrorCode("NULL argument shape for the shape construction");
951 //Add a new Glued object
952 Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
954 //Add a new Glue function
955 Handle(GEOM_Function) aFunction;
956 aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_FACES_BY_LIST);
957 if (aFunction.IsNull()) return NULL;
959 //Check if the function is set correctly
960 if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
962 GEOMImpl_IGlue aCI (aFunction);
964 aCI.SetBase( objects );
965 aCI.SetTolerance(theTolerance);
966 aCI.SetKeepNonSolids(doKeepNonSolids);
967 aCI.SetGlueAllEdges(doGlueAllEdges);
968 aCI.SetFaces(aFaces);
970 //Compute the sub-shape value
971 Standard_Boolean isWarning = Standard_False;
974 if (!GetSolver()->ComputeFunction(aFunction)) {
975 SetErrorCode("Shape driver failed to glue faces");
979 catch (Standard_Failure) {
980 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
981 SetErrorCode(aFail->GetMessageString());
982 // to provide warning
983 if (!aFunction->GetValue().IsNull()) {
984 isWarning = Standard_True;
990 //Make a Python command
992 GEOM::TPythonDump pd(aFunction);
993 pd << aGlued << " = geompy.MakeGlueFacesByList("
994 << theShapes << ", " << theTolerance << ", " << theFaces << ", "
995 << (bool)doKeepNonSolids << ", " << (bool)doGlueAllEdges << ")";
997 // to provide warning
998 if (!isWarning) SetErrorCode(OK);
1002 //=============================================================================
1006 //=============================================================================
1008 GEOMImpl_IShapesOperations::MakeGlueEdges (std::list< Handle(GEOM_Object) >& theShapes,
1009 const Standard_Real theTolerance)
1013 Handle(TColStd_HSequenceOfTransient) objects = GEOM_Object::GetLastFunctions( theShapes );
1014 if ( objects.IsNull() || objects->IsEmpty() ) {
1015 SetErrorCode("NULL argument shape");
1019 //Add a new Glued object
1020 Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
1022 //Add a new Glue function
1023 Handle(GEOM_Function) aFunction;
1024 aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_EDGES);
1025 if (aFunction.IsNull()) return NULL;
1027 //Check if the function is set correctly
1028 if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
1030 GEOMImpl_IGlue aCI (aFunction);
1032 aCI.SetBase( objects );
1033 aCI.SetTolerance(theTolerance);
1034 aCI.SetKeepNonSolids(true);
1036 //Compute the sub-shape value
1037 Standard_Boolean isWarning = Standard_False;
1040 if (!GetSolver()->ComputeFunction(aFunction)) {
1041 SetErrorCode("Shape driver failed to glue edges");
1045 catch (Standard_Failure) {
1046 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1047 SetErrorCode(aFail->GetMessageString());
1048 // to provide warning
1049 if (!aFunction->GetValue().IsNull()) {
1050 isWarning = Standard_True;
1056 //Make a Python command
1057 GEOM::TPythonDump(aFunction) << aGlued << " = geompy.MakeGlueEdges("
1058 << theShapes << ", " << theTolerance << ")";
1060 // to provide warning
1061 if (!isWarning) SetErrorCode(OK);
1065 //=============================================================================
1069 //=============================================================================
1070 Handle(TColStd_HSequenceOfTransient)
1071 GEOMImpl_IShapesOperations::GetGlueShapes (std::list< Handle(GEOM_Object) >& theShapes,
1072 const Standard_Real theTolerance,
1073 const TopAbs_ShapeEnum theType)
1077 TopoDS_Shape aShape;
1078 TopTools_SequenceOfShape shapes;
1079 std::list< Handle(GEOM_Object) >::iterator s = theShapes.begin();
1080 Handle(GEOM_Object) lastCreatedGO;
1081 for ( ; s != theShapes.end(); ++s )
1083 Handle(GEOM_Object) go = *s;
1084 if ( go.IsNull() ) return NULL;
1085 aShape = go->GetValue();
1086 if ( aShape.IsNull() ) return NULL;
1087 shapes.Append( aShape );
1088 lastCreatedGO = GEOM::GetCreatedLast( lastCreatedGO, go );
1090 if ( shapes.Length() > 1 )
1092 TopoDS_Compound compound;
1093 BRep_Builder builder;
1094 builder.MakeCompound( compound );
1095 for ( int i = 1; i <= shapes.Length(); ++i )
1096 builder.Add( compound, shapes( i ) );
1101 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1103 GEOMAlgo_GlueDetector aGluer;
1104 aGluer.SetArgument(aShape);
1105 aGluer.SetTolerance(theTolerance);
1107 Standard_Integer iErr = aGluer.ErrorStatus();
1108 if (iErr) return NULL;
1110 std::vector< TopTools_IndexedMapOfShape* > anIndices( shapes.Length(), NULL );
1111 Handle(TColStd_HArray1OfInteger) anArray;
1112 Handle(GEOM_Object) anObj;
1114 TopTools_ListOfShape listOnePerSet;
1116 const TopTools_DataMapOfShapeListOfShape& aImages = aGluer.Images();
1117 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape aItDMSLS (aImages);
1118 for (int index = 1; aItDMSLS.More(); aItDMSLS.Next(), ++index) {
1120 //const TopoDS_Shape& aSkey = aItDMSLS.Key();
1122 // list of shapes of the argument that can be glued
1123 const TopTools_ListOfShape& aLSD = aItDMSLS.Value();
1125 //listShape.Append(aLSD.First());
1126 TopoDS_Shape aValue = aLSD.First();
1128 if (aValue.ShapeType() == theType) {
1129 listOnePerSet.Append(aValue);
1133 // for stable order of returned entities
1134 GEOMUtils::SortShapes(listOnePerSet, Standard_False);
1136 TopTools_ListIteratorOfListOfShape aListIt (listOnePerSet);
1137 for (; aListIt.More(); aListIt.Next())
1139 TopoDS_Shape aValue = aListIt.Value();
1140 // find a shape to add aValue as a sub-shape
1142 s = theShapes.begin();
1143 for ( int i = 0; i < shapes.Length(); ++i, ++s )
1145 Handle(GEOM_Object) object = *s;
1146 if ( !anIndices[i] ) {
1147 anIndices[i] = new TopTools_IndexedMapOfShape;
1148 TopExp::MapShapes( object->GetValue(), *anIndices[i]);
1150 if (int index = anIndices[i]->FindIndex( aValue )) {
1151 anArray = new TColStd_HArray1OfInteger(1,1);
1152 anArray->SetValue(1, index);
1153 anObj = GetEngine()->AddSubShape( object, anArray);
1157 if (!anObj.IsNull())
1158 aSeq->Append(anObj);
1160 for ( size_t i = 0 ; i < anIndices.size(); ++i )
1161 delete anIndices[i];
1163 // Make a Python command
1164 if ( aSeq->Length() > 0)
1166 Handle(GEOM_Function) aFunction = lastCreatedGO->GetLastFunction();
1167 GEOM::TPythonDump pd (aFunction, /*append=*/true);
1169 << " = geompy." << (theType == TopAbs_FACE ? "GetGlueFaces" : "GetGlueEdges" )
1170 << "( " << theShapes << ", " << theTolerance << ")";
1178 //=============================================================================
1180 * MakeGlueEdgesByList
1182 //=============================================================================
1184 GEOMImpl_IShapesOperations::MakeGlueEdgesByList (std::list< Handle(GEOM_Object) >& theShapes,
1185 const Standard_Real theTolerance,
1186 std::list<Handle(GEOM_Object)>& theEdges)
1190 Handle(TColStd_HSequenceOfTransient) objects = GEOM_Object::GetLastFunctions( theShapes );
1191 if ( objects.IsNull() || objects->IsEmpty() ) {
1192 SetErrorCode("NULL argument shape");
1195 Handle(TColStd_HSequenceOfTransient) anEdges = GEOM_Object::GetLastFunctions( theEdges );
1196 if ( anEdges.IsNull() ) {
1197 SetErrorCode("NULL argument shape for the shape construction");
1200 //Add a new Glued object
1201 Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
1203 //Add a new Glue function
1204 Handle(GEOM_Function) aFunction;
1205 aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_EDGES_BY_LIST);
1206 if (aFunction.IsNull()) return NULL;
1208 //Check if the function is set correctly
1209 if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
1211 GEOMImpl_IGlue aCI (aFunction);
1213 aCI.SetBase( objects );
1214 aCI.SetTolerance(theTolerance);
1215 aCI.SetKeepNonSolids(true);
1216 aCI.SetFaces(anEdges);
1218 //Compute the sub-shape value
1219 Standard_Boolean isWarning = Standard_False;
1222 if (!GetSolver()->ComputeFunction(aFunction)) {
1223 SetErrorCode("Shape driver failed to glue edges");
1227 catch (Standard_Failure) {
1228 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1229 SetErrorCode(aFail->GetMessageString());
1230 // to provide warning
1231 if (!aFunction->GetValue().IsNull()) {
1232 isWarning = Standard_True;
1238 //Make a Python command
1240 GEOM::TPythonDump pd (aFunction);
1241 pd << aGlued << " = geompy.MakeGlueEdgesByList("
1242 << theShapes << ", " << theTolerance << ", " << theEdges << " )";
1244 // to provide warning
1245 if (!isWarning) SetErrorCode(OK);
1249 //=============================================================================
1251 * GetExistingSubObjects
1253 //=============================================================================
1254 Handle(TColStd_HSequenceOfTransient)
1255 GEOMImpl_IShapesOperations::GetExistingSubObjects(Handle(GEOM_Object) theShape,
1256 const Standard_Boolean theGroupsOnly)
1258 // note: this method does not return fields
1260 Standard_Integer types = theGroupsOnly ? Groups : Groups|SubShapes;
1261 Handle(TColStd_HSequenceOfTransient) results = GetExistingSubObjects(theShape, types);
1263 if (results->Length() > 0) {
1264 //Make a Python command
1265 TCollection_AsciiString anAsciiList;
1266 for (int i = 1; i <= results->Length(); i++)
1268 Handle(GEOM_BaseObject) obj = Handle(GEOM_BaseObject)::DownCast( results->Value(i));
1269 obj->GetEntryString();
1270 if ( i < results->Length() )
1274 GEOM::TPythonDump pd (theShape->GetLastFunction(), /*append=*/true);
1275 pd << "[" << anAsciiList.ToCString();
1276 pd << "] = geompy.GetExistingSubObjects(";
1277 pd << theShape << ", " << (bool)theGroupsOnly << ")";
1283 Handle(TColStd_HSequenceOfTransient)
1284 GEOMImpl_IShapesOperations::GetExistingSubObjects(Handle(GEOM_Object) theShape,
1285 const Standard_Integer theTypes)
1289 if (theShape.IsNull()) return NULL;
1291 Handle(GEOM_Function) aMainShape = theShape->GetLastFunction();
1292 if (aMainShape.IsNull()) return NULL;
1294 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1295 SetErrorCode(NOT_FOUND_ANY);
1297 if (!aMainShape->HasSubShapeReferences()) return aSeq;
1298 const TDataStd_ListOfExtendedString& aListEntries = aMainShape->GetSubShapeReferences();
1299 if (aListEntries.IsEmpty()) return aSeq;
1303 TDataStd_ListIteratorOfListOfExtendedString anIt (aListEntries);
1304 for (; anIt.More(); anIt.Next()) {
1305 TCollection_ExtendedString anEntry = anIt.Value();
1306 Standard_Integer aStrLen = anEntry.LengthOfCString();
1307 char* anEntryStr = new char[aStrLen+1];
1308 anEntry.ToUTF8CString(anEntryStr);
1309 Handle(GEOM_BaseObject) anObj = GetEngine()->GetObject(GetDocID(), anEntryStr, false);
1310 if (!anObj.IsNull() ) {
1311 bool isGroup = anObj->IsKind(STANDARD_TYPE(GEOM_Object)) && anObj->GetType() == GEOM_GROUP;
1312 bool isSubShape = anObj->IsKind(STANDARD_TYPE(GEOM_Object)) && anObj->GetType() != GEOM_GROUP;
1313 bool isField = anObj->IsKind(STANDARD_TYPE(GEOM_Field));
1314 if (theTypes & Groups && isGroup ||
1315 theTypes & SubShapes && isSubShape ||
1316 theTypes & Fields && isField) {
1317 aSeq->Append(anObj);
1320 delete [] anEntryStr;
1323 if (aSeq->Length() == 0) {
1324 SetErrorCode(NOT_FOUND_ANY);
1333 //=============================================================================
1337 //=============================================================================
1338 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::MakeExplode
1339 (Handle(GEOM_Object) theShape,
1340 const Standard_Integer theShapeType,
1341 const Standard_Boolean isSorted,
1342 const ExplodeType theExplodeType)
1346 if (theShape.IsNull()) return NULL;
1347 TopoDS_Shape aShape = theShape->GetValue();
1348 if (aShape.IsNull()) return NULL;
1350 Handle(GEOM_Function) aMainShape = theShape->GetLastFunction();
1352 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1353 Handle(GEOM_Object) anObj;
1354 TopTools_MapOfShape mapShape;
1355 TopTools_ListOfShape listShape;
1357 if (aShape.ShapeType() == TopAbs_COMPOUND &&
1358 (theShapeType == TopAbs_SHAPE || theShapeType == TopAbs_FLAT || theShapeType == TopAbs_COMPOUND))
1360 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
1361 for (; It.More(); It.Next()) {
1362 TopoDS_Shape SS = It.Value();
1363 if (mapShape.Add(SS)) {
1364 if (theShapeType == TopAbs_FLAT) {
1365 AddFlatSubShapes(SS, listShape, mapShape);
1367 else if (theShapeType == TopAbs_SHAPE || theShapeType == SS.ShapeType()) {
1368 listShape.Append(SS);
1370 // VSR: for EXPLODE_NEW_INCLUDE_MAIN and EXPLODE_OLD_INCLUDE_MAIN:
1371 // it seems it is necessary to add top-level shape if theShapeType == TopAbs_COMPOUND
1375 else if (theExplodeType != EXPLODE_NEW_EXCLUDE_MAIN || aShape.ShapeType() != theShapeType) // issue 0021079
1377 TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
1378 for (; exp.More(); exp.Next())
1379 if (mapShape.Add(exp.Current()))
1380 listShape.Append(exp.Current());
1383 if (listShape.IsEmpty()){
1384 //SetErrorCode("The given shape has no sub-shapes of the requested type");
1385 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
1390 bool isOldSorting = false;
1391 if (theExplodeType == EXPLODE_OLD_INCLUDE_MAIN)
1392 isOldSorting = true;
1393 GEOMUtils::SortShapes(listShape, isOldSorting);
1396 TopTools_IndexedMapOfShape anIndices;
1397 TopExp::MapShapes(aShape, anIndices);
1398 Handle(TColStd_HArray1OfInteger) anArray;
1400 TopTools_ListIteratorOfListOfShape itSub (listShape);
1401 TCollection_AsciiString anAsciiList, anEntry;
1402 for (int index = 1; itSub.More(); itSub.Next(), ++index)
1404 TopoDS_Shape aValue = itSub.Value();
1405 anArray = new TColStd_HArray1OfInteger(1,1);
1406 anArray->SetValue(1, anIndices.FindIndex(aValue));
1408 //anObj = GetEngine()->AddSubShape(theShape, anArray);
1410 anObj = GetEngine()->AddObject(GetDocID(), GEOM_SUBSHAPE);
1411 Handle(GEOM_Function) aFunction = anObj->AddFunction(GEOM_Object::GetSubShapeID(), 1);
1412 if (aFunction.IsNull()) return aSeq;
1414 GEOM_ISubShape aSSI (aFunction);
1415 aSSI.SetMainShape(aMainShape);
1416 aSSI.SetIndices(anArray);
1418 // Set function value directly, as we know it.
1419 // Usage of Solver here would lead to significant loss of time,
1420 // because GEOM_SubShapeDriver will build TopTools_IndexedMapOfShape
1421 // on the main shape for each being calculated sub-shape separately.
1422 aFunction->SetValue(aValue);
1424 // Put this subshape in the list of sub-shapes of theMainShape
1425 aMainShape->AddSubShapeReference(aFunction);
1427 if (!anObj.IsNull()) {
1428 aSeq->Append(anObj);
1430 // for python command
1431 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
1432 anAsciiList += anEntry;
1437 //Make a Python command
1438 anAsciiList.Trunc(anAsciiList.Length() - 1);
1440 GEOM::TPythonDump pd (aMainShape, /*append=*/true);
1441 pd << "[" << anAsciiList.ToCString() << "] = geompy.";
1442 switch (theExplodeType) {
1443 case EXPLODE_NEW_EXCLUDE_MAIN:
1444 pd << "ExtractShapes(" << theShape << ", "
1445 << TopAbs_ShapeEnum(theShapeType) << ", " << (isSorted ? "True" : "False") << ")";
1447 case EXPLODE_NEW_INCLUDE_MAIN:
1448 pd << "SubShapeAll" << (isSorted ? "SortedCentres(" : "(")
1449 << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
1451 case EXPLODE_OLD_INCLUDE_MAIN:
1452 pd << "SubShapeAll" << (isSorted ? "Sorted(" : "(")
1453 << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
1462 //=============================================================================
1466 //=============================================================================
1467 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::SubShapeAllIDs
1468 (Handle(GEOM_Object) theShape,
1469 const Standard_Integer theShapeType,
1470 const Standard_Boolean isSorted,
1471 const ExplodeType theExplodeType)
1475 if (theShape.IsNull()) return NULL;
1476 TopoDS_Shape aShape = theShape->GetValue();
1477 if (aShape.IsNull()) return NULL;
1479 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
1480 TopTools_MapOfShape mapShape;
1481 TopTools_ListOfShape listShape;
1483 if (aShape.ShapeType() == TopAbs_COMPOUND &&
1484 (theShapeType == TopAbs_SHAPE || theShapeType == TopAbs_FLAT || theShapeType == TopAbs_COMPOUND))
1486 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
1487 for (; It.More(); It.Next()) {
1488 TopoDS_Shape SS = It.Value();
1489 if (mapShape.Add(SS)) {
1490 if (theShapeType == TopAbs_FLAT) {
1491 AddFlatSubShapes(SS, listShape, mapShape);
1493 else if (theShapeType == TopAbs_SHAPE || theShapeType == SS.ShapeType()) {
1494 listShape.Append(SS);
1499 else if (theExplodeType != EXPLODE_NEW_EXCLUDE_MAIN || aShape.ShapeType() != theShapeType) // issue 0021079
1501 TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
1502 for (; exp.More(); exp.Next())
1503 if (mapShape.Add(exp.Current()))
1504 listShape.Append(exp.Current());
1507 if (listShape.IsEmpty()) {
1508 //SetErrorCode("The given shape has no sub-shapes of the requested type");
1509 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
1514 bool isOldSorting = false;
1515 if (theExplodeType == EXPLODE_OLD_INCLUDE_MAIN)
1516 isOldSorting = true;
1517 GEOMUtils::SortShapes(listShape, isOldSorting);
1520 TopTools_IndexedMapOfShape anIndices;
1521 TopExp::MapShapes(aShape, anIndices);
1522 Handle(TColStd_HArray1OfInteger) anArray;
1524 TopTools_ListIteratorOfListOfShape itSub (listShape);
1525 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
1526 TopoDS_Shape aValue = itSub.Value();
1527 aSeq->Append(anIndices.FindIndex(aValue));
1530 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
1532 //Make a Python command
1533 GEOM::TPythonDump pd (aFunction, /*append=*/true);
1534 pd << "listSubShapeIDs = geompy.SubShapeAll";
1535 switch (theExplodeType) {
1536 case EXPLODE_NEW_EXCLUDE_MAIN:
1538 case EXPLODE_NEW_INCLUDE_MAIN:
1539 pd << (isSorted ? "SortedCentresIDs(" : "IDs(")
1540 << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
1542 case EXPLODE_OLD_INCLUDE_MAIN:
1543 pd << (isSorted ? "SortedIDs(" : "IDs(")
1544 << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
1553 //=============================================================================
1557 //=============================================================================
1558 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetSubShape
1559 (Handle(GEOM_Object) theMainShape,
1560 const Standard_Integer theID)
1564 if (theMainShape.IsNull()) return NULL;
1566 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
1567 anArray->SetValue(1, theID);
1568 Handle(GEOM_Object) anObj = GetEngine()->AddSubShape(theMainShape, anArray,true);
1569 if (anObj.IsNull()) {
1570 SetErrorCode("Can not get a sub-shape with the given ID");
1574 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1576 //Make a Python command
1577 GEOM::TPythonDump(aFunction) << anObj << " = geompy.GetSubShape("
1578 << theMainShape << ", [" << theID << "])";
1584 //=============================================================================
1588 //=============================================================================
1589 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::MakeSubShapes
1590 (Handle(GEOM_Object) theMainShape,
1591 Handle(TColStd_HArray1OfInteger) theIndices)
1595 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1597 if (!theIndices->Length()) {
1598 SetErrorCode(NOT_FOUND_ANY);
1602 if (theMainShape.IsNull()) return NULL;
1603 TopoDS_Shape aShape = theMainShape->GetValue();
1604 if (aShape.IsNull()) return NULL;
1606 Handle(GEOM_Function) aMainShape = theMainShape->GetLastFunction();
1608 TopTools_IndexedMapOfShape anIndices;
1609 TopExp::MapShapes(aShape, anIndices);
1611 Handle(TColStd_HArray1OfInteger) anArray;
1612 Handle(GEOM_Object) anObj;
1614 TCollection_AsciiString anAsciiList, anEntry;
1615 Standard_Integer i, low = theIndices->Lower(), up = theIndices->Upper();
1616 for (i = low; i <= up; i++) {
1617 int id = theIndices->Value(i);
1618 if (1 <= id && id <= anIndices.Extent()) {
1619 TopoDS_Shape aValue = anIndices.FindKey(id);
1620 anArray = new TColStd_HArray1OfInteger(1,1);
1621 anArray->SetValue(1, id);
1623 anObj = GetEngine()->AddObject(GetDocID(), GEOM_SUBSHAPE);
1624 if (!anObj.IsNull()) {
1625 Handle(GEOM_Function) aFunction = anObj->AddFunction(GEOM_Object::GetSubShapeID(), 1);
1626 if (aFunction.IsNull()) return aSeq;
1628 GEOM_ISubShape aSSI (aFunction);
1629 aSSI.SetMainShape(aMainShape);
1630 aSSI.SetIndices(anArray);
1632 // Set function value directly, as we know it.
1633 // Usage of Solver here would lead to significant loss of time,
1634 // because GEOM_SubShapeDriver will build TopTools_IndexedMapOfShape
1635 // on the main shape for each being calculated sub-shape separately.
1636 aFunction->SetValue(aValue);
1638 // Put this sub-shape in the list of sub-shapes of theMainShape
1639 aMainShape->AddSubShapeReference(aFunction);
1641 aSeq->Append(anObj);
1643 // for python command
1644 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
1645 anAsciiList += anEntry;
1651 //Make a Python command
1652 anAsciiList.Trunc(anAsciiList.Length() - 1);
1654 GEOM::TPythonDump pd (aMainShape, /*append=*/true);
1655 pd << "[" << anAsciiList.ToCString() << "] = geompy.SubShapes("
1656 << theMainShape << ", [" ;
1657 for (i = low; i <= up - 1; i++) {
1658 pd << theIndices->Value(i) << ", ";
1660 pd << theIndices->Value(up) << "])";
1667 //=============================================================================
1671 //=============================================================================
1672 Standard_Integer GEOMImpl_IShapesOperations::GetSubShapeIndex (Handle(GEOM_Object) theMainShape,
1673 Handle(GEOM_Object) theSubShape)
1677 TopoDS_Shape aMainShape = theMainShape->GetValue();
1678 TopoDS_Shape aSubShape = theSubShape->GetValue();
1680 if (aMainShape.IsNull() || aSubShape.IsNull()) return -1;
1682 TopTools_IndexedMapOfShape anIndices;
1683 TopExp::MapShapes(aMainShape, anIndices);
1684 // if (anIndices.Contains(aSubShape)) {
1685 // SetErrorCode(OK);
1686 // return anIndices.FindIndex(aSubShape);
1688 int id = anIndices.FindIndex(aSubShape);
1699 //=============================================================================
1701 * GetSubShapeIndices
1703 //=============================================================================
1704 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetSubShapesIndices (Handle(GEOM_Object) theMainShape,
1705 std::list<Handle(GEOM_Object)> theSubShapes)
1707 MESSAGE("GEOMImpl_IShapesOperations::GetSubShapesIndices")
1710 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
1712 TopoDS_Shape aMainShape = theMainShape->GetValue();
1713 if (aMainShape.IsNull())
1715 MESSAGE("NULL main shape")
1719 TopTools_IndexedMapOfShape anIndices;
1720 TopExp::MapShapes(aMainShape, anIndices);
1722 std::list<Handle(GEOM_Object)>::iterator it;
1723 for (it=theSubShapes.begin(); it != theSubShapes.end(); ++it)
1725 TopoDS_Shape aSubShape = (*it)->GetValue();
1726 if (aSubShape.IsNull())
1728 MESSAGE("NULL subshape")
1731 int id = anIndices.FindIndex(aSubShape);
1740 //=============================================================================
1744 //=============================================================================
1745 Standard_Integer GEOMImpl_IShapesOperations::GetTopologyIndex (Handle(GEOM_Object) theMainShape,
1746 Handle(GEOM_Object) theSubShape)
1750 TopoDS_Shape aMainShape = theMainShape->GetValue();
1751 TopoDS_Shape aSubShape = theSubShape->GetValue();
1753 if (aMainShape.IsNull() || aSubShape.IsNull()) {
1754 SetErrorCode("Null argument shape given");
1759 if (aSubShape.ShapeType() == TopAbs_COMPOUND) {
1761 TopTools_ListOfShape CL;
1762 CL.Append(aMainShape);
1763 TopTools_ListIteratorOfListOfShape itC;
1764 for (itC.Initialize(CL); itC.More(); itC.Next()) {
1765 for (it.Initialize(itC.Value()); it.More(); it.Next()) {
1766 if (it.Value().ShapeType() == TopAbs_COMPOUND) {
1767 if (it.Value().IsSame(aSubShape))
1771 CL.Append(it.Value());
1776 TopExp_Explorer anExp (aMainShape, aSubShape.ShapeType());
1777 TopTools_MapOfShape M;
1778 for (; anExp.More(); anExp.Next()) {
1779 if (M.Add(anExp.Current())) {
1780 if (anExp.Current().IsSame(aSubShape))
1787 SetErrorCode("The sub-shape does not belong to the main shape");
1791 //=============================================================================
1793 * GetShapeTypeString
1795 //=============================================================================
1796 TCollection_AsciiString GEOMImpl_IShapesOperations::GetShapeTypeString (Handle(GEOM_Object) theShape)
1800 TCollection_AsciiString aTypeName ("Null Shape");
1802 TopoDS_Shape aShape = theShape->GetValue();
1803 if (aShape.IsNull())
1806 switch (aShape.ShapeType() )
1808 case TopAbs_COMPOUND:
1809 aTypeName = "Compound";
1811 case TopAbs_COMPSOLID:
1812 aTypeName = "Compound Solid";
1815 aTypeName = "Solid";
1818 aTypeName = "Shell";
1822 BRepAdaptor_Surface surf (TopoDS::Face(aShape));
1823 if (surf.GetType() == GeomAbs_Plane)
1824 aTypeName = "Plane";
1825 else if (surf.GetType() == GeomAbs_Cylinder)
1826 aTypeName = "Cylindrical Face";
1827 else if (surf.GetType() == GeomAbs_Sphere)
1828 aTypeName = "Spherical Face";
1829 else if (surf.GetType() == GeomAbs_Torus)
1830 aTypeName = "Toroidal Face";
1831 else if (surf.GetType() == GeomAbs_Cone)
1832 aTypeName = "Conical Face";
1834 aTypeName = "GEOM::FACE";
1842 BRepAdaptor_Curve curv (TopoDS::Edge(aShape));
1843 if (curv.GetType() == GeomAbs_Line) {
1844 if ((Abs(curv.FirstParameter()) >= 1E6) ||
1845 (Abs(curv.LastParameter()) >= 1E6))
1849 } else if (curv.GetType() == GeomAbs_Circle) {
1850 if (curv.IsClosed())
1851 aTypeName = "Circle";
1860 aTypeName = "Vertex";
1863 aTypeName = "Shape";
1866 aTypeName = "Shape of unknown type";
1872 //=============================================================================
1876 //=============================================================================
1877 Standard_Integer GEOMImpl_IShapesOperations::NumberOfSubShapes
1878 (Handle(GEOM_Object) theShape,
1879 const Standard_Integer theShapeType)
1882 Standard_Integer nbShapes = 0;
1884 if (theShape.IsNull()) return -1;
1885 TopoDS_Shape aShape = theShape->GetValue();
1886 if (aShape.IsNull()) return -1;
1889 TopTools_MapOfShape mapShape;
1891 if (aShape.ShapeType() == TopAbs_COMPOUND &&
1892 (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
1893 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPSOLID ||
1894 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPOUND)) {
1895 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
1896 for (; It.More(); It.Next()) {
1897 if (mapShape.Add(It.Value())) {
1898 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
1899 TopAbs_ShapeEnum(theShapeType) == It.Value().ShapeType()) {
1905 TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
1906 for (; exp.More(); exp.Next())
1907 if (mapShape.Add(exp.Current()))
1913 if (theShapeType == TopAbs_FLAT) {
1914 TopTools_MapOfShape aMapOfShape;
1915 TopTools_ListOfShape aListOfShape;
1916 AddFlatSubShapes(aShape, aListOfShape, aMapOfShape);
1917 nbShapes = aListOfShape.Extent();
1921 int iType, nbTypes [TopAbs_SHAPE];
1922 for (iType = 0; iType < TopAbs_SHAPE; ++iType)
1924 nbTypes[aShape.ShapeType()]++;
1926 TopTools_MapOfShape aMapOfShape;
1927 aMapOfShape.Add(aShape);
1928 TopTools_ListOfShape aListOfShape;
1929 aListOfShape.Append(aShape);
1931 TopTools_ListIteratorOfListOfShape itL (aListOfShape);
1932 for (; itL.More(); itL.Next()) {
1933 TopoDS_Iterator it (itL.Value());
1934 for (; it.More(); it.Next()) {
1935 TopoDS_Shape s = it.Value();
1936 if (aMapOfShape.Add(s)) {
1937 aListOfShape.Append(s);
1938 nbTypes[s.ShapeType()]++;
1943 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE)
1944 nbShapes = aMapOfShape.Extent();
1946 nbShapes = nbTypes[theShapeType];
1949 catch (Standard_Failure) {
1950 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1951 SetErrorCode(aFail->GetMessageString());
1959 //=============================================================================
1963 //=============================================================================
1964 Handle(GEOM_Object) GEOMImpl_IShapesOperations::ReverseShape(Handle(GEOM_Object) theShape)
1968 if (theShape.IsNull()) return NULL;
1971 //Add a new reversed object
1972 Handle(GEOM_Object) aReversed = GetEngine()->AddObject(GetDocID(), theShape->GetType());
1974 //Add a new Revese function
1975 Handle(GEOM_Function) aFunction;
1976 aFunction = aReversed->AddFunction(GEOMImpl_ShapeDriver::GetID(), REVERSE_ORIENTATION);
1977 if (aFunction.IsNull()) return NULL;
1979 //Check if the function is set correctly
1980 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
1982 GEOMImpl_IShapes aSI (aFunction);
1984 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
1985 if (aRefShape.IsNull()) return NULL;
1987 aSI.SetBase(aRefShape);
1989 //Compute the sub-shape value
1992 if (!GetSolver()->ComputeFunction(aFunction)) {
1993 SetErrorCode("Shape driver failed to reverse shape");
1997 catch (Standard_Failure) {
1998 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1999 SetErrorCode(aFail->GetMessageString());
2003 //Make a Python command
2004 GEOM::TPythonDump(aFunction) << aReversed
2005 << " = geompy.ChangeOrientation(" << theShape << ")";
2010 Handle(GEOM_Object) aReversed;
2012 GEOM_Engine* anEngine = GetEngine();
2013 //GEOMImpl_Gen* aGen = dynamic_cast<GEOMImpl_Gen*>(anEngine);
2014 GEOMImpl_Gen* aGen = (GEOMImpl_Gen*)anEngine;
2017 GEOMImpl_IHealingOperations* anIHealingOperations =
2018 aGen->GetIHealingOperations(GetDocID());
2019 aReversed = anIHealingOperations->ChangeOrientationCopy(theShape);
2020 SetErrorCode(anIHealingOperations->GetErrorCode());
2026 //=============================================================================
2030 //=============================================================================
2031 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetFreeFacesIDs
2032 (Handle(GEOM_Object) theShape)
2036 if (theShape.IsNull()) return NULL;
2037 TopoDS_Shape aShape = theShape->GetValue();
2038 if (aShape.IsNull()) return NULL;
2040 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
2042 TopTools_IndexedDataMapOfShapeListOfShape mapFaceBlocks;
2043 GEOMImpl_Block6Explorer::MapShapesAndAncestors
2044 (aShape, TopAbs_FACE, TopAbs_SOLID, mapFaceBlocks);
2046 Standard_Integer ind = 1, nbFaces = mapFaceBlocks.Extent();
2049 SetErrorCode("The given shape has no faces");
2053 TopTools_IndexedMapOfShape anIndices;
2054 TopExp::MapShapes(aShape, anIndices);
2056 Standard_Integer id;
2057 for (; ind <= nbFaces; ind++) {
2058 if (mapFaceBlocks.FindFromIndex(ind).Extent() != 2) {
2059 id = anIndices.FindIndex(mapFaceBlocks.FindKey(ind));
2064 //The explode doesn't change object so no new function is required.
2065 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
2067 //Make a Python command
2068 GEOM::TPythonDump(aFunction, /*append=*/true)
2069 << "listFreeFacesIDs = geompy.GetFreeFacesIDs(" << theShape << ")";
2075 //=======================================================================
2076 //function : GetSharedShapes
2078 //=======================================================================
2079 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetSharedShapes
2080 (Handle(GEOM_Object) theShape1,
2081 Handle(GEOM_Object) theShape2,
2082 const Standard_Integer theShapeType)
2086 if (theShape1.IsNull() || theShape2.IsNull()) return NULL;
2088 TopoDS_Shape aShape1 = theShape1->GetValue();
2089 TopoDS_Shape aShape2 = theShape2->GetValue();
2091 if (aShape1.IsNull() || aShape2.IsNull()) return NULL;
2093 TopTools_IndexedMapOfShape anIndices;
2094 TopExp::MapShapes(aShape1, anIndices);
2095 Handle(TColStd_HArray1OfInteger) anArray;
2097 TopTools_IndexedMapOfShape mapShape1;
2098 TopExp::MapShapes(aShape1, TopAbs_ShapeEnum(theShapeType), mapShape1);
2100 Handle(GEOM_Object) anObj;
2101 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
2102 TCollection_AsciiString anAsciiList, anEntry;
2104 TopTools_MapOfShape mapShape2;
2105 TopExp_Explorer exp (aShape2, TopAbs_ShapeEnum(theShapeType));
2106 for (; exp.More(); exp.Next()) {
2107 TopoDS_Shape aSS = exp.Current();
2108 if (mapShape2.Add(aSS) && mapShape1.Contains(aSS)) {
2109 anArray = new TColStd_HArray1OfInteger(1,1);
2110 anArray->SetValue(1, anIndices.FindIndex(aSS));
2111 anObj = GetEngine()->AddSubShape(theShape1, anArray);
2112 aSeq->Append(anObj);
2114 // for python command
2115 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
2116 anAsciiList += anEntry;
2121 if (aSeq->IsEmpty()) {
2122 SetErrorCode("The given shapes have no shared sub-shapes of the requested type");
2126 //Make a Python command
2127 anAsciiList.Trunc(anAsciiList.Length() - 1);
2129 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2131 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
2132 << "] = geompy.GetSharedShapes(" << theShape1 << ", "
2133 << theShape2 << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
2139 //=======================================================================
2140 //function : GetSharedShapes
2142 //=======================================================================
2143 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetSharedShapes
2144 (std::list<Handle(GEOM_Object)> & theShapes,
2145 const Standard_Integer theShapeType)
2149 int aLen = theShapes.size();
2150 if (aLen < 1) return NULL;
2153 std::list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
2155 Handle(GEOM_Object) aMainObj = *it;
2156 Handle(GEOM_Function) aMainShape = aMainObj->GetLastFunction();
2158 TopTools_SequenceOfShape shapeSeq;
2159 for (; it != theShapes.end(); it++, ind++) {
2160 Handle(GEOM_Function) aRefShape = (*it)->GetLastFunction();
2161 if (aRefShape.IsNull()) {
2162 SetErrorCode("NULL shape for GetSharedShapes");
2165 TopoDS_Shape aShape2 = aRefShape->GetValue();
2166 if (aShape2.IsNull()) return NULL;
2167 shapeSeq.Append( aShape2 );
2170 TopoDS_Shape aShape1 = shapeSeq.First();
2172 if ( shapeSeq.Length() == 1 )
2175 for ( TopoDS_Iterator it( aShape1); it.More(); it.Next() )
2176 shapeSeq.Append( it.Value() );
2177 aShape1 = shapeSeq.First();
2180 TopTools_IndexedMapOfShape anIndices;
2181 TopExp::MapShapes(aMainShape->GetValue(), anIndices);
2183 TopTools_IndexedMapOfShape mapSelected;
2184 TopExp::MapShapes(aShape1, TopAbs_ShapeEnum(theShapeType), mapSelected);
2186 // Find shared shapes
2188 TopoDS_Compound aCurrSelection;
2190 for ( ind = 2; ind <= shapeSeq.Length(); ind++) {
2192 TopoDS_Compound aCompound;
2193 B.MakeCompound(aCompound);
2195 const TopoDS_Shape& aShape2 = shapeSeq.Value( ind );
2197 TopTools_MapOfShape mapShape2;
2198 TopExp_Explorer exp (aShape2, TopAbs_ShapeEnum(theShapeType));
2199 for (; exp.More(); exp.Next()) {
2200 const TopoDS_Shape& aSS = exp.Current();
2201 if (mapShape2.Add(aSS) && mapSelected.Contains(aSS)) {
2202 B.Add(aCompound, aSS);
2206 mapSelected.Clear();
2207 TopExp::MapShapes(aCompound, TopAbs_ShapeEnum(theShapeType), mapSelected);
2208 aCurrSelection = aCompound;
2211 // Create GEOM_Object for each found shared shape (collected in aCurrSelection)
2212 Handle(GEOM_Object) anObj, aLastCreated;
2213 Handle(TColStd_HArray1OfInteger) anArray;
2214 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
2215 TCollection_AsciiString anAsciiList, anEntry;
2217 TopoDS_Iterator itSel (aCurrSelection, Standard_True, Standard_True);
2218 for (; itSel.More(); itSel.Next()) {
2219 anArray = new TColStd_HArray1OfInteger(1,1);
2220 anArray->SetValue(1, anIndices.FindIndex(itSel.Value()));
2221 anObj = GetEngine()->AddSubShape(aMainObj, anArray);
2222 aSeq->Append(anObj);
2224 aLastCreated = GEOM::GetCreatedLast( aLastCreated, anObj );
2226 // for python command
2227 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
2228 anAsciiList += anEntry;
2232 if (aSeq->IsEmpty()) {
2233 SetErrorCode("The given shapes have no shared sub-shapes of the requested type");
2237 // Make a Python command
2238 anAsciiList.Trunc(anAsciiList.Length() - 1);
2240 // IPAL22904: TC6.5.0: order of python commands is wrong after dump study
2241 // Get the function of the latest published object
2242 Handle(GEOM_Function) aFunction = aLastCreated->GetLastFunction();
2243 if( aFunction.IsNull() ) // just in case
2244 aFunction = aMainShape;
2246 GEOM::TPythonDump pd (aFunction, /*append=*/true);
2247 pd << "[" << anAsciiList.ToCString()
2248 << "] = geompy.GetSharedShapesMulti([";
2250 it = theShapes.begin();
2252 while (it != theShapes.end()) {
2253 pd << ", " << (*it++);
2256 pd << "], " << TopAbs_ShapeEnum(theShapeType) << ")";
2262 //=============================================================================
2266 //=============================================================================
2267 static GEOM::TPythonDump& operator<< (GEOM::TPythonDump& theDump,
2268 const GEOMAlgo_State theState)
2271 case GEOMAlgo_ST_IN:
2272 theDump << "GEOM.ST_IN";
2274 case GEOMAlgo_ST_OUT:
2275 theDump << "GEOM.ST_OUT";
2277 case GEOMAlgo_ST_ON:
2278 theDump << "GEOM.ST_ON";
2280 case GEOMAlgo_ST_ONIN:
2281 theDump << "GEOM.ST_ONIN";
2283 case GEOMAlgo_ST_ONOUT:
2284 theDump << "GEOM.ST_ONOUT";
2287 theDump << "GEOM.ST_UNKNOWN";
2293 //=======================================================================
2294 //function : checkTypeShapesOn
2296 * \brief Checks if theShapeType parameter of GetShapesOnXXX() is OK
2297 * \param theShapeType - the shape type to check
2298 * \retval bool - result of the check
2300 //=======================================================================
2301 bool GEOMImpl_IShapesOperations::checkTypeShapesOn(const Standard_Integer theShapeType)
2303 if (theShapeType != TopAbs_VERTEX &&
2304 theShapeType != TopAbs_EDGE &&
2305 theShapeType != TopAbs_FACE &&
2306 theShapeType != TopAbs_SOLID) {
2307 SetErrorCode("Only solids, vertices, edges or faces can be found by this method");
2313 //=======================================================================
2314 //function : makePlane
2316 * \brief Creates Geom_Plane
2317 * \param theAx1 - shape object defining plane parameters
2318 * \retval Handle(Geom_Surface) - resulting surface
2320 //=======================================================================
2321 Handle(Geom_Surface) GEOMImpl_IShapesOperations::makePlane(const TopoDS_Shape& anAx1)
2323 if (anAx1.ShapeType() != TopAbs_EDGE) return NULL;
2324 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
2325 TopoDS_Vertex V1, V2;
2326 TopExp::Vertices(anEdge, V1, V2, Standard_True);
2327 if (V1.IsNull() || V2.IsNull()) {
2328 SetErrorCode("Bad edge given for the plane normal vector");
2331 gp_Pnt aLoc = BRep_Tool::Pnt(V1);
2332 gp_Vec aVec (aLoc, BRep_Tool::Pnt(V2));
2333 if (aVec.Magnitude() < Precision::Confusion()) {
2334 SetErrorCode("Vector with null magnitude given");
2337 return new Geom_Plane(aLoc, aVec);
2340 //=======================================================================
2341 //function : makeCylinder
2343 * \brief Creates Geom_CylindricalSurface
2344 * \param theAx1 - edge defining cylinder axis
2345 * \param theRadius - cylinder radius
2346 * \retval Handle(Geom_Surface) - resulting surface
2348 //=======================================================================
2349 Handle(Geom_Surface) GEOMImpl_IShapesOperations::makeCylinder(const TopoDS_Shape& anAxis,
2350 const Standard_Real theRadius)
2352 //Axis of the cylinder
2353 if (anAxis.ShapeType() != TopAbs_EDGE) {
2354 SetErrorCode("Not an edge given for the axis");
2357 TopoDS_Edge anEdge = TopoDS::Edge(anAxis);
2358 TopoDS_Vertex V1, V2;
2359 TopExp::Vertices(anEdge, V1, V2, Standard_True);
2360 if (V1.IsNull() || V2.IsNull()) {
2361 SetErrorCode("Bad edge given for the axis");
2364 gp_Pnt aLoc = BRep_Tool::Pnt(V1);
2365 gp_Vec aVec (aLoc, BRep_Tool::Pnt(V2));
2366 if (aVec.Magnitude() < Precision::Confusion()) {
2367 SetErrorCode("Vector with null magnitude given");
2371 gp_Ax3 anAx3 (aLoc, aVec);
2372 return new Geom_CylindricalSurface(anAx3, theRadius);
2375 //=======================================================================
2376 //function : getShapesOnBoxIDs
2378 * \brief Find IDs of sub-shapes complying with given status about surface
2379 * \param theBox - the box to check state of sub-shapes against
2380 * \param theShape - the shape to explore
2381 * \param theShapeType - type of sub-shape of theShape
2382 * \param theState - required state
2383 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
2385 //=======================================================================
2386 Handle(TColStd_HSequenceOfInteger)
2387 GEOMImpl_IShapesOperations::getShapesOnBoxIDs(const Handle(GEOM_Object)& theBox,
2388 const Handle(GEOM_Object)& theShape,
2389 const Standard_Integer theShapeType,
2390 GEOMAlgo_State theState)
2392 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
2394 TopoDS_Shape aBox = theBox->GetValue();
2395 TopoDS_Shape aShape = theShape->GetValue();
2397 // Check presence of triangulation, build if need
2398 if (!GEOMUtils::CheckTriangulation(aShape)) {
2399 SetErrorCode("Cannot build triangulation on the shape");
2404 GEOMAlgo_FinderShapeOn2 aFinder;
2405 Standard_Real aTol = 0.0001; // default value
2407 Handle(GEOMAlgo_ClsfBox) aClsfBox = new GEOMAlgo_ClsfBox;
2408 aClsfBox->SetBox(aBox);
2410 aFinder.SetShape(aShape);
2411 aFinder.SetTolerance(aTol);
2412 aFinder.SetClsf(aClsfBox);
2413 aFinder.SetShapeType( (TopAbs_ShapeEnum)theShapeType );
2414 aFinder.SetState(theState);
2417 // Interprete results
2418 Standard_Integer iErr = aFinder.ErrorStatus();
2419 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
2421 MESSAGE(" iErr : " << iErr);
2422 TCollection_AsciiString aMsg (" iErr : ");
2423 aMsg += TCollection_AsciiString(iErr);
2427 Standard_Integer iWrn = aFinder.WarningStatus();
2428 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
2430 MESSAGE(" *** iWrn : " << iWrn);
2433 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
2435 if (listSS.Extent() < 1) {
2436 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
2437 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
2441 // Fill sequence of object IDs
2442 aSeqOfIDs = new TColStd_HSequenceOfInteger;
2444 TopTools_IndexedMapOfShape anIndices;
2445 TopExp::MapShapes(aShape, anIndices);
2447 TopTools_ListIteratorOfListOfShape itSub (listSS);
2448 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
2449 int id = anIndices.FindIndex(itSub.Value());
2450 aSeqOfIDs->Append(id);
2456 //=======================================================================
2457 //function : GetShapesOnBoxIDs
2459 * \brief Find sub-shapes complying with given status about surface
2460 * \param theBox - the box to check state of sub-shapes against
2461 * \param theShape - the shape to explore
2462 * \param theShapeType - type of sub-shape of theShape
2463 * \param theState - required state
2464 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
2466 //=======================================================================
2467 Handle(TColStd_HSequenceOfInteger)
2468 GEOMImpl_IShapesOperations::GetShapesOnBoxIDs(const Handle(GEOM_Object)& theBox,
2469 const Handle(GEOM_Object)& theShape,
2470 const Standard_Integer theShapeType,
2471 GEOMAlgo_State theState)
2473 // Find sub-shapes ids
2474 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2475 getShapesOnBoxIDs (theBox, theShape, theShapeType, theState);
2476 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2479 // The GetShapesOnBox() doesn't change object so no new function is required.
2480 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theBox)->GetLastFunction();
2482 // Make a Python command
2483 GEOM::TPythonDump(aFunction, /*append=*/true)
2484 << "listShapesOnBoxIDs = geompy.GetShapesOnBoxIDs("
2487 << TopAbs_ShapeEnum(theShapeType) << ", "
2494 //=======================================================================
2495 //function : GetShapesOnBox
2497 * \brief Find sub-shapes complying with given status about surface
2498 * \param theBox - the box to check state of sub-shapes against
2499 * \param theShape - the shape to explore
2500 * \param theShapeType - type of sub-shape of theShape
2501 * \param theState - required state
2502 * \retval Handle(TColStd_HSequenceOfTransient) - found sub-shapes
2504 //=======================================================================
2505 Handle(TColStd_HSequenceOfTransient)
2506 GEOMImpl_IShapesOperations::GetShapesOnBox(const Handle(GEOM_Object)& theBox,
2507 const Handle(GEOM_Object)& theShape,
2508 const Standard_Integer theShapeType,
2509 GEOMAlgo_State theState)
2511 // Find sub-shapes ids
2512 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2513 getShapesOnBoxIDs (theBox, theShape, theShapeType, theState);
2514 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2517 // Find objects by indices
2518 TCollection_AsciiString anAsciiList;
2519 Handle(TColStd_HSequenceOfTransient) aSeq;
2520 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
2521 if ( aSeq.IsNull() || aSeq->IsEmpty() )
2524 // Make a Python command
2526 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2527 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2529 GEOM::TPythonDump(aFunction)
2530 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnBox("
2533 << TopAbs_ShapeEnum(theShapeType) << ", "
2540 //=======================================================================
2541 //function : getShapesOnShapeIDs
2543 * \brief Find IDs of sub-shapes complying with given status about surface
2544 * \param theCheckShape - the shape to check state of sub-shapes against
2545 * \param theShape - the shape to explore
2546 * \param theShapeType - type of sub-shape of theShape
2547 * \param theState - required state
2548 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
2550 //=======================================================================
2551 Handle(TColStd_HSequenceOfInteger)
2552 GEOMImpl_IShapesOperations::getShapesOnShapeIDs
2553 (const Handle(GEOM_Object)& theCheckShape,
2554 const Handle(GEOM_Object)& theShape,
2555 const Standard_Integer theShapeType,
2556 GEOMAlgo_State theState)
2558 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
2560 TopoDS_Shape aCheckShape = theCheckShape->GetValue();
2561 TopoDS_Shape aShape = theShape->GetValue();
2562 TopTools_ListOfShape res;
2564 // Check presence of triangulation, build if need
2565 if (!GEOMUtils::CheckTriangulation(aShape)) {
2566 SetErrorCode("Cannot build triangulation on the shape");
2571 GEOMAlgo_FinderShapeOn2 aFinder;
2572 Standard_Real aTol = 0.0001; // default value
2574 Handle(GEOMAlgo_ClsfSolid) aClsfSolid = new GEOMAlgo_ClsfSolid;
2575 aClsfSolid->SetShape(aCheckShape);
2577 aFinder.SetShape(aShape);
2578 aFinder.SetTolerance(aTol);
2579 aFinder.SetClsf(aClsfSolid);
2580 aFinder.SetShapeType( (TopAbs_ShapeEnum)theShapeType );
2581 aFinder.SetState(theState);
2584 // Interprete results
2585 Standard_Integer iErr = aFinder.ErrorStatus();
2586 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
2589 SetErrorCode("theCheckShape must be a solid");
2592 MESSAGE(" iErr : " << iErr);
2593 TCollection_AsciiString aMsg (" iErr : ");
2594 aMsg += TCollection_AsciiString(iErr);
2599 Standard_Integer iWrn = aFinder.WarningStatus();
2600 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
2602 MESSAGE(" *** iWrn : " << iWrn);
2605 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
2607 if (listSS.Extent() < 1) {
2608 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
2609 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
2612 // Fill sequence of object IDs
2613 aSeqOfIDs = new TColStd_HSequenceOfInteger;
2615 TopTools_IndexedMapOfShape anIndices;
2616 TopExp::MapShapes(aShape, anIndices);
2618 TopTools_ListIteratorOfListOfShape itSub (listSS);
2619 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
2620 int id = anIndices.FindIndex(itSub.Value());
2621 aSeqOfIDs->Append(id);
2627 //=======================================================================
2628 //function : GetShapesOnShapeIDs
2630 * \brief Find sub-shapes complying with given status about surface
2631 * \param theCheckShape - the shape to check state of sub-shapes against
2632 * \param theShape - the shape to explore
2633 * \param theShapeType - type of sub-shape of theShape
2634 * \param theState - required state
2635 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
2637 //=======================================================================
2638 Handle(TColStd_HSequenceOfInteger)
2639 GEOMImpl_IShapesOperations::GetShapesOnShapeIDs
2640 (const Handle(GEOM_Object)& theCheckShape,
2641 const Handle(GEOM_Object)& theShape,
2642 const Standard_Integer theShapeType,
2643 GEOMAlgo_State theState)
2645 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2646 getShapesOnShapeIDs (theCheckShape, theShape, theShapeType, theState);
2648 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2651 // The GetShapesOnShape() doesn't change object so no new function is required.
2652 Handle(GEOM_Function) aFunction =
2653 GEOM::GetCreatedLast(theShape,theCheckShape)->GetLastFunction();
2655 // Make a Python command
2656 GEOM::TPythonDump(aFunction, /*append=*/true)
2657 << "listShapesOnBoxIDs = geompy.GetShapesOnShapeIDs("
2658 << theCheckShape << ", "
2660 << TopAbs_ShapeEnum(theShapeType) << ", "
2667 //=======================================================================
2668 //function : GetShapesOnShape
2670 * \brief Find sub-shapes complying with given status about surface
2671 * \param theCheckShape - the shape to check state of sub-shapes against
2672 * \param theShape - the shape to explore
2673 * \param theShapeType - type of sub-shape of theShape
2674 * \param theState - required state
2675 * \retval Handle(TColStd_HSequenceOfTransient) - found sub-shapes
2677 //=======================================================================
2678 Handle(TColStd_HSequenceOfTransient)
2679 GEOMImpl_IShapesOperations::GetShapesOnShape
2680 (const Handle(GEOM_Object)& theCheckShape,
2681 const Handle(GEOM_Object)& theShape,
2682 const Standard_Integer theShapeType,
2683 GEOMAlgo_State theState)
2685 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2686 getShapesOnShapeIDs (theCheckShape, theShape, theShapeType, theState);
2687 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2690 // Find objects by indices
2691 TCollection_AsciiString anAsciiList;
2692 Handle(TColStd_HSequenceOfTransient) aSeq;
2693 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
2695 if ( aSeq.IsNull() || aSeq->IsEmpty() )
2698 // Make a Python command
2700 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2701 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2703 GEOM::TPythonDump(aFunction)
2704 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnShape("
2705 << theCheckShape << ", "
2707 << TopAbs_ShapeEnum(theShapeType) << ", "
2714 //=======================================================================
2715 //function : GetShapesOnShapeAsCompound
2716 //=======================================================================
2717 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetShapesOnShapeAsCompound
2718 (const Handle(GEOM_Object)& theCheckShape,
2719 const Handle(GEOM_Object)& theShape,
2720 const Standard_Integer theShapeType,
2721 GEOMAlgo_State theState)
2723 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2724 getShapesOnShapeIDs (theCheckShape, theShape, theShapeType, theState);
2726 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2729 // Find objects by indices
2730 TCollection_AsciiString anAsciiList;
2731 Handle(TColStd_HSequenceOfTransient) aSeq;
2732 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
2734 if ( aSeq.IsNull() || aSeq->IsEmpty() )
2737 TopoDS_Compound aCompound;
2739 B.MakeCompound(aCompound);
2741 for(; i<=aSeq->Length(); i++) {
2742 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(aSeq->Value(i));
2743 TopoDS_Shape aShape_i = anObj->GetValue();
2744 B.Add(aCompound,aShape_i);
2747 //Add a new result object
2748 Handle(GEOM_Object) aRes = GetEngine()->AddObject(GetDocID(), GEOM_SHAPES_ON_SHAPE);
2749 Handle(GEOM_Function) aFunction =
2750 aRes->AddFunction(GEOMImpl_ShapeDriver::GetID(), SHAPES_ON_SHAPE);
2751 aFunction->SetValue(aCompound);
2754 aSeq->Append( theCheckShape->GetLastFunction() );
2755 aSeq->Append( theShape->GetLastFunction() );
2757 GEOMImpl_IShapes aCI( aFunction );
2758 aCI.SetShapes( aSeq );
2759 aCI.SetSubShapeType( theShapeType );
2760 aCI.SetTolerance( theState );
2762 GEOM::TPythonDump(aFunction)
2763 << aRes << " = geompy.GetShapesOnShapeAsCompound("
2764 << theCheckShape << ", "
2766 << TopAbs_ShapeEnum(theShapeType) << ", "
2774 //=======================================================================
2775 //function : getShapesOnSurfaceIDs
2777 * \brief Find IDs of sub-shapes complying with given status about surface
2778 * \param theSurface - the surface to check state of sub-shapes against
2779 * \param theShape - the shape to explore
2780 * \param theShapeType - type of sub-shape of theShape
2781 * \param theState - required state
2782 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
2784 //=======================================================================
2785 Handle(TColStd_HSequenceOfInteger)
2786 GEOMImpl_IShapesOperations::getShapesOnSurfaceIDs(const Handle(Geom_Surface)& theSurface,
2787 const TopoDS_Shape& theShape,
2788 TopAbs_ShapeEnum theShapeType,
2789 GEOMAlgo_State theState)
2791 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
2793 // Check presence of triangulation, build if need
2794 if (!GEOMUtils::CheckTriangulation(theShape)) {
2795 SetErrorCode("Cannot build triangulation on the shape");
2799 // BEGIN: Mantis issue 0020961: Error on a pipe T-Shape
2800 // Compute tolerance
2801 Standard_Real T, VertMax = -RealLast();
2804 for (TopExp_Explorer ExV (theShape, TopAbs_VERTEX); ExV.More(); ExV.Next()) {
2805 TopoDS_Vertex Vertex = TopoDS::Vertex(ExV.Current());
2806 T = BRep_Tool::Tolerance(Vertex);
2811 catch (Standard_Failure) {
2812 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2813 SetErrorCode(aFail->GetMessageString());
2816 // END: Mantis issue 0020961
2819 GEOMAlgo_FinderShapeOn1 aFinder;
2820 //Standard_Real aTol = 0.0001; // default value
2821 Standard_Real aTol = VertMax; // Mantis issue 0020961
2823 aFinder.SetShape(theShape);
2824 aFinder.SetTolerance(aTol);
2825 aFinder.SetSurface(theSurface);
2826 aFinder.SetShapeType(theShapeType);
2827 aFinder.SetState(theState);
2829 // Sets the minimal number of inner points for the faces that do not have own
2830 // inner points at all (for e.g. rectangular planar faces have just 2 triangles).
2832 aFinder.SetNbPntsMin(3);
2833 // Sets the maximal number of inner points for edges or faces.
2834 // It is usefull for the cases when this number is very big (e.g =2000) to improve
2835 // the performance. If this value =0, all inner points will be taken into account.
2837 aFinder.SetNbPntsMax(100);
2841 // Interprete results
2842 Standard_Integer iErr = aFinder.ErrorStatus();
2843 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
2845 MESSAGE(" iErr : " << iErr);
2846 TCollection_AsciiString aMsg (" iErr : ");
2847 aMsg += TCollection_AsciiString(iErr);
2851 Standard_Integer iWrn = aFinder.WarningStatus();
2852 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
2854 MESSAGE(" *** iWrn : " << iWrn);
2857 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
2859 if (listSS.Extent() < 1) {
2860 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
2861 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
2865 // Fill sequence of object IDs
2866 aSeqOfIDs = new TColStd_HSequenceOfInteger;
2868 TopTools_IndexedMapOfShape anIndices;
2869 TopExp::MapShapes(theShape, anIndices);
2871 TopTools_ListIteratorOfListOfShape itSub (listSS);
2872 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
2873 int id = anIndices.FindIndex(itSub.Value());
2874 aSeqOfIDs->Append(id);
2880 //=======================================================================
2881 //function : getObjectsShapesOn
2883 * \brief Find shape objects and their entries by their ids
2884 * \param theShapeIDs - incoming shape ids
2885 * \param theShapeEntries - outgoing entries like "entry1, entry2, ..."
2886 * \retval Handle(TColStd_HSequenceOfTransient) - found shape objects
2888 //=======================================================================
2889 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::
2890 getObjectsShapesOn(const Handle(GEOM_Object)& theShape,
2891 const Handle(TColStd_HSequenceOfInteger)& theShapeIDs,
2892 TCollection_AsciiString & theShapeEntries)
2894 Handle(TColStd_HSequenceOfTransient) aSeq;
2896 if ( !theShapeIDs.IsNull() && theShapeIDs->Length() > 0 )
2898 aSeq = new TColStd_HSequenceOfTransient;
2899 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
2900 TCollection_AsciiString anEntry;
2901 for ( int i = 1; i <= theShapeIDs->Length(); ++i )
2903 anArray->SetValue(1, theShapeIDs->Value( i ));
2904 Handle(GEOM_Object) anObj = GetEngine()->AddSubShape(theShape, anArray);
2905 aSeq->Append( anObj );
2907 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
2908 if ( i != 1 ) theShapeEntries += ",";
2909 theShapeEntries += anEntry;
2915 //=======================================================================
2916 //function : getShapesOnSurface
2918 * \brief Find sub-shapes complying with given status about surface
2919 * \param theSurface - the surface to check state of sub-shapes against
2920 * \param theShape - the shape to explore
2921 * \param theShapeType - type of sub-shape of theShape
2922 * \param theState - required state
2923 * \param theShapeEntries - outgoing entries like "entry1, entry2, ..."
2924 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
2926 //=======================================================================
2927 Handle(TColStd_HSequenceOfTransient)
2928 GEOMImpl_IShapesOperations::getShapesOnSurface(const Handle(Geom_Surface)& theSurface,
2929 const Handle(GEOM_Object)& theShape,
2930 TopAbs_ShapeEnum theShapeType,
2931 GEOMAlgo_State theState,
2932 TCollection_AsciiString & theShapeEntries)
2934 // Find sub-shapes ids
2935 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2936 getShapesOnSurfaceIDs (theSurface, theShape->GetValue(), theShapeType, theState);
2937 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2940 return getObjectsShapesOn( theShape, aSeqOfIDs, theShapeEntries );
2943 //=============================================================================
2947 //=============================================================================
2948 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnPlane
2949 (const Handle(GEOM_Object)& theShape,
2950 const Standard_Integer theShapeType,
2951 const Handle(GEOM_Object)& theAx1,
2952 const GEOMAlgo_State theState)
2956 if (theShape.IsNull() || theAx1.IsNull()) return NULL;
2958 TopoDS_Shape aShape = theShape->GetValue();
2959 TopoDS_Shape anAx1 = theAx1->GetValue();
2961 if (aShape.IsNull() || anAx1.IsNull()) return NULL;
2963 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2964 if ( !checkTypeShapesOn( theShapeType ))
2968 Handle(Geom_Surface) aPlane = makePlane( anAx1 );
2969 if ( aPlane.IsNull() )
2973 TCollection_AsciiString anAsciiList;
2974 Handle(TColStd_HSequenceOfTransient) aSeq;
2975 aSeq = getShapesOnSurface( aPlane, theShape, aShapeType, theState, anAsciiList );
2976 if ( aSeq.IsNull() || aSeq->Length() == 0 )
2979 // Make a Python command
2981 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2982 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2984 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
2985 << "] = geompy.GetShapesOnPlane(" << theShape << ", "
2986 << aShapeType << ", " << theAx1 << ", " << theState << ")";
2992 //=============================================================================
2994 * GetShapesOnPlaneWithLocation
2996 //=============================================================================
2997 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnPlaneWithLocation
2998 (const Handle(GEOM_Object)& theShape,
2999 const Standard_Integer theShapeType,
3000 const Handle(GEOM_Object)& theAx1,
3001 const Handle(GEOM_Object)& thePnt,
3002 const GEOMAlgo_State theState)
3006 if (theShape.IsNull() || theAx1.IsNull() || thePnt.IsNull()) return NULL;
3008 TopoDS_Shape aShape = theShape->GetValue();
3009 TopoDS_Shape anAx1 = theAx1->GetValue();
3010 TopoDS_Shape anPnt = thePnt->GetValue();
3012 if (aShape.IsNull() || anAx1.IsNull() || anPnt.IsNull()) return NULL;
3014 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3015 if ( !checkTypeShapesOn( theShapeType ))
3019 if ( anAx1.ShapeType() != TopAbs_EDGE || anPnt.ShapeType() != TopAbs_VERTEX ) return NULL;
3020 TopoDS_Vertex V1, V2, V3;
3021 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
3022 TopExp::Vertices(anEdge, V1, V2, Standard_True);
3024 if (V1.IsNull() || V2.IsNull()) {
3025 SetErrorCode("Bad edge given for the plane normal vector");
3028 V3 = TopoDS::Vertex(anPnt);
3031 SetErrorCode("Bad vertex given for the plane location");
3034 gp_Pnt aLoc = BRep_Tool::Pnt(V3);
3035 gp_Vec aVec(BRep_Tool::Pnt(V1),BRep_Tool::Pnt(V2));
3037 if (aVec.Magnitude() < Precision::Confusion()) {
3038 SetErrorCode("Vector with null magnitude given");
3041 Handle(Geom_Surface) aPlane = new Geom_Plane(aLoc, aVec);
3043 if ( aPlane.IsNull() )
3047 TCollection_AsciiString anAsciiList;
3048 Handle(TColStd_HSequenceOfTransient) aSeq;
3049 aSeq = getShapesOnSurface( aPlane, theShape, aShapeType, theState, anAsciiList );
3050 if ( aSeq.IsNull() || aSeq->Length() == 0 )
3053 // Make a Python command
3055 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
3056 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
3058 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
3059 << "] = geompy.GetShapesOnPlaneWithLocation(" << theShape << ", "
3060 << aShapeType << ", " << theAx1 << ", "<< thePnt <<", " << theState << ")";
3066 //=============================================================================
3068 * GetShapesOnCylinder
3070 //=============================================================================
3071 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnCylinder
3072 (const Handle(GEOM_Object)& theShape,
3073 const Standard_Integer theShapeType,
3074 const Handle(GEOM_Object)& theAxis,
3075 const Standard_Real theRadius,
3076 const GEOMAlgo_State theState)
3080 if (theShape.IsNull() || theAxis.IsNull()) return NULL;
3082 TopoDS_Shape aShape = theShape->GetValue();
3083 TopoDS_Shape anAxis = theAxis->GetValue();
3085 if (aShape.IsNull() || anAxis.IsNull()) return NULL;
3087 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3088 if ( !checkTypeShapesOn( aShapeType ))
3091 // Create a cylinder surface
3092 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
3093 if ( aCylinder.IsNull() )
3097 TCollection_AsciiString anAsciiList;
3098 Handle(TColStd_HSequenceOfTransient) aSeq;
3099 aSeq = getShapesOnSurface( aCylinder, theShape, aShapeType, theState, anAsciiList );
3100 if ( aSeq.IsNull() || aSeq->Length() == 0 )
3103 // Make a Python command
3105 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
3106 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
3108 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
3109 << "] = geompy.GetShapesOnCylinder(" << theShape << ", " << aShapeType
3110 << ", " << theAxis << ", " << theRadius << ", " << theState << ")";
3116 //=============================================================================
3118 * GetShapesOnCylinderWithLocation
3120 //=============================================================================
3121 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnCylinderWithLocation
3122 (const Handle(GEOM_Object)& theShape,
3123 const Standard_Integer theShapeType,
3124 const Handle(GEOM_Object)& theAxis,
3125 const Handle(GEOM_Object)& thePnt,
3126 const Standard_Real theRadius,
3127 const GEOMAlgo_State theState)
3131 if (theShape.IsNull() || theAxis.IsNull() || thePnt.IsNull()) return NULL;
3133 TopoDS_Shape aShape = theShape->GetValue();
3134 TopoDS_Shape anAxis = theAxis->GetValue();
3135 TopoDS_Shape aPnt = thePnt->GetValue();
3137 if (aShape.IsNull() || anAxis.IsNull() || aPnt.IsNull()) return NULL;
3139 if (aPnt.ShapeType() != TopAbs_VERTEX )
3141 SetErrorCode("Bottom location point must be vertex");
3145 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3146 if ( !checkTypeShapesOn( aShapeType ))
3149 // Create a cylinder surface
3150 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
3151 if ( aCylinder.IsNull() )
3154 // translate the surface
3155 Handle(Geom_CylindricalSurface) aCylSurface =
3156 Handle(Geom_CylindricalSurface)::DownCast( aCylinder );
3157 if ( aCylSurface.IsNull() )
3159 SetErrorCode("Unexpected surface type instead of Geom_CylindricalSurface");
3162 gp_Pnt fromLoc = aCylSurface->Cylinder().Location();
3163 gp_Pnt toLoc = BRep_Tool::Pnt( TopoDS::Vertex( aPnt ));
3164 aCylinder->Translate( fromLoc, toLoc );
3167 TCollection_AsciiString anAsciiList;
3168 Handle(TColStd_HSequenceOfTransient) aSeq;
3169 aSeq = getShapesOnSurface( aCylinder, theShape, aShapeType, theState, anAsciiList );
3170 if ( aSeq.IsNull() || aSeq->Length() == 0 )
3173 // Make a Python command
3175 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
3176 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
3178 GEOM::TPythonDump(aFunction)
3179 << "[" << anAsciiList.ToCString()
3180 << "] = geompy.GetShapesOnCylinderWithLocation(" << theShape << ", " << aShapeType << ", "
3181 << theAxis << ", " << thePnt << ", " << theRadius << ", " << theState << ")";
3187 //=============================================================================
3191 //=============================================================================
3192 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnSphere
3193 (const Handle(GEOM_Object)& theShape,
3194 const Standard_Integer theShapeType,
3195 const Handle(GEOM_Object)& theCenter,
3196 const Standard_Real theRadius,
3197 const GEOMAlgo_State theState)
3201 if (theShape.IsNull() || theCenter.IsNull()) return NULL;
3203 TopoDS_Shape aShape = theShape->GetValue();
3204 TopoDS_Shape aCenter = theCenter->GetValue();
3206 if (aShape.IsNull() || aCenter.IsNull()) return NULL;
3208 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3209 if ( !checkTypeShapesOn( aShapeType ))
3212 // Center of the sphere
3213 if (aCenter.ShapeType() != TopAbs_VERTEX) return NULL;
3214 gp_Pnt aLoc = BRep_Tool::Pnt(TopoDS::Vertex(aCenter));
3216 gp_Ax3 anAx3 (aLoc, gp::DZ());
3217 Handle(Geom_SphericalSurface) aSphere =
3218 new Geom_SphericalSurface(anAx3, theRadius);
3221 TCollection_AsciiString anAsciiList;
3222 Handle(TColStd_HSequenceOfTransient) aSeq;
3223 aSeq = getShapesOnSurface( aSphere, theShape, aShapeType, theState, anAsciiList );
3224 if ( aSeq.IsNull() || aSeq->Length() == 0 )
3227 // Make a Python command
3229 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
3230 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
3232 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
3233 << "] = geompy.GetShapesOnSphere(" << theShape << ", " << aShapeType
3234 << ", " << theCenter << ", " << theRadius << ", " << theState << ")";
3240 //=============================================================================
3242 * GetShapesOnPlaneIDs
3244 //=============================================================================
3245 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnPlaneIDs
3246 (const Handle(GEOM_Object)& theShape,
3247 const Standard_Integer theShapeType,
3248 const Handle(GEOM_Object)& theAx1,
3249 const GEOMAlgo_State theState)
3253 if (theShape.IsNull() || theAx1.IsNull()) return NULL;
3255 TopoDS_Shape aShape = theShape->GetValue();
3256 TopoDS_Shape anAx1 = theAx1->GetValue();
3258 if (aShape.IsNull() || anAx1.IsNull()) return NULL;
3260 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3261 if ( !checkTypeShapesOn( aShapeType ))
3265 Handle(Geom_Surface) aPlane = makePlane( anAx1 );
3266 if ( aPlane.IsNull() )
3270 Handle(TColStd_HSequenceOfInteger) aSeq;
3271 aSeq = getShapesOnSurfaceIDs( aPlane, aShape, aShapeType, theState );
3273 // The GetShapesOnPlaneIDs() doesn't change object so no new function is required.
3274 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAx1)->GetLastFunction();
3276 // Make a Python command
3277 GEOM::TPythonDump(aFunction, /*append=*/true)
3278 << "listShapesOnPlane = geompy.GetShapesOnPlaneIDs"
3279 << "(" << theShape << "," << aShapeType << "," << theAx1 << "," << theState << ")";
3285 //=============================================================================
3287 * GetShapesOnPlaneWithLocationIDs
3289 //=============================================================================
3290 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnPlaneWithLocationIDs
3291 (const Handle(GEOM_Object)& theShape,
3292 const Standard_Integer theShapeType,
3293 const Handle(GEOM_Object)& theAx1,
3294 const Handle(GEOM_Object)& thePnt,
3295 const GEOMAlgo_State theState)
3299 if (theShape.IsNull() || theAx1.IsNull() || thePnt.IsNull()) return NULL;
3301 TopoDS_Shape aShape = theShape->GetValue();
3302 TopoDS_Shape anAx1 = theAx1->GetValue();
3303 TopoDS_Shape anPnt = thePnt->GetValue();
3305 if (aShape.IsNull() || anAx1.IsNull() || anPnt.IsNull()) return NULL;
3307 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3308 if ( !checkTypeShapesOn( aShapeType ))
3312 if (anAx1.ShapeType() != TopAbs_EDGE || anPnt.ShapeType() != TopAbs_VERTEX) return NULL;
3313 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
3314 TopoDS_Vertex V1, V2, V3;
3315 TopExp::Vertices(anEdge, V1, V2, Standard_True);
3316 if (V1.IsNull() || V2.IsNull()) {
3317 SetErrorCode("Bad edge given for the plane normal vector");
3320 V3 = TopoDS::Vertex(anPnt);
3322 SetErrorCode("Bad vertex given for the plane location");
3325 gp_Pnt aLoc = BRep_Tool::Pnt(V3);
3326 gp_Vec aVec(BRep_Tool::Pnt(V1),BRep_Tool::Pnt(V2));
3327 if (aVec.Magnitude() < Precision::Confusion()) {
3328 SetErrorCode("Vector with null magnitude given");
3332 Handle(Geom_Surface) aPlane = new Geom_Plane(aLoc, aVec);
3333 if ( aPlane.IsNull() )
3337 Handle(TColStd_HSequenceOfInteger) aSeq;
3338 aSeq = getShapesOnSurfaceIDs( aPlane, aShape, aShapeType, theState );
3340 // The GetShapesOnPlaneIDs() doesn't change object so no new function is required.
3341 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAx1)->GetLastFunction();
3343 // Make a Python command
3344 GEOM::TPythonDump(aFunction, /*append=*/true)
3345 << "listShapesOnPlane = geompy.GetShapesOnPlaneWithLocationIDs"
3346 << "(" << theShape << ", " << aShapeType << ", " << theAx1 << ", "<< thePnt << ", " << theState << ")";
3352 //=============================================================================
3354 * GetShapesOnCylinderIDs
3356 //=============================================================================
3357 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnCylinderIDs
3358 (const Handle(GEOM_Object)& theShape,
3359 const Standard_Integer theShapeType,
3360 const Handle(GEOM_Object)& theAxis,
3361 const Standard_Real theRadius,
3362 const GEOMAlgo_State theState)
3366 if (theShape.IsNull() || theAxis.IsNull()) return NULL;
3368 TopoDS_Shape aShape = theShape->GetValue();
3369 TopoDS_Shape anAxis = theAxis->GetValue();
3371 if (aShape.IsNull() || anAxis.IsNull()) return NULL;
3373 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3374 if ( !checkTypeShapesOn( aShapeType ))
3377 // Create a cylinder surface
3378 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
3379 if ( aCylinder.IsNull() )
3383 Handle(TColStd_HSequenceOfInteger) aSeq;
3384 aSeq = getShapesOnSurfaceIDs( aCylinder, aShape, aShapeType, theState );
3386 // The GetShapesOnCylinder() doesn't change object so no new function is required.
3387 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAxis)->GetLastFunction();
3389 // Make a Python command
3390 GEOM::TPythonDump(aFunction, /*append=*/true)
3391 << "listShapesOnCylinder = geompy.GetShapesOnCylinderIDs"
3392 << "(" << theShape << ", " << aShapeType << ", " << theAxis << ", "
3393 << theRadius << ", " << theState << ")";
3399 //=============================================================================
3401 * GetShapesOnCylinderWithLocationIDs
3403 //=============================================================================
3404 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnCylinderWithLocationIDs
3405 (const Handle(GEOM_Object)& theShape,
3406 const Standard_Integer theShapeType,
3407 const Handle(GEOM_Object)& theAxis,
3408 const Handle(GEOM_Object)& thePnt,
3409 const Standard_Real theRadius,
3410 const GEOMAlgo_State theState)
3414 if (theShape.IsNull() || theAxis.IsNull() || thePnt.IsNull()) return NULL;
3416 TopoDS_Shape aShape = theShape->GetValue();
3417 TopoDS_Shape anAxis = theAxis->GetValue();
3418 TopoDS_Shape aPnt = thePnt->GetValue();
3420 if (aShape.IsNull() || anAxis.IsNull() || aPnt.IsNull()) return NULL;
3422 if (aPnt.ShapeType() != TopAbs_VERTEX )
3424 SetErrorCode("Bottom location point must be vertex");
3428 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3429 if ( !checkTypeShapesOn( aShapeType ))
3432 // Create a cylinder surface
3433 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
3434 if ( aCylinder.IsNull() )
3437 // translate the surface
3438 Handle(Geom_CylindricalSurface) aCylSurface =
3439 Handle(Geom_CylindricalSurface)::DownCast( aCylinder );
3440 if ( aCylSurface.IsNull() )
3442 SetErrorCode("Unexpected surface type instead of Geom_CylindricalSurface");
3445 gp_Pnt fromLoc = aCylSurface->Cylinder().Location();
3446 gp_Pnt toLoc = BRep_Tool::Pnt( TopoDS::Vertex( aPnt ));
3447 aCylinder->Translate( fromLoc, toLoc );
3450 Handle(TColStd_HSequenceOfInteger) aSeq;
3451 aSeq = getShapesOnSurfaceIDs( aCylinder, aShape, aShapeType, theState );
3453 // The GetShapesOnCylinder() doesn't change object so no new function is required.
3454 Handle(GEOM_Function) aFunction =
3455 GEOM::GetCreatedLast(theShape, GEOM::GetCreatedLast(thePnt,theAxis))->GetLastFunction();
3457 // Make a Python command
3458 GEOM::TPythonDump(aFunction, /*append=*/true)
3459 << "listShapesOnCylinder = geompy.GetShapesOnCylinderWithLocationIDs"
3460 << "(" << theShape << ", " << aShapeType << ", " << theAxis << ", "
3461 << thePnt << ", " << theRadius << ", " << theState << ")";
3467 //=============================================================================
3469 * GetShapesOnSphereIDs
3471 //=============================================================================
3472 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnSphereIDs
3473 (const Handle(GEOM_Object)& theShape,
3474 const Standard_Integer theShapeType,
3475 const Handle(GEOM_Object)& theCenter,
3476 const Standard_Real theRadius,
3477 const GEOMAlgo_State theState)
3481 if (theShape.IsNull() || theCenter.IsNull()) return NULL;
3483 TopoDS_Shape aShape = theShape->GetValue();
3484 TopoDS_Shape aCenter = theCenter->GetValue();
3486 if (aShape.IsNull() || aCenter.IsNull()) return NULL;
3488 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3489 if ( !checkTypeShapesOn( aShapeType ))
3492 // Center of the sphere
3493 if (aCenter.ShapeType() != TopAbs_VERTEX) return NULL;
3494 gp_Pnt aLoc = BRep_Tool::Pnt(TopoDS::Vertex(aCenter));
3496 gp_Ax3 anAx3 (aLoc, gp::DZ());
3497 Handle(Geom_SphericalSurface) aSphere =
3498 new Geom_SphericalSurface(anAx3, theRadius);
3501 Handle(TColStd_HSequenceOfInteger) aSeq;
3502 aSeq = getShapesOnSurfaceIDs( aSphere, aShape, aShapeType, theState );
3504 // The GetShapesOnSphere() doesn't change object so no new function is required.
3505 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theCenter)->GetLastFunction();
3507 // Make a Python command
3508 GEOM::TPythonDump(aFunction, /*append=*/true)
3509 << "listShapesOnCylinder = geompy.GetShapesOnSphereIDs"
3510 << "(" << theShape << ", " << aShapeType << ", " << theCenter << ", "
3511 << theRadius << ", " << theState << ")";
3517 //=======================================================================
3518 //function : getShapesOnQuadrangleIDs
3520 * \brief Find IDs of sub-shapes complying with given status about quadrangle
3521 * \param theShape - the shape to explore
3522 * \param theShapeType - type of sub-shape of theShape
3523 * \param theTopLeftPoint - top left quadrangle corner
3524 * \param theTopRigthPoint - top right quadrangle corner
3525 * \param theBottomLeftPoint - bottom left quadrangle corner
3526 * \param theBottomRigthPoint - bottom right quadrangle corner
3527 * \param theState - required state
3528 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
3530 //=======================================================================
3531 Handle(TColStd_HSequenceOfInteger)
3532 GEOMImpl_IShapesOperations::getShapesOnQuadrangleIDs (const Handle(GEOM_Object)& theShape,
3533 const Standard_Integer theShapeType,
3534 const Handle(GEOM_Object)& theTopLeftPoint,
3535 const Handle(GEOM_Object)& theTopRigthPoint,
3536 const Handle(GEOM_Object)& theBottomLeftPoint,
3537 const Handle(GEOM_Object)& theBottomRigthPoint,
3538 const GEOMAlgo_State theState)
3542 if ( theShape.IsNull() ||
3543 theTopLeftPoint.IsNull() ||
3544 theTopRigthPoint.IsNull() ||
3545 theBottomLeftPoint.IsNull() ||
3546 theBottomRigthPoint.IsNull() )
3549 TopoDS_Shape aShape = theShape->GetValue();
3550 TopoDS_Shape aTL = theTopLeftPoint->GetValue();
3551 TopoDS_Shape aTR = theTopRigthPoint->GetValue();
3552 TopoDS_Shape aBL = theBottomLeftPoint->GetValue();
3553 TopoDS_Shape aBR = theBottomRigthPoint->GetValue();
3555 if (aShape.IsNull() ||
3560 aTL.ShapeType() != TopAbs_VERTEX ||
3561 aTR.ShapeType() != TopAbs_VERTEX ||
3562 aBL.ShapeType() != TopAbs_VERTEX ||
3563 aBR.ShapeType() != TopAbs_VERTEX )
3566 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3567 if ( !checkTypeShapesOn( aShapeType ))
3570 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
3572 // Check presence of triangulation, build if need
3573 if (!GEOMUtils::CheckTriangulation(aShape)) {
3574 SetErrorCode("Cannot build triangulation on the shape");
3579 gp_Pnt aPntTL = BRep_Tool::Pnt(TopoDS::Vertex(aTL));
3580 gp_Pnt aPntTR = BRep_Tool::Pnt(TopoDS::Vertex(aTR));
3581 gp_Pnt aPntBL = BRep_Tool::Pnt(TopoDS::Vertex(aBL));
3582 gp_Pnt aPntBR = BRep_Tool::Pnt(TopoDS::Vertex(aBR));
3584 GEOMAlgo_FinderShapeOnQuad aFinder( aPntTL, aPntTR, aPntBL, aPntBR );
3585 Standard_Real aTol = 0.0001; // default value
3587 aFinder.SetShape(aShape);
3588 aFinder.SetTolerance(aTol);
3589 //aFinder.SetSurface(theSurface);
3590 aFinder.SetShapeType(aShapeType);
3591 aFinder.SetState(theState);
3593 // Sets the minimal number of inner points for the faces that do not have own
3594 // inner points at all (for e.g. rectangular planar faces have just 2 triangles).
3596 aFinder.SetNbPntsMin(3);
3597 // Sets the maximal number of inner points for edges or faces.
3598 // It is usefull for the cases when this number is very big (e.g =2000) to improve
3599 // the performance. If this value =0, all inner points will be taken into account.
3601 aFinder.SetNbPntsMax(100);
3605 // Interprete results
3606 Standard_Integer iErr = aFinder.ErrorStatus();
3607 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
3609 MESSAGE(" iErr : " << iErr);
3610 TCollection_AsciiString aMsg (" iErr : ");
3611 aMsg += TCollection_AsciiString(iErr);
3615 Standard_Integer iWrn = aFinder.WarningStatus();
3616 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
3618 MESSAGE(" *** iWrn : " << iWrn);
3621 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
3623 if (listSS.Extent() < 1) {
3624 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
3625 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
3629 // Fill sequence of object IDs
3630 aSeqOfIDs = new TColStd_HSequenceOfInteger;
3632 TopTools_IndexedMapOfShape anIndices;
3633 TopExp::MapShapes(aShape, anIndices);
3635 TopTools_ListIteratorOfListOfShape itSub (listSS);
3636 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
3637 int id = anIndices.FindIndex(itSub.Value());
3638 aSeqOfIDs->Append(id);
3643 //=======================================================================
3644 //function : GetShapesOnQuadrangle
3646 * \brief Find sub-shapes complying with given status about quadrangle
3647 * \param theShape - the shape to explore
3648 * \param theShapeType - type of sub-shape of theShape
3649 * \param theTopLeftPoint - top left quadrangle corner
3650 * \param theTopRigthPoint - top right quadrangle corner
3651 * \param theBottomLeftPoint - bottom left quadrangle corner
3652 * \param theBottomRigthPoint - bottom right quadrangle corner
3653 * \param theState - required state
3654 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
3656 //=======================================================================
3657 Handle(TColStd_HSequenceOfTransient)
3658 GEOMImpl_IShapesOperations::GetShapesOnQuadrangle (const Handle(GEOM_Object)& theShape,
3659 const Standard_Integer theShapeType,
3660 const Handle(GEOM_Object)& theTopLeftPoint,
3661 const Handle(GEOM_Object)& theTopRigthPoint,
3662 const Handle(GEOM_Object)& theBottomLeftPoint,
3663 const Handle(GEOM_Object)& theBottomRigthPoint,
3664 const GEOMAlgo_State theState)
3667 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
3668 getShapesOnQuadrangleIDs( theShape,
3673 theBottomRigthPoint,
3675 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->IsEmpty() )
3678 // Find objects by indices
3679 TCollection_AsciiString anAsciiList;
3680 Handle(TColStd_HSequenceOfTransient) aSeq;
3681 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
3682 if ( aSeq.IsNull() || aSeq->IsEmpty() )
3685 // Make a Python command
3687 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
3688 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
3690 GEOM::TPythonDump(aFunction)
3691 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnQuadrangle("
3693 << TopAbs_ShapeEnum(theShapeType) << ", "
3694 << theTopLeftPoint << ", "
3695 << theTopRigthPoint << ", "
3696 << theBottomLeftPoint << ", "
3697 << theBottomRigthPoint << ", "
3704 //=======================================================================
3705 //function : GetShapesOnQuadrangleIDs
3707 * \brief Find IDs of sub-shapes complying with given status about quadrangle
3708 * \param theShape - the shape to explore
3709 * \param theShapeType - type of sub-shape of theShape
3710 * \param theTopLeftPoint - top left quadrangle corner
3711 * \param theTopRigthPoint - top right quadrangle corner
3712 * \param theBottomLeftPoint - bottom left quadrangle corner
3713 * \param theBottomRigthPoint - bottom right quadrangle corner
3714 * \param theState - required state
3715 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
3717 //=======================================================================
3718 Handle(TColStd_HSequenceOfInteger)
3719 GEOMImpl_IShapesOperations::GetShapesOnQuadrangleIDs (const Handle(GEOM_Object)& theShape,
3720 const Standard_Integer theShapeType,
3721 const Handle(GEOM_Object)& theTopLeftPoint,
3722 const Handle(GEOM_Object)& theTopRigthPoint,
3723 const Handle(GEOM_Object)& theBottomLeftPoint,
3724 const Handle(GEOM_Object)& theBottomRigthPoint,
3725 const GEOMAlgo_State theState)
3728 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
3729 getShapesOnQuadrangleIDs( theShape,
3734 theBottomRigthPoint,
3736 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->IsEmpty() )
3739 // Make a Python command
3741 // The GetShapesOnCylinder() doesn't change object so no new function is required.
3742 Handle(GEOM_Object) lastObj = GEOM::GetCreatedLast(theShape,theTopLeftPoint);
3743 lastObj = GEOM::GetCreatedLast(lastObj,theTopRigthPoint);
3744 lastObj = GEOM::GetCreatedLast(lastObj,theBottomRigthPoint);
3745 lastObj = GEOM::GetCreatedLast(lastObj,theBottomLeftPoint);
3746 Handle(GEOM_Function) aFunction = lastObj->GetLastFunction();
3748 GEOM::TPythonDump(aFunction, /*append=*/true)
3749 << "listShapesOnQuadrangle = geompy.GetShapesOnQuadrangleIDs("
3751 << TopAbs_ShapeEnum(theShapeType) << ", "
3752 << theTopLeftPoint << ", "
3753 << theTopRigthPoint << ", "
3754 << theBottomLeftPoint << ", "
3755 << theBottomRigthPoint << ", "
3762 //=============================================================================
3766 //=============================================================================
3767 static bool GetInPlaceOfShape (const Handle(GEOM_Function)& theWhereFunction,
3768 const TopTools_IndexedMapOfShape& theWhereIndices,
3769 const TopoDS_Shape& theWhat,
3770 TColStd_ListOfInteger& theModifiedList)
3772 if (theWhereFunction.IsNull() || theWhat.IsNull()) return false;
3774 if (theWhereIndices.Contains(theWhat)) {
3775 // entity was not changed by the operation
3776 Standard_Integer aWhatIndex = theWhereIndices.FindIndex(theWhat);
3777 theModifiedList.Append(aWhatIndex);
3781 // try to find in history
3782 TDF_Label aHistoryLabel = theWhereFunction->GetHistoryEntry(Standard_False);
3784 // search in history for all argument shapes
3785 Standard_Boolean isFound = Standard_False;
3786 Standard_Boolean isGood = Standard_False;
3788 TDF_LabelSequence aLabelSeq;
3789 theWhereFunction->GetDependency(aLabelSeq);
3790 Standard_Integer nbArg = aLabelSeq.Length();
3792 for (Standard_Integer iarg = 1; iarg <= nbArg && !isFound; iarg++) {
3794 TDF_Label anArgumentRefLabel = aLabelSeq.Value(iarg);
3796 Handle(GEOM_Object) anArgumentObject = GEOM_Object::GetReferencedObject(anArgumentRefLabel);
3797 TopoDS_Shape anArgumentShape = anArgumentObject->GetValue();
3799 TopTools_IndexedMapOfShape anArgumentIndices;
3800 TopExp::MapShapes(anArgumentShape, anArgumentIndices);
3802 if (anArgumentIndices.Contains(theWhat)) {
3803 isFound = Standard_True;
3804 Standard_Integer aWhatIndex = anArgumentIndices.FindIndex(theWhat);
3806 // Find corresponding label in history
3807 TDF_Label anArgumentHistoryLabel =
3808 theWhereFunction->GetArgumentHistoryEntry(anArgumentRefLabel, Standard_False);
3809 if (anArgumentHistoryLabel.IsNull()) {
3810 // Lost History of operation argument. Possibly, all its entities was removed.
3811 isGood = Standard_True;
3814 TDF_Label aWhatHistoryLabel = anArgumentHistoryLabel.FindChild(aWhatIndex, Standard_False);
3816 if (aWhatHistoryLabel.IsNull()) {
3817 // Removed entity ? Compound ? Compsolid ? Shell ? Wire
3818 isGood = Standard_False;
3820 Handle(TDataStd_IntegerArray) anIntegerArray;
3821 if (!aWhatHistoryLabel.FindAttribute(TDataStd_IntegerArray::GetID(), anIntegerArray)) {
3822 //Error: Empty modifications history for the sought shape.
3823 isGood = Standard_False;
3826 isGood = Standard_True;
3827 Standard_Integer imod, aModifLen = anIntegerArray->Array()->Length();
3828 for (imod = 1; imod <= aModifLen; imod++) {
3829 theModifiedList.Append(anIntegerArray->Array()->Value(imod));
3840 // try compound/compsolid/shell/wire element by element
3841 bool isFoundAny = false;
3842 TopTools_MapOfShape mapShape;
3844 if (theWhat.ShapeType() == TopAbs_COMPOUND ||
3845 theWhat.ShapeType() == TopAbs_COMPSOLID) {
3846 // recursive processing of compound/compsolid
3847 TopoDS_Iterator anIt (theWhat, Standard_True, Standard_True);
3848 for (; anIt.More(); anIt.Next()) {
3849 if (mapShape.Add(anIt.Value())) {
3850 TopoDS_Shape curWhat = anIt.Value();
3851 isFoundAny = GetInPlaceOfShape(theWhereFunction, theWhereIndices, curWhat, theModifiedList);
3852 if (isFoundAny) isFound = Standard_True;
3856 else if (theWhat.ShapeType() == TopAbs_SHELL) {
3857 // try to replace a shell by its faces images
3858 TopExp_Explorer anExp (theWhat, TopAbs_FACE);
3859 for (; anExp.More(); anExp.Next()) {
3860 if (mapShape.Add(anExp.Current())) {
3861 TopoDS_Shape curWhat = anExp.Current();
3862 isFoundAny = GetInPlaceOfShape(theWhereFunction, theWhereIndices, curWhat, theModifiedList);
3863 if (isFoundAny) isFound = Standard_True;
3867 else if (theWhat.ShapeType() == TopAbs_WIRE) {
3868 // try to replace a wire by its edges images
3869 TopExp_Explorer anExp (theWhat, TopAbs_EDGE);
3870 for (; anExp.More(); anExp.Next()) {
3871 if (mapShape.Add(anExp.Current())) {
3872 TopoDS_Shape curWhat = anExp.Current();
3873 isFoundAny = GetInPlaceOfShape(theWhereFunction, theWhereIndices, curWhat, theModifiedList);
3874 if (isFoundAny) isFound = Standard_True;
3886 //=============================================================================
3888 * GetShapeProperties
3890 //=============================================================================
3891 void GEOMImpl_IShapesOperations::GetShapeProperties( const TopoDS_Shape aShape, Standard_Real tab[],
3894 GProp_GProps theProps;
3896 //TopoDS_Shape aPntShape;
3897 Standard_Real aShapeSize;
3899 if (aShape.ShapeType() == TopAbs_VERTEX) aCenterMass = BRep_Tool::Pnt( TopoDS::Vertex( aShape ) );
3900 else if (aShape.ShapeType() == TopAbs_EDGE) BRepGProp::LinearProperties(aShape, theProps);
3901 else if (aShape.ShapeType() == TopAbs_FACE) BRepGProp::SurfaceProperties(aShape, theProps);
3902 else BRepGProp::VolumeProperties(aShape, theProps);
3904 if (aShape.ShapeType() == TopAbs_VERTEX)
3907 aCenterMass = theProps.CentreOfMass();
3908 aShapeSize = theProps.Mass();
3911 // aPntShape = BRepBuilderAPI_MakeVertex(aCenterMass).Shape();
3912 // aVertex = BRep_Tool::Pnt( TopoDS::Vertex( aPntShape ) );
3913 aVertex = aCenterMass;
3914 tab[0] = aVertex.X();
3915 tab[1] = aVertex.Y();
3916 tab[2] = aVertex.Z();
3917 tab[3] = aShapeSize;
3921 //=============================================================================
3926 //=============================================================================
3927 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlace (Handle(GEOM_Object) theShapeWhere,
3928 Handle(GEOM_Object) theShapeWhat)
3932 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
3934 TopoDS_Shape aWhere = theShapeWhere->GetValue();
3935 TopoDS_Shape aWhat = theShapeWhat->GetValue();
3937 if (aWhere.IsNull() || aWhat.IsNull()) {
3938 SetErrorCode("Error: aWhere and aWhat TopoDS_Shape are Null.");
3942 // Compute confusion tolerance.
3943 Standard_Real aTolConf = Precision::Confusion();
3946 for (i = 0; i < 2; ++i) {
3947 TopExp_Explorer anExp(i == 0 ? aWhere : aWhat, TopAbs_VERTEX);
3949 for (; anExp.More(); anExp.Next()) {
3950 const TopoDS_Vertex aVtx = TopoDS::Vertex(anExp.Current());
3951 const Standard_Real aTolVtx = BRep_Tool::Tolerance(aVtx);
3953 if (aTolVtx > aTolConf) {
3959 // Compute mass tolerance.
3960 Bnd_Box aBoundingBox;
3961 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
3962 Standard_Real aMassTol;
3964 BRepBndLib::Add(aWhere, aBoundingBox);
3965 BRepBndLib::Add(aWhat, aBoundingBox);
3966 aBoundingBox.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
3967 aMassTol = Max(aXmax - aXmin, aYmax - aYmin);
3968 aMassTol = Max(aMassTol, aZmax - aZmin);
3969 aMassTol *= aTolConf;
3971 // Searching for the sub-shapes inside the ShapeWhere shape
3972 GEOMAlgo_GetInPlace aGIP;
3973 aGIP.SetTolerance(aTolConf);
3974 aGIP.SetTolMass(aMassTol);
3975 aGIP.SetTolCG(aTolConf);
3977 aGIP.SetArgument(aWhat);
3978 aGIP.SetShapeWhere(aWhere);
3981 int iErr = aGIP.ErrorStatus();
3983 SetErrorCode("Error in GEOMAlgo_GetInPlace");
3987 // Add direct result.
3988 TopTools_ListOfShape aLSA;
3989 const TopoDS_Shape &aShapeResult = aGIP.Result();
3990 TopTools_MapOfShape aMFence;
3991 TopTools_IndexedMapOfShape aWhereIndices;
3993 TopExp::MapShapes(aWhere, aWhereIndices);
3995 if (aShapeResult.IsNull() == Standard_False) {
3996 TopoDS_Iterator anIt(aShapeResult);
3998 for (; anIt.More(); anIt.Next()) {
3999 const TopoDS_Shape &aPart = anIt.Value();
4001 if(aWhereIndices.Contains(aPart) && aMFence.Add(aPart)) {
4007 if (aLSA.Extent() == 0) {
4008 SetErrorCode(NOT_FOUND_ANY); // Not found any Results
4012 Handle(TColStd_HArray1OfInteger) aModifiedArray = new TColStd_HArray1OfInteger (1, aLSA.Extent());
4013 TopTools_ListIteratorOfListOfShape anIterModif (aLSA);
4014 for (Standard_Integer imod = 1; anIterModif.More(); anIterModif.Next(), imod++) {
4015 if (aWhereIndices.Contains(anIterModif.Value())) {
4016 aModifiedArray->SetValue(imod, aWhereIndices.FindIndex(anIterModif.Value()));
4019 SetErrorCode("Error: wrong sub-shape returned");
4025 Handle(GEOM_Object) aResult = GetEngine()->AddSubShape(theShapeWhere, aModifiedArray);
4026 if (aResult.IsNull()) {
4027 SetErrorCode("Error in algorithm: result found, but cannot be returned.");
4031 if (aModifiedArray->Length() > 1 || theShapeWhat->GetType() == GEOM_GROUP) {
4033 aResult->SetType(GEOM_GROUP);
4035 //Set a sub-shape type
4036 TopoDS_Shape aFirstFound = aLSA.First();
4037 TopAbs_ShapeEnum aShapeType = aFirstFound.ShapeType();
4039 TDF_Label aFreeLabel = aResult->GetFreeLabel();
4040 TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aShapeType);
4043 //Make a Python command
4044 Handle(GEOM_Function) aFunction = aResult->GetFunction(1);
4046 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetInPlace("
4047 << theShapeWhere << ", " << theShapeWhat << ", True)";
4053 //=============================================================================
4055 * case GetInPlaceOld:
4058 //=============================================================================
4059 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlaceOld (Handle(GEOM_Object) theShapeWhere,
4060 Handle(GEOM_Object) theShapeWhat)
4064 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
4066 TopoDS_Shape aWhere = theShapeWhere->GetValue();
4067 TopoDS_Shape aWhat = theShapeWhat->GetValue();
4068 TopoDS_Shape aPntShape;
4069 TopoDS_Vertex aVertex;
4071 if (aWhere.IsNull() || aWhat.IsNull()) {
4072 SetErrorCode("Error: aWhere and aWhat TopoDS_Shape are Null.");
4076 Handle(GEOM_Function) aWhereFunction = theShapeWhere->GetLastFunction();
4077 if (aWhereFunction.IsNull()) {
4078 SetErrorCode("Error: aWhereFunction is Null.");
4082 TopTools_IndexedMapOfShape aWhereIndices;
4083 TopExp::MapShapes(aWhere, aWhereIndices);
4085 TColStd_ListOfInteger aModifiedList;
4086 Standard_Integer aWhereIndex;
4087 Handle(TColStd_HArray1OfInteger) aModifiedArray;
4088 Handle(GEOM_Object) aResult;
4090 bool isFound = false;
4091 TopAbs_ShapeEnum iType = TopAbs_SOLID;
4092 //Standard_Real aWhat_Mass = 0., aWhere_Mass = 0.;
4093 Standard_Real tab_aWhat[4], tab_aWhere[4];
4094 Standard_Real dl_l = 1e-3;
4095 Standard_Real min_l, Tol_0D, Tol_1D, Tol_2D, Tol_3D, Tol_Mass;
4096 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
4097 Bnd_Box BoundingBox;
4098 gp_Pnt aPnt, aPnt_aWhat, tab_Pnt[2];
4099 GProp_GProps aProps;
4101 // Find the iType of the aWhat shape
4103 if ( aWhat.ShapeType() == TopAbs_VERTEX ) iType = TopAbs_VERTEX;
4104 else if ( aWhat.ShapeType() == TopAbs_EDGE || aWhat.ShapeType() == TopAbs_WIRE ) iType = TopAbs_EDGE;
4105 else if ( aWhat.ShapeType() == TopAbs_FACE || aWhat.ShapeType() == TopAbs_SHELL ) iType = TopAbs_FACE;
4106 else if ( aWhat.ShapeType() == TopAbs_SOLID || aWhat.ShapeType() == TopAbs_COMPSOLID ) iType = TopAbs_SOLID;
4107 else if ( aWhat.ShapeType() == TopAbs_COMPOUND ) {
4108 // Only the iType of the first shape in the compound is taken into account
4109 TopoDS_Iterator It (aWhat, Standard_False, Standard_False);
4111 SetErrorCode("Error: theShapeWhat is an empty COMPOUND.");
4114 TopAbs_ShapeEnum compType = It.Value().ShapeType();
4115 if ( compType == TopAbs_VERTEX ) iType = TopAbs_VERTEX;
4116 else if ( compType == TopAbs_EDGE || compType == TopAbs_WIRE ) iType = TopAbs_EDGE;
4117 else if ( compType == TopAbs_FACE || compType == TopAbs_SHELL) iType = TopAbs_FACE;
4118 else if ( compType == TopAbs_SOLID || compType == TopAbs_COMPSOLID) iType = TopAbs_SOLID;
4121 SetErrorCode("Error: An attempt to extract a shape of not supported type.");
4125 iType = GEOMUtils::GetTypeOfSimplePart(aWhat);
4126 if (iType == TopAbs_SHAPE) {
4127 SetErrorCode("Error: An attempt to extract a shape of not supported type.");
4131 TopExp_Explorer Exp_aWhat ( aWhat, iType );
4132 TopExp_Explorer Exp_aWhere ( aWhere, iType );
4133 TopExp_Explorer Exp_Edge ( aWhere, TopAbs_EDGE );
4135 // Find the shortest edge in theShapeWhere shape
4136 BRepBndLib::Add(aWhere, BoundingBox);
4137 BoundingBox.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
4138 min_l = fabs(aXmax - aXmin);
4139 if( min_l < fabs(aYmax - aYmin) ) min_l = fabs(aYmax - aYmin);
4140 if( min_l < fabs(aZmax - aZmin) ) min_l = fabs(aZmax - aZmin);
4142 // Mantis issue 0020908 BEGIN
4143 if (!Exp_Edge.More()) {
4144 min_l = Precision::Confusion();
4146 // Mantis issue 0020908 END
4147 for ( Standard_Integer nbEdge = 0; Exp_Edge.More(); Exp_Edge.Next(), nbEdge++ ) {
4148 TopExp_Explorer Exp_Vertex( Exp_Edge.Current(), TopAbs_VERTEX);
4149 for ( Standard_Integer nbVertex = 0; Exp_Vertex.More(); Exp_Vertex.Next(), nbVertex++ ) {
4150 aPnt = BRep_Tool::Pnt( TopoDS::Vertex( Exp_Vertex.Current() ) );
4151 tab_Pnt[nbVertex] = aPnt;
4153 if ( ! tab_Pnt[0].IsEqual(tab_Pnt[1], dl_l) ) {
4154 BRepGProp::LinearProperties(Exp_Edge.Current(), aProps);
4155 if ( aProps.Mass() < min_l ) min_l = aProps.Mass();
4159 // Compute tolerances
4161 Tol_1D = dl_l * min_l;
4162 Tol_2D = dl_l * ( min_l * min_l) * ( 2. + dl_l);
4163 Tol_3D = dl_l * ( min_l * min_l * min_l ) * ( 3. + (3 * dl_l) + (dl_l * dl_l) );
4165 if (Tol_0D < Precision::Confusion()) Tol_0D = Precision::Confusion();
4166 if (Tol_1D < Precision::Confusion()) Tol_1D = Precision::Confusion();
4167 if (Tol_2D < Precision::Confusion()) Tol_2D = Precision::Confusion();
4168 if (Tol_3D < Precision::Confusion()) Tol_3D = Precision::Confusion();
4170 //if (Tol_1D > 1.0) Tol_1D = 1.0;
4171 //if (Tol_2D > 1.0) Tol_2D = 1.0;
4172 //if (Tol_3D > 1.0) Tol_3D = 1.0;
4175 if ( iType == TopAbs_VERTEX ) Tol_Mass = Tol_0D;
4176 else if ( iType == TopAbs_EDGE ) Tol_Mass = Tol_1D;
4177 else if ( iType == TopAbs_FACE ) Tol_Mass = Tol_2D;
4179 // Compute the ShapeWhat Mass
4181 for ( ; Exp_aWhat.More(); Exp_aWhat.Next() ) {
4182 if ( iType == TopAbs_VERTEX ) {
4186 else if ( iType == TopAbs_EDGE ) BRepGProp::LinearProperties(Exp_aWhat.Current(), aProps);
4187 else if ( iType == TopAbs_FACE ) BRepGProp::SurfaceProperties(Exp_aWhat.Current(), aProps);
4188 else BRepGProp::VolumeProperties(Exp_aWhat.Current(), aProps);
4189 aWhat_Mass += aProps.Mass();
4193 // Searching for the sub-shapes inside the ShapeWhere shape
4194 TopTools_MapOfShape map_aWhere;
4195 for ( Exp_aWhere.ReInit(); Exp_aWhere.More(); Exp_aWhere.Next() ) {
4196 if (!map_aWhere.Add(Exp_aWhere.Current()))
4197 continue; // skip repeated shape to avoid mass addition
4198 GetShapeProperties( Exp_aWhere.Current(), tab_aWhere, aPnt );
4199 for ( Exp_aWhat.ReInit(); Exp_aWhat.More(); Exp_aWhat.Next() ) {
4200 GetShapeProperties( Exp_aWhat.Current(), tab_aWhat, aPnt_aWhat );
4201 if ( fabs(tab_aWhat[3] - tab_aWhere[3]) <= Tol_Mass && aPnt_aWhat.Distance(aPnt) <= Tol_1D )
4204 if ( (tab_aWhat[3] - tab_aWhere[3]) > Tol_Mass ) {
4205 aPntShape = BRepBuilderAPI_MakeVertex( aPnt ).Shape();
4206 aVertex = TopoDS::Vertex( aPntShape );
4207 BRepExtrema_DistShapeShape aWhereDistance ( aVertex, Exp_aWhere.Current() );
4208 BRepExtrema_DistShapeShape aWhatDistance ( aVertex, Exp_aWhat.Current() );
4209 if ( aWhereDistance.IsDone() && aWhatDistance.IsDone() &&
4210 fabs(aWhereDistance.Value() - aWhatDistance.Value()) <= Tol_1D )
4212 // 0020162: "EDF 961 GEOM : Getinplace is getting additionnal orthogonal faces"
4213 // aVertex must be projected to the same point on Where and on What
4214 gp_Pnt pOnWhat = aWhatDistance.PointOnShape2(1);
4215 gp_Pnt pOnWhere = aWhereDistance.PointOnShape2(1);
4216 isFound = ( pOnWhat.Distance(pOnWhere) <= Tol_1D );
4217 if ( isFound && iType == TopAbs_FACE )
4219 // check normals at pOnWhat and pOnWhere
4220 const double angleTol = M_PI/180.;
4221 gp_Vec normToWhat = GetNormal( TopoDS::Face(Exp_aWhat.Current()), aWhatDistance);
4222 gp_Vec normToWhere = GetNormal( TopoDS::Face(Exp_aWhere.Current()), aWhereDistance);
4223 if ( normToWhat * normToWhere < 0 )
4224 normToWhat.Reverse();
4225 isFound = ( normToWhat.Angle( normToWhere ) < angleTol );
4231 aWhereIndex = aWhereIndices.FindIndex(Exp_aWhere.Current());
4232 aModifiedList.Append(aWhereIndex);
4233 //aWhere_Mass += tab_aWhere[3];
4238 //if ( fabs( aWhat_Mass - aWhere_Mass ) <= Tol_Mass )
4242 if (aModifiedList.Extent() == 0) { // Not found any Results
4243 SetErrorCode(NOT_FOUND_ANY);
4247 aModifiedArray = new TColStd_HArray1OfInteger (1, aModifiedList.Extent());
4248 TColStd_ListIteratorOfListOfInteger anIterModif (aModifiedList);
4249 for (Standard_Integer imod = 1; anIterModif.More(); anIterModif.Next(), imod++)
4250 aModifiedArray->SetValue(imod, anIterModif.Value());
4253 aResult = GetEngine()->AddSubShape(theShapeWhere, aModifiedArray);
4254 if (aResult.IsNull()) {
4255 SetErrorCode("Error in algorithm: result found, but cannot be returned.");
4259 if (aModifiedArray->Length() > 1 || theShapeWhat->GetType() == GEOM_GROUP) {
4261 aResult->SetType(GEOM_GROUP);
4263 //Set a sub-shape type
4264 TopoDS_Shape aFirstFound = aWhereIndices.FindKey(aModifiedArray->Value(1));
4265 TopAbs_ShapeEnum aShapeType = aFirstFound.ShapeType();
4267 TDF_Label aFreeLabel = aResult->GetFreeLabel();
4268 TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aShapeType);
4271 //Make a Python command
4272 Handle(GEOM_Function) aFunction = aResult->GetFunction(1);
4274 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetInPlace("
4275 << theShapeWhere << ", " << theShapeWhat << ", False)";
4281 //=======================================================================
4282 //function : GetInPlaceByHistory
4284 //=======================================================================
4285 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlaceByHistory
4286 (Handle(GEOM_Object) theShapeWhere,
4287 Handle(GEOM_Object) theShapeWhat)
4291 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
4293 TopoDS_Shape aWhere = theShapeWhere->GetValue();
4294 TopoDS_Shape aWhat = theShapeWhat->GetValue();
4296 if (aWhere.IsNull() || aWhat.IsNull()) return NULL;
4298 Handle(GEOM_Function) aWhereFunction = theShapeWhere->GetLastFunction();
4299 if (aWhereFunction.IsNull()) return NULL;
4301 //Fill array of indices
4302 TopTools_IndexedMapOfShape aWhereIndices;
4303 TopExp::MapShapes(aWhere, aWhereIndices);
4306 TColStd_ListOfInteger aModifiedList;
4307 bool isFound = GetInPlaceOfShape(aWhereFunction, aWhereIndices, aWhat, aModifiedList);
4309 if (!isFound || aModifiedList.Extent() < 1) {
4310 SetErrorCode("Error: No history found for the sought shape or its sub-shapes.");
4314 Standard_Integer nbFound = aModifiedList.Extent();
4315 TColStd_ListIteratorOfListOfInteger anIterModif (aModifiedList);
4318 // remove sub-shapes inappropriate for group creation
4319 TopAbs_ShapeEnum subType = TopAbs_SHAPE;
4320 while ( anIterModif.More() ) {
4321 TopAbs_ShapeEnum type = aWhereIndices( anIterModif.Value() ).ShapeType();
4322 bool okForGroup = ( type == TopAbs_VERTEX || type == TopAbs_EDGE ||
4323 type == TopAbs_FACE || type == TopAbs_SOLID );
4325 if ( subType == TopAbs_SHAPE )
4328 okForGroup = ( subType == type );
4333 aModifiedList.Remove( anIterModif );
4334 nbFound -= ( !okForGroup );
4336 if ( nbFound == 0 ) {
4337 SetErrorCode("Error: result found but it's type is inappropriate for group creation.");
4342 Handle(TColStd_HArray1OfInteger) aModifiedArray =
4343 new TColStd_HArray1OfInteger( 1, nbFound );
4344 anIterModif.Initialize(aModifiedList);
4345 for (Standard_Integer imod = 1; anIterModif.More(); anIterModif.Next(), imod++)
4346 aModifiedArray->SetValue(imod, anIterModif.Value());
4349 Handle(GEOM_Object) aResult = GetEngine()->AddSubShape(theShapeWhere, aModifiedArray);
4350 if (aResult.IsNull()) {
4351 SetErrorCode("Error in algorithm: result found, but cannot be returned.");
4355 if (aModifiedArray->Length() > 1) {
4357 aResult->SetType(GEOM_GROUP);
4359 //Set a sub-shape type
4360 TopoDS_Shape aFirstFound = aWhereIndices.FindKey(aModifiedArray->Value(1));
4361 TopAbs_ShapeEnum aShapeType = aFirstFound.ShapeType();
4363 TDF_Label aFreeLabel = aResult->GetFreeLabel();
4364 TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aShapeType);
4367 //Make a Python command
4368 Handle(GEOM_Function) aFunction = aResult->GetFunction(1);
4370 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetInPlaceByHistory("
4371 << theShapeWhere << ", " << theShapeWhat << ")";
4377 #define MAX_TOLERANCE 1.e-7
4379 //=======================================================================
4380 //function : isSameEdge
4381 //purpose : Returns True if two edges coincide
4382 //=======================================================================
4383 static bool isSameEdge(const TopoDS_Edge& theEdge1, const TopoDS_Edge& theEdge2)
4385 TopoDS_Vertex V11, V12, V21, V22;
4386 TopExp::Vertices(theEdge1, V11, V12);
4387 TopExp::Vertices(theEdge2, V21, V22);
4388 gp_Pnt P11 = BRep_Tool::Pnt(V11);
4389 gp_Pnt P12 = BRep_Tool::Pnt(V12);
4390 gp_Pnt P21 = BRep_Tool::Pnt(V21);
4391 gp_Pnt P22 = BRep_Tool::Pnt(V22);
4392 bool coincide = false;
4394 //Check that ends of edges coincide
4395 if(P11.Distance(P21) <= MAX_TOLERANCE) {
4396 if(P12.Distance(P22) <= MAX_TOLERANCE) coincide = true;
4398 else if(P11.Distance(P22) <= MAX_TOLERANCE) {
4399 if(P12.Distance(P21) <= MAX_TOLERANCE) coincide = true;
4402 if(!coincide) return false;
4404 if (BRep_Tool::Degenerated(theEdge1))
4405 if (BRep_Tool::Degenerated(theEdge2)) return true;
4408 if (BRep_Tool::Degenerated(theEdge2)) return false;
4410 double U11, U12, U21, U22;
4411 Handle(Geom_Curve) C1 = BRep_Tool::Curve(theEdge1, U11, U12);
4412 Handle(Geom_Curve) C2 = BRep_Tool::Curve(theEdge2, U21, U22);
4413 if(C1->DynamicType() == C2->DynamicType()) return true;
4415 //Check that both edges has the same geometry
4416 double range = U12-U11;
4417 double U = U11+ range/3.0;
4418 gp_Pnt P1 = C1->Value(U); //Compute a point on one third of the edge's length
4419 U = U11+range*2.0/3.0;
4420 gp_Pnt P2 = C1->Value(U); //Compute a point on two thirds of the edge's length
4422 if(!GeomLib_Tool::Parameter(C2, P1, MAX_TOLERANCE, U) || U < U21 || U > U22)
4425 if(P1.Distance(C2->Value(U)) > MAX_TOLERANCE) return false;
4427 if(!GeomLib_Tool::Parameter(C2, P2, MAX_TOLERANCE, U) || U < U21 || U > U22)
4430 if(P2.Distance(C2->Value(U)) > MAX_TOLERANCE) return false;
4435 #include <TopoDS_TShape.hxx>
4436 //=======================================================================
4437 //function : isSameFace
4438 //purpose : Returns True if two faces coincide
4439 //=======================================================================
4440 static bool isSameFace(const TopoDS_Face& theFace1, const TopoDS_Face& theFace2)
4442 TopExp_Explorer E(theFace1, TopAbs_EDGE);
4443 TopTools_ListOfShape LS1, LS2;
4444 for(; E.More(); E.Next()) LS1.Append(E.Current());
4446 E.Init(theFace2, TopAbs_EDGE);
4447 for(; E.More(); E.Next()) LS2.Append(E.Current());
4449 //Compare the number of edges in the faces
4450 if(LS1.Extent() != LS2.Extent()) return false;
4452 double aMin = RealFirst(), aMax = RealLast();
4453 double xminB1=aMax, yminB1=aMax, zminB1=aMax, xminB2=aMax, yminB2=aMax, zminB2=aMax;
4454 double xmaxB1=aMin, ymaxB1=aMin, zmaxB1=aMin, xmaxB2=aMin, ymaxB2=aMin, zmaxB2=aMin;
4456 for(E.Init(theFace1, TopAbs_VERTEX); E.More(); E.Next()) {
4457 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4458 if(P.X() < xminB1) xminB1 = P.X();
4459 if(P.Y() < yminB1) yminB1 = P.Y();
4460 if(P.Z() < zminB1) zminB1 = P.Z();
4461 if(P.X() > xmaxB1) xmaxB1 = P.X();
4462 if(P.Y() > ymaxB1) ymaxB1 = P.Y();
4463 if(P.Z() > zmaxB1) zmaxB1 = P.Z();
4466 for(E.Init(theFace2, TopAbs_VERTEX); E.More(); E.Next()) {
4467 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4468 if(P.X() < xminB2) xminB2 = P.X();
4469 if(P.Y() < yminB2) yminB2 = P.Y();
4470 if(P.Z() < zminB2) zminB2 = P.Z();
4471 if(P.X() > xmaxB2) xmaxB2 = P.X();
4472 if(P.Y() > ymaxB2) ymaxB2 = P.Y();
4473 if(P.Z() > zmaxB2) zmaxB2 = P.Z();
4476 //Compare the bounding boxes of both faces
4477 if(gp_Pnt(xminB1, yminB1, zminB1).Distance(gp_Pnt(xminB2, yminB2, zminB2)) > MAX_TOLERANCE)
4480 if(gp_Pnt(xmaxB1, ymaxB1, zmaxB1).Distance(gp_Pnt(xmaxB2, ymaxB2, zmaxB2)) > MAX_TOLERANCE)
4483 Handle(Geom_Surface) S1 = BRep_Tool::Surface(theFace1);
4484 Handle(Geom_Surface) S2 = BRep_Tool::Surface(theFace2);
4486 //Check if there a coincidence of two surfaces at least in two points
4487 double U11, U12, V11, V12, U21, U22, V21, V22;
4488 BRepTools::UVBounds(theFace1, U11, U12, V11, V12);
4489 BRepTools::UVBounds(theFace2, U21, U22, V21, V22);
4491 double rangeU = U12-U11;
4492 double rangeV = V12-V11;
4493 double U = U11 + rangeU/3.0;
4494 double V = V11 + rangeV/3.0;
4495 gp_Pnt P1 = S1->Value(U, V);
4496 U = U11+rangeU*2.0/3.0;
4497 V = V11+rangeV*2.0/3.0;
4498 gp_Pnt P2 = S1->Value(U, V);
4500 if (!GeomLib_Tool::Parameters(S2, P1, MAX_TOLERANCE, U, V) || U < U21 || U > U22 || V < V21 || V > V22)
4503 if (P1.Distance(S2->Value(U,V)) > MAX_TOLERANCE) return false;
4505 if (!GeomLib_Tool::Parameters(S2, P2, MAX_TOLERANCE, U, V) || U < U21 || U > U22 || V < V21 || V > V22)
4508 if (P2.Distance(S2->Value(U, V)) > MAX_TOLERANCE) return false;
4510 //Check that each edge of the Face1 has a counterpart in the Face2
4511 TopTools_MapOfOrientedShape aMap;
4512 TopTools_ListIteratorOfListOfShape LSI1(LS1);
4513 for(; LSI1.More(); LSI1.Next()) {
4514 TopoDS_Edge E = TopoDS::Edge(LSI1.Value());
4515 bool isFound = false;
4516 TopTools_ListIteratorOfListOfShape LSI2(LS2);
4517 for(; LSI2.More(); LSI2.Next()) {
4518 TopoDS_Shape aValue = LSI2.Value();
4519 if(aMap.Contains(aValue)) continue; //To avoid checking already found edge several times
4520 if(isSameEdge(E, TopoDS::Edge(aValue))) {
4526 if(!isFound) return false;
4532 //=======================================================================
4533 //function : isSameSolid
4534 //purpose : Returns True if two solids coincide
4535 //=======================================================================
4536 bool isSameSolid(const TopoDS_Solid& theSolid1, const TopoDS_Solid& theSolid2)
4538 TopExp_Explorer E(theSolid1, TopAbs_FACE);
4539 TopTools_ListOfShape LS1, LS2;
4540 for(; E.More(); E.Next()) LS1.Append(E.Current());
4541 E.Init(theSolid2, TopAbs_FACE);
4542 for(; E.More(); E.Next()) LS2.Append(E.Current());
4544 if(LS1.Extent() != LS2.Extent()) return false;
4546 double aMin = RealFirst(), aMax = RealLast();
4547 double xminB1=aMax, yminB1=aMax, zminB1=aMax, xminB2=aMax, yminB2=aMax, zminB2=aMax;
4548 double xmaxB1=aMin, ymaxB1=aMin, zmaxB1=aMin, xmaxB2=aMin, ymaxB2=aMin, zmaxB2=aMin;
4550 for(E.Init(theSolid1, TopAbs_VERTEX); E.More(); E.Next()) {
4551 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4552 if(P.X() < xminB1) xminB1 = P.X();
4553 if(P.Y() < yminB1) yminB1 = P.Y();
4554 if(P.Z() < zminB1) zminB1 = P.Z();
4555 if(P.X() > xmaxB1) xmaxB1 = P.X();
4556 if(P.Y() > ymaxB1) ymaxB1 = P.Y();
4557 if(P.Z() > zmaxB1) zmaxB1 = P.Z();
4560 for(E.Init(theSolid2, TopAbs_VERTEX); E.More(); E.Next()) {
4561 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4562 if(P.X() < xminB2) xminB2 = P.X();
4563 if(P.Y() < yminB2) yminB2 = P.Y();
4564 if(P.Z() < zminB2) zminB2 = P.Z();
4565 if(P.X() > xmaxB2) xmaxB2 = P.X();
4566 if(P.Y() > ymaxB2) ymaxB2 = P.Y();
4567 if(P.Z() > zmaxB2) zmaxB2 = P.Z();
4570 //Compare the bounding boxes of both solids
4571 if(gp_Pnt(xminB1, yminB1, zminB1).Distance(gp_Pnt(xminB2, yminB2, zminB2)) > MAX_TOLERANCE)
4574 if(gp_Pnt(xmaxB1, ymaxB1, zmaxB1).Distance(gp_Pnt(xmaxB2, ymaxB2, zmaxB2)) > MAX_TOLERANCE)
4577 //Check that each face of the Solid1 has a counterpart in the Solid2
4578 TopTools_MapOfOrientedShape aMap;
4579 TopTools_ListIteratorOfListOfShape LSI1(LS1);
4580 for(; LSI1.More(); LSI1.Next()) {
4581 TopoDS_Face F = TopoDS::Face(LSI1.Value());
4582 bool isFound = false;
4583 TopTools_ListIteratorOfListOfShape LSI2(LS2);
4584 for(; LSI2.More(); LSI2.Next()) {
4585 if(aMap.Contains(LSI2.Value())) continue; //To avoid checking already found faces several times
4586 if(isSameFace(F, TopoDS::Face(LSI2.Value()))) {
4587 aMap.Add(LSI2.Value());
4592 if(!isFound) return false;
4598 //=======================================================================
4599 //function : GetSame
4601 //=======================================================================
4602 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetSame(const Handle(GEOM_Object)& theShapeWhere,
4603 const Handle(GEOM_Object)& theShapeWhat)
4606 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
4608 TopoDS_Shape aWhere = theShapeWhere->GetValue();
4609 TopoDS_Shape aWhat = theShapeWhat->GetValue();
4611 if (aWhere.IsNull() || aWhat.IsNull()) return NULL;
4614 bool isFound = false;
4615 TopoDS_Shape aSubShape;
4616 TopTools_MapOfShape aMap;
4618 if (aWhat.ShapeType() == TopAbs_COMPOUND || aWhat.ShapeType() == TopAbs_COMPSOLID) {
4619 TopoDS_Iterator It (aWhat, Standard_True, Standard_True);
4620 if (It.More()) aWhat = It.Value();
4623 SetErrorCode("Compounds of two or more shapes are not allowed for aWhat argument");
4628 switch (aWhat.ShapeType()) {
4629 case TopAbs_VERTEX: {
4630 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(aWhat));
4631 TopExp_Explorer E(aWhere, TopAbs_VERTEX);
4632 for(; E.More(); E.Next()) {
4633 if(!aMap.Add(E.Current())) continue;
4634 gp_Pnt P2 = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4635 if(P.Distance(P2) <= MAX_TOLERANCE) {
4637 aSubShape = E.Current();
4644 TopoDS_Edge anEdge = TopoDS::Edge(aWhat);
4645 TopExp_Explorer E(aWhere, TopAbs_EDGE);
4646 for(; E.More(); E.Next()) {
4647 if(!aMap.Add(E.Current())) continue;
4648 if(isSameEdge(anEdge, TopoDS::Edge(E.Current()))) {
4649 aSubShape = E.Current();
4657 TopoDS_Face aFace = TopoDS::Face(aWhat);
4658 TopExp_Explorer E(aWhere, TopAbs_FACE);
4659 for(; E.More(); E.Next()) {
4660 if(!aMap.Add(E.Current())) continue;
4661 if(isSameFace(aFace, TopoDS::Face(E.Current()))) {
4662 aSubShape = E.Current();
4669 case TopAbs_SOLID: {
4670 TopoDS_Solid aSolid = TopoDS::Solid(aWhat);
4671 TopExp_Explorer E(aWhere, TopAbs_SOLID);
4672 for(; E.More(); E.Next()) {
4673 if(!aMap.Add(E.Current())) continue;
4674 if(isSameSolid(aSolid, TopoDS::Solid(E.Current()))) {
4675 aSubShape = E.Current();
4687 TopTools_IndexedMapOfShape anIndices;
4688 TopExp::MapShapes(aWhere, anIndices);
4689 if (anIndices.Contains(aSubShape))
4690 anIndex = anIndices.FindIndex(aSubShape);
4693 if (anIndex < 0) return NULL;
4695 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
4697 anArray->SetValue(1, anIndex);
4699 Handle(GEOM_Object) aResult = GetEngine()->AddSubShape(theShapeWhere, anArray);
4700 Handle(GEOM_Function) aFunction = aResult->GetLastFunction();
4702 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetSame("
4703 << theShapeWhere << ", " << theShapeWhat << ")";
4711 //=======================================================================
4712 //function : GetSameIDs
4714 //=======================================================================
4715 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetSameIDs
4716 (const Handle(GEOM_Object)& theShapeWhere,
4717 const Handle(GEOM_Object)& theShapeWhat)
4720 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
4722 TopoDS_Shape aWhere = theShapeWhere->GetValue();
4723 TopoDS_Shape aWhat = theShapeWhat->GetValue();
4725 if (aWhere.IsNull() || aWhat.IsNull()) return NULL;
4727 TopTools_ListOfShape listShape;
4728 TopTools_MapOfShape aMap;
4730 if (aWhat.ShapeType() == TopAbs_COMPOUND || aWhat.ShapeType() == TopAbs_COMPSOLID) {
4731 TopoDS_Iterator It (aWhat, Standard_True, Standard_True);
4732 if (It.More()) aWhat = It.Value();
4735 SetErrorCode("Compounds of two or more shapes are not allowed for aWhat argument");
4740 switch (aWhat.ShapeType()) {
4741 case TopAbs_VERTEX: {
4742 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(aWhat));
4743 TopExp_Explorer E(aWhere, TopAbs_VERTEX);
4744 for(; E.More(); E.Next()) {
4745 if(!aMap.Add(E.Current())) continue;
4746 gp_Pnt P2 = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4747 if(P.Distance(P2) <= MAX_TOLERANCE) {
4748 listShape.Append(E.Current());
4754 TopoDS_Edge anEdge = TopoDS::Edge(aWhat);
4755 TopExp_Explorer E(aWhere, TopAbs_EDGE);
4756 for(; E.More(); E.Next()) {
4757 if(!aMap.Add(E.Current())) continue;
4758 if(isSameEdge(anEdge, TopoDS::Edge(E.Current()))) {
4759 listShape.Append(E.Current());
4765 TopoDS_Face aFace = TopoDS::Face(aWhat);
4766 TopExp_Explorer E(aWhere, TopAbs_FACE);
4767 for(; E.More(); E.Next()) {
4768 if(!aMap.Add(E.Current())) continue;
4769 if(isSameFace(aFace, TopoDS::Face(E.Current()))) {
4770 listShape.Append(E.Current());
4775 case TopAbs_SOLID: {
4776 TopoDS_Solid aSolid = TopoDS::Solid(aWhat);
4777 TopExp_Explorer E(aWhere, TopAbs_SOLID);
4778 for(; E.More(); E.Next()) {
4779 if(!aMap.Add(E.Current())) continue;
4780 if(isSameSolid(aSolid, TopoDS::Solid(E.Current()))) {
4781 listShape.Append(E.Current());
4790 if ( !listShape.IsEmpty() ) {
4791 TopTools_IndexedMapOfShape anIndices;
4792 TopExp::MapShapes(aWhere, anIndices);
4793 TopTools_ListIteratorOfListOfShape itSub (listShape);
4794 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
4795 for (; itSub.More(); itSub.Next()) {
4796 if (anIndices.Contains(itSub.Value()))
4797 aSeq->Append(anIndices.FindIndex(itSub.Value()));
4800 // The GetSameIDs() doesn't change object so no new function is required.
4801 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShapeWhere,theShapeWhat)->GetLastFunction();
4803 // Make a Python command
4804 GEOM::TPythonDump(aFunction, /*append=*/true)
4805 << "listSameIDs = geompy.GetSameIDs("
4806 << theShapeWhere << ", "
4807 << theShapeWhat << ")";
4810 SetErrorCode(NOT_FOUND_ANY);
4815 //=======================================================================
4816 //function : ExtendEdge
4818 //=======================================================================
4819 Handle(GEOM_Object) GEOMImpl_IShapesOperations::ExtendEdge
4820 (const Handle(GEOM_Object) &theEdge,
4821 const Standard_Real theMin,
4822 const Standard_Real theMax)
4826 if (theEdge.IsNull()) {
4830 //Add a new Edge object
4831 Handle(GEOM_Object) aResEdge = GetEngine()->AddObject(GetDocID(), GEOM_EDGE);
4833 //Add a new Vector function
4834 Handle(GEOM_Function) aFunction =
4835 aResEdge->AddFunction(GEOMImpl_ShapeDriver::GetID(), EDGE_UV);
4837 //Check if the function is set correctly
4838 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) {
4842 GEOMImpl_IShapeExtend aCI (aFunction);
4844 Handle(GEOM_Function) anEdge = theEdge->GetLastFunction();
4846 if (anEdge.IsNull()) {
4850 aCI.SetShape(anEdge);
4851 aCI.SetUMin(theMin);
4852 aCI.SetUMax(theMax);
4854 //Compute the Edge value
4857 if (!GetSolver()->ComputeFunction(aFunction)) {
4858 SetErrorCode("Shape driver failed");
4863 catch (Standard_Failure) {
4864 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
4865 SetErrorCode(aFail->GetMessageString());
4870 //Make a Python command
4871 GEOM::TPythonDump(aFunction)
4872 << aResEdge << " = geompy.ExtendEdge("
4873 << theEdge << ", " << theMin << ", " << theMax << ")";
4880 //=======================================================================
4881 //function : ExtendFace
4883 //=======================================================================
4884 Handle(GEOM_Object) GEOMImpl_IShapesOperations::ExtendFace
4885 (const Handle(GEOM_Object) &theFace,
4886 const Standard_Real theUMin,
4887 const Standard_Real theUMax,
4888 const Standard_Real theVMin,
4889 const Standard_Real theVMax)
4893 if (theFace.IsNull()) {
4897 //Add a new Face object
4898 Handle(GEOM_Object) aResFace = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
4900 //Add a new Vector function
4901 Handle(GEOM_Function) aFunction =
4902 aResFace->AddFunction(GEOMImpl_ShapeDriver::GetID(), FACE_UV);
4904 //Check if the function is set correctly
4905 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) {
4909 GEOMImpl_IShapeExtend aCI (aFunction);
4911 Handle(GEOM_Function) aFace = theFace->GetLastFunction();
4913 if (aFace.IsNull()) {
4917 aCI.SetShape(aFace);
4918 aCI.SetUMin(theUMin);
4919 aCI.SetUMax(theUMax);
4920 aCI.SetVMin(theVMin);
4921 aCI.SetVMax(theVMax);
4923 //Compute the Face value
4926 if (!GetSolver()->ComputeFunction(aFunction)) {
4927 SetErrorCode("Shape driver failed");
4932 catch (Standard_Failure) {
4933 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
4934 SetErrorCode(aFail->GetMessageString());
4939 //Make a Python command
4940 GEOM::TPythonDump(aFunction)
4941 << aResFace << " = geompy.ExtendFace("
4942 << theFace << ", " << theUMin << ", " << theUMax << ", "
4943 << theVMin << ", " << theVMax << ")";
4950 //=======================================================================
4951 //function : MakeSurfaceFromFace
4953 //=======================================================================
4954 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeSurfaceFromFace
4955 (const Handle(GEOM_Object) &theFace)
4959 if (theFace.IsNull()) {
4963 //Add a new Face object
4964 Handle(GEOM_Object) aResFace = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
4966 //Add a new Vector function
4967 Handle(GEOM_Function) aFunction =
4968 aResFace->AddFunction(GEOMImpl_ShapeDriver::GetID(), SURFACE_FROM_FACE);
4970 //Check if the function is set correctly
4971 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) {
4975 GEOMImpl_IShapeExtend aCI (aFunction);
4977 Handle(GEOM_Function) aFace = theFace->GetLastFunction();
4979 if (aFace.IsNull()) {
4983 aCI.SetShape(aFace);
4985 //Compute the Face value
4988 if (!GetSolver()->ComputeFunction(aFunction)) {
4989 SetErrorCode("Shape driver failed");
4994 catch (Standard_Failure) {
4995 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
4996 SetErrorCode(aFail->GetMessageString());
5001 //Make a Python command
5002 GEOM::TPythonDump(aFunction)
5003 << aResFace << " = geompy.MakeSurfaceFromFace("