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
139 //=============================================================================
143 //=============================================================================
144 GEOMImpl_IShapesOperations::GEOMImpl_IShapesOperations (GEOM_Engine* theEngine, int theDocID)
145 : GEOM_IOperations(theEngine, theDocID)
147 MESSAGE("GEOMImpl_IShapesOperations::GEOMImpl_IShapesOperations");
150 //=============================================================================
154 //=============================================================================
155 GEOMImpl_IShapesOperations::~GEOMImpl_IShapesOperations()
157 MESSAGE("GEOMImpl_IShapesOperations::~GEOMImpl_IShapesOperations");
160 //=============================================================================
164 //=============================================================================
165 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeEdge
166 (Handle(GEOM_Object) thePnt1, Handle(GEOM_Object) thePnt2)
170 if (thePnt1.IsNull() || thePnt2.IsNull()) return NULL;
172 //Add a new Edge object
173 Handle(GEOM_Object) anEdge = GetEngine()->AddObject(GetDocID(), GEOM_EDGE);
175 //Add a new Vector function
176 Handle(GEOM_Function) aFunction =
177 anEdge->AddFunction(GEOMImpl_VectorDriver::GetID(), VECTOR_TWO_PNT);
179 //Check if the function is set correctly
180 if (aFunction->GetDriverGUID() != GEOMImpl_VectorDriver::GetID()) return NULL;
182 GEOMImpl_IVector aPI (aFunction);
184 Handle(GEOM_Function) aRef1 = thePnt1->GetLastFunction();
185 Handle(GEOM_Function) aRef2 = thePnt2->GetLastFunction();
186 if (aRef1.IsNull() || aRef2.IsNull()) return NULL;
188 aPI.SetPoint1(aRef1);
189 aPI.SetPoint2(aRef2);
191 //Compute the Edge value
194 if (!GetSolver()->ComputeFunction(aFunction)) {
195 SetErrorCode("Vector driver failed");
199 catch (Standard_Failure) {
200 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
201 SetErrorCode(aFail->GetMessageString());
205 //Make a Python command
206 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdge("
207 << thePnt1 << ", " << thePnt2 << ")";
213 //=============================================================================
215 * MakeEdgeOnCurveByLength
217 //=============================================================================
218 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeEdgeOnCurveByLength
219 (Handle(GEOM_Object) theRefCurve,
220 const Standard_Real theLength,
221 Handle(GEOM_Object) theStartPoint)
225 if (theRefCurve.IsNull()) return NULL;
227 //Add a new Edge object
228 Handle(GEOM_Object) anEdge = GetEngine()->AddObject(GetDocID(), GEOM_EDGE);
230 //Add a new Vector function
231 Handle(GEOM_Function) aFunction =
232 anEdge->AddFunction(GEOMImpl_ShapeDriver::GetID(), EDGE_CURVE_LENGTH);
234 //Check if the function is set correctly
235 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
237 GEOMImpl_IVector aPI (aFunction);
239 Handle(GEOM_Function) aRef1 = theRefCurve->GetLastFunction();
240 if (aRef1.IsNull()) return NULL;
241 aPI.SetPoint1(aRef1);
243 if (!theStartPoint.IsNull()) {
244 Handle(GEOM_Function) aRef2 = theStartPoint->GetLastFunction();
245 aPI.SetPoint2(aRef2);
248 aPI.SetParameter(theLength);
250 //Compute the Edge value
253 if (!GetSolver()->ComputeFunction(aFunction)) {
254 SetErrorCode("Vector driver failed");
258 catch (Standard_Failure) {
259 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
260 SetErrorCode(aFail->GetMessageString());
264 //Make a Python command
265 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdgeOnCurveByLength("
266 << theRefCurve << ", " << theLength << ", " << theStartPoint << ")";
272 //=============================================================================
276 //=============================================================================
277 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeEdgeWire
278 (Handle(GEOM_Object) theWire,
279 const Standard_Real theLinearTolerance,
280 const Standard_Real theAngularTolerance)
284 if (theWire.IsNull()) return NULL;
286 //Add a new Edge object
287 Handle(GEOM_Object) anEdge = GetEngine()->AddObject(GetDocID(), GEOM_EDGE);
289 //Add a new Vector function
290 Handle(GEOM_Function) aFunction =
291 anEdge->AddFunction(GEOMImpl_ShapeDriver::GetID(), EDGE_WIRE);
293 //Check if the function is set correctly
294 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
296 GEOMImpl_IShapes aCI (aFunction);
298 Handle(GEOM_Function) aWire = theWire->GetLastFunction();
300 if (aWire.IsNull()) return NULL;
303 aCI.SetTolerance(theLinearTolerance);
304 aCI.SetAngularTolerance(theAngularTolerance);
306 //Compute the Edge value
309 if (!GetSolver()->ComputeFunction(aFunction)) {
310 SetErrorCode("Shape driver failed");
314 catch (Standard_Failure) {
315 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
316 SetErrorCode(aFail->GetMessageString());
320 const double DEF_LIN_TOL = Precision::Confusion();
321 const double DEF_ANG_TOL = Precision::Angular();
322 //Make a Python command
323 if ( theAngularTolerance == DEF_ANG_TOL ) {
324 if ( theLinearTolerance == DEF_LIN_TOL )
325 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdgeWire("
328 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdgeWire("
329 << theWire << ", " << theLinearTolerance << ")";
332 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdgeWire("
333 << theWire << ", " << theLinearTolerance << ", "
334 << theAngularTolerance << ")";
341 //=============================================================================
345 //=============================================================================
346 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeWire
347 (std::list<Handle(GEOM_Object)> theShapes,
348 const Standard_Real theTolerance)
353 Handle(GEOM_Object) aWire = GetEngine()->AddObject(GetDocID(), GEOM_WIRE);
356 Handle(GEOM_Function) aFunction =
357 aWire->AddFunction(GEOMImpl_ShapeDriver::GetID(), WIRE_EDGES);
358 if (aFunction.IsNull()) return NULL;
360 //Check if the function is set correctly
361 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
363 GEOMImpl_IShapes aCI (aFunction);
364 aCI.SetTolerance(theTolerance);
366 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
369 std::list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
370 for (; it != theShapes.end(); it++) {
371 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
372 if (aRefSh.IsNull()) {
373 SetErrorCode("NULL argument shape for the shape construction");
376 aShapesSeq->Append(aRefSh);
378 aCI.SetShapes(aShapesSeq);
383 if (!GetSolver()->ComputeFunction(aFunction)) {
384 SetErrorCode("Shape driver failed");
388 catch (Standard_Failure) {
389 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
390 SetErrorCode(aFail->GetMessageString());
394 //Make a Python command
395 GEOM::TPythonDump pd (aFunction);
396 pd << aWire << " = geompy.MakeWire([";
399 it = theShapes.begin();
400 if (it != theShapes.end()) {
402 while (it != theShapes.end()) {
403 pd << ", " << (*it++);
406 pd << "], " << theTolerance << ")";
412 //=============================================================================
416 //=============================================================================
417 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFace (Handle(GEOM_Object) theWire,
418 const bool isPlanarWanted)
422 if (theWire.IsNull()) return NULL;
424 //Add a new Face object
425 Handle(GEOM_Object) aFace = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
427 //Add a new Shape function for creation of a face from a wire
428 Handle(GEOM_Function) aFunction =
429 aFace->AddFunction(GEOMImpl_ShapeDriver::GetID(), FACE_WIRE);
430 if (aFunction.IsNull()) return NULL;
432 //Check if the function is set correctly
433 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
435 GEOMImpl_IShapes aCI (aFunction);
437 Handle(GEOM_Function) aRefWire = theWire->GetLastFunction();
439 if (aRefWire.IsNull()) return NULL;
441 aCI.SetBase(aRefWire);
442 aCI.SetIsPlanar(isPlanarWanted);
444 //Compute the Face value
445 Standard_Boolean isWarning = Standard_False;
448 if (!GetSolver()->ComputeFunction(aFunction)) {
449 SetErrorCode("Shape driver failed to compute a face");
453 catch (Standard_Failure) {
454 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
455 SetErrorCode(aFail->GetMessageString());
456 // to provide warning
457 if (!aFunction->GetValue().IsNull()) {
458 isWarning = Standard_True;
464 //Make a Python command
465 GEOM::TPythonDump(aFunction) << aFace << " = geompy.MakeFace("
466 << theWire << ", " << (int)isPlanarWanted << ")";
468 // to provide warning
469 if (!isWarning) SetErrorCode(OK);
473 //=============================================================================
477 //=============================================================================
478 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFaceWires
479 (std::list<Handle(GEOM_Object)> theShapes,
480 const bool isPlanarWanted)
485 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
488 Handle(GEOM_Function) aFunction =
489 aShape->AddFunction(GEOMImpl_ShapeDriver::GetID(), FACE_WIRES);
490 if (aFunction.IsNull()) return NULL;
492 //Check if the function is set correctly
493 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
495 GEOMImpl_IShapes aCI (aFunction);
497 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
500 std::list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
501 for (; it != theShapes.end(); it++) {
502 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
503 if (aRefSh.IsNull()) {
504 SetErrorCode("NULL argument shape for the face construction");
507 aShapesSeq->Append(aRefSh);
509 aCI.SetShapes(aShapesSeq);
511 aCI.SetIsPlanar(isPlanarWanted);
514 Standard_Boolean isWarning = Standard_False;
517 if (!GetSolver()->ComputeFunction(aFunction)) {
518 SetErrorCode("Shape driver failed");
522 catch (Standard_Failure) {
523 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
524 SetErrorCode(aFail->GetMessageString());
525 // to provide warning
526 if (!aFunction->GetValue().IsNull()) {
527 isWarning = Standard_True;
533 //Make a Python command
534 GEOM::TPythonDump pd (aFunction);
535 pd << aShape << " = geompy.MakeFaceWires([";
538 it = theShapes.begin();
539 if (it != theShapes.end()) {
541 while (it != theShapes.end()) {
542 pd << ", " << (*it++);
545 pd << "], " << (int)isPlanarWanted << ")";
547 // to provide warning
548 if (!isWarning) SetErrorCode(OK);
552 //=============================================================================
554 * MakeFaceFromSurface
556 //=============================================================================
557 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFaceFromSurface
558 (Handle(GEOM_Object) theFace,
559 Handle(GEOM_Object) theWire)
564 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
567 Handle(GEOM_Function) aFunction =
568 aShape->AddFunction(GEOMImpl_ShapeDriver::GetID(), FACE_FROM_SURFACE);
570 if (aFunction.IsNull()) {
574 //Check if the function is set correctly
575 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) {
579 GEOMImpl_IShapes aCI (aFunction);
580 Handle(TColStd_HSequenceOfTransient) aShapesSeq =
581 new TColStd_HSequenceOfTransient;
582 Handle(GEOM_Function) aRefFace = theFace->GetLastFunction();
583 Handle(GEOM_Function) aRefWire = theWire->GetLastFunction();
585 if (aRefFace.IsNull()) {
586 SetErrorCode("NULL argument face for the face construction");
590 if (aRefWire.IsNull()) {
591 SetErrorCode("NULL argument wire for the face construction");
595 aShapesSeq->Append(aRefFace);
596 aShapesSeq->Append(aRefWire);
598 aCI.SetShapes(aShapesSeq);
603 if (!GetSolver()->ComputeFunction(aFunction)) {
604 SetErrorCode("Shape driver failed");
608 catch (Standard_Failure) {
609 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
610 SetErrorCode(aFail->GetMessageString());
614 //Make a Python command
615 GEOM::TPythonDump (aFunction) << aShape
616 << " = geompy.MakeFaceFromSurface(" << theFace << ", " << theWire << ")";
623 //=============================================================================
627 //=============================================================================
628 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeShell
629 (std::list<Handle(GEOM_Object)> theShapes)
631 return MakeShape(theShapes, GEOM_SHELL, SHELL_FACES, "MakeShell");
634 //=============================================================================
638 //=============================================================================
639 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeSolidShells
640 (std::list<Handle(GEOM_Object)> theShapes)
642 return MakeShape(theShapes, GEOM_SOLID, SOLID_SHELLS, "MakeSolid");
645 //=============================================================================
649 //=============================================================================
650 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeCompound
651 (std::list<Handle(GEOM_Object)> theShapes)
653 return MakeShape(theShapes, GEOM_COMPOUND, COMPOUND_SHAPES, "MakeCompound");
656 //=============================================================================
660 //=============================================================================
661 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeShape
662 (std::list<Handle(GEOM_Object)> theShapes,
663 const Standard_Integer theObjectType,
664 const Standard_Integer theFunctionType,
665 const TCollection_AsciiString& theMethodName)
670 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), theObjectType);
673 Handle(GEOM_Function) aFunction =
674 aShape->AddFunction(GEOMImpl_ShapeDriver::GetID(), theFunctionType);
675 if (aFunction.IsNull()) return NULL;
677 //Check if the function is set correctly
678 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
680 GEOMImpl_IShapes aCI (aFunction);
682 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
685 std::list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
686 for (; it != theShapes.end(); it++) {
687 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
688 if (aRefSh.IsNull()) {
689 SetErrorCode("NULL argument shape for the shape construction");
692 aShapesSeq->Append(aRefSh);
694 aCI.SetShapes(aShapesSeq);
699 if (!GetSolver()->ComputeFunction(aFunction)) {
700 SetErrorCode("Shape driver failed");
704 catch (Standard_Failure) {
705 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
706 SetErrorCode(aFail->GetMessageString());
710 //Make a Python command
711 GEOM::TPythonDump pd (aFunction);
712 pd << aShape << " = geompy." << theMethodName.ToCString() << "([";
715 it = theShapes.begin();
716 if (it != theShapes.end()) {
718 while (it != theShapes.end()) {
719 pd << ", " << (*it++);
728 //=============================================================================
732 //=============================================================================
734 GEOMImpl_IShapesOperations::MakeGlueFaces (std::list< Handle(GEOM_Object) >& theShapes,
735 const Standard_Real theTolerance,
736 const Standard_Boolean doKeepNonSolids)
740 Handle(TColStd_HSequenceOfTransient) objects = GEOM_Object::GetLastFunctions( theShapes );
741 if ( objects.IsNull() || objects->IsEmpty() ) {
742 SetErrorCode("NULL argument shape");
746 //Add a new Glued object
747 Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
749 //Add a new Glue function
750 Handle(GEOM_Function) aFunction;
751 aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_FACES);
752 if (aFunction.IsNull()) return NULL;
754 //Check if the function is set correctly
755 if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
757 GEOMImpl_IGlue aCI (aFunction);
759 aCI.SetBase( objects );
760 aCI.SetTolerance(theTolerance);
761 aCI.SetKeepNonSolids(doKeepNonSolids);
763 //Compute the sub-shape value
764 Standard_Boolean isWarning = Standard_False;
767 if (!GetSolver()->ComputeFunction(aFunction)) {
768 SetErrorCode("Shape driver failed to glue faces");
772 catch (Standard_Failure) {
773 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
774 SetErrorCode(aFail->GetMessageString());
775 // to provide warning
776 if (!aFunction->GetValue().IsNull()) {
777 isWarning = Standard_True;
783 //Make a Python command
784 GEOM::TPythonDump(aFunction) << aGlued << " = geompy.MakeGlueFaces("
785 << theShapes << ", " << theTolerance << ")";
787 // to provide warning
788 if (!isWarning) SetErrorCode(OK);
792 //=============================================================================
796 //=============================================================================
798 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetGlueFaces
799 (Handle(GEOM_Object) theShape,
800 const Standard_Real theTolerance)
804 if (theShape.IsNull()) return NULL;
805 TopoDS_Shape aShape = theShape->GetValue();
806 if (aShape.IsNull()) return NULL;
808 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
810 Standard_Integer iErr;
812 GEOMAlgo_Gluer1 aGluer;
813 GEOMAlgo_ListIteratorOfListOfCoupleOfShapes aItCS;
814 GEOMAlgo_CoupleOfShapes aCS;
815 GEOMAlgo_ListOfCoupleOfShapes aLCS;
817 //aGluer = new GEOMAlgo_Gluer1;
818 aGluer.SetShape(aShape);
819 aGluer.SetTolerance(theTolerance);
821 iErr = aGluer.ErrorStatus();
822 if (iErr) return NULL;
824 TopTools_ListOfShape listShape;
825 const GEOMAlgo_ListOfCoupleOfShapes& aLCSG = aGluer.GluedFaces();
827 aItCS.Initialize(aLCSG);
828 for (; aItCS.More(); aItCS.Next()) {
829 const GEOMAlgo_CoupleOfShapes& aCSG = aItCS.Value();
830 listShape.Append(aCSG.Shape1());
833 TopTools_ListIteratorOfListOfShape itSub (listShape);
834 TCollection_AsciiString anAsciiList, anEntry;
835 TopTools_IndexedMapOfShape anIndices;
836 TopExp::MapShapes(aShape, anIndices);
837 Handle(TColStd_HArray1OfInteger) anArray;
838 Handle(GEOM_Object) anObj;
839 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
840 TopoDS_Shape aValue = itSub.Value();
841 anArray = new TColStd_HArray1OfInteger(1,1);
842 anArray->SetValue(1, anIndices.FindIndex(aValue));
843 anObj = GetEngine()->AddSubShape(theShape, anArray);
844 if (!anObj.IsNull()) {
847 // for python command
848 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
849 anAsciiList += anEntry;
854 //Make a Python command
855 if( anAsciiList.Length() > 0 ) {
856 anAsciiList.Trunc(anAsciiList.Length() - 1);
857 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
858 GEOM::TPythonDump pd (aFunction, true);
859 pd << "[" << anAsciiList.ToCString();
860 pd << "] = geompy.GetGlueFaces(" << theShape << ", " << theTolerance << ")";
869 //=============================================================================
871 * MakeGlueFacesByList
873 //=============================================================================
875 GEOMImpl_IShapesOperations::MakeGlueFacesByList(std::list< Handle(GEOM_Object) >& theShapes,
876 const Standard_Real theTolerance,
877 std::list<Handle(GEOM_Object)> & theFaces,
878 const Standard_Boolean doKeepNonSolids,
879 const Standard_Boolean doGlueAllEdges)
883 Handle(TColStd_HSequenceOfTransient) objects = GEOM_Object::GetLastFunctions( theShapes );
884 if ( objects.IsNull() || objects->IsEmpty() ) {
885 SetErrorCode("NULL argument shape");
888 Handle(TColStd_HSequenceOfTransient) aFaces = GEOM_Object::GetLastFunctions( theFaces );
889 if ( aFaces.IsNull() ) {
890 SetErrorCode("NULL argument shape for the shape construction");
894 //Add a new Glued object
895 Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
897 //Add a new Glue function
898 Handle(GEOM_Function) aFunction;
899 aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_FACES_BY_LIST);
900 if (aFunction.IsNull()) return NULL;
902 //Check if the function is set correctly
903 if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
905 GEOMImpl_IGlue aCI (aFunction);
907 aCI.SetBase( objects );
908 aCI.SetTolerance(theTolerance);
909 aCI.SetKeepNonSolids(doKeepNonSolids);
910 aCI.SetGlueAllEdges(doGlueAllEdges);
911 aCI.SetFaces(aFaces);
913 //Compute the sub-shape value
914 Standard_Boolean isWarning = Standard_False;
917 if (!GetSolver()->ComputeFunction(aFunction)) {
918 SetErrorCode("Shape driver failed to glue faces");
922 catch (Standard_Failure) {
923 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
924 SetErrorCode(aFail->GetMessageString());
925 // to provide warning
926 if (!aFunction->GetValue().IsNull()) {
927 isWarning = Standard_True;
933 //Make a Python command
935 GEOM::TPythonDump pd(aFunction);
936 pd << aGlued << " = geompy.MakeGlueFacesByList("
937 << theShapes << ", " << theTolerance << ", " << theFaces << ", "
938 << (bool)doKeepNonSolids << ", " << (bool)doGlueAllEdges << ")";
940 // to provide warning
941 if (!isWarning) SetErrorCode(OK);
945 //=============================================================================
949 //=============================================================================
951 GEOMImpl_IShapesOperations::MakeGlueEdges (std::list< Handle(GEOM_Object) >& theShapes,
952 const Standard_Real theTolerance)
956 Handle(TColStd_HSequenceOfTransient) objects = GEOM_Object::GetLastFunctions( theShapes );
957 if ( objects.IsNull() || objects->IsEmpty() ) {
958 SetErrorCode("NULL argument shape");
962 //Add a new Glued object
963 Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
965 //Add a new Glue function
966 Handle(GEOM_Function) aFunction;
967 aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_EDGES);
968 if (aFunction.IsNull()) return NULL;
970 //Check if the function is set correctly
971 if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
973 GEOMImpl_IGlue aCI (aFunction);
975 aCI.SetBase( objects );
976 aCI.SetTolerance(theTolerance);
977 aCI.SetKeepNonSolids(true);
979 //Compute the sub-shape value
980 Standard_Boolean isWarning = Standard_False;
983 if (!GetSolver()->ComputeFunction(aFunction)) {
984 SetErrorCode("Shape driver failed to glue edges");
988 catch (Standard_Failure) {
989 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
990 SetErrorCode(aFail->GetMessageString());
991 // to provide warning
992 if (!aFunction->GetValue().IsNull()) {
993 isWarning = Standard_True;
999 //Make a Python command
1000 GEOM::TPythonDump(aFunction) << aGlued << " = geompy.MakeGlueEdges("
1001 << theShapes << ", " << theTolerance << ")";
1003 // to provide warning
1004 if (!isWarning) SetErrorCode(OK);
1008 //=============================================================================
1012 //=============================================================================
1013 Handle(TColStd_HSequenceOfTransient)
1014 GEOMImpl_IShapesOperations::GetGlueShapes (std::list< Handle(GEOM_Object) >& theShapes,
1015 const Standard_Real theTolerance,
1016 const TopAbs_ShapeEnum theType)
1020 TopoDS_Shape aShape;
1021 TopTools_SequenceOfShape shapes;
1022 std::list< Handle(GEOM_Object) >::iterator s = theShapes.begin();
1023 Handle(GEOM_Object) lastCreatedGO;
1024 for ( ; s != theShapes.end(); ++s )
1026 Handle(GEOM_Object) go = *s;
1027 if ( go.IsNull() ) return NULL;
1028 aShape = go->GetValue();
1029 if ( aShape.IsNull() ) return NULL;
1030 shapes.Append( aShape );
1031 lastCreatedGO = GEOM::GetCreatedLast( lastCreatedGO, go );
1033 if ( shapes.Length() > 1 )
1035 TopoDS_Compound compound;
1036 BRep_Builder builder;
1037 builder.MakeCompound( compound );
1038 for ( int i = 1; i <= shapes.Length(); ++i )
1039 builder.Add( compound, shapes( i ) );
1044 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1046 GEOMAlgo_GlueDetector aGluer;
1047 aGluer.SetArgument(aShape);
1048 aGluer.SetTolerance(theTolerance);
1050 Standard_Integer iErr = aGluer.ErrorStatus();
1051 if (iErr) return NULL;
1053 std::vector< TopTools_IndexedMapOfShape* > anIndices( shapes.Length(), NULL );
1054 Handle(TColStd_HArray1OfInteger) anArray;
1055 Handle(GEOM_Object) anObj;
1057 TopTools_ListOfShape listOnePerSet;
1059 const TopTools_DataMapOfShapeListOfShape& aImages = aGluer.Images();
1060 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape aItDMSLS (aImages);
1061 for (int index = 1; aItDMSLS.More(); aItDMSLS.Next(), ++index) {
1063 //const TopoDS_Shape& aSkey = aItDMSLS.Key();
1065 // list of shapes of the argument that can be glued
1066 const TopTools_ListOfShape& aLSD = aItDMSLS.Value();
1068 //listShape.Append(aLSD.First());
1069 TopoDS_Shape aValue = aLSD.First();
1071 if (aValue.ShapeType() == theType) {
1072 listOnePerSet.Append(aValue);
1076 // for stable order of returned entities
1077 GEOMUtils::SortShapes(listOnePerSet, Standard_False);
1079 TopTools_ListIteratorOfListOfShape aListIt (listOnePerSet);
1080 for (; aListIt.More(); aListIt.Next())
1082 TopoDS_Shape aValue = aListIt.Value();
1083 // find a shape to add aValue as a sub-shape
1085 s = theShapes.begin();
1086 for ( int i = 0; i < shapes.Length(); ++i, ++s )
1088 Handle(GEOM_Object) object = *s;
1089 if ( !anIndices[i] ) {
1090 anIndices[i] = new TopTools_IndexedMapOfShape;
1091 TopExp::MapShapes( object->GetValue(), *anIndices[i]);
1093 if (int index = anIndices[i]->FindIndex( aValue )) {
1094 anArray = new TColStd_HArray1OfInteger(1,1);
1095 anArray->SetValue(1, index);
1096 anObj = GetEngine()->AddSubShape( object, anArray);
1100 if (!anObj.IsNull())
1101 aSeq->Append(anObj);
1103 for ( size_t i = 0 ; i < anIndices.size(); ++i )
1104 delete anIndices[i];
1106 // Make a Python command
1107 if ( aSeq->Length() > 0)
1109 Handle(GEOM_Function) aFunction = lastCreatedGO->GetLastFunction();
1110 GEOM::TPythonDump pd (aFunction, /*append=*/true);
1112 << " = geompy." << (theType == TopAbs_FACE ? "GetGlueFaces" : "GetGlueEdges" )
1113 << "( " << theShapes << ", " << theTolerance << ")";
1121 //=============================================================================
1123 * MakeGlueEdgesByList
1125 //=============================================================================
1127 GEOMImpl_IShapesOperations::MakeGlueEdgesByList (std::list< Handle(GEOM_Object) >& theShapes,
1128 const Standard_Real theTolerance,
1129 std::list<Handle(GEOM_Object)>& theEdges)
1133 Handle(TColStd_HSequenceOfTransient) objects = GEOM_Object::GetLastFunctions( theShapes );
1134 if ( objects.IsNull() || objects->IsEmpty() ) {
1135 SetErrorCode("NULL argument shape");
1138 Handle(TColStd_HSequenceOfTransient) anEdges = GEOM_Object::GetLastFunctions( theEdges );
1139 if ( anEdges.IsNull() ) {
1140 SetErrorCode("NULL argument shape for the shape construction");
1143 //Add a new Glued object
1144 Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
1146 //Add a new Glue function
1147 Handle(GEOM_Function) aFunction;
1148 aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_EDGES_BY_LIST);
1149 if (aFunction.IsNull()) return NULL;
1151 //Check if the function is set correctly
1152 if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
1154 GEOMImpl_IGlue aCI (aFunction);
1156 aCI.SetBase( objects );
1157 aCI.SetTolerance(theTolerance);
1158 aCI.SetKeepNonSolids(true);
1159 aCI.SetFaces(anEdges);
1161 //Compute the sub-shape value
1162 Standard_Boolean isWarning = Standard_False;
1165 if (!GetSolver()->ComputeFunction(aFunction)) {
1166 SetErrorCode("Shape driver failed to glue edges");
1170 catch (Standard_Failure) {
1171 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1172 SetErrorCode(aFail->GetMessageString());
1173 // to provide warning
1174 if (!aFunction->GetValue().IsNull()) {
1175 isWarning = Standard_True;
1181 //Make a Python command
1183 GEOM::TPythonDump pd (aFunction);
1184 pd << aGlued << " = geompy.MakeGlueEdgesByList("
1185 << theShapes << ", " << theTolerance << ", " << theEdges << " )";
1187 // to provide warning
1188 if (!isWarning) SetErrorCode(OK);
1192 //=============================================================================
1194 * GetExistingSubObjects
1196 //=============================================================================
1197 Handle(TColStd_HSequenceOfTransient)
1198 GEOMImpl_IShapesOperations::GetExistingSubObjects(Handle(GEOM_Object) theShape,
1199 const Standard_Boolean theGroupsOnly)
1201 // note: this method does not return fields
1203 Standard_Integer types = theGroupsOnly ? Groups : Groups|SubShapes;
1204 Handle(TColStd_HSequenceOfTransient) results = GetExistingSubObjects(theShape, types);
1206 if (results->Length() > 0) {
1207 //Make a Python command
1208 TCollection_AsciiString anAsciiList;
1209 for (int i = 1; i <= results->Length(); i++)
1211 Handle(GEOM_BaseObject) obj = Handle(GEOM_BaseObject)::DownCast( results->Value(i));
1212 obj->GetEntryString();
1213 if ( i < results->Length() )
1217 GEOM::TPythonDump pd (theShape->GetLastFunction(), /*append=*/true);
1218 pd << "[" << anAsciiList.ToCString();
1219 pd << "] = geompy.GetExistingSubObjects(";
1220 pd << theShape << ", " << (bool)theGroupsOnly << ")";
1226 Handle(TColStd_HSequenceOfTransient)
1227 GEOMImpl_IShapesOperations::GetExistingSubObjects(Handle(GEOM_Object) theShape,
1228 const Standard_Integer theTypes)
1232 if (theShape.IsNull()) return NULL;
1234 Handle(GEOM_Function) aMainShape = theShape->GetLastFunction();
1235 if (aMainShape.IsNull()) return NULL;
1237 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1238 SetErrorCode(NOT_FOUND_ANY);
1240 if (!aMainShape->HasSubShapeReferences()) return aSeq;
1241 const TDataStd_ListOfExtendedString& aListEntries = aMainShape->GetSubShapeReferences();
1242 if (aListEntries.IsEmpty()) return aSeq;
1246 TDataStd_ListIteratorOfListOfExtendedString anIt (aListEntries);
1247 for (; anIt.More(); anIt.Next()) {
1248 TCollection_ExtendedString anEntry = anIt.Value();
1249 Standard_Integer aStrLen = anEntry.LengthOfCString();
1250 char* anEntryStr = new char[aStrLen+1];
1251 anEntry.ToUTF8CString(anEntryStr);
1252 Handle(GEOM_BaseObject) anObj = GetEngine()->GetObject(GetDocID(), anEntryStr, false);
1253 if (!anObj.IsNull() ) {
1254 bool isGroup = anObj->IsKind(STANDARD_TYPE(GEOM_Object)) && anObj->GetType() == GEOM_GROUP;
1255 bool isSubShape = anObj->IsKind(STANDARD_TYPE(GEOM_Object)) && anObj->GetType() != GEOM_GROUP;
1256 bool isField = anObj->IsKind(STANDARD_TYPE(GEOM_Field));
1257 if (theTypes & Groups && isGroup ||
1258 theTypes & SubShapes && isSubShape ||
1259 theTypes & Fields && isField) {
1260 aSeq->Append(anObj);
1263 delete [] anEntryStr;
1266 if (aSeq->Length() == 0) {
1267 SetErrorCode(NOT_FOUND_ANY);
1276 //=============================================================================
1280 //=============================================================================
1281 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::MakeExplode
1282 (Handle(GEOM_Object) theShape,
1283 const Standard_Integer theShapeType,
1284 const Standard_Boolean isSorted,
1285 const ExplodeType theExplodeType)
1289 if (theShape.IsNull()) return NULL;
1290 TopoDS_Shape aShape = theShape->GetValue();
1291 if (aShape.IsNull()) return NULL;
1293 Handle(GEOM_Function) aMainShape = theShape->GetLastFunction();
1295 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1296 Handle(GEOM_Object) anObj;
1297 TopTools_MapOfShape mapShape;
1298 TopTools_ListOfShape listShape;
1300 if (aShape.ShapeType() == TopAbs_COMPOUND &&
1301 (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
1302 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPSOLID ||
1303 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPOUND))
1305 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
1306 for (; It.More(); It.Next()) {
1307 if (mapShape.Add(It.Value())) {
1308 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
1309 TopAbs_ShapeEnum(theShapeType) == It.Value().ShapeType()) {
1310 listShape.Append(It.Value());
1315 else if (theExplodeType != EXPLODE_NEW_EXCLUDE_MAIN || aShape.ShapeType() != theShapeType) // issue 0021079
1317 TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
1318 for (; exp.More(); exp.Next())
1319 if (mapShape.Add(exp.Current()))
1320 listShape.Append(exp.Current());
1323 if (listShape.IsEmpty()) {
1324 //SetErrorCode("The given shape has no sub-shapes of the requested type");
1325 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
1330 bool isOldSorting = false;
1331 if (theExplodeType == EXPLODE_OLD_INCLUDE_MAIN)
1332 isOldSorting = true;
1333 GEOMUtils::SortShapes(listShape, isOldSorting);
1336 TopTools_IndexedMapOfShape anIndices;
1337 TopExp::MapShapes(aShape, anIndices);
1338 Handle(TColStd_HArray1OfInteger) anArray;
1340 TopTools_ListIteratorOfListOfShape itSub (listShape);
1341 TCollection_AsciiString anAsciiList, anEntry;
1342 for (int index = 1; itSub.More(); itSub.Next(), ++index)
1344 TopoDS_Shape aValue = itSub.Value();
1345 anArray = new TColStd_HArray1OfInteger(1,1);
1346 anArray->SetValue(1, anIndices.FindIndex(aValue));
1348 //anObj = GetEngine()->AddSubShape(theShape, anArray);
1350 anObj = GetEngine()->AddObject(GetDocID(), GEOM_SUBSHAPE);
1351 Handle(GEOM_Function) aFunction = anObj->AddFunction(GEOM_Object::GetSubShapeID(), 1);
1352 if (aFunction.IsNull()) return aSeq;
1354 GEOM_ISubShape aSSI (aFunction);
1355 aSSI.SetMainShape(aMainShape);
1356 aSSI.SetIndices(anArray);
1358 // Set function value directly, as we know it.
1359 // Usage of Solver here would lead to significant loss of time,
1360 // because GEOM_SubShapeDriver will build TopTools_IndexedMapOfShape
1361 // on the main shape for each being calculated sub-shape separately.
1362 aFunction->SetValue(aValue);
1364 // Put this subshape in the list of sub-shapes of theMainShape
1365 aMainShape->AddSubShapeReference(aFunction);
1368 if (!anObj.IsNull()) {
1369 aSeq->Append(anObj);
1371 // for python command
1372 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
1373 anAsciiList += anEntry;
1378 //Make a Python command
1379 anAsciiList.Trunc(anAsciiList.Length() - 1);
1381 GEOM::TPythonDump pd (aMainShape, /*append=*/true);
1382 pd << "[" << anAsciiList.ToCString() << "] = geompy.";
1383 switch (theExplodeType) {
1384 case EXPLODE_NEW_EXCLUDE_MAIN:
1385 pd << "ExtractShapes(" << theShape << ", "
1386 << TopAbs_ShapeEnum(theShapeType) << ", " << (isSorted ? "True" : "False") << ")";
1388 case EXPLODE_NEW_INCLUDE_MAIN:
1389 pd << "SubShapeAll" << (isSorted ? "SortedCentres(" : "(")
1390 << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
1392 case EXPLODE_OLD_INCLUDE_MAIN:
1393 pd << "SubShapeAll" << (isSorted ? "Sorted(" : "(")
1394 << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
1403 //=============================================================================
1407 //=============================================================================
1408 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::SubShapeAllIDs
1409 (Handle(GEOM_Object) theShape,
1410 const Standard_Integer theShapeType,
1411 const Standard_Boolean isSorted,
1412 const ExplodeType theExplodeType)
1416 if (theShape.IsNull()) return NULL;
1417 TopoDS_Shape aShape = theShape->GetValue();
1418 if (aShape.IsNull()) return NULL;
1420 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
1421 TopTools_MapOfShape mapShape;
1422 TopTools_ListOfShape listShape;
1424 if (aShape.ShapeType() == TopAbs_COMPOUND &&
1425 (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
1426 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPSOLID ||
1427 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPOUND))
1429 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
1430 for (; It.More(); It.Next()) {
1431 if (mapShape.Add(It.Value())) {
1432 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
1433 TopAbs_ShapeEnum(theShapeType) == It.Value().ShapeType()) {
1434 listShape.Append(It.Value());
1439 else if (theExplodeType != EXPLODE_NEW_EXCLUDE_MAIN || aShape.ShapeType() != theShapeType) // issue 0021079
1441 TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
1442 for (; exp.More(); exp.Next())
1443 if (mapShape.Add(exp.Current()))
1444 listShape.Append(exp.Current());
1447 if (listShape.IsEmpty()) {
1448 //SetErrorCode("The given shape has no sub-shapes of the requested type");
1449 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
1454 bool isOldSorting = false;
1455 if (theExplodeType == EXPLODE_OLD_INCLUDE_MAIN)
1456 isOldSorting = true;
1457 GEOMUtils::SortShapes(listShape, isOldSorting);
1460 TopTools_IndexedMapOfShape anIndices;
1461 TopExp::MapShapes(aShape, anIndices);
1462 Handle(TColStd_HArray1OfInteger) anArray;
1464 TopTools_ListIteratorOfListOfShape itSub (listShape);
1465 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
1466 TopoDS_Shape aValue = itSub.Value();
1467 aSeq->Append(anIndices.FindIndex(aValue));
1470 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
1472 //Make a Python command
1473 GEOM::TPythonDump pd (aFunction, /*append=*/true);
1474 pd << "listSubShapeIDs = geompy.SubShapeAll";
1475 switch (theExplodeType) {
1476 case EXPLODE_NEW_EXCLUDE_MAIN:
1478 case EXPLODE_NEW_INCLUDE_MAIN:
1479 pd << (isSorted ? "SortedCentresIDs(" : "IDs(")
1480 << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
1482 case EXPLODE_OLD_INCLUDE_MAIN:
1483 pd << (isSorted ? "SortedIDs(" : "IDs(")
1484 << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
1493 //=============================================================================
1497 //=============================================================================
1498 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetSubShape
1499 (Handle(GEOM_Object) theMainShape,
1500 const Standard_Integer theID)
1504 if (theMainShape.IsNull()) return NULL;
1506 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
1507 anArray->SetValue(1, theID);
1508 Handle(GEOM_Object) anObj = GetEngine()->AddSubShape(theMainShape, anArray,true);
1509 if (anObj.IsNull()) {
1510 SetErrorCode("Can not get a sub-shape with the given ID");
1514 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1516 //Make a Python command
1517 GEOM::TPythonDump(aFunction) << anObj << " = geompy.GetSubShape("
1518 << theMainShape << ", [" << theID << "])";
1524 //=============================================================================
1528 //=============================================================================
1529 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::MakeSubShapes
1530 (Handle(GEOM_Object) theMainShape,
1531 Handle(TColStd_HArray1OfInteger) theIndices)
1535 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1537 if (!theIndices->Length()) {
1538 SetErrorCode(NOT_FOUND_ANY);
1542 if (theMainShape.IsNull()) return NULL;
1543 TopoDS_Shape aShape = theMainShape->GetValue();
1544 if (aShape.IsNull()) return NULL;
1546 Handle(GEOM_Function) aMainShape = theMainShape->GetLastFunction();
1548 TopTools_IndexedMapOfShape anIndices;
1549 TopExp::MapShapes(aShape, anIndices);
1551 Handle(TColStd_HArray1OfInteger) anArray;
1552 Handle(GEOM_Object) anObj;
1554 TCollection_AsciiString anAsciiList, anEntry;
1555 Standard_Integer i, low = theIndices->Lower(), up = theIndices->Upper();
1556 for (i = low; i <= up; i++) {
1557 int id = theIndices->Value(i);
1558 if (1 <= id && id <= anIndices.Extent()) {
1559 TopoDS_Shape aValue = anIndices.FindKey(id);
1560 anArray = new TColStd_HArray1OfInteger(1,1);
1561 anArray->SetValue(1, id);
1563 anObj = GetEngine()->AddObject(GetDocID(), GEOM_SUBSHAPE);
1564 if (!anObj.IsNull()) {
1565 Handle(GEOM_Function) aFunction = anObj->AddFunction(GEOM_Object::GetSubShapeID(), 1);
1566 if (aFunction.IsNull()) return aSeq;
1568 GEOM_ISubShape aSSI (aFunction);
1569 aSSI.SetMainShape(aMainShape);
1570 aSSI.SetIndices(anArray);
1572 // Set function value directly, as we know it.
1573 // Usage of Solver here would lead to significant loss of time,
1574 // because GEOM_SubShapeDriver will build TopTools_IndexedMapOfShape
1575 // on the main shape for each being calculated sub-shape separately.
1576 aFunction->SetValue(aValue);
1578 // Put this sub-shape in the list of sub-shapes of theMainShape
1579 aMainShape->AddSubShapeReference(aFunction);
1581 aSeq->Append(anObj);
1583 // for python command
1584 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
1585 anAsciiList += anEntry;
1591 //Make a Python command
1592 anAsciiList.Trunc(anAsciiList.Length() - 1);
1594 GEOM::TPythonDump pd (aMainShape, /*append=*/true);
1595 pd << "[" << anAsciiList.ToCString() << "] = geompy.SubShapes("
1596 << theMainShape << ", [" ;
1597 for (i = low; i <= up - 1; i++) {
1598 pd << theIndices->Value(i) << ", ";
1600 pd << theIndices->Value(up) << "])";
1607 //=============================================================================
1611 //=============================================================================
1612 Standard_Integer GEOMImpl_IShapesOperations::GetSubShapeIndex (Handle(GEOM_Object) theMainShape,
1613 Handle(GEOM_Object) theSubShape)
1617 TopoDS_Shape aMainShape = theMainShape->GetValue();
1618 TopoDS_Shape aSubShape = theSubShape->GetValue();
1620 if (aMainShape.IsNull() || aSubShape.IsNull()) return -1;
1622 TopTools_IndexedMapOfShape anIndices;
1623 TopExp::MapShapes(aMainShape, anIndices);
1624 // if (anIndices.Contains(aSubShape)) {
1625 // SetErrorCode(OK);
1626 // return anIndices.FindIndex(aSubShape);
1628 int id = anIndices.FindIndex(aSubShape);
1639 //=============================================================================
1641 * GetSubShapeIndices
1643 //=============================================================================
1644 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetSubShapesIndices (Handle(GEOM_Object) theMainShape,
1645 std::list<Handle(GEOM_Object)> theSubShapes)
1647 MESSAGE("GEOMImpl_IShapesOperations::GetSubShapesIndices")
1650 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
1652 TopoDS_Shape aMainShape = theMainShape->GetValue();
1653 if (aMainShape.IsNull())
1655 MESSAGE("NULL main shape")
1659 TopTools_IndexedMapOfShape anIndices;
1660 TopExp::MapShapes(aMainShape, anIndices);
1662 std::list<Handle(GEOM_Object)>::iterator it;
1663 for (it=theSubShapes.begin(); it != theSubShapes.end(); ++it)
1665 TopoDS_Shape aSubShape = (*it)->GetValue();
1666 if (aSubShape.IsNull())
1668 MESSAGE("NULL subshape")
1671 int id = anIndices.FindIndex(aSubShape);
1680 //=============================================================================
1684 //=============================================================================
1685 Standard_Integer GEOMImpl_IShapesOperations::GetTopologyIndex (Handle(GEOM_Object) theMainShape,
1686 Handle(GEOM_Object) theSubShape)
1690 TopoDS_Shape aMainShape = theMainShape->GetValue();
1691 TopoDS_Shape aSubShape = theSubShape->GetValue();
1693 if (aMainShape.IsNull() || aSubShape.IsNull()) {
1694 SetErrorCode("Null argument shape given");
1699 if (aSubShape.ShapeType() == TopAbs_COMPOUND) {
1701 TopTools_ListOfShape CL;
1702 CL.Append(aMainShape);
1703 TopTools_ListIteratorOfListOfShape itC;
1704 for (itC.Initialize(CL); itC.More(); itC.Next()) {
1705 for (it.Initialize(itC.Value()); it.More(); it.Next()) {
1706 if (it.Value().ShapeType() == TopAbs_COMPOUND) {
1707 if (it.Value().IsSame(aSubShape))
1711 CL.Append(it.Value());
1716 TopExp_Explorer anExp (aMainShape, aSubShape.ShapeType());
1717 TopTools_MapOfShape M;
1718 for (; anExp.More(); anExp.Next()) {
1719 if (M.Add(anExp.Current())) {
1720 if (anExp.Current().IsSame(aSubShape))
1727 SetErrorCode("The sub-shape does not belong to the main shape");
1731 //=============================================================================
1733 * GetShapeTypeString
1735 //=============================================================================
1736 TCollection_AsciiString GEOMImpl_IShapesOperations::GetShapeTypeString (Handle(GEOM_Object) theShape)
1740 TCollection_AsciiString aTypeName ("Null Shape");
1742 TopoDS_Shape aShape = theShape->GetValue();
1743 if (aShape.IsNull())
1746 switch (aShape.ShapeType() )
1748 case TopAbs_COMPOUND:
1749 aTypeName = "Compound";
1751 case TopAbs_COMPSOLID:
1752 aTypeName = "Compound Solid";
1755 aTypeName = "Solid";
1758 aTypeName = "Shell";
1762 BRepAdaptor_Surface surf (TopoDS::Face(aShape));
1763 if (surf.GetType() == GeomAbs_Plane)
1764 aTypeName = "Plane";
1765 else if (surf.GetType() == GeomAbs_Cylinder)
1766 aTypeName = "Cylindrical Face";
1767 else if (surf.GetType() == GeomAbs_Sphere)
1768 aTypeName = "Spherical Face";
1769 else if (surf.GetType() == GeomAbs_Torus)
1770 aTypeName = "Toroidal Face";
1771 else if (surf.GetType() == GeomAbs_Cone)
1772 aTypeName = "Conical Face";
1774 aTypeName = "GEOM::FACE";
1782 BRepAdaptor_Curve curv (TopoDS::Edge(aShape));
1783 if (curv.GetType() == GeomAbs_Line) {
1784 if ((Abs(curv.FirstParameter()) >= 1E6) ||
1785 (Abs(curv.LastParameter()) >= 1E6))
1789 } else if (curv.GetType() == GeomAbs_Circle) {
1790 if (curv.IsClosed())
1791 aTypeName = "Circle";
1800 aTypeName = "Vertex";
1803 aTypeName = "Shape";
1806 aTypeName = "Shape of unknown type";
1812 //=============================================================================
1816 //=============================================================================
1817 Standard_Integer GEOMImpl_IShapesOperations::NumberOfSubShapes
1818 (Handle(GEOM_Object) theShape,
1819 const Standard_Integer theShapeType)
1822 Standard_Integer nbShapes = 0;
1824 if (theShape.IsNull()) return -1;
1825 TopoDS_Shape aShape = theShape->GetValue();
1826 if (aShape.IsNull()) return -1;
1829 TopTools_MapOfShape mapShape;
1831 if (aShape.ShapeType() == TopAbs_COMPOUND &&
1832 (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
1833 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPSOLID ||
1834 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPOUND)) {
1835 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
1836 for (; It.More(); It.Next()) {
1837 if (mapShape.Add(It.Value())) {
1838 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
1839 TopAbs_ShapeEnum(theShapeType) == It.Value().ShapeType()) {
1845 TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
1846 for (; exp.More(); exp.Next())
1847 if (mapShape.Add(exp.Current()))
1854 int iType, nbTypes [TopAbs_SHAPE];
1855 for (iType = 0; iType < TopAbs_SHAPE; ++iType)
1857 nbTypes[aShape.ShapeType()]++;
1859 TopTools_MapOfShape aMapOfShape;
1860 aMapOfShape.Add(aShape);
1861 TopTools_ListOfShape aListOfShape;
1862 aListOfShape.Append(aShape);
1864 TopTools_ListIteratorOfListOfShape itL (aListOfShape);
1865 for (; itL.More(); itL.Next()) {
1866 TopoDS_Iterator it (itL.Value());
1867 for (; it.More(); it.Next()) {
1868 TopoDS_Shape s = it.Value();
1869 if (aMapOfShape.Add(s)) {
1870 aListOfShape.Append(s);
1871 nbTypes[s.ShapeType()]++;
1876 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE)
1877 nbShapes = aMapOfShape.Extent();
1879 nbShapes = nbTypes[theShapeType];
1881 catch (Standard_Failure) {
1882 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1883 SetErrorCode(aFail->GetMessageString());
1891 //=============================================================================
1895 //=============================================================================
1896 Handle(GEOM_Object) GEOMImpl_IShapesOperations::ReverseShape(Handle(GEOM_Object) theShape)
1900 if (theShape.IsNull()) return NULL;
1903 //Add a new reversed object
1904 Handle(GEOM_Object) aReversed = GetEngine()->AddObject(GetDocID(), theShape->GetType());
1906 //Add a new Revese function
1907 Handle(GEOM_Function) aFunction;
1908 aFunction = aReversed->AddFunction(GEOMImpl_ShapeDriver::GetID(), REVERSE_ORIENTATION);
1909 if (aFunction.IsNull()) return NULL;
1911 //Check if the function is set correctly
1912 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
1914 GEOMImpl_IShapes aSI (aFunction);
1916 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
1917 if (aRefShape.IsNull()) return NULL;
1919 aSI.SetBase(aRefShape);
1921 //Compute the sub-shape value
1924 if (!GetSolver()->ComputeFunction(aFunction)) {
1925 SetErrorCode("Shape driver failed to reverse shape");
1929 catch (Standard_Failure) {
1930 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1931 SetErrorCode(aFail->GetMessageString());
1935 //Make a Python command
1936 GEOM::TPythonDump(aFunction) << aReversed
1937 << " = geompy.ChangeOrientation(" << theShape << ")";
1942 Handle(GEOM_Object) aReversed;
1944 GEOM_Engine* anEngine = GetEngine();
1945 //GEOMImpl_Gen* aGen = dynamic_cast<GEOMImpl_Gen*>(anEngine);
1946 GEOMImpl_Gen* aGen = (GEOMImpl_Gen*)anEngine;
1949 GEOMImpl_IHealingOperations* anIHealingOperations =
1950 aGen->GetIHealingOperations(GetDocID());
1951 aReversed = anIHealingOperations->ChangeOrientationCopy(theShape);
1952 SetErrorCode(anIHealingOperations->GetErrorCode());
1958 //=============================================================================
1962 //=============================================================================
1963 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetFreeFacesIDs
1964 (Handle(GEOM_Object) theShape)
1968 if (theShape.IsNull()) return NULL;
1969 TopoDS_Shape aShape = theShape->GetValue();
1970 if (aShape.IsNull()) return NULL;
1972 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
1974 TopTools_IndexedDataMapOfShapeListOfShape mapFaceBlocks;
1975 GEOMImpl_Block6Explorer::MapShapesAndAncestors
1976 (aShape, TopAbs_FACE, TopAbs_SOLID, mapFaceBlocks);
1978 Standard_Integer ind = 1, nbFaces = mapFaceBlocks.Extent();
1981 SetErrorCode("The given shape has no faces");
1985 TopTools_IndexedMapOfShape anIndices;
1986 TopExp::MapShapes(aShape, anIndices);
1988 Standard_Integer id;
1989 for (; ind <= nbFaces; ind++) {
1990 if (mapFaceBlocks.FindFromIndex(ind).Extent() != 2) {
1991 id = anIndices.FindIndex(mapFaceBlocks.FindKey(ind));
1996 //The explode doesn't change object so no new function is required.
1997 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
1999 //Make a Python command
2000 GEOM::TPythonDump(aFunction, /*append=*/true)
2001 << "listFreeFacesIDs = geompy.GetFreeFacesIDs(" << theShape << ")";
2007 //=======================================================================
2008 //function : GetSharedShapes
2010 //=======================================================================
2011 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetSharedShapes
2012 (Handle(GEOM_Object) theShape1,
2013 Handle(GEOM_Object) theShape2,
2014 const Standard_Integer theShapeType)
2018 if (theShape1.IsNull() || theShape2.IsNull()) return NULL;
2020 TopoDS_Shape aShape1 = theShape1->GetValue();
2021 TopoDS_Shape aShape2 = theShape2->GetValue();
2023 if (aShape1.IsNull() || aShape2.IsNull()) return NULL;
2025 TopTools_IndexedMapOfShape anIndices;
2026 TopExp::MapShapes(aShape1, anIndices);
2027 Handle(TColStd_HArray1OfInteger) anArray;
2029 TopTools_IndexedMapOfShape mapShape1;
2030 TopExp::MapShapes(aShape1, TopAbs_ShapeEnum(theShapeType), mapShape1);
2032 Handle(GEOM_Object) anObj;
2033 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
2034 TCollection_AsciiString anAsciiList, anEntry;
2036 TopTools_MapOfShape mapShape2;
2037 TopExp_Explorer exp (aShape2, TopAbs_ShapeEnum(theShapeType));
2038 for (; exp.More(); exp.Next()) {
2039 TopoDS_Shape aSS = exp.Current();
2040 if (mapShape2.Add(aSS) && mapShape1.Contains(aSS)) {
2041 anArray = new TColStd_HArray1OfInteger(1,1);
2042 anArray->SetValue(1, anIndices.FindIndex(aSS));
2043 anObj = GetEngine()->AddSubShape(theShape1, anArray);
2044 aSeq->Append(anObj);
2046 // for python command
2047 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
2048 anAsciiList += anEntry;
2053 if (aSeq->IsEmpty()) {
2054 SetErrorCode("The given shapes have no shared sub-shapes of the requested type");
2058 //Make a Python command
2059 anAsciiList.Trunc(anAsciiList.Length() - 1);
2061 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2063 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
2064 << "] = geompy.GetSharedShapes(" << theShape1 << ", "
2065 << theShape2 << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
2071 //=======================================================================
2072 //function : GetSharedShapes
2074 //=======================================================================
2075 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetSharedShapes
2076 (std::list<Handle(GEOM_Object)> & theShapes,
2077 const Standard_Integer theShapeType)
2081 int aLen = theShapes.size();
2082 if (aLen < 1) return NULL;
2085 std::list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
2087 Handle(GEOM_Object) aMainObj = *it;
2088 Handle(GEOM_Function) aMainShape = aMainObj->GetLastFunction();
2090 TopTools_SequenceOfShape shapeSeq;
2091 for (; it != theShapes.end(); it++, ind++) {
2092 Handle(GEOM_Function) aRefShape = (*it)->GetLastFunction();
2093 if (aRefShape.IsNull()) {
2094 SetErrorCode("NULL shape for GetSharedShapes");
2097 TopoDS_Shape aShape2 = aRefShape->GetValue();
2098 if (aShape2.IsNull()) return NULL;
2099 shapeSeq.Append( aShape2 );
2102 TopoDS_Shape aShape1 = shapeSeq.First();
2104 if ( shapeSeq.Length() == 1 )
2107 for ( TopoDS_Iterator it( aShape1); it.More(); it.Next() )
2108 shapeSeq.Append( it.Value() );
2109 aShape1 = shapeSeq.First();
2112 TopTools_IndexedMapOfShape anIndices;
2113 TopExp::MapShapes(aMainShape->GetValue(), anIndices);
2115 TopTools_IndexedMapOfShape mapSelected;
2116 TopExp::MapShapes(aShape1, TopAbs_ShapeEnum(theShapeType), mapSelected);
2118 // Find shared shapes
2120 TopoDS_Compound aCurrSelection;
2122 for ( ind = 2; ind <= shapeSeq.Length(); ind++) {
2124 TopoDS_Compound aCompound;
2125 B.MakeCompound(aCompound);
2127 const TopoDS_Shape& aShape2 = shapeSeq.Value( ind );
2129 TopTools_MapOfShape mapShape2;
2130 TopExp_Explorer exp (aShape2, TopAbs_ShapeEnum(theShapeType));
2131 for (; exp.More(); exp.Next()) {
2132 const TopoDS_Shape& aSS = exp.Current();
2133 if (mapShape2.Add(aSS) && mapSelected.Contains(aSS)) {
2134 B.Add(aCompound, aSS);
2138 mapSelected.Clear();
2139 TopExp::MapShapes(aCompound, TopAbs_ShapeEnum(theShapeType), mapSelected);
2140 aCurrSelection = aCompound;
2143 // Create GEOM_Object for each found shared shape (collected in aCurrSelection)
2144 Handle(GEOM_Object) anObj, aLastCreated;
2145 Handle(TColStd_HArray1OfInteger) anArray;
2146 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
2147 TCollection_AsciiString anAsciiList, anEntry;
2149 TopoDS_Iterator itSel (aCurrSelection, Standard_True, Standard_True);
2150 for (; itSel.More(); itSel.Next()) {
2151 anArray = new TColStd_HArray1OfInteger(1,1);
2152 anArray->SetValue(1, anIndices.FindIndex(itSel.Value()));
2153 anObj = GetEngine()->AddSubShape(aMainObj, anArray);
2154 aSeq->Append(anObj);
2156 aLastCreated = GEOM::GetCreatedLast( aLastCreated, anObj );
2158 // for python command
2159 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
2160 anAsciiList += anEntry;
2164 if (aSeq->IsEmpty()) {
2165 SetErrorCode("The given shapes have no shared sub-shapes of the requested type");
2169 // Make a Python command
2170 anAsciiList.Trunc(anAsciiList.Length() - 1);
2172 // IPAL22904: TC6.5.0: order of python commands is wrong after dump study
2173 // Get the function of the latest published object
2174 Handle(GEOM_Function) aFunction = aLastCreated->GetLastFunction();
2175 if( aFunction.IsNull() ) // just in case
2176 aFunction = aMainShape;
2178 GEOM::TPythonDump pd (aFunction, /*append=*/true);
2179 pd << "[" << anAsciiList.ToCString()
2180 << "] = geompy.GetSharedShapesMulti([";
2182 it = theShapes.begin();
2184 while (it != theShapes.end()) {
2185 pd << ", " << (*it++);
2188 pd << "], " << TopAbs_ShapeEnum(theShapeType) << ")";
2194 //=============================================================================
2198 //=============================================================================
2199 static GEOM::TPythonDump& operator<< (GEOM::TPythonDump& theDump,
2200 const GEOMAlgo_State theState)
2203 case GEOMAlgo_ST_IN:
2204 theDump << "GEOM.ST_IN";
2206 case GEOMAlgo_ST_OUT:
2207 theDump << "GEOM.ST_OUT";
2209 case GEOMAlgo_ST_ON:
2210 theDump << "GEOM.ST_ON";
2212 case GEOMAlgo_ST_ONIN:
2213 theDump << "GEOM.ST_ONIN";
2215 case GEOMAlgo_ST_ONOUT:
2216 theDump << "GEOM.ST_ONOUT";
2219 theDump << "GEOM.ST_UNKNOWN";
2225 //=======================================================================
2226 //function : checkTypeShapesOn
2228 * \brief Checks if theShapeType parameter of GetShapesOnXXX() is OK
2229 * \param theShapeType - the shape type to check
2230 * \retval bool - result of the check
2232 //=======================================================================
2233 bool GEOMImpl_IShapesOperations::checkTypeShapesOn(const Standard_Integer theShapeType)
2235 if (theShapeType != TopAbs_VERTEX &&
2236 theShapeType != TopAbs_EDGE &&
2237 theShapeType != TopAbs_FACE &&
2238 theShapeType != TopAbs_SOLID) {
2239 SetErrorCode("Only solids, vertices, edges or faces can be found by this method");
2245 //=======================================================================
2246 //function : makePlane
2248 * \brief Creates Geom_Plane
2249 * \param theAx1 - shape object defining plane parameters
2250 * \retval Handle(Geom_Surface) - resulting surface
2252 //=======================================================================
2253 Handle(Geom_Surface) GEOMImpl_IShapesOperations::makePlane(const TopoDS_Shape& anAx1)
2255 if (anAx1.ShapeType() != TopAbs_EDGE) return NULL;
2256 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
2257 TopoDS_Vertex V1, V2;
2258 TopExp::Vertices(anEdge, V1, V2, Standard_True);
2259 if (V1.IsNull() || V2.IsNull()) {
2260 SetErrorCode("Bad edge given for the plane normal vector");
2263 gp_Pnt aLoc = BRep_Tool::Pnt(V1);
2264 gp_Vec aVec (aLoc, BRep_Tool::Pnt(V2));
2265 if (aVec.Magnitude() < Precision::Confusion()) {
2266 SetErrorCode("Vector with null magnitude given");
2269 return new Geom_Plane(aLoc, aVec);
2272 //=======================================================================
2273 //function : makeCylinder
2275 * \brief Creates Geom_CylindricalSurface
2276 * \param theAx1 - edge defining cylinder axis
2277 * \param theRadius - cylinder radius
2278 * \retval Handle(Geom_Surface) - resulting surface
2280 //=======================================================================
2281 Handle(Geom_Surface) GEOMImpl_IShapesOperations::makeCylinder(const TopoDS_Shape& anAxis,
2282 const Standard_Real theRadius)
2284 //Axis of the cylinder
2285 if (anAxis.ShapeType() != TopAbs_EDGE) {
2286 SetErrorCode("Not an edge given for the axis");
2289 TopoDS_Edge anEdge = TopoDS::Edge(anAxis);
2290 TopoDS_Vertex V1, V2;
2291 TopExp::Vertices(anEdge, V1, V2, Standard_True);
2292 if (V1.IsNull() || V2.IsNull()) {
2293 SetErrorCode("Bad edge given for the axis");
2296 gp_Pnt aLoc = BRep_Tool::Pnt(V1);
2297 gp_Vec aVec (aLoc, BRep_Tool::Pnt(V2));
2298 if (aVec.Magnitude() < Precision::Confusion()) {
2299 SetErrorCode("Vector with null magnitude given");
2303 gp_Ax3 anAx3 (aLoc, aVec);
2304 return new Geom_CylindricalSurface(anAx3, theRadius);
2307 //=======================================================================
2308 //function : getShapesOnBoxIDs
2310 * \brief Find IDs of sub-shapes complying with given status about surface
2311 * \param theBox - the box to check state of sub-shapes against
2312 * \param theShape - the shape to explore
2313 * \param theShapeType - type of sub-shape of theShape
2314 * \param theState - required state
2315 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
2317 //=======================================================================
2318 Handle(TColStd_HSequenceOfInteger)
2319 GEOMImpl_IShapesOperations::getShapesOnBoxIDs(const Handle(GEOM_Object)& theBox,
2320 const Handle(GEOM_Object)& theShape,
2321 const Standard_Integer theShapeType,
2322 GEOMAlgo_State theState)
2324 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
2326 TopoDS_Shape aBox = theBox->GetValue();
2327 TopoDS_Shape aShape = theShape->GetValue();
2329 // Check presence of triangulation, build if need
2330 if (!GEOMUtils::CheckTriangulation(aShape)) {
2331 SetErrorCode("Cannot build triangulation on the shape");
2336 GEOMAlgo_FinderShapeOn2 aFinder;
2337 Standard_Real aTol = 0.0001; // default value
2339 Handle(GEOMAlgo_ClsfBox) aClsfBox = new GEOMAlgo_ClsfBox;
2340 aClsfBox->SetBox(aBox);
2342 aFinder.SetShape(aShape);
2343 aFinder.SetTolerance(aTol);
2344 aFinder.SetClsf(aClsfBox);
2345 aFinder.SetShapeType( (TopAbs_ShapeEnum)theShapeType );
2346 aFinder.SetState(theState);
2349 // Interprete results
2350 Standard_Integer iErr = aFinder.ErrorStatus();
2351 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
2353 MESSAGE(" iErr : " << iErr);
2354 TCollection_AsciiString aMsg (" iErr : ");
2355 aMsg += TCollection_AsciiString(iErr);
2359 Standard_Integer iWrn = aFinder.WarningStatus();
2360 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
2362 MESSAGE(" *** iWrn : " << iWrn);
2365 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
2367 if (listSS.Extent() < 1) {
2368 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
2369 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
2373 // Fill sequence of object IDs
2374 aSeqOfIDs = new TColStd_HSequenceOfInteger;
2376 TopTools_IndexedMapOfShape anIndices;
2377 TopExp::MapShapes(aShape, anIndices);
2379 TopTools_ListIteratorOfListOfShape itSub (listSS);
2380 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
2381 int id = anIndices.FindIndex(itSub.Value());
2382 aSeqOfIDs->Append(id);
2388 //=======================================================================
2389 //function : GetShapesOnBoxIDs
2391 * \brief Find sub-shapes complying with given status about surface
2392 * \param theBox - the box to check state of sub-shapes against
2393 * \param theShape - the shape to explore
2394 * \param theShapeType - type of sub-shape of theShape
2395 * \param theState - required state
2396 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
2398 //=======================================================================
2399 Handle(TColStd_HSequenceOfInteger)
2400 GEOMImpl_IShapesOperations::GetShapesOnBoxIDs(const Handle(GEOM_Object)& theBox,
2401 const Handle(GEOM_Object)& theShape,
2402 const Standard_Integer theShapeType,
2403 GEOMAlgo_State theState)
2405 // Find sub-shapes ids
2406 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2407 getShapesOnBoxIDs (theBox, theShape, theShapeType, theState);
2408 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2411 // The GetShapesOnBox() doesn't change object so no new function is required.
2412 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theBox)->GetLastFunction();
2414 // Make a Python command
2415 GEOM::TPythonDump(aFunction, /*append=*/true)
2416 << "listShapesOnBoxIDs = geompy.GetShapesOnBoxIDs("
2419 << TopAbs_ShapeEnum(theShapeType) << ", "
2426 //=======================================================================
2427 //function : GetShapesOnBox
2429 * \brief Find sub-shapes complying with given status about surface
2430 * \param theBox - the box to check state of sub-shapes against
2431 * \param theShape - the shape to explore
2432 * \param theShapeType - type of sub-shape of theShape
2433 * \param theState - required state
2434 * \retval Handle(TColStd_HSequenceOfTransient) - found sub-shapes
2436 //=======================================================================
2437 Handle(TColStd_HSequenceOfTransient)
2438 GEOMImpl_IShapesOperations::GetShapesOnBox(const Handle(GEOM_Object)& theBox,
2439 const Handle(GEOM_Object)& theShape,
2440 const Standard_Integer theShapeType,
2441 GEOMAlgo_State theState)
2443 // Find sub-shapes ids
2444 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2445 getShapesOnBoxIDs (theBox, theShape, theShapeType, theState);
2446 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2449 // Find objects by indices
2450 TCollection_AsciiString anAsciiList;
2451 Handle(TColStd_HSequenceOfTransient) aSeq;
2452 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
2453 if ( aSeq.IsNull() || aSeq->IsEmpty() )
2456 // Make a Python command
2458 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2459 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2461 GEOM::TPythonDump(aFunction)
2462 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnBox("
2465 << TopAbs_ShapeEnum(theShapeType) << ", "
2472 //=======================================================================
2473 //function : getShapesOnShapeIDs
2475 * \brief Find IDs of sub-shapes complying with given status about surface
2476 * \param theCheckShape - the shape to check state of sub-shapes against
2477 * \param theShape - the shape to explore
2478 * \param theShapeType - type of sub-shape of theShape
2479 * \param theState - required state
2480 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
2482 //=======================================================================
2483 Handle(TColStd_HSequenceOfInteger)
2484 GEOMImpl_IShapesOperations::getShapesOnShapeIDs
2485 (const Handle(GEOM_Object)& theCheckShape,
2486 const Handle(GEOM_Object)& theShape,
2487 const Standard_Integer theShapeType,
2488 GEOMAlgo_State theState)
2490 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
2492 TopoDS_Shape aCheckShape = theCheckShape->GetValue();
2493 TopoDS_Shape aShape = theShape->GetValue();
2494 TopTools_ListOfShape res;
2496 // Check presence of triangulation, build if need
2497 if (!GEOMUtils::CheckTriangulation(aShape)) {
2498 SetErrorCode("Cannot build triangulation on the shape");
2503 GEOMAlgo_FinderShapeOn2 aFinder;
2504 Standard_Real aTol = 0.0001; // default value
2506 Handle(GEOMAlgo_ClsfSolid) aClsfSolid = new GEOMAlgo_ClsfSolid;
2507 aClsfSolid->SetShape(aCheckShape);
2509 aFinder.SetShape(aShape);
2510 aFinder.SetTolerance(aTol);
2511 aFinder.SetClsf(aClsfSolid);
2512 aFinder.SetShapeType( (TopAbs_ShapeEnum)theShapeType );
2513 aFinder.SetState(theState);
2516 // Interprete results
2517 Standard_Integer iErr = aFinder.ErrorStatus();
2518 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
2521 SetErrorCode("theCheckShape must be a solid");
2524 MESSAGE(" iErr : " << iErr);
2525 TCollection_AsciiString aMsg (" iErr : ");
2526 aMsg += TCollection_AsciiString(iErr);
2531 Standard_Integer iWrn = aFinder.WarningStatus();
2532 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
2534 MESSAGE(" *** iWrn : " << iWrn);
2537 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
2539 if (listSS.Extent() < 1) {
2540 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
2541 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
2544 // Fill sequence of object IDs
2545 aSeqOfIDs = new TColStd_HSequenceOfInteger;
2547 TopTools_IndexedMapOfShape anIndices;
2548 TopExp::MapShapes(aShape, anIndices);
2550 TopTools_ListIteratorOfListOfShape itSub (listSS);
2551 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
2552 int id = anIndices.FindIndex(itSub.Value());
2553 aSeqOfIDs->Append(id);
2559 //=======================================================================
2560 //function : GetShapesOnShapeIDs
2562 * \brief Find sub-shapes complying with given status about surface
2563 * \param theCheckShape - the shape to check state of sub-shapes against
2564 * \param theShape - the shape to explore
2565 * \param theShapeType - type of sub-shape of theShape
2566 * \param theState - required state
2567 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
2569 //=======================================================================
2570 Handle(TColStd_HSequenceOfInteger)
2571 GEOMImpl_IShapesOperations::GetShapesOnShapeIDs
2572 (const Handle(GEOM_Object)& theCheckShape,
2573 const Handle(GEOM_Object)& theShape,
2574 const Standard_Integer theShapeType,
2575 GEOMAlgo_State theState)
2577 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2578 getShapesOnShapeIDs (theCheckShape, theShape, theShapeType, theState);
2580 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2583 // The GetShapesOnShape() doesn't change object so no new function is required.
2584 Handle(GEOM_Function) aFunction =
2585 GEOM::GetCreatedLast(theShape,theCheckShape)->GetLastFunction();
2587 // Make a Python command
2588 GEOM::TPythonDump(aFunction, /*append=*/true)
2589 << "listShapesOnBoxIDs = geompy.GetShapesOnShapeIDs("
2590 << theCheckShape << ", "
2592 << TopAbs_ShapeEnum(theShapeType) << ", "
2599 //=======================================================================
2600 //function : GetShapesOnShape
2602 * \brief Find sub-shapes complying with given status about surface
2603 * \param theCheckShape - the shape to check state of sub-shapes against
2604 * \param theShape - the shape to explore
2605 * \param theShapeType - type of sub-shape of theShape
2606 * \param theState - required state
2607 * \retval Handle(TColStd_HSequenceOfTransient) - found sub-shapes
2609 //=======================================================================
2610 Handle(TColStd_HSequenceOfTransient)
2611 GEOMImpl_IShapesOperations::GetShapesOnShape
2612 (const Handle(GEOM_Object)& theCheckShape,
2613 const Handle(GEOM_Object)& theShape,
2614 const Standard_Integer theShapeType,
2615 GEOMAlgo_State theState)
2617 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2618 getShapesOnShapeIDs (theCheckShape, theShape, theShapeType, theState);
2619 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2622 // Find objects by indices
2623 TCollection_AsciiString anAsciiList;
2624 Handle(TColStd_HSequenceOfTransient) aSeq;
2625 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
2627 if ( aSeq.IsNull() || aSeq->IsEmpty() )
2630 // Make a Python command
2632 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2633 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2635 GEOM::TPythonDump(aFunction)
2636 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnShape("
2637 << theCheckShape << ", "
2639 << TopAbs_ShapeEnum(theShapeType) << ", "
2646 //=======================================================================
2647 //function : GetShapesOnShapeAsCompound
2648 //=======================================================================
2649 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetShapesOnShapeAsCompound
2650 (const Handle(GEOM_Object)& theCheckShape,
2651 const Handle(GEOM_Object)& theShape,
2652 const Standard_Integer theShapeType,
2653 GEOMAlgo_State theState)
2655 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2656 getShapesOnShapeIDs (theCheckShape, theShape, theShapeType, theState);
2658 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2661 // Find objects by indices
2662 TCollection_AsciiString anAsciiList;
2663 Handle(TColStd_HSequenceOfTransient) aSeq;
2664 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
2666 if ( aSeq.IsNull() || aSeq->IsEmpty() )
2669 TopoDS_Compound aCompound;
2671 B.MakeCompound(aCompound);
2673 for(; i<=aSeq->Length(); i++) {
2674 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(aSeq->Value(i));
2675 TopoDS_Shape aShape_i = anObj->GetValue();
2676 B.Add(aCompound,aShape_i);
2679 //Add a new result object
2680 Handle(GEOM_Object) aRes = GetEngine()->AddObject(GetDocID(), GEOM_SHAPES_ON_SHAPE);
2681 Handle(GEOM_Function) aFunction =
2682 aRes->AddFunction(GEOMImpl_ShapeDriver::GetID(), SHAPES_ON_SHAPE);
2683 aFunction->SetValue(aCompound);
2686 aSeq->Append( theCheckShape->GetLastFunction() );
2687 aSeq->Append( theShape->GetLastFunction() );
2689 GEOMImpl_IShapes aCI( aFunction );
2690 aCI.SetShapes( aSeq );
2691 aCI.SetSubShapeType( theShapeType );
2692 aCI.SetTolerance( theState );
2694 GEOM::TPythonDump(aFunction)
2695 << aRes << " = geompy.GetShapesOnShapeAsCompound("
2696 << theCheckShape << ", "
2698 << TopAbs_ShapeEnum(theShapeType) << ", "
2706 //=======================================================================
2707 //function : getShapesOnSurfaceIDs
2709 * \brief Find IDs of sub-shapes complying with given status about surface
2710 * \param theSurface - the surface to check state of sub-shapes against
2711 * \param theShape - the shape to explore
2712 * \param theShapeType - type of sub-shape of theShape
2713 * \param theState - required state
2714 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
2716 //=======================================================================
2717 Handle(TColStd_HSequenceOfInteger)
2718 GEOMImpl_IShapesOperations::getShapesOnSurfaceIDs(const Handle(Geom_Surface)& theSurface,
2719 const TopoDS_Shape& theShape,
2720 TopAbs_ShapeEnum theShapeType,
2721 GEOMAlgo_State theState)
2723 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
2725 // Check presence of triangulation, build if need
2726 if (!GEOMUtils::CheckTriangulation(theShape)) {
2727 SetErrorCode("Cannot build triangulation on the shape");
2731 // BEGIN: Mantis issue 0020961: Error on a pipe T-Shape
2732 // Compute tolerance
2733 Standard_Real T, VertMax = -RealLast();
2736 for (TopExp_Explorer ExV (theShape, TopAbs_VERTEX); ExV.More(); ExV.Next()) {
2737 TopoDS_Vertex Vertex = TopoDS::Vertex(ExV.Current());
2738 T = BRep_Tool::Tolerance(Vertex);
2743 catch (Standard_Failure) {
2744 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2745 SetErrorCode(aFail->GetMessageString());
2748 // END: Mantis issue 0020961
2751 GEOMAlgo_FinderShapeOn1 aFinder;
2752 //Standard_Real aTol = 0.0001; // default value
2753 Standard_Real aTol = VertMax; // Mantis issue 0020961
2755 aFinder.SetShape(theShape);
2756 aFinder.SetTolerance(aTol);
2757 aFinder.SetSurface(theSurface);
2758 aFinder.SetShapeType(theShapeType);
2759 aFinder.SetState(theState);
2761 // Sets the minimal number of inner points for the faces that do not have own
2762 // inner points at all (for e.g. rectangular planar faces have just 2 triangles).
2764 aFinder.SetNbPntsMin(3);
2765 // Sets the maximal number of inner points for edges or faces.
2766 // It is usefull for the cases when this number is very big (e.g =2000) to improve
2767 // the performance. If this value =0, all inner points will be taken into account.
2769 aFinder.SetNbPntsMax(100);
2773 // Interprete results
2774 Standard_Integer iErr = aFinder.ErrorStatus();
2775 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
2777 MESSAGE(" iErr : " << iErr);
2778 TCollection_AsciiString aMsg (" iErr : ");
2779 aMsg += TCollection_AsciiString(iErr);
2783 Standard_Integer iWrn = aFinder.WarningStatus();
2784 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
2786 MESSAGE(" *** iWrn : " << iWrn);
2789 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
2791 if (listSS.Extent() < 1) {
2792 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
2793 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
2797 // Fill sequence of object IDs
2798 aSeqOfIDs = new TColStd_HSequenceOfInteger;
2800 TopTools_IndexedMapOfShape anIndices;
2801 TopExp::MapShapes(theShape, anIndices);
2803 TopTools_ListIteratorOfListOfShape itSub (listSS);
2804 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
2805 int id = anIndices.FindIndex(itSub.Value());
2806 aSeqOfIDs->Append(id);
2812 //=======================================================================
2813 //function : getObjectsShapesOn
2815 * \brief Find shape objects and their entries by their ids
2816 * \param theShapeIDs - incoming shape ids
2817 * \param theShapeEntries - outgoing entries like "entry1, entry2, ..."
2818 * \retval Handle(TColStd_HSequenceOfTransient) - found shape objects
2820 //=======================================================================
2821 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::
2822 getObjectsShapesOn(const Handle(GEOM_Object)& theShape,
2823 const Handle(TColStd_HSequenceOfInteger)& theShapeIDs,
2824 TCollection_AsciiString & theShapeEntries)
2826 Handle(TColStd_HSequenceOfTransient) aSeq;
2828 if ( !theShapeIDs.IsNull() && theShapeIDs->Length() > 0 )
2830 aSeq = new TColStd_HSequenceOfTransient;
2831 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
2832 TCollection_AsciiString anEntry;
2833 for ( int i = 1; i <= theShapeIDs->Length(); ++i )
2835 anArray->SetValue(1, theShapeIDs->Value( i ));
2836 Handle(GEOM_Object) anObj = GetEngine()->AddSubShape(theShape, anArray);
2837 aSeq->Append( anObj );
2839 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
2840 if ( i != 1 ) theShapeEntries += ",";
2841 theShapeEntries += anEntry;
2847 //=======================================================================
2848 //function : getShapesOnSurface
2850 * \brief Find sub-shapes complying with given status about surface
2851 * \param theSurface - the surface to check state of sub-shapes against
2852 * \param theShape - the shape to explore
2853 * \param theShapeType - type of sub-shape of theShape
2854 * \param theState - required state
2855 * \param theShapeEntries - outgoing entries like "entry1, entry2, ..."
2856 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
2858 //=======================================================================
2859 Handle(TColStd_HSequenceOfTransient)
2860 GEOMImpl_IShapesOperations::getShapesOnSurface(const Handle(Geom_Surface)& theSurface,
2861 const Handle(GEOM_Object)& theShape,
2862 TopAbs_ShapeEnum theShapeType,
2863 GEOMAlgo_State theState,
2864 TCollection_AsciiString & theShapeEntries)
2866 // Find sub-shapes ids
2867 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2868 getShapesOnSurfaceIDs (theSurface, theShape->GetValue(), theShapeType, theState);
2869 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2872 return getObjectsShapesOn( theShape, aSeqOfIDs, theShapeEntries );
2875 //=============================================================================
2879 //=============================================================================
2880 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnPlane
2881 (const Handle(GEOM_Object)& theShape,
2882 const Standard_Integer theShapeType,
2883 const Handle(GEOM_Object)& theAx1,
2884 const GEOMAlgo_State theState)
2888 if (theShape.IsNull() || theAx1.IsNull()) return NULL;
2890 TopoDS_Shape aShape = theShape->GetValue();
2891 TopoDS_Shape anAx1 = theAx1->GetValue();
2893 if (aShape.IsNull() || anAx1.IsNull()) return NULL;
2895 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2896 if ( !checkTypeShapesOn( theShapeType ))
2900 Handle(Geom_Surface) aPlane = makePlane( anAx1 );
2901 if ( aPlane.IsNull() )
2905 TCollection_AsciiString anAsciiList;
2906 Handle(TColStd_HSequenceOfTransient) aSeq;
2907 aSeq = getShapesOnSurface( aPlane, theShape, aShapeType, theState, anAsciiList );
2908 if ( aSeq.IsNull() || aSeq->Length() == 0 )
2911 // Make a Python command
2913 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2914 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2916 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
2917 << "] = geompy.GetShapesOnPlane(" << theShape << ", "
2918 << aShapeType << ", " << theAx1 << ", " << theState << ")";
2924 //=============================================================================
2926 * GetShapesOnPlaneWithLocation
2928 //=============================================================================
2929 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnPlaneWithLocation
2930 (const Handle(GEOM_Object)& theShape,
2931 const Standard_Integer theShapeType,
2932 const Handle(GEOM_Object)& theAx1,
2933 const Handle(GEOM_Object)& thePnt,
2934 const GEOMAlgo_State theState)
2938 if (theShape.IsNull() || theAx1.IsNull() || thePnt.IsNull()) return NULL;
2940 TopoDS_Shape aShape = theShape->GetValue();
2941 TopoDS_Shape anAx1 = theAx1->GetValue();
2942 TopoDS_Shape anPnt = thePnt->GetValue();
2944 if (aShape.IsNull() || anAx1.IsNull() || anPnt.IsNull()) return NULL;
2946 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2947 if ( !checkTypeShapesOn( theShapeType ))
2951 if ( anAx1.ShapeType() != TopAbs_EDGE || anPnt.ShapeType() != TopAbs_VERTEX ) return NULL;
2952 TopoDS_Vertex V1, V2, V3;
2953 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
2954 TopExp::Vertices(anEdge, V1, V2, Standard_True);
2956 if (V1.IsNull() || V2.IsNull()) {
2957 SetErrorCode("Bad edge given for the plane normal vector");
2960 V3 = TopoDS::Vertex(anPnt);
2963 SetErrorCode("Bad vertex given for the plane location");
2966 gp_Pnt aLoc = BRep_Tool::Pnt(V3);
2967 gp_Vec aVec(BRep_Tool::Pnt(V1),BRep_Tool::Pnt(V2));
2969 if (aVec.Magnitude() < Precision::Confusion()) {
2970 SetErrorCode("Vector with null magnitude given");
2973 Handle(Geom_Surface) aPlane = new Geom_Plane(aLoc, aVec);
2975 if ( aPlane.IsNull() )
2979 TCollection_AsciiString anAsciiList;
2980 Handle(TColStd_HSequenceOfTransient) aSeq;
2981 aSeq = getShapesOnSurface( aPlane, theShape, aShapeType, theState, anAsciiList );
2982 if ( aSeq.IsNull() || aSeq->Length() == 0 )
2985 // Make a Python command
2987 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2988 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2990 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
2991 << "] = geompy.GetShapesOnPlaneWithLocation(" << theShape << ", "
2992 << aShapeType << ", " << theAx1 << ", "<< thePnt <<", " << theState << ")";
2998 //=============================================================================
3000 * GetShapesOnCylinder
3002 //=============================================================================
3003 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnCylinder
3004 (const Handle(GEOM_Object)& theShape,
3005 const Standard_Integer theShapeType,
3006 const Handle(GEOM_Object)& theAxis,
3007 const Standard_Real theRadius,
3008 const GEOMAlgo_State theState)
3012 if (theShape.IsNull() || theAxis.IsNull()) return NULL;
3014 TopoDS_Shape aShape = theShape->GetValue();
3015 TopoDS_Shape anAxis = theAxis->GetValue();
3017 if (aShape.IsNull() || anAxis.IsNull()) return NULL;
3019 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3020 if ( !checkTypeShapesOn( aShapeType ))
3023 // Create a cylinder surface
3024 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
3025 if ( aCylinder.IsNull() )
3029 TCollection_AsciiString anAsciiList;
3030 Handle(TColStd_HSequenceOfTransient) aSeq;
3031 aSeq = getShapesOnSurface( aCylinder, theShape, aShapeType, theState, anAsciiList );
3032 if ( aSeq.IsNull() || aSeq->Length() == 0 )
3035 // Make a Python command
3037 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
3038 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
3040 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
3041 << "] = geompy.GetShapesOnCylinder(" << theShape << ", " << aShapeType
3042 << ", " << theAxis << ", " << theRadius << ", " << theState << ")";
3048 //=============================================================================
3050 * GetShapesOnCylinderWithLocation
3052 //=============================================================================
3053 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnCylinderWithLocation
3054 (const Handle(GEOM_Object)& theShape,
3055 const Standard_Integer theShapeType,
3056 const Handle(GEOM_Object)& theAxis,
3057 const Handle(GEOM_Object)& thePnt,
3058 const Standard_Real theRadius,
3059 const GEOMAlgo_State theState)
3063 if (theShape.IsNull() || theAxis.IsNull() || thePnt.IsNull()) return NULL;
3065 TopoDS_Shape aShape = theShape->GetValue();
3066 TopoDS_Shape anAxis = theAxis->GetValue();
3067 TopoDS_Shape aPnt = thePnt->GetValue();
3069 if (aShape.IsNull() || anAxis.IsNull() || aPnt.IsNull()) return NULL;
3071 if (aPnt.ShapeType() != TopAbs_VERTEX )
3073 SetErrorCode("Bottom location point must be vertex");
3077 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3078 if ( !checkTypeShapesOn( aShapeType ))
3081 // Create a cylinder surface
3082 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
3083 if ( aCylinder.IsNull() )
3086 // translate the surface
3087 Handle(Geom_CylindricalSurface) aCylSurface =
3088 Handle(Geom_CylindricalSurface)::DownCast( aCylinder );
3089 if ( aCylSurface.IsNull() )
3091 SetErrorCode("Unexpected surface type instead of Geom_CylindricalSurface");
3094 gp_Pnt fromLoc = aCylSurface->Cylinder().Location();
3095 gp_Pnt toLoc = BRep_Tool::Pnt( TopoDS::Vertex( aPnt ));
3096 aCylinder->Translate( fromLoc, toLoc );
3099 TCollection_AsciiString anAsciiList;
3100 Handle(TColStd_HSequenceOfTransient) aSeq;
3101 aSeq = getShapesOnSurface( aCylinder, theShape, aShapeType, theState, anAsciiList );
3102 if ( aSeq.IsNull() || aSeq->Length() == 0 )
3105 // Make a Python command
3107 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
3108 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
3110 GEOM::TPythonDump(aFunction)
3111 << "[" << anAsciiList.ToCString()
3112 << "] = geompy.GetShapesOnCylinderWithLocation(" << theShape << ", " << aShapeType << ", "
3113 << theAxis << ", " << thePnt << ", " << theRadius << ", " << theState << ")";
3119 //=============================================================================
3123 //=============================================================================
3124 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnSphere
3125 (const Handle(GEOM_Object)& theShape,
3126 const Standard_Integer theShapeType,
3127 const Handle(GEOM_Object)& theCenter,
3128 const Standard_Real theRadius,
3129 const GEOMAlgo_State theState)
3133 if (theShape.IsNull() || theCenter.IsNull()) return NULL;
3135 TopoDS_Shape aShape = theShape->GetValue();
3136 TopoDS_Shape aCenter = theCenter->GetValue();
3138 if (aShape.IsNull() || aCenter.IsNull()) return NULL;
3140 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3141 if ( !checkTypeShapesOn( aShapeType ))
3144 // Center of the sphere
3145 if (aCenter.ShapeType() != TopAbs_VERTEX) return NULL;
3146 gp_Pnt aLoc = BRep_Tool::Pnt(TopoDS::Vertex(aCenter));
3148 gp_Ax3 anAx3 (aLoc, gp::DZ());
3149 Handle(Geom_SphericalSurface) aSphere =
3150 new Geom_SphericalSurface(anAx3, theRadius);
3153 TCollection_AsciiString anAsciiList;
3154 Handle(TColStd_HSequenceOfTransient) aSeq;
3155 aSeq = getShapesOnSurface( aSphere, theShape, aShapeType, theState, anAsciiList );
3156 if ( aSeq.IsNull() || aSeq->Length() == 0 )
3159 // Make a Python command
3161 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
3162 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
3164 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
3165 << "] = geompy.GetShapesOnSphere(" << theShape << ", " << aShapeType
3166 << ", " << theCenter << ", " << theRadius << ", " << theState << ")";
3172 //=============================================================================
3174 * GetShapesOnPlaneIDs
3176 //=============================================================================
3177 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnPlaneIDs
3178 (const Handle(GEOM_Object)& theShape,
3179 const Standard_Integer theShapeType,
3180 const Handle(GEOM_Object)& theAx1,
3181 const GEOMAlgo_State theState)
3185 if (theShape.IsNull() || theAx1.IsNull()) return NULL;
3187 TopoDS_Shape aShape = theShape->GetValue();
3188 TopoDS_Shape anAx1 = theAx1->GetValue();
3190 if (aShape.IsNull() || anAx1.IsNull()) return NULL;
3192 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3193 if ( !checkTypeShapesOn( aShapeType ))
3197 Handle(Geom_Surface) aPlane = makePlane( anAx1 );
3198 if ( aPlane.IsNull() )
3202 Handle(TColStd_HSequenceOfInteger) aSeq;
3203 aSeq = getShapesOnSurfaceIDs( aPlane, aShape, aShapeType, theState );
3205 // The GetShapesOnPlaneIDs() doesn't change object so no new function is required.
3206 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAx1)->GetLastFunction();
3208 // Make a Python command
3209 GEOM::TPythonDump(aFunction, /*append=*/true)
3210 << "listShapesOnPlane = geompy.GetShapesOnPlaneIDs"
3211 << "(" << theShape << "," << aShapeType << "," << theAx1 << "," << theState << ")";
3217 //=============================================================================
3219 * GetShapesOnPlaneWithLocationIDs
3221 //=============================================================================
3222 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnPlaneWithLocationIDs
3223 (const Handle(GEOM_Object)& theShape,
3224 const Standard_Integer theShapeType,
3225 const Handle(GEOM_Object)& theAx1,
3226 const Handle(GEOM_Object)& thePnt,
3227 const GEOMAlgo_State theState)
3231 if (theShape.IsNull() || theAx1.IsNull() || thePnt.IsNull()) return NULL;
3233 TopoDS_Shape aShape = theShape->GetValue();
3234 TopoDS_Shape anAx1 = theAx1->GetValue();
3235 TopoDS_Shape anPnt = thePnt->GetValue();
3237 if (aShape.IsNull() || anAx1.IsNull() || anPnt.IsNull()) return NULL;
3239 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3240 if ( !checkTypeShapesOn( aShapeType ))
3244 if (anAx1.ShapeType() != TopAbs_EDGE || anPnt.ShapeType() != TopAbs_VERTEX) return NULL;
3245 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
3246 TopoDS_Vertex V1, V2, V3;
3247 TopExp::Vertices(anEdge, V1, V2, Standard_True);
3248 if (V1.IsNull() || V2.IsNull()) {
3249 SetErrorCode("Bad edge given for the plane normal vector");
3252 V3 = TopoDS::Vertex(anPnt);
3254 SetErrorCode("Bad vertex given for the plane location");
3257 gp_Pnt aLoc = BRep_Tool::Pnt(V3);
3258 gp_Vec aVec(BRep_Tool::Pnt(V1),BRep_Tool::Pnt(V2));
3259 if (aVec.Magnitude() < Precision::Confusion()) {
3260 SetErrorCode("Vector with null magnitude given");
3264 Handle(Geom_Surface) aPlane = new Geom_Plane(aLoc, aVec);
3265 if ( aPlane.IsNull() )
3269 Handle(TColStd_HSequenceOfInteger) aSeq;
3270 aSeq = getShapesOnSurfaceIDs( aPlane, aShape, aShapeType, theState );
3272 // The GetShapesOnPlaneIDs() doesn't change object so no new function is required.
3273 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAx1)->GetLastFunction();
3275 // Make a Python command
3276 GEOM::TPythonDump(aFunction, /*append=*/true)
3277 << "listShapesOnPlane = geompy.GetShapesOnPlaneWithLocationIDs"
3278 << "(" << theShape << ", " << aShapeType << ", " << theAx1 << ", "<< thePnt << ", " << theState << ")";
3284 //=============================================================================
3286 * GetShapesOnCylinderIDs
3288 //=============================================================================
3289 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnCylinderIDs
3290 (const Handle(GEOM_Object)& theShape,
3291 const Standard_Integer theShapeType,
3292 const Handle(GEOM_Object)& theAxis,
3293 const Standard_Real theRadius,
3294 const GEOMAlgo_State theState)
3298 if (theShape.IsNull() || theAxis.IsNull()) return NULL;
3300 TopoDS_Shape aShape = theShape->GetValue();
3301 TopoDS_Shape anAxis = theAxis->GetValue();
3303 if (aShape.IsNull() || anAxis.IsNull()) return NULL;
3305 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3306 if ( !checkTypeShapesOn( aShapeType ))
3309 // Create a cylinder surface
3310 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
3311 if ( aCylinder.IsNull() )
3315 Handle(TColStd_HSequenceOfInteger) aSeq;
3316 aSeq = getShapesOnSurfaceIDs( aCylinder, aShape, aShapeType, theState );
3318 // The GetShapesOnCylinder() doesn't change object so no new function is required.
3319 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAxis)->GetLastFunction();
3321 // Make a Python command
3322 GEOM::TPythonDump(aFunction, /*append=*/true)
3323 << "listShapesOnCylinder = geompy.GetShapesOnCylinderIDs"
3324 << "(" << theShape << ", " << aShapeType << ", " << theAxis << ", "
3325 << theRadius << ", " << theState << ")";
3331 //=============================================================================
3333 * GetShapesOnCylinderWithLocationIDs
3335 //=============================================================================
3336 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnCylinderWithLocationIDs
3337 (const Handle(GEOM_Object)& theShape,
3338 const Standard_Integer theShapeType,
3339 const Handle(GEOM_Object)& theAxis,
3340 const Handle(GEOM_Object)& thePnt,
3341 const Standard_Real theRadius,
3342 const GEOMAlgo_State theState)
3346 if (theShape.IsNull() || theAxis.IsNull() || thePnt.IsNull()) return NULL;
3348 TopoDS_Shape aShape = theShape->GetValue();
3349 TopoDS_Shape anAxis = theAxis->GetValue();
3350 TopoDS_Shape aPnt = thePnt->GetValue();
3352 if (aShape.IsNull() || anAxis.IsNull() || aPnt.IsNull()) return NULL;
3354 if (aPnt.ShapeType() != TopAbs_VERTEX )
3356 SetErrorCode("Bottom location point must be vertex");
3360 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3361 if ( !checkTypeShapesOn( aShapeType ))
3364 // Create a cylinder surface
3365 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
3366 if ( aCylinder.IsNull() )
3369 // translate the surface
3370 Handle(Geom_CylindricalSurface) aCylSurface =
3371 Handle(Geom_CylindricalSurface)::DownCast( aCylinder );
3372 if ( aCylSurface.IsNull() )
3374 SetErrorCode("Unexpected surface type instead of Geom_CylindricalSurface");
3377 gp_Pnt fromLoc = aCylSurface->Cylinder().Location();
3378 gp_Pnt toLoc = BRep_Tool::Pnt( TopoDS::Vertex( aPnt ));
3379 aCylinder->Translate( fromLoc, toLoc );
3382 Handle(TColStd_HSequenceOfInteger) aSeq;
3383 aSeq = getShapesOnSurfaceIDs( aCylinder, aShape, aShapeType, theState );
3385 // The GetShapesOnCylinder() doesn't change object so no new function is required.
3386 Handle(GEOM_Function) aFunction =
3387 GEOM::GetCreatedLast(theShape, GEOM::GetCreatedLast(thePnt,theAxis))->GetLastFunction();
3389 // Make a Python command
3390 GEOM::TPythonDump(aFunction, /*append=*/true)
3391 << "listShapesOnCylinder = geompy.GetShapesOnCylinderWithLocationIDs"
3392 << "(" << theShape << ", " << aShapeType << ", " << theAxis << ", "
3393 << thePnt << ", " << theRadius << ", " << theState << ")";
3399 //=============================================================================
3401 * GetShapesOnSphereIDs
3403 //=============================================================================
3404 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnSphereIDs
3405 (const Handle(GEOM_Object)& theShape,
3406 const Standard_Integer theShapeType,
3407 const Handle(GEOM_Object)& theCenter,
3408 const Standard_Real theRadius,
3409 const GEOMAlgo_State theState)
3413 if (theShape.IsNull() || theCenter.IsNull()) return NULL;
3415 TopoDS_Shape aShape = theShape->GetValue();
3416 TopoDS_Shape aCenter = theCenter->GetValue();
3418 if (aShape.IsNull() || aCenter.IsNull()) return NULL;
3420 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3421 if ( !checkTypeShapesOn( aShapeType ))
3424 // Center of the sphere
3425 if (aCenter.ShapeType() != TopAbs_VERTEX) return NULL;
3426 gp_Pnt aLoc = BRep_Tool::Pnt(TopoDS::Vertex(aCenter));
3428 gp_Ax3 anAx3 (aLoc, gp::DZ());
3429 Handle(Geom_SphericalSurface) aSphere =
3430 new Geom_SphericalSurface(anAx3, theRadius);
3433 Handle(TColStd_HSequenceOfInteger) aSeq;
3434 aSeq = getShapesOnSurfaceIDs( aSphere, aShape, aShapeType, theState );
3436 // The GetShapesOnSphere() doesn't change object so no new function is required.
3437 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theCenter)->GetLastFunction();
3439 // Make a Python command
3440 GEOM::TPythonDump(aFunction, /*append=*/true)
3441 << "listShapesOnCylinder = geompy.GetShapesOnSphereIDs"
3442 << "(" << theShape << ", " << aShapeType << ", " << theCenter << ", "
3443 << theRadius << ", " << theState << ")";
3449 //=======================================================================
3450 //function : getShapesOnQuadrangleIDs
3452 * \brief Find IDs of sub-shapes complying with given status about quadrangle
3453 * \param theShape - the shape to explore
3454 * \param theShapeType - type of sub-shape of theShape
3455 * \param theTopLeftPoint - top left quadrangle corner
3456 * \param theTopRigthPoint - top right quadrangle corner
3457 * \param theBottomLeftPoint - bottom left quadrangle corner
3458 * \param theBottomRigthPoint - bottom right quadrangle corner
3459 * \param theState - required state
3460 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
3462 //=======================================================================
3463 Handle(TColStd_HSequenceOfInteger)
3464 GEOMImpl_IShapesOperations::getShapesOnQuadrangleIDs (const Handle(GEOM_Object)& theShape,
3465 const Standard_Integer theShapeType,
3466 const Handle(GEOM_Object)& theTopLeftPoint,
3467 const Handle(GEOM_Object)& theTopRigthPoint,
3468 const Handle(GEOM_Object)& theBottomLeftPoint,
3469 const Handle(GEOM_Object)& theBottomRigthPoint,
3470 const GEOMAlgo_State theState)
3474 if ( theShape.IsNull() ||
3475 theTopLeftPoint.IsNull() ||
3476 theTopRigthPoint.IsNull() ||
3477 theBottomLeftPoint.IsNull() ||
3478 theBottomRigthPoint.IsNull() )
3481 TopoDS_Shape aShape = theShape->GetValue();
3482 TopoDS_Shape aTL = theTopLeftPoint->GetValue();
3483 TopoDS_Shape aTR = theTopRigthPoint->GetValue();
3484 TopoDS_Shape aBL = theBottomLeftPoint->GetValue();
3485 TopoDS_Shape aBR = theBottomRigthPoint->GetValue();
3487 if (aShape.IsNull() ||
3492 aTL.ShapeType() != TopAbs_VERTEX ||
3493 aTR.ShapeType() != TopAbs_VERTEX ||
3494 aBL.ShapeType() != TopAbs_VERTEX ||
3495 aBR.ShapeType() != TopAbs_VERTEX )
3498 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3499 if ( !checkTypeShapesOn( aShapeType ))
3502 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
3504 // Check presence of triangulation, build if need
3505 if (!GEOMUtils::CheckTriangulation(aShape)) {
3506 SetErrorCode("Cannot build triangulation on the shape");
3511 gp_Pnt aPntTL = BRep_Tool::Pnt(TopoDS::Vertex(aTL));
3512 gp_Pnt aPntTR = BRep_Tool::Pnt(TopoDS::Vertex(aTR));
3513 gp_Pnt aPntBL = BRep_Tool::Pnt(TopoDS::Vertex(aBL));
3514 gp_Pnt aPntBR = BRep_Tool::Pnt(TopoDS::Vertex(aBR));
3516 GEOMAlgo_FinderShapeOnQuad aFinder( aPntTL, aPntTR, aPntBL, aPntBR );
3517 Standard_Real aTol = 0.0001; // default value
3519 aFinder.SetShape(aShape);
3520 aFinder.SetTolerance(aTol);
3521 //aFinder.SetSurface(theSurface);
3522 aFinder.SetShapeType(aShapeType);
3523 aFinder.SetState(theState);
3525 // Sets the minimal number of inner points for the faces that do not have own
3526 // inner points at all (for e.g. rectangular planar faces have just 2 triangles).
3528 aFinder.SetNbPntsMin(3);
3529 // Sets the maximal number of inner points for edges or faces.
3530 // It is usefull for the cases when this number is very big (e.g =2000) to improve
3531 // the performance. If this value =0, all inner points will be taken into account.
3533 aFinder.SetNbPntsMax(100);
3537 // Interprete results
3538 Standard_Integer iErr = aFinder.ErrorStatus();
3539 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
3541 MESSAGE(" iErr : " << iErr);
3542 TCollection_AsciiString aMsg (" iErr : ");
3543 aMsg += TCollection_AsciiString(iErr);
3547 Standard_Integer iWrn = aFinder.WarningStatus();
3548 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
3550 MESSAGE(" *** iWrn : " << iWrn);
3553 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
3555 if (listSS.Extent() < 1) {
3556 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
3557 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
3561 // Fill sequence of object IDs
3562 aSeqOfIDs = new TColStd_HSequenceOfInteger;
3564 TopTools_IndexedMapOfShape anIndices;
3565 TopExp::MapShapes(aShape, anIndices);
3567 TopTools_ListIteratorOfListOfShape itSub (listSS);
3568 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
3569 int id = anIndices.FindIndex(itSub.Value());
3570 aSeqOfIDs->Append(id);
3575 //=======================================================================
3576 //function : GetShapesOnQuadrangle
3578 * \brief Find sub-shapes complying with given status about quadrangle
3579 * \param theShape - the shape to explore
3580 * \param theShapeType - type of sub-shape of theShape
3581 * \param theTopLeftPoint - top left quadrangle corner
3582 * \param theTopRigthPoint - top right quadrangle corner
3583 * \param theBottomLeftPoint - bottom left quadrangle corner
3584 * \param theBottomRigthPoint - bottom right quadrangle corner
3585 * \param theState - required state
3586 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
3588 //=======================================================================
3589 Handle(TColStd_HSequenceOfTransient)
3590 GEOMImpl_IShapesOperations::GetShapesOnQuadrangle (const Handle(GEOM_Object)& theShape,
3591 const Standard_Integer theShapeType,
3592 const Handle(GEOM_Object)& theTopLeftPoint,
3593 const Handle(GEOM_Object)& theTopRigthPoint,
3594 const Handle(GEOM_Object)& theBottomLeftPoint,
3595 const Handle(GEOM_Object)& theBottomRigthPoint,
3596 const GEOMAlgo_State theState)
3599 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
3600 getShapesOnQuadrangleIDs( theShape,
3605 theBottomRigthPoint,
3607 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->IsEmpty() )
3610 // Find objects by indices
3611 TCollection_AsciiString anAsciiList;
3612 Handle(TColStd_HSequenceOfTransient) aSeq;
3613 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
3614 if ( aSeq.IsNull() || aSeq->IsEmpty() )
3617 // Make a Python command
3619 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
3620 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
3622 GEOM::TPythonDump(aFunction)
3623 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnQuadrangle("
3625 << TopAbs_ShapeEnum(theShapeType) << ", "
3626 << theTopLeftPoint << ", "
3627 << theTopRigthPoint << ", "
3628 << theBottomLeftPoint << ", "
3629 << theBottomRigthPoint << ", "
3636 //=======================================================================
3637 //function : GetShapesOnQuadrangleIDs
3639 * \brief Find IDs of sub-shapes complying with given status about quadrangle
3640 * \param theShape - the shape to explore
3641 * \param theShapeType - type of sub-shape of theShape
3642 * \param theTopLeftPoint - top left quadrangle corner
3643 * \param theTopRigthPoint - top right quadrangle corner
3644 * \param theBottomLeftPoint - bottom left quadrangle corner
3645 * \param theBottomRigthPoint - bottom right quadrangle corner
3646 * \param theState - required state
3647 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
3649 //=======================================================================
3650 Handle(TColStd_HSequenceOfInteger)
3651 GEOMImpl_IShapesOperations::GetShapesOnQuadrangleIDs (const Handle(GEOM_Object)& theShape,
3652 const Standard_Integer theShapeType,
3653 const Handle(GEOM_Object)& theTopLeftPoint,
3654 const Handle(GEOM_Object)& theTopRigthPoint,
3655 const Handle(GEOM_Object)& theBottomLeftPoint,
3656 const Handle(GEOM_Object)& theBottomRigthPoint,
3657 const GEOMAlgo_State theState)
3660 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
3661 getShapesOnQuadrangleIDs( theShape,
3666 theBottomRigthPoint,
3668 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->IsEmpty() )
3671 // Make a Python command
3673 // The GetShapesOnCylinder() doesn't change object so no new function is required.
3674 Handle(GEOM_Object) lastObj = GEOM::GetCreatedLast(theShape,theTopLeftPoint);
3675 lastObj = GEOM::GetCreatedLast(lastObj,theTopRigthPoint);
3676 lastObj = GEOM::GetCreatedLast(lastObj,theBottomRigthPoint);
3677 lastObj = GEOM::GetCreatedLast(lastObj,theBottomLeftPoint);
3678 Handle(GEOM_Function) aFunction = lastObj->GetLastFunction();
3680 GEOM::TPythonDump(aFunction, /*append=*/true)
3681 << "listShapesOnQuadrangle = geompy.GetShapesOnQuadrangleIDs("
3683 << TopAbs_ShapeEnum(theShapeType) << ", "
3684 << theTopLeftPoint << ", "
3685 << theTopRigthPoint << ", "
3686 << theBottomLeftPoint << ", "
3687 << theBottomRigthPoint << ", "
3694 //=============================================================================
3698 //=============================================================================
3699 static bool GetInPlaceOfShape (const Handle(GEOM_Function)& theWhereFunction,
3700 const TopTools_IndexedMapOfShape& theWhereIndices,
3701 const TopoDS_Shape& theWhat,
3702 TColStd_ListOfInteger& theModifiedList)
3704 if (theWhereFunction.IsNull() || theWhat.IsNull()) return false;
3706 if (theWhereIndices.Contains(theWhat)) {
3707 // entity was not changed by the operation
3708 Standard_Integer aWhatIndex = theWhereIndices.FindIndex(theWhat);
3709 theModifiedList.Append(aWhatIndex);
3713 // try to find in history
3714 TDF_Label aHistoryLabel = theWhereFunction->GetHistoryEntry(Standard_False);
3716 // search in history for all argument shapes
3717 Standard_Boolean isFound = Standard_False;
3718 Standard_Boolean isGood = Standard_False;
3720 TDF_LabelSequence aLabelSeq;
3721 theWhereFunction->GetDependency(aLabelSeq);
3722 Standard_Integer nbArg = aLabelSeq.Length();
3724 for (Standard_Integer iarg = 1; iarg <= nbArg && !isFound; iarg++) {
3726 TDF_Label anArgumentRefLabel = aLabelSeq.Value(iarg);
3728 Handle(GEOM_Object) anArgumentObject = GEOM_Object::GetReferencedObject(anArgumentRefLabel);
3729 TopoDS_Shape anArgumentShape = anArgumentObject->GetValue();
3731 TopTools_IndexedMapOfShape anArgumentIndices;
3732 TopExp::MapShapes(anArgumentShape, anArgumentIndices);
3734 if (anArgumentIndices.Contains(theWhat)) {
3735 isFound = Standard_True;
3736 Standard_Integer aWhatIndex = anArgumentIndices.FindIndex(theWhat);
3738 // Find corresponding label in history
3739 TDF_Label anArgumentHistoryLabel =
3740 theWhereFunction->GetArgumentHistoryEntry(anArgumentRefLabel, Standard_False);
3741 if (anArgumentHistoryLabel.IsNull()) {
3742 // Lost History of operation argument. Possibly, all its entities was removed.
3743 isGood = Standard_True;
3746 TDF_Label aWhatHistoryLabel = anArgumentHistoryLabel.FindChild(aWhatIndex, Standard_False);
3748 if (aWhatHistoryLabel.IsNull()) {
3749 // Removed entity ? Compound ? Compsolid ? Shell ? Wire
3750 isGood = Standard_False;
3752 Handle(TDataStd_IntegerArray) anIntegerArray;
3753 if (!aWhatHistoryLabel.FindAttribute(TDataStd_IntegerArray::GetID(), anIntegerArray)) {
3754 //Error: Empty modifications history for the sought shape.
3755 isGood = Standard_False;
3758 isGood = Standard_True;
3759 Standard_Integer imod, aModifLen = anIntegerArray->Array()->Length();
3760 for (imod = 1; imod <= aModifLen; imod++) {
3761 theModifiedList.Append(anIntegerArray->Array()->Value(imod));
3772 // try compound/compsolid/shell/wire element by element
3773 bool isFoundAny = false;
3774 TopTools_MapOfShape mapShape;
3776 if (theWhat.ShapeType() == TopAbs_COMPOUND ||
3777 theWhat.ShapeType() == TopAbs_COMPSOLID) {
3778 // recursive processing of compound/compsolid
3779 TopoDS_Iterator anIt (theWhat, Standard_True, Standard_True);
3780 for (; anIt.More(); anIt.Next()) {
3781 if (mapShape.Add(anIt.Value())) {
3782 TopoDS_Shape curWhat = anIt.Value();
3783 isFoundAny = GetInPlaceOfShape(theWhereFunction, theWhereIndices, curWhat, theModifiedList);
3784 if (isFoundAny) isFound = Standard_True;
3788 else if (theWhat.ShapeType() == TopAbs_SHELL) {
3789 // try to replace a shell by its faces images
3790 TopExp_Explorer anExp (theWhat, TopAbs_FACE);
3791 for (; anExp.More(); anExp.Next()) {
3792 if (mapShape.Add(anExp.Current())) {
3793 TopoDS_Shape curWhat = anExp.Current();
3794 isFoundAny = GetInPlaceOfShape(theWhereFunction, theWhereIndices, curWhat, theModifiedList);
3795 if (isFoundAny) isFound = Standard_True;
3799 else if (theWhat.ShapeType() == TopAbs_WIRE) {
3800 // try to replace a wire by its edges images
3801 TopExp_Explorer anExp (theWhat, TopAbs_EDGE);
3802 for (; anExp.More(); anExp.Next()) {
3803 if (mapShape.Add(anExp.Current())) {
3804 TopoDS_Shape curWhat = anExp.Current();
3805 isFoundAny = GetInPlaceOfShape(theWhereFunction, theWhereIndices, curWhat, theModifiedList);
3806 if (isFoundAny) isFound = Standard_True;
3818 //=============================================================================
3820 * GetShapeProperties
3822 //=============================================================================
3823 void GEOMImpl_IShapesOperations::GetShapeProperties( const TopoDS_Shape aShape, Standard_Real tab[],
3826 GProp_GProps theProps;
3828 //TopoDS_Shape aPntShape;
3829 Standard_Real aShapeSize;
3831 if (aShape.ShapeType() == TopAbs_VERTEX) aCenterMass = BRep_Tool::Pnt( TopoDS::Vertex( aShape ) );
3832 else if (aShape.ShapeType() == TopAbs_EDGE) BRepGProp::LinearProperties(aShape, theProps);
3833 else if (aShape.ShapeType() == TopAbs_FACE) BRepGProp::SurfaceProperties(aShape, theProps);
3834 else BRepGProp::VolumeProperties(aShape, theProps);
3836 if (aShape.ShapeType() == TopAbs_VERTEX)
3839 aCenterMass = theProps.CentreOfMass();
3840 aShapeSize = theProps.Mass();
3843 // aPntShape = BRepBuilderAPI_MakeVertex(aCenterMass).Shape();
3844 // aVertex = BRep_Tool::Pnt( TopoDS::Vertex( aPntShape ) );
3845 aVertex = aCenterMass;
3846 tab[0] = aVertex.X();
3847 tab[1] = aVertex.Y();
3848 tab[2] = aVertex.Z();
3849 tab[3] = aShapeSize;
3855 //================================================================================
3857 * \brief Return normal to face at extrema point
3859 //================================================================================
3861 gp_Vec GetNormal (const TopoDS_Face& face, const BRepExtrema_DistShapeShape& extrema)
3863 gp_Vec defaultNorm(1,0,0); // to have same normals on different faces
3865 // get UV at extrema point
3866 Standard_Real u,v, f,l;
3867 switch ( extrema.SupportTypeShape2(1) ) {
3868 case BRepExtrema_IsInFace: {
3869 extrema.ParOnFaceS2(1, u, v );
3872 case BRepExtrema_IsOnEdge: {
3873 TopoDS_Edge edge = TopoDS::Edge( extrema.SupportOnShape2(1));
3874 Handle(Geom2d_Curve) pcurve = BRep_Tool::CurveOnSurface( edge, face, f,l );
3875 extrema.ParOnEdgeS2( 1, u );
3876 gp_Pnt2d uv = pcurve->Value( u );
3881 case BRepExtrema_IsVertex: return defaultNorm;
3884 BRepAdaptor_Surface surface( face, false );
3885 gp_Vec du, dv; gp_Pnt p;
3886 surface.D1( u, v, p, du, dv );
3890 } catch (Standard_Failure ) {
3896 //=============================================================================
3901 //=============================================================================
3902 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlace (Handle(GEOM_Object) theShapeWhere,
3903 Handle(GEOM_Object) theShapeWhat)
3907 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
3909 TopoDS_Shape aWhere = theShapeWhere->GetValue();
3910 TopoDS_Shape aWhat = theShapeWhat->GetValue();
3912 if (aWhere.IsNull() || aWhat.IsNull()) {
3913 SetErrorCode("Error: aWhere and aWhat TopoDS_Shape are Null.");
3917 // Compute confusion tolerance.
3918 Standard_Real aTolConf = Precision::Confusion();
3921 for (i = 0; i < 2; ++i) {
3922 TopExp_Explorer anExp(i == 0 ? aWhere : aWhat, TopAbs_VERTEX);
3924 for (; anExp.More(); anExp.Next()) {
3925 const TopoDS_Vertex aVtx = TopoDS::Vertex(anExp.Current());
3926 const Standard_Real aTolVtx = BRep_Tool::Tolerance(aVtx);
3928 if (aTolVtx > aTolConf) {
3934 // Compute mass tolerance.
3935 Bnd_Box aBoundingBox;
3936 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
3937 Standard_Real aMassTol;
3939 BRepBndLib::Add(aWhere, aBoundingBox);
3940 BRepBndLib::Add(aWhat, aBoundingBox);
3941 aBoundingBox.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
3942 aMassTol = Max(aXmax - aXmin, aYmax - aYmin);
3943 aMassTol = Max(aMassTol, aZmax - aZmin);
3944 aMassTol *= aTolConf;
3946 // Searching for the sub-shapes inside the ShapeWhere shape
3947 GEOMAlgo_GetInPlace aGIP;
3948 aGIP.SetTolerance(aTolConf);
3949 aGIP.SetTolMass(aMassTol);
3950 aGIP.SetTolCG(aTolConf);
3952 aGIP.SetArgument(aWhat);
3953 aGIP.SetShapeWhere(aWhere);
3956 int iErr = aGIP.ErrorStatus();
3958 SetErrorCode("Error in GEOMAlgo_GetInPlace");
3962 // Add direct result.
3963 TopTools_ListOfShape aLSA;
3964 const TopoDS_Shape &aShapeResult = aGIP.Result();
3965 TopTools_MapOfShape aMFence;
3966 TopTools_IndexedMapOfShape aWhereIndices;
3968 TopExp::MapShapes(aWhere, aWhereIndices);
3970 if (aShapeResult.IsNull() == Standard_False) {
3971 TopoDS_Iterator anIt(aShapeResult);
3973 for (; anIt.More(); anIt.Next()) {
3974 const TopoDS_Shape &aPart = anIt.Value();
3976 if(aWhereIndices.Contains(aPart) && aMFence.Add(aPart)) {
3982 if (aLSA.Extent() == 0) {
3983 SetErrorCode(NOT_FOUND_ANY); // Not found any Results
3987 Handle(TColStd_HArray1OfInteger) aModifiedArray = new TColStd_HArray1OfInteger (1, aLSA.Extent());
3988 TopTools_ListIteratorOfListOfShape anIterModif (aLSA);
3989 for (Standard_Integer imod = 1; anIterModif.More(); anIterModif.Next(), imod++) {
3990 if (aWhereIndices.Contains(anIterModif.Value())) {
3991 aModifiedArray->SetValue(imod, aWhereIndices.FindIndex(anIterModif.Value()));
3994 SetErrorCode("Error: wrong sub-shape returned");
4000 Handle(GEOM_Object) aResult = GetEngine()->AddSubShape(theShapeWhere, aModifiedArray);
4001 if (aResult.IsNull()) {
4002 SetErrorCode("Error in algorithm: result found, but cannot be returned.");
4006 if (aModifiedArray->Length() > 1 || theShapeWhat->GetType() == GEOM_GROUP) {
4008 aResult->SetType(GEOM_GROUP);
4010 //Set a sub-shape type
4011 TopoDS_Shape aFirstFound = aLSA.First();
4012 TopAbs_ShapeEnum aShapeType = aFirstFound.ShapeType();
4014 TDF_Label aFreeLabel = aResult->GetFreeLabel();
4015 TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aShapeType);
4018 //Make a Python command
4019 Handle(GEOM_Function) aFunction = aResult->GetFunction(1);
4021 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetInPlace("
4022 << theShapeWhere << ", " << theShapeWhat << ", True)";
4028 //=============================================================================
4030 * case GetInPlaceOld:
4033 //=============================================================================
4034 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlaceOld (Handle(GEOM_Object) theShapeWhere,
4035 Handle(GEOM_Object) theShapeWhat)
4039 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
4041 TopoDS_Shape aWhere = theShapeWhere->GetValue();
4042 TopoDS_Shape aWhat = theShapeWhat->GetValue();
4043 TopoDS_Shape aPntShape;
4044 TopoDS_Vertex aVertex;
4046 if (aWhere.IsNull() || aWhat.IsNull()) {
4047 SetErrorCode("Error: aWhere and aWhat TopoDS_Shape are Null.");
4051 Handle(GEOM_Function) aWhereFunction = theShapeWhere->GetLastFunction();
4052 if (aWhereFunction.IsNull()) {
4053 SetErrorCode("Error: aWhereFunction is Null.");
4057 TopTools_IndexedMapOfShape aWhereIndices;
4058 TopExp::MapShapes(aWhere, aWhereIndices);
4060 TColStd_ListOfInteger aModifiedList;
4061 Standard_Integer aWhereIndex;
4062 Handle(TColStd_HArray1OfInteger) aModifiedArray;
4063 Handle(GEOM_Object) aResult;
4065 bool isFound = false;
4066 TopAbs_ShapeEnum iType = TopAbs_SOLID;
4067 //Standard_Real aWhat_Mass = 0., aWhere_Mass = 0.;
4068 Standard_Real tab_aWhat[4], tab_aWhere[4];
4069 Standard_Real dl_l = 1e-3;
4070 Standard_Real min_l, Tol_0D, Tol_1D, Tol_2D, Tol_3D, Tol_Mass;
4071 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
4072 Bnd_Box BoundingBox;
4073 gp_Pnt aPnt, aPnt_aWhat, tab_Pnt[2];
4074 GProp_GProps aProps;
4076 // Find the iType of the aWhat shape
4078 if ( aWhat.ShapeType() == TopAbs_VERTEX ) iType = TopAbs_VERTEX;
4079 else if ( aWhat.ShapeType() == TopAbs_EDGE || aWhat.ShapeType() == TopAbs_WIRE ) iType = TopAbs_EDGE;
4080 else if ( aWhat.ShapeType() == TopAbs_FACE || aWhat.ShapeType() == TopAbs_SHELL ) iType = TopAbs_FACE;
4081 else if ( aWhat.ShapeType() == TopAbs_SOLID || aWhat.ShapeType() == TopAbs_COMPSOLID ) iType = TopAbs_SOLID;
4082 else if ( aWhat.ShapeType() == TopAbs_COMPOUND ) {
4083 // Only the iType of the first shape in the compound is taken into account
4084 TopoDS_Iterator It (aWhat, Standard_False, Standard_False);
4086 SetErrorCode("Error: theShapeWhat is an empty COMPOUND.");
4089 TopAbs_ShapeEnum compType = It.Value().ShapeType();
4090 if ( compType == TopAbs_VERTEX ) iType = TopAbs_VERTEX;
4091 else if ( compType == TopAbs_EDGE || compType == TopAbs_WIRE ) iType = TopAbs_EDGE;
4092 else if ( compType == TopAbs_FACE || compType == TopAbs_SHELL) iType = TopAbs_FACE;
4093 else if ( compType == TopAbs_SOLID || compType == TopAbs_COMPSOLID) iType = TopAbs_SOLID;
4096 SetErrorCode("Error: An attempt to extract a shape of not supported type.");
4100 iType = GEOMUtils::GetTypeOfSimplePart(aWhat);
4101 if (iType == TopAbs_SHAPE) {
4102 SetErrorCode("Error: An attempt to extract a shape of not supported type.");
4106 TopExp_Explorer Exp_aWhat ( aWhat, iType );
4107 TopExp_Explorer Exp_aWhere ( aWhere, iType );
4108 TopExp_Explorer Exp_Edge ( aWhere, TopAbs_EDGE );
4110 // Find the shortest edge in theShapeWhere shape
4111 BRepBndLib::Add(aWhere, BoundingBox);
4112 BoundingBox.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
4113 min_l = fabs(aXmax - aXmin);
4114 if( min_l < fabs(aYmax - aYmin) ) min_l = fabs(aYmax - aYmin);
4115 if( min_l < fabs(aZmax - aZmin) ) min_l = fabs(aZmax - aZmin);
4117 // Mantis issue 0020908 BEGIN
4118 if (!Exp_Edge.More()) {
4119 min_l = Precision::Confusion();
4121 // Mantis issue 0020908 END
4122 for ( Standard_Integer nbEdge = 0; Exp_Edge.More(); Exp_Edge.Next(), nbEdge++ ) {
4123 TopExp_Explorer Exp_Vertex( Exp_Edge.Current(), TopAbs_VERTEX);
4124 for ( Standard_Integer nbVertex = 0; Exp_Vertex.More(); Exp_Vertex.Next(), nbVertex++ ) {
4125 aPnt = BRep_Tool::Pnt( TopoDS::Vertex( Exp_Vertex.Current() ) );
4126 tab_Pnt[nbVertex] = aPnt;
4128 if ( ! tab_Pnt[0].IsEqual(tab_Pnt[1], dl_l) ) {
4129 BRepGProp::LinearProperties(Exp_Edge.Current(), aProps);
4130 if ( aProps.Mass() < min_l ) min_l = aProps.Mass();
4134 // Compute tolerances
4136 Tol_1D = dl_l * min_l;
4137 Tol_2D = dl_l * ( min_l * min_l) * ( 2. + dl_l);
4138 Tol_3D = dl_l * ( min_l * min_l * min_l ) * ( 3. + (3 * dl_l) + (dl_l * dl_l) );
4140 if (Tol_0D < Precision::Confusion()) Tol_0D = Precision::Confusion();
4141 if (Tol_1D < Precision::Confusion()) Tol_1D = Precision::Confusion();
4142 if (Tol_2D < Precision::Confusion()) Tol_2D = Precision::Confusion();
4143 if (Tol_3D < Precision::Confusion()) Tol_3D = Precision::Confusion();
4145 //if (Tol_1D > 1.0) Tol_1D = 1.0;
4146 //if (Tol_2D > 1.0) Tol_2D = 1.0;
4147 //if (Tol_3D > 1.0) Tol_3D = 1.0;
4150 if ( iType == TopAbs_VERTEX ) Tol_Mass = Tol_0D;
4151 else if ( iType == TopAbs_EDGE ) Tol_Mass = Tol_1D;
4152 else if ( iType == TopAbs_FACE ) Tol_Mass = Tol_2D;
4154 // Compute the ShapeWhat Mass
4156 for ( ; Exp_aWhat.More(); Exp_aWhat.Next() ) {
4157 if ( iType == TopAbs_VERTEX ) {
4161 else if ( iType == TopAbs_EDGE ) BRepGProp::LinearProperties(Exp_aWhat.Current(), aProps);
4162 else if ( iType == TopAbs_FACE ) BRepGProp::SurfaceProperties(Exp_aWhat.Current(), aProps);
4163 else BRepGProp::VolumeProperties(Exp_aWhat.Current(), aProps);
4164 aWhat_Mass += aProps.Mass();
4168 // Searching for the sub-shapes inside the ShapeWhere shape
4169 TopTools_MapOfShape map_aWhere;
4170 for ( Exp_aWhere.ReInit(); Exp_aWhere.More(); Exp_aWhere.Next() ) {
4171 if (!map_aWhere.Add(Exp_aWhere.Current()))
4172 continue; // skip repeated shape to avoid mass addition
4173 GetShapeProperties( Exp_aWhere.Current(), tab_aWhere, aPnt );
4174 for ( Exp_aWhat.ReInit(); Exp_aWhat.More(); Exp_aWhat.Next() ) {
4175 GetShapeProperties( Exp_aWhat.Current(), tab_aWhat, aPnt_aWhat );
4176 if ( fabs(tab_aWhat[3] - tab_aWhere[3]) <= Tol_Mass && aPnt_aWhat.Distance(aPnt) <= Tol_1D )
4179 if ( (tab_aWhat[3] - tab_aWhere[3]) > Tol_Mass ) {
4180 aPntShape = BRepBuilderAPI_MakeVertex( aPnt ).Shape();
4181 aVertex = TopoDS::Vertex( aPntShape );
4182 BRepExtrema_DistShapeShape aWhereDistance ( aVertex, Exp_aWhere.Current() );
4183 BRepExtrema_DistShapeShape aWhatDistance ( aVertex, Exp_aWhat.Current() );
4184 if ( aWhereDistance.IsDone() && aWhatDistance.IsDone() &&
4185 fabs(aWhereDistance.Value() - aWhatDistance.Value()) <= Tol_1D )
4187 // 0020162: "EDF 961 GEOM : Getinplace is getting additionnal orthogonal faces"
4188 // aVertex must be projected to the same point on Where and on What
4189 gp_Pnt pOnWhat = aWhatDistance.PointOnShape2(1);
4190 gp_Pnt pOnWhere = aWhereDistance.PointOnShape2(1);
4191 isFound = ( pOnWhat.Distance(pOnWhere) <= Tol_1D );
4192 if ( isFound && iType == TopAbs_FACE )
4194 // check normals at pOnWhat and pOnWhere
4195 const double angleTol = M_PI/180.;
4196 gp_Vec normToWhat = GetNormal( TopoDS::Face(Exp_aWhat.Current()), aWhatDistance);
4197 gp_Vec normToWhere = GetNormal( TopoDS::Face(Exp_aWhere.Current()), aWhereDistance);
4198 if ( normToWhat * normToWhere < 0 )
4199 normToWhat.Reverse();
4200 isFound = ( normToWhat.Angle( normToWhere ) < angleTol );
4206 aWhereIndex = aWhereIndices.FindIndex(Exp_aWhere.Current());
4207 aModifiedList.Append(aWhereIndex);
4208 //aWhere_Mass += tab_aWhere[3];
4213 //if ( fabs( aWhat_Mass - aWhere_Mass ) <= Tol_Mass )
4217 if (aModifiedList.Extent() == 0) { // Not found any Results
4218 SetErrorCode(NOT_FOUND_ANY);
4222 aModifiedArray = new TColStd_HArray1OfInteger (1, aModifiedList.Extent());
4223 TColStd_ListIteratorOfListOfInteger anIterModif (aModifiedList);
4224 for (Standard_Integer imod = 1; anIterModif.More(); anIterModif.Next(), imod++)
4225 aModifiedArray->SetValue(imod, anIterModif.Value());
4228 aResult = GetEngine()->AddSubShape(theShapeWhere, aModifiedArray);
4229 if (aResult.IsNull()) {
4230 SetErrorCode("Error in algorithm: result found, but cannot be returned.");
4234 if (aModifiedArray->Length() > 1 || theShapeWhat->GetType() == GEOM_GROUP) {
4236 aResult->SetType(GEOM_GROUP);
4238 //Set a sub-shape type
4239 TopoDS_Shape aFirstFound = aWhereIndices.FindKey(aModifiedArray->Value(1));
4240 TopAbs_ShapeEnum aShapeType = aFirstFound.ShapeType();
4242 TDF_Label aFreeLabel = aResult->GetFreeLabel();
4243 TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aShapeType);
4246 //Make a Python command
4247 Handle(GEOM_Function) aFunction = aResult->GetFunction(1);
4249 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetInPlace("
4250 << theShapeWhere << ", " << theShapeWhat << ", False)";
4256 //=======================================================================
4257 //function : GetInPlaceByHistory
4259 //=======================================================================
4260 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlaceByHistory
4261 (Handle(GEOM_Object) theShapeWhere,
4262 Handle(GEOM_Object) theShapeWhat)
4266 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
4268 TopoDS_Shape aWhere = theShapeWhere->GetValue();
4269 TopoDS_Shape aWhat = theShapeWhat->GetValue();
4271 if (aWhere.IsNull() || aWhat.IsNull()) return NULL;
4273 Handle(GEOM_Function) aWhereFunction = theShapeWhere->GetLastFunction();
4274 if (aWhereFunction.IsNull()) return NULL;
4276 //Fill array of indices
4277 TopTools_IndexedMapOfShape aWhereIndices;
4278 TopExp::MapShapes(aWhere, aWhereIndices);
4281 TColStd_ListOfInteger aModifiedList;
4282 bool isFound = GetInPlaceOfShape(aWhereFunction, aWhereIndices, aWhat, aModifiedList);
4284 if (!isFound || aModifiedList.Extent() < 1) {
4285 SetErrorCode("Error: No history found for the sought shape or its sub-shapes.");
4289 Standard_Integer nbFound = aModifiedList.Extent();
4290 TColStd_ListIteratorOfListOfInteger anIterModif (aModifiedList);
4293 // remove sub-shapes inappropriate for group creation
4294 TopAbs_ShapeEnum subType = TopAbs_SHAPE;
4295 while ( anIterModif.More() ) {
4296 TopAbs_ShapeEnum type = aWhereIndices( anIterModif.Value() ).ShapeType();
4297 bool okForGroup = ( type == TopAbs_VERTEX || type == TopAbs_EDGE ||
4298 type == TopAbs_FACE || type == TopAbs_SOLID );
4300 if ( subType == TopAbs_SHAPE )
4303 okForGroup = ( subType == type );
4308 aModifiedList.Remove( anIterModif );
4309 nbFound -= ( !okForGroup );
4311 if ( nbFound == 0 ) {
4312 SetErrorCode("Error: result found but it's type is inappropriate for group creation.");
4317 Handle(TColStd_HArray1OfInteger) aModifiedArray =
4318 new TColStd_HArray1OfInteger( 1, nbFound );
4319 anIterModif.Initialize(aModifiedList);
4320 for (Standard_Integer imod = 1; anIterModif.More(); anIterModif.Next(), imod++)
4321 aModifiedArray->SetValue(imod, anIterModif.Value());
4324 Handle(GEOM_Object) aResult = GetEngine()->AddSubShape(theShapeWhere, aModifiedArray);
4325 if (aResult.IsNull()) {
4326 SetErrorCode("Error in algorithm: result found, but cannot be returned.");
4330 if (aModifiedArray->Length() > 1) {
4332 aResult->SetType(GEOM_GROUP);
4334 //Set a sub-shape type
4335 TopoDS_Shape aFirstFound = aWhereIndices.FindKey(aModifiedArray->Value(1));
4336 TopAbs_ShapeEnum aShapeType = aFirstFound.ShapeType();
4338 TDF_Label aFreeLabel = aResult->GetFreeLabel();
4339 TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aShapeType);
4342 //Make a Python command
4343 Handle(GEOM_Function) aFunction = aResult->GetFunction(1);
4345 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetInPlaceByHistory("
4346 << theShapeWhere << ", " << theShapeWhat << ")";
4352 #define MAX_TOLERANCE 1.e-7
4354 //=======================================================================
4355 //function : isSameEdge
4356 //purpose : Returns True if two edges coincide
4357 //=======================================================================
4358 static bool isSameEdge(const TopoDS_Edge& theEdge1, const TopoDS_Edge& theEdge2)
4360 TopoDS_Vertex V11, V12, V21, V22;
4361 TopExp::Vertices(theEdge1, V11, V12);
4362 TopExp::Vertices(theEdge2, V21, V22);
4363 gp_Pnt P11 = BRep_Tool::Pnt(V11);
4364 gp_Pnt P12 = BRep_Tool::Pnt(V12);
4365 gp_Pnt P21 = BRep_Tool::Pnt(V21);
4366 gp_Pnt P22 = BRep_Tool::Pnt(V22);
4367 bool coincide = false;
4369 //Check that ends of edges coincide
4370 if(P11.Distance(P21) <= MAX_TOLERANCE) {
4371 if(P12.Distance(P22) <= MAX_TOLERANCE) coincide = true;
4373 else if(P11.Distance(P22) <= MAX_TOLERANCE) {
4374 if(P12.Distance(P21) <= MAX_TOLERANCE) coincide = true;
4377 if(!coincide) return false;
4379 if (BRep_Tool::Degenerated(theEdge1))
4380 if (BRep_Tool::Degenerated(theEdge2)) return true;
4383 if (BRep_Tool::Degenerated(theEdge2)) return false;
4385 double U11, U12, U21, U22;
4386 Handle(Geom_Curve) C1 = BRep_Tool::Curve(theEdge1, U11, U12);
4387 Handle(Geom_Curve) C2 = BRep_Tool::Curve(theEdge2, U21, U22);
4388 if(C1->DynamicType() == C2->DynamicType()) return true;
4390 //Check that both edges has the same geometry
4391 double range = U12-U11;
4392 double U = U11+ range/3.0;
4393 gp_Pnt P1 = C1->Value(U); //Compute a point on one third of the edge's length
4394 U = U11+range*2.0/3.0;
4395 gp_Pnt P2 = C1->Value(U); //Compute a point on two thirds of the edge's length
4397 if(!GeomLib_Tool::Parameter(C2, P1, MAX_TOLERANCE, U) || U < U21 || U > U22)
4400 if(P1.Distance(C2->Value(U)) > MAX_TOLERANCE) return false;
4402 if(!GeomLib_Tool::Parameter(C2, P2, MAX_TOLERANCE, U) || U < U21 || U > U22)
4405 if(P2.Distance(C2->Value(U)) > MAX_TOLERANCE) return false;
4410 #include <TopoDS_TShape.hxx>
4411 //=======================================================================
4412 //function : isSameFace
4413 //purpose : Returns True if two faces coincide
4414 //=======================================================================
4415 static bool isSameFace(const TopoDS_Face& theFace1, const TopoDS_Face& theFace2)
4417 TopExp_Explorer E(theFace1, TopAbs_EDGE);
4418 TopTools_ListOfShape LS1, LS2;
4419 for(; E.More(); E.Next()) LS1.Append(E.Current());
4421 E.Init(theFace2, TopAbs_EDGE);
4422 for(; E.More(); E.Next()) LS2.Append(E.Current());
4424 //Compare the number of edges in the faces
4425 if(LS1.Extent() != LS2.Extent()) return false;
4427 double aMin = RealFirst(), aMax = RealLast();
4428 double xminB1=aMax, yminB1=aMax, zminB1=aMax, xminB2=aMax, yminB2=aMax, zminB2=aMax;
4429 double xmaxB1=aMin, ymaxB1=aMin, zmaxB1=aMin, xmaxB2=aMin, ymaxB2=aMin, zmaxB2=aMin;
4431 for(E.Init(theFace1, TopAbs_VERTEX); E.More(); E.Next()) {
4432 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4433 if(P.X() < xminB1) xminB1 = P.X();
4434 if(P.Y() < yminB1) yminB1 = P.Y();
4435 if(P.Z() < zminB1) zminB1 = P.Z();
4436 if(P.X() > xmaxB1) xmaxB1 = P.X();
4437 if(P.Y() > ymaxB1) ymaxB1 = P.Y();
4438 if(P.Z() > zmaxB1) zmaxB1 = P.Z();
4441 for(E.Init(theFace2, TopAbs_VERTEX); E.More(); E.Next()) {
4442 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4443 if(P.X() < xminB2) xminB2 = P.X();
4444 if(P.Y() < yminB2) yminB2 = P.Y();
4445 if(P.Z() < zminB2) zminB2 = P.Z();
4446 if(P.X() > xmaxB2) xmaxB2 = P.X();
4447 if(P.Y() > ymaxB2) ymaxB2 = P.Y();
4448 if(P.Z() > zmaxB2) zmaxB2 = P.Z();
4451 //Compare the bounding boxes of both faces
4452 if(gp_Pnt(xminB1, yminB1, zminB1).Distance(gp_Pnt(xminB2, yminB2, zminB2)) > MAX_TOLERANCE)
4455 if(gp_Pnt(xmaxB1, ymaxB1, zmaxB1).Distance(gp_Pnt(xmaxB2, ymaxB2, zmaxB2)) > MAX_TOLERANCE)
4458 Handle(Geom_Surface) S1 = BRep_Tool::Surface(theFace1);
4459 Handle(Geom_Surface) S2 = BRep_Tool::Surface(theFace2);
4461 //Check if there a coincidence of two surfaces at least in two points
4462 double U11, U12, V11, V12, U21, U22, V21, V22;
4463 BRepTools::UVBounds(theFace1, U11, U12, V11, V12);
4464 BRepTools::UVBounds(theFace2, U21, U22, V21, V22);
4466 double rangeU = U12-U11;
4467 double rangeV = V12-V11;
4468 double U = U11 + rangeU/3.0;
4469 double V = V11 + rangeV/3.0;
4470 gp_Pnt P1 = S1->Value(U, V);
4471 U = U11+rangeU*2.0/3.0;
4472 V = V11+rangeV*2.0/3.0;
4473 gp_Pnt P2 = S1->Value(U, V);
4475 if (!GeomLib_Tool::Parameters(S2, P1, MAX_TOLERANCE, U, V) || U < U21 || U > U22 || V < V21 || V > V22)
4478 if (P1.Distance(S2->Value(U,V)) > MAX_TOLERANCE) return false;
4480 if (!GeomLib_Tool::Parameters(S2, P2, MAX_TOLERANCE, U, V) || U < U21 || U > U22 || V < V21 || V > V22)
4483 if (P2.Distance(S2->Value(U, V)) > MAX_TOLERANCE) return false;
4485 //Check that each edge of the Face1 has a counterpart in the Face2
4486 TopTools_MapOfOrientedShape aMap;
4487 TopTools_ListIteratorOfListOfShape LSI1(LS1);
4488 for(; LSI1.More(); LSI1.Next()) {
4489 TopoDS_Edge E = TopoDS::Edge(LSI1.Value());
4490 bool isFound = false;
4491 TopTools_ListIteratorOfListOfShape LSI2(LS2);
4492 for(; LSI2.More(); LSI2.Next()) {
4493 TopoDS_Shape aValue = LSI2.Value();
4494 if(aMap.Contains(aValue)) continue; //To avoid checking already found edge several times
4495 if(isSameEdge(E, TopoDS::Edge(aValue))) {
4501 if(!isFound) return false;
4507 //=======================================================================
4508 //function : isSameSolid
4509 //purpose : Returns True if two solids coincide
4510 //=======================================================================
4511 bool isSameSolid(const TopoDS_Solid& theSolid1, const TopoDS_Solid& theSolid2)
4513 TopExp_Explorer E(theSolid1, TopAbs_FACE);
4514 TopTools_ListOfShape LS1, LS2;
4515 for(; E.More(); E.Next()) LS1.Append(E.Current());
4516 E.Init(theSolid2, TopAbs_FACE);
4517 for(; E.More(); E.Next()) LS2.Append(E.Current());
4519 if(LS1.Extent() != LS2.Extent()) return false;
4521 double aMin = RealFirst(), aMax = RealLast();
4522 double xminB1=aMax, yminB1=aMax, zminB1=aMax, xminB2=aMax, yminB2=aMax, zminB2=aMax;
4523 double xmaxB1=aMin, ymaxB1=aMin, zmaxB1=aMin, xmaxB2=aMin, ymaxB2=aMin, zmaxB2=aMin;
4525 for(E.Init(theSolid1, TopAbs_VERTEX); E.More(); E.Next()) {
4526 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4527 if(P.X() < xminB1) xminB1 = P.X();
4528 if(P.Y() < yminB1) yminB1 = P.Y();
4529 if(P.Z() < zminB1) zminB1 = P.Z();
4530 if(P.X() > xmaxB1) xmaxB1 = P.X();
4531 if(P.Y() > ymaxB1) ymaxB1 = P.Y();
4532 if(P.Z() > zmaxB1) zmaxB1 = P.Z();
4535 for(E.Init(theSolid2, TopAbs_VERTEX); E.More(); E.Next()) {
4536 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4537 if(P.X() < xminB2) xminB2 = P.X();
4538 if(P.Y() < yminB2) yminB2 = P.Y();
4539 if(P.Z() < zminB2) zminB2 = P.Z();
4540 if(P.X() > xmaxB2) xmaxB2 = P.X();
4541 if(P.Y() > ymaxB2) ymaxB2 = P.Y();
4542 if(P.Z() > zmaxB2) zmaxB2 = P.Z();
4545 //Compare the bounding boxes of both solids
4546 if(gp_Pnt(xminB1, yminB1, zminB1).Distance(gp_Pnt(xminB2, yminB2, zminB2)) > MAX_TOLERANCE)
4549 if(gp_Pnt(xmaxB1, ymaxB1, zmaxB1).Distance(gp_Pnt(xmaxB2, ymaxB2, zmaxB2)) > MAX_TOLERANCE)
4552 //Check that each face of the Solid1 has a counterpart in the Solid2
4553 TopTools_MapOfOrientedShape aMap;
4554 TopTools_ListIteratorOfListOfShape LSI1(LS1);
4555 for(; LSI1.More(); LSI1.Next()) {
4556 TopoDS_Face F = TopoDS::Face(LSI1.Value());
4557 bool isFound = false;
4558 TopTools_ListIteratorOfListOfShape LSI2(LS2);
4559 for(; LSI2.More(); LSI2.Next()) {
4560 if(aMap.Contains(LSI2.Value())) continue; //To avoid checking already found faces several times
4561 if(isSameFace(F, TopoDS::Face(LSI2.Value()))) {
4562 aMap.Add(LSI2.Value());
4567 if(!isFound) return false;
4573 //=======================================================================
4574 //function : GetSame
4576 //=======================================================================
4577 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetSame(const Handle(GEOM_Object)& theShapeWhere,
4578 const Handle(GEOM_Object)& theShapeWhat)
4581 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
4583 TopoDS_Shape aWhere = theShapeWhere->GetValue();
4584 TopoDS_Shape aWhat = theShapeWhat->GetValue();
4586 if (aWhere.IsNull() || aWhat.IsNull()) return NULL;
4589 bool isFound = false;
4590 TopoDS_Shape aSubShape;
4591 TopTools_MapOfShape aMap;
4593 if (aWhat.ShapeType() == TopAbs_COMPOUND || aWhat.ShapeType() == TopAbs_COMPSOLID) {
4594 TopoDS_Iterator It (aWhat, Standard_True, Standard_True);
4595 if (It.More()) aWhat = It.Value();
4598 SetErrorCode("Compounds of two or more shapes are not allowed for aWhat argument");
4603 switch (aWhat.ShapeType()) {
4604 case TopAbs_VERTEX: {
4605 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(aWhat));
4606 TopExp_Explorer E(aWhere, TopAbs_VERTEX);
4607 for(; E.More(); E.Next()) {
4608 if(!aMap.Add(E.Current())) continue;
4609 gp_Pnt P2 = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4610 if(P.Distance(P2) <= MAX_TOLERANCE) {
4612 aSubShape = E.Current();
4619 TopoDS_Edge anEdge = TopoDS::Edge(aWhat);
4620 TopExp_Explorer E(aWhere, TopAbs_EDGE);
4621 for(; E.More(); E.Next()) {
4622 if(!aMap.Add(E.Current())) continue;
4623 if(isSameEdge(anEdge, TopoDS::Edge(E.Current()))) {
4624 aSubShape = E.Current();
4632 TopoDS_Face aFace = TopoDS::Face(aWhat);
4633 TopExp_Explorer E(aWhere, TopAbs_FACE);
4634 for(; E.More(); E.Next()) {
4635 if(!aMap.Add(E.Current())) continue;
4636 if(isSameFace(aFace, TopoDS::Face(E.Current()))) {
4637 aSubShape = E.Current();
4644 case TopAbs_SOLID: {
4645 TopoDS_Solid aSolid = TopoDS::Solid(aWhat);
4646 TopExp_Explorer E(aWhere, TopAbs_SOLID);
4647 for(; E.More(); E.Next()) {
4648 if(!aMap.Add(E.Current())) continue;
4649 if(isSameSolid(aSolid, TopoDS::Solid(E.Current()))) {
4650 aSubShape = E.Current();
4662 TopTools_IndexedMapOfShape anIndices;
4663 TopExp::MapShapes(aWhere, anIndices);
4664 if (anIndices.Contains(aSubShape))
4665 anIndex = anIndices.FindIndex(aSubShape);
4668 if (anIndex < 0) return NULL;
4670 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
4672 anArray->SetValue(1, anIndex);
4674 Handle(GEOM_Object) aResult = GetEngine()->AddSubShape(theShapeWhere, anArray);
4675 Handle(GEOM_Function) aFunction = aResult->GetLastFunction();
4677 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetSame("
4678 << theShapeWhere << ", " << theShapeWhat << ")";
4686 //=======================================================================
4687 //function : GetSameIDs
4689 //=======================================================================
4690 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetSameIDs
4691 (const Handle(GEOM_Object)& theShapeWhere,
4692 const Handle(GEOM_Object)& theShapeWhat)
4695 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
4697 TopoDS_Shape aWhere = theShapeWhere->GetValue();
4698 TopoDS_Shape aWhat = theShapeWhat->GetValue();
4700 if (aWhere.IsNull() || aWhat.IsNull()) return NULL;
4702 TopTools_ListOfShape listShape;
4703 TopTools_MapOfShape aMap;
4705 if (aWhat.ShapeType() == TopAbs_COMPOUND || aWhat.ShapeType() == TopAbs_COMPSOLID) {
4706 TopoDS_Iterator It (aWhat, Standard_True, Standard_True);
4707 if (It.More()) aWhat = It.Value();
4710 SetErrorCode("Compounds of two or more shapes are not allowed for aWhat argument");
4715 switch (aWhat.ShapeType()) {
4716 case TopAbs_VERTEX: {
4717 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(aWhat));
4718 TopExp_Explorer E(aWhere, TopAbs_VERTEX);
4719 for(; E.More(); E.Next()) {
4720 if(!aMap.Add(E.Current())) continue;
4721 gp_Pnt P2 = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4722 if(P.Distance(P2) <= MAX_TOLERANCE) {
4723 listShape.Append(E.Current());
4729 TopoDS_Edge anEdge = TopoDS::Edge(aWhat);
4730 TopExp_Explorer E(aWhere, TopAbs_EDGE);
4731 for(; E.More(); E.Next()) {
4732 if(!aMap.Add(E.Current())) continue;
4733 if(isSameEdge(anEdge, TopoDS::Edge(E.Current()))) {
4734 listShape.Append(E.Current());
4740 TopoDS_Face aFace = TopoDS::Face(aWhat);
4741 TopExp_Explorer E(aWhere, TopAbs_FACE);
4742 for(; E.More(); E.Next()) {
4743 if(!aMap.Add(E.Current())) continue;
4744 if(isSameFace(aFace, TopoDS::Face(E.Current()))) {
4745 listShape.Append(E.Current());
4750 case TopAbs_SOLID: {
4751 TopoDS_Solid aSolid = TopoDS::Solid(aWhat);
4752 TopExp_Explorer E(aWhere, TopAbs_SOLID);
4753 for(; E.More(); E.Next()) {
4754 if(!aMap.Add(E.Current())) continue;
4755 if(isSameSolid(aSolid, TopoDS::Solid(E.Current()))) {
4756 listShape.Append(E.Current());
4765 if ( !listShape.IsEmpty() ) {
4766 TopTools_IndexedMapOfShape anIndices;
4767 TopExp::MapShapes(aWhere, anIndices);
4768 TopTools_ListIteratorOfListOfShape itSub (listShape);
4769 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
4770 for (; itSub.More(); itSub.Next()) {
4771 if (anIndices.Contains(itSub.Value()))
4772 aSeq->Append(anIndices.FindIndex(itSub.Value()));
4775 // The GetSameIDs() doesn't change object so no new function is required.
4776 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShapeWhere,theShapeWhat)->GetLastFunction();
4778 // Make a Python command
4779 GEOM::TPythonDump(aFunction, /*append=*/true)
4780 << "listSameIDs = geompy.GetSameIDs("
4781 << theShapeWhere << ", "
4782 << theShapeWhat << ")";
4785 SetErrorCode(NOT_FOUND_ANY);
4790 //=======================================================================
4791 //function : ExtendEdge
4793 //=======================================================================
4794 Handle(GEOM_Object) GEOMImpl_IShapesOperations::ExtendEdge
4795 (const Handle(GEOM_Object) &theEdge,
4796 const Standard_Real theMin,
4797 const Standard_Real theMax)
4801 if (theEdge.IsNull()) {
4805 //Add a new Edge object
4806 Handle(GEOM_Object) aResEdge = GetEngine()->AddObject(GetDocID(), GEOM_EDGE);
4808 //Add a new Vector function
4809 Handle(GEOM_Function) aFunction =
4810 aResEdge->AddFunction(GEOMImpl_ShapeDriver::GetID(), EDGE_UV);
4812 //Check if the function is set correctly
4813 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) {
4817 GEOMImpl_IShapeExtend aCI (aFunction);
4819 Handle(GEOM_Function) anEdge = theEdge->GetLastFunction();
4821 if (anEdge.IsNull()) {
4825 aCI.SetShape(anEdge);
4826 aCI.SetUMin(theMin);
4827 aCI.SetUMax(theMax);
4829 //Compute the Edge value
4832 if (!GetSolver()->ComputeFunction(aFunction)) {
4833 SetErrorCode("Shape driver failed");
4838 catch (Standard_Failure) {
4839 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
4840 SetErrorCode(aFail->GetMessageString());
4845 //Make a Python command
4846 GEOM::TPythonDump(aFunction)
4847 << aResEdge << " = geompy.ExtendEdge("
4848 << theEdge << ", " << theMin << ", " << theMax << ")";
4855 //=======================================================================
4856 //function : ExtendFace
4858 //=======================================================================
4859 Handle(GEOM_Object) GEOMImpl_IShapesOperations::ExtendFace
4860 (const Handle(GEOM_Object) &theFace,
4861 const Standard_Real theUMin,
4862 const Standard_Real theUMax,
4863 const Standard_Real theVMin,
4864 const Standard_Real theVMax)
4868 if (theFace.IsNull()) {
4872 //Add a new Face object
4873 Handle(GEOM_Object) aResFace = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
4875 //Add a new Vector function
4876 Handle(GEOM_Function) aFunction =
4877 aResFace->AddFunction(GEOMImpl_ShapeDriver::GetID(), FACE_UV);
4879 //Check if the function is set correctly
4880 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) {
4884 GEOMImpl_IShapeExtend aCI (aFunction);
4886 Handle(GEOM_Function) aFace = theFace->GetLastFunction();
4888 if (aFace.IsNull()) {
4892 aCI.SetShape(aFace);
4893 aCI.SetUMin(theUMin);
4894 aCI.SetUMax(theUMax);
4895 aCI.SetVMin(theVMin);
4896 aCI.SetVMax(theVMax);
4898 //Compute the Face value
4901 if (!GetSolver()->ComputeFunction(aFunction)) {
4902 SetErrorCode("Shape driver failed");
4907 catch (Standard_Failure) {
4908 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
4909 SetErrorCode(aFail->GetMessageString());
4914 //Make a Python command
4915 GEOM::TPythonDump(aFunction)
4916 << aResFace << " = geompy.ExtendFace("
4917 << theFace << ", " << theUMin << ", " << theUMax << ", "
4918 << theVMin << ", " << theVMax << ")";