1 // Copyright (C) 2007-2015 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_ClsfQuad.hxx"
58 #include "GEOMAlgo_ClsfSolid.hxx"
59 #include "GEOMAlgo_ClsfSurf.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);
126 const double MAX_TOLERANCE = 1.e-7;
129 * \brief Returns the vertex from theWhere shape that is coincident with
132 * \param theWhere the shape where the coinsident vertex is searched.
133 * \param theVertex the vertex to be searched.
134 * \return the coincident vertex if it is found. Otherwise null object.
136 static TopoDS_Vertex getSameVertex(const TopoDS_Shape &theWhere,
137 const TopoDS_Vertex &theVertex)
139 TopoDS_Vertex aResult;
140 gp_Pnt aPoint = BRep_Tool::Pnt(theVertex);
141 TopExp_Explorer anExp(theWhere, TopAbs_VERTEX);
142 TopTools_MapOfShape aMap;
144 for(; anExp.More(); anExp.Next()) {
145 const TopoDS_Shape &aLocalShape = anExp.Current();
147 if(!aMap.Add(aLocalShape)) {
151 TopoDS_Vertex aVertex = TopoDS::Vertex(aLocalShape);
152 gp_Pnt aPoint2 = BRep_Tool::Pnt(aVertex);
154 if(aPoint.Distance(aPoint2) <= MAX_TOLERANCE) {
162 } // end of namespace
164 //=============================================================================
168 //=============================================================================
169 GEOMImpl_IShapesOperations::GEOMImpl_IShapesOperations (GEOM_Engine* theEngine, int theDocID)
170 : GEOM_IOperations(theEngine, theDocID)
172 MESSAGE("GEOMImpl_IShapesOperations::GEOMImpl_IShapesOperations");
175 //=============================================================================
179 //=============================================================================
180 GEOMImpl_IShapesOperations::~GEOMImpl_IShapesOperations()
182 MESSAGE("GEOMImpl_IShapesOperations::~GEOMImpl_IShapesOperations");
185 //=============================================================================
189 //=============================================================================
190 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeEdge
191 (Handle(GEOM_Object) thePnt1, Handle(GEOM_Object) thePnt2)
195 if (thePnt1.IsNull() || thePnt2.IsNull()) return NULL;
197 //Add a new Edge object
198 Handle(GEOM_Object) anEdge = GetEngine()->AddObject(GetDocID(), GEOM_EDGE);
200 //Add a new Vector function
201 Handle(GEOM_Function) aFunction =
202 anEdge->AddFunction(GEOMImpl_VectorDriver::GetID(), VECTOR_TWO_PNT);
204 //Check if the function is set correctly
205 if (aFunction->GetDriverGUID() != GEOMImpl_VectorDriver::GetID()) return NULL;
207 GEOMImpl_IVector aPI (aFunction);
209 Handle(GEOM_Function) aRef1 = thePnt1->GetLastFunction();
210 Handle(GEOM_Function) aRef2 = thePnt2->GetLastFunction();
211 if (aRef1.IsNull() || aRef2.IsNull()) return NULL;
213 aPI.SetPoint1(aRef1);
214 aPI.SetPoint2(aRef2);
216 //Compute the Edge value
219 if (!GetSolver()->ComputeFunction(aFunction)) {
220 SetErrorCode("Vector driver failed");
224 catch (Standard_Failure) {
225 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
226 SetErrorCode(aFail->GetMessageString());
230 //Make a Python command
231 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdge("
232 << thePnt1 << ", " << thePnt2 << ")";
238 //=============================================================================
240 * MakeEdgeOnCurveByLength
242 //=============================================================================
243 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeEdgeOnCurveByLength
244 (Handle(GEOM_Object) theRefCurve,
245 const Standard_Real theLength,
246 Handle(GEOM_Object) theStartPoint)
250 if (theRefCurve.IsNull()) return NULL;
252 //Add a new Edge object
253 Handle(GEOM_Object) anEdge = GetEngine()->AddObject(GetDocID(), GEOM_EDGE);
255 //Add a new Vector function
256 Handle(GEOM_Function) aFunction =
257 anEdge->AddFunction(GEOMImpl_ShapeDriver::GetID(), EDGE_CURVE_LENGTH);
259 //Check if the function is set correctly
260 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
262 GEOMImpl_IVector aPI (aFunction);
264 Handle(GEOM_Function) aRef1 = theRefCurve->GetLastFunction();
265 if (aRef1.IsNull()) return NULL;
266 aPI.SetPoint1(aRef1);
268 if (!theStartPoint.IsNull()) {
269 Handle(GEOM_Function) aRef2 = theStartPoint->GetLastFunction();
270 aPI.SetPoint2(aRef2);
273 aPI.SetParameter(theLength);
275 //Compute the Edge value
278 if (!GetSolver()->ComputeFunction(aFunction)) {
279 SetErrorCode("Vector driver failed");
283 catch (Standard_Failure) {
284 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
285 SetErrorCode(aFail->GetMessageString());
289 //Make a Python command
290 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdgeOnCurveByLength("
291 << theRefCurve << ", " << theLength << ", " << theStartPoint << ")";
297 //=============================================================================
301 //=============================================================================
302 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeEdgeWire
303 (Handle(GEOM_Object) theWire,
304 const Standard_Real theLinearTolerance,
305 const Standard_Real theAngularTolerance)
309 if (theWire.IsNull()) return NULL;
311 //Add a new Edge object
312 Handle(GEOM_Object) anEdge = GetEngine()->AddObject(GetDocID(), GEOM_EDGE);
314 //Add a new Vector function
315 Handle(GEOM_Function) aFunction =
316 anEdge->AddFunction(GEOMImpl_ShapeDriver::GetID(), EDGE_WIRE);
318 //Check if the function is set correctly
319 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
321 GEOMImpl_IShapes aCI (aFunction);
323 Handle(GEOM_Function) aWire = theWire->GetLastFunction();
325 if (aWire.IsNull()) return NULL;
328 aCI.SetTolerance(theLinearTolerance);
329 aCI.SetAngularTolerance(theAngularTolerance);
331 //Compute the Edge value
334 if (!GetSolver()->ComputeFunction(aFunction)) {
335 SetErrorCode("Shape driver failed");
339 catch (Standard_Failure) {
340 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
341 SetErrorCode(aFail->GetMessageString());
345 const double DEF_LIN_TOL = Precision::Confusion();
346 const double DEF_ANG_TOL = Precision::Angular();
347 //Make a Python command
348 if ( theAngularTolerance == DEF_ANG_TOL ) {
349 if ( theLinearTolerance == DEF_LIN_TOL )
350 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdgeWire("
353 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdgeWire("
354 << theWire << ", " << theLinearTolerance << ")";
357 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdgeWire("
358 << theWire << ", " << theLinearTolerance << ", "
359 << theAngularTolerance << ")";
366 //=============================================================================
370 //=============================================================================
371 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeWire
372 (std::list<Handle(GEOM_Object)> theShapes,
373 const Standard_Real theTolerance)
378 Handle(GEOM_Object) aWire = GetEngine()->AddObject(GetDocID(), GEOM_WIRE);
381 Handle(GEOM_Function) aFunction =
382 aWire->AddFunction(GEOMImpl_ShapeDriver::GetID(), WIRE_EDGES);
383 if (aFunction.IsNull()) return NULL;
385 //Check if the function is set correctly
386 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
388 GEOMImpl_IShapes aCI (aFunction);
389 aCI.SetTolerance(theTolerance);
391 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
394 std::list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
395 for (; it != theShapes.end(); it++) {
396 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
397 if (aRefSh.IsNull()) {
398 SetErrorCode("NULL argument shape for the shape construction");
401 aShapesSeq->Append(aRefSh);
403 aCI.SetShapes(aShapesSeq);
408 if (!GetSolver()->ComputeFunction(aFunction)) {
409 SetErrorCode("Shape driver failed");
413 catch (Standard_Failure) {
414 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
415 SetErrorCode(aFail->GetMessageString());
419 //Make a Python command
420 GEOM::TPythonDump pd (aFunction);
421 pd << aWire << " = geompy.MakeWire([";
424 it = theShapes.begin();
425 if (it != theShapes.end()) {
427 while (it != theShapes.end()) {
428 pd << ", " << (*it++);
431 pd << "], " << theTolerance << ")";
437 //=============================================================================
441 //=============================================================================
442 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFace (Handle(GEOM_Object) theWire,
443 const bool isPlanarWanted)
447 if (theWire.IsNull()) return NULL;
449 //Add a new Face object
450 Handle(GEOM_Object) aFace = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
452 //Add a new Shape function for creation of a face from a wire
453 Handle(GEOM_Function) aFunction =
454 aFace->AddFunction(GEOMImpl_ShapeDriver::GetID(), FACE_WIRE);
455 if (aFunction.IsNull()) return NULL;
457 //Check if the function is set correctly
458 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
460 GEOMImpl_IShapes aCI (aFunction);
462 Handle(GEOM_Function) aRefWire = theWire->GetLastFunction();
464 if (aRefWire.IsNull()) return NULL;
466 aCI.SetBase(aRefWire);
467 aCI.SetIsPlanar(isPlanarWanted);
469 //Compute the Face value
470 Standard_Boolean isWarning = Standard_False;
473 if (!GetSolver()->ComputeFunction(aFunction)) {
474 SetErrorCode("Shape driver failed to compute a face");
478 catch (Standard_Failure) {
479 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
480 SetErrorCode(aFail->GetMessageString());
481 // to provide warning
482 if (!aFunction->GetValue().IsNull()) {
483 isWarning = Standard_True;
489 //Make a Python command
490 GEOM::TPythonDump(aFunction) << aFace << " = geompy.MakeFace("
491 << theWire << ", " << (int)isPlanarWanted << ")";
493 // to provide warning
494 if (!isWarning) SetErrorCode(OK);
498 //=============================================================================
502 //=============================================================================
503 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFaceWires
504 (std::list<Handle(GEOM_Object)> theShapes,
505 const bool isPlanarWanted)
510 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
513 Handle(GEOM_Function) aFunction =
514 aShape->AddFunction(GEOMImpl_ShapeDriver::GetID(), FACE_WIRES);
515 if (aFunction.IsNull()) return NULL;
517 //Check if the function is set correctly
518 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
520 GEOMImpl_IShapes aCI (aFunction);
522 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
525 std::list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
526 for (; it != theShapes.end(); it++) {
527 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
528 if (aRefSh.IsNull()) {
529 SetErrorCode("NULL argument shape for the face construction");
532 aShapesSeq->Append(aRefSh);
534 aCI.SetShapes(aShapesSeq);
536 aCI.SetIsPlanar(isPlanarWanted);
539 Standard_Boolean isWarning = Standard_False;
542 if (!GetSolver()->ComputeFunction(aFunction)) {
543 SetErrorCode("Shape driver failed");
547 catch (Standard_Failure) {
548 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
549 SetErrorCode(aFail->GetMessageString());
550 // to provide warning
551 if (!aFunction->GetValue().IsNull()) {
552 isWarning = Standard_True;
558 //Make a Python command
559 GEOM::TPythonDump pd (aFunction);
560 pd << aShape << " = geompy.MakeFaceWires([";
563 it = theShapes.begin();
564 if (it != theShapes.end()) {
566 while (it != theShapes.end()) {
567 pd << ", " << (*it++);
570 pd << "], " << (int)isPlanarWanted << ")";
572 // to provide warning
573 if (!isWarning) SetErrorCode(OK);
577 //=============================================================================
579 * MakeFaceFromSurface
581 //=============================================================================
582 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFaceFromSurface
583 (Handle(GEOM_Object) theFace,
584 Handle(GEOM_Object) theWire)
589 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
592 Handle(GEOM_Function) aFunction =
593 aShape->AddFunction(GEOMImpl_ShapeDriver::GetID(), FACE_FROM_SURFACE);
595 if (aFunction.IsNull()) {
599 //Check if the function is set correctly
600 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) {
604 GEOMImpl_IShapes aCI (aFunction);
605 Handle(TColStd_HSequenceOfTransient) aShapesSeq =
606 new TColStd_HSequenceOfTransient;
607 Handle(GEOM_Function) aRefFace = theFace->GetLastFunction();
608 Handle(GEOM_Function) aRefWire = theWire->GetLastFunction();
610 if (aRefFace.IsNull()) {
611 SetErrorCode("NULL argument face for the face construction");
615 if (aRefWire.IsNull()) {
616 SetErrorCode("NULL argument wire for the face construction");
620 aShapesSeq->Append(aRefFace);
621 aShapesSeq->Append(aRefWire);
623 aCI.SetShapes(aShapesSeq);
628 if (!GetSolver()->ComputeFunction(aFunction)) {
629 SetErrorCode("Shape driver failed");
633 catch (Standard_Failure) {
634 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
635 SetErrorCode(aFail->GetMessageString());
639 //Make a Python command
640 GEOM::TPythonDump (aFunction) << aShape
641 << " = geompy.MakeFaceFromSurface(" << theFace << ", " << theWire << ")";
648 //=============================================================================
650 * MakeFaceWithConstraints
652 //=============================================================================
653 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFaceWithConstraints
654 (std::list<Handle(GEOM_Object)> theConstraints)
659 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_FILLING);
662 Handle(GEOM_Function) aFunction =
663 aShape->AddFunction(GEOMImpl_FillingDriver::GetID(), FILLING_ON_CONSTRAINTS);
664 if (aFunction.IsNull()) return NULL;
666 //Check if the function is set correctly
667 if (aFunction->GetDriverGUID() != GEOMImpl_FillingDriver::GetID()) return NULL;
669 GEOMImpl_IFilling aCI (aFunction);
670 Handle(TColStd_HSequenceOfTransient) aConstraints = new TColStd_HSequenceOfTransient;
673 std::list<Handle(GEOM_Object)>::iterator it = theConstraints.begin();
674 while (it != theConstraints.end()) {
675 Handle(GEOM_Object) anObject = (*it);
676 if ( anObject.IsNull() || anObject->GetValue().ShapeType() != TopAbs_EDGE ) {
677 SetErrorCode("NULL argument edge for the face construction");
680 Handle(GEOM_Function) aRefSh = anObject->GetLastFunction();
681 aConstraints->Append(aRefSh);
683 if ( it != theConstraints.end() ) {
684 Handle(GEOM_Object) aFace = (*it);
685 if ( aFace.IsNull() ) {
686 // null constraint face - it is a valid case
690 if ( aFace->GetValue().ShapeType() != TopAbs_FACE )
691 // constraint face can be omitted - it is a valid case
693 if ( IsSubShapeBelongsTo( anObject, 0, aFace, 0 ) ) {
695 aRefSh = aFace->GetLastFunction();
696 aConstraints->Append(aRefSh);
701 SetErrorCode("Face is NULL or not connected to the Edge");
706 aCI.SetShapes( aConstraints );
709 Standard_Boolean isWarning = Standard_False;
712 if (!GetSolver()->ComputeFunction(aFunction)) {
713 SetErrorCode("Shape driver failed");
717 catch (Standard_Failure) {
718 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
719 SetErrorCode(aFail->GetMessageString());
720 // to provide warning
721 if (!aFunction->GetValue().IsNull()) {
722 isWarning = Standard_True;
728 //Make a Python command
729 GEOM::TPythonDump pd (aFunction);
730 pd << aShape << " = geompy.MakeFaceWithConstraints([";
733 it = theConstraints.begin();
734 if (it != theConstraints.end() ) {
736 while (it != theConstraints.end()) {
737 Handle(GEOM_Object) anObject = (*it++);
738 if( !anObject.IsNull() )
739 pd << ", " << anObject;
744 // to provide warning
745 if (!isWarning) SetErrorCode(OK);
749 //=============================================================================
753 //=============================================================================
754 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeShell
755 (std::list<Handle(GEOM_Object)> theShapes)
757 return MakeShape(theShapes, GEOM_SHELL, SHELL_FACES, "MakeShell");
760 //=============================================================================
764 //=============================================================================
765 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeSolidShells
766 (std::list<Handle(GEOM_Object)> theShapes)
768 return MakeShape(theShapes, GEOM_SOLID, SOLID_SHELLS, "MakeSolid");
771 //=============================================================================
775 //=============================================================================
776 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeCompound
777 (std::list<Handle(GEOM_Object)> theShapes)
779 return MakeShape(theShapes, GEOM_COMPOUND, COMPOUND_SHAPES, "MakeCompound");
782 //=============================================================================
786 //=============================================================================
787 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeShape
788 (std::list<Handle(GEOM_Object)> theShapes,
789 const Standard_Integer theObjectType,
790 const Standard_Integer theFunctionType,
791 const TCollection_AsciiString& theMethodName)
796 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), theObjectType);
799 Handle(GEOM_Function) aFunction =
800 aShape->AddFunction(GEOMImpl_ShapeDriver::GetID(), theFunctionType);
801 if (aFunction.IsNull()) return NULL;
803 //Check if the function is set correctly
804 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
806 GEOMImpl_IShapes aCI (aFunction);
808 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
811 std::list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
812 for (; it != theShapes.end(); it++) {
813 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
814 if (aRefSh.IsNull()) {
815 SetErrorCode("NULL argument shape for the shape construction");
818 aShapesSeq->Append(aRefSh);
820 aCI.SetShapes(aShapesSeq);
825 if (!GetSolver()->ComputeFunction(aFunction)) {
826 SetErrorCode("Shape driver failed");
830 catch (Standard_Failure) {
831 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
832 SetErrorCode(aFail->GetMessageString());
836 //Make a Python command
837 GEOM::TPythonDump pd (aFunction);
838 pd << aShape << " = geompy." << theMethodName.ToCString() << "([";
841 it = theShapes.begin();
842 if (it != theShapes.end()) {
844 while (it != theShapes.end()) {
845 pd << ", " << (*it++);
854 //=============================================================================
856 * MakeSolidFromConnectedFaces
858 //=============================================================================
859 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeSolidFromConnectedFaces
860 (std::list<Handle(GEOM_Object)> theFacesOrShells,
861 const Standard_Boolean isIntersect)
866 Handle(GEOM_Object) aSolid = GetEngine()->AddObject(GetDocID(), GEOM_SOLID);
869 Handle(GEOM_Function) aFunction =
870 aSolid->AddFunction(GEOMImpl_ShapeDriver::GetID(), SOLID_FACES);
871 if (aFunction.IsNull()) return NULL;
873 //Check if the function is set correctly
874 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
876 GEOMImpl_IShapes aCI (aFunction);
878 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
881 std::list<Handle(GEOM_Object)>::iterator it = theFacesOrShells.begin();
882 for (; it != theFacesOrShells.end(); it++) {
883 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
884 if (aRefSh.IsNull()) {
885 SetErrorCode("NULL argument shape for the shape construction");
888 aShapesSeq->Append(aRefSh);
890 aCI.SetShapes(aShapesSeq);
891 aCI.SetIsIntersect(isIntersect);
896 if (!GetSolver()->ComputeFunction(aFunction)) {
897 SetErrorCode("Shape driver failed");
901 catch (Standard_Failure) {
902 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
903 SetErrorCode(aFail->GetMessageString());
907 //Make a Python command
908 GEOM::TPythonDump pd (aFunction);
909 pd << aSolid << " = geompy.MakeSolidFromConnectedFaces([";
912 it = theFacesOrShells.begin();
913 if (it != theFacesOrShells.end()) {
915 while (it != theFacesOrShells.end()) {
916 pd << ", " << (*it++);
919 pd << "]," << (isIntersect ? "True" : "False") << ")";
925 //=============================================================================
929 //=============================================================================
931 GEOMImpl_IShapesOperations::MakeGlueFaces (std::list< Handle(GEOM_Object) >& theShapes,
932 const Standard_Real theTolerance,
933 const Standard_Boolean doKeepNonSolids)
937 Handle(TColStd_HSequenceOfTransient) objects = GEOM_Object::GetLastFunctions( theShapes );
938 if ( objects.IsNull() || objects->IsEmpty() ) {
939 SetErrorCode("NULL argument shape");
943 //Add a new Glued object
944 Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
946 //Add a new Glue function
947 Handle(GEOM_Function) aFunction;
948 aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_FACES);
949 if (aFunction.IsNull()) return NULL;
951 //Check if the function is set correctly
952 if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
954 GEOMImpl_IGlue aCI (aFunction);
956 aCI.SetBase( objects );
957 aCI.SetTolerance(theTolerance);
958 aCI.SetKeepNonSolids(doKeepNonSolids);
960 //Compute the sub-shape value
961 Standard_Boolean isWarning = Standard_False;
964 if (!GetSolver()->ComputeFunction(aFunction)) {
965 SetErrorCode("Shape driver failed to glue faces");
969 catch (Standard_Failure) {
970 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
971 SetErrorCode(aFail->GetMessageString());
972 // to provide warning
973 if (!aFunction->GetValue().IsNull()) {
974 isWarning = Standard_True;
980 //Make a Python command
981 GEOM::TPythonDump(aFunction) << aGlued << " = geompy.MakeGlueFaces("
982 << theShapes << ", " << theTolerance << ")";
984 // to provide warning
985 if (!isWarning) SetErrorCode(OK);
989 //=============================================================================
993 //=============================================================================
995 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetGlueFaces
996 (Handle(GEOM_Object) theShape,
997 const Standard_Real theTolerance)
1001 if (theShape.IsNull()) return NULL;
1002 TopoDS_Shape aShape = theShape->GetValue();
1003 if (aShape.IsNull()) return NULL;
1005 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1007 Standard_Integer iErr;
1009 GEOMAlgo_Gluer1 aGluer;
1010 GEOMAlgo_ListIteratorOfListOfCoupleOfShapes aItCS;
1011 GEOMAlgo_CoupleOfShapes aCS;
1012 GEOMAlgo_ListOfCoupleOfShapes aLCS;
1014 //aGluer = new GEOMAlgo_Gluer1;
1015 aGluer.SetShape(aShape);
1016 aGluer.SetTolerance(theTolerance);
1018 iErr = aGluer.ErrorStatus();
1019 if (iErr) return NULL;
1021 TopTools_ListOfShape listShape;
1022 const GEOMAlgo_ListOfCoupleOfShapes& aLCSG = aGluer.GluedFaces();
1024 aItCS.Initialize(aLCSG);
1025 for (; aItCS.More(); aItCS.Next()) {
1026 const GEOMAlgo_CoupleOfShapes& aCSG = aItCS.Value();
1027 listShape.Append(aCSG.Shape1());
1030 TopTools_ListIteratorOfListOfShape itSub (listShape);
1031 TCollection_AsciiString anAsciiList, anEntry;
1032 TopTools_IndexedMapOfShape anIndices;
1033 TopExp::MapShapes(aShape, anIndices);
1034 Handle(TColStd_HArray1OfInteger) anArray;
1035 Handle(GEOM_Object) anObj;
1036 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
1037 TopoDS_Shape aValue = itSub.Value();
1038 anArray = new TColStd_HArray1OfInteger(1,1);
1039 anArray->SetValue(1, anIndices.FindIndex(aValue));
1040 anObj = GetEngine()->AddSubShape(theShape, anArray);
1041 if (!anObj.IsNull()) {
1042 aSeq->Append(anObj);
1044 // for python command
1045 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
1046 anAsciiList += anEntry;
1051 //Make a Python command
1052 if( anAsciiList.Length() > 0 ) {
1053 anAsciiList.Trunc(anAsciiList.Length() - 1);
1054 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
1055 GEOM::TPythonDump pd (aFunction, true);
1056 pd << "[" << anAsciiList.ToCString();
1057 pd << "] = geompy.GetGlueFaces(" << theShape << ", " << theTolerance << ")";
1066 //=============================================================================
1068 * MakeGlueFacesByList
1070 //=============================================================================
1072 GEOMImpl_IShapesOperations::MakeGlueFacesByList(std::list< Handle(GEOM_Object) >& theShapes,
1073 const Standard_Real theTolerance,
1074 std::list<Handle(GEOM_Object)> & theFaces,
1075 const Standard_Boolean doKeepNonSolids,
1076 const Standard_Boolean doGlueAllEdges)
1080 Handle(TColStd_HSequenceOfTransient) objects = GEOM_Object::GetLastFunctions( theShapes );
1081 if ( objects.IsNull() || objects->IsEmpty() ) {
1082 SetErrorCode("NULL argument shape");
1085 Handle(TColStd_HSequenceOfTransient) aFaces = GEOM_Object::GetLastFunctions( theFaces );
1086 if ( aFaces.IsNull() ) {
1087 SetErrorCode("NULL argument shape for the shape construction");
1091 //Add a new Glued object
1092 Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
1094 //Add a new Glue function
1095 Handle(GEOM_Function) aFunction;
1096 aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_FACES_BY_LIST);
1097 if (aFunction.IsNull()) return NULL;
1099 //Check if the function is set correctly
1100 if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
1102 GEOMImpl_IGlue aCI (aFunction);
1104 aCI.SetBase( objects );
1105 aCI.SetTolerance(theTolerance);
1106 aCI.SetKeepNonSolids(doKeepNonSolids);
1107 aCI.SetGlueAllEdges(doGlueAllEdges);
1108 aCI.SetFaces(aFaces);
1110 //Compute the sub-shape value
1111 Standard_Boolean isWarning = Standard_False;
1114 if (!GetSolver()->ComputeFunction(aFunction)) {
1115 SetErrorCode("Shape driver failed to glue faces");
1119 catch (Standard_Failure) {
1120 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1121 SetErrorCode(aFail->GetMessageString());
1122 // to provide warning
1123 if (!aFunction->GetValue().IsNull()) {
1124 isWarning = Standard_True;
1130 //Make a Python command
1132 GEOM::TPythonDump pd(aFunction);
1133 pd << aGlued << " = geompy.MakeGlueFacesByList("
1134 << theShapes << ", " << theTolerance << ", " << theFaces << ", "
1135 << (bool)doKeepNonSolids << ", " << (bool)doGlueAllEdges << ")";
1137 // to provide warning
1138 if (!isWarning) SetErrorCode(OK);
1142 //=============================================================================
1146 //=============================================================================
1148 GEOMImpl_IShapesOperations::MakeGlueEdges (std::list< Handle(GEOM_Object) >& theShapes,
1149 const Standard_Real theTolerance)
1153 Handle(TColStd_HSequenceOfTransient) objects = GEOM_Object::GetLastFunctions( theShapes );
1154 if ( objects.IsNull() || objects->IsEmpty() ) {
1155 SetErrorCode("NULL argument shape");
1159 //Add a new Glued object
1160 Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
1162 //Add a new Glue function
1163 Handle(GEOM_Function) aFunction;
1164 aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_EDGES);
1165 if (aFunction.IsNull()) return NULL;
1167 //Check if the function is set correctly
1168 if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
1170 GEOMImpl_IGlue aCI (aFunction);
1172 aCI.SetBase( objects );
1173 aCI.SetTolerance(theTolerance);
1174 aCI.SetKeepNonSolids(true);
1176 //Compute the sub-shape value
1177 Standard_Boolean isWarning = Standard_False;
1180 if (!GetSolver()->ComputeFunction(aFunction)) {
1181 SetErrorCode("Shape driver failed to glue edges");
1185 catch (Standard_Failure) {
1186 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1187 SetErrorCode(aFail->GetMessageString());
1188 // to provide warning
1189 if (!aFunction->GetValue().IsNull()) {
1190 isWarning = Standard_True;
1196 //Make a Python command
1197 GEOM::TPythonDump(aFunction) << aGlued << " = geompy.MakeGlueEdges("
1198 << theShapes << ", " << theTolerance << ")";
1200 // to provide warning
1201 if (!isWarning) SetErrorCode(OK);
1205 //=============================================================================
1209 //=============================================================================
1210 Handle(TColStd_HSequenceOfTransient)
1211 GEOMImpl_IShapesOperations::GetGlueShapes (std::list< Handle(GEOM_Object) >& theShapes,
1212 const Standard_Real theTolerance,
1213 const TopAbs_ShapeEnum theType)
1217 TopoDS_Shape aShape;
1218 TopTools_SequenceOfShape shapes;
1219 std::list< Handle(GEOM_Object) >::iterator s = theShapes.begin();
1220 Handle(GEOM_Object) lastCreatedGO;
1221 for ( ; s != theShapes.end(); ++s )
1223 Handle(GEOM_Object) go = *s;
1224 if ( go.IsNull() ) return NULL;
1225 aShape = go->GetValue();
1226 if ( aShape.IsNull() ) return NULL;
1227 shapes.Append( aShape );
1228 lastCreatedGO = GEOM::GetCreatedLast( lastCreatedGO, go );
1230 if ( shapes.Length() > 1 )
1232 TopoDS_Compound compound;
1233 BRep_Builder builder;
1234 builder.MakeCompound( compound );
1235 for ( int i = 1; i <= shapes.Length(); ++i )
1236 builder.Add( compound, shapes( i ) );
1241 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1243 GEOMAlgo_GlueDetector aGluer;
1244 aGluer.SetArgument(aShape);
1245 aGluer.SetTolerance(theTolerance);
1247 Standard_Integer iErr = aGluer.ErrorStatus();
1248 if (iErr) return NULL;
1250 std::vector< TopTools_IndexedMapOfShape* > anIndices( shapes.Length(), NULL );
1251 Handle(TColStd_HArray1OfInteger) anArray;
1252 Handle(GEOM_Object) anObj;
1254 TopTools_ListOfShape listOnePerSet;
1256 const TopTools_DataMapOfShapeListOfShape& aImages = aGluer.Images();
1257 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape aItDMSLS (aImages);
1258 for (int index = 1; aItDMSLS.More(); aItDMSLS.Next(), ++index) {
1260 //const TopoDS_Shape& aSkey = aItDMSLS.Key();
1262 // list of shapes of the argument that can be glued
1263 const TopTools_ListOfShape& aLSD = aItDMSLS.Value();
1265 //listShape.Append(aLSD.First());
1266 TopoDS_Shape aValue = aLSD.First();
1268 if (aValue.ShapeType() == theType) {
1269 listOnePerSet.Append(aValue);
1273 // for stable order of returned entities
1274 GEOMUtils::SortShapes(listOnePerSet, Standard_False);
1276 TopTools_ListIteratorOfListOfShape aListIt (listOnePerSet);
1277 for (; aListIt.More(); aListIt.Next())
1279 TopoDS_Shape aValue = aListIt.Value();
1280 // find a shape to add aValue as a sub-shape
1282 s = theShapes.begin();
1283 for ( int i = 0; i < shapes.Length(); ++i, ++s )
1285 Handle(GEOM_Object) object = *s;
1286 if ( !anIndices[i] ) {
1287 anIndices[i] = new TopTools_IndexedMapOfShape;
1288 TopExp::MapShapes( object->GetValue(), *anIndices[i]);
1290 if (int index = anIndices[i]->FindIndex( aValue )) {
1291 anArray = new TColStd_HArray1OfInteger(1,1);
1292 anArray->SetValue(1, index);
1293 anObj = GetEngine()->AddSubShape( object, anArray);
1297 if (!anObj.IsNull())
1298 aSeq->Append(anObj);
1300 for ( size_t i = 0 ; i < anIndices.size(); ++i )
1301 delete anIndices[i];
1303 // Make a Python command
1304 if ( aSeq->Length() > 0)
1306 Handle(GEOM_Function) aFunction = lastCreatedGO->GetLastFunction();
1307 GEOM::TPythonDump pd (aFunction, /*append=*/true);
1309 << " = geompy." << (theType == TopAbs_FACE ? "GetGlueFaces" : "GetGlueEdges" )
1310 << "( " << theShapes << ", " << theTolerance << ")";
1318 //=============================================================================
1320 * MakeGlueEdgesByList
1322 //=============================================================================
1324 GEOMImpl_IShapesOperations::MakeGlueEdgesByList (std::list< Handle(GEOM_Object) >& theShapes,
1325 const Standard_Real theTolerance,
1326 std::list<Handle(GEOM_Object)>& theEdges)
1330 Handle(TColStd_HSequenceOfTransient) objects = GEOM_Object::GetLastFunctions( theShapes );
1331 if ( objects.IsNull() || objects->IsEmpty() ) {
1332 SetErrorCode("NULL argument shape");
1335 Handle(TColStd_HSequenceOfTransient) anEdges = GEOM_Object::GetLastFunctions( theEdges );
1336 if ( anEdges.IsNull() ) {
1337 SetErrorCode("NULL argument shape for the shape construction");
1340 //Add a new Glued object
1341 Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
1343 //Add a new Glue function
1344 Handle(GEOM_Function) aFunction;
1345 aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_EDGES_BY_LIST);
1346 if (aFunction.IsNull()) return NULL;
1348 //Check if the function is set correctly
1349 if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
1351 GEOMImpl_IGlue aCI (aFunction);
1353 aCI.SetBase( objects );
1354 aCI.SetTolerance(theTolerance);
1355 aCI.SetKeepNonSolids(true);
1356 aCI.SetFaces(anEdges);
1358 //Compute the sub-shape value
1359 Standard_Boolean isWarning = Standard_False;
1362 if (!GetSolver()->ComputeFunction(aFunction)) {
1363 SetErrorCode("Shape driver failed to glue edges");
1367 catch (Standard_Failure) {
1368 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1369 SetErrorCode(aFail->GetMessageString());
1370 // to provide warning
1371 if (!aFunction->GetValue().IsNull()) {
1372 isWarning = Standard_True;
1378 //Make a Python command
1380 GEOM::TPythonDump pd (aFunction);
1381 pd << aGlued << " = geompy.MakeGlueEdgesByList("
1382 << theShapes << ", " << theTolerance << ", " << theEdges << " )";
1384 // to provide warning
1385 if (!isWarning) SetErrorCode(OK);
1389 //=============================================================================
1391 * GetExistingSubObjects
1393 //=============================================================================
1394 Handle(TColStd_HSequenceOfTransient)
1395 GEOMImpl_IShapesOperations::GetExistingSubObjects(Handle(GEOM_Object) theShape,
1396 const Standard_Boolean theGroupsOnly)
1398 // note: this method does not return fields
1400 Standard_Integer types = theGroupsOnly ? Groups : Groups|SubShapes;
1401 Handle(TColStd_HSequenceOfTransient) results = GetExistingSubObjects(theShape, types);
1403 if (results->Length() > 0) {
1404 //Make a Python command
1405 TCollection_AsciiString anAsciiList;
1406 for (int i = 1; i <= results->Length(); i++)
1408 Handle(GEOM_BaseObject) obj = Handle(GEOM_BaseObject)::DownCast( results->Value(i));
1409 obj->GetEntryString();
1410 if ( i < results->Length() )
1414 GEOM::TPythonDump pd (theShape->GetLastFunction(), /*append=*/true);
1415 pd << "[" << anAsciiList.ToCString();
1416 pd << "] = geompy.GetExistingSubObjects(";
1417 pd << theShape << ", " << (bool)theGroupsOnly << ")";
1423 Handle(TColStd_HSequenceOfTransient)
1424 GEOMImpl_IShapesOperations::GetExistingSubObjects(Handle(GEOM_Object) theShape,
1425 const Standard_Integer theTypes)
1429 if (theShape.IsNull()) return NULL;
1431 Handle(GEOM_Function) aMainShape = theShape->GetLastFunction();
1432 if (aMainShape.IsNull()) return NULL;
1434 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1435 SetErrorCode(NOT_FOUND_ANY);
1437 if (!aMainShape->HasSubShapeReferences()) return aSeq;
1438 const TDataStd_ListOfExtendedString& aListEntries = aMainShape->GetSubShapeReferences();
1439 if (aListEntries.IsEmpty()) return aSeq;
1443 TDataStd_ListIteratorOfListOfExtendedString anIt (aListEntries);
1444 for (; anIt.More(); anIt.Next()) {
1445 TCollection_ExtendedString anEntry = anIt.Value();
1446 Standard_Integer aStrLen = anEntry.LengthOfCString();
1447 char* anEntryStr = new char[aStrLen+1];
1448 anEntry.ToUTF8CString(anEntryStr);
1449 Handle(GEOM_BaseObject) anObj = GetEngine()->GetObject(GetDocID(), anEntryStr, false);
1450 if (!anObj.IsNull() ) {
1451 bool isGroup = anObj->IsKind(STANDARD_TYPE(GEOM_Object)) && anObj->GetType() == GEOM_GROUP;
1452 bool isSubShape = anObj->IsKind(STANDARD_TYPE(GEOM_Object)) && anObj->GetType() != GEOM_GROUP;
1453 bool isField = anObj->IsKind(STANDARD_TYPE(GEOM_Field));
1454 if (theTypes & Groups && isGroup ||
1455 theTypes & SubShapes && isSubShape ||
1456 theTypes & Fields && isField) {
1457 aSeq->Append(anObj);
1460 delete [] anEntryStr;
1463 if (aSeq->Length() == 0) {
1464 SetErrorCode(NOT_FOUND_ANY);
1473 //=============================================================================
1477 //=============================================================================
1478 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::MakeExplode
1479 (Handle(GEOM_Object) theShape,
1480 const Standard_Integer theShapeType,
1481 const Standard_Boolean isSorted,
1482 const ExplodeType theExplodeType)
1486 if (theShape.IsNull()) return NULL;
1487 TopoDS_Shape aShape = theShape->GetValue();
1488 if (aShape.IsNull()) return NULL;
1490 Handle(GEOM_Function) aMainShape = theShape->GetLastFunction();
1492 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1493 Handle(GEOM_Object) anObj;
1494 TopTools_MapOfShape mapShape;
1495 TopTools_ListOfShape listShape;
1497 if (aShape.ShapeType() == TopAbs_COMPOUND &&
1498 (theShapeType == TopAbs_SHAPE || theShapeType == TopAbs_FLAT || theShapeType == TopAbs_COMPOUND))
1500 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
1501 for (; It.More(); It.Next()) {
1502 TopoDS_Shape SS = It.Value();
1503 if (mapShape.Add(SS)) {
1504 if (theShapeType == TopAbs_FLAT) {
1505 AddFlatSubShapes(SS, listShape, mapShape);
1507 else if (theShapeType == TopAbs_SHAPE || theShapeType == SS.ShapeType()) {
1508 listShape.Append(SS);
1510 // VSR: for EXPLODE_NEW_INCLUDE_MAIN and EXPLODE_OLD_INCLUDE_MAIN:
1511 // it seems it is necessary to add top-level shape if theShapeType == TopAbs_COMPOUND
1515 else if (theExplodeType != EXPLODE_NEW_EXCLUDE_MAIN || aShape.ShapeType() != theShapeType) // issue 0021079
1517 TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
1518 for (; exp.More(); exp.Next())
1519 if (mapShape.Add(exp.Current()))
1520 listShape.Append(exp.Current());
1523 if (listShape.IsEmpty()){
1524 //SetErrorCode("The given shape has no sub-shapes of the requested type");
1525 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
1530 bool isOldSorting = false;
1531 if (theExplodeType == EXPLODE_OLD_INCLUDE_MAIN)
1532 isOldSorting = true;
1533 GEOMUtils::SortShapes(listShape, isOldSorting);
1536 TopTools_IndexedMapOfShape anIndices;
1537 TopExp::MapShapes(aShape, anIndices);
1538 Handle(TColStd_HArray1OfInteger) anArray;
1540 TopTools_ListIteratorOfListOfShape itSub (listShape);
1541 TCollection_AsciiString anAsciiList, anEntry;
1542 for (int index = 1; itSub.More(); itSub.Next(), ++index)
1544 TopoDS_Shape aValue = itSub.Value();
1545 anArray = new TColStd_HArray1OfInteger(1,1);
1546 anArray->SetValue(1, anIndices.FindIndex(aValue));
1548 //anObj = GetEngine()->AddSubShape(theShape, anArray);
1550 anObj = GetEngine()->AddObject(GetDocID(), GEOM_SUBSHAPE);
1551 Handle(GEOM_Function) aFunction = anObj->AddFunction(GEOM_Object::GetSubShapeID(), 1);
1552 if (aFunction.IsNull()) return aSeq;
1554 GEOM_ISubShape aSSI (aFunction);
1555 aSSI.SetMainShape(aMainShape);
1556 aSSI.SetIndices(anArray);
1558 // Set function value directly, as we know it.
1559 // Usage of Solver here would lead to significant loss of time,
1560 // because GEOM_SubShapeDriver will build TopTools_IndexedMapOfShape
1561 // on the main shape for each being calculated sub-shape separately.
1562 aFunction->SetValue(aValue);
1564 // Put this subshape in the list of sub-shapes of theMainShape
1565 aMainShape->AddSubShapeReference(aFunction);
1567 if (!anObj.IsNull()) {
1568 aSeq->Append(anObj);
1570 // for python command
1571 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
1572 anAsciiList += anEntry;
1577 //Make a Python command
1578 anAsciiList.Trunc(anAsciiList.Length() - 1);
1580 GEOM::TPythonDump pd (aMainShape, /*append=*/true);
1581 pd << "[" << anAsciiList.ToCString() << "] = geompy.";
1582 switch (theExplodeType) {
1583 case EXPLODE_NEW_EXCLUDE_MAIN:
1584 pd << "ExtractShapes(" << theShape << ", "
1585 << TopAbs_ShapeEnum(theShapeType) << ", " << (isSorted ? "True" : "False") << ")";
1587 case EXPLODE_NEW_INCLUDE_MAIN:
1588 pd << "SubShapeAll" << (isSorted ? "SortedCentres(" : "(")
1589 << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
1591 case EXPLODE_OLD_INCLUDE_MAIN:
1592 pd << "SubShapeAll" << (isSorted ? "Sorted(" : "(")
1593 << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
1602 //=============================================================================
1606 //=============================================================================
1607 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::SubShapeAllIDs
1608 (Handle(GEOM_Object) theShape,
1609 const Standard_Integer theShapeType,
1610 const Standard_Boolean isSorted,
1611 const ExplodeType theExplodeType)
1615 if (theShape.IsNull()) return NULL;
1616 TopoDS_Shape aShape = theShape->GetValue();
1617 if (aShape.IsNull()) return NULL;
1619 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
1620 TopTools_MapOfShape mapShape;
1621 TopTools_ListOfShape listShape;
1623 if (aShape.ShapeType() == TopAbs_COMPOUND &&
1624 (theShapeType == TopAbs_SHAPE || theShapeType == TopAbs_FLAT || theShapeType == TopAbs_COMPOUND))
1626 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
1627 for (; It.More(); It.Next()) {
1628 TopoDS_Shape SS = It.Value();
1629 if (mapShape.Add(SS)) {
1630 if (theShapeType == TopAbs_FLAT) {
1631 AddFlatSubShapes(SS, listShape, mapShape);
1633 else if (theShapeType == TopAbs_SHAPE || theShapeType == SS.ShapeType()) {
1634 listShape.Append(SS);
1639 else if (theExplodeType != EXPLODE_NEW_EXCLUDE_MAIN || aShape.ShapeType() != theShapeType) // issue 0021079
1641 TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
1642 for (; exp.More(); exp.Next())
1643 if (mapShape.Add(exp.Current()))
1644 listShape.Append(exp.Current());
1647 if (listShape.IsEmpty()) {
1648 //SetErrorCode("The given shape has no sub-shapes of the requested type");
1649 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
1654 bool isOldSorting = false;
1655 if (theExplodeType == EXPLODE_OLD_INCLUDE_MAIN)
1656 isOldSorting = true;
1657 GEOMUtils::SortShapes(listShape, isOldSorting);
1660 TopTools_IndexedMapOfShape anIndices;
1661 TopExp::MapShapes(aShape, anIndices);
1662 Handle(TColStd_HArray1OfInteger) anArray;
1664 TopTools_ListIteratorOfListOfShape itSub (listShape);
1665 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
1666 TopoDS_Shape aValue = itSub.Value();
1667 aSeq->Append(anIndices.FindIndex(aValue));
1670 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
1672 //Make a Python command
1673 GEOM::TPythonDump pd (aFunction, /*append=*/true);
1674 pd << "listSubShapeIDs = geompy.SubShapeAll";
1675 switch (theExplodeType) {
1676 case EXPLODE_NEW_EXCLUDE_MAIN:
1678 case EXPLODE_NEW_INCLUDE_MAIN:
1679 pd << (isSorted ? "SortedCentresIDs(" : "IDs(")
1680 << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
1682 case EXPLODE_OLD_INCLUDE_MAIN:
1683 pd << (isSorted ? "SortedIDs(" : "IDs(")
1684 << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
1693 //=============================================================================
1697 //=============================================================================
1698 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetSubShape
1699 (Handle(GEOM_Object) theMainShape,
1700 const Standard_Integer theID)
1704 if (theMainShape.IsNull()) return NULL;
1706 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
1707 anArray->SetValue(1, theID);
1708 Handle(GEOM_Object) anObj = GetEngine()->AddSubShape(theMainShape, anArray,true);
1709 if (anObj.IsNull()) {
1710 SetErrorCode("Can not get a sub-shape with the given ID");
1714 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1716 //Make a Python command
1717 GEOM::TPythonDump(aFunction) << anObj << " = geompy.GetSubShape("
1718 << theMainShape << ", [" << theID << "])";
1724 //=============================================================================
1728 //=============================================================================
1729 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::MakeSubShapes
1730 (Handle(GEOM_Object) theMainShape,
1731 Handle(TColStd_HArray1OfInteger) theIndices)
1735 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1737 if (!theIndices->Length()) {
1738 SetErrorCode(NOT_FOUND_ANY);
1742 if (theMainShape.IsNull()) return NULL;
1743 TopoDS_Shape aShape = theMainShape->GetValue();
1744 if (aShape.IsNull()) return NULL;
1746 Handle(GEOM_Function) aMainShape = theMainShape->GetLastFunction();
1748 TopTools_IndexedMapOfShape anIndices;
1749 TopExp::MapShapes(aShape, anIndices);
1751 Handle(TColStd_HArray1OfInteger) anArray;
1752 Handle(GEOM_Object) anObj;
1754 TCollection_AsciiString anAsciiList, anEntry;
1755 Standard_Integer i, low = theIndices->Lower(), up = theIndices->Upper();
1756 for (i = low; i <= up; i++) {
1757 int id = theIndices->Value(i);
1758 if (1 <= id && id <= anIndices.Extent()) {
1759 TopoDS_Shape aValue = anIndices.FindKey(id);
1760 anArray = new TColStd_HArray1OfInteger(1,1);
1761 anArray->SetValue(1, id);
1763 anObj = GetEngine()->AddObject(GetDocID(), GEOM_SUBSHAPE);
1764 if (!anObj.IsNull()) {
1765 Handle(GEOM_Function) aFunction = anObj->AddFunction(GEOM_Object::GetSubShapeID(), 1);
1766 if (aFunction.IsNull()) return aSeq;
1768 GEOM_ISubShape aSSI (aFunction);
1769 aSSI.SetMainShape(aMainShape);
1770 aSSI.SetIndices(anArray);
1772 // Set function value directly, as we know it.
1773 // Usage of Solver here would lead to significant loss of time,
1774 // because GEOM_SubShapeDriver will build TopTools_IndexedMapOfShape
1775 // on the main shape for each being calculated sub-shape separately.
1776 aFunction->SetValue(aValue);
1778 // Put this sub-shape in the list of sub-shapes of theMainShape
1779 aMainShape->AddSubShapeReference(aFunction);
1781 aSeq->Append(anObj);
1783 // for python command
1784 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
1785 anAsciiList += anEntry;
1791 //Make a Python command
1792 anAsciiList.Trunc(anAsciiList.Length() - 1);
1794 GEOM::TPythonDump pd (aMainShape, /*append=*/true);
1795 pd << "[" << anAsciiList.ToCString() << "] = geompy.SubShapes("
1796 << theMainShape << ", [" ;
1797 for (i = low; i <= up - 1; i++) {
1798 pd << theIndices->Value(i) << ", ";
1800 pd << theIndices->Value(up) << "])";
1807 //=============================================================================
1811 //=============================================================================
1812 Standard_Integer GEOMImpl_IShapesOperations::GetSubShapeIndex (Handle(GEOM_Object) theMainShape,
1813 Handle(GEOM_Object) theSubShape)
1817 TopoDS_Shape aMainShape = theMainShape->GetValue();
1818 TopoDS_Shape aSubShape = theSubShape->GetValue();
1820 if (aMainShape.IsNull() || aSubShape.IsNull()) return -1;
1822 TopTools_IndexedMapOfShape anIndices;
1823 TopExp::MapShapes(aMainShape, anIndices);
1824 // if (anIndices.Contains(aSubShape)) {
1825 // SetErrorCode(OK);
1826 // return anIndices.FindIndex(aSubShape);
1828 int id = anIndices.FindIndex(aSubShape);
1839 //=============================================================================
1841 * GetSubShapeIndices
1843 //=============================================================================
1844 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetSubShapesIndices (Handle(GEOM_Object) theMainShape,
1845 std::list<Handle(GEOM_Object)> theSubShapes)
1847 MESSAGE("GEOMImpl_IShapesOperations::GetSubShapesIndices")
1850 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
1852 TopoDS_Shape aMainShape = theMainShape->GetValue();
1853 if (aMainShape.IsNull())
1855 MESSAGE("NULL main shape")
1859 TopTools_IndexedMapOfShape anIndices;
1860 TopExp::MapShapes(aMainShape, anIndices);
1862 std::list<Handle(GEOM_Object)>::iterator it;
1863 for (it=theSubShapes.begin(); it != theSubShapes.end(); ++it)
1865 TopoDS_Shape aSubShape = (*it)->GetValue();
1866 if (aSubShape.IsNull())
1868 MESSAGE("NULL subshape")
1871 int id = anIndices.FindIndex(aSubShape);
1880 //=============================================================================
1884 //=============================================================================
1885 Standard_Integer GEOMImpl_IShapesOperations::GetTopologyIndex (Handle(GEOM_Object) theMainShape,
1886 Handle(GEOM_Object) theSubShape)
1890 TopoDS_Shape aMainShape = theMainShape->GetValue();
1891 TopoDS_Shape aSubShape = theSubShape->GetValue();
1893 if (aMainShape.IsNull() || aSubShape.IsNull()) {
1894 SetErrorCode("Null argument shape given");
1899 if (aSubShape.ShapeType() == TopAbs_COMPOUND) {
1901 TopTools_ListOfShape CL;
1902 CL.Append(aMainShape);
1903 TopTools_ListIteratorOfListOfShape itC;
1904 for (itC.Initialize(CL); itC.More(); itC.Next()) {
1905 for (it.Initialize(itC.Value()); it.More(); it.Next()) {
1906 if (it.Value().ShapeType() == TopAbs_COMPOUND) {
1907 if (it.Value().IsSame(aSubShape))
1911 CL.Append(it.Value());
1916 TopExp_Explorer anExp (aMainShape, aSubShape.ShapeType());
1917 TopTools_MapOfShape M;
1918 for (; anExp.More(); anExp.Next()) {
1919 if (M.Add(anExp.Current())) {
1920 if (anExp.Current().IsSame(aSubShape))
1927 SetErrorCode("The sub-shape does not belong to the main shape");
1931 //=============================================================================
1933 * GetShapeTypeString
1935 //=============================================================================
1936 TCollection_AsciiString GEOMImpl_IShapesOperations::GetShapeTypeString (Handle(GEOM_Object) theShape)
1940 TCollection_AsciiString aTypeName ("Null Shape");
1942 TopoDS_Shape aShape = theShape->GetValue();
1943 if (aShape.IsNull())
1946 switch (aShape.ShapeType() )
1948 case TopAbs_COMPOUND:
1949 aTypeName = "Compound";
1951 case TopAbs_COMPSOLID:
1952 aTypeName = "Compound Solid";
1955 aTypeName = "Solid";
1958 aTypeName = "Shell";
1962 BRepAdaptor_Surface surf (TopoDS::Face(aShape));
1963 if (surf.GetType() == GeomAbs_Plane)
1964 aTypeName = "Plane";
1965 else if (surf.GetType() == GeomAbs_Cylinder)
1966 aTypeName = "Cylindrical Face";
1967 else if (surf.GetType() == GeomAbs_Sphere)
1968 aTypeName = "Spherical Face";
1969 else if (surf.GetType() == GeomAbs_Torus)
1970 aTypeName = "Toroidal Face";
1971 else if (surf.GetType() == GeomAbs_Cone)
1972 aTypeName = "Conical Face";
1974 aTypeName = "GEOM::FACE";
1982 BRepAdaptor_Curve curv (TopoDS::Edge(aShape));
1983 if (curv.GetType() == GeomAbs_Line) {
1984 if ((Abs(curv.FirstParameter()) >= 1E6) ||
1985 (Abs(curv.LastParameter()) >= 1E6))
1989 } else if (curv.GetType() == GeomAbs_Circle) {
1990 if (curv.IsClosed())
1991 aTypeName = "Circle";
2000 aTypeName = "Vertex";
2003 aTypeName = "Shape";
2006 aTypeName = "Shape of unknown type";
2012 //=============================================================================
2014 * IsSubShapeBelongsTo
2016 //=============================================================================
2017 Standard_Boolean GEOMImpl_IShapesOperations::IsSubShapeBelongsTo( Handle(GEOM_Object) theSubObject,
2018 const Standard_Integer theSubObjectIndex,
2019 Handle(GEOM_Object) theObject,
2020 const Standard_Integer theObjectIndex)
2022 if ( theObject.IsNull() || theSubObject.IsNull() )
2025 TopoDS_Shape shape = theObject->GetValue();
2026 TopoDS_Shape subShape = theSubObject->GetValue();
2028 if ( shape.IsNull() || subShape.IsNull() )
2031 TopTools_IndexedMapOfShape anIndices;
2032 if ( theObjectIndex > 0 ) {
2033 TopExp::MapShapes( shape, anIndices );
2034 shape = anIndices.FindKey(theObjectIndex);
2036 if ( theSubObjectIndex > 0 ) {
2037 TopExp::MapShapes( subShape, anIndices );
2038 subShape = anIndices.FindKey(theSubObjectIndex);
2041 TopExp::MapShapes( shape, anIndices );
2042 return anIndices.Contains( subShape );
2045 //=============================================================================
2049 //=============================================================================
2050 Standard_Integer GEOMImpl_IShapesOperations::NumberOfSubShapes
2051 (Handle(GEOM_Object) theShape,
2052 const Standard_Integer theShapeType)
2055 Standard_Integer nbShapes = 0;
2057 if (theShape.IsNull()) return -1;
2058 TopoDS_Shape aShape = theShape->GetValue();
2059 if (aShape.IsNull()) return -1;
2062 TopTools_MapOfShape mapShape;
2064 if (aShape.ShapeType() == TopAbs_COMPOUND &&
2065 (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
2066 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPSOLID ||
2067 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPOUND)) {
2068 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
2069 for (; It.More(); It.Next()) {
2070 if (mapShape.Add(It.Value())) {
2071 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
2072 TopAbs_ShapeEnum(theShapeType) == It.Value().ShapeType()) {
2078 TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
2079 for (; exp.More(); exp.Next())
2080 if (mapShape.Add(exp.Current()))
2086 if (theShapeType == TopAbs_FLAT) {
2087 TopTools_MapOfShape aMapOfShape;
2088 TopTools_ListOfShape aListOfShape;
2089 AddFlatSubShapes(aShape, aListOfShape, aMapOfShape);
2090 nbShapes = aListOfShape.Extent();
2094 int iType, nbTypes [TopAbs_SHAPE];
2095 for (iType = 0; iType < TopAbs_SHAPE; ++iType)
2097 nbTypes[aShape.ShapeType()]++;
2099 TopTools_MapOfShape aMapOfShape;
2100 aMapOfShape.Add(aShape);
2101 TopTools_ListOfShape aListOfShape;
2102 aListOfShape.Append(aShape);
2104 TopTools_ListIteratorOfListOfShape itL (aListOfShape);
2105 for (; itL.More(); itL.Next()) {
2106 TopoDS_Iterator it (itL.Value());
2107 for (; it.More(); it.Next()) {
2108 TopoDS_Shape s = it.Value();
2109 if (aMapOfShape.Add(s)) {
2110 aListOfShape.Append(s);
2111 nbTypes[s.ShapeType()]++;
2116 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE)
2117 nbShapes = aMapOfShape.Extent();
2119 nbShapes = nbTypes[theShapeType];
2122 catch (Standard_Failure) {
2123 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2124 SetErrorCode(aFail->GetMessageString());
2132 //=============================================================================
2136 //=============================================================================
2137 Handle(GEOM_Object) GEOMImpl_IShapesOperations::ReverseShape(Handle(GEOM_Object) theShape)
2141 if (theShape.IsNull()) return NULL;
2144 //Add a new reversed object
2145 Handle(GEOM_Object) aReversed = GetEngine()->AddObject(GetDocID(), theShape->GetType());
2147 //Add a new Revese function
2148 Handle(GEOM_Function) aFunction;
2149 aFunction = aReversed->AddFunction(GEOMImpl_ShapeDriver::GetID(), REVERSE_ORIENTATION);
2150 if (aFunction.IsNull()) return NULL;
2152 //Check if the function is set correctly
2153 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
2155 GEOMImpl_IShapes aSI (aFunction);
2157 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
2158 if (aRefShape.IsNull()) return NULL;
2160 aSI.SetBase(aRefShape);
2162 //Compute the sub-shape value
2165 if (!GetSolver()->ComputeFunction(aFunction)) {
2166 SetErrorCode("Shape driver failed to reverse shape");
2170 catch (Standard_Failure) {
2171 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2172 SetErrorCode(aFail->GetMessageString());
2176 //Make a Python command
2177 GEOM::TPythonDump(aFunction) << aReversed
2178 << " = geompy.ChangeOrientation(" << theShape << ")";
2183 Handle(GEOM_Object) aReversed;
2185 GEOM_Engine* anEngine = GetEngine();
2186 //GEOMImpl_Gen* aGen = dynamic_cast<GEOMImpl_Gen*>(anEngine);
2187 GEOMImpl_Gen* aGen = (GEOMImpl_Gen*)anEngine;
2190 GEOMImpl_IHealingOperations* anIHealingOperations =
2191 aGen->GetIHealingOperations(GetDocID());
2192 aReversed = anIHealingOperations->ChangeOrientationCopy(theShape);
2193 SetErrorCode(anIHealingOperations->GetErrorCode());
2199 //=============================================================================
2203 //=============================================================================
2204 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetFreeFacesIDs
2205 (Handle(GEOM_Object) theShape)
2209 if (theShape.IsNull()) return NULL;
2210 TopoDS_Shape aShape = theShape->GetValue();
2211 if (aShape.IsNull()) return NULL;
2213 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
2215 TopTools_IndexedDataMapOfShapeListOfShape mapFaceBlocks;
2216 GEOMImpl_Block6Explorer::MapShapesAndAncestors
2217 (aShape, TopAbs_FACE, TopAbs_SOLID, mapFaceBlocks);
2219 Standard_Integer ind = 1, nbFaces = mapFaceBlocks.Extent();
2222 SetErrorCode("The given shape has no faces");
2226 TopTools_IndexedMapOfShape anIndices;
2227 TopExp::MapShapes(aShape, anIndices);
2229 Standard_Integer id;
2230 for (; ind <= nbFaces; ind++) {
2231 if (mapFaceBlocks.FindFromIndex(ind).Extent() != 2) {
2232 id = anIndices.FindIndex(mapFaceBlocks.FindKey(ind));
2237 //The explode doesn't change object so no new function is required.
2238 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
2240 //Make a Python command
2241 GEOM::TPythonDump(aFunction, /*append=*/true)
2242 << "listFreeFacesIDs = geompy.GetFreeFacesIDs(" << theShape << ")";
2248 //=======================================================================
2249 //function : GetSharedShapes
2251 //=======================================================================
2252 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetSharedShapes
2253 (Handle(GEOM_Object) theShape1,
2254 Handle(GEOM_Object) theShape2,
2255 const Standard_Integer theShapeType)
2259 if (theShape1.IsNull() || theShape2.IsNull()) return NULL;
2261 TopoDS_Shape aShape1 = theShape1->GetValue();
2262 TopoDS_Shape aShape2 = theShape2->GetValue();
2264 if (aShape1.IsNull() || aShape2.IsNull()) return NULL;
2266 TopTools_IndexedMapOfShape anIndices;
2267 TopExp::MapShapes(aShape1, anIndices);
2268 Handle(TColStd_HArray1OfInteger) anArray;
2270 TopTools_IndexedMapOfShape mapShape1;
2271 TopExp::MapShapes(aShape1, TopAbs_ShapeEnum(theShapeType), mapShape1);
2273 Handle(GEOM_Object) anObj;
2274 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
2275 TCollection_AsciiString anAsciiList, anEntry;
2277 TopTools_MapOfShape mapShape2;
2278 TopExp_Explorer exp (aShape2, TopAbs_ShapeEnum(theShapeType));
2279 for (; exp.More(); exp.Next()) {
2280 TopoDS_Shape aSS = exp.Current();
2281 if (mapShape2.Add(aSS) && mapShape1.Contains(aSS)) {
2282 anArray = new TColStd_HArray1OfInteger(1,1);
2283 anArray->SetValue(1, anIndices.FindIndex(aSS));
2284 anObj = GetEngine()->AddSubShape(theShape1, anArray);
2285 aSeq->Append(anObj);
2287 // for python command
2288 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
2289 anAsciiList += anEntry;
2294 if (aSeq->IsEmpty()) {
2295 SetErrorCode(NOT_FOUND_ANY);
2299 //Make a Python command
2300 anAsciiList.Trunc(anAsciiList.Length() - 1);
2302 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2304 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
2305 << "] = geompy.GetSharedShapes(" << theShape1 << ", "
2306 << theShape2 << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
2312 //=======================================================================
2313 //function : GetSharedShapes
2316 // NOTE on the implementation
2318 // 1) Resulting sub-shapes are published as a children of the 1st input shape
2319 // from theShapes list. Due to this reason only direct sub-shapes of the 1st
2320 // shape can be contained in the result of the operation (i.e. shares between
2321 // 2nd/3rd, etc couples cannot be retrieved.
2322 // 2) An exception from above case is when a single compound is specified as an
2323 // input. In this case we search shares between its top-level content, so we
2324 // are able to search shares between all possible couples of shapes.
2325 // 3) Parameter theMultiShare controls what types of shares to search:
2326 // - True: get sub-shapes that are shared between ALL input shapes;
2327 // - False: get shares between couples of input sub-shapes (see points 1 and 2).
2329 // Thus, we have the following cases:
2330 // [1] theShapes = N shapes (N>1), theMultiShare = True
2331 // Result: sub-shapes that are shared by all theShapes
2332 // [2] theShapes = N shapes (N>1), theMultiShare = False
2333 // Result: sub-shapes of 1st shape from theShapes that are shared with any shape
2335 // [3] theShapes = 1 shape, theMultiShare = True
2336 // Result: sub-shapes that are shared by all top-level sub-objects of theShapes[0]
2337 // [4] theShapes = 1 shape, theMultiShare = False
2338 // Result: sub-shapes of all possible couples of all top-level sub-objects of
2340 //=======================================================================
2341 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetSharedShapes
2342 (std::list<Handle(GEOM_Object)> & theShapes,
2343 const Standard_Integer theShapeType,
2344 const bool theMultiShare)
2348 int aLen = theShapes.size();
2349 if (aLen < 1) return NULL;
2351 std::list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
2353 // main object is always first in the input list
2354 // it is the object from which sub-shapes indices are taken
2355 // and where results are published
2356 Handle(GEOM_Object) aMainObj = *it;
2357 Handle(GEOM_Function) aMainShape = aMainObj->GetLastFunction();
2359 // collect all shapes from the input list (including first one) for processing
2360 TopTools_SequenceOfShape shapeSeq;
2361 for (; it != theShapes.end(); it++) {
2362 Handle(GEOM_Function) aRefShape = (*it)->GetLastFunction();
2363 if (aRefShape.IsNull()) {
2364 SetErrorCode("NULL shape for GetSharedShapes");
2367 TopoDS_Shape aShape = aRefShape->GetValue();
2368 if (aShape.IsNull()) {
2369 SetErrorCode("NULL shape for GetSharedShapes");
2372 shapeSeq.Append( aShape );
2375 // if only single shape is specified as input
2376 // collect all ites top-level sub-shapes for processing
2377 if ( shapeSeq.Length() == 1 )
2379 TopoDS_Shape aShape = shapeSeq.First();
2381 for ( TopoDS_Iterator it( aShape ); it.More(); it.Next() )
2382 shapeSeq.Append( it.Value() );
2385 // map all sub-shapes in a main shape to their indices
2386 TopTools_IndexedMapOfShape anIndices;
2387 TopExp::MapShapes(aMainShape->GetValue(), anIndices);
2388 TopTools_MapOfShape mapShape;
2390 // find shared shapes
2392 // here we will collect all shares
2393 TopTools_ListOfShape aShared;
2395 // number of iterations
2396 int nbIters = theMultiShare || theShapes.size() > 1 ? 1 : shapeSeq.Length()-1;
2397 // numShares factor to search (i.e. by what nb of shapes each found sub-shape should be shared)
2398 int nbShares = theMultiShare ? shapeSeq.Length()-1 : 1;
2400 for ( int iter = 1; iter <= nbIters; iter++) {
2401 for ( int ind = iter+1; ind <= shapeSeq.Length(); ind++) {
2402 if ( ind-1+nbShares > shapeSeq.Length() ) break;
2403 TopoDS_Compound aCurrSelection;
2404 TopoDS_Shape aShape1 = shapeSeq.Value( iter );
2405 TopTools_IndexedMapOfShape mapSelected;
2406 TopExp::MapShapes(aShape1, TopAbs_ShapeEnum(theShapeType), mapSelected);
2407 for ( int s = 0; s < nbShares; s++ ) {
2409 TopoDS_Compound aCompound;
2410 B.MakeCompound(aCompound);
2411 const TopoDS_Shape& aShape2 = shapeSeq.Value( ind+s );
2412 TopTools_MapOfShape mapShape2;
2413 TopExp_Explorer exp (aShape2, TopAbs_ShapeEnum(theShapeType));
2414 for (; exp.More(); exp.Next()) {
2415 const TopoDS_Shape& aSS = exp.Current();
2416 if (mapShape2.Add(aSS) && mapSelected.Contains(aSS)) {
2417 B.Add(aCompound, aSS);
2420 mapSelected.Clear();
2421 aCurrSelection = aCompound;
2422 TopExp::MapShapes(aCurrSelection, TopAbs_ShapeEnum(theShapeType), mapSelected);
2424 TopoDS_Iterator itSel(aCurrSelection, Standard_True, Standard_True);
2425 for (; itSel.More(); itSel.Next()) {
2426 const TopoDS_Shape& aSS = itSel.Value();
2427 if (mapShape.Add(aSS) )
2428 aShared.Append(aSS);
2433 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
2435 if (aShared.IsEmpty()){
2436 SetErrorCode(NOT_FOUND_ANY);
2440 // create GEOM_Object for each found shared shape (collected in aShared)
2441 TCollection_AsciiString anAsciiList;
2442 Handle(GEOM_Object) anObj;
2443 TopTools_ListIteratorOfListOfShape itSub (aShared);
2444 for (; itSub.More(); itSub.Next()) {
2445 TopoDS_Shape aValue = itSub.Value();
2446 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
2447 anArray->SetValue(1, anIndices.FindIndex(aValue));
2448 anObj = GetEngine()->AddSubShape(aMainObj, anArray);
2449 aSeq->Append(anObj);
2451 // for python command
2452 TCollection_AsciiString anEntry;
2453 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
2454 anAsciiList += anEntry;
2458 // make a Python command
2459 anAsciiList.Trunc(anAsciiList.Length() - 1);
2461 GEOM::TPythonDump pd (anObj->GetLastFunction());
2462 pd << "[" << anAsciiList.ToCString()
2463 << "] = geompy.GetSharedShapesMulti(";
2468 it = theShapes.begin();
2470 while (it != theShapes.end()) {
2471 pd << ", " << (*it++);
2476 pd << ", " << TopAbs_ShapeEnum(theShapeType) << ", " << theMultiShare << ")";
2482 //=============================================================================
2486 //=============================================================================
2487 static GEOM::TPythonDump& operator<< (GEOM::TPythonDump& theDump,
2488 const GEOMAlgo_State theState)
2491 case GEOMAlgo_ST_IN:
2492 theDump << "GEOM.ST_IN";
2494 case GEOMAlgo_ST_OUT:
2495 theDump << "GEOM.ST_OUT";
2497 case GEOMAlgo_ST_ON:
2498 theDump << "GEOM.ST_ON";
2500 case GEOMAlgo_ST_ONIN:
2501 theDump << "GEOM.ST_ONIN";
2503 case GEOMAlgo_ST_ONOUT:
2504 theDump << "GEOM.ST_ONOUT";
2507 theDump << "GEOM.ST_UNKNOWN";
2513 //=======================================================================
2514 //function : checkTypeShapesOn
2516 * \brief Checks if theShapeType parameter of GetShapesOnXXX() is OK
2517 * \param theShapeType - the shape type to check
2518 * \retval bool - result of the check
2520 //=======================================================================
2521 bool GEOMImpl_IShapesOperations::checkTypeShapesOn(const Standard_Integer theShapeType)
2523 if (theShapeType != TopAbs_VERTEX &&
2524 theShapeType != TopAbs_EDGE &&
2525 theShapeType != TopAbs_FACE &&
2526 theShapeType != TopAbs_SOLID) {
2527 SetErrorCode("Only solids, vertices, edges or faces can be found by this method");
2533 //=======================================================================
2534 //function : makePlane
2536 * \brief Creates Geom_Plane
2537 * \param theAx1 - shape object defining plane parameters
2538 * \retval Handle(Geom_Surface) - resulting surface
2540 //=======================================================================
2541 Handle(Geom_Surface) GEOMImpl_IShapesOperations::makePlane(const TopoDS_Shape& anAx1)
2543 if (anAx1.ShapeType() != TopAbs_EDGE) return NULL;
2544 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
2545 TopoDS_Vertex V1, V2;
2546 TopExp::Vertices(anEdge, V1, V2, Standard_True);
2547 if (V1.IsNull() || V2.IsNull()) {
2548 SetErrorCode("Bad edge given for the plane normal vector");
2551 gp_Pnt aLoc = BRep_Tool::Pnt(V1);
2552 gp_Vec aVec (aLoc, BRep_Tool::Pnt(V2));
2553 if (aVec.Magnitude() < Precision::Confusion()) {
2554 SetErrorCode("Vector with null magnitude given");
2557 return new Geom_Plane(aLoc, aVec);
2560 //=======================================================================
2561 //function : makeCylinder
2563 * \brief Creates Geom_CylindricalSurface
2564 * \param theAx1 - edge defining cylinder axis
2565 * \param theRadius - cylinder radius
2566 * \retval Handle(Geom_Surface) - resulting surface
2568 //=======================================================================
2569 Handle(Geom_Surface) GEOMImpl_IShapesOperations::makeCylinder(const TopoDS_Shape& anAxis,
2570 const Standard_Real theRadius)
2572 //Axis of the cylinder
2573 if (anAxis.ShapeType() != TopAbs_EDGE) {
2574 SetErrorCode("Not an edge given for the axis");
2577 TopoDS_Edge anEdge = TopoDS::Edge(anAxis);
2578 TopoDS_Vertex V1, V2;
2579 TopExp::Vertices(anEdge, V1, V2, Standard_True);
2580 if (V1.IsNull() || V2.IsNull()) {
2581 SetErrorCode("Bad edge given for the axis");
2584 gp_Pnt aLoc = BRep_Tool::Pnt(V1);
2585 gp_Vec aVec (aLoc, BRep_Tool::Pnt(V2));
2586 if (aVec.Magnitude() < Precision::Confusion()) {
2587 SetErrorCode("Vector with null magnitude given");
2591 gp_Ax3 anAx3 (aLoc, aVec);
2592 return new Geom_CylindricalSurface(anAx3, theRadius);
2595 //=======================================================================
2596 //function : getShapesOnBoxIDs
2598 * \brief Find IDs of sub-shapes complying with given status about surface
2599 * \param theBox - the box to check state of sub-shapes against
2600 * \param theShape - the shape to explore
2601 * \param theShapeType - type of sub-shape of theShape
2602 * \param theState - required state
2603 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
2605 //=======================================================================
2606 Handle(TColStd_HSequenceOfInteger)
2607 GEOMImpl_IShapesOperations::getShapesOnBoxIDs(const Handle(GEOM_Object)& theBox,
2608 const Handle(GEOM_Object)& theShape,
2609 const Standard_Integer theShapeType,
2610 GEOMAlgo_State theState)
2612 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
2614 TopoDS_Shape aBox = theBox->GetValue();
2615 TopoDS_Shape aShape = theShape->GetValue();
2617 // Check presence of triangulation, build if need
2618 if (!GEOMUtils::CheckTriangulation(aShape)) {
2619 SetErrorCode("Cannot build triangulation on the shape");
2624 GEOMAlgo_FinderShapeOn2 aFinder;
2625 Standard_Real aTol = 0.0001; // default value
2627 Handle(GEOMAlgo_ClsfBox) aClsfBox = new GEOMAlgo_ClsfBox;
2628 aClsfBox->SetBox(aBox);
2630 aFinder.SetShape(aShape);
2631 aFinder.SetTolerance(aTol);
2632 aFinder.SetClsf(aClsfBox);
2633 aFinder.SetShapeType( (TopAbs_ShapeEnum)theShapeType );
2634 aFinder.SetState(theState);
2637 // Interprete results
2638 Standard_Integer iErr = aFinder.ErrorStatus();
2639 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn2.cxx
2641 MESSAGE(" iErr : " << iErr);
2642 TCollection_AsciiString aMsg (" iErr : ");
2643 aMsg += TCollection_AsciiString(iErr);
2647 Standard_Integer iWrn = aFinder.WarningStatus();
2648 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn2.cxx
2650 MESSAGE(" *** iWrn : " << iWrn);
2653 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
2655 if (listSS.Extent() < 1) {
2656 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
2657 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
2661 // Fill sequence of object IDs
2662 aSeqOfIDs = new TColStd_HSequenceOfInteger;
2664 TopTools_IndexedMapOfShape anIndices;
2665 TopExp::MapShapes(aShape, anIndices);
2667 TopTools_ListIteratorOfListOfShape itSub (listSS);
2668 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
2669 int id = anIndices.FindIndex(itSub.Value());
2670 aSeqOfIDs->Append(id);
2676 //=======================================================================
2677 //function : GetShapesOnBoxIDs
2679 * \brief Find sub-shapes complying with given status about surface
2680 * \param theBox - the box to check state of sub-shapes against
2681 * \param theShape - the shape to explore
2682 * \param theShapeType - type of sub-shape of theShape
2683 * \param theState - required state
2684 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
2686 //=======================================================================
2687 Handle(TColStd_HSequenceOfInteger)
2688 GEOMImpl_IShapesOperations::GetShapesOnBoxIDs(const Handle(GEOM_Object)& theBox,
2689 const Handle(GEOM_Object)& theShape,
2690 const Standard_Integer theShapeType,
2691 GEOMAlgo_State theState)
2693 // Find sub-shapes ids
2694 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2695 getShapesOnBoxIDs (theBox, theShape, theShapeType, theState);
2696 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2699 // The GetShapesOnBox() doesn't change object so no new function is required.
2700 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theBox)->GetLastFunction();
2702 // Make a Python command
2703 GEOM::TPythonDump(aFunction, /*append=*/true)
2704 << "listShapesOnBoxIDs = geompy.GetShapesOnBoxIDs("
2707 << TopAbs_ShapeEnum(theShapeType) << ", "
2714 //=======================================================================
2715 //function : GetShapesOnBox
2717 * \brief Find sub-shapes complying with given status about surface
2718 * \param theBox - the box to check state of sub-shapes against
2719 * \param theShape - the shape to explore
2720 * \param theShapeType - type of sub-shape of theShape
2721 * \param theState - required state
2722 * \retval Handle(TColStd_HSequenceOfTransient) - found sub-shapes
2724 //=======================================================================
2725 Handle(TColStd_HSequenceOfTransient)
2726 GEOMImpl_IShapesOperations::GetShapesOnBox(const Handle(GEOM_Object)& theBox,
2727 const Handle(GEOM_Object)& theShape,
2728 const Standard_Integer theShapeType,
2729 GEOMAlgo_State theState)
2731 // Find sub-shapes ids
2732 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2733 getShapesOnBoxIDs (theBox, theShape, theShapeType, theState);
2734 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2737 // Find objects by indices
2738 TCollection_AsciiString anAsciiList;
2739 Handle(TColStd_HSequenceOfTransient) aSeq;
2740 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
2741 if ( aSeq.IsNull() || aSeq->IsEmpty() )
2744 // Make a Python command
2746 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2747 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2749 GEOM::TPythonDump(aFunction)
2750 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnBox("
2753 << TopAbs_ShapeEnum(theShapeType) << ", "
2760 //=======================================================================
2761 //function : getShapesOnShapeIDs
2763 * \brief Find IDs of sub-shapes complying with given status about surface
2764 * \param theCheckShape - the shape to check state of sub-shapes against
2765 * \param theShape - the shape to explore
2766 * \param theShapeType - type of sub-shape of theShape
2767 * \param theState - required state
2768 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
2770 //=======================================================================
2771 Handle(TColStd_HSequenceOfInteger)
2772 GEOMImpl_IShapesOperations::getShapesOnShapeIDs
2773 (const Handle(GEOM_Object)& theCheckShape,
2774 const Handle(GEOM_Object)& theShape,
2775 const Standard_Integer theShapeType,
2776 GEOMAlgo_State theState)
2778 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
2780 TopoDS_Shape aCheckShape = theCheckShape->GetValue();
2781 TopoDS_Shape aShape = theShape->GetValue();
2782 TopTools_ListOfShape res;
2784 // Check presence of triangulation, build if need
2785 if (!GEOMUtils::CheckTriangulation(aShape)) {
2786 SetErrorCode("Cannot build triangulation on the shape");
2791 GEOMAlgo_FinderShapeOn2 aFinder;
2792 Standard_Real aTol = 0.0001; // default value
2794 Handle(GEOMAlgo_ClsfSolid) aClsfSolid = new GEOMAlgo_ClsfSolid;
2795 aClsfSolid->SetShape(aCheckShape);
2797 aFinder.SetShape(aShape);
2798 aFinder.SetTolerance(aTol);
2799 aFinder.SetClsf(aClsfSolid);
2800 aFinder.SetShapeType( (TopAbs_ShapeEnum)theShapeType );
2801 aFinder.SetState(theState);
2804 // Interprete results
2805 Standard_Integer iErr = aFinder.ErrorStatus();
2806 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn2.cxx
2809 SetErrorCode("theCheckShape must be a solid");
2812 MESSAGE(" iErr : " << iErr);
2813 TCollection_AsciiString aMsg (" iErr : ");
2814 aMsg += TCollection_AsciiString(iErr);
2819 Standard_Integer iWrn = aFinder.WarningStatus();
2820 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn2.cxx
2822 MESSAGE(" *** iWrn : " << iWrn);
2825 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
2827 if (listSS.Extent() < 1) {
2828 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
2829 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
2832 // Fill sequence of object IDs
2833 aSeqOfIDs = new TColStd_HSequenceOfInteger;
2835 TopTools_IndexedMapOfShape anIndices;
2836 TopExp::MapShapes(aShape, anIndices);
2838 TopTools_ListIteratorOfListOfShape itSub (listSS);
2839 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
2840 int id = anIndices.FindIndex(itSub.Value());
2841 aSeqOfIDs->Append(id);
2847 //=======================================================================
2848 //function : GetShapesOnShapeIDs
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_HSequenceOfInteger) - IDs of found sub-shapes
2857 //=======================================================================
2858 Handle(TColStd_HSequenceOfInteger)
2859 GEOMImpl_IShapesOperations::GetShapesOnShapeIDs
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);
2868 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2871 // The GetShapesOnShape() doesn't change object so no new function is required.
2872 Handle(GEOM_Function) aFunction =
2873 GEOM::GetCreatedLast(theShape,theCheckShape)->GetLastFunction();
2875 // Make a Python command
2876 GEOM::TPythonDump(aFunction, /*append=*/true)
2877 << "listShapesOnBoxIDs = geompy.GetShapesOnShapeIDs("
2878 << theCheckShape << ", "
2880 << TopAbs_ShapeEnum(theShapeType) << ", "
2887 //=======================================================================
2888 //function : GetShapesOnShape
2890 * \brief Find sub-shapes complying with given status about surface
2891 * \param theCheckShape - the shape to check state of sub-shapes against
2892 * \param theShape - the shape to explore
2893 * \param theShapeType - type of sub-shape of theShape
2894 * \param theState - required state
2895 * \retval Handle(TColStd_HSequenceOfTransient) - found sub-shapes
2897 //=======================================================================
2898 Handle(TColStd_HSequenceOfTransient)
2899 GEOMImpl_IShapesOperations::GetShapesOnShape
2900 (const Handle(GEOM_Object)& theCheckShape,
2901 const Handle(GEOM_Object)& theShape,
2902 const Standard_Integer theShapeType,
2903 GEOMAlgo_State theState)
2905 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2906 getShapesOnShapeIDs (theCheckShape, theShape, theShapeType, theState);
2907 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2910 // Find objects by indices
2911 TCollection_AsciiString anAsciiList;
2912 Handle(TColStd_HSequenceOfTransient) aSeq;
2913 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
2915 if ( aSeq.IsNull() || aSeq->IsEmpty() )
2918 // Make a Python command
2920 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2921 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2923 GEOM::TPythonDump(aFunction)
2924 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnShape("
2925 << theCheckShape << ", "
2927 << TopAbs_ShapeEnum(theShapeType) << ", "
2934 //=======================================================================
2935 //function : GetShapesOnShapeAsCompound
2936 //=======================================================================
2937 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetShapesOnShapeAsCompound
2938 (const Handle(GEOM_Object)& theCheckShape,
2939 const Handle(GEOM_Object)& theShape,
2940 const Standard_Integer theShapeType,
2941 GEOMAlgo_State theState)
2943 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2944 getShapesOnShapeIDs (theCheckShape, theShape, theShapeType, theState);
2946 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2949 // Find objects by indices
2950 TCollection_AsciiString anAsciiList;
2951 Handle(TColStd_HSequenceOfTransient) aSeq;
2952 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
2954 if ( aSeq.IsNull() || aSeq->IsEmpty() )
2957 TopoDS_Compound aCompound;
2959 B.MakeCompound(aCompound);
2961 for(; i<=aSeq->Length(); i++) {
2962 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(aSeq->Value(i));
2963 TopoDS_Shape aShape_i = anObj->GetValue();
2964 B.Add(aCompound,aShape_i);
2967 //Add a new result object
2968 Handle(GEOM_Object) aRes = GetEngine()->AddObject(GetDocID(), GEOM_SHAPES_ON_SHAPE);
2969 Handle(GEOM_Function) aFunction =
2970 aRes->AddFunction(GEOMImpl_ShapeDriver::GetID(), SHAPES_ON_SHAPE);
2971 aFunction->SetValue(aCompound);
2974 aSeq->Append( theCheckShape->GetLastFunction() );
2975 aSeq->Append( theShape->GetLastFunction() );
2977 GEOMImpl_IShapes aCI( aFunction );
2978 aCI.SetShapes( aSeq );
2979 aCI.SetSubShapeType( theShapeType );
2980 aCI.SetTolerance( theState );
2982 GEOM::TPythonDump(aFunction)
2983 << aRes << " = geompy.GetShapesOnShapeAsCompound("
2984 << theCheckShape << ", "
2986 << TopAbs_ShapeEnum(theShapeType) << ", "
2994 //=============================================================================
2996 * GetSubShapeEdgeSorted
2998 //=============================================================================
2999 Handle(TColStd_HSequenceOfTransient)
3000 GEOMImpl_IShapesOperations::GetSubShapeEdgeSorted
3001 (const Handle(GEOM_Object) &theShape,
3002 const Handle(GEOM_Object) &theStartPoint)
3004 // Get the sorted edges indices.
3005 Handle(TColStd_HSequenceOfInteger) aSortedIDs =
3006 getSubShapeEdgeSortedIDs(theShape, theStartPoint);
3008 // Get object by indices.
3009 TCollection_AsciiString anAsciiList;
3010 Handle(TColStd_HSequenceOfTransient) aSeq =
3011 getObjectsShapesOn(theShape, aSortedIDs, anAsciiList);
3013 if (aSeq.IsNull() || aSeq->IsEmpty()) {
3014 SetErrorCode("Empty sequence of edges");
3018 // Make a Python command
3019 Handle(GEOM_Object) anObj =
3020 Handle(GEOM_Object)::DownCast(aSeq->Value(1));
3021 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
3023 GEOM::TPythonDump(aFunction)
3024 << "[" << anAsciiList.ToCString() << "] = geompy.GetSubShapeEdgeSorted("
3025 << theShape << ", " << theStartPoint << ")";
3032 //=======================================================================
3033 //function : getShapesOnSurfaceIDs
3035 * \brief Find IDs of sub-shapes complying with given status about surface
3036 * \param theSurface - the surface to check state of sub-shapes against
3037 * \param theShape - the shape to explore
3038 * \param theShapeType - type of sub-shape of theShape
3039 * \param theState - required state
3040 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
3042 //=======================================================================
3043 Handle(TColStd_HSequenceOfInteger)
3044 GEOMImpl_IShapesOperations::getShapesOnSurfaceIDs(const Handle(Geom_Surface)& theSurface,
3045 const TopoDS_Shape& theShape,
3046 TopAbs_ShapeEnum theShapeType,
3047 GEOMAlgo_State theState)
3049 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
3051 // Check presence of triangulation, build if need
3052 if (!GEOMUtils::CheckTriangulation(theShape)) {
3053 SetErrorCode("Cannot build triangulation on the shape");
3057 // BEGIN: Mantis issue 0020961: Error on a pipe T-Shape
3058 // Compute tolerance
3059 Standard_Real T, VertMax = -RealLast();
3062 for (TopExp_Explorer ExV (theShape, TopAbs_VERTEX); ExV.More(); ExV.Next()) {
3063 TopoDS_Vertex Vertex = TopoDS::Vertex(ExV.Current());
3064 T = BRep_Tool::Tolerance(Vertex);
3069 catch (Standard_Failure) {
3070 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
3071 SetErrorCode(aFail->GetMessageString());
3074 // END: Mantis issue 0020961
3077 GEOMAlgo_FinderShapeOn2 aFinder;
3078 Handle(GEOMAlgo_ClsfSurf) aClsfSurf = new GEOMAlgo_ClsfSurf;
3079 Standard_Real aTol = VertMax; // Mantis issue 0020961
3081 aClsfSurf->SetSurface(theSurface);
3082 aFinder.SetShape(theShape);
3083 aFinder.SetTolerance(aTol);
3084 aFinder.SetClsf(aClsfSurf);
3085 aFinder.SetShapeType(theShapeType);
3086 aFinder.SetState(theState);
3088 // Sets the minimal number of inner points for the faces that do not have own
3089 // inner points at all (for e.g. rectangular planar faces have just 2 triangles).
3091 aFinder.SetNbPntsMin(3);
3092 // Sets the maximal number of inner points for edges or faces.
3093 // It is usefull for the cases when this number is very big (e.g =2000) to improve
3094 // the performance. If this value =0, all inner points will be taken into account.
3096 aFinder.SetNbPntsMax(100);
3100 // Interprete results
3101 Standard_Integer iErr = aFinder.ErrorStatus();
3102 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn2.cxx
3104 MESSAGE(" iErr : " << iErr);
3105 TCollection_AsciiString aMsg (" iErr : ");
3106 aMsg += TCollection_AsciiString(iErr);
3110 Standard_Integer iWrn = aFinder.WarningStatus();
3111 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn2.cxx
3113 MESSAGE(" *** iWrn : " << iWrn);
3116 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
3118 if (listSS.Extent() < 1) {
3119 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
3120 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
3124 // Fill sequence of object IDs
3125 aSeqOfIDs = new TColStd_HSequenceOfInteger;
3127 TopTools_IndexedMapOfShape anIndices;
3128 TopExp::MapShapes(theShape, anIndices);
3130 TopTools_ListIteratorOfListOfShape itSub (listSS);
3131 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
3132 int id = anIndices.FindIndex(itSub.Value());
3133 aSeqOfIDs->Append(id);
3139 //=======================================================================
3140 //function : getObjectsShapesOn
3142 * \brief Find shape objects and their entries by their ids
3143 * \param theShapeIDs - incoming shape ids
3144 * \param theShapeEntries - outgoing entries like "entry1, entry2, ..."
3145 * \retval Handle(TColStd_HSequenceOfTransient) - found shape objects
3147 //=======================================================================
3148 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::
3149 getObjectsShapesOn(const Handle(GEOM_Object)& theShape,
3150 const Handle(TColStd_HSequenceOfInteger)& theShapeIDs,
3151 TCollection_AsciiString & theShapeEntries)
3153 Handle(TColStd_HSequenceOfTransient) aSeq;
3155 if ( !theShapeIDs.IsNull() && theShapeIDs->Length() > 0 )
3157 aSeq = new TColStd_HSequenceOfTransient;
3158 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
3159 TCollection_AsciiString anEntry;
3160 for ( int i = 1; i <= theShapeIDs->Length(); ++i )
3162 anArray->SetValue(1, theShapeIDs->Value( i ));
3163 Handle(GEOM_Object) anObj = GetEngine()->AddSubShape(theShape, anArray);
3164 aSeq->Append( anObj );
3166 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
3167 if ( i != 1 ) theShapeEntries += ",";
3168 theShapeEntries += anEntry;
3174 //=============================================================================
3176 * getSubShapeEdgeSortedIDs
3178 //=============================================================================
3179 Handle(TColStd_HSequenceOfInteger)
3180 GEOMImpl_IShapesOperations::getSubShapeEdgeSortedIDs
3181 (const Handle(GEOM_Object) &theShape,
3182 const Handle(GEOM_Object) &theStartPoint)
3184 Handle(TColStd_HSequenceOfInteger) aResult;
3186 if (theShape.IsNull() || theStartPoint.IsNull()) {
3187 SetErrorCode("NULL GEOM object");
3191 const TopoDS_Shape aShape = theShape->GetValue();
3192 const TopoDS_Shape aStartPoint = theStartPoint->GetValue();
3194 if (aShape.IsNull() || aStartPoint.IsNull()) {
3195 SetErrorCode("NULL Shape");
3199 if (aStartPoint.ShapeType() != TopAbs_VERTEX) {
3200 SetErrorCode("Starting point is not a vertex");
3204 TopExp_Explorer anExp(aShape, TopAbs_EDGE);
3205 TopTools_MapOfShape aMapFence;
3206 TopTools_ListOfShape anEdges;
3208 for (; anExp.More(); anExp.Next()) {
3209 const TopoDS_Shape &anEdge = anExp.Current();
3211 if (aMapFence.Add(anEdge)) {
3212 anEdges.Append(anEdge);
3216 if (anEdges.IsEmpty()) {
3217 SetErrorCode("Shape doesn't contain edges");
3221 // Step 1: Sort edges
3222 GEOMUtils::SortShapes(anEdges, Standard_False);
3224 TopTools_ListIteratorOfListOfShape anIter(anEdges);
3225 TopoDS_Vertex aV[2];
3226 TopTools_DataMapOfShapeListOfShape aMapVE;
3228 // Step 2: Fill the map vertex - list of edges.
3229 for (; anIter.More(); anIter.Next()) {
3230 TopoDS_Edge anEdge = TopoDS::Edge(anIter.Value());
3232 TopExp::Vertices(anEdge, aV[0], aV[1]);
3234 const Standard_Integer aNbV = aV[0].IsSame(aV[1]) ? 1 : 2;
3237 for (i = 0; i < aNbV; ++i) {
3238 if (aV[i].IsNull() == Standard_False) {
3239 if (!aMapVE.IsBound(aV[i])) {
3240 // There is no this vertex in the map.
3241 aMapVE.Bind(aV[i], TopTools_ListOfShape());
3244 // Add the edge to the list bound with the vertex aV[i].
3245 TopTools_ListOfShape &aLEdges = aMapVE.ChangeFind(aV[i]);
3247 aLEdges.Append(anEdge);
3252 // Step 3: Find starting point in aMapVE.
3253 TopoDS_Vertex aStartVtx = TopoDS::Vertex(aStartPoint);
3255 if (!aMapVE.IsBound(aStartVtx)) {
3256 aStartVtx = getSameVertex(aShape, aStartVtx);
3258 if (aStartVtx.IsNull()) {
3259 SetErrorCode("Invalid Starting point");
3264 TopTools_IndexedMapOfShape anIndices;
3265 TopTools_MapOfShape aMapVFence;
3266 TopoDS_Shape aCurVtx = aStartVtx;
3267 TopoDS_Edge aCurEdge =
3268 TopoDS::Edge(aMapVE.Find(aCurVtx).First());
3270 aResult = new TColStd_HSequenceOfInteger;
3271 TopExp::MapShapes(aShape, anIndices);
3273 // Step 4: Fill the list of sorted edges.
3274 while (aMapVFence.Add(aCurVtx)) {
3275 // Append the ID of the current edge to the list of sorted.
3276 aResult->Append(anIndices.FindIndex(aCurEdge));
3277 TopExp::Vertices(aCurEdge, aV[0], aV[1]);
3279 // Get the next vertex.
3280 if (aCurVtx.IsSame(aV[0])) {
3281 if (aCurVtx.IsSame(aV[1])) {
3282 // There is no next vertex.
3291 if (aCurVtx.IsNull()) {
3292 // There is no next vertex.
3296 // Get the next edge.
3297 const TopTools_ListOfShape &aLEdges = aMapVE.Find(aCurVtx);
3298 TopTools_ListIteratorOfListOfShape anEIter(aLEdges);
3300 for (; anEIter.More(); anEIter.Next()) {
3301 const TopoDS_Shape &aLocalEdge = anEIter.Value();
3303 if (aLocalEdge.IsNull() == Standard_False) {
3304 if (!aCurEdge.IsSame(aLocalEdge)) {
3305 aCurEdge = TopoDS::Edge(aLocalEdge);
3311 if (!anEIter.More()) {
3312 // There is no next edge.
3320 //=======================================================================
3321 //function : getShapesOnSurface
3323 * \brief Find sub-shapes complying with given status about surface
3324 * \param theSurface - the surface to check state of sub-shapes against
3325 * \param theShape - the shape to explore
3326 * \param theShapeType - type of sub-shape of theShape
3327 * \param theState - required state
3328 * \param theShapeEntries - outgoing entries like "entry1, entry2, ..."
3329 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
3331 //=======================================================================
3332 Handle(TColStd_HSequenceOfTransient)
3333 GEOMImpl_IShapesOperations::getShapesOnSurface(const Handle(Geom_Surface)& theSurface,
3334 const Handle(GEOM_Object)& theShape,
3335 TopAbs_ShapeEnum theShapeType,
3336 GEOMAlgo_State theState,
3337 TCollection_AsciiString & theShapeEntries)
3339 // Find sub-shapes ids
3340 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
3341 getShapesOnSurfaceIDs (theSurface, theShape->GetValue(), theShapeType, theState);
3342 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
3345 return getObjectsShapesOn( theShape, aSeqOfIDs, theShapeEntries );
3348 //=============================================================================
3352 //=============================================================================
3353 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnPlane
3354 (const Handle(GEOM_Object)& theShape,
3355 const Standard_Integer theShapeType,
3356 const Handle(GEOM_Object)& theAx1,
3357 const GEOMAlgo_State theState)
3361 if (theShape.IsNull() || theAx1.IsNull()) return NULL;
3363 TopoDS_Shape aShape = theShape->GetValue();
3364 TopoDS_Shape anAx1 = theAx1->GetValue();
3366 if (aShape.IsNull() || anAx1.IsNull()) return NULL;
3368 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3369 if ( !checkTypeShapesOn( theShapeType ))
3373 Handle(Geom_Surface) aPlane = makePlane( anAx1 );
3374 if ( aPlane.IsNull() )
3378 TCollection_AsciiString anAsciiList;
3379 Handle(TColStd_HSequenceOfTransient) aSeq;
3380 aSeq = getShapesOnSurface( aPlane, theShape, aShapeType, theState, anAsciiList );
3381 if ( aSeq.IsNull() || aSeq->Length() == 0 )
3384 // Make a Python command
3386 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
3387 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
3389 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
3390 << "] = geompy.GetShapesOnPlane(" << theShape << ", "
3391 << aShapeType << ", " << theAx1 << ", " << theState << ")";
3397 //=============================================================================
3399 * GetShapesOnPlaneWithLocation
3401 //=============================================================================
3402 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnPlaneWithLocation
3403 (const Handle(GEOM_Object)& theShape,
3404 const Standard_Integer theShapeType,
3405 const Handle(GEOM_Object)& theAx1,
3406 const Handle(GEOM_Object)& thePnt,
3407 const GEOMAlgo_State theState)
3411 if (theShape.IsNull() || theAx1.IsNull() || thePnt.IsNull()) return NULL;
3413 TopoDS_Shape aShape = theShape->GetValue();
3414 TopoDS_Shape anAx1 = theAx1->GetValue();
3415 TopoDS_Shape anPnt = thePnt->GetValue();
3417 if (aShape.IsNull() || anAx1.IsNull() || anPnt.IsNull()) return NULL;
3419 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3420 if ( !checkTypeShapesOn( theShapeType ))
3424 if ( anAx1.ShapeType() != TopAbs_EDGE || anPnt.ShapeType() != TopAbs_VERTEX ) return NULL;
3425 TopoDS_Vertex V1, V2, V3;
3426 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
3427 TopExp::Vertices(anEdge, V1, V2, Standard_True);
3429 if (V1.IsNull() || V2.IsNull()) {
3430 SetErrorCode("Bad edge given for the plane normal vector");
3433 V3 = TopoDS::Vertex(anPnt);
3436 SetErrorCode("Bad vertex given for the plane location");
3439 gp_Pnt aLoc = BRep_Tool::Pnt(V3);
3440 gp_Vec aVec(BRep_Tool::Pnt(V1),BRep_Tool::Pnt(V2));
3442 if (aVec.Magnitude() < Precision::Confusion()) {
3443 SetErrorCode("Vector with null magnitude given");
3446 Handle(Geom_Surface) aPlane = new Geom_Plane(aLoc, aVec);
3448 if ( aPlane.IsNull() )
3452 TCollection_AsciiString anAsciiList;
3453 Handle(TColStd_HSequenceOfTransient) aSeq;
3454 aSeq = getShapesOnSurface( aPlane, theShape, aShapeType, theState, anAsciiList );
3455 if ( aSeq.IsNull() || aSeq->Length() == 0 )
3458 // Make a Python command
3460 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
3461 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
3463 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
3464 << "] = geompy.GetShapesOnPlaneWithLocation(" << theShape << ", "
3465 << aShapeType << ", " << theAx1 << ", "<< thePnt <<", " << theState << ")";
3471 //=============================================================================
3473 * GetShapesOnCylinder
3475 //=============================================================================
3476 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnCylinder
3477 (const Handle(GEOM_Object)& theShape,
3478 const Standard_Integer theShapeType,
3479 const Handle(GEOM_Object)& theAxis,
3480 const Standard_Real theRadius,
3481 const GEOMAlgo_State theState)
3485 if (theShape.IsNull() || theAxis.IsNull()) return NULL;
3487 TopoDS_Shape aShape = theShape->GetValue();
3488 TopoDS_Shape anAxis = theAxis->GetValue();
3490 if (aShape.IsNull() || anAxis.IsNull()) return NULL;
3492 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3493 if ( !checkTypeShapesOn( aShapeType ))
3496 // Create a cylinder surface
3497 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
3498 if ( aCylinder.IsNull() )
3502 TCollection_AsciiString anAsciiList;
3503 Handle(TColStd_HSequenceOfTransient) aSeq;
3504 aSeq = getShapesOnSurface( aCylinder, theShape, aShapeType, theState, anAsciiList );
3505 if ( aSeq.IsNull() || aSeq->Length() == 0 )
3508 // Make a Python command
3510 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
3511 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
3513 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
3514 << "] = geompy.GetShapesOnCylinder(" << theShape << ", " << aShapeType
3515 << ", " << theAxis << ", " << theRadius << ", " << theState << ")";
3521 //=============================================================================
3523 * GetShapesOnCylinderWithLocation
3525 //=============================================================================
3526 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnCylinderWithLocation
3527 (const Handle(GEOM_Object)& theShape,
3528 const Standard_Integer theShapeType,
3529 const Handle(GEOM_Object)& theAxis,
3530 const Handle(GEOM_Object)& thePnt,
3531 const Standard_Real theRadius,
3532 const GEOMAlgo_State theState)
3536 if (theShape.IsNull() || theAxis.IsNull() || thePnt.IsNull()) return NULL;
3538 TopoDS_Shape aShape = theShape->GetValue();
3539 TopoDS_Shape anAxis = theAxis->GetValue();
3540 TopoDS_Shape aPnt = thePnt->GetValue();
3542 if (aShape.IsNull() || anAxis.IsNull() || aPnt.IsNull()) return NULL;
3544 if (aPnt.ShapeType() != TopAbs_VERTEX )
3546 SetErrorCode("Bottom location point must be vertex");
3550 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3551 if ( !checkTypeShapesOn( aShapeType ))
3554 // Create a cylinder surface
3555 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
3556 if ( aCylinder.IsNull() )
3559 // translate the surface
3560 Handle(Geom_CylindricalSurface) aCylSurface =
3561 Handle(Geom_CylindricalSurface)::DownCast( aCylinder );
3562 if ( aCylSurface.IsNull() )
3564 SetErrorCode("Unexpected surface type instead of Geom_CylindricalSurface");
3567 gp_Pnt fromLoc = aCylSurface->Cylinder().Location();
3568 gp_Pnt toLoc = BRep_Tool::Pnt( TopoDS::Vertex( aPnt ));
3569 aCylinder->Translate( fromLoc, toLoc );
3572 TCollection_AsciiString anAsciiList;
3573 Handle(TColStd_HSequenceOfTransient) aSeq;
3574 aSeq = getShapesOnSurface( aCylinder, theShape, aShapeType, theState, anAsciiList );
3575 if ( aSeq.IsNull() || aSeq->Length() == 0 )
3578 // Make a Python command
3580 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
3581 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
3583 GEOM::TPythonDump(aFunction)
3584 << "[" << anAsciiList.ToCString()
3585 << "] = geompy.GetShapesOnCylinderWithLocation(" << theShape << ", " << aShapeType << ", "
3586 << theAxis << ", " << thePnt << ", " << theRadius << ", " << theState << ")";
3592 //=============================================================================
3596 //=============================================================================
3597 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnSphere
3598 (const Handle(GEOM_Object)& theShape,
3599 const Standard_Integer theShapeType,
3600 const Handle(GEOM_Object)& theCenter,
3601 const Standard_Real theRadius,
3602 const GEOMAlgo_State theState)
3606 if (theShape.IsNull() || theCenter.IsNull()) return NULL;
3608 TopoDS_Shape aShape = theShape->GetValue();
3609 TopoDS_Shape aCenter = theCenter->GetValue();
3611 if (aShape.IsNull() || aCenter.IsNull()) return NULL;
3613 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3614 if ( !checkTypeShapesOn( aShapeType ))
3617 // Center of the sphere
3618 if (aCenter.ShapeType() != TopAbs_VERTEX) return NULL;
3619 gp_Pnt aLoc = BRep_Tool::Pnt(TopoDS::Vertex(aCenter));
3621 gp_Ax3 anAx3 (aLoc, gp::DZ());
3622 Handle(Geom_SphericalSurface) aSphere =
3623 new Geom_SphericalSurface(anAx3, theRadius);
3626 TCollection_AsciiString anAsciiList;
3627 Handle(TColStd_HSequenceOfTransient) aSeq;
3628 aSeq = getShapesOnSurface( aSphere, theShape, aShapeType, theState, anAsciiList );
3629 if ( aSeq.IsNull() || aSeq->Length() == 0 )
3632 // Make a Python command
3634 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
3635 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
3637 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
3638 << "] = geompy.GetShapesOnSphere(" << theShape << ", " << aShapeType
3639 << ", " << theCenter << ", " << theRadius << ", " << theState << ")";
3645 //=============================================================================
3647 * GetShapesOnPlaneIDs
3649 //=============================================================================
3650 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnPlaneIDs
3651 (const Handle(GEOM_Object)& theShape,
3652 const Standard_Integer theShapeType,
3653 const Handle(GEOM_Object)& theAx1,
3654 const GEOMAlgo_State theState)
3658 if (theShape.IsNull() || theAx1.IsNull()) return NULL;
3660 TopoDS_Shape aShape = theShape->GetValue();
3661 TopoDS_Shape anAx1 = theAx1->GetValue();
3663 if (aShape.IsNull() || anAx1.IsNull()) return NULL;
3665 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3666 if ( !checkTypeShapesOn( aShapeType ))
3670 Handle(Geom_Surface) aPlane = makePlane( anAx1 );
3671 if ( aPlane.IsNull() )
3675 Handle(TColStd_HSequenceOfInteger) aSeq;
3676 aSeq = getShapesOnSurfaceIDs( aPlane, aShape, aShapeType, theState );
3678 // The GetShapesOnPlaneIDs() doesn't change object so no new function is required.
3679 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAx1)->GetLastFunction();
3681 // Make a Python command
3682 GEOM::TPythonDump(aFunction, /*append=*/true)
3683 << "listShapesOnPlane = geompy.GetShapesOnPlaneIDs"
3684 << "(" << theShape << "," << aShapeType << "," << theAx1 << "," << theState << ")";
3690 //=============================================================================
3692 * GetShapesOnPlaneWithLocationIDs
3694 //=============================================================================
3695 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnPlaneWithLocationIDs
3696 (const Handle(GEOM_Object)& theShape,
3697 const Standard_Integer theShapeType,
3698 const Handle(GEOM_Object)& theAx1,
3699 const Handle(GEOM_Object)& thePnt,
3700 const GEOMAlgo_State theState)
3704 if (theShape.IsNull() || theAx1.IsNull() || thePnt.IsNull()) return NULL;
3706 TopoDS_Shape aShape = theShape->GetValue();
3707 TopoDS_Shape anAx1 = theAx1->GetValue();
3708 TopoDS_Shape anPnt = thePnt->GetValue();
3710 if (aShape.IsNull() || anAx1.IsNull() || anPnt.IsNull()) return NULL;
3712 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3713 if ( !checkTypeShapesOn( aShapeType ))
3717 if (anAx1.ShapeType() != TopAbs_EDGE || anPnt.ShapeType() != TopAbs_VERTEX) return NULL;
3718 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
3719 TopoDS_Vertex V1, V2, V3;
3720 TopExp::Vertices(anEdge, V1, V2, Standard_True);
3721 if (V1.IsNull() || V2.IsNull()) {
3722 SetErrorCode("Bad edge given for the plane normal vector");
3725 V3 = TopoDS::Vertex(anPnt);
3727 SetErrorCode("Bad vertex given for the plane location");
3730 gp_Pnt aLoc = BRep_Tool::Pnt(V3);
3731 gp_Vec aVec(BRep_Tool::Pnt(V1),BRep_Tool::Pnt(V2));
3732 if (aVec.Magnitude() < Precision::Confusion()) {
3733 SetErrorCode("Vector with null magnitude given");
3737 Handle(Geom_Surface) aPlane = new Geom_Plane(aLoc, aVec);
3738 if ( aPlane.IsNull() )
3742 Handle(TColStd_HSequenceOfInteger) aSeq;
3743 aSeq = getShapesOnSurfaceIDs( aPlane, aShape, aShapeType, theState );
3745 // The GetShapesOnPlaneIDs() doesn't change object so no new function is required.
3746 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAx1)->GetLastFunction();
3748 // Make a Python command
3749 GEOM::TPythonDump(aFunction, /*append=*/true)
3750 << "listShapesOnPlane = geompy.GetShapesOnPlaneWithLocationIDs"
3751 << "(" << theShape << ", " << aShapeType << ", " << theAx1 << ", "<< thePnt << ", " << theState << ")";
3757 //=============================================================================
3759 * GetShapesOnCylinderIDs
3761 //=============================================================================
3762 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnCylinderIDs
3763 (const Handle(GEOM_Object)& theShape,
3764 const Standard_Integer theShapeType,
3765 const Handle(GEOM_Object)& theAxis,
3766 const Standard_Real theRadius,
3767 const GEOMAlgo_State theState)
3771 if (theShape.IsNull() || theAxis.IsNull()) return NULL;
3773 TopoDS_Shape aShape = theShape->GetValue();
3774 TopoDS_Shape anAxis = theAxis->GetValue();
3776 if (aShape.IsNull() || anAxis.IsNull()) return NULL;
3778 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3779 if ( !checkTypeShapesOn( aShapeType ))
3782 // Create a cylinder surface
3783 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
3784 if ( aCylinder.IsNull() )
3788 Handle(TColStd_HSequenceOfInteger) aSeq;
3789 aSeq = getShapesOnSurfaceIDs( aCylinder, aShape, aShapeType, theState );
3791 // The GetShapesOnCylinder() doesn't change object so no new function is required.
3792 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAxis)->GetLastFunction();
3794 // Make a Python command
3795 GEOM::TPythonDump(aFunction, /*append=*/true)
3796 << "listShapesOnCylinder = geompy.GetShapesOnCylinderIDs"
3797 << "(" << theShape << ", " << aShapeType << ", " << theAxis << ", "
3798 << theRadius << ", " << theState << ")";
3804 //=============================================================================
3806 * GetShapesOnCylinderWithLocationIDs
3808 //=============================================================================
3809 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnCylinderWithLocationIDs
3810 (const Handle(GEOM_Object)& theShape,
3811 const Standard_Integer theShapeType,
3812 const Handle(GEOM_Object)& theAxis,
3813 const Handle(GEOM_Object)& thePnt,
3814 const Standard_Real theRadius,
3815 const GEOMAlgo_State theState)
3819 if (theShape.IsNull() || theAxis.IsNull() || thePnt.IsNull()) return NULL;
3821 TopoDS_Shape aShape = theShape->GetValue();
3822 TopoDS_Shape anAxis = theAxis->GetValue();
3823 TopoDS_Shape aPnt = thePnt->GetValue();
3825 if (aShape.IsNull() || anAxis.IsNull() || aPnt.IsNull()) return NULL;
3827 if (aPnt.ShapeType() != TopAbs_VERTEX )
3829 SetErrorCode("Bottom location point must be vertex");
3833 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3834 if ( !checkTypeShapesOn( aShapeType ))
3837 // Create a cylinder surface
3838 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
3839 if ( aCylinder.IsNull() )
3842 // translate the surface
3843 Handle(Geom_CylindricalSurface) aCylSurface =
3844 Handle(Geom_CylindricalSurface)::DownCast( aCylinder );
3845 if ( aCylSurface.IsNull() )
3847 SetErrorCode("Unexpected surface type instead of Geom_CylindricalSurface");
3850 gp_Pnt fromLoc = aCylSurface->Cylinder().Location();
3851 gp_Pnt toLoc = BRep_Tool::Pnt( TopoDS::Vertex( aPnt ));
3852 aCylinder->Translate( fromLoc, toLoc );
3855 Handle(TColStd_HSequenceOfInteger) aSeq;
3856 aSeq = getShapesOnSurfaceIDs( aCylinder, aShape, aShapeType, theState );
3858 // The GetShapesOnCylinder() doesn't change object so no new function is required.
3859 Handle(GEOM_Function) aFunction =
3860 GEOM::GetCreatedLast(theShape, GEOM::GetCreatedLast(thePnt,theAxis))->GetLastFunction();
3862 // Make a Python command
3863 GEOM::TPythonDump(aFunction, /*append=*/true)
3864 << "listShapesOnCylinder = geompy.GetShapesOnCylinderWithLocationIDs"
3865 << "(" << theShape << ", " << aShapeType << ", " << theAxis << ", "
3866 << thePnt << ", " << theRadius << ", " << theState << ")";
3872 //=============================================================================
3874 * GetShapesOnSphereIDs
3876 //=============================================================================
3877 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnSphereIDs
3878 (const Handle(GEOM_Object)& theShape,
3879 const Standard_Integer theShapeType,
3880 const Handle(GEOM_Object)& theCenter,
3881 const Standard_Real theRadius,
3882 const GEOMAlgo_State theState)
3886 if (theShape.IsNull() || theCenter.IsNull()) return NULL;
3888 TopoDS_Shape aShape = theShape->GetValue();
3889 TopoDS_Shape aCenter = theCenter->GetValue();
3891 if (aShape.IsNull() || aCenter.IsNull()) return NULL;
3893 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3894 if ( !checkTypeShapesOn( aShapeType ))
3897 // Center of the sphere
3898 if (aCenter.ShapeType() != TopAbs_VERTEX) return NULL;
3899 gp_Pnt aLoc = BRep_Tool::Pnt(TopoDS::Vertex(aCenter));
3901 gp_Ax3 anAx3 (aLoc, gp::DZ());
3902 Handle(Geom_SphericalSurface) aSphere =
3903 new Geom_SphericalSurface(anAx3, theRadius);
3906 Handle(TColStd_HSequenceOfInteger) aSeq;
3907 aSeq = getShapesOnSurfaceIDs( aSphere, aShape, aShapeType, theState );
3909 // The GetShapesOnSphere() doesn't change object so no new function is required.
3910 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theCenter)->GetLastFunction();
3912 // Make a Python command
3913 GEOM::TPythonDump(aFunction, /*append=*/true)
3914 << "listShapesOnCylinder = geompy.GetShapesOnSphereIDs"
3915 << "(" << theShape << ", " << aShapeType << ", " << theCenter << ", "
3916 << theRadius << ", " << theState << ")";
3922 //=======================================================================
3923 //function : getShapesOnQuadrangleIDs
3925 * \brief Find IDs of sub-shapes complying with given status about quadrangle
3926 * \param theShape - the shape to explore
3927 * \param theShapeType - type of sub-shape of theShape
3928 * \param theTopLeftPoint - top left quadrangle corner
3929 * \param theTopRigthPoint - top right quadrangle corner
3930 * \param theBottomLeftPoint - bottom left quadrangle corner
3931 * \param theBottomRigthPoint - bottom right quadrangle corner
3932 * \param theState - required state
3933 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
3935 //=======================================================================
3936 Handle(TColStd_HSequenceOfInteger)
3937 GEOMImpl_IShapesOperations::getShapesOnQuadrangleIDs (const Handle(GEOM_Object)& theShape,
3938 const Standard_Integer theShapeType,
3939 const Handle(GEOM_Object)& theTopLeftPoint,
3940 const Handle(GEOM_Object)& theTopRigthPoint,
3941 const Handle(GEOM_Object)& theBottomLeftPoint,
3942 const Handle(GEOM_Object)& theBottomRigthPoint,
3943 const GEOMAlgo_State theState)
3947 if ( theShape.IsNull() ||
3948 theTopLeftPoint.IsNull() ||
3949 theTopRigthPoint.IsNull() ||
3950 theBottomLeftPoint.IsNull() ||
3951 theBottomRigthPoint.IsNull() )
3954 TopoDS_Shape aShape = theShape->GetValue();
3955 TopoDS_Shape aTL = theTopLeftPoint->GetValue();
3956 TopoDS_Shape aTR = theTopRigthPoint->GetValue();
3957 TopoDS_Shape aBL = theBottomLeftPoint->GetValue();
3958 TopoDS_Shape aBR = theBottomRigthPoint->GetValue();
3960 if (aShape.IsNull() ||
3965 aTL.ShapeType() != TopAbs_VERTEX ||
3966 aTR.ShapeType() != TopAbs_VERTEX ||
3967 aBL.ShapeType() != TopAbs_VERTEX ||
3968 aBR.ShapeType() != TopAbs_VERTEX )
3971 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3972 if ( !checkTypeShapesOn( aShapeType ))
3975 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
3977 // Check presence of triangulation, build if need
3978 if (!GEOMUtils::CheckTriangulation(aShape)) {
3979 SetErrorCode("Cannot build triangulation on the shape");
3984 gp_Pnt aPntTL = BRep_Tool::Pnt(TopoDS::Vertex(aTL));
3985 gp_Pnt aPntTR = BRep_Tool::Pnt(TopoDS::Vertex(aTR));
3986 gp_Pnt aPntBL = BRep_Tool::Pnt(TopoDS::Vertex(aBL));
3987 gp_Pnt aPntBR = BRep_Tool::Pnt(TopoDS::Vertex(aBR));
3989 GEOMAlgo_FinderShapeOn2 aFinder;
3990 Handle(GEOMAlgo_ClsfQuad) aClsfQuad = new GEOMAlgo_ClsfQuad;
3992 Standard_Real aTol = 0.0001; // default value
3994 aClsfQuad->SetCorners(aPntTL, aPntTR, aPntBL, aPntBR);
3995 aFinder.SetShape(aShape);
3996 aFinder.SetTolerance(aTol);
3997 aFinder.SetClsf(aClsfQuad);
3998 aFinder.SetShapeType(aShapeType);
3999 aFinder.SetState(theState);
4001 // Sets the minimal number of inner points for the faces that do not have own
4002 // inner points at all (for e.g. rectangular planar faces have just 2 triangles).
4004 aFinder.SetNbPntsMin(3);
4005 // Sets the maximal number of inner points for edges or faces.
4006 // It is usefull for the cases when this number is very big (e.g =2000) to improve
4007 // the performance. If this value =0, all inner points will be taken into account.
4009 aFinder.SetNbPntsMax(100);
4013 // Interprete results
4014 Standard_Integer iErr = aFinder.ErrorStatus();
4015 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn2.cxx
4017 MESSAGE(" iErr : " << iErr);
4018 TCollection_AsciiString aMsg (" iErr : ");
4019 aMsg += TCollection_AsciiString(iErr);
4023 Standard_Integer iWrn = aFinder.WarningStatus();
4024 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn2.cxx
4026 MESSAGE(" *** iWrn : " << iWrn);
4029 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
4031 if (listSS.Extent() < 1) {
4032 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
4033 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
4037 // Fill sequence of object IDs
4038 aSeqOfIDs = new TColStd_HSequenceOfInteger;
4040 TopTools_IndexedMapOfShape anIndices;
4041 TopExp::MapShapes(aShape, anIndices);
4043 TopTools_ListIteratorOfListOfShape itSub (listSS);
4044 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
4045 int id = anIndices.FindIndex(itSub.Value());
4046 aSeqOfIDs->Append(id);
4051 //=======================================================================
4052 //function : GetShapesOnQuadrangle
4054 * \brief Find sub-shapes complying with given status about quadrangle
4055 * \param theShape - the shape to explore
4056 * \param theShapeType - type of sub-shape of theShape
4057 * \param theTopLeftPoint - top left quadrangle corner
4058 * \param theTopRigthPoint - top right quadrangle corner
4059 * \param theBottomLeftPoint - bottom left quadrangle corner
4060 * \param theBottomRigthPoint - bottom right quadrangle corner
4061 * \param theState - required state
4062 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
4064 //=======================================================================
4065 Handle(TColStd_HSequenceOfTransient)
4066 GEOMImpl_IShapesOperations::GetShapesOnQuadrangle (const Handle(GEOM_Object)& theShape,
4067 const Standard_Integer theShapeType,
4068 const Handle(GEOM_Object)& theTopLeftPoint,
4069 const Handle(GEOM_Object)& theTopRigthPoint,
4070 const Handle(GEOM_Object)& theBottomLeftPoint,
4071 const Handle(GEOM_Object)& theBottomRigthPoint,
4072 const GEOMAlgo_State theState)
4075 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
4076 getShapesOnQuadrangleIDs( theShape,
4081 theBottomRigthPoint,
4083 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->IsEmpty() )
4086 // Find objects by indices
4087 TCollection_AsciiString anAsciiList;
4088 Handle(TColStd_HSequenceOfTransient) aSeq;
4089 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
4090 if ( aSeq.IsNull() || aSeq->IsEmpty() )
4093 // Make a Python command
4095 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
4096 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
4098 GEOM::TPythonDump(aFunction)
4099 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnQuadrangle("
4101 << TopAbs_ShapeEnum(theShapeType) << ", "
4102 << theTopLeftPoint << ", "
4103 << theTopRigthPoint << ", "
4104 << theBottomLeftPoint << ", "
4105 << theBottomRigthPoint << ", "
4112 //=======================================================================
4113 //function : GetShapesOnQuadrangleIDs
4115 * \brief Find IDs of sub-shapes complying with given status about quadrangle
4116 * \param theShape - the shape to explore
4117 * \param theShapeType - type of sub-shape of theShape
4118 * \param theTopLeftPoint - top left quadrangle corner
4119 * \param theTopRigthPoint - top right quadrangle corner
4120 * \param theBottomLeftPoint - bottom left quadrangle corner
4121 * \param theBottomRigthPoint - bottom right quadrangle corner
4122 * \param theState - required state
4123 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
4125 //=======================================================================
4126 Handle(TColStd_HSequenceOfInteger)
4127 GEOMImpl_IShapesOperations::GetShapesOnQuadrangleIDs (const Handle(GEOM_Object)& theShape,
4128 const Standard_Integer theShapeType,
4129 const Handle(GEOM_Object)& theTopLeftPoint,
4130 const Handle(GEOM_Object)& theTopRigthPoint,
4131 const Handle(GEOM_Object)& theBottomLeftPoint,
4132 const Handle(GEOM_Object)& theBottomRigthPoint,
4133 const GEOMAlgo_State theState)
4136 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
4137 getShapesOnQuadrangleIDs( theShape,
4142 theBottomRigthPoint,
4144 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->IsEmpty() )
4147 // Make a Python command
4149 // The GetShapesOnCylinder() doesn't change object so no new function is required.
4150 Handle(GEOM_Object) lastObj = GEOM::GetCreatedLast(theShape,theTopLeftPoint);
4151 lastObj = GEOM::GetCreatedLast(lastObj,theTopRigthPoint);
4152 lastObj = GEOM::GetCreatedLast(lastObj,theBottomRigthPoint);
4153 lastObj = GEOM::GetCreatedLast(lastObj,theBottomLeftPoint);
4154 Handle(GEOM_Function) aFunction = lastObj->GetLastFunction();
4156 GEOM::TPythonDump(aFunction, /*append=*/true)
4157 << "listShapesOnQuadrangle = geompy.GetShapesOnQuadrangleIDs("
4159 << TopAbs_ShapeEnum(theShapeType) << ", "
4160 << theTopLeftPoint << ", "
4161 << theTopRigthPoint << ", "
4162 << theBottomLeftPoint << ", "
4163 << theBottomRigthPoint << ", "
4170 //=============================================================================
4175 //=============================================================================
4176 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlace (Handle(GEOM_Object) theShapeWhere,
4177 Handle(GEOM_Object) theShapeWhat)
4181 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
4183 TopoDS_Shape aWhere = theShapeWhere->GetValue();
4184 TopoDS_Shape aWhat = theShapeWhat->GetValue();
4186 if (aWhere.IsNull() || aWhat.IsNull()) {
4187 SetErrorCode("Error: aWhere and aWhat TopoDS_Shape are Null.");
4191 // Searching for the sub-shapes inside the ShapeWhere shape
4192 GEOMAlgo_GetInPlace aGIP;
4194 if (!GEOMAlgo_GetInPlaceAPI::GetInPlace(aWhere, aWhat, aGIP)) {
4195 SetErrorCode("Error in GEOMAlgo_GetInPlace");
4199 // Add direct result.
4200 TopTools_ListOfShape aLSA;
4201 const TopoDS_Shape &aShapeResult = aGIP.Result();
4202 TopTools_MapOfShape aMFence;
4203 TopTools_IndexedMapOfShape aWhereIndices;
4205 TopExp::MapShapes(aWhere, aWhereIndices);
4207 if (aShapeResult.IsNull() == Standard_False) {
4208 TopoDS_Iterator anIt(aShapeResult);
4210 for (; anIt.More(); anIt.Next()) {
4211 const TopoDS_Shape &aPart = anIt.Value();
4213 if(aWhereIndices.Contains(aPart) && aMFence.Add(aPart)) {
4219 if (aLSA.Extent() == 0) {
4220 SetErrorCode(NOT_FOUND_ANY); // Not found any Results
4224 Handle(TColStd_HArray1OfInteger) aModifiedArray = new TColStd_HArray1OfInteger (1, aLSA.Extent());
4225 TopTools_ListIteratorOfListOfShape anIterModif (aLSA);
4226 for (Standard_Integer imod = 1; anIterModif.More(); anIterModif.Next(), imod++) {
4227 if (aWhereIndices.Contains(anIterModif.Value())) {
4228 aModifiedArray->SetValue(imod, aWhereIndices.FindIndex(anIterModif.Value()));
4231 SetErrorCode("Error: wrong sub-shape returned");
4237 Handle(GEOM_Object) aResult = GetEngine()->AddSubShape(theShapeWhere, aModifiedArray);
4238 if (aResult.IsNull()) {
4239 SetErrorCode("Error in algorithm: result found, but cannot be returned.");
4243 if (aModifiedArray->Length() > 1 || theShapeWhat->GetType() == GEOM_GROUP) {
4245 aResult->SetType(GEOM_GROUP);
4247 //Set a sub-shape type
4248 TopoDS_Shape aFirstFound = aLSA.First();
4249 TopAbs_ShapeEnum aShapeType = aFirstFound.ShapeType();
4251 TDF_Label aFreeLabel = aResult->GetFreeLabel();
4252 TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aShapeType);
4255 //Make a Python command
4256 Handle(GEOM_Function) aFunction = aResult->GetFunction(1);
4258 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetInPlace("
4259 << theShapeWhere << ", " << theShapeWhat << ", True)";
4265 //=============================================================================
4267 * case GetInPlaceOld:
4270 //=============================================================================
4271 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlaceOld
4272 (Handle(GEOM_Object) theShapeWhere,
4273 Handle(GEOM_Object) theShapeWhat)
4277 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
4279 TopoDS_Shape aWhere = theShapeWhere->GetValue();
4280 TopoDS_Shape aWhat = theShapeWhat->GetValue();
4281 TopTools_ListOfShape aModifiedList;
4282 const Standard_Integer iErr =
4283 GEOMAlgo_GetInPlaceAPI::GetInPlaceOld(aWhere, aWhat, aModifiedList);
4288 SetErrorCode("Error: aWhere and aWhat TopoDS_Shape are Null.");
4292 ("Error: An attempt to extract a shape of not supported type.");
4295 SetErrorCode(NOT_FOUND_ANY);
4298 SetErrorCode("Shape driver failed");
4305 TopTools_IndexedMapOfShape aWhereIndices;
4306 TopExp::MapShapes(aWhere, aWhereIndices);
4308 Handle(TColStd_HArray1OfInteger) aModifiedArray =
4309 new TColStd_HArray1OfInteger (1, aModifiedList.Extent());
4310 TopTools_ListIteratorOfListOfShape anIterModif (aModifiedList);
4311 Standard_Integer imod;
4313 for (imod = 1; anIterModif.More(); anIterModif.Next(), imod++) {
4314 const Standard_Integer anIndex =
4315 aWhereIndices.FindIndex(anIterModif.Value());
4317 aModifiedArray->SetValue(imod, anIndex);
4321 Handle(GEOM_Object) aResult =
4322 GetEngine()->AddSubShape(theShapeWhere, aModifiedArray);
4324 if (aResult.IsNull()) {
4325 SetErrorCode("Error in algorithm: result found, but cannot be returned.");
4329 if (aModifiedArray->Length() > 1 || theShapeWhat->GetType() == GEOM_GROUP) {
4331 aResult->SetType(GEOM_GROUP);
4333 //Set a sub-shape type
4334 TopoDS_Shape aFirstFound = aWhereIndices.FindKey(aModifiedArray->Value(1));
4335 TopAbs_ShapeEnum aShapeType = aFirstFound.ShapeType();
4337 TDF_Label aFreeLabel = aResult->GetFreeLabel();
4338 TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aShapeType);
4341 //Make a Python command
4342 Handle(GEOM_Function) aFunction = aResult->GetFunction(1);
4344 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetInPlace("
4345 << theShapeWhere << ", " << theShapeWhat << ", False)";
4352 //=======================================================================
4353 //function : GetInPlaceByHistory
4355 //=======================================================================
4356 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlaceByHistory
4357 (Handle(GEOM_Object) theShapeWhere,
4358 Handle(GEOM_Object) theShapeWhat)
4362 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
4364 TopoDS_Shape aWhere = theShapeWhere->GetValue();
4365 TopoDS_Shape aWhat = theShapeWhat->GetValue();
4367 if (aWhere.IsNull() || aWhat.IsNull()) return NULL;
4369 Handle(GEOM_Function) aWhereFunction = theShapeWhere->GetLastFunction();
4370 if (aWhereFunction.IsNull()) return NULL;
4372 //Fill array of indices
4373 TopTools_IndexedMapOfShape aWhereIndices;
4375 TopExp::MapShapes(aWhere, aWhereIndices);
4378 TopTools_ListOfShape aModifiedList;
4379 bool isFound = GEOMAlgo_GetInPlaceAPI::GetInPlaceByHistory
4380 (aWhereFunction, aWhereIndices, aWhat, aModifiedList);
4382 if (!isFound || aModifiedList.Extent() < 1) {
4383 SetErrorCode("Error: No history found for the sought shape or its sub-shapes.");
4387 Standard_Integer nbFound = aModifiedList.Extent();
4388 TopTools_ListIteratorOfListOfShape anIterModif (aModifiedList);
4391 // remove sub-shapes inappropriate for group creation
4392 TopAbs_ShapeEnum subType = TopAbs_SHAPE;
4393 while ( anIterModif.More() ) {
4394 TopAbs_ShapeEnum type = anIterModif.Value().ShapeType();
4395 bool okForGroup = ( type == TopAbs_VERTEX || type == TopAbs_EDGE ||
4396 type == TopAbs_FACE || type == TopAbs_SOLID );
4398 if ( subType == TopAbs_SHAPE )
4401 okForGroup = ( subType == type );
4406 aModifiedList.Remove( anIterModif );
4407 nbFound -= ( !okForGroup );
4409 if ( nbFound == 0 ) {
4410 SetErrorCode("Error: result found but it's type is inappropriate for group creation.");
4415 Handle(TColStd_HArray1OfInteger) aModifiedArray =
4416 new TColStd_HArray1OfInteger( 1, nbFound );
4417 anIterModif.Initialize(aModifiedList);
4418 for (Standard_Integer imod = 1; anIterModif.More(); anIterModif.Next(), imod++)
4419 aModifiedArray->SetValue
4420 (imod, aWhereIndices.FindIndex(anIterModif.Value()));
4423 Handle(GEOM_Object) aResult = GetEngine()->AddSubShape(theShapeWhere, aModifiedArray);
4424 if (aResult.IsNull()) {
4425 SetErrorCode("Error in algorithm: result found, but cannot be returned.");
4429 if (aModifiedArray->Length() > 1) {
4431 aResult->SetType(GEOM_GROUP);
4433 //Set a sub-shape type
4434 TopoDS_Shape aFirstFound = aWhereIndices.FindKey(aModifiedArray->Value(1));
4435 TopAbs_ShapeEnum aShapeType = aFirstFound.ShapeType();
4437 TDF_Label aFreeLabel = aResult->GetFreeLabel();
4438 TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aShapeType);
4441 //Make a Python command
4442 Handle(GEOM_Function) aFunction = aResult->GetFunction(1);
4444 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetInPlaceByHistory("
4445 << theShapeWhere << ", " << theShapeWhat << ")";
4451 //=======================================================================
4452 //function : isSameEdge
4453 //purpose : Returns True if two edges coincide
4454 //=======================================================================
4455 static bool isSameEdge(const TopoDS_Edge& theEdge1, const TopoDS_Edge& theEdge2)
4457 TopoDS_Vertex V11, V12, V21, V22;
4458 TopExp::Vertices(theEdge1, V11, V12);
4459 TopExp::Vertices(theEdge2, V21, V22);
4460 gp_Pnt P11 = BRep_Tool::Pnt(V11);
4461 gp_Pnt P12 = BRep_Tool::Pnt(V12);
4462 gp_Pnt P21 = BRep_Tool::Pnt(V21);
4463 gp_Pnt P22 = BRep_Tool::Pnt(V22);
4464 bool coincide = false;
4466 //Check that ends of edges coincide
4467 if(P11.Distance(P21) <= MAX_TOLERANCE) {
4468 if(P12.Distance(P22) <= MAX_TOLERANCE) coincide = true;
4470 else if(P11.Distance(P22) <= MAX_TOLERANCE) {
4471 if(P12.Distance(P21) <= MAX_TOLERANCE) coincide = true;
4474 if(!coincide) return false;
4476 if (BRep_Tool::Degenerated(theEdge1))
4477 if (BRep_Tool::Degenerated(theEdge2)) return true;
4480 if (BRep_Tool::Degenerated(theEdge2)) return false;
4482 double U11, U12, U21, U22;
4483 Handle(Geom_Curve) C1 = BRep_Tool::Curve(theEdge1, U11, U12);
4484 Handle(Geom_Curve) C2 = BRep_Tool::Curve(theEdge2, U21, U22);
4486 //Check that both edges has the same geometry
4487 double range = U12-U11;
4488 double U = U11+ range/3.0;
4489 gp_Pnt P1 = C1->Value(U); //Compute a point on one third of the edge's length
4490 U = U11+range*2.0/3.0;
4491 gp_Pnt P2 = C1->Value(U); //Compute a point on two thirds of the edge's length
4493 if(!GeomLib_Tool::Parameter(C2, P1, MAX_TOLERANCE, U) || U < U21 || U > U22)
4496 if(P1.Distance(C2->Value(U)) > MAX_TOLERANCE) return false;
4498 if(!GeomLib_Tool::Parameter(C2, P2, MAX_TOLERANCE, U) || U < U21 || U > U22)
4501 if(P2.Distance(C2->Value(U)) > MAX_TOLERANCE) return false;
4506 #include <TopoDS_TShape.hxx>
4507 //=======================================================================
4508 //function : isSameFace
4509 //purpose : Returns True if two faces coincide
4510 //=======================================================================
4511 static bool isSameFace(const TopoDS_Face& theFace1, const TopoDS_Face& theFace2)
4513 TopExp_Explorer E(theFace1, TopAbs_EDGE);
4514 TopTools_ListOfShape LS1, LS2;
4515 for(; E.More(); E.Next()) LS1.Append(E.Current());
4517 E.Init(theFace2, TopAbs_EDGE);
4518 for(; E.More(); E.Next()) LS2.Append(E.Current());
4520 //Compare the number of edges in the faces
4521 if(LS1.Extent() != LS2.Extent()) return false;
4523 double aMin = RealFirst(), aMax = RealLast();
4524 double xminB1=aMax, yminB1=aMax, zminB1=aMax, xminB2=aMax, yminB2=aMax, zminB2=aMax;
4525 double xmaxB1=aMin, ymaxB1=aMin, zmaxB1=aMin, xmaxB2=aMin, ymaxB2=aMin, zmaxB2=aMin;
4527 for(E.Init(theFace1, TopAbs_VERTEX); E.More(); E.Next()) {
4528 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4529 if(P.X() < xminB1) xminB1 = P.X();
4530 if(P.Y() < yminB1) yminB1 = P.Y();
4531 if(P.Z() < zminB1) zminB1 = P.Z();
4532 if(P.X() > xmaxB1) xmaxB1 = P.X();
4533 if(P.Y() > ymaxB1) ymaxB1 = P.Y();
4534 if(P.Z() > zmaxB1) zmaxB1 = P.Z();
4537 for(E.Init(theFace2, TopAbs_VERTEX); E.More(); E.Next()) {
4538 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4539 if(P.X() < xminB2) xminB2 = P.X();
4540 if(P.Y() < yminB2) yminB2 = P.Y();
4541 if(P.Z() < zminB2) zminB2 = P.Z();
4542 if(P.X() > xmaxB2) xmaxB2 = P.X();
4543 if(P.Y() > ymaxB2) ymaxB2 = P.Y();
4544 if(P.Z() > zmaxB2) zmaxB2 = P.Z();
4547 //Compare the bounding boxes of both faces
4548 if(gp_Pnt(xminB1, yminB1, zminB1).Distance(gp_Pnt(xminB2, yminB2, zminB2)) > MAX_TOLERANCE)
4551 if(gp_Pnt(xmaxB1, ymaxB1, zmaxB1).Distance(gp_Pnt(xmaxB2, ymaxB2, zmaxB2)) > MAX_TOLERANCE)
4554 Handle(Geom_Surface) S1 = BRep_Tool::Surface(theFace1);
4555 Handle(Geom_Surface) S2 = BRep_Tool::Surface(theFace2);
4557 //Check if there a coincidence of two surfaces at least in two points
4558 double U11, U12, V11, V12, U21, U22, V21, V22;
4559 BRepTools::UVBounds(theFace1, U11, U12, V11, V12);
4560 BRepTools::UVBounds(theFace2, U21, U22, V21, V22);
4562 double rangeU = U12-U11;
4563 double rangeV = V12-V11;
4564 double U = U11 + rangeU/3.0;
4565 double V = V11 + rangeV/3.0;
4566 gp_Pnt P1 = S1->Value(U, V);
4567 U = U11+rangeU*2.0/3.0;
4568 V = V11+rangeV*2.0/3.0;
4569 gp_Pnt P2 = S1->Value(U, V);
4571 if (!GeomLib_Tool::Parameters(S2, P1, MAX_TOLERANCE, U, V) || U < U21 || U > U22 || V < V21 || V > V22)
4574 if (P1.Distance(S2->Value(U,V)) > MAX_TOLERANCE) return false;
4576 if (!GeomLib_Tool::Parameters(S2, P2, MAX_TOLERANCE, U, V) || U < U21 || U > U22 || V < V21 || V > V22)
4579 if (P2.Distance(S2->Value(U, V)) > MAX_TOLERANCE) return false;
4581 //Check that each edge of the Face1 has a counterpart in the Face2
4582 TopTools_MapOfOrientedShape aMap;
4583 TopTools_ListIteratorOfListOfShape LSI1(LS1);
4584 for(; LSI1.More(); LSI1.Next()) {
4585 TopoDS_Edge E = TopoDS::Edge(LSI1.Value());
4586 bool isFound = false;
4587 TopTools_ListIteratorOfListOfShape LSI2(LS2);
4588 for(; LSI2.More(); LSI2.Next()) {
4589 TopoDS_Shape aValue = LSI2.Value();
4590 if(aMap.Contains(aValue)) continue; //To avoid checking already found edge several times
4591 if(isSameEdge(E, TopoDS::Edge(aValue))) {
4597 if(!isFound) return false;
4603 //=======================================================================
4604 //function : isSameSolid
4605 //purpose : Returns True if two solids coincide
4606 //=======================================================================
4607 bool isSameSolid(const TopoDS_Solid& theSolid1, const TopoDS_Solid& theSolid2)
4609 TopExp_Explorer E(theSolid1, TopAbs_FACE);
4610 TopTools_ListOfShape LS1, LS2;
4611 for(; E.More(); E.Next()) LS1.Append(E.Current());
4612 E.Init(theSolid2, TopAbs_FACE);
4613 for(; E.More(); E.Next()) LS2.Append(E.Current());
4615 if(LS1.Extent() != LS2.Extent()) return false;
4617 double aMin = RealFirst(), aMax = RealLast();
4618 double xminB1=aMax, yminB1=aMax, zminB1=aMax, xminB2=aMax, yminB2=aMax, zminB2=aMax;
4619 double xmaxB1=aMin, ymaxB1=aMin, zmaxB1=aMin, xmaxB2=aMin, ymaxB2=aMin, zmaxB2=aMin;
4621 for(E.Init(theSolid1, TopAbs_VERTEX); E.More(); E.Next()) {
4622 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4623 if(P.X() < xminB1) xminB1 = P.X();
4624 if(P.Y() < yminB1) yminB1 = P.Y();
4625 if(P.Z() < zminB1) zminB1 = P.Z();
4626 if(P.X() > xmaxB1) xmaxB1 = P.X();
4627 if(P.Y() > ymaxB1) ymaxB1 = P.Y();
4628 if(P.Z() > zmaxB1) zmaxB1 = P.Z();
4631 for(E.Init(theSolid2, TopAbs_VERTEX); E.More(); E.Next()) {
4632 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4633 if(P.X() < xminB2) xminB2 = P.X();
4634 if(P.Y() < yminB2) yminB2 = P.Y();
4635 if(P.Z() < zminB2) zminB2 = P.Z();
4636 if(P.X() > xmaxB2) xmaxB2 = P.X();
4637 if(P.Y() > ymaxB2) ymaxB2 = P.Y();
4638 if(P.Z() > zmaxB2) zmaxB2 = P.Z();
4641 //Compare the bounding boxes of both solids
4642 if(gp_Pnt(xminB1, yminB1, zminB1).Distance(gp_Pnt(xminB2, yminB2, zminB2)) > MAX_TOLERANCE)
4645 if(gp_Pnt(xmaxB1, ymaxB1, zmaxB1).Distance(gp_Pnt(xmaxB2, ymaxB2, zmaxB2)) > MAX_TOLERANCE)
4648 //Check that each face of the Solid1 has a counterpart in the Solid2
4649 TopTools_MapOfOrientedShape aMap;
4650 TopTools_ListIteratorOfListOfShape LSI1(LS1);
4651 for(; LSI1.More(); LSI1.Next()) {
4652 TopoDS_Face F = TopoDS::Face(LSI1.Value());
4653 bool isFound = false;
4654 TopTools_ListIteratorOfListOfShape LSI2(LS2);
4655 for(; LSI2.More(); LSI2.Next()) {
4656 if(aMap.Contains(LSI2.Value())) continue; //To avoid checking already found faces several times
4657 if(isSameFace(F, TopoDS::Face(LSI2.Value()))) {
4658 aMap.Add(LSI2.Value());
4663 if(!isFound) return false;
4669 //=======================================================================
4670 //function : GetSame
4672 //=======================================================================
4673 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetSame(const Handle(GEOM_Object)& theShapeWhere,
4674 const Handle(GEOM_Object)& theShapeWhat)
4677 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
4679 TopoDS_Shape aWhere = theShapeWhere->GetValue();
4680 TopoDS_Shape aWhat = theShapeWhat->GetValue();
4682 if (aWhere.IsNull() || aWhat.IsNull()) return NULL;
4685 bool isFound = false;
4686 TopoDS_Shape aSubShape;
4687 TopTools_MapOfShape aMap;
4689 if (aWhat.ShapeType() == TopAbs_COMPOUND || aWhat.ShapeType() == TopAbs_COMPSOLID) {
4690 TopoDS_Iterator It (aWhat, Standard_True, Standard_True);
4691 if (It.More()) aWhat = It.Value();
4694 SetErrorCode("Compounds of two or more shapes are not allowed for aWhat argument");
4699 switch (aWhat.ShapeType()) {
4700 case TopAbs_VERTEX: {
4701 aSubShape = getSameVertex(aWhere, TopoDS::Vertex(aWhat));
4702 isFound = !aSubShape.IsNull();
4706 TopoDS_Edge anEdge = TopoDS::Edge(aWhat);
4707 TopExp_Explorer E(aWhere, TopAbs_EDGE);
4708 for(; E.More(); E.Next()) {
4709 if(!aMap.Add(E.Current())) continue;
4710 if(isSameEdge(anEdge, TopoDS::Edge(E.Current()))) {
4711 aSubShape = E.Current();
4719 TopoDS_Face aFace = TopoDS::Face(aWhat);
4720 TopExp_Explorer E(aWhere, TopAbs_FACE);
4721 for(; E.More(); E.Next()) {
4722 if(!aMap.Add(E.Current())) continue;
4723 if(isSameFace(aFace, TopoDS::Face(E.Current()))) {
4724 aSubShape = E.Current();
4731 case TopAbs_SOLID: {
4732 TopoDS_Solid aSolid = TopoDS::Solid(aWhat);
4733 TopExp_Explorer E(aWhere, TopAbs_SOLID);
4734 for(; E.More(); E.Next()) {
4735 if(!aMap.Add(E.Current())) continue;
4736 if(isSameSolid(aSolid, TopoDS::Solid(E.Current()))) {
4737 aSubShape = E.Current();
4749 TopTools_IndexedMapOfShape anIndices;
4750 TopExp::MapShapes(aWhere, anIndices);
4751 if (anIndices.Contains(aSubShape))
4752 anIndex = anIndices.FindIndex(aSubShape);
4755 if (anIndex < 0) return NULL;
4757 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
4759 anArray->SetValue(1, anIndex);
4761 Handle(GEOM_Object) aResult = GetEngine()->AddSubShape(theShapeWhere, anArray);
4762 Handle(GEOM_Function) aFunction = aResult->GetLastFunction();
4764 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetSame("
4765 << theShapeWhere << ", " << theShapeWhat << ")";
4773 //=======================================================================
4774 //function : GetSameIDs
4776 //=======================================================================
4777 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetSameIDs
4778 (const Handle(GEOM_Object)& theShapeWhere,
4779 const Handle(GEOM_Object)& theShapeWhat)
4782 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
4784 TopoDS_Shape aWhere = theShapeWhere->GetValue();
4785 TopoDS_Shape aWhat = theShapeWhat->GetValue();
4787 if (aWhere.IsNull() || aWhat.IsNull()) return NULL;
4789 TopTools_ListOfShape listShape;
4790 TopTools_MapOfShape aMap;
4792 if (aWhat.ShapeType() == TopAbs_COMPOUND || aWhat.ShapeType() == TopAbs_COMPSOLID) {
4793 TopoDS_Iterator It (aWhat, Standard_True, Standard_True);
4794 if (It.More()) aWhat = It.Value();
4797 SetErrorCode("Compounds of two or more shapes are not allowed for aWhat argument");
4802 switch (aWhat.ShapeType()) {
4803 case TopAbs_VERTEX: {
4804 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(aWhat));
4805 TopExp_Explorer E(aWhere, TopAbs_VERTEX);
4806 for(; E.More(); E.Next()) {
4807 if(!aMap.Add(E.Current())) continue;
4808 gp_Pnt P2 = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4809 if(P.Distance(P2) <= MAX_TOLERANCE) {
4810 listShape.Append(E.Current());
4816 TopoDS_Edge anEdge = TopoDS::Edge(aWhat);
4817 TopExp_Explorer E(aWhere, TopAbs_EDGE);
4818 for(; E.More(); E.Next()) {
4819 if(!aMap.Add(E.Current())) continue;
4820 if(isSameEdge(anEdge, TopoDS::Edge(E.Current()))) {
4821 listShape.Append(E.Current());
4827 TopoDS_Face aFace = TopoDS::Face(aWhat);
4828 TopExp_Explorer E(aWhere, TopAbs_FACE);
4829 for(; E.More(); E.Next()) {
4830 if(!aMap.Add(E.Current())) continue;
4831 if(isSameFace(aFace, TopoDS::Face(E.Current()))) {
4832 listShape.Append(E.Current());
4837 case TopAbs_SOLID: {
4838 TopoDS_Solid aSolid = TopoDS::Solid(aWhat);
4839 TopExp_Explorer E(aWhere, TopAbs_SOLID);
4840 for(; E.More(); E.Next()) {
4841 if(!aMap.Add(E.Current())) continue;
4842 if(isSameSolid(aSolid, TopoDS::Solid(E.Current()))) {
4843 listShape.Append(E.Current());
4852 if ( !listShape.IsEmpty() ) {
4853 TopTools_IndexedMapOfShape anIndices;
4854 TopExp::MapShapes(aWhere, anIndices);
4855 TopTools_ListIteratorOfListOfShape itSub (listShape);
4856 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
4857 for (; itSub.More(); itSub.Next()) {
4858 if (anIndices.Contains(itSub.Value()))
4859 aSeq->Append(anIndices.FindIndex(itSub.Value()));
4862 // The GetSameIDs() doesn't change object so no new function is required.
4863 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShapeWhere,theShapeWhat)->GetLastFunction();
4865 // Make a Python command
4866 GEOM::TPythonDump(aFunction, /*append=*/true)
4867 << "listSameIDs = geompy.GetSameIDs("
4868 << theShapeWhere << ", "
4869 << theShapeWhat << ")";
4872 SetErrorCode(NOT_FOUND_ANY);
4877 //=======================================================================
4878 //function : ExtendEdge
4880 //=======================================================================
4881 Handle(GEOM_Object) GEOMImpl_IShapesOperations::ExtendEdge
4882 (const Handle(GEOM_Object) &theEdge,
4883 const Standard_Real theMin,
4884 const Standard_Real theMax)
4888 if (theEdge.IsNull()) {
4892 //Add a new Edge object
4893 Handle(GEOM_Object) aResEdge = GetEngine()->AddObject(GetDocID(), GEOM_EDGE);
4895 //Add a new Vector function
4896 Handle(GEOM_Function) aFunction =
4897 aResEdge->AddFunction(GEOMImpl_ShapeDriver::GetID(), EDGE_UV);
4899 //Check if the function is set correctly
4900 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) {
4904 GEOMImpl_IShapeExtend aCI (aFunction);
4906 Handle(GEOM_Function) anEdge = theEdge->GetLastFunction();
4908 if (anEdge.IsNull()) {
4912 aCI.SetShape(anEdge);
4913 aCI.SetUMin(theMin);
4914 aCI.SetUMax(theMax);
4916 //Compute the Edge value
4919 if (!GetSolver()->ComputeFunction(aFunction)) {
4920 SetErrorCode("Shape driver failed");
4925 catch (Standard_Failure) {
4926 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
4927 SetErrorCode(aFail->GetMessageString());
4932 //Make a Python command
4933 GEOM::TPythonDump(aFunction)
4934 << aResEdge << " = geompy.ExtendEdge("
4935 << theEdge << ", " << theMin << ", " << theMax << ")";
4942 //=======================================================================
4943 //function : ExtendFace
4945 //=======================================================================
4946 Handle(GEOM_Object) GEOMImpl_IShapesOperations::ExtendFace
4947 (const Handle(GEOM_Object) &theFace,
4948 const Standard_Real theUMin,
4949 const Standard_Real theUMax,
4950 const Standard_Real theVMin,
4951 const Standard_Real theVMax)
4955 if (theFace.IsNull()) {
4959 //Add a new Face object
4960 Handle(GEOM_Object) aResFace = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
4962 //Add a new Vector function
4963 Handle(GEOM_Function) aFunction =
4964 aResFace->AddFunction(GEOMImpl_ShapeDriver::GetID(), FACE_UV);
4966 //Check if the function is set correctly
4967 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) {
4971 GEOMImpl_IShapeExtend aCI (aFunction);
4973 Handle(GEOM_Function) aFace = theFace->GetLastFunction();
4975 if (aFace.IsNull()) {
4979 aCI.SetShape(aFace);
4980 aCI.SetUMin(theUMin);
4981 aCI.SetUMax(theUMax);
4982 aCI.SetVMin(theVMin);
4983 aCI.SetVMax(theVMax);
4985 //Compute the Face value
4988 if (!GetSolver()->ComputeFunction(aFunction)) {
4989 SetErrorCode("Shape driver failed");
4994 catch (Standard_Failure) {
4995 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
4996 SetErrorCode(aFail->GetMessageString());
5001 //Make a Python command
5002 GEOM::TPythonDump(aFunction)
5003 << aResFace << " = geompy.ExtendFace("
5004 << theFace << ", " << theUMin << ", " << theUMax << ", "
5005 << theVMin << ", " << theVMax << ")";
5012 //=======================================================================
5013 //function : MakeSurfaceFromFace
5015 //=======================================================================
5016 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeSurfaceFromFace
5017 (const Handle(GEOM_Object) &theFace)
5021 if (theFace.IsNull()) {
5025 //Add a new Face object
5026 Handle(GEOM_Object) aResFace = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
5028 //Add a new Vector function
5029 Handle(GEOM_Function) aFunction =
5030 aResFace->AddFunction(GEOMImpl_ShapeDriver::GetID(), SURFACE_FROM_FACE);
5032 //Check if the function is set correctly
5033 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) {
5037 GEOMImpl_IShapeExtend aCI (aFunction);
5039 Handle(GEOM_Function) aFace = theFace->GetLastFunction();
5041 if (aFace.IsNull()) {
5045 aCI.SetShape(aFace);
5047 //Compute the Face value
5050 if (!GetSolver()->ComputeFunction(aFunction)) {
5051 SetErrorCode("Shape driver failed");
5056 catch (Standard_Failure) {
5057 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
5058 SetErrorCode(aFail->GetMessageString());
5063 //Make a Python command
5064 GEOM::TPythonDump(aFunction)
5065 << aResFace << " = geompy.MakeSurfaceFromFace("