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"
37 #include "GEOMImpl_FillingDriver.hxx"
39 #include "GEOMImpl_IVector.hxx"
40 #include "GEOMImpl_IShapes.hxx"
41 #include "GEOMImpl_IShapeExtend.hxx"
42 #include "GEOMImpl_IGlue.hxx"
43 #include "GEOMImpl_IFilling.hxx"
45 #include "GEOMImpl_Block6Explorer.hxx"
46 #include "GEOMImpl_IHealingOperations.hxx"
48 #include "GEOMImpl_Gen.hxx"
50 #include "GEOM_Function.hxx"
51 #include "GEOM_ISubShape.hxx"
52 #include "GEOM_PythonDump.hxx"
54 #include "GEOMUtils.hxx"
56 #include "GEOMAlgo_ClsfBox.hxx"
57 #include "GEOMAlgo_ClsfSolid.hxx"
58 #include "GEOMAlgo_FinderShapeOn1.hxx"
59 #include "GEOMAlgo_FinderShapeOnQuad.hxx"
60 #include "GEOMAlgo_FinderShapeOn2.hxx"
61 #include "GEOMAlgo_GetInPlace.hxx"
62 #include "GEOMAlgo_GetInPlaceAPI.hxx"
63 #include "GEOMAlgo_GlueDetector.hxx"
65 #include <utilities.h>
67 #include <BRepAdaptor_Curve.hxx>
68 #include <BRepAdaptor_Surface.hxx>
69 #include <BRepTools.hxx>
70 #include <BRep_Builder.hxx>
71 #include <BRep_Tool.hxx>
72 #include <GeomLib_Tool.hxx>
73 #include <Geom_CylindricalSurface.hxx>
74 #include <Geom_Plane.hxx>
75 #include <Geom_SphericalSurface.hxx>
76 #include <Geom_Surface.hxx>
77 #include <Precision.hxx>
78 #include <TColStd_HArray1OfInteger.hxx>
79 #include <TDF_Tool.hxx>
80 #include <TDataStd_Integer.hxx>
81 #include <TDataStd_ListIteratorOfListOfExtendedString.hxx>
83 #include <TopExp_Explorer.hxx>
84 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
85 #include <TopTools_IndexedMapOfShape.hxx>
86 #include <TopTools_ListIteratorOfListOfShape.hxx>
87 #include <TopTools_MapOfOrientedShape.hxx>
88 #include <TopTools_MapOfShape.hxx>
89 #include <TopTools_SequenceOfShape.hxx>
91 #include <TopoDS_Compound.hxx>
92 #include <TopoDS_Edge.hxx>
93 #include <TopoDS_Face.hxx>
94 #include <TopoDS_Iterator.hxx>
95 #include <TopoDS_Shape.hxx>
96 #include <TopoDS_Solid.hxx>
97 #include <TopoDS_Vertex.hxx>
98 #include <gp_Cylinder.hxx>
103 #include <Standard_Failure.hxx>
104 #include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
108 void AddFlatSubShapes(const TopoDS_Shape& S, TopTools_ListOfShape& L, TopTools_MapOfShape& M)
110 if (S.ShapeType() != TopAbs_COMPOUND) {
114 TopoDS_Iterator It(S, Standard_True, Standard_True);
115 for (; It.More(); It.Next()) {
116 TopoDS_Shape SS = It.Value();
118 AddFlatSubShapes(SS, L, M);
124 //=============================================================================
128 //=============================================================================
129 GEOMImpl_IShapesOperations::GEOMImpl_IShapesOperations (GEOM_Engine* theEngine, int theDocID)
130 : GEOM_IOperations(theEngine, theDocID)
132 MESSAGE("GEOMImpl_IShapesOperations::GEOMImpl_IShapesOperations");
135 //=============================================================================
139 //=============================================================================
140 GEOMImpl_IShapesOperations::~GEOMImpl_IShapesOperations()
142 MESSAGE("GEOMImpl_IShapesOperations::~GEOMImpl_IShapesOperations");
145 //=============================================================================
149 //=============================================================================
150 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeEdge
151 (Handle(GEOM_Object) thePnt1, Handle(GEOM_Object) thePnt2)
155 if (thePnt1.IsNull() || thePnt2.IsNull()) return NULL;
157 //Add a new Edge object
158 Handle(GEOM_Object) anEdge = GetEngine()->AddObject(GetDocID(), GEOM_EDGE);
160 //Add a new Vector function
161 Handle(GEOM_Function) aFunction =
162 anEdge->AddFunction(GEOMImpl_VectorDriver::GetID(), VECTOR_TWO_PNT);
164 //Check if the function is set correctly
165 if (aFunction->GetDriverGUID() != GEOMImpl_VectorDriver::GetID()) return NULL;
167 GEOMImpl_IVector aPI (aFunction);
169 Handle(GEOM_Function) aRef1 = thePnt1->GetLastFunction();
170 Handle(GEOM_Function) aRef2 = thePnt2->GetLastFunction();
171 if (aRef1.IsNull() || aRef2.IsNull()) return NULL;
173 aPI.SetPoint1(aRef1);
174 aPI.SetPoint2(aRef2);
176 //Compute the Edge value
179 if (!GetSolver()->ComputeFunction(aFunction)) {
180 SetErrorCode("Vector driver failed");
184 catch (Standard_Failure) {
185 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
186 SetErrorCode(aFail->GetMessageString());
190 //Make a Python command
191 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdge("
192 << thePnt1 << ", " << thePnt2 << ")";
198 //=============================================================================
200 * MakeEdgeOnCurveByLength
202 //=============================================================================
203 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeEdgeOnCurveByLength
204 (Handle(GEOM_Object) theRefCurve,
205 const Standard_Real theLength,
206 Handle(GEOM_Object) theStartPoint)
210 if (theRefCurve.IsNull()) return NULL;
212 //Add a new Edge object
213 Handle(GEOM_Object) anEdge = GetEngine()->AddObject(GetDocID(), GEOM_EDGE);
215 //Add a new Vector function
216 Handle(GEOM_Function) aFunction =
217 anEdge->AddFunction(GEOMImpl_ShapeDriver::GetID(), EDGE_CURVE_LENGTH);
219 //Check if the function is set correctly
220 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
222 GEOMImpl_IVector aPI (aFunction);
224 Handle(GEOM_Function) aRef1 = theRefCurve->GetLastFunction();
225 if (aRef1.IsNull()) return NULL;
226 aPI.SetPoint1(aRef1);
228 if (!theStartPoint.IsNull()) {
229 Handle(GEOM_Function) aRef2 = theStartPoint->GetLastFunction();
230 aPI.SetPoint2(aRef2);
233 aPI.SetParameter(theLength);
235 //Compute the Edge value
238 if (!GetSolver()->ComputeFunction(aFunction)) {
239 SetErrorCode("Vector driver failed");
243 catch (Standard_Failure) {
244 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
245 SetErrorCode(aFail->GetMessageString());
249 //Make a Python command
250 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdgeOnCurveByLength("
251 << theRefCurve << ", " << theLength << ", " << theStartPoint << ")";
257 //=============================================================================
261 //=============================================================================
262 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeEdgeWire
263 (Handle(GEOM_Object) theWire,
264 const Standard_Real theLinearTolerance,
265 const Standard_Real theAngularTolerance)
269 if (theWire.IsNull()) return NULL;
271 //Add a new Edge object
272 Handle(GEOM_Object) anEdge = GetEngine()->AddObject(GetDocID(), GEOM_EDGE);
274 //Add a new Vector function
275 Handle(GEOM_Function) aFunction =
276 anEdge->AddFunction(GEOMImpl_ShapeDriver::GetID(), EDGE_WIRE);
278 //Check if the function is set correctly
279 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
281 GEOMImpl_IShapes aCI (aFunction);
283 Handle(GEOM_Function) aWire = theWire->GetLastFunction();
285 if (aWire.IsNull()) return NULL;
288 aCI.SetTolerance(theLinearTolerance);
289 aCI.SetAngularTolerance(theAngularTolerance);
291 //Compute the Edge value
294 if (!GetSolver()->ComputeFunction(aFunction)) {
295 SetErrorCode("Shape driver failed");
299 catch (Standard_Failure) {
300 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
301 SetErrorCode(aFail->GetMessageString());
305 const double DEF_LIN_TOL = Precision::Confusion();
306 const double DEF_ANG_TOL = Precision::Angular();
307 //Make a Python command
308 if ( theAngularTolerance == DEF_ANG_TOL ) {
309 if ( theLinearTolerance == DEF_LIN_TOL )
310 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdgeWire("
313 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdgeWire("
314 << theWire << ", " << theLinearTolerance << ")";
317 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdgeWire("
318 << theWire << ", " << theLinearTolerance << ", "
319 << theAngularTolerance << ")";
326 //=============================================================================
330 //=============================================================================
331 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeWire
332 (std::list<Handle(GEOM_Object)> theShapes,
333 const Standard_Real theTolerance)
338 Handle(GEOM_Object) aWire = GetEngine()->AddObject(GetDocID(), GEOM_WIRE);
341 Handle(GEOM_Function) aFunction =
342 aWire->AddFunction(GEOMImpl_ShapeDriver::GetID(), WIRE_EDGES);
343 if (aFunction.IsNull()) return NULL;
345 //Check if the function is set correctly
346 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
348 GEOMImpl_IShapes aCI (aFunction);
349 aCI.SetTolerance(theTolerance);
351 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
354 std::list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
355 for (; it != theShapes.end(); it++) {
356 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
357 if (aRefSh.IsNull()) {
358 SetErrorCode("NULL argument shape for the shape construction");
361 aShapesSeq->Append(aRefSh);
363 aCI.SetShapes(aShapesSeq);
368 if (!GetSolver()->ComputeFunction(aFunction)) {
369 SetErrorCode("Shape driver failed");
373 catch (Standard_Failure) {
374 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
375 SetErrorCode(aFail->GetMessageString());
379 //Make a Python command
380 GEOM::TPythonDump pd (aFunction);
381 pd << aWire << " = geompy.MakeWire([";
384 it = theShapes.begin();
385 if (it != theShapes.end()) {
387 while (it != theShapes.end()) {
388 pd << ", " << (*it++);
391 pd << "], " << theTolerance << ")";
397 //=============================================================================
401 //=============================================================================
402 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFace (Handle(GEOM_Object) theWire,
403 const bool isPlanarWanted)
407 if (theWire.IsNull()) return NULL;
409 //Add a new Face object
410 Handle(GEOM_Object) aFace = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
412 //Add a new Shape function for creation of a face from a wire
413 Handle(GEOM_Function) aFunction =
414 aFace->AddFunction(GEOMImpl_ShapeDriver::GetID(), FACE_WIRE);
415 if (aFunction.IsNull()) return NULL;
417 //Check if the function is set correctly
418 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
420 GEOMImpl_IShapes aCI (aFunction);
422 Handle(GEOM_Function) aRefWire = theWire->GetLastFunction();
424 if (aRefWire.IsNull()) return NULL;
426 aCI.SetBase(aRefWire);
427 aCI.SetIsPlanar(isPlanarWanted);
429 //Compute the Face value
430 Standard_Boolean isWarning = Standard_False;
433 if (!GetSolver()->ComputeFunction(aFunction)) {
434 SetErrorCode("Shape driver failed to compute a face");
438 catch (Standard_Failure) {
439 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
440 SetErrorCode(aFail->GetMessageString());
441 // to provide warning
442 if (!aFunction->GetValue().IsNull()) {
443 isWarning = Standard_True;
449 //Make a Python command
450 GEOM::TPythonDump(aFunction) << aFace << " = geompy.MakeFace("
451 << theWire << ", " << (int)isPlanarWanted << ")";
453 // to provide warning
454 if (!isWarning) SetErrorCode(OK);
458 //=============================================================================
462 //=============================================================================
463 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFaceWires
464 (std::list<Handle(GEOM_Object)> theShapes,
465 const bool isPlanarWanted)
470 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
473 Handle(GEOM_Function) aFunction =
474 aShape->AddFunction(GEOMImpl_ShapeDriver::GetID(), FACE_WIRES);
475 if (aFunction.IsNull()) return NULL;
477 //Check if the function is set correctly
478 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
480 GEOMImpl_IShapes aCI (aFunction);
482 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
485 std::list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
486 for (; it != theShapes.end(); it++) {
487 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
488 if (aRefSh.IsNull()) {
489 SetErrorCode("NULL argument shape for the face construction");
492 aShapesSeq->Append(aRefSh);
494 aCI.SetShapes(aShapesSeq);
496 aCI.SetIsPlanar(isPlanarWanted);
499 Standard_Boolean isWarning = Standard_False;
502 if (!GetSolver()->ComputeFunction(aFunction)) {
503 SetErrorCode("Shape driver failed");
507 catch (Standard_Failure) {
508 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
509 SetErrorCode(aFail->GetMessageString());
510 // to provide warning
511 if (!aFunction->GetValue().IsNull()) {
512 isWarning = Standard_True;
518 //Make a Python command
519 GEOM::TPythonDump pd (aFunction);
520 pd << aShape << " = geompy.MakeFaceWires([";
523 it = theShapes.begin();
524 if (it != theShapes.end()) {
526 while (it != theShapes.end()) {
527 pd << ", " << (*it++);
530 pd << "], " << (int)isPlanarWanted << ")";
532 // to provide warning
533 if (!isWarning) SetErrorCode(OK);
537 //=============================================================================
539 * MakeFaceFromSurface
541 //=============================================================================
542 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFaceFromSurface
543 (Handle(GEOM_Object) theFace,
544 Handle(GEOM_Object) theWire)
549 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
552 Handle(GEOM_Function) aFunction =
553 aShape->AddFunction(GEOMImpl_ShapeDriver::GetID(), FACE_FROM_SURFACE);
555 if (aFunction.IsNull()) {
559 //Check if the function is set correctly
560 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) {
564 GEOMImpl_IShapes aCI (aFunction);
565 Handle(TColStd_HSequenceOfTransient) aShapesSeq =
566 new TColStd_HSequenceOfTransient;
567 Handle(GEOM_Function) aRefFace = theFace->GetLastFunction();
568 Handle(GEOM_Function) aRefWire = theWire->GetLastFunction();
570 if (aRefFace.IsNull()) {
571 SetErrorCode("NULL argument face for the face construction");
575 if (aRefWire.IsNull()) {
576 SetErrorCode("NULL argument wire for the face construction");
580 aShapesSeq->Append(aRefFace);
581 aShapesSeq->Append(aRefWire);
583 aCI.SetShapes(aShapesSeq);
588 if (!GetSolver()->ComputeFunction(aFunction)) {
589 SetErrorCode("Shape driver failed");
593 catch (Standard_Failure) {
594 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
595 SetErrorCode(aFail->GetMessageString());
599 //Make a Python command
600 GEOM::TPythonDump (aFunction) << aShape
601 << " = geompy.MakeFaceFromSurface(" << theFace << ", " << theWire << ")";
608 //=============================================================================
610 * MakeFaceWithConstraints
612 //=============================================================================
613 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFaceWithConstraints
614 (std::list<Handle(GEOM_Object)> theConstraints)
619 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_FILLING);
622 Handle(GEOM_Function) aFunction =
623 aShape->AddFunction(GEOMImpl_FillingDriver::GetID(), FILLING_ON_CONSTRAINTS);
624 if (aFunction.IsNull()) return NULL;
626 //Check if the function is set correctly
627 if (aFunction->GetDriverGUID() != GEOMImpl_FillingDriver::GetID()) return NULL;
629 GEOMImpl_IFilling aCI (aFunction);
630 Handle(TColStd_HSequenceOfTransient) aConstraints = new TColStd_HSequenceOfTransient;
633 std::list<Handle(GEOM_Object)>::iterator it = theConstraints.begin();
634 while (it != theConstraints.end()) {
635 Handle(GEOM_Object) anObject = (*it);
636 if ( anObject.IsNull() || anObject->GetValue().ShapeType() != TopAbs_EDGE ) {
637 SetErrorCode("NULL argument edge for the face construction");
640 Handle(GEOM_Function) aRefSh = anObject->GetLastFunction();
641 aConstraints->Append(aRefSh);
643 if ( it != theConstraints.end() ) {
644 Handle(GEOM_Object) aFace = (*it);
645 if ( aFace.IsNull() ) {
646 // null constraint face - it is a valid case
650 if ( aFace->GetValue().ShapeType() != TopAbs_FACE )
651 // constraint face can be omitted - it is a valid case
653 if ( IsSubShapeBelongsTo( anObject, 0, aFace, 0 ) ) {
655 aRefSh = aFace->GetLastFunction();
656 aConstraints->Append(aRefSh);
661 SetErrorCode("Face is NULL or not connected to the Edge");
666 aCI.SetShapes( aConstraints );
669 Standard_Boolean isWarning = Standard_False;
672 if (!GetSolver()->ComputeFunction(aFunction)) {
673 SetErrorCode("Shape driver failed");
677 catch (Standard_Failure) {
678 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
679 SetErrorCode(aFail->GetMessageString());
680 // to provide warning
681 if (!aFunction->GetValue().IsNull()) {
682 isWarning = Standard_True;
688 //Make a Python command
689 GEOM::TPythonDump pd (aFunction);
690 pd << aShape << " = geompy.MakeFaceWithConstraints([";
693 it = theConstraints.begin();
694 if (it != theConstraints.end() ) {
696 while (it != theConstraints.end()) {
697 Handle(GEOM_Object) anObject = (*it++);
698 if( !anObject.IsNull() )
699 pd << ", " << anObject;
704 // to provide warning
705 if (!isWarning) SetErrorCode(OK);
709 //=============================================================================
713 //=============================================================================
714 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeShell
715 (std::list<Handle(GEOM_Object)> theShapes)
717 return MakeShape(theShapes, GEOM_SHELL, SHELL_FACES, "MakeShell");
720 //=============================================================================
724 //=============================================================================
725 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeSolidShells
726 (std::list<Handle(GEOM_Object)> theShapes)
728 return MakeShape(theShapes, GEOM_SOLID, SOLID_SHELLS, "MakeSolid");
731 //=============================================================================
735 //=============================================================================
736 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeCompound
737 (std::list<Handle(GEOM_Object)> theShapes)
739 return MakeShape(theShapes, GEOM_COMPOUND, COMPOUND_SHAPES, "MakeCompound");
742 //=============================================================================
746 //=============================================================================
747 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeShape
748 (std::list<Handle(GEOM_Object)> theShapes,
749 const Standard_Integer theObjectType,
750 const Standard_Integer theFunctionType,
751 const TCollection_AsciiString& theMethodName)
756 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), theObjectType);
759 Handle(GEOM_Function) aFunction =
760 aShape->AddFunction(GEOMImpl_ShapeDriver::GetID(), theFunctionType);
761 if (aFunction.IsNull()) return NULL;
763 //Check if the function is set correctly
764 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
766 GEOMImpl_IShapes aCI (aFunction);
768 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
771 std::list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
772 for (; it != theShapes.end(); it++) {
773 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
774 if (aRefSh.IsNull()) {
775 SetErrorCode("NULL argument shape for the shape construction");
778 aShapesSeq->Append(aRefSh);
780 aCI.SetShapes(aShapesSeq);
785 if (!GetSolver()->ComputeFunction(aFunction)) {
786 SetErrorCode("Shape driver failed");
790 catch (Standard_Failure) {
791 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
792 SetErrorCode(aFail->GetMessageString());
796 //Make a Python command
797 GEOM::TPythonDump pd (aFunction);
798 pd << aShape << " = geompy." << theMethodName.ToCString() << "([";
801 it = theShapes.begin();
802 if (it != theShapes.end()) {
804 while (it != theShapes.end()) {
805 pd << ", " << (*it++);
814 //=============================================================================
816 * MakeSolidFromConnectedFaces
818 //=============================================================================
819 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeSolidFromConnectedFaces
820 (std::list<Handle(GEOM_Object)> theFacesOrShells,
821 const Standard_Boolean isIntersect)
826 Handle(GEOM_Object) aSolid = GetEngine()->AddObject(GetDocID(), GEOM_SOLID);
829 Handle(GEOM_Function) aFunction =
830 aSolid->AddFunction(GEOMImpl_ShapeDriver::GetID(), SOLID_FACES);
831 if (aFunction.IsNull()) return NULL;
833 //Check if the function is set correctly
834 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
836 GEOMImpl_IShapes aCI (aFunction);
838 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
841 std::list<Handle(GEOM_Object)>::iterator it = theFacesOrShells.begin();
842 for (; it != theFacesOrShells.end(); it++) {
843 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
844 if (aRefSh.IsNull()) {
845 SetErrorCode("NULL argument shape for the shape construction");
848 aShapesSeq->Append(aRefSh);
850 aCI.SetShapes(aShapesSeq);
851 aCI.SetIsIntersect(isIntersect);
856 if (!GetSolver()->ComputeFunction(aFunction)) {
857 SetErrorCode("Shape driver failed");
861 catch (Standard_Failure) {
862 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
863 SetErrorCode(aFail->GetMessageString());
867 //Make a Python command
868 GEOM::TPythonDump pd (aFunction);
869 pd << aSolid << " = geompy.MakeSolidFromConnectedFaces([";
872 it = theFacesOrShells.begin();
873 if (it != theFacesOrShells.end()) {
875 while (it != theFacesOrShells.end()) {
876 pd << ", " << (*it++);
879 pd << "]," << (isIntersect ? "True" : "False") << ")";
885 //=============================================================================
889 //=============================================================================
891 GEOMImpl_IShapesOperations::MakeGlueFaces (std::list< Handle(GEOM_Object) >& theShapes,
892 const Standard_Real theTolerance,
893 const Standard_Boolean doKeepNonSolids)
897 Handle(TColStd_HSequenceOfTransient) objects = GEOM_Object::GetLastFunctions( theShapes );
898 if ( objects.IsNull() || objects->IsEmpty() ) {
899 SetErrorCode("NULL argument shape");
903 //Add a new Glued object
904 Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
906 //Add a new Glue function
907 Handle(GEOM_Function) aFunction;
908 aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_FACES);
909 if (aFunction.IsNull()) return NULL;
911 //Check if the function is set correctly
912 if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
914 GEOMImpl_IGlue aCI (aFunction);
916 aCI.SetBase( objects );
917 aCI.SetTolerance(theTolerance);
918 aCI.SetKeepNonSolids(doKeepNonSolids);
920 //Compute the sub-shape value
921 Standard_Boolean isWarning = Standard_False;
924 if (!GetSolver()->ComputeFunction(aFunction)) {
925 SetErrorCode("Shape driver failed to glue faces");
929 catch (Standard_Failure) {
930 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
931 SetErrorCode(aFail->GetMessageString());
932 // to provide warning
933 if (!aFunction->GetValue().IsNull()) {
934 isWarning = Standard_True;
940 //Make a Python command
941 GEOM::TPythonDump(aFunction) << aGlued << " = geompy.MakeGlueFaces("
942 << theShapes << ", " << theTolerance << ")";
944 // to provide warning
945 if (!isWarning) SetErrorCode(OK);
949 //=============================================================================
953 //=============================================================================
955 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetGlueFaces
956 (Handle(GEOM_Object) theShape,
957 const Standard_Real theTolerance)
961 if (theShape.IsNull()) return NULL;
962 TopoDS_Shape aShape = theShape->GetValue();
963 if (aShape.IsNull()) return NULL;
965 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
967 Standard_Integer iErr;
969 GEOMAlgo_Gluer1 aGluer;
970 GEOMAlgo_ListIteratorOfListOfCoupleOfShapes aItCS;
971 GEOMAlgo_CoupleOfShapes aCS;
972 GEOMAlgo_ListOfCoupleOfShapes aLCS;
974 //aGluer = new GEOMAlgo_Gluer1;
975 aGluer.SetShape(aShape);
976 aGluer.SetTolerance(theTolerance);
978 iErr = aGluer.ErrorStatus();
979 if (iErr) return NULL;
981 TopTools_ListOfShape listShape;
982 const GEOMAlgo_ListOfCoupleOfShapes& aLCSG = aGluer.GluedFaces();
984 aItCS.Initialize(aLCSG);
985 for (; aItCS.More(); aItCS.Next()) {
986 const GEOMAlgo_CoupleOfShapes& aCSG = aItCS.Value();
987 listShape.Append(aCSG.Shape1());
990 TopTools_ListIteratorOfListOfShape itSub (listShape);
991 TCollection_AsciiString anAsciiList, anEntry;
992 TopTools_IndexedMapOfShape anIndices;
993 TopExp::MapShapes(aShape, anIndices);
994 Handle(TColStd_HArray1OfInteger) anArray;
995 Handle(GEOM_Object) anObj;
996 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
997 TopoDS_Shape aValue = itSub.Value();
998 anArray = new TColStd_HArray1OfInteger(1,1);
999 anArray->SetValue(1, anIndices.FindIndex(aValue));
1000 anObj = GetEngine()->AddSubShape(theShape, anArray);
1001 if (!anObj.IsNull()) {
1002 aSeq->Append(anObj);
1004 // for python command
1005 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
1006 anAsciiList += anEntry;
1011 //Make a Python command
1012 if( anAsciiList.Length() > 0 ) {
1013 anAsciiList.Trunc(anAsciiList.Length() - 1);
1014 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
1015 GEOM::TPythonDump pd (aFunction, true);
1016 pd << "[" << anAsciiList.ToCString();
1017 pd << "] = geompy.GetGlueFaces(" << theShape << ", " << theTolerance << ")";
1026 //=============================================================================
1028 * MakeGlueFacesByList
1030 //=============================================================================
1032 GEOMImpl_IShapesOperations::MakeGlueFacesByList(std::list< Handle(GEOM_Object) >& theShapes,
1033 const Standard_Real theTolerance,
1034 std::list<Handle(GEOM_Object)> & theFaces,
1035 const Standard_Boolean doKeepNonSolids,
1036 const Standard_Boolean doGlueAllEdges)
1040 Handle(TColStd_HSequenceOfTransient) objects = GEOM_Object::GetLastFunctions( theShapes );
1041 if ( objects.IsNull() || objects->IsEmpty() ) {
1042 SetErrorCode("NULL argument shape");
1045 Handle(TColStd_HSequenceOfTransient) aFaces = GEOM_Object::GetLastFunctions( theFaces );
1046 if ( aFaces.IsNull() ) {
1047 SetErrorCode("NULL argument shape for the shape construction");
1051 //Add a new Glued object
1052 Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
1054 //Add a new Glue function
1055 Handle(GEOM_Function) aFunction;
1056 aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_FACES_BY_LIST);
1057 if (aFunction.IsNull()) return NULL;
1059 //Check if the function is set correctly
1060 if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
1062 GEOMImpl_IGlue aCI (aFunction);
1064 aCI.SetBase( objects );
1065 aCI.SetTolerance(theTolerance);
1066 aCI.SetKeepNonSolids(doKeepNonSolids);
1067 aCI.SetGlueAllEdges(doGlueAllEdges);
1068 aCI.SetFaces(aFaces);
1070 //Compute the sub-shape value
1071 Standard_Boolean isWarning = Standard_False;
1074 if (!GetSolver()->ComputeFunction(aFunction)) {
1075 SetErrorCode("Shape driver failed to glue faces");
1079 catch (Standard_Failure) {
1080 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1081 SetErrorCode(aFail->GetMessageString());
1082 // to provide warning
1083 if (!aFunction->GetValue().IsNull()) {
1084 isWarning = Standard_True;
1090 //Make a Python command
1092 GEOM::TPythonDump pd(aFunction);
1093 pd << aGlued << " = geompy.MakeGlueFacesByList("
1094 << theShapes << ", " << theTolerance << ", " << theFaces << ", "
1095 << (bool)doKeepNonSolids << ", " << (bool)doGlueAllEdges << ")";
1097 // to provide warning
1098 if (!isWarning) SetErrorCode(OK);
1102 //=============================================================================
1106 //=============================================================================
1108 GEOMImpl_IShapesOperations::MakeGlueEdges (std::list< Handle(GEOM_Object) >& theShapes,
1109 const Standard_Real theTolerance)
1113 Handle(TColStd_HSequenceOfTransient) objects = GEOM_Object::GetLastFunctions( theShapes );
1114 if ( objects.IsNull() || objects->IsEmpty() ) {
1115 SetErrorCode("NULL argument shape");
1119 //Add a new Glued object
1120 Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
1122 //Add a new Glue function
1123 Handle(GEOM_Function) aFunction;
1124 aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_EDGES);
1125 if (aFunction.IsNull()) return NULL;
1127 //Check if the function is set correctly
1128 if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
1130 GEOMImpl_IGlue aCI (aFunction);
1132 aCI.SetBase( objects );
1133 aCI.SetTolerance(theTolerance);
1134 aCI.SetKeepNonSolids(true);
1136 //Compute the sub-shape value
1137 Standard_Boolean isWarning = Standard_False;
1140 if (!GetSolver()->ComputeFunction(aFunction)) {
1141 SetErrorCode("Shape driver failed to glue edges");
1145 catch (Standard_Failure) {
1146 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1147 SetErrorCode(aFail->GetMessageString());
1148 // to provide warning
1149 if (!aFunction->GetValue().IsNull()) {
1150 isWarning = Standard_True;
1156 //Make a Python command
1157 GEOM::TPythonDump(aFunction) << aGlued << " = geompy.MakeGlueEdges("
1158 << theShapes << ", " << theTolerance << ")";
1160 // to provide warning
1161 if (!isWarning) SetErrorCode(OK);
1165 //=============================================================================
1169 //=============================================================================
1170 Handle(TColStd_HSequenceOfTransient)
1171 GEOMImpl_IShapesOperations::GetGlueShapes (std::list< Handle(GEOM_Object) >& theShapes,
1172 const Standard_Real theTolerance,
1173 const TopAbs_ShapeEnum theType)
1177 TopoDS_Shape aShape;
1178 TopTools_SequenceOfShape shapes;
1179 std::list< Handle(GEOM_Object) >::iterator s = theShapes.begin();
1180 Handle(GEOM_Object) lastCreatedGO;
1181 for ( ; s != theShapes.end(); ++s )
1183 Handle(GEOM_Object) go = *s;
1184 if ( go.IsNull() ) return NULL;
1185 aShape = go->GetValue();
1186 if ( aShape.IsNull() ) return NULL;
1187 shapes.Append( aShape );
1188 lastCreatedGO = GEOM::GetCreatedLast( lastCreatedGO, go );
1190 if ( shapes.Length() > 1 )
1192 TopoDS_Compound compound;
1193 BRep_Builder builder;
1194 builder.MakeCompound( compound );
1195 for ( int i = 1; i <= shapes.Length(); ++i )
1196 builder.Add( compound, shapes( i ) );
1201 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1203 GEOMAlgo_GlueDetector aGluer;
1204 aGluer.SetArgument(aShape);
1205 aGluer.SetTolerance(theTolerance);
1207 Standard_Integer iErr = aGluer.ErrorStatus();
1208 if (iErr) return NULL;
1210 std::vector< TopTools_IndexedMapOfShape* > anIndices( shapes.Length(), NULL );
1211 Handle(TColStd_HArray1OfInteger) anArray;
1212 Handle(GEOM_Object) anObj;
1214 TopTools_ListOfShape listOnePerSet;
1216 const TopTools_DataMapOfShapeListOfShape& aImages = aGluer.Images();
1217 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape aItDMSLS (aImages);
1218 for (int index = 1; aItDMSLS.More(); aItDMSLS.Next(), ++index) {
1220 //const TopoDS_Shape& aSkey = aItDMSLS.Key();
1222 // list of shapes of the argument that can be glued
1223 const TopTools_ListOfShape& aLSD = aItDMSLS.Value();
1225 //listShape.Append(aLSD.First());
1226 TopoDS_Shape aValue = aLSD.First();
1228 if (aValue.ShapeType() == theType) {
1229 listOnePerSet.Append(aValue);
1233 // for stable order of returned entities
1234 GEOMUtils::SortShapes(listOnePerSet, Standard_False);
1236 TopTools_ListIteratorOfListOfShape aListIt (listOnePerSet);
1237 for (; aListIt.More(); aListIt.Next())
1239 TopoDS_Shape aValue = aListIt.Value();
1240 // find a shape to add aValue as a sub-shape
1242 s = theShapes.begin();
1243 for ( int i = 0; i < shapes.Length(); ++i, ++s )
1245 Handle(GEOM_Object) object = *s;
1246 if ( !anIndices[i] ) {
1247 anIndices[i] = new TopTools_IndexedMapOfShape;
1248 TopExp::MapShapes( object->GetValue(), *anIndices[i]);
1250 if (int index = anIndices[i]->FindIndex( aValue )) {
1251 anArray = new TColStd_HArray1OfInteger(1,1);
1252 anArray->SetValue(1, index);
1253 anObj = GetEngine()->AddSubShape( object, anArray);
1257 if (!anObj.IsNull())
1258 aSeq->Append(anObj);
1260 for ( size_t i = 0 ; i < anIndices.size(); ++i )
1261 delete anIndices[i];
1263 // Make a Python command
1264 if ( aSeq->Length() > 0)
1266 Handle(GEOM_Function) aFunction = lastCreatedGO->GetLastFunction();
1267 GEOM::TPythonDump pd (aFunction, /*append=*/true);
1269 << " = geompy." << (theType == TopAbs_FACE ? "GetGlueFaces" : "GetGlueEdges" )
1270 << "( " << theShapes << ", " << theTolerance << ")";
1278 //=============================================================================
1280 * MakeGlueEdgesByList
1282 //=============================================================================
1284 GEOMImpl_IShapesOperations::MakeGlueEdgesByList (std::list< Handle(GEOM_Object) >& theShapes,
1285 const Standard_Real theTolerance,
1286 std::list<Handle(GEOM_Object)>& theEdges)
1290 Handle(TColStd_HSequenceOfTransient) objects = GEOM_Object::GetLastFunctions( theShapes );
1291 if ( objects.IsNull() || objects->IsEmpty() ) {
1292 SetErrorCode("NULL argument shape");
1295 Handle(TColStd_HSequenceOfTransient) anEdges = GEOM_Object::GetLastFunctions( theEdges );
1296 if ( anEdges.IsNull() ) {
1297 SetErrorCode("NULL argument shape for the shape construction");
1300 //Add a new Glued object
1301 Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
1303 //Add a new Glue function
1304 Handle(GEOM_Function) aFunction;
1305 aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_EDGES_BY_LIST);
1306 if (aFunction.IsNull()) return NULL;
1308 //Check if the function is set correctly
1309 if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
1311 GEOMImpl_IGlue aCI (aFunction);
1313 aCI.SetBase( objects );
1314 aCI.SetTolerance(theTolerance);
1315 aCI.SetKeepNonSolids(true);
1316 aCI.SetFaces(anEdges);
1318 //Compute the sub-shape value
1319 Standard_Boolean isWarning = Standard_False;
1322 if (!GetSolver()->ComputeFunction(aFunction)) {
1323 SetErrorCode("Shape driver failed to glue edges");
1327 catch (Standard_Failure) {
1328 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1329 SetErrorCode(aFail->GetMessageString());
1330 // to provide warning
1331 if (!aFunction->GetValue().IsNull()) {
1332 isWarning = Standard_True;
1338 //Make a Python command
1340 GEOM::TPythonDump pd (aFunction);
1341 pd << aGlued << " = geompy.MakeGlueEdgesByList("
1342 << theShapes << ", " << theTolerance << ", " << theEdges << " )";
1344 // to provide warning
1345 if (!isWarning) SetErrorCode(OK);
1349 //=============================================================================
1351 * GetExistingSubObjects
1353 //=============================================================================
1354 Handle(TColStd_HSequenceOfTransient)
1355 GEOMImpl_IShapesOperations::GetExistingSubObjects(Handle(GEOM_Object) theShape,
1356 const Standard_Boolean theGroupsOnly)
1358 // note: this method does not return fields
1360 Standard_Integer types = theGroupsOnly ? Groups : Groups|SubShapes;
1361 Handle(TColStd_HSequenceOfTransient) results = GetExistingSubObjects(theShape, types);
1363 if (results->Length() > 0) {
1364 //Make a Python command
1365 TCollection_AsciiString anAsciiList;
1366 for (int i = 1; i <= results->Length(); i++)
1368 Handle(GEOM_BaseObject) obj = Handle(GEOM_BaseObject)::DownCast( results->Value(i));
1369 obj->GetEntryString();
1370 if ( i < results->Length() )
1374 GEOM::TPythonDump pd (theShape->GetLastFunction(), /*append=*/true);
1375 pd << "[" << anAsciiList.ToCString();
1376 pd << "] = geompy.GetExistingSubObjects(";
1377 pd << theShape << ", " << (bool)theGroupsOnly << ")";
1383 Handle(TColStd_HSequenceOfTransient)
1384 GEOMImpl_IShapesOperations::GetExistingSubObjects(Handle(GEOM_Object) theShape,
1385 const Standard_Integer theTypes)
1389 if (theShape.IsNull()) return NULL;
1391 Handle(GEOM_Function) aMainShape = theShape->GetLastFunction();
1392 if (aMainShape.IsNull()) return NULL;
1394 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1395 SetErrorCode(NOT_FOUND_ANY);
1397 if (!aMainShape->HasSubShapeReferences()) return aSeq;
1398 const TDataStd_ListOfExtendedString& aListEntries = aMainShape->GetSubShapeReferences();
1399 if (aListEntries.IsEmpty()) return aSeq;
1403 TDataStd_ListIteratorOfListOfExtendedString anIt (aListEntries);
1404 for (; anIt.More(); anIt.Next()) {
1405 TCollection_ExtendedString anEntry = anIt.Value();
1406 Standard_Integer aStrLen = anEntry.LengthOfCString();
1407 char* anEntryStr = new char[aStrLen+1];
1408 anEntry.ToUTF8CString(anEntryStr);
1409 Handle(GEOM_BaseObject) anObj = GetEngine()->GetObject(GetDocID(), anEntryStr, false);
1410 if (!anObj.IsNull() ) {
1411 bool isGroup = anObj->IsKind(STANDARD_TYPE(GEOM_Object)) && anObj->GetType() == GEOM_GROUP;
1412 bool isSubShape = anObj->IsKind(STANDARD_TYPE(GEOM_Object)) && anObj->GetType() != GEOM_GROUP;
1413 bool isField = anObj->IsKind(STANDARD_TYPE(GEOM_Field));
1414 if (theTypes & Groups && isGroup ||
1415 theTypes & SubShapes && isSubShape ||
1416 theTypes & Fields && isField) {
1417 aSeq->Append(anObj);
1420 delete [] anEntryStr;
1423 if (aSeq->Length() == 0) {
1424 SetErrorCode(NOT_FOUND_ANY);
1433 //=============================================================================
1437 //=============================================================================
1438 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::MakeExplode
1439 (Handle(GEOM_Object) theShape,
1440 const Standard_Integer theShapeType,
1441 const Standard_Boolean isSorted,
1442 const ExplodeType theExplodeType)
1446 if (theShape.IsNull()) return NULL;
1447 TopoDS_Shape aShape = theShape->GetValue();
1448 if (aShape.IsNull()) return NULL;
1450 Handle(GEOM_Function) aMainShape = theShape->GetLastFunction();
1452 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1453 Handle(GEOM_Object) anObj;
1454 TopTools_MapOfShape mapShape;
1455 TopTools_ListOfShape listShape;
1457 if (aShape.ShapeType() == TopAbs_COMPOUND &&
1458 (theShapeType == TopAbs_SHAPE || theShapeType == TopAbs_FLAT || theShapeType == TopAbs_COMPOUND))
1460 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
1461 for (; It.More(); It.Next()) {
1462 TopoDS_Shape SS = It.Value();
1463 if (mapShape.Add(SS)) {
1464 if (theShapeType == TopAbs_FLAT) {
1465 AddFlatSubShapes(SS, listShape, mapShape);
1467 else if (theShapeType == TopAbs_SHAPE || theShapeType == SS.ShapeType()) {
1468 listShape.Append(SS);
1470 // VSR: for EXPLODE_NEW_INCLUDE_MAIN and EXPLODE_OLD_INCLUDE_MAIN:
1471 // it seems it is necessary to add top-level shape if theShapeType == TopAbs_COMPOUND
1475 else if (theExplodeType != EXPLODE_NEW_EXCLUDE_MAIN || aShape.ShapeType() != theShapeType) // issue 0021079
1477 TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
1478 for (; exp.More(); exp.Next())
1479 if (mapShape.Add(exp.Current()))
1480 listShape.Append(exp.Current());
1483 if (listShape.IsEmpty()){
1484 //SetErrorCode("The given shape has no sub-shapes of the requested type");
1485 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
1490 bool isOldSorting = false;
1491 if (theExplodeType == EXPLODE_OLD_INCLUDE_MAIN)
1492 isOldSorting = true;
1493 GEOMUtils::SortShapes(listShape, isOldSorting);
1496 TopTools_IndexedMapOfShape anIndices;
1497 TopExp::MapShapes(aShape, anIndices);
1498 Handle(TColStd_HArray1OfInteger) anArray;
1500 TopTools_ListIteratorOfListOfShape itSub (listShape);
1501 TCollection_AsciiString anAsciiList, anEntry;
1502 for (int index = 1; itSub.More(); itSub.Next(), ++index)
1504 TopoDS_Shape aValue = itSub.Value();
1505 anArray = new TColStd_HArray1OfInteger(1,1);
1506 anArray->SetValue(1, anIndices.FindIndex(aValue));
1508 //anObj = GetEngine()->AddSubShape(theShape, anArray);
1510 anObj = GetEngine()->AddObject(GetDocID(), GEOM_SUBSHAPE);
1511 Handle(GEOM_Function) aFunction = anObj->AddFunction(GEOM_Object::GetSubShapeID(), 1);
1512 if (aFunction.IsNull()) return aSeq;
1514 GEOM_ISubShape aSSI (aFunction);
1515 aSSI.SetMainShape(aMainShape);
1516 aSSI.SetIndices(anArray);
1518 // Set function value directly, as we know it.
1519 // Usage of Solver here would lead to significant loss of time,
1520 // because GEOM_SubShapeDriver will build TopTools_IndexedMapOfShape
1521 // on the main shape for each being calculated sub-shape separately.
1522 aFunction->SetValue(aValue);
1524 // Put this subshape in the list of sub-shapes of theMainShape
1525 aMainShape->AddSubShapeReference(aFunction);
1527 if (!anObj.IsNull()) {
1528 aSeq->Append(anObj);
1530 // for python command
1531 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
1532 anAsciiList += anEntry;
1537 //Make a Python command
1538 anAsciiList.Trunc(anAsciiList.Length() - 1);
1540 GEOM::TPythonDump pd (aMainShape, /*append=*/true);
1541 pd << "[" << anAsciiList.ToCString() << "] = geompy.";
1542 switch (theExplodeType) {
1543 case EXPLODE_NEW_EXCLUDE_MAIN:
1544 pd << "ExtractShapes(" << theShape << ", "
1545 << TopAbs_ShapeEnum(theShapeType) << ", " << (isSorted ? "True" : "False") << ")";
1547 case EXPLODE_NEW_INCLUDE_MAIN:
1548 pd << "SubShapeAll" << (isSorted ? "SortedCentres(" : "(")
1549 << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
1551 case EXPLODE_OLD_INCLUDE_MAIN:
1552 pd << "SubShapeAll" << (isSorted ? "Sorted(" : "(")
1553 << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
1562 //=============================================================================
1566 //=============================================================================
1567 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::SubShapeAllIDs
1568 (Handle(GEOM_Object) theShape,
1569 const Standard_Integer theShapeType,
1570 const Standard_Boolean isSorted,
1571 const ExplodeType theExplodeType)
1575 if (theShape.IsNull()) return NULL;
1576 TopoDS_Shape aShape = theShape->GetValue();
1577 if (aShape.IsNull()) return NULL;
1579 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
1580 TopTools_MapOfShape mapShape;
1581 TopTools_ListOfShape listShape;
1583 if (aShape.ShapeType() == TopAbs_COMPOUND &&
1584 (theShapeType == TopAbs_SHAPE || theShapeType == TopAbs_FLAT || theShapeType == TopAbs_COMPOUND))
1586 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
1587 for (; It.More(); It.Next()) {
1588 TopoDS_Shape SS = It.Value();
1589 if (mapShape.Add(SS)) {
1590 if (theShapeType == TopAbs_FLAT) {
1591 AddFlatSubShapes(SS, listShape, mapShape);
1593 else if (theShapeType == TopAbs_SHAPE || theShapeType == SS.ShapeType()) {
1594 listShape.Append(SS);
1599 else if (theExplodeType != EXPLODE_NEW_EXCLUDE_MAIN || aShape.ShapeType() != theShapeType) // issue 0021079
1601 TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
1602 for (; exp.More(); exp.Next())
1603 if (mapShape.Add(exp.Current()))
1604 listShape.Append(exp.Current());
1607 if (listShape.IsEmpty()) {
1608 //SetErrorCode("The given shape has no sub-shapes of the requested type");
1609 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
1614 bool isOldSorting = false;
1615 if (theExplodeType == EXPLODE_OLD_INCLUDE_MAIN)
1616 isOldSorting = true;
1617 GEOMUtils::SortShapes(listShape, isOldSorting);
1620 TopTools_IndexedMapOfShape anIndices;
1621 TopExp::MapShapes(aShape, anIndices);
1622 Handle(TColStd_HArray1OfInteger) anArray;
1624 TopTools_ListIteratorOfListOfShape itSub (listShape);
1625 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
1626 TopoDS_Shape aValue = itSub.Value();
1627 aSeq->Append(anIndices.FindIndex(aValue));
1630 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
1632 //Make a Python command
1633 GEOM::TPythonDump pd (aFunction, /*append=*/true);
1634 pd << "listSubShapeIDs = geompy.SubShapeAll";
1635 switch (theExplodeType) {
1636 case EXPLODE_NEW_EXCLUDE_MAIN:
1638 case EXPLODE_NEW_INCLUDE_MAIN:
1639 pd << (isSorted ? "SortedCentresIDs(" : "IDs(")
1640 << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
1642 case EXPLODE_OLD_INCLUDE_MAIN:
1643 pd << (isSorted ? "SortedIDs(" : "IDs(")
1644 << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
1653 //=============================================================================
1657 //=============================================================================
1658 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetSubShape
1659 (Handle(GEOM_Object) theMainShape,
1660 const Standard_Integer theID)
1664 if (theMainShape.IsNull()) return NULL;
1666 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
1667 anArray->SetValue(1, theID);
1668 Handle(GEOM_Object) anObj = GetEngine()->AddSubShape(theMainShape, anArray,true);
1669 if (anObj.IsNull()) {
1670 SetErrorCode("Can not get a sub-shape with the given ID");
1674 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1676 //Make a Python command
1677 GEOM::TPythonDump(aFunction) << anObj << " = geompy.GetSubShape("
1678 << theMainShape << ", [" << theID << "])";
1684 //=============================================================================
1688 //=============================================================================
1689 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::MakeSubShapes
1690 (Handle(GEOM_Object) theMainShape,
1691 Handle(TColStd_HArray1OfInteger) theIndices)
1695 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1697 if (!theIndices->Length()) {
1698 SetErrorCode(NOT_FOUND_ANY);
1702 if (theMainShape.IsNull()) return NULL;
1703 TopoDS_Shape aShape = theMainShape->GetValue();
1704 if (aShape.IsNull()) return NULL;
1706 Handle(GEOM_Function) aMainShape = theMainShape->GetLastFunction();
1708 TopTools_IndexedMapOfShape anIndices;
1709 TopExp::MapShapes(aShape, anIndices);
1711 Handle(TColStd_HArray1OfInteger) anArray;
1712 Handle(GEOM_Object) anObj;
1714 TCollection_AsciiString anAsciiList, anEntry;
1715 Standard_Integer i, low = theIndices->Lower(), up = theIndices->Upper();
1716 for (i = low; i <= up; i++) {
1717 int id = theIndices->Value(i);
1718 if (1 <= id && id <= anIndices.Extent()) {
1719 TopoDS_Shape aValue = anIndices.FindKey(id);
1720 anArray = new TColStd_HArray1OfInteger(1,1);
1721 anArray->SetValue(1, id);
1723 anObj = GetEngine()->AddObject(GetDocID(), GEOM_SUBSHAPE);
1724 if (!anObj.IsNull()) {
1725 Handle(GEOM_Function) aFunction = anObj->AddFunction(GEOM_Object::GetSubShapeID(), 1);
1726 if (aFunction.IsNull()) return aSeq;
1728 GEOM_ISubShape aSSI (aFunction);
1729 aSSI.SetMainShape(aMainShape);
1730 aSSI.SetIndices(anArray);
1732 // Set function value directly, as we know it.
1733 // Usage of Solver here would lead to significant loss of time,
1734 // because GEOM_SubShapeDriver will build TopTools_IndexedMapOfShape
1735 // on the main shape for each being calculated sub-shape separately.
1736 aFunction->SetValue(aValue);
1738 // Put this sub-shape in the list of sub-shapes of theMainShape
1739 aMainShape->AddSubShapeReference(aFunction);
1741 aSeq->Append(anObj);
1743 // for python command
1744 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
1745 anAsciiList += anEntry;
1751 //Make a Python command
1752 anAsciiList.Trunc(anAsciiList.Length() - 1);
1754 GEOM::TPythonDump pd (aMainShape, /*append=*/true);
1755 pd << "[" << anAsciiList.ToCString() << "] = geompy.SubShapes("
1756 << theMainShape << ", [" ;
1757 for (i = low; i <= up - 1; i++) {
1758 pd << theIndices->Value(i) << ", ";
1760 pd << theIndices->Value(up) << "])";
1767 //=============================================================================
1771 //=============================================================================
1772 Standard_Integer GEOMImpl_IShapesOperations::GetSubShapeIndex (Handle(GEOM_Object) theMainShape,
1773 Handle(GEOM_Object) theSubShape)
1777 TopoDS_Shape aMainShape = theMainShape->GetValue();
1778 TopoDS_Shape aSubShape = theSubShape->GetValue();
1780 if (aMainShape.IsNull() || aSubShape.IsNull()) return -1;
1782 TopTools_IndexedMapOfShape anIndices;
1783 TopExp::MapShapes(aMainShape, anIndices);
1784 // if (anIndices.Contains(aSubShape)) {
1785 // SetErrorCode(OK);
1786 // return anIndices.FindIndex(aSubShape);
1788 int id = anIndices.FindIndex(aSubShape);
1799 //=============================================================================
1801 * GetSubShapeIndices
1803 //=============================================================================
1804 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetSubShapesIndices (Handle(GEOM_Object) theMainShape,
1805 std::list<Handle(GEOM_Object)> theSubShapes)
1807 MESSAGE("GEOMImpl_IShapesOperations::GetSubShapesIndices")
1810 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
1812 TopoDS_Shape aMainShape = theMainShape->GetValue();
1813 if (aMainShape.IsNull())
1815 MESSAGE("NULL main shape")
1819 TopTools_IndexedMapOfShape anIndices;
1820 TopExp::MapShapes(aMainShape, anIndices);
1822 std::list<Handle(GEOM_Object)>::iterator it;
1823 for (it=theSubShapes.begin(); it != theSubShapes.end(); ++it)
1825 TopoDS_Shape aSubShape = (*it)->GetValue();
1826 if (aSubShape.IsNull())
1828 MESSAGE("NULL subshape")
1831 int id = anIndices.FindIndex(aSubShape);
1840 //=============================================================================
1844 //=============================================================================
1845 Standard_Integer GEOMImpl_IShapesOperations::GetTopologyIndex (Handle(GEOM_Object) theMainShape,
1846 Handle(GEOM_Object) theSubShape)
1850 TopoDS_Shape aMainShape = theMainShape->GetValue();
1851 TopoDS_Shape aSubShape = theSubShape->GetValue();
1853 if (aMainShape.IsNull() || aSubShape.IsNull()) {
1854 SetErrorCode("Null argument shape given");
1859 if (aSubShape.ShapeType() == TopAbs_COMPOUND) {
1861 TopTools_ListOfShape CL;
1862 CL.Append(aMainShape);
1863 TopTools_ListIteratorOfListOfShape itC;
1864 for (itC.Initialize(CL); itC.More(); itC.Next()) {
1865 for (it.Initialize(itC.Value()); it.More(); it.Next()) {
1866 if (it.Value().ShapeType() == TopAbs_COMPOUND) {
1867 if (it.Value().IsSame(aSubShape))
1871 CL.Append(it.Value());
1876 TopExp_Explorer anExp (aMainShape, aSubShape.ShapeType());
1877 TopTools_MapOfShape M;
1878 for (; anExp.More(); anExp.Next()) {
1879 if (M.Add(anExp.Current())) {
1880 if (anExp.Current().IsSame(aSubShape))
1887 SetErrorCode("The sub-shape does not belong to the main shape");
1891 //=============================================================================
1893 * GetShapeTypeString
1895 //=============================================================================
1896 TCollection_AsciiString GEOMImpl_IShapesOperations::GetShapeTypeString (Handle(GEOM_Object) theShape)
1900 TCollection_AsciiString aTypeName ("Null Shape");
1902 TopoDS_Shape aShape = theShape->GetValue();
1903 if (aShape.IsNull())
1906 switch (aShape.ShapeType() )
1908 case TopAbs_COMPOUND:
1909 aTypeName = "Compound";
1911 case TopAbs_COMPSOLID:
1912 aTypeName = "Compound Solid";
1915 aTypeName = "Solid";
1918 aTypeName = "Shell";
1922 BRepAdaptor_Surface surf (TopoDS::Face(aShape));
1923 if (surf.GetType() == GeomAbs_Plane)
1924 aTypeName = "Plane";
1925 else if (surf.GetType() == GeomAbs_Cylinder)
1926 aTypeName = "Cylindrical Face";
1927 else if (surf.GetType() == GeomAbs_Sphere)
1928 aTypeName = "Spherical Face";
1929 else if (surf.GetType() == GeomAbs_Torus)
1930 aTypeName = "Toroidal Face";
1931 else if (surf.GetType() == GeomAbs_Cone)
1932 aTypeName = "Conical Face";
1934 aTypeName = "GEOM::FACE";
1942 BRepAdaptor_Curve curv (TopoDS::Edge(aShape));
1943 if (curv.GetType() == GeomAbs_Line) {
1944 if ((Abs(curv.FirstParameter()) >= 1E6) ||
1945 (Abs(curv.LastParameter()) >= 1E6))
1949 } else if (curv.GetType() == GeomAbs_Circle) {
1950 if (curv.IsClosed())
1951 aTypeName = "Circle";
1960 aTypeName = "Vertex";
1963 aTypeName = "Shape";
1966 aTypeName = "Shape of unknown type";
1972 //=============================================================================
1974 * IsSubShapeBelongsTo
1976 //=============================================================================
1977 Standard_Boolean GEOMImpl_IShapesOperations::IsSubShapeBelongsTo( Handle(GEOM_Object) theSubObject,
1978 const Standard_Integer theSubObjectIndex,
1979 Handle(GEOM_Object) theObject,
1980 const Standard_Integer theObjectIndex)
1982 if ( theObject.IsNull() || theSubObject.IsNull() )
1985 TopoDS_Shape shape = theObject->GetValue();
1986 TopoDS_Shape subShape = theSubObject->GetValue();
1988 if ( shape.IsNull() || subShape.IsNull() )
1991 TopTools_IndexedMapOfShape anIndices;
1992 if ( theObjectIndex > 0 ) {
1993 TopExp::MapShapes( shape, anIndices );
1994 shape = anIndices.FindKey(theObjectIndex);
1996 if ( theSubObjectIndex > 0 ) {
1997 TopExp::MapShapes( subShape, anIndices );
1998 subShape = anIndices.FindKey(theSubObjectIndex);
2001 TopExp::MapShapes( shape, anIndices );
2002 return anIndices.Contains( subShape );
2005 //=============================================================================
2009 //=============================================================================
2010 Standard_Integer GEOMImpl_IShapesOperations::NumberOfSubShapes
2011 (Handle(GEOM_Object) theShape,
2012 const Standard_Integer theShapeType)
2015 Standard_Integer nbShapes = 0;
2017 if (theShape.IsNull()) return -1;
2018 TopoDS_Shape aShape = theShape->GetValue();
2019 if (aShape.IsNull()) return -1;
2022 TopTools_MapOfShape mapShape;
2024 if (aShape.ShapeType() == TopAbs_COMPOUND &&
2025 (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
2026 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPSOLID ||
2027 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPOUND)) {
2028 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
2029 for (; It.More(); It.Next()) {
2030 if (mapShape.Add(It.Value())) {
2031 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
2032 TopAbs_ShapeEnum(theShapeType) == It.Value().ShapeType()) {
2038 TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
2039 for (; exp.More(); exp.Next())
2040 if (mapShape.Add(exp.Current()))
2046 if (theShapeType == TopAbs_FLAT) {
2047 TopTools_MapOfShape aMapOfShape;
2048 TopTools_ListOfShape aListOfShape;
2049 AddFlatSubShapes(aShape, aListOfShape, aMapOfShape);
2050 nbShapes = aListOfShape.Extent();
2054 int iType, nbTypes [TopAbs_SHAPE];
2055 for (iType = 0; iType < TopAbs_SHAPE; ++iType)
2057 nbTypes[aShape.ShapeType()]++;
2059 TopTools_MapOfShape aMapOfShape;
2060 aMapOfShape.Add(aShape);
2061 TopTools_ListOfShape aListOfShape;
2062 aListOfShape.Append(aShape);
2064 TopTools_ListIteratorOfListOfShape itL (aListOfShape);
2065 for (; itL.More(); itL.Next()) {
2066 TopoDS_Iterator it (itL.Value());
2067 for (; it.More(); it.Next()) {
2068 TopoDS_Shape s = it.Value();
2069 if (aMapOfShape.Add(s)) {
2070 aListOfShape.Append(s);
2071 nbTypes[s.ShapeType()]++;
2076 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE)
2077 nbShapes = aMapOfShape.Extent();
2079 nbShapes = nbTypes[theShapeType];
2082 catch (Standard_Failure) {
2083 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2084 SetErrorCode(aFail->GetMessageString());
2092 //=============================================================================
2096 //=============================================================================
2097 Handle(GEOM_Object) GEOMImpl_IShapesOperations::ReverseShape(Handle(GEOM_Object) theShape)
2101 if (theShape.IsNull()) return NULL;
2104 //Add a new reversed object
2105 Handle(GEOM_Object) aReversed = GetEngine()->AddObject(GetDocID(), theShape->GetType());
2107 //Add a new Revese function
2108 Handle(GEOM_Function) aFunction;
2109 aFunction = aReversed->AddFunction(GEOMImpl_ShapeDriver::GetID(), REVERSE_ORIENTATION);
2110 if (aFunction.IsNull()) return NULL;
2112 //Check if the function is set correctly
2113 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
2115 GEOMImpl_IShapes aSI (aFunction);
2117 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
2118 if (aRefShape.IsNull()) return NULL;
2120 aSI.SetBase(aRefShape);
2122 //Compute the sub-shape value
2125 if (!GetSolver()->ComputeFunction(aFunction)) {
2126 SetErrorCode("Shape driver failed to reverse shape");
2130 catch (Standard_Failure) {
2131 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2132 SetErrorCode(aFail->GetMessageString());
2136 //Make a Python command
2137 GEOM::TPythonDump(aFunction) << aReversed
2138 << " = geompy.ChangeOrientation(" << theShape << ")";
2143 Handle(GEOM_Object) aReversed;
2145 GEOM_Engine* anEngine = GetEngine();
2146 //GEOMImpl_Gen* aGen = dynamic_cast<GEOMImpl_Gen*>(anEngine);
2147 GEOMImpl_Gen* aGen = (GEOMImpl_Gen*)anEngine;
2150 GEOMImpl_IHealingOperations* anIHealingOperations =
2151 aGen->GetIHealingOperations(GetDocID());
2152 aReversed = anIHealingOperations->ChangeOrientationCopy(theShape);
2153 SetErrorCode(anIHealingOperations->GetErrorCode());
2159 //=============================================================================
2163 //=============================================================================
2164 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetFreeFacesIDs
2165 (Handle(GEOM_Object) theShape)
2169 if (theShape.IsNull()) return NULL;
2170 TopoDS_Shape aShape = theShape->GetValue();
2171 if (aShape.IsNull()) return NULL;
2173 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
2175 TopTools_IndexedDataMapOfShapeListOfShape mapFaceBlocks;
2176 GEOMImpl_Block6Explorer::MapShapesAndAncestors
2177 (aShape, TopAbs_FACE, TopAbs_SOLID, mapFaceBlocks);
2179 Standard_Integer ind = 1, nbFaces = mapFaceBlocks.Extent();
2182 SetErrorCode("The given shape has no faces");
2186 TopTools_IndexedMapOfShape anIndices;
2187 TopExp::MapShapes(aShape, anIndices);
2189 Standard_Integer id;
2190 for (; ind <= nbFaces; ind++) {
2191 if (mapFaceBlocks.FindFromIndex(ind).Extent() != 2) {
2192 id = anIndices.FindIndex(mapFaceBlocks.FindKey(ind));
2197 //The explode doesn't change object so no new function is required.
2198 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
2200 //Make a Python command
2201 GEOM::TPythonDump(aFunction, /*append=*/true)
2202 << "listFreeFacesIDs = geompy.GetFreeFacesIDs(" << theShape << ")";
2208 //=======================================================================
2209 //function : GetSharedShapes
2211 //=======================================================================
2212 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetSharedShapes
2213 (Handle(GEOM_Object) theShape1,
2214 Handle(GEOM_Object) theShape2,
2215 const Standard_Integer theShapeType)
2219 if (theShape1.IsNull() || theShape2.IsNull()) return NULL;
2221 TopoDS_Shape aShape1 = theShape1->GetValue();
2222 TopoDS_Shape aShape2 = theShape2->GetValue();
2224 if (aShape1.IsNull() || aShape2.IsNull()) return NULL;
2226 TopTools_IndexedMapOfShape anIndices;
2227 TopExp::MapShapes(aShape1, anIndices);
2228 Handle(TColStd_HArray1OfInteger) anArray;
2230 TopTools_IndexedMapOfShape mapShape1;
2231 TopExp::MapShapes(aShape1, TopAbs_ShapeEnum(theShapeType), mapShape1);
2233 Handle(GEOM_Object) anObj;
2234 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
2235 TCollection_AsciiString anAsciiList, anEntry;
2237 TopTools_MapOfShape mapShape2;
2238 TopExp_Explorer exp (aShape2, TopAbs_ShapeEnum(theShapeType));
2239 for (; exp.More(); exp.Next()) {
2240 TopoDS_Shape aSS = exp.Current();
2241 if (mapShape2.Add(aSS) && mapShape1.Contains(aSS)) {
2242 anArray = new TColStd_HArray1OfInteger(1,1);
2243 anArray->SetValue(1, anIndices.FindIndex(aSS));
2244 anObj = GetEngine()->AddSubShape(theShape1, anArray);
2245 aSeq->Append(anObj);
2247 // for python command
2248 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
2249 anAsciiList += anEntry;
2254 if (aSeq->IsEmpty()) {
2255 SetErrorCode(NOT_FOUND_ANY);
2259 //Make a Python command
2260 anAsciiList.Trunc(anAsciiList.Length() - 1);
2262 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2264 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
2265 << "] = geompy.GetSharedShapes(" << theShape1 << ", "
2266 << theShape2 << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
2272 //=======================================================================
2273 //function : GetSharedShapes
2276 // NOTE on the implementation
2278 // 1) Resulting sub-shapes are published as a children of the 1st input shape
2279 // from theShapes list. Due to this reason only direct sub-shapes of the 1st
2280 // shape can be contained in the result of the operation (i.e. shares between
2281 // 2nd/3rd, etc couples cannot be retrieved.
2282 // 2) An exception from above case is when a single compound is specified as an
2283 // input. In this case we search shares between its top-level content, so we
2284 // are able to search shares between all possible couples of shapes.
2285 // 3) Parameter theMultiShare controls what types of shares to search:
2286 // - True: get sub-shapes that are shared between ALL input shapes;
2287 // - False: get shares between couples of input sub-shapes (see points 1 and 2).
2289 // Thus, we have the following cases:
2290 // [1] theShapes = N shapes (N>1), theMultiShare = True
2291 // Result: sub-shapes that are shared by all theShapes
2292 // [2] theShapes = N shapes (N>1), theMultiShare = False
2293 // Result: sub-shapes of 1st shape from theShapes that are shared with any shape
2295 // [3] theShapes = 1 shape, theMultiShare = True
2296 // Result: sub-shapes that are shared by all top-level sub-objects of theShapes[0]
2297 // [4] theShapes = 1 shape, theMultiShare = False
2298 // Result: sub-shapes of all possible couples of all top-level sub-objects of
2300 //=======================================================================
2301 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetSharedShapes
2302 (std::list<Handle(GEOM_Object)> & theShapes,
2303 const Standard_Integer theShapeType,
2304 const bool theMultiShare)
2308 int aLen = theShapes.size();
2309 if (aLen < 1) return NULL;
2311 std::list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
2313 // main object is always first in the input list
2314 // it is the object from which sub-shapes indices are taken
2315 // and where results are published
2316 Handle(GEOM_Object) aMainObj = *it;
2317 Handle(GEOM_Function) aMainShape = aMainObj->GetLastFunction();
2319 // collect all shapes from the input list (including first one) for processing
2320 TopTools_SequenceOfShape shapeSeq;
2321 for (; it != theShapes.end(); it++) {
2322 Handle(GEOM_Function) aRefShape = (*it)->GetLastFunction();
2323 if (aRefShape.IsNull()) {
2324 SetErrorCode("NULL shape for GetSharedShapes");
2327 TopoDS_Shape aShape = aRefShape->GetValue();
2328 if (aShape.IsNull()) {
2329 SetErrorCode("NULL shape for GetSharedShapes");
2332 shapeSeq.Append( aShape );
2335 // if only single shape is specified as input
2336 // collect all ites top-level sub-shapes for processing
2337 if ( shapeSeq.Length() == 1 )
2339 TopoDS_Shape aShape = shapeSeq.First();
2341 for ( TopoDS_Iterator it( aShape ); it.More(); it.Next() )
2342 shapeSeq.Append( it.Value() );
2345 // map all sub-shapes in a main shape to their indices
2346 TopTools_IndexedMapOfShape anIndices;
2347 TopExp::MapShapes(aMainShape->GetValue(), anIndices);
2348 TopTools_MapOfShape mapShape;
2350 // find shared shapes
2352 // here we will collect all shares
2353 TopTools_ListOfShape aShared;
2355 // number of iterations
2356 int nbIters = theMultiShare || theShapes.size() > 1 ? 1 : shapeSeq.Length()-1;
2357 // numShares factor to search (i.e. by what nb of shapes each found sub-shape should be shared)
2358 int nbShares = theMultiShare ? shapeSeq.Length()-1 : 1;
2360 for ( int iter = 1; iter <= nbIters; iter++) {
2361 for ( int ind = iter+1; ind <= shapeSeq.Length(); ind++) {
2362 if ( ind-1+nbShares > shapeSeq.Length() ) break;
2363 TopoDS_Compound aCurrSelection;
2364 TopoDS_Shape aShape1 = shapeSeq.Value( iter );
2365 TopTools_IndexedMapOfShape mapSelected;
2366 TopExp::MapShapes(aShape1, TopAbs_ShapeEnum(theShapeType), mapSelected);
2367 for ( int s = 0; s < nbShares; s++ ) {
2369 TopoDS_Compound aCompound;
2370 B.MakeCompound(aCompound);
2371 const TopoDS_Shape& aShape2 = shapeSeq.Value( ind+s );
2372 TopTools_MapOfShape mapShape2;
2373 TopExp_Explorer exp (aShape2, TopAbs_ShapeEnum(theShapeType));
2374 for (; exp.More(); exp.Next()) {
2375 const TopoDS_Shape& aSS = exp.Current();
2376 if (mapShape2.Add(aSS) && mapSelected.Contains(aSS)) {
2377 B.Add(aCompound, aSS);
2380 mapSelected.Clear();
2381 aCurrSelection = aCompound;
2382 TopExp::MapShapes(aCurrSelection, TopAbs_ShapeEnum(theShapeType), mapSelected);
2384 TopoDS_Iterator itSel(aCurrSelection, Standard_True, Standard_True);
2385 for (; itSel.More(); itSel.Next()) {
2386 const TopoDS_Shape& aSS = itSel.Value();
2387 if (mapShape.Add(aSS) )
2388 aShared.Append(aSS);
2393 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
2395 if (aShared.IsEmpty()){
2396 SetErrorCode(NOT_FOUND_ANY);
2400 // create GEOM_Object for each found shared shape (collected in aShared)
2401 TCollection_AsciiString anAsciiList;
2402 Handle(GEOM_Object) anObj;
2403 TopTools_ListIteratorOfListOfShape itSub (aShared);
2404 for (; itSub.More(); itSub.Next()) {
2405 TopoDS_Shape aValue = itSub.Value();
2406 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
2407 anArray->SetValue(1, anIndices.FindIndex(aValue));
2408 anObj = GetEngine()->AddSubShape(aMainObj, anArray);
2409 aSeq->Append(anObj);
2411 // for python command
2412 TCollection_AsciiString anEntry;
2413 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
2414 anAsciiList += anEntry;
2418 // make a Python command
2419 anAsciiList.Trunc(anAsciiList.Length() - 1);
2421 GEOM::TPythonDump pd (anObj->GetLastFunction());
2422 pd << "[" << anAsciiList.ToCString()
2423 << "] = geompy.GetSharedShapesMulti(";
2428 it = theShapes.begin();
2430 while (it != theShapes.end()) {
2431 pd << ", " << (*it++);
2436 pd << ", " << TopAbs_ShapeEnum(theShapeType) << ", " << theMultiShare << ")";
2442 //=============================================================================
2446 //=============================================================================
2447 static GEOM::TPythonDump& operator<< (GEOM::TPythonDump& theDump,
2448 const GEOMAlgo_State theState)
2451 case GEOMAlgo_ST_IN:
2452 theDump << "GEOM.ST_IN";
2454 case GEOMAlgo_ST_OUT:
2455 theDump << "GEOM.ST_OUT";
2457 case GEOMAlgo_ST_ON:
2458 theDump << "GEOM.ST_ON";
2460 case GEOMAlgo_ST_ONIN:
2461 theDump << "GEOM.ST_ONIN";
2463 case GEOMAlgo_ST_ONOUT:
2464 theDump << "GEOM.ST_ONOUT";
2467 theDump << "GEOM.ST_UNKNOWN";
2473 //=======================================================================
2474 //function : checkTypeShapesOn
2476 * \brief Checks if theShapeType parameter of GetShapesOnXXX() is OK
2477 * \param theShapeType - the shape type to check
2478 * \retval bool - result of the check
2480 //=======================================================================
2481 bool GEOMImpl_IShapesOperations::checkTypeShapesOn(const Standard_Integer theShapeType)
2483 if (theShapeType != TopAbs_VERTEX &&
2484 theShapeType != TopAbs_EDGE &&
2485 theShapeType != TopAbs_FACE &&
2486 theShapeType != TopAbs_SOLID) {
2487 SetErrorCode("Only solids, vertices, edges or faces can be found by this method");
2493 //=======================================================================
2494 //function : makePlane
2496 * \brief Creates Geom_Plane
2497 * \param theAx1 - shape object defining plane parameters
2498 * \retval Handle(Geom_Surface) - resulting surface
2500 //=======================================================================
2501 Handle(Geom_Surface) GEOMImpl_IShapesOperations::makePlane(const TopoDS_Shape& anAx1)
2503 if (anAx1.ShapeType() != TopAbs_EDGE) return NULL;
2504 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
2505 TopoDS_Vertex V1, V2;
2506 TopExp::Vertices(anEdge, V1, V2, Standard_True);
2507 if (V1.IsNull() || V2.IsNull()) {
2508 SetErrorCode("Bad edge given for the plane normal vector");
2511 gp_Pnt aLoc = BRep_Tool::Pnt(V1);
2512 gp_Vec aVec (aLoc, BRep_Tool::Pnt(V2));
2513 if (aVec.Magnitude() < Precision::Confusion()) {
2514 SetErrorCode("Vector with null magnitude given");
2517 return new Geom_Plane(aLoc, aVec);
2520 //=======================================================================
2521 //function : makeCylinder
2523 * \brief Creates Geom_CylindricalSurface
2524 * \param theAx1 - edge defining cylinder axis
2525 * \param theRadius - cylinder radius
2526 * \retval Handle(Geom_Surface) - resulting surface
2528 //=======================================================================
2529 Handle(Geom_Surface) GEOMImpl_IShapesOperations::makeCylinder(const TopoDS_Shape& anAxis,
2530 const Standard_Real theRadius)
2532 //Axis of the cylinder
2533 if (anAxis.ShapeType() != TopAbs_EDGE) {
2534 SetErrorCode("Not an edge given for the axis");
2537 TopoDS_Edge anEdge = TopoDS::Edge(anAxis);
2538 TopoDS_Vertex V1, V2;
2539 TopExp::Vertices(anEdge, V1, V2, Standard_True);
2540 if (V1.IsNull() || V2.IsNull()) {
2541 SetErrorCode("Bad edge given for the axis");
2544 gp_Pnt aLoc = BRep_Tool::Pnt(V1);
2545 gp_Vec aVec (aLoc, BRep_Tool::Pnt(V2));
2546 if (aVec.Magnitude() < Precision::Confusion()) {
2547 SetErrorCode("Vector with null magnitude given");
2551 gp_Ax3 anAx3 (aLoc, aVec);
2552 return new Geom_CylindricalSurface(anAx3, theRadius);
2555 //=======================================================================
2556 //function : getShapesOnBoxIDs
2558 * \brief Find IDs of sub-shapes complying with given status about surface
2559 * \param theBox - the box to check state of sub-shapes against
2560 * \param theShape - the shape to explore
2561 * \param theShapeType - type of sub-shape of theShape
2562 * \param theState - required state
2563 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
2565 //=======================================================================
2566 Handle(TColStd_HSequenceOfInteger)
2567 GEOMImpl_IShapesOperations::getShapesOnBoxIDs(const Handle(GEOM_Object)& theBox,
2568 const Handle(GEOM_Object)& theShape,
2569 const Standard_Integer theShapeType,
2570 GEOMAlgo_State theState)
2572 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
2574 TopoDS_Shape aBox = theBox->GetValue();
2575 TopoDS_Shape aShape = theShape->GetValue();
2577 // Check presence of triangulation, build if need
2578 if (!GEOMUtils::CheckTriangulation(aShape)) {
2579 SetErrorCode("Cannot build triangulation on the shape");
2584 GEOMAlgo_FinderShapeOn2 aFinder;
2585 Standard_Real aTol = 0.0001; // default value
2587 Handle(GEOMAlgo_ClsfBox) aClsfBox = new GEOMAlgo_ClsfBox;
2588 aClsfBox->SetBox(aBox);
2590 aFinder.SetShape(aShape);
2591 aFinder.SetTolerance(aTol);
2592 aFinder.SetClsf(aClsfBox);
2593 aFinder.SetShapeType( (TopAbs_ShapeEnum)theShapeType );
2594 aFinder.SetState(theState);
2597 // Interprete results
2598 Standard_Integer iErr = aFinder.ErrorStatus();
2599 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
2601 MESSAGE(" iErr : " << iErr);
2602 TCollection_AsciiString aMsg (" iErr : ");
2603 aMsg += TCollection_AsciiString(iErr);
2607 Standard_Integer iWrn = aFinder.WarningStatus();
2608 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
2610 MESSAGE(" *** iWrn : " << iWrn);
2613 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
2615 if (listSS.Extent() < 1) {
2616 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
2617 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
2621 // Fill sequence of object IDs
2622 aSeqOfIDs = new TColStd_HSequenceOfInteger;
2624 TopTools_IndexedMapOfShape anIndices;
2625 TopExp::MapShapes(aShape, anIndices);
2627 TopTools_ListIteratorOfListOfShape itSub (listSS);
2628 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
2629 int id = anIndices.FindIndex(itSub.Value());
2630 aSeqOfIDs->Append(id);
2636 //=======================================================================
2637 //function : GetShapesOnBoxIDs
2639 * \brief Find sub-shapes complying with given status about surface
2640 * \param theBox - the box to check state of sub-shapes against
2641 * \param theShape - the shape to explore
2642 * \param theShapeType - type of sub-shape of theShape
2643 * \param theState - required state
2644 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
2646 //=======================================================================
2647 Handle(TColStd_HSequenceOfInteger)
2648 GEOMImpl_IShapesOperations::GetShapesOnBoxIDs(const Handle(GEOM_Object)& theBox,
2649 const Handle(GEOM_Object)& theShape,
2650 const Standard_Integer theShapeType,
2651 GEOMAlgo_State theState)
2653 // Find sub-shapes ids
2654 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2655 getShapesOnBoxIDs (theBox, theShape, theShapeType, theState);
2656 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2659 // The GetShapesOnBox() doesn't change object so no new function is required.
2660 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theBox)->GetLastFunction();
2662 // Make a Python command
2663 GEOM::TPythonDump(aFunction, /*append=*/true)
2664 << "listShapesOnBoxIDs = geompy.GetShapesOnBoxIDs("
2667 << TopAbs_ShapeEnum(theShapeType) << ", "
2674 //=======================================================================
2675 //function : GetShapesOnBox
2677 * \brief Find sub-shapes complying with given status about surface
2678 * \param theBox - the box to check state of sub-shapes against
2679 * \param theShape - the shape to explore
2680 * \param theShapeType - type of sub-shape of theShape
2681 * \param theState - required state
2682 * \retval Handle(TColStd_HSequenceOfTransient) - found sub-shapes
2684 //=======================================================================
2685 Handle(TColStd_HSequenceOfTransient)
2686 GEOMImpl_IShapesOperations::GetShapesOnBox(const Handle(GEOM_Object)& theBox,
2687 const Handle(GEOM_Object)& theShape,
2688 const Standard_Integer theShapeType,
2689 GEOMAlgo_State theState)
2691 // Find sub-shapes ids
2692 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2693 getShapesOnBoxIDs (theBox, theShape, theShapeType, theState);
2694 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2697 // Find objects by indices
2698 TCollection_AsciiString anAsciiList;
2699 Handle(TColStd_HSequenceOfTransient) aSeq;
2700 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
2701 if ( aSeq.IsNull() || aSeq->IsEmpty() )
2704 // Make a Python command
2706 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2707 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2709 GEOM::TPythonDump(aFunction)
2710 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnBox("
2713 << TopAbs_ShapeEnum(theShapeType) << ", "
2720 //=======================================================================
2721 //function : getShapesOnShapeIDs
2723 * \brief Find IDs of sub-shapes complying with given status about surface
2724 * \param theCheckShape - the shape to check state of sub-shapes against
2725 * \param theShape - the shape to explore
2726 * \param theShapeType - type of sub-shape of theShape
2727 * \param theState - required state
2728 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
2730 //=======================================================================
2731 Handle(TColStd_HSequenceOfInteger)
2732 GEOMImpl_IShapesOperations::getShapesOnShapeIDs
2733 (const Handle(GEOM_Object)& theCheckShape,
2734 const Handle(GEOM_Object)& theShape,
2735 const Standard_Integer theShapeType,
2736 GEOMAlgo_State theState)
2738 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
2740 TopoDS_Shape aCheckShape = theCheckShape->GetValue();
2741 TopoDS_Shape aShape = theShape->GetValue();
2742 TopTools_ListOfShape res;
2744 // Check presence of triangulation, build if need
2745 if (!GEOMUtils::CheckTriangulation(aShape)) {
2746 SetErrorCode("Cannot build triangulation on the shape");
2751 GEOMAlgo_FinderShapeOn2 aFinder;
2752 Standard_Real aTol = 0.0001; // default value
2754 Handle(GEOMAlgo_ClsfSolid) aClsfSolid = new GEOMAlgo_ClsfSolid;
2755 aClsfSolid->SetShape(aCheckShape);
2757 aFinder.SetShape(aShape);
2758 aFinder.SetTolerance(aTol);
2759 aFinder.SetClsf(aClsfSolid);
2760 aFinder.SetShapeType( (TopAbs_ShapeEnum)theShapeType );
2761 aFinder.SetState(theState);
2764 // Interprete results
2765 Standard_Integer iErr = aFinder.ErrorStatus();
2766 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
2769 SetErrorCode("theCheckShape must be a solid");
2772 MESSAGE(" iErr : " << iErr);
2773 TCollection_AsciiString aMsg (" iErr : ");
2774 aMsg += TCollection_AsciiString(iErr);
2779 Standard_Integer iWrn = aFinder.WarningStatus();
2780 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
2782 MESSAGE(" *** iWrn : " << iWrn);
2785 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
2787 if (listSS.Extent() < 1) {
2788 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
2789 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
2792 // Fill sequence of object IDs
2793 aSeqOfIDs = new TColStd_HSequenceOfInteger;
2795 TopTools_IndexedMapOfShape anIndices;
2796 TopExp::MapShapes(aShape, anIndices);
2798 TopTools_ListIteratorOfListOfShape itSub (listSS);
2799 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
2800 int id = anIndices.FindIndex(itSub.Value());
2801 aSeqOfIDs->Append(id);
2807 //=======================================================================
2808 //function : GetShapesOnShapeIDs
2810 * \brief Find sub-shapes complying with given status about surface
2811 * \param theCheckShape - the shape to check state of sub-shapes against
2812 * \param theShape - the shape to explore
2813 * \param theShapeType - type of sub-shape of theShape
2814 * \param theState - required state
2815 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
2817 //=======================================================================
2818 Handle(TColStd_HSequenceOfInteger)
2819 GEOMImpl_IShapesOperations::GetShapesOnShapeIDs
2820 (const Handle(GEOM_Object)& theCheckShape,
2821 const Handle(GEOM_Object)& theShape,
2822 const Standard_Integer theShapeType,
2823 GEOMAlgo_State theState)
2825 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2826 getShapesOnShapeIDs (theCheckShape, theShape, theShapeType, theState);
2828 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2831 // The GetShapesOnShape() doesn't change object so no new function is required.
2832 Handle(GEOM_Function) aFunction =
2833 GEOM::GetCreatedLast(theShape,theCheckShape)->GetLastFunction();
2835 // Make a Python command
2836 GEOM::TPythonDump(aFunction, /*append=*/true)
2837 << "listShapesOnBoxIDs = geompy.GetShapesOnShapeIDs("
2838 << theCheckShape << ", "
2840 << TopAbs_ShapeEnum(theShapeType) << ", "
2847 //=======================================================================
2848 //function : GetShapesOnShape
2850 * \brief Find sub-shapes complying with given status about surface
2851 * \param theCheckShape - the shape 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 * \retval Handle(TColStd_HSequenceOfTransient) - found sub-shapes
2857 //=======================================================================
2858 Handle(TColStd_HSequenceOfTransient)
2859 GEOMImpl_IShapesOperations::GetShapesOnShape
2860 (const Handle(GEOM_Object)& theCheckShape,
2861 const Handle(GEOM_Object)& theShape,
2862 const Standard_Integer theShapeType,
2863 GEOMAlgo_State theState)
2865 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2866 getShapesOnShapeIDs (theCheckShape, theShape, theShapeType, theState);
2867 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2870 // Find objects by indices
2871 TCollection_AsciiString anAsciiList;
2872 Handle(TColStd_HSequenceOfTransient) aSeq;
2873 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
2875 if ( aSeq.IsNull() || aSeq->IsEmpty() )
2878 // Make a Python command
2880 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2881 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2883 GEOM::TPythonDump(aFunction)
2884 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnShape("
2885 << theCheckShape << ", "
2887 << TopAbs_ShapeEnum(theShapeType) << ", "
2894 //=======================================================================
2895 //function : GetShapesOnShapeAsCompound
2896 //=======================================================================
2897 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetShapesOnShapeAsCompound
2898 (const Handle(GEOM_Object)& theCheckShape,
2899 const Handle(GEOM_Object)& theShape,
2900 const Standard_Integer theShapeType,
2901 GEOMAlgo_State theState)
2903 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2904 getShapesOnShapeIDs (theCheckShape, theShape, theShapeType, theState);
2906 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2909 // Find objects by indices
2910 TCollection_AsciiString anAsciiList;
2911 Handle(TColStd_HSequenceOfTransient) aSeq;
2912 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
2914 if ( aSeq.IsNull() || aSeq->IsEmpty() )
2917 TopoDS_Compound aCompound;
2919 B.MakeCompound(aCompound);
2921 for(; i<=aSeq->Length(); i++) {
2922 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(aSeq->Value(i));
2923 TopoDS_Shape aShape_i = anObj->GetValue();
2924 B.Add(aCompound,aShape_i);
2927 //Add a new result object
2928 Handle(GEOM_Object) aRes = GetEngine()->AddObject(GetDocID(), GEOM_SHAPES_ON_SHAPE);
2929 Handle(GEOM_Function) aFunction =
2930 aRes->AddFunction(GEOMImpl_ShapeDriver::GetID(), SHAPES_ON_SHAPE);
2931 aFunction->SetValue(aCompound);
2934 aSeq->Append( theCheckShape->GetLastFunction() );
2935 aSeq->Append( theShape->GetLastFunction() );
2937 GEOMImpl_IShapes aCI( aFunction );
2938 aCI.SetShapes( aSeq );
2939 aCI.SetSubShapeType( theShapeType );
2940 aCI.SetTolerance( theState );
2942 GEOM::TPythonDump(aFunction)
2943 << aRes << " = geompy.GetShapesOnShapeAsCompound("
2944 << theCheckShape << ", "
2946 << TopAbs_ShapeEnum(theShapeType) << ", "
2954 //=======================================================================
2955 //function : getShapesOnSurfaceIDs
2957 * \brief Find IDs of sub-shapes complying with given status about surface
2958 * \param theSurface - the surface to check state of sub-shapes against
2959 * \param theShape - the shape to explore
2960 * \param theShapeType - type of sub-shape of theShape
2961 * \param theState - required state
2962 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
2964 //=======================================================================
2965 Handle(TColStd_HSequenceOfInteger)
2966 GEOMImpl_IShapesOperations::getShapesOnSurfaceIDs(const Handle(Geom_Surface)& theSurface,
2967 const TopoDS_Shape& theShape,
2968 TopAbs_ShapeEnum theShapeType,
2969 GEOMAlgo_State theState)
2971 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
2973 // Check presence of triangulation, build if need
2974 if (!GEOMUtils::CheckTriangulation(theShape)) {
2975 SetErrorCode("Cannot build triangulation on the shape");
2979 // BEGIN: Mantis issue 0020961: Error on a pipe T-Shape
2980 // Compute tolerance
2981 Standard_Real T, VertMax = -RealLast();
2984 for (TopExp_Explorer ExV (theShape, TopAbs_VERTEX); ExV.More(); ExV.Next()) {
2985 TopoDS_Vertex Vertex = TopoDS::Vertex(ExV.Current());
2986 T = BRep_Tool::Tolerance(Vertex);
2991 catch (Standard_Failure) {
2992 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2993 SetErrorCode(aFail->GetMessageString());
2996 // END: Mantis issue 0020961
2999 GEOMAlgo_FinderShapeOn1 aFinder;
3000 //Standard_Real aTol = 0.0001; // default value
3001 Standard_Real aTol = VertMax; // Mantis issue 0020961
3003 aFinder.SetShape(theShape);
3004 aFinder.SetTolerance(aTol);
3005 aFinder.SetSurface(theSurface);
3006 aFinder.SetShapeType(theShapeType);
3007 aFinder.SetState(theState);
3009 // Sets the minimal number of inner points for the faces that do not have own
3010 // inner points at all (for e.g. rectangular planar faces have just 2 triangles).
3012 aFinder.SetNbPntsMin(3);
3013 // Sets the maximal number of inner points for edges or faces.
3014 // It is usefull for the cases when this number is very big (e.g =2000) to improve
3015 // the performance. If this value =0, all inner points will be taken into account.
3017 aFinder.SetNbPntsMax(100);
3021 // Interprete results
3022 Standard_Integer iErr = aFinder.ErrorStatus();
3023 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
3025 MESSAGE(" iErr : " << iErr);
3026 TCollection_AsciiString aMsg (" iErr : ");
3027 aMsg += TCollection_AsciiString(iErr);
3031 Standard_Integer iWrn = aFinder.WarningStatus();
3032 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
3034 MESSAGE(" *** iWrn : " << iWrn);
3037 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
3039 if (listSS.Extent() < 1) {
3040 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
3041 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
3045 // Fill sequence of object IDs
3046 aSeqOfIDs = new TColStd_HSequenceOfInteger;
3048 TopTools_IndexedMapOfShape anIndices;
3049 TopExp::MapShapes(theShape, anIndices);
3051 TopTools_ListIteratorOfListOfShape itSub (listSS);
3052 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
3053 int id = anIndices.FindIndex(itSub.Value());
3054 aSeqOfIDs->Append(id);
3060 //=======================================================================
3061 //function : getObjectsShapesOn
3063 * \brief Find shape objects and their entries by their ids
3064 * \param theShapeIDs - incoming shape ids
3065 * \param theShapeEntries - outgoing entries like "entry1, entry2, ..."
3066 * \retval Handle(TColStd_HSequenceOfTransient) - found shape objects
3068 //=======================================================================
3069 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::
3070 getObjectsShapesOn(const Handle(GEOM_Object)& theShape,
3071 const Handle(TColStd_HSequenceOfInteger)& theShapeIDs,
3072 TCollection_AsciiString & theShapeEntries)
3074 Handle(TColStd_HSequenceOfTransient) aSeq;
3076 if ( !theShapeIDs.IsNull() && theShapeIDs->Length() > 0 )
3078 aSeq = new TColStd_HSequenceOfTransient;
3079 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
3080 TCollection_AsciiString anEntry;
3081 for ( int i = 1; i <= theShapeIDs->Length(); ++i )
3083 anArray->SetValue(1, theShapeIDs->Value( i ));
3084 Handle(GEOM_Object) anObj = GetEngine()->AddSubShape(theShape, anArray);
3085 aSeq->Append( anObj );
3087 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
3088 if ( i != 1 ) theShapeEntries += ",";
3089 theShapeEntries += anEntry;
3095 //=======================================================================
3096 //function : getShapesOnSurface
3098 * \brief Find sub-shapes complying with given status about surface
3099 * \param theSurface - the surface to check state of sub-shapes against
3100 * \param theShape - the shape to explore
3101 * \param theShapeType - type of sub-shape of theShape
3102 * \param theState - required state
3103 * \param theShapeEntries - outgoing entries like "entry1, entry2, ..."
3104 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
3106 //=======================================================================
3107 Handle(TColStd_HSequenceOfTransient)
3108 GEOMImpl_IShapesOperations::getShapesOnSurface(const Handle(Geom_Surface)& theSurface,
3109 const Handle(GEOM_Object)& theShape,
3110 TopAbs_ShapeEnum theShapeType,
3111 GEOMAlgo_State theState,
3112 TCollection_AsciiString & theShapeEntries)
3114 // Find sub-shapes ids
3115 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
3116 getShapesOnSurfaceIDs (theSurface, theShape->GetValue(), theShapeType, theState);
3117 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
3120 return getObjectsShapesOn( theShape, aSeqOfIDs, theShapeEntries );
3123 //=============================================================================
3127 //=============================================================================
3128 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnPlane
3129 (const Handle(GEOM_Object)& theShape,
3130 const Standard_Integer theShapeType,
3131 const Handle(GEOM_Object)& theAx1,
3132 const GEOMAlgo_State theState)
3136 if (theShape.IsNull() || theAx1.IsNull()) return NULL;
3138 TopoDS_Shape aShape = theShape->GetValue();
3139 TopoDS_Shape anAx1 = theAx1->GetValue();
3141 if (aShape.IsNull() || anAx1.IsNull()) return NULL;
3143 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3144 if ( !checkTypeShapesOn( theShapeType ))
3148 Handle(Geom_Surface) aPlane = makePlane( anAx1 );
3149 if ( aPlane.IsNull() )
3153 TCollection_AsciiString anAsciiList;
3154 Handle(TColStd_HSequenceOfTransient) aSeq;
3155 aSeq = getShapesOnSurface( aPlane, 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.GetShapesOnPlane(" << theShape << ", "
3166 << aShapeType << ", " << theAx1 << ", " << theState << ")";
3172 //=============================================================================
3174 * GetShapesOnPlaneWithLocation
3176 //=============================================================================
3177 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnPlaneWithLocation
3178 (const Handle(GEOM_Object)& theShape,
3179 const Standard_Integer theShapeType,
3180 const Handle(GEOM_Object)& theAx1,
3181 const Handle(GEOM_Object)& thePnt,
3182 const GEOMAlgo_State theState)
3186 if (theShape.IsNull() || theAx1.IsNull() || thePnt.IsNull()) return NULL;
3188 TopoDS_Shape aShape = theShape->GetValue();
3189 TopoDS_Shape anAx1 = theAx1->GetValue();
3190 TopoDS_Shape anPnt = thePnt->GetValue();
3192 if (aShape.IsNull() || anAx1.IsNull() || anPnt.IsNull()) return NULL;
3194 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3195 if ( !checkTypeShapesOn( theShapeType ))
3199 if ( anAx1.ShapeType() != TopAbs_EDGE || anPnt.ShapeType() != TopAbs_VERTEX ) return NULL;
3200 TopoDS_Vertex V1, V2, V3;
3201 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
3202 TopExp::Vertices(anEdge, V1, V2, Standard_True);
3204 if (V1.IsNull() || V2.IsNull()) {
3205 SetErrorCode("Bad edge given for the plane normal vector");
3208 V3 = TopoDS::Vertex(anPnt);
3211 SetErrorCode("Bad vertex given for the plane location");
3214 gp_Pnt aLoc = BRep_Tool::Pnt(V3);
3215 gp_Vec aVec(BRep_Tool::Pnt(V1),BRep_Tool::Pnt(V2));
3217 if (aVec.Magnitude() < Precision::Confusion()) {
3218 SetErrorCode("Vector with null magnitude given");
3221 Handle(Geom_Surface) aPlane = new Geom_Plane(aLoc, aVec);
3223 if ( aPlane.IsNull() )
3227 TCollection_AsciiString anAsciiList;
3228 Handle(TColStd_HSequenceOfTransient) aSeq;
3229 aSeq = getShapesOnSurface( aPlane, theShape, aShapeType, theState, anAsciiList );
3230 if ( aSeq.IsNull() || aSeq->Length() == 0 )
3233 // Make a Python command
3235 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
3236 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
3238 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
3239 << "] = geompy.GetShapesOnPlaneWithLocation(" << theShape << ", "
3240 << aShapeType << ", " << theAx1 << ", "<< thePnt <<", " << theState << ")";
3246 //=============================================================================
3248 * GetShapesOnCylinder
3250 //=============================================================================
3251 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnCylinder
3252 (const Handle(GEOM_Object)& theShape,
3253 const Standard_Integer theShapeType,
3254 const Handle(GEOM_Object)& theAxis,
3255 const Standard_Real theRadius,
3256 const GEOMAlgo_State theState)
3260 if (theShape.IsNull() || theAxis.IsNull()) return NULL;
3262 TopoDS_Shape aShape = theShape->GetValue();
3263 TopoDS_Shape anAxis = theAxis->GetValue();
3265 if (aShape.IsNull() || anAxis.IsNull()) return NULL;
3267 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3268 if ( !checkTypeShapesOn( aShapeType ))
3271 // Create a cylinder surface
3272 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
3273 if ( aCylinder.IsNull() )
3277 TCollection_AsciiString anAsciiList;
3278 Handle(TColStd_HSequenceOfTransient) aSeq;
3279 aSeq = getShapesOnSurface( aCylinder, theShape, aShapeType, theState, anAsciiList );
3280 if ( aSeq.IsNull() || aSeq->Length() == 0 )
3283 // Make a Python command
3285 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
3286 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
3288 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
3289 << "] = geompy.GetShapesOnCylinder(" << theShape << ", " << aShapeType
3290 << ", " << theAxis << ", " << theRadius << ", " << theState << ")";
3296 //=============================================================================
3298 * GetShapesOnCylinderWithLocation
3300 //=============================================================================
3301 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnCylinderWithLocation
3302 (const Handle(GEOM_Object)& theShape,
3303 const Standard_Integer theShapeType,
3304 const Handle(GEOM_Object)& theAxis,
3305 const Handle(GEOM_Object)& thePnt,
3306 const Standard_Real theRadius,
3307 const GEOMAlgo_State theState)
3311 if (theShape.IsNull() || theAxis.IsNull() || thePnt.IsNull()) return NULL;
3313 TopoDS_Shape aShape = theShape->GetValue();
3314 TopoDS_Shape anAxis = theAxis->GetValue();
3315 TopoDS_Shape aPnt = thePnt->GetValue();
3317 if (aShape.IsNull() || anAxis.IsNull() || aPnt.IsNull()) return NULL;
3319 if (aPnt.ShapeType() != TopAbs_VERTEX )
3321 SetErrorCode("Bottom location point must be vertex");
3325 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3326 if ( !checkTypeShapesOn( aShapeType ))
3329 // Create a cylinder surface
3330 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
3331 if ( aCylinder.IsNull() )
3334 // translate the surface
3335 Handle(Geom_CylindricalSurface) aCylSurface =
3336 Handle(Geom_CylindricalSurface)::DownCast( aCylinder );
3337 if ( aCylSurface.IsNull() )
3339 SetErrorCode("Unexpected surface type instead of Geom_CylindricalSurface");
3342 gp_Pnt fromLoc = aCylSurface->Cylinder().Location();
3343 gp_Pnt toLoc = BRep_Tool::Pnt( TopoDS::Vertex( aPnt ));
3344 aCylinder->Translate( fromLoc, toLoc );
3347 TCollection_AsciiString anAsciiList;
3348 Handle(TColStd_HSequenceOfTransient) aSeq;
3349 aSeq = getShapesOnSurface( aCylinder, theShape, aShapeType, theState, anAsciiList );
3350 if ( aSeq.IsNull() || aSeq->Length() == 0 )
3353 // Make a Python command
3355 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
3356 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
3358 GEOM::TPythonDump(aFunction)
3359 << "[" << anAsciiList.ToCString()
3360 << "] = geompy.GetShapesOnCylinderWithLocation(" << theShape << ", " << aShapeType << ", "
3361 << theAxis << ", " << thePnt << ", " << theRadius << ", " << theState << ")";
3367 //=============================================================================
3371 //=============================================================================
3372 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnSphere
3373 (const Handle(GEOM_Object)& theShape,
3374 const Standard_Integer theShapeType,
3375 const Handle(GEOM_Object)& theCenter,
3376 const Standard_Real theRadius,
3377 const GEOMAlgo_State theState)
3381 if (theShape.IsNull() || theCenter.IsNull()) return NULL;
3383 TopoDS_Shape aShape = theShape->GetValue();
3384 TopoDS_Shape aCenter = theCenter->GetValue();
3386 if (aShape.IsNull() || aCenter.IsNull()) return NULL;
3388 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3389 if ( !checkTypeShapesOn( aShapeType ))
3392 // Center of the sphere
3393 if (aCenter.ShapeType() != TopAbs_VERTEX) return NULL;
3394 gp_Pnt aLoc = BRep_Tool::Pnt(TopoDS::Vertex(aCenter));
3396 gp_Ax3 anAx3 (aLoc, gp::DZ());
3397 Handle(Geom_SphericalSurface) aSphere =
3398 new Geom_SphericalSurface(anAx3, theRadius);
3401 TCollection_AsciiString anAsciiList;
3402 Handle(TColStd_HSequenceOfTransient) aSeq;
3403 aSeq = getShapesOnSurface( aSphere, theShape, aShapeType, theState, anAsciiList );
3404 if ( aSeq.IsNull() || aSeq->Length() == 0 )
3407 // Make a Python command
3409 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
3410 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
3412 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
3413 << "] = geompy.GetShapesOnSphere(" << theShape << ", " << aShapeType
3414 << ", " << theCenter << ", " << theRadius << ", " << theState << ")";
3420 //=============================================================================
3422 * GetShapesOnPlaneIDs
3424 //=============================================================================
3425 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnPlaneIDs
3426 (const Handle(GEOM_Object)& theShape,
3427 const Standard_Integer theShapeType,
3428 const Handle(GEOM_Object)& theAx1,
3429 const GEOMAlgo_State theState)
3433 if (theShape.IsNull() || theAx1.IsNull()) return NULL;
3435 TopoDS_Shape aShape = theShape->GetValue();
3436 TopoDS_Shape anAx1 = theAx1->GetValue();
3438 if (aShape.IsNull() || anAx1.IsNull()) return NULL;
3440 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3441 if ( !checkTypeShapesOn( aShapeType ))
3445 Handle(Geom_Surface) aPlane = makePlane( anAx1 );
3446 if ( aPlane.IsNull() )
3450 Handle(TColStd_HSequenceOfInteger) aSeq;
3451 aSeq = getShapesOnSurfaceIDs( aPlane, aShape, aShapeType, theState );
3453 // The GetShapesOnPlaneIDs() doesn't change object so no new function is required.
3454 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAx1)->GetLastFunction();
3456 // Make a Python command
3457 GEOM::TPythonDump(aFunction, /*append=*/true)
3458 << "listShapesOnPlane = geompy.GetShapesOnPlaneIDs"
3459 << "(" << theShape << "," << aShapeType << "," << theAx1 << "," << theState << ")";
3465 //=============================================================================
3467 * GetShapesOnPlaneWithLocationIDs
3469 //=============================================================================
3470 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnPlaneWithLocationIDs
3471 (const Handle(GEOM_Object)& theShape,
3472 const Standard_Integer theShapeType,
3473 const Handle(GEOM_Object)& theAx1,
3474 const Handle(GEOM_Object)& thePnt,
3475 const GEOMAlgo_State theState)
3479 if (theShape.IsNull() || theAx1.IsNull() || thePnt.IsNull()) return NULL;
3481 TopoDS_Shape aShape = theShape->GetValue();
3482 TopoDS_Shape anAx1 = theAx1->GetValue();
3483 TopoDS_Shape anPnt = thePnt->GetValue();
3485 if (aShape.IsNull() || anAx1.IsNull() || anPnt.IsNull()) return NULL;
3487 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3488 if ( !checkTypeShapesOn( aShapeType ))
3492 if (anAx1.ShapeType() != TopAbs_EDGE || anPnt.ShapeType() != TopAbs_VERTEX) return NULL;
3493 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
3494 TopoDS_Vertex V1, V2, V3;
3495 TopExp::Vertices(anEdge, V1, V2, Standard_True);
3496 if (V1.IsNull() || V2.IsNull()) {
3497 SetErrorCode("Bad edge given for the plane normal vector");
3500 V3 = TopoDS::Vertex(anPnt);
3502 SetErrorCode("Bad vertex given for the plane location");
3505 gp_Pnt aLoc = BRep_Tool::Pnt(V3);
3506 gp_Vec aVec(BRep_Tool::Pnt(V1),BRep_Tool::Pnt(V2));
3507 if (aVec.Magnitude() < Precision::Confusion()) {
3508 SetErrorCode("Vector with null magnitude given");
3512 Handle(Geom_Surface) aPlane = new Geom_Plane(aLoc, aVec);
3513 if ( aPlane.IsNull() )
3517 Handle(TColStd_HSequenceOfInteger) aSeq;
3518 aSeq = getShapesOnSurfaceIDs( aPlane, aShape, aShapeType, theState );
3520 // The GetShapesOnPlaneIDs() doesn't change object so no new function is required.
3521 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAx1)->GetLastFunction();
3523 // Make a Python command
3524 GEOM::TPythonDump(aFunction, /*append=*/true)
3525 << "listShapesOnPlane = geompy.GetShapesOnPlaneWithLocationIDs"
3526 << "(" << theShape << ", " << aShapeType << ", " << theAx1 << ", "<< thePnt << ", " << theState << ")";
3532 //=============================================================================
3534 * GetShapesOnCylinderIDs
3536 //=============================================================================
3537 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnCylinderIDs
3538 (const Handle(GEOM_Object)& theShape,
3539 const Standard_Integer theShapeType,
3540 const Handle(GEOM_Object)& theAxis,
3541 const Standard_Real theRadius,
3542 const GEOMAlgo_State theState)
3546 if (theShape.IsNull() || theAxis.IsNull()) return NULL;
3548 TopoDS_Shape aShape = theShape->GetValue();
3549 TopoDS_Shape anAxis = theAxis->GetValue();
3551 if (aShape.IsNull() || anAxis.IsNull()) return NULL;
3553 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3554 if ( !checkTypeShapesOn( aShapeType ))
3557 // Create a cylinder surface
3558 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
3559 if ( aCylinder.IsNull() )
3563 Handle(TColStd_HSequenceOfInteger) aSeq;
3564 aSeq = getShapesOnSurfaceIDs( aCylinder, aShape, aShapeType, theState );
3566 // The GetShapesOnCylinder() doesn't change object so no new function is required.
3567 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAxis)->GetLastFunction();
3569 // Make a Python command
3570 GEOM::TPythonDump(aFunction, /*append=*/true)
3571 << "listShapesOnCylinder = geompy.GetShapesOnCylinderIDs"
3572 << "(" << theShape << ", " << aShapeType << ", " << theAxis << ", "
3573 << theRadius << ", " << theState << ")";
3579 //=============================================================================
3581 * GetShapesOnCylinderWithLocationIDs
3583 //=============================================================================
3584 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnCylinderWithLocationIDs
3585 (const Handle(GEOM_Object)& theShape,
3586 const Standard_Integer theShapeType,
3587 const Handle(GEOM_Object)& theAxis,
3588 const Handle(GEOM_Object)& thePnt,
3589 const Standard_Real theRadius,
3590 const GEOMAlgo_State theState)
3594 if (theShape.IsNull() || theAxis.IsNull() || thePnt.IsNull()) return NULL;
3596 TopoDS_Shape aShape = theShape->GetValue();
3597 TopoDS_Shape anAxis = theAxis->GetValue();
3598 TopoDS_Shape aPnt = thePnt->GetValue();
3600 if (aShape.IsNull() || anAxis.IsNull() || aPnt.IsNull()) return NULL;
3602 if (aPnt.ShapeType() != TopAbs_VERTEX )
3604 SetErrorCode("Bottom location point must be vertex");
3608 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3609 if ( !checkTypeShapesOn( aShapeType ))
3612 // Create a cylinder surface
3613 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
3614 if ( aCylinder.IsNull() )
3617 // translate the surface
3618 Handle(Geom_CylindricalSurface) aCylSurface =
3619 Handle(Geom_CylindricalSurface)::DownCast( aCylinder );
3620 if ( aCylSurface.IsNull() )
3622 SetErrorCode("Unexpected surface type instead of Geom_CylindricalSurface");
3625 gp_Pnt fromLoc = aCylSurface->Cylinder().Location();
3626 gp_Pnt toLoc = BRep_Tool::Pnt( TopoDS::Vertex( aPnt ));
3627 aCylinder->Translate( fromLoc, toLoc );
3630 Handle(TColStd_HSequenceOfInteger) aSeq;
3631 aSeq = getShapesOnSurfaceIDs( aCylinder, aShape, aShapeType, theState );
3633 // The GetShapesOnCylinder() doesn't change object so no new function is required.
3634 Handle(GEOM_Function) aFunction =
3635 GEOM::GetCreatedLast(theShape, GEOM::GetCreatedLast(thePnt,theAxis))->GetLastFunction();
3637 // Make a Python command
3638 GEOM::TPythonDump(aFunction, /*append=*/true)
3639 << "listShapesOnCylinder = geompy.GetShapesOnCylinderWithLocationIDs"
3640 << "(" << theShape << ", " << aShapeType << ", " << theAxis << ", "
3641 << thePnt << ", " << theRadius << ", " << theState << ")";
3647 //=============================================================================
3649 * GetShapesOnSphereIDs
3651 //=============================================================================
3652 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnSphereIDs
3653 (const Handle(GEOM_Object)& theShape,
3654 const Standard_Integer theShapeType,
3655 const Handle(GEOM_Object)& theCenter,
3656 const Standard_Real theRadius,
3657 const GEOMAlgo_State theState)
3661 if (theShape.IsNull() || theCenter.IsNull()) return NULL;
3663 TopoDS_Shape aShape = theShape->GetValue();
3664 TopoDS_Shape aCenter = theCenter->GetValue();
3666 if (aShape.IsNull() || aCenter.IsNull()) return NULL;
3668 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3669 if ( !checkTypeShapesOn( aShapeType ))
3672 // Center of the sphere
3673 if (aCenter.ShapeType() != TopAbs_VERTEX) return NULL;
3674 gp_Pnt aLoc = BRep_Tool::Pnt(TopoDS::Vertex(aCenter));
3676 gp_Ax3 anAx3 (aLoc, gp::DZ());
3677 Handle(Geom_SphericalSurface) aSphere =
3678 new Geom_SphericalSurface(anAx3, theRadius);
3681 Handle(TColStd_HSequenceOfInteger) aSeq;
3682 aSeq = getShapesOnSurfaceIDs( aSphere, aShape, aShapeType, theState );
3684 // The GetShapesOnSphere() doesn't change object so no new function is required.
3685 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theCenter)->GetLastFunction();
3687 // Make a Python command
3688 GEOM::TPythonDump(aFunction, /*append=*/true)
3689 << "listShapesOnCylinder = geompy.GetShapesOnSphereIDs"
3690 << "(" << theShape << ", " << aShapeType << ", " << theCenter << ", "
3691 << theRadius << ", " << theState << ")";
3697 //=======================================================================
3698 //function : getShapesOnQuadrangleIDs
3700 * \brief Find IDs of sub-shapes complying with given status about quadrangle
3701 * \param theShape - the shape to explore
3702 * \param theShapeType - type of sub-shape of theShape
3703 * \param theTopLeftPoint - top left quadrangle corner
3704 * \param theTopRigthPoint - top right quadrangle corner
3705 * \param theBottomLeftPoint - bottom left quadrangle corner
3706 * \param theBottomRigthPoint - bottom right quadrangle corner
3707 * \param theState - required state
3708 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
3710 //=======================================================================
3711 Handle(TColStd_HSequenceOfInteger)
3712 GEOMImpl_IShapesOperations::getShapesOnQuadrangleIDs (const Handle(GEOM_Object)& theShape,
3713 const Standard_Integer theShapeType,
3714 const Handle(GEOM_Object)& theTopLeftPoint,
3715 const Handle(GEOM_Object)& theTopRigthPoint,
3716 const Handle(GEOM_Object)& theBottomLeftPoint,
3717 const Handle(GEOM_Object)& theBottomRigthPoint,
3718 const GEOMAlgo_State theState)
3722 if ( theShape.IsNull() ||
3723 theTopLeftPoint.IsNull() ||
3724 theTopRigthPoint.IsNull() ||
3725 theBottomLeftPoint.IsNull() ||
3726 theBottomRigthPoint.IsNull() )
3729 TopoDS_Shape aShape = theShape->GetValue();
3730 TopoDS_Shape aTL = theTopLeftPoint->GetValue();
3731 TopoDS_Shape aTR = theTopRigthPoint->GetValue();
3732 TopoDS_Shape aBL = theBottomLeftPoint->GetValue();
3733 TopoDS_Shape aBR = theBottomRigthPoint->GetValue();
3735 if (aShape.IsNull() ||
3740 aTL.ShapeType() != TopAbs_VERTEX ||
3741 aTR.ShapeType() != TopAbs_VERTEX ||
3742 aBL.ShapeType() != TopAbs_VERTEX ||
3743 aBR.ShapeType() != TopAbs_VERTEX )
3746 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3747 if ( !checkTypeShapesOn( aShapeType ))
3750 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
3752 // Check presence of triangulation, build if need
3753 if (!GEOMUtils::CheckTriangulation(aShape)) {
3754 SetErrorCode("Cannot build triangulation on the shape");
3759 gp_Pnt aPntTL = BRep_Tool::Pnt(TopoDS::Vertex(aTL));
3760 gp_Pnt aPntTR = BRep_Tool::Pnt(TopoDS::Vertex(aTR));
3761 gp_Pnt aPntBL = BRep_Tool::Pnt(TopoDS::Vertex(aBL));
3762 gp_Pnt aPntBR = BRep_Tool::Pnt(TopoDS::Vertex(aBR));
3764 GEOMAlgo_FinderShapeOnQuad aFinder( aPntTL, aPntTR, aPntBL, aPntBR );
3765 Standard_Real aTol = 0.0001; // default value
3767 aFinder.SetShape(aShape);
3768 aFinder.SetTolerance(aTol);
3769 //aFinder.SetSurface(theSurface);
3770 aFinder.SetShapeType(aShapeType);
3771 aFinder.SetState(theState);
3773 // Sets the minimal number of inner points for the faces that do not have own
3774 // inner points at all (for e.g. rectangular planar faces have just 2 triangles).
3776 aFinder.SetNbPntsMin(3);
3777 // Sets the maximal number of inner points for edges or faces.
3778 // It is usefull for the cases when this number is very big (e.g =2000) to improve
3779 // the performance. If this value =0, all inner points will be taken into account.
3781 aFinder.SetNbPntsMax(100);
3785 // Interprete results
3786 Standard_Integer iErr = aFinder.ErrorStatus();
3787 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
3789 MESSAGE(" iErr : " << iErr);
3790 TCollection_AsciiString aMsg (" iErr : ");
3791 aMsg += TCollection_AsciiString(iErr);
3795 Standard_Integer iWrn = aFinder.WarningStatus();
3796 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
3798 MESSAGE(" *** iWrn : " << iWrn);
3801 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
3803 if (listSS.Extent() < 1) {
3804 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
3805 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
3809 // Fill sequence of object IDs
3810 aSeqOfIDs = new TColStd_HSequenceOfInteger;
3812 TopTools_IndexedMapOfShape anIndices;
3813 TopExp::MapShapes(aShape, anIndices);
3815 TopTools_ListIteratorOfListOfShape itSub (listSS);
3816 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
3817 int id = anIndices.FindIndex(itSub.Value());
3818 aSeqOfIDs->Append(id);
3823 //=======================================================================
3824 //function : GetShapesOnQuadrangle
3826 * \brief Find sub-shapes complying with given status about quadrangle
3827 * \param theShape - the shape to explore
3828 * \param theShapeType - type of sub-shape of theShape
3829 * \param theTopLeftPoint - top left quadrangle corner
3830 * \param theTopRigthPoint - top right quadrangle corner
3831 * \param theBottomLeftPoint - bottom left quadrangle corner
3832 * \param theBottomRigthPoint - bottom right quadrangle corner
3833 * \param theState - required state
3834 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
3836 //=======================================================================
3837 Handle(TColStd_HSequenceOfTransient)
3838 GEOMImpl_IShapesOperations::GetShapesOnQuadrangle (const Handle(GEOM_Object)& theShape,
3839 const Standard_Integer theShapeType,
3840 const Handle(GEOM_Object)& theTopLeftPoint,
3841 const Handle(GEOM_Object)& theTopRigthPoint,
3842 const Handle(GEOM_Object)& theBottomLeftPoint,
3843 const Handle(GEOM_Object)& theBottomRigthPoint,
3844 const GEOMAlgo_State theState)
3847 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
3848 getShapesOnQuadrangleIDs( theShape,
3853 theBottomRigthPoint,
3855 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->IsEmpty() )
3858 // Find objects by indices
3859 TCollection_AsciiString anAsciiList;
3860 Handle(TColStd_HSequenceOfTransient) aSeq;
3861 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
3862 if ( aSeq.IsNull() || aSeq->IsEmpty() )
3865 // Make a Python command
3867 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
3868 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
3870 GEOM::TPythonDump(aFunction)
3871 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnQuadrangle("
3873 << TopAbs_ShapeEnum(theShapeType) << ", "
3874 << theTopLeftPoint << ", "
3875 << theTopRigthPoint << ", "
3876 << theBottomLeftPoint << ", "
3877 << theBottomRigthPoint << ", "
3884 //=======================================================================
3885 //function : GetShapesOnQuadrangleIDs
3887 * \brief Find IDs of sub-shapes complying with given status about quadrangle
3888 * \param theShape - the shape to explore
3889 * \param theShapeType - type of sub-shape of theShape
3890 * \param theTopLeftPoint - top left quadrangle corner
3891 * \param theTopRigthPoint - top right quadrangle corner
3892 * \param theBottomLeftPoint - bottom left quadrangle corner
3893 * \param theBottomRigthPoint - bottom right quadrangle corner
3894 * \param theState - required state
3895 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
3897 //=======================================================================
3898 Handle(TColStd_HSequenceOfInteger)
3899 GEOMImpl_IShapesOperations::GetShapesOnQuadrangleIDs (const Handle(GEOM_Object)& theShape,
3900 const Standard_Integer theShapeType,
3901 const Handle(GEOM_Object)& theTopLeftPoint,
3902 const Handle(GEOM_Object)& theTopRigthPoint,
3903 const Handle(GEOM_Object)& theBottomLeftPoint,
3904 const Handle(GEOM_Object)& theBottomRigthPoint,
3905 const GEOMAlgo_State theState)
3908 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
3909 getShapesOnQuadrangleIDs( theShape,
3914 theBottomRigthPoint,
3916 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->IsEmpty() )
3919 // Make a Python command
3921 // The GetShapesOnCylinder() doesn't change object so no new function is required.
3922 Handle(GEOM_Object) lastObj = GEOM::GetCreatedLast(theShape,theTopLeftPoint);
3923 lastObj = GEOM::GetCreatedLast(lastObj,theTopRigthPoint);
3924 lastObj = GEOM::GetCreatedLast(lastObj,theBottomRigthPoint);
3925 lastObj = GEOM::GetCreatedLast(lastObj,theBottomLeftPoint);
3926 Handle(GEOM_Function) aFunction = lastObj->GetLastFunction();
3928 GEOM::TPythonDump(aFunction, /*append=*/true)
3929 << "listShapesOnQuadrangle = geompy.GetShapesOnQuadrangleIDs("
3931 << TopAbs_ShapeEnum(theShapeType) << ", "
3932 << theTopLeftPoint << ", "
3933 << theTopRigthPoint << ", "
3934 << theBottomLeftPoint << ", "
3935 << theBottomRigthPoint << ", "
3942 //=============================================================================
3947 //=============================================================================
3948 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlace (Handle(GEOM_Object) theShapeWhere,
3949 Handle(GEOM_Object) theShapeWhat)
3953 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
3955 TopoDS_Shape aWhere = theShapeWhere->GetValue();
3956 TopoDS_Shape aWhat = theShapeWhat->GetValue();
3958 if (aWhere.IsNull() || aWhat.IsNull()) {
3959 SetErrorCode("Error: aWhere and aWhat TopoDS_Shape are Null.");
3963 // Searching for the sub-shapes inside the ShapeWhere shape
3964 GEOMAlgo_GetInPlace aGIP;
3966 if (!GEOMAlgo_GetInPlaceAPI::GetInPlace(aWhere, aWhat, aGIP)) {
3967 SetErrorCode("Error in GEOMAlgo_GetInPlace");
3971 // Add direct result.
3972 TopTools_ListOfShape aLSA;
3973 const TopoDS_Shape &aShapeResult = aGIP.Result();
3974 TopTools_MapOfShape aMFence;
3975 TopTools_IndexedMapOfShape aWhereIndices;
3977 TopExp::MapShapes(aWhere, aWhereIndices);
3979 if (aShapeResult.IsNull() == Standard_False) {
3980 TopoDS_Iterator anIt(aShapeResult);
3982 for (; anIt.More(); anIt.Next()) {
3983 const TopoDS_Shape &aPart = anIt.Value();
3985 if(aWhereIndices.Contains(aPart) && aMFence.Add(aPart)) {
3991 if (aLSA.Extent() == 0) {
3992 SetErrorCode(NOT_FOUND_ANY); // Not found any Results
3996 Handle(TColStd_HArray1OfInteger) aModifiedArray = new TColStd_HArray1OfInteger (1, aLSA.Extent());
3997 TopTools_ListIteratorOfListOfShape anIterModif (aLSA);
3998 for (Standard_Integer imod = 1; anIterModif.More(); anIterModif.Next(), imod++) {
3999 if (aWhereIndices.Contains(anIterModif.Value())) {
4000 aModifiedArray->SetValue(imod, aWhereIndices.FindIndex(anIterModif.Value()));
4003 SetErrorCode("Error: wrong sub-shape returned");
4009 Handle(GEOM_Object) aResult = GetEngine()->AddSubShape(theShapeWhere, aModifiedArray);
4010 if (aResult.IsNull()) {
4011 SetErrorCode("Error in algorithm: result found, but cannot be returned.");
4015 if (aModifiedArray->Length() > 1 || theShapeWhat->GetType() == GEOM_GROUP) {
4017 aResult->SetType(GEOM_GROUP);
4019 //Set a sub-shape type
4020 TopoDS_Shape aFirstFound = aLSA.First();
4021 TopAbs_ShapeEnum aShapeType = aFirstFound.ShapeType();
4023 TDF_Label aFreeLabel = aResult->GetFreeLabel();
4024 TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aShapeType);
4027 //Make a Python command
4028 Handle(GEOM_Function) aFunction = aResult->GetFunction(1);
4030 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetInPlace("
4031 << theShapeWhere << ", " << theShapeWhat << ", True)";
4037 //=============================================================================
4039 * case GetInPlaceOld:
4042 //=============================================================================
4043 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlaceOld
4044 (Handle(GEOM_Object) theShapeWhere,
4045 Handle(GEOM_Object) theShapeWhat)
4049 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
4051 TopoDS_Shape aWhere = theShapeWhere->GetValue();
4052 TopoDS_Shape aWhat = theShapeWhat->GetValue();
4053 TopTools_ListOfShape aModifiedList;
4054 const Standard_Integer iErr =
4055 GEOMAlgo_GetInPlaceAPI::GetInPlaceOld(aWhere, aWhat, aModifiedList);
4060 SetErrorCode("Error: aWhere and aWhat TopoDS_Shape are Null.");
4064 ("Error: An attempt to extract a shape of not supported type.");
4067 SetErrorCode(NOT_FOUND_ANY);
4070 SetErrorCode("Shape driver failed");
4077 TopTools_IndexedMapOfShape aWhereIndices;
4078 TopExp::MapShapes(aWhere, aWhereIndices);
4080 Handle(TColStd_HArray1OfInteger) aModifiedArray =
4081 new TColStd_HArray1OfInteger (1, aModifiedList.Extent());
4082 TopTools_ListIteratorOfListOfShape anIterModif (aModifiedList);
4083 Standard_Integer imod;
4085 for (imod = 1; anIterModif.More(); anIterModif.Next(), imod++) {
4086 const Standard_Integer anIndex =
4087 aWhereIndices.FindIndex(anIterModif.Value());
4089 aModifiedArray->SetValue(imod, anIndex);
4093 Handle(GEOM_Object) aResult =
4094 GetEngine()->AddSubShape(theShapeWhere, aModifiedArray);
4096 if (aResult.IsNull()) {
4097 SetErrorCode("Error in algorithm: result found, but cannot be returned.");
4101 if (aModifiedArray->Length() > 1 || theShapeWhat->GetType() == GEOM_GROUP) {
4103 aResult->SetType(GEOM_GROUP);
4105 //Set a sub-shape type
4106 TopoDS_Shape aFirstFound = aWhereIndices.FindKey(aModifiedArray->Value(1));
4107 TopAbs_ShapeEnum aShapeType = aFirstFound.ShapeType();
4109 TDF_Label aFreeLabel = aResult->GetFreeLabel();
4110 TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aShapeType);
4113 //Make a Python command
4114 Handle(GEOM_Function) aFunction = aResult->GetFunction(1);
4116 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetInPlace("
4117 << theShapeWhere << ", " << theShapeWhat << ", False)";
4124 //=======================================================================
4125 //function : GetInPlaceByHistory
4127 //=======================================================================
4128 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlaceByHistory
4129 (Handle(GEOM_Object) theShapeWhere,
4130 Handle(GEOM_Object) theShapeWhat)
4134 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
4136 TopoDS_Shape aWhere = theShapeWhere->GetValue();
4137 TopoDS_Shape aWhat = theShapeWhat->GetValue();
4139 if (aWhere.IsNull() || aWhat.IsNull()) return NULL;
4141 Handle(GEOM_Function) aWhereFunction = theShapeWhere->GetLastFunction();
4142 if (aWhereFunction.IsNull()) return NULL;
4144 //Fill array of indices
4145 TopTools_IndexedMapOfShape aWhereIndices;
4147 TopExp::MapShapes(aWhere, aWhereIndices);
4150 TopTools_ListOfShape aModifiedList;
4151 bool isFound = GEOMAlgo_GetInPlaceAPI::GetInPlaceByHistory
4152 (aWhereFunction, aWhereIndices, aWhat, aModifiedList);
4154 if (!isFound || aModifiedList.Extent() < 1) {
4155 SetErrorCode("Error: No history found for the sought shape or its sub-shapes.");
4159 Standard_Integer nbFound = aModifiedList.Extent();
4160 TopTools_ListIteratorOfListOfShape anIterModif (aModifiedList);
4163 // remove sub-shapes inappropriate for group creation
4164 TopAbs_ShapeEnum subType = TopAbs_SHAPE;
4165 while ( anIterModif.More() ) {
4166 TopAbs_ShapeEnum type = anIterModif.Value().ShapeType();
4167 bool okForGroup = ( type == TopAbs_VERTEX || type == TopAbs_EDGE ||
4168 type == TopAbs_FACE || type == TopAbs_SOLID );
4170 if ( subType == TopAbs_SHAPE )
4173 okForGroup = ( subType == type );
4178 aModifiedList.Remove( anIterModif );
4179 nbFound -= ( !okForGroup );
4181 if ( nbFound == 0 ) {
4182 SetErrorCode("Error: result found but it's type is inappropriate for group creation.");
4187 Handle(TColStd_HArray1OfInteger) aModifiedArray =
4188 new TColStd_HArray1OfInteger( 1, nbFound );
4189 anIterModif.Initialize(aModifiedList);
4190 for (Standard_Integer imod = 1; anIterModif.More(); anIterModif.Next(), imod++)
4191 aModifiedArray->SetValue
4192 (imod, aWhereIndices.FindIndex(anIterModif.Value()));
4195 Handle(GEOM_Object) aResult = GetEngine()->AddSubShape(theShapeWhere, aModifiedArray);
4196 if (aResult.IsNull()) {
4197 SetErrorCode("Error in algorithm: result found, but cannot be returned.");
4201 if (aModifiedArray->Length() > 1) {
4203 aResult->SetType(GEOM_GROUP);
4205 //Set a sub-shape type
4206 TopoDS_Shape aFirstFound = aWhereIndices.FindKey(aModifiedArray->Value(1));
4207 TopAbs_ShapeEnum aShapeType = aFirstFound.ShapeType();
4209 TDF_Label aFreeLabel = aResult->GetFreeLabel();
4210 TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aShapeType);
4213 //Make a Python command
4214 Handle(GEOM_Function) aFunction = aResult->GetFunction(1);
4216 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetInPlaceByHistory("
4217 << theShapeWhere << ", " << theShapeWhat << ")";
4223 #define MAX_TOLERANCE 1.e-7
4225 //=======================================================================
4226 //function : isSameEdge
4227 //purpose : Returns True if two edges coincide
4228 //=======================================================================
4229 static bool isSameEdge(const TopoDS_Edge& theEdge1, const TopoDS_Edge& theEdge2)
4231 TopoDS_Vertex V11, V12, V21, V22;
4232 TopExp::Vertices(theEdge1, V11, V12);
4233 TopExp::Vertices(theEdge2, V21, V22);
4234 gp_Pnt P11 = BRep_Tool::Pnt(V11);
4235 gp_Pnt P12 = BRep_Tool::Pnt(V12);
4236 gp_Pnt P21 = BRep_Tool::Pnt(V21);
4237 gp_Pnt P22 = BRep_Tool::Pnt(V22);
4238 bool coincide = false;
4240 //Check that ends of edges coincide
4241 if(P11.Distance(P21) <= MAX_TOLERANCE) {
4242 if(P12.Distance(P22) <= MAX_TOLERANCE) coincide = true;
4244 else if(P11.Distance(P22) <= MAX_TOLERANCE) {
4245 if(P12.Distance(P21) <= MAX_TOLERANCE) coincide = true;
4248 if(!coincide) return false;
4250 if (BRep_Tool::Degenerated(theEdge1))
4251 if (BRep_Tool::Degenerated(theEdge2)) return true;
4254 if (BRep_Tool::Degenerated(theEdge2)) return false;
4256 double U11, U12, U21, U22;
4257 Handle(Geom_Curve) C1 = BRep_Tool::Curve(theEdge1, U11, U12);
4258 Handle(Geom_Curve) C2 = BRep_Tool::Curve(theEdge2, U21, U22);
4259 if(C1->DynamicType() == C2->DynamicType()) return true;
4261 //Check that both edges has the same geometry
4262 double range = U12-U11;
4263 double U = U11+ range/3.0;
4264 gp_Pnt P1 = C1->Value(U); //Compute a point on one third of the edge's length
4265 U = U11+range*2.0/3.0;
4266 gp_Pnt P2 = C1->Value(U); //Compute a point on two thirds of the edge's length
4268 if(!GeomLib_Tool::Parameter(C2, P1, MAX_TOLERANCE, U) || U < U21 || U > U22)
4271 if(P1.Distance(C2->Value(U)) > MAX_TOLERANCE) return false;
4273 if(!GeomLib_Tool::Parameter(C2, P2, MAX_TOLERANCE, U) || U < U21 || U > U22)
4276 if(P2.Distance(C2->Value(U)) > MAX_TOLERANCE) return false;
4281 #include <TopoDS_TShape.hxx>
4282 //=======================================================================
4283 //function : isSameFace
4284 //purpose : Returns True if two faces coincide
4285 //=======================================================================
4286 static bool isSameFace(const TopoDS_Face& theFace1, const TopoDS_Face& theFace2)
4288 TopExp_Explorer E(theFace1, TopAbs_EDGE);
4289 TopTools_ListOfShape LS1, LS2;
4290 for(; E.More(); E.Next()) LS1.Append(E.Current());
4292 E.Init(theFace2, TopAbs_EDGE);
4293 for(; E.More(); E.Next()) LS2.Append(E.Current());
4295 //Compare the number of edges in the faces
4296 if(LS1.Extent() != LS2.Extent()) return false;
4298 double aMin = RealFirst(), aMax = RealLast();
4299 double xminB1=aMax, yminB1=aMax, zminB1=aMax, xminB2=aMax, yminB2=aMax, zminB2=aMax;
4300 double xmaxB1=aMin, ymaxB1=aMin, zmaxB1=aMin, xmaxB2=aMin, ymaxB2=aMin, zmaxB2=aMin;
4302 for(E.Init(theFace1, TopAbs_VERTEX); E.More(); E.Next()) {
4303 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4304 if(P.X() < xminB1) xminB1 = P.X();
4305 if(P.Y() < yminB1) yminB1 = P.Y();
4306 if(P.Z() < zminB1) zminB1 = P.Z();
4307 if(P.X() > xmaxB1) xmaxB1 = P.X();
4308 if(P.Y() > ymaxB1) ymaxB1 = P.Y();
4309 if(P.Z() > zmaxB1) zmaxB1 = P.Z();
4312 for(E.Init(theFace2, TopAbs_VERTEX); E.More(); E.Next()) {
4313 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4314 if(P.X() < xminB2) xminB2 = P.X();
4315 if(P.Y() < yminB2) yminB2 = P.Y();
4316 if(P.Z() < zminB2) zminB2 = P.Z();
4317 if(P.X() > xmaxB2) xmaxB2 = P.X();
4318 if(P.Y() > ymaxB2) ymaxB2 = P.Y();
4319 if(P.Z() > zmaxB2) zmaxB2 = P.Z();
4322 //Compare the bounding boxes of both faces
4323 if(gp_Pnt(xminB1, yminB1, zminB1).Distance(gp_Pnt(xminB2, yminB2, zminB2)) > MAX_TOLERANCE)
4326 if(gp_Pnt(xmaxB1, ymaxB1, zmaxB1).Distance(gp_Pnt(xmaxB2, ymaxB2, zmaxB2)) > MAX_TOLERANCE)
4329 Handle(Geom_Surface) S1 = BRep_Tool::Surface(theFace1);
4330 Handle(Geom_Surface) S2 = BRep_Tool::Surface(theFace2);
4332 //Check if there a coincidence of two surfaces at least in two points
4333 double U11, U12, V11, V12, U21, U22, V21, V22;
4334 BRepTools::UVBounds(theFace1, U11, U12, V11, V12);
4335 BRepTools::UVBounds(theFace2, U21, U22, V21, V22);
4337 double rangeU = U12-U11;
4338 double rangeV = V12-V11;
4339 double U = U11 + rangeU/3.0;
4340 double V = V11 + rangeV/3.0;
4341 gp_Pnt P1 = S1->Value(U, V);
4342 U = U11+rangeU*2.0/3.0;
4343 V = V11+rangeV*2.0/3.0;
4344 gp_Pnt P2 = S1->Value(U, V);
4346 if (!GeomLib_Tool::Parameters(S2, P1, MAX_TOLERANCE, U, V) || U < U21 || U > U22 || V < V21 || V > V22)
4349 if (P1.Distance(S2->Value(U,V)) > MAX_TOLERANCE) return false;
4351 if (!GeomLib_Tool::Parameters(S2, P2, MAX_TOLERANCE, U, V) || U < U21 || U > U22 || V < V21 || V > V22)
4354 if (P2.Distance(S2->Value(U, V)) > MAX_TOLERANCE) return false;
4356 //Check that each edge of the Face1 has a counterpart in the Face2
4357 TopTools_MapOfOrientedShape aMap;
4358 TopTools_ListIteratorOfListOfShape LSI1(LS1);
4359 for(; LSI1.More(); LSI1.Next()) {
4360 TopoDS_Edge E = TopoDS::Edge(LSI1.Value());
4361 bool isFound = false;
4362 TopTools_ListIteratorOfListOfShape LSI2(LS2);
4363 for(; LSI2.More(); LSI2.Next()) {
4364 TopoDS_Shape aValue = LSI2.Value();
4365 if(aMap.Contains(aValue)) continue; //To avoid checking already found edge several times
4366 if(isSameEdge(E, TopoDS::Edge(aValue))) {
4372 if(!isFound) return false;
4378 //=======================================================================
4379 //function : isSameSolid
4380 //purpose : Returns True if two solids coincide
4381 //=======================================================================
4382 bool isSameSolid(const TopoDS_Solid& theSolid1, const TopoDS_Solid& theSolid2)
4384 TopExp_Explorer E(theSolid1, TopAbs_FACE);
4385 TopTools_ListOfShape LS1, LS2;
4386 for(; E.More(); E.Next()) LS1.Append(E.Current());
4387 E.Init(theSolid2, TopAbs_FACE);
4388 for(; E.More(); E.Next()) LS2.Append(E.Current());
4390 if(LS1.Extent() != LS2.Extent()) return false;
4392 double aMin = RealFirst(), aMax = RealLast();
4393 double xminB1=aMax, yminB1=aMax, zminB1=aMax, xminB2=aMax, yminB2=aMax, zminB2=aMax;
4394 double xmaxB1=aMin, ymaxB1=aMin, zmaxB1=aMin, xmaxB2=aMin, ymaxB2=aMin, zmaxB2=aMin;
4396 for(E.Init(theSolid1, TopAbs_VERTEX); E.More(); E.Next()) {
4397 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4398 if(P.X() < xminB1) xminB1 = P.X();
4399 if(P.Y() < yminB1) yminB1 = P.Y();
4400 if(P.Z() < zminB1) zminB1 = P.Z();
4401 if(P.X() > xmaxB1) xmaxB1 = P.X();
4402 if(P.Y() > ymaxB1) ymaxB1 = P.Y();
4403 if(P.Z() > zmaxB1) zmaxB1 = P.Z();
4406 for(E.Init(theSolid2, TopAbs_VERTEX); E.More(); E.Next()) {
4407 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4408 if(P.X() < xminB2) xminB2 = P.X();
4409 if(P.Y() < yminB2) yminB2 = P.Y();
4410 if(P.Z() < zminB2) zminB2 = P.Z();
4411 if(P.X() > xmaxB2) xmaxB2 = P.X();
4412 if(P.Y() > ymaxB2) ymaxB2 = P.Y();
4413 if(P.Z() > zmaxB2) zmaxB2 = P.Z();
4416 //Compare the bounding boxes of both solids
4417 if(gp_Pnt(xminB1, yminB1, zminB1).Distance(gp_Pnt(xminB2, yminB2, zminB2)) > MAX_TOLERANCE)
4420 if(gp_Pnt(xmaxB1, ymaxB1, zmaxB1).Distance(gp_Pnt(xmaxB2, ymaxB2, zmaxB2)) > MAX_TOLERANCE)
4423 //Check that each face of the Solid1 has a counterpart in the Solid2
4424 TopTools_MapOfOrientedShape aMap;
4425 TopTools_ListIteratorOfListOfShape LSI1(LS1);
4426 for(; LSI1.More(); LSI1.Next()) {
4427 TopoDS_Face F = TopoDS::Face(LSI1.Value());
4428 bool isFound = false;
4429 TopTools_ListIteratorOfListOfShape LSI2(LS2);
4430 for(; LSI2.More(); LSI2.Next()) {
4431 if(aMap.Contains(LSI2.Value())) continue; //To avoid checking already found faces several times
4432 if(isSameFace(F, TopoDS::Face(LSI2.Value()))) {
4433 aMap.Add(LSI2.Value());
4438 if(!isFound) return false;
4444 //=======================================================================
4445 //function : GetSame
4447 //=======================================================================
4448 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetSame(const Handle(GEOM_Object)& theShapeWhere,
4449 const Handle(GEOM_Object)& theShapeWhat)
4452 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
4454 TopoDS_Shape aWhere = theShapeWhere->GetValue();
4455 TopoDS_Shape aWhat = theShapeWhat->GetValue();
4457 if (aWhere.IsNull() || aWhat.IsNull()) return NULL;
4460 bool isFound = false;
4461 TopoDS_Shape aSubShape;
4462 TopTools_MapOfShape aMap;
4464 if (aWhat.ShapeType() == TopAbs_COMPOUND || aWhat.ShapeType() == TopAbs_COMPSOLID) {
4465 TopoDS_Iterator It (aWhat, Standard_True, Standard_True);
4466 if (It.More()) aWhat = It.Value();
4469 SetErrorCode("Compounds of two or more shapes are not allowed for aWhat argument");
4474 switch (aWhat.ShapeType()) {
4475 case TopAbs_VERTEX: {
4476 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(aWhat));
4477 TopExp_Explorer E(aWhere, TopAbs_VERTEX);
4478 for(; E.More(); E.Next()) {
4479 if(!aMap.Add(E.Current())) continue;
4480 gp_Pnt P2 = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4481 if(P.Distance(P2) <= MAX_TOLERANCE) {
4483 aSubShape = E.Current();
4490 TopoDS_Edge anEdge = TopoDS::Edge(aWhat);
4491 TopExp_Explorer E(aWhere, TopAbs_EDGE);
4492 for(; E.More(); E.Next()) {
4493 if(!aMap.Add(E.Current())) continue;
4494 if(isSameEdge(anEdge, TopoDS::Edge(E.Current()))) {
4495 aSubShape = E.Current();
4503 TopoDS_Face aFace = TopoDS::Face(aWhat);
4504 TopExp_Explorer E(aWhere, TopAbs_FACE);
4505 for(; E.More(); E.Next()) {
4506 if(!aMap.Add(E.Current())) continue;
4507 if(isSameFace(aFace, TopoDS::Face(E.Current()))) {
4508 aSubShape = E.Current();
4515 case TopAbs_SOLID: {
4516 TopoDS_Solid aSolid = TopoDS::Solid(aWhat);
4517 TopExp_Explorer E(aWhere, TopAbs_SOLID);
4518 for(; E.More(); E.Next()) {
4519 if(!aMap.Add(E.Current())) continue;
4520 if(isSameSolid(aSolid, TopoDS::Solid(E.Current()))) {
4521 aSubShape = E.Current();
4533 TopTools_IndexedMapOfShape anIndices;
4534 TopExp::MapShapes(aWhere, anIndices);
4535 if (anIndices.Contains(aSubShape))
4536 anIndex = anIndices.FindIndex(aSubShape);
4539 if (anIndex < 0) return NULL;
4541 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
4543 anArray->SetValue(1, anIndex);
4545 Handle(GEOM_Object) aResult = GetEngine()->AddSubShape(theShapeWhere, anArray);
4546 Handle(GEOM_Function) aFunction = aResult->GetLastFunction();
4548 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetSame("
4549 << theShapeWhere << ", " << theShapeWhat << ")";
4557 //=======================================================================
4558 //function : GetSameIDs
4560 //=======================================================================
4561 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetSameIDs
4562 (const Handle(GEOM_Object)& theShapeWhere,
4563 const Handle(GEOM_Object)& theShapeWhat)
4566 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
4568 TopoDS_Shape aWhere = theShapeWhere->GetValue();
4569 TopoDS_Shape aWhat = theShapeWhat->GetValue();
4571 if (aWhere.IsNull() || aWhat.IsNull()) return NULL;
4573 TopTools_ListOfShape listShape;
4574 TopTools_MapOfShape aMap;
4576 if (aWhat.ShapeType() == TopAbs_COMPOUND || aWhat.ShapeType() == TopAbs_COMPSOLID) {
4577 TopoDS_Iterator It (aWhat, Standard_True, Standard_True);
4578 if (It.More()) aWhat = It.Value();
4581 SetErrorCode("Compounds of two or more shapes are not allowed for aWhat argument");
4586 switch (aWhat.ShapeType()) {
4587 case TopAbs_VERTEX: {
4588 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(aWhat));
4589 TopExp_Explorer E(aWhere, TopAbs_VERTEX);
4590 for(; E.More(); E.Next()) {
4591 if(!aMap.Add(E.Current())) continue;
4592 gp_Pnt P2 = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4593 if(P.Distance(P2) <= MAX_TOLERANCE) {
4594 listShape.Append(E.Current());
4600 TopoDS_Edge anEdge = TopoDS::Edge(aWhat);
4601 TopExp_Explorer E(aWhere, TopAbs_EDGE);
4602 for(; E.More(); E.Next()) {
4603 if(!aMap.Add(E.Current())) continue;
4604 if(isSameEdge(anEdge, TopoDS::Edge(E.Current()))) {
4605 listShape.Append(E.Current());
4611 TopoDS_Face aFace = TopoDS::Face(aWhat);
4612 TopExp_Explorer E(aWhere, TopAbs_FACE);
4613 for(; E.More(); E.Next()) {
4614 if(!aMap.Add(E.Current())) continue;
4615 if(isSameFace(aFace, TopoDS::Face(E.Current()))) {
4616 listShape.Append(E.Current());
4621 case TopAbs_SOLID: {
4622 TopoDS_Solid aSolid = TopoDS::Solid(aWhat);
4623 TopExp_Explorer E(aWhere, TopAbs_SOLID);
4624 for(; E.More(); E.Next()) {
4625 if(!aMap.Add(E.Current())) continue;
4626 if(isSameSolid(aSolid, TopoDS::Solid(E.Current()))) {
4627 listShape.Append(E.Current());
4636 if ( !listShape.IsEmpty() ) {
4637 TopTools_IndexedMapOfShape anIndices;
4638 TopExp::MapShapes(aWhere, anIndices);
4639 TopTools_ListIteratorOfListOfShape itSub (listShape);
4640 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
4641 for (; itSub.More(); itSub.Next()) {
4642 if (anIndices.Contains(itSub.Value()))
4643 aSeq->Append(anIndices.FindIndex(itSub.Value()));
4646 // The GetSameIDs() doesn't change object so no new function is required.
4647 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShapeWhere,theShapeWhat)->GetLastFunction();
4649 // Make a Python command
4650 GEOM::TPythonDump(aFunction, /*append=*/true)
4651 << "listSameIDs = geompy.GetSameIDs("
4652 << theShapeWhere << ", "
4653 << theShapeWhat << ")";
4656 SetErrorCode(NOT_FOUND_ANY);
4661 //=======================================================================
4662 //function : ExtendEdge
4664 //=======================================================================
4665 Handle(GEOM_Object) GEOMImpl_IShapesOperations::ExtendEdge
4666 (const Handle(GEOM_Object) &theEdge,
4667 const Standard_Real theMin,
4668 const Standard_Real theMax)
4672 if (theEdge.IsNull()) {
4676 //Add a new Edge object
4677 Handle(GEOM_Object) aResEdge = GetEngine()->AddObject(GetDocID(), GEOM_EDGE);
4679 //Add a new Vector function
4680 Handle(GEOM_Function) aFunction =
4681 aResEdge->AddFunction(GEOMImpl_ShapeDriver::GetID(), EDGE_UV);
4683 //Check if the function is set correctly
4684 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) {
4688 GEOMImpl_IShapeExtend aCI (aFunction);
4690 Handle(GEOM_Function) anEdge = theEdge->GetLastFunction();
4692 if (anEdge.IsNull()) {
4696 aCI.SetShape(anEdge);
4697 aCI.SetUMin(theMin);
4698 aCI.SetUMax(theMax);
4700 //Compute the Edge value
4703 if (!GetSolver()->ComputeFunction(aFunction)) {
4704 SetErrorCode("Shape driver failed");
4709 catch (Standard_Failure) {
4710 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
4711 SetErrorCode(aFail->GetMessageString());
4716 //Make a Python command
4717 GEOM::TPythonDump(aFunction)
4718 << aResEdge << " = geompy.ExtendEdge("
4719 << theEdge << ", " << theMin << ", " << theMax << ")";
4726 //=======================================================================
4727 //function : ExtendFace
4729 //=======================================================================
4730 Handle(GEOM_Object) GEOMImpl_IShapesOperations::ExtendFace
4731 (const Handle(GEOM_Object) &theFace,
4732 const Standard_Real theUMin,
4733 const Standard_Real theUMax,
4734 const Standard_Real theVMin,
4735 const Standard_Real theVMax)
4739 if (theFace.IsNull()) {
4743 //Add a new Face object
4744 Handle(GEOM_Object) aResFace = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
4746 //Add a new Vector function
4747 Handle(GEOM_Function) aFunction =
4748 aResFace->AddFunction(GEOMImpl_ShapeDriver::GetID(), FACE_UV);
4750 //Check if the function is set correctly
4751 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) {
4755 GEOMImpl_IShapeExtend aCI (aFunction);
4757 Handle(GEOM_Function) aFace = theFace->GetLastFunction();
4759 if (aFace.IsNull()) {
4763 aCI.SetShape(aFace);
4764 aCI.SetUMin(theUMin);
4765 aCI.SetUMax(theUMax);
4766 aCI.SetVMin(theVMin);
4767 aCI.SetVMax(theVMax);
4769 //Compute the Face value
4772 if (!GetSolver()->ComputeFunction(aFunction)) {
4773 SetErrorCode("Shape driver failed");
4778 catch (Standard_Failure) {
4779 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
4780 SetErrorCode(aFail->GetMessageString());
4785 //Make a Python command
4786 GEOM::TPythonDump(aFunction)
4787 << aResFace << " = geompy.ExtendFace("
4788 << theFace << ", " << theUMin << ", " << theUMax << ", "
4789 << theVMin << ", " << theVMax << ")";
4796 //=======================================================================
4797 //function : MakeSurfaceFromFace
4799 //=======================================================================
4800 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeSurfaceFromFace
4801 (const Handle(GEOM_Object) &theFace)
4805 if (theFace.IsNull()) {
4809 //Add a new Face object
4810 Handle(GEOM_Object) aResFace = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
4812 //Add a new Vector function
4813 Handle(GEOM_Function) aFunction =
4814 aResFace->AddFunction(GEOMImpl_ShapeDriver::GetID(), SURFACE_FROM_FACE);
4816 //Check if the function is set correctly
4817 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) {
4821 GEOMImpl_IShapeExtend aCI (aFunction);
4823 Handle(GEOM_Function) aFace = theFace->GetLastFunction();
4825 if (aFace.IsNull()) {
4829 aCI.SetShape(aFace);
4831 //Compute the Face value
4834 if (!GetSolver()->ComputeFunction(aFunction)) {
4835 SetErrorCode("Shape driver failed");
4840 catch (Standard_Failure) {
4841 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
4842 SetErrorCode(aFail->GetMessageString());
4847 //Make a Python command
4848 GEOM::TPythonDump(aFunction)
4849 << aResFace << " = geompy.MakeSurfaceFromFace("