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 // Keep the old error code as IsSubShapeBelongsTo changes it.
694 TCollection_AsciiString anOldCode = GetErrorCode();
696 if ( IsSubShapeBelongsTo( anObject, 0, aFace, 0 ) ) {
698 SetErrorCode(anOldCode);
699 aRefSh = aFace->GetLastFunction();
700 aConstraints->Append(aRefSh);
705 SetErrorCode("Face is NULL or not connected to the Edge");
710 aCI.SetShapes( aConstraints );
713 Standard_Boolean isWarning = Standard_False;
716 if (!GetSolver()->ComputeFunction(aFunction)) {
717 SetErrorCode("Shape driver failed");
721 catch (Standard_Failure) {
722 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
723 SetErrorCode(aFail->GetMessageString());
724 // to provide warning
725 if (!aFunction->GetValue().IsNull()) {
726 isWarning = Standard_True;
732 //Make a Python command
733 GEOM::TPythonDump pd (aFunction);
734 pd << aShape << " = geompy.MakeFaceWithConstraints([";
737 it = theConstraints.begin();
738 if (it != theConstraints.end() ) {
740 while (it != theConstraints.end()) {
741 Handle(GEOM_Object) anObject = (*it++);
742 if( !anObject.IsNull() )
743 pd << ", " << anObject;
748 // to provide warning
749 if (!isWarning) SetErrorCode(OK);
753 //=============================================================================
757 //=============================================================================
758 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeShell
759 (std::list<Handle(GEOM_Object)> theShapes)
761 return MakeShape(theShapes, GEOM_SHELL, SHELL_FACES, "MakeShell");
764 //=============================================================================
768 //=============================================================================
769 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeSolidShells
770 (std::list<Handle(GEOM_Object)> theShapes)
772 return MakeShape(theShapes, GEOM_SOLID, SOLID_SHELLS, "MakeSolid");
775 //=============================================================================
779 //=============================================================================
780 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeCompound
781 (std::list<Handle(GEOM_Object)> theShapes)
783 return MakeShape(theShapes, GEOM_COMPOUND, COMPOUND_SHAPES, "MakeCompound");
786 //=============================================================================
790 //=============================================================================
791 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeShape
792 (std::list<Handle(GEOM_Object)> theShapes,
793 const Standard_Integer theObjectType,
794 const Standard_Integer theFunctionType,
795 const TCollection_AsciiString& theMethodName)
800 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), theObjectType);
803 Handle(GEOM_Function) aFunction =
804 aShape->AddFunction(GEOMImpl_ShapeDriver::GetID(), theFunctionType);
805 if (aFunction.IsNull()) return NULL;
807 //Check if the function is set correctly
808 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
810 GEOMImpl_IShapes aCI (aFunction);
812 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
815 std::list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
816 for (; it != theShapes.end(); it++) {
817 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
818 if (aRefSh.IsNull()) {
819 SetErrorCode("NULL argument shape for the shape construction");
822 aShapesSeq->Append(aRefSh);
824 aCI.SetShapes(aShapesSeq);
829 if (!GetSolver()->ComputeFunction(aFunction)) {
830 SetErrorCode("Shape driver failed");
834 catch (Standard_Failure) {
835 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
836 SetErrorCode(aFail->GetMessageString());
840 //Make a Python command
841 GEOM::TPythonDump pd (aFunction);
842 pd << aShape << " = geompy." << theMethodName.ToCString() << "([";
845 it = theShapes.begin();
846 if (it != theShapes.end()) {
848 while (it != theShapes.end()) {
849 pd << ", " << (*it++);
858 //=============================================================================
860 * MakeSolidFromConnectedFaces
862 //=============================================================================
863 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeSolidFromConnectedFaces
864 (std::list<Handle(GEOM_Object)> theFacesOrShells,
865 const Standard_Boolean isIntersect)
870 Handle(GEOM_Object) aSolid = GetEngine()->AddObject(GetDocID(), GEOM_SOLID);
873 Handle(GEOM_Function) aFunction =
874 aSolid->AddFunction(GEOMImpl_ShapeDriver::GetID(), SOLID_FACES);
875 if (aFunction.IsNull()) return NULL;
877 //Check if the function is set correctly
878 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
880 GEOMImpl_IShapes aCI (aFunction);
882 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
885 std::list<Handle(GEOM_Object)>::iterator it = theFacesOrShells.begin();
886 for (; it != theFacesOrShells.end(); it++) {
887 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
888 if (aRefSh.IsNull()) {
889 SetErrorCode("NULL argument shape for the shape construction");
892 aShapesSeq->Append(aRefSh);
894 aCI.SetShapes(aShapesSeq);
895 aCI.SetIsIntersect(isIntersect);
900 if (!GetSolver()->ComputeFunction(aFunction)) {
901 SetErrorCode("Shape driver failed");
905 catch (Standard_Failure) {
906 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
907 SetErrorCode(aFail->GetMessageString());
911 //Make a Python command
912 GEOM::TPythonDump pd (aFunction);
913 pd << aSolid << " = geompy.MakeSolidFromConnectedFaces([";
916 it = theFacesOrShells.begin();
917 if (it != theFacesOrShells.end()) {
919 while (it != theFacesOrShells.end()) {
920 pd << ", " << (*it++);
923 pd << "]," << (isIntersect ? "True" : "False") << ")";
929 //=============================================================================
933 //=============================================================================
935 GEOMImpl_IShapesOperations::MakeGlueFaces (std::list< Handle(GEOM_Object) >& theShapes,
936 const Standard_Real theTolerance,
937 const Standard_Boolean doKeepNonSolids)
941 Handle(TColStd_HSequenceOfTransient) objects = GEOM_Object::GetLastFunctions( theShapes );
942 if ( objects.IsNull() || objects->IsEmpty() ) {
943 SetErrorCode("NULL argument shape");
947 //Add a new Glued object
948 Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
950 //Add a new Glue function
951 Handle(GEOM_Function) aFunction;
952 aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_FACES);
953 if (aFunction.IsNull()) return NULL;
955 //Check if the function is set correctly
956 if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
958 GEOMImpl_IGlue aCI (aFunction);
960 aCI.SetBase( objects );
961 aCI.SetTolerance(theTolerance);
962 aCI.SetKeepNonSolids(doKeepNonSolids);
964 //Compute the sub-shape value
965 Standard_Boolean isWarning = Standard_False;
968 if (!GetSolver()->ComputeFunction(aFunction)) {
969 SetErrorCode("Shape driver failed to glue faces");
973 catch (Standard_Failure) {
974 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
975 SetErrorCode(aFail->GetMessageString());
976 // to provide warning
977 if (!aFunction->GetValue().IsNull()) {
978 isWarning = Standard_True;
984 //Make a Python command
985 GEOM::TPythonDump(aFunction) << aGlued << " = geompy.MakeGlueFaces("
986 << theShapes << ", " << theTolerance << ")";
988 // to provide warning
989 if (!isWarning) SetErrorCode(OK);
993 //=============================================================================
997 //=============================================================================
999 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetGlueFaces
1000 (Handle(GEOM_Object) theShape,
1001 const Standard_Real theTolerance)
1005 if (theShape.IsNull()) return NULL;
1006 TopoDS_Shape aShape = theShape->GetValue();
1007 if (aShape.IsNull()) return NULL;
1009 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1011 Standard_Integer iErr;
1013 GEOMAlgo_Gluer1 aGluer;
1014 GEOMAlgo_ListIteratorOfListOfCoupleOfShapes aItCS;
1015 GEOMAlgo_CoupleOfShapes aCS;
1016 GEOMAlgo_ListOfCoupleOfShapes aLCS;
1018 //aGluer = new GEOMAlgo_Gluer1;
1019 aGluer.SetShape(aShape);
1020 aGluer.SetTolerance(theTolerance);
1022 iErr = aGluer.ErrorStatus();
1023 if (iErr) return NULL;
1025 TopTools_ListOfShape listShape;
1026 const GEOMAlgo_ListOfCoupleOfShapes& aLCSG = aGluer.GluedFaces();
1028 aItCS.Initialize(aLCSG);
1029 for (; aItCS.More(); aItCS.Next()) {
1030 const GEOMAlgo_CoupleOfShapes& aCSG = aItCS.Value();
1031 listShape.Append(aCSG.Shape1());
1034 TopTools_ListIteratorOfListOfShape itSub (listShape);
1035 TCollection_AsciiString anAsciiList, anEntry;
1036 TopTools_IndexedMapOfShape anIndices;
1037 TopExp::MapShapes(aShape, anIndices);
1038 Handle(TColStd_HArray1OfInteger) anArray;
1039 Handle(GEOM_Object) anObj;
1040 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
1041 TopoDS_Shape aValue = itSub.Value();
1042 anArray = new TColStd_HArray1OfInteger(1,1);
1043 anArray->SetValue(1, anIndices.FindIndex(aValue));
1044 anObj = GetEngine()->AddSubShape(theShape, anArray);
1045 if (!anObj.IsNull()) {
1046 aSeq->Append(anObj);
1048 // for python command
1049 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
1050 anAsciiList += anEntry;
1055 //Make a Python command
1056 if( anAsciiList.Length() > 0 ) {
1057 anAsciiList.Trunc(anAsciiList.Length() - 1);
1058 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
1059 GEOM::TPythonDump pd (aFunction, true);
1060 pd << "[" << anAsciiList.ToCString();
1061 pd << "] = geompy.GetGlueFaces(" << theShape << ", " << theTolerance << ")";
1070 //=============================================================================
1072 * MakeGlueFacesByList
1074 //=============================================================================
1076 GEOMImpl_IShapesOperations::MakeGlueFacesByList(std::list< Handle(GEOM_Object) >& theShapes,
1077 const Standard_Real theTolerance,
1078 std::list<Handle(GEOM_Object)> & theFaces,
1079 const Standard_Boolean doKeepNonSolids,
1080 const Standard_Boolean doGlueAllEdges)
1084 Handle(TColStd_HSequenceOfTransient) objects = GEOM_Object::GetLastFunctions( theShapes );
1085 if ( objects.IsNull() || objects->IsEmpty() ) {
1086 SetErrorCode("NULL argument shape");
1089 Handle(TColStd_HSequenceOfTransient) aFaces = GEOM_Object::GetLastFunctions( theFaces );
1090 if ( aFaces.IsNull() ) {
1091 SetErrorCode("NULL argument shape for the shape construction");
1095 //Add a new Glued object
1096 Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
1098 //Add a new Glue function
1099 Handle(GEOM_Function) aFunction;
1100 aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_FACES_BY_LIST);
1101 if (aFunction.IsNull()) return NULL;
1103 //Check if the function is set correctly
1104 if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
1106 GEOMImpl_IGlue aCI (aFunction);
1108 aCI.SetBase( objects );
1109 aCI.SetTolerance(theTolerance);
1110 aCI.SetKeepNonSolids(doKeepNonSolids);
1111 aCI.SetGlueAllEdges(doGlueAllEdges);
1112 aCI.SetFaces(aFaces);
1114 //Compute the sub-shape value
1115 Standard_Boolean isWarning = Standard_False;
1118 if (!GetSolver()->ComputeFunction(aFunction)) {
1119 SetErrorCode("Shape driver failed to glue faces");
1123 catch (Standard_Failure) {
1124 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1125 SetErrorCode(aFail->GetMessageString());
1126 // to provide warning
1127 if (!aFunction->GetValue().IsNull()) {
1128 isWarning = Standard_True;
1134 //Make a Python command
1136 GEOM::TPythonDump pd(aFunction);
1137 pd << aGlued << " = geompy.MakeGlueFacesByList("
1138 << theShapes << ", " << theTolerance << ", " << theFaces << ", "
1139 << (bool)doKeepNonSolids << ", " << (bool)doGlueAllEdges << ")";
1141 // to provide warning
1142 if (!isWarning) SetErrorCode(OK);
1146 //=============================================================================
1150 //=============================================================================
1152 GEOMImpl_IShapesOperations::MakeGlueEdges (std::list< Handle(GEOM_Object) >& theShapes,
1153 const Standard_Real theTolerance)
1157 Handle(TColStd_HSequenceOfTransient) objects = GEOM_Object::GetLastFunctions( theShapes );
1158 if ( objects.IsNull() || objects->IsEmpty() ) {
1159 SetErrorCode("NULL argument shape");
1163 //Add a new Glued object
1164 Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
1166 //Add a new Glue function
1167 Handle(GEOM_Function) aFunction;
1168 aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_EDGES);
1169 if (aFunction.IsNull()) return NULL;
1171 //Check if the function is set correctly
1172 if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
1174 GEOMImpl_IGlue aCI (aFunction);
1176 aCI.SetBase( objects );
1177 aCI.SetTolerance(theTolerance);
1178 aCI.SetKeepNonSolids(true);
1180 //Compute the sub-shape value
1181 Standard_Boolean isWarning = Standard_False;
1184 if (!GetSolver()->ComputeFunction(aFunction)) {
1185 SetErrorCode("Shape driver failed to glue edges");
1189 catch (Standard_Failure) {
1190 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1191 SetErrorCode(aFail->GetMessageString());
1192 // to provide warning
1193 if (!aFunction->GetValue().IsNull()) {
1194 isWarning = Standard_True;
1200 //Make a Python command
1201 GEOM::TPythonDump(aFunction) << aGlued << " = geompy.MakeGlueEdges("
1202 << theShapes << ", " << theTolerance << ")";
1204 // to provide warning
1205 if (!isWarning) SetErrorCode(OK);
1209 //=============================================================================
1213 //=============================================================================
1214 Handle(TColStd_HSequenceOfTransient)
1215 GEOMImpl_IShapesOperations::GetGlueShapes (std::list< Handle(GEOM_Object) >& theShapes,
1216 const Standard_Real theTolerance,
1217 const TopAbs_ShapeEnum theType)
1221 TopoDS_Shape aShape;
1222 TopTools_SequenceOfShape shapes;
1223 std::list< Handle(GEOM_Object) >::iterator s = theShapes.begin();
1224 Handle(GEOM_Object) lastCreatedGO;
1225 for ( ; s != theShapes.end(); ++s )
1227 Handle(GEOM_Object) go = *s;
1228 if ( go.IsNull() ) return NULL;
1229 aShape = go->GetValue();
1230 if ( aShape.IsNull() ) return NULL;
1231 shapes.Append( aShape );
1232 lastCreatedGO = GEOM::GetCreatedLast( lastCreatedGO, go );
1234 if ( shapes.Length() > 1 )
1236 TopoDS_Compound compound;
1237 BRep_Builder builder;
1238 builder.MakeCompound( compound );
1239 for ( int i = 1; i <= shapes.Length(); ++i )
1240 builder.Add( compound, shapes( i ) );
1245 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1247 GEOMAlgo_GlueDetector aGluer;
1248 aGluer.SetArgument(aShape);
1249 aGluer.SetTolerance(theTolerance);
1251 Standard_Integer iErr = aGluer.ErrorStatus();
1252 if (iErr) return NULL;
1254 std::vector< TopTools_IndexedMapOfShape* > anIndices( shapes.Length(), NULL );
1255 Handle(TColStd_HArray1OfInteger) anArray;
1256 Handle(GEOM_Object) anObj;
1258 TopTools_ListOfShape listOnePerSet;
1260 const TopTools_DataMapOfShapeListOfShape& aImages = aGluer.Images();
1261 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape aItDMSLS (aImages);
1262 for (int index = 1; aItDMSLS.More(); aItDMSLS.Next(), ++index) {
1264 //const TopoDS_Shape& aSkey = aItDMSLS.Key();
1266 // list of shapes of the argument that can be glued
1267 const TopTools_ListOfShape& aLSD = aItDMSLS.Value();
1269 //listShape.Append(aLSD.First());
1270 TopoDS_Shape aValue = aLSD.First();
1272 if (aValue.ShapeType() == theType) {
1273 listOnePerSet.Append(aValue);
1277 // for stable order of returned entities
1278 GEOMUtils::SortShapes(listOnePerSet, Standard_False);
1280 TopTools_ListIteratorOfListOfShape aListIt (listOnePerSet);
1281 for (; aListIt.More(); aListIt.Next())
1283 TopoDS_Shape aValue = aListIt.Value();
1284 // find a shape to add aValue as a sub-shape
1286 s = theShapes.begin();
1287 for ( int i = 0; i < shapes.Length(); ++i, ++s )
1289 Handle(GEOM_Object) object = *s;
1290 if ( !anIndices[i] ) {
1291 anIndices[i] = new TopTools_IndexedMapOfShape;
1292 TopExp::MapShapes( object->GetValue(), *anIndices[i]);
1294 if (int index = anIndices[i]->FindIndex( aValue )) {
1295 anArray = new TColStd_HArray1OfInteger(1,1);
1296 anArray->SetValue(1, index);
1297 anObj = GetEngine()->AddSubShape( object, anArray);
1301 if (!anObj.IsNull())
1302 aSeq->Append(anObj);
1304 for ( size_t i = 0 ; i < anIndices.size(); ++i )
1305 delete anIndices[i];
1307 // Make a Python command
1308 if ( aSeq->Length() > 0)
1310 Handle(GEOM_Function) aFunction = lastCreatedGO->GetLastFunction();
1311 GEOM::TPythonDump pd (aFunction, /*append=*/true);
1313 << " = geompy." << (theType == TopAbs_FACE ? "GetGlueFaces" : "GetGlueEdges" )
1314 << "( " << theShapes << ", " << theTolerance << ")";
1322 //=============================================================================
1324 * MakeGlueEdgesByList
1326 //=============================================================================
1328 GEOMImpl_IShapesOperations::MakeGlueEdgesByList (std::list< Handle(GEOM_Object) >& theShapes,
1329 const Standard_Real theTolerance,
1330 std::list<Handle(GEOM_Object)>& theEdges)
1334 Handle(TColStd_HSequenceOfTransient) objects = GEOM_Object::GetLastFunctions( theShapes );
1335 if ( objects.IsNull() || objects->IsEmpty() ) {
1336 SetErrorCode("NULL argument shape");
1339 Handle(TColStd_HSequenceOfTransient) anEdges = GEOM_Object::GetLastFunctions( theEdges );
1340 if ( anEdges.IsNull() ) {
1341 SetErrorCode("NULL argument shape for the shape construction");
1344 //Add a new Glued object
1345 Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
1347 //Add a new Glue function
1348 Handle(GEOM_Function) aFunction;
1349 aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_EDGES_BY_LIST);
1350 if (aFunction.IsNull()) return NULL;
1352 //Check if the function is set correctly
1353 if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
1355 GEOMImpl_IGlue aCI (aFunction);
1357 aCI.SetBase( objects );
1358 aCI.SetTolerance(theTolerance);
1359 aCI.SetKeepNonSolids(true);
1360 aCI.SetFaces(anEdges);
1362 //Compute the sub-shape value
1363 Standard_Boolean isWarning = Standard_False;
1366 if (!GetSolver()->ComputeFunction(aFunction)) {
1367 SetErrorCode("Shape driver failed to glue edges");
1371 catch (Standard_Failure) {
1372 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1373 SetErrorCode(aFail->GetMessageString());
1374 // to provide warning
1375 if (!aFunction->GetValue().IsNull()) {
1376 isWarning = Standard_True;
1382 //Make a Python command
1384 GEOM::TPythonDump pd (aFunction);
1385 pd << aGlued << " = geompy.MakeGlueEdgesByList("
1386 << theShapes << ", " << theTolerance << ", " << theEdges << " )";
1388 // to provide warning
1389 if (!isWarning) SetErrorCode(OK);
1393 //=============================================================================
1395 * GetExistingSubObjects
1397 //=============================================================================
1398 Handle(TColStd_HSequenceOfTransient)
1399 GEOMImpl_IShapesOperations::GetExistingSubObjects(Handle(GEOM_Object) theShape,
1400 const Standard_Boolean theGroupsOnly)
1402 // note: this method does not return fields
1404 Standard_Integer types = theGroupsOnly ? Groups : Groups|SubShapes;
1405 Handle(TColStd_HSequenceOfTransient) results = GetExistingSubObjects(theShape, types);
1407 if (results->Length() > 0) {
1408 //Make a Python command
1409 TCollection_AsciiString anAsciiList;
1410 for (int i = 1; i <= results->Length(); i++)
1412 Handle(GEOM_BaseObject) obj = Handle(GEOM_BaseObject)::DownCast( results->Value(i));
1413 obj->GetEntryString();
1414 if ( i < results->Length() )
1418 GEOM::TPythonDump pd (theShape->GetLastFunction(), /*append=*/true);
1419 pd << "[" << anAsciiList.ToCString();
1420 pd << "] = geompy.GetExistingSubObjects(";
1421 pd << theShape << ", " << (bool)theGroupsOnly << ")";
1427 Handle(TColStd_HSequenceOfTransient)
1428 GEOMImpl_IShapesOperations::GetExistingSubObjects(Handle(GEOM_Object) theShape,
1429 const Standard_Integer theTypes)
1433 if (theShape.IsNull()) return NULL;
1435 Handle(GEOM_Function) aMainShape = theShape->GetLastFunction();
1436 if (aMainShape.IsNull()) return NULL;
1438 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1439 SetErrorCode(NOT_FOUND_ANY);
1441 if (!aMainShape->HasSubShapeReferences()) return aSeq;
1442 const TDataStd_ListOfExtendedString& aListEntries = aMainShape->GetSubShapeReferences();
1443 if (aListEntries.IsEmpty()) return aSeq;
1447 TDataStd_ListIteratorOfListOfExtendedString anIt (aListEntries);
1448 for (; anIt.More(); anIt.Next()) {
1449 TCollection_ExtendedString anEntry = anIt.Value();
1450 Standard_Integer aStrLen = anEntry.LengthOfCString();
1451 char* anEntryStr = new char[aStrLen+1];
1452 anEntry.ToUTF8CString(anEntryStr);
1453 Handle(GEOM_BaseObject) anObj = GetEngine()->GetObject(GetDocID(), anEntryStr, false);
1454 if (!anObj.IsNull() ) {
1455 bool isGroup = anObj->IsKind(STANDARD_TYPE(GEOM_Object)) && anObj->GetType() == GEOM_GROUP;
1456 bool isSubShape = anObj->IsKind(STANDARD_TYPE(GEOM_Object)) && anObj->GetType() != GEOM_GROUP;
1457 bool isField = anObj->IsKind(STANDARD_TYPE(GEOM_Field));
1458 if (theTypes & Groups && isGroup ||
1459 theTypes & SubShapes && isSubShape ||
1460 theTypes & Fields && isField) {
1461 aSeq->Append(anObj);
1464 delete [] anEntryStr;
1467 if (aSeq->Length() == 0) {
1468 SetErrorCode(NOT_FOUND_ANY);
1477 //=============================================================================
1481 //=============================================================================
1482 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::MakeExplode
1483 (Handle(GEOM_Object) theShape,
1484 const Standard_Integer theShapeType,
1485 const Standard_Boolean isSorted,
1486 const ExplodeType theExplodeType)
1490 if (theShape.IsNull()) return NULL;
1491 TopoDS_Shape aShape = theShape->GetValue();
1492 if (aShape.IsNull()) return NULL;
1494 Handle(GEOM_Function) aMainShape = theShape->GetLastFunction();
1496 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1497 Handle(GEOM_Object) anObj;
1498 TopTools_MapOfShape mapShape;
1499 TopTools_ListOfShape listShape;
1501 if (aShape.ShapeType() == TopAbs_COMPOUND &&
1502 (theShapeType == TopAbs_SHAPE || theShapeType == TopAbs_FLAT || theShapeType == TopAbs_COMPOUND))
1504 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
1505 for (; It.More(); It.Next()) {
1506 TopoDS_Shape SS = It.Value();
1507 if (mapShape.Add(SS)) {
1508 if (theShapeType == TopAbs_FLAT) {
1509 AddFlatSubShapes(SS, listShape, mapShape);
1511 else if (theShapeType == TopAbs_SHAPE || theShapeType == SS.ShapeType()) {
1512 listShape.Append(SS);
1514 // VSR: for EXPLODE_NEW_INCLUDE_MAIN and EXPLODE_OLD_INCLUDE_MAIN:
1515 // it seems it is necessary to add top-level shape if theShapeType == TopAbs_COMPOUND
1519 else if (theExplodeType != EXPLODE_NEW_EXCLUDE_MAIN || aShape.ShapeType() != theShapeType) // issue 0021079
1521 TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
1522 for (; exp.More(); exp.Next())
1523 if (mapShape.Add(exp.Current()))
1524 listShape.Append(exp.Current());
1527 if (listShape.IsEmpty()){
1528 //SetErrorCode("The given shape has no sub-shapes of the requested type");
1529 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
1534 bool isOldSorting = false;
1535 if (theExplodeType == EXPLODE_OLD_INCLUDE_MAIN)
1536 isOldSorting = true;
1537 GEOMUtils::SortShapes(listShape, isOldSorting);
1540 TopTools_IndexedMapOfShape anIndices;
1541 TopExp::MapShapes(aShape, anIndices);
1542 Handle(TColStd_HArray1OfInteger) anArray;
1544 TopTools_ListIteratorOfListOfShape itSub (listShape);
1545 TCollection_AsciiString anAsciiList, anEntry;
1546 for (int index = 1; itSub.More(); itSub.Next(), ++index)
1548 TopoDS_Shape aValue = itSub.Value();
1549 anArray = new TColStd_HArray1OfInteger(1,1);
1550 anArray->SetValue(1, anIndices.FindIndex(aValue));
1552 //anObj = GetEngine()->AddSubShape(theShape, anArray);
1554 anObj = GetEngine()->AddObject(GetDocID(), GEOM_SUBSHAPE);
1555 Handle(GEOM_Function) aFunction = anObj->AddFunction(GEOM_Object::GetSubShapeID(), 1);
1556 if (aFunction.IsNull()) return aSeq;
1558 GEOM_ISubShape aSSI (aFunction);
1559 aSSI.SetMainShape(aMainShape);
1560 aSSI.SetIndices(anArray);
1562 // Set function value directly, as we know it.
1563 // Usage of Solver here would lead to significant loss of time,
1564 // because GEOM_SubShapeDriver will build TopTools_IndexedMapOfShape
1565 // on the main shape for each being calculated sub-shape separately.
1566 aFunction->SetValue(aValue);
1568 // Put this subshape in the list of sub-shapes of theMainShape
1569 aMainShape->AddSubShapeReference(aFunction);
1571 if (!anObj.IsNull()) {
1572 aSeq->Append(anObj);
1574 // for python command
1575 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
1576 anAsciiList += anEntry;
1581 //Make a Python command
1582 anAsciiList.Trunc(anAsciiList.Length() - 1);
1584 GEOM::TPythonDump pd (aMainShape, /*append=*/true);
1585 pd << "[" << anAsciiList.ToCString() << "] = geompy.";
1586 switch (theExplodeType) {
1587 case EXPLODE_NEW_EXCLUDE_MAIN:
1588 pd << "ExtractShapes(" << theShape << ", "
1589 << TopAbs_ShapeEnum(theShapeType) << ", " << (isSorted ? "True" : "False") << ")";
1591 case EXPLODE_NEW_INCLUDE_MAIN:
1592 pd << "SubShapeAll" << (isSorted ? "SortedCentres(" : "(")
1593 << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
1595 case EXPLODE_OLD_INCLUDE_MAIN:
1596 pd << "SubShapeAll" << (isSorted ? "Sorted(" : "(")
1597 << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
1606 //=============================================================================
1610 //=============================================================================
1611 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::SubShapeAllIDs
1612 (Handle(GEOM_Object) theShape,
1613 const Standard_Integer theShapeType,
1614 const Standard_Boolean isSorted,
1615 const ExplodeType theExplodeType)
1619 if (theShape.IsNull()) return NULL;
1620 TopoDS_Shape aShape = theShape->GetValue();
1621 if (aShape.IsNull()) return NULL;
1623 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
1624 TopTools_MapOfShape mapShape;
1625 TopTools_ListOfShape listShape;
1627 if (aShape.ShapeType() == TopAbs_COMPOUND &&
1628 (theShapeType == TopAbs_SHAPE || theShapeType == TopAbs_FLAT || theShapeType == TopAbs_COMPOUND))
1630 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
1631 for (; It.More(); It.Next()) {
1632 TopoDS_Shape SS = It.Value();
1633 if (mapShape.Add(SS)) {
1634 if (theShapeType == TopAbs_FLAT) {
1635 AddFlatSubShapes(SS, listShape, mapShape);
1637 else if (theShapeType == TopAbs_SHAPE || theShapeType == SS.ShapeType()) {
1638 listShape.Append(SS);
1643 else if (theExplodeType != EXPLODE_NEW_EXCLUDE_MAIN || aShape.ShapeType() != theShapeType) // issue 0021079
1645 TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
1646 for (; exp.More(); exp.Next())
1647 if (mapShape.Add(exp.Current()))
1648 listShape.Append(exp.Current());
1651 if (listShape.IsEmpty()) {
1652 //SetErrorCode("The given shape has no sub-shapes of the requested type");
1653 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
1658 bool isOldSorting = false;
1659 if (theExplodeType == EXPLODE_OLD_INCLUDE_MAIN)
1660 isOldSorting = true;
1661 GEOMUtils::SortShapes(listShape, isOldSorting);
1664 TopTools_IndexedMapOfShape anIndices;
1665 TopExp::MapShapes(aShape, anIndices);
1666 Handle(TColStd_HArray1OfInteger) anArray;
1668 TopTools_ListIteratorOfListOfShape itSub (listShape);
1669 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
1670 TopoDS_Shape aValue = itSub.Value();
1671 aSeq->Append(anIndices.FindIndex(aValue));
1674 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
1676 //Make a Python command
1677 GEOM::TPythonDump pd (aFunction, /*append=*/true);
1678 pd << "listSubShapeIDs = geompy.SubShapeAll";
1679 switch (theExplodeType) {
1680 case EXPLODE_NEW_EXCLUDE_MAIN:
1682 case EXPLODE_NEW_INCLUDE_MAIN:
1683 pd << (isSorted ? "SortedCentresIDs(" : "IDs(")
1684 << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
1686 case EXPLODE_OLD_INCLUDE_MAIN:
1687 pd << (isSorted ? "SortedIDs(" : "IDs(")
1688 << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
1697 //=============================================================================
1701 //=============================================================================
1702 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetSubShape
1703 (Handle(GEOM_Object) theMainShape,
1704 const Standard_Integer theID)
1708 if (theMainShape.IsNull()) return NULL;
1710 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
1711 anArray->SetValue(1, theID);
1712 Handle(GEOM_Object) anObj = GetEngine()->AddSubShape(theMainShape, anArray,true);
1713 if (anObj.IsNull()) {
1714 SetErrorCode("Can not get a sub-shape with the given ID");
1718 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1720 //Make a Python command
1721 GEOM::TPythonDump(aFunction) << anObj << " = geompy.GetSubShape("
1722 << theMainShape << ", [" << theID << "])";
1728 //=============================================================================
1732 //=============================================================================
1733 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::MakeSubShapes
1734 (Handle(GEOM_Object) theMainShape,
1735 Handle(TColStd_HArray1OfInteger) theIndices)
1739 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1741 if (!theIndices->Length()) {
1742 SetErrorCode(NOT_FOUND_ANY);
1746 if (theMainShape.IsNull()) return NULL;
1747 TopoDS_Shape aShape = theMainShape->GetValue();
1748 if (aShape.IsNull()) return NULL;
1750 Handle(GEOM_Function) aMainShape = theMainShape->GetLastFunction();
1752 TopTools_IndexedMapOfShape anIndices;
1753 TopExp::MapShapes(aShape, anIndices);
1755 Handle(TColStd_HArray1OfInteger) anArray;
1756 Handle(GEOM_Object) anObj;
1758 TCollection_AsciiString anAsciiList, anEntry;
1759 Standard_Integer i, low = theIndices->Lower(), up = theIndices->Upper();
1760 for (i = low; i <= up; i++) {
1761 int id = theIndices->Value(i);
1762 if (1 <= id && id <= anIndices.Extent()) {
1763 TopoDS_Shape aValue = anIndices.FindKey(id);
1764 anArray = new TColStd_HArray1OfInteger(1,1);
1765 anArray->SetValue(1, id);
1767 anObj = GetEngine()->AddObject(GetDocID(), GEOM_SUBSHAPE);
1768 if (!anObj.IsNull()) {
1769 Handle(GEOM_Function) aFunction = anObj->AddFunction(GEOM_Object::GetSubShapeID(), 1);
1770 if (aFunction.IsNull()) return aSeq;
1772 GEOM_ISubShape aSSI (aFunction);
1773 aSSI.SetMainShape(aMainShape);
1774 aSSI.SetIndices(anArray);
1776 // Set function value directly, as we know it.
1777 // Usage of Solver here would lead to significant loss of time,
1778 // because GEOM_SubShapeDriver will build TopTools_IndexedMapOfShape
1779 // on the main shape for each being calculated sub-shape separately.
1780 aFunction->SetValue(aValue);
1782 // Put this sub-shape in the list of sub-shapes of theMainShape
1783 aMainShape->AddSubShapeReference(aFunction);
1785 aSeq->Append(anObj);
1787 // for python command
1788 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
1789 anAsciiList += anEntry;
1795 //Make a Python command
1796 anAsciiList.Trunc(anAsciiList.Length() - 1);
1798 GEOM::TPythonDump pd (aMainShape, /*append=*/true);
1799 pd << "[" << anAsciiList.ToCString() << "] = geompy.SubShapes("
1800 << theMainShape << ", [" ;
1801 for (i = low; i <= up - 1; i++) {
1802 pd << theIndices->Value(i) << ", ";
1804 pd << theIndices->Value(up) << "])";
1811 //=============================================================================
1815 //=============================================================================
1816 Standard_Integer GEOMImpl_IShapesOperations::GetSubShapeIndex (Handle(GEOM_Object) theMainShape,
1817 Handle(GEOM_Object) theSubShape)
1821 TopoDS_Shape aMainShape = theMainShape->GetValue();
1822 TopoDS_Shape aSubShape = theSubShape->GetValue();
1824 if (aMainShape.IsNull() || aSubShape.IsNull()) return -1;
1826 TopTools_IndexedMapOfShape anIndices;
1827 TopExp::MapShapes(aMainShape, anIndices);
1828 // if (anIndices.Contains(aSubShape)) {
1829 // SetErrorCode(OK);
1830 // return anIndices.FindIndex(aSubShape);
1832 int id = anIndices.FindIndex(aSubShape);
1843 //=============================================================================
1845 * GetSubShapeIndices
1847 //=============================================================================
1848 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetSubShapesIndices (Handle(GEOM_Object) theMainShape,
1849 std::list<Handle(GEOM_Object)> theSubShapes)
1851 MESSAGE("GEOMImpl_IShapesOperations::GetSubShapesIndices")
1854 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
1856 TopoDS_Shape aMainShape = theMainShape->GetValue();
1857 if (aMainShape.IsNull())
1859 MESSAGE("NULL main shape")
1863 TopTools_IndexedMapOfShape anIndices;
1864 TopExp::MapShapes(aMainShape, anIndices);
1866 std::list<Handle(GEOM_Object)>::iterator it;
1867 for (it=theSubShapes.begin(); it != theSubShapes.end(); ++it)
1869 TopoDS_Shape aSubShape = (*it)->GetValue();
1870 if (aSubShape.IsNull())
1872 MESSAGE("NULL subshape")
1875 int id = anIndices.FindIndex(aSubShape);
1884 //=============================================================================
1888 //=============================================================================
1889 Standard_Integer GEOMImpl_IShapesOperations::GetTopologyIndex (Handle(GEOM_Object) theMainShape,
1890 Handle(GEOM_Object) theSubShape)
1894 TopoDS_Shape aMainShape = theMainShape->GetValue();
1895 TopoDS_Shape aSubShape = theSubShape->GetValue();
1897 if (aMainShape.IsNull() || aSubShape.IsNull()) {
1898 SetErrorCode("Null argument shape given");
1903 if (aSubShape.ShapeType() == TopAbs_COMPOUND) {
1905 TopTools_ListOfShape CL;
1906 CL.Append(aMainShape);
1907 TopTools_ListIteratorOfListOfShape itC;
1908 for (itC.Initialize(CL); itC.More(); itC.Next()) {
1909 for (it.Initialize(itC.Value()); it.More(); it.Next()) {
1910 if (it.Value().ShapeType() == TopAbs_COMPOUND) {
1911 if (it.Value().IsSame(aSubShape))
1915 CL.Append(it.Value());
1920 TopExp_Explorer anExp (aMainShape, aSubShape.ShapeType());
1921 TopTools_MapOfShape M;
1922 for (; anExp.More(); anExp.Next()) {
1923 if (M.Add(anExp.Current())) {
1924 if (anExp.Current().IsSame(aSubShape))
1931 SetErrorCode("The sub-shape does not belong to the main shape");
1935 //=============================================================================
1937 * GetShapeTypeString
1939 //=============================================================================
1940 TCollection_AsciiString GEOMImpl_IShapesOperations::GetShapeTypeString (Handle(GEOM_Object) theShape)
1944 TCollection_AsciiString aTypeName ("Null Shape");
1946 TopoDS_Shape aShape = theShape->GetValue();
1947 if (aShape.IsNull())
1950 switch (aShape.ShapeType() )
1952 case TopAbs_COMPOUND:
1953 aTypeName = "Compound";
1955 case TopAbs_COMPSOLID:
1956 aTypeName = "Compound Solid";
1959 aTypeName = "Solid";
1962 aTypeName = "Shell";
1966 BRepAdaptor_Surface surf (TopoDS::Face(aShape));
1967 if (surf.GetType() == GeomAbs_Plane)
1968 aTypeName = "Plane";
1969 else if (surf.GetType() == GeomAbs_Cylinder)
1970 aTypeName = "Cylindrical Face";
1971 else if (surf.GetType() == GeomAbs_Sphere)
1972 aTypeName = "Spherical Face";
1973 else if (surf.GetType() == GeomAbs_Torus)
1974 aTypeName = "Toroidal Face";
1975 else if (surf.GetType() == GeomAbs_Cone)
1976 aTypeName = "Conical Face";
1978 aTypeName = "GEOM::FACE";
1986 BRepAdaptor_Curve curv (TopoDS::Edge(aShape));
1987 if (curv.GetType() == GeomAbs_Line) {
1988 if ((Abs(curv.FirstParameter()) >= 1E6) ||
1989 (Abs(curv.LastParameter()) >= 1E6))
1993 } else if (curv.GetType() == GeomAbs_Circle) {
1994 if (curv.IsClosed())
1995 aTypeName = "Circle";
2004 aTypeName = "Vertex";
2007 aTypeName = "Shape";
2010 aTypeName = "Shape of unknown type";
2016 //=============================================================================
2018 * IsSubShapeBelongsTo
2020 //=============================================================================
2021 Standard_Boolean GEOMImpl_IShapesOperations::IsSubShapeBelongsTo( Handle(GEOM_Object) theSubObject,
2022 const Standard_Integer theSubObjectIndex,
2023 Handle(GEOM_Object) theObject,
2024 const Standard_Integer theObjectIndex)
2028 if ( theObject.IsNull() || theSubObject.IsNull() )
2031 TopoDS_Shape shape = theObject->GetValue();
2032 TopoDS_Shape subShape = theSubObject->GetValue();
2034 if ( shape.IsNull() || subShape.IsNull() )
2037 TopTools_IndexedMapOfShape anIndices;
2038 if ( theObjectIndex > 0 ) {
2039 TopExp::MapShapes( shape, anIndices );
2040 shape = anIndices.FindKey(theObjectIndex);
2042 if ( theSubObjectIndex > 0 ) {
2043 TopExp::MapShapes( subShape, anIndices );
2044 subShape = anIndices.FindKey(theSubObjectIndex);
2047 TopExp::MapShapes( shape, anIndices );
2049 const Standard_Boolean isBelongTo = anIndices.Contains(subShape);
2056 //=============================================================================
2060 //=============================================================================
2061 Standard_Integer GEOMImpl_IShapesOperations::NumberOfSubShapes
2062 (Handle(GEOM_Object) theShape,
2063 const Standard_Integer theShapeType)
2066 Standard_Integer nbShapes = 0;
2068 if (theShape.IsNull()) return -1;
2069 TopoDS_Shape aShape = theShape->GetValue();
2070 if (aShape.IsNull()) return -1;
2073 TopTools_MapOfShape mapShape;
2075 if (aShape.ShapeType() == TopAbs_COMPOUND &&
2076 (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
2077 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPSOLID ||
2078 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPOUND)) {
2079 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
2080 for (; It.More(); It.Next()) {
2081 if (mapShape.Add(It.Value())) {
2082 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
2083 TopAbs_ShapeEnum(theShapeType) == It.Value().ShapeType()) {
2089 TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
2090 for (; exp.More(); exp.Next())
2091 if (mapShape.Add(exp.Current()))
2097 if (theShapeType == TopAbs_FLAT) {
2098 TopTools_MapOfShape aMapOfShape;
2099 TopTools_ListOfShape aListOfShape;
2100 AddFlatSubShapes(aShape, aListOfShape, aMapOfShape);
2101 nbShapes = aListOfShape.Extent();
2105 int iType, nbTypes [TopAbs_SHAPE];
2106 for (iType = 0; iType < TopAbs_SHAPE; ++iType)
2108 nbTypes[aShape.ShapeType()]++;
2110 TopTools_MapOfShape aMapOfShape;
2111 aMapOfShape.Add(aShape);
2112 TopTools_ListOfShape aListOfShape;
2113 aListOfShape.Append(aShape);
2115 TopTools_ListIteratorOfListOfShape itL (aListOfShape);
2116 for (; itL.More(); itL.Next()) {
2117 TopoDS_Iterator it (itL.Value());
2118 for (; it.More(); it.Next()) {
2119 TopoDS_Shape s = it.Value();
2120 if (aMapOfShape.Add(s)) {
2121 aListOfShape.Append(s);
2122 nbTypes[s.ShapeType()]++;
2127 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE)
2128 nbShapes = aMapOfShape.Extent();
2130 nbShapes = nbTypes[theShapeType];
2133 catch (Standard_Failure) {
2134 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2135 SetErrorCode(aFail->GetMessageString());
2143 //=============================================================================
2147 //=============================================================================
2148 Handle(GEOM_Object) GEOMImpl_IShapesOperations::ReverseShape(Handle(GEOM_Object) theShape)
2152 if (theShape.IsNull()) return NULL;
2155 //Add a new reversed object
2156 Handle(GEOM_Object) aReversed = GetEngine()->AddObject(GetDocID(), theShape->GetType());
2158 //Add a new Revese function
2159 Handle(GEOM_Function) aFunction;
2160 aFunction = aReversed->AddFunction(GEOMImpl_ShapeDriver::GetID(), REVERSE_ORIENTATION);
2161 if (aFunction.IsNull()) return NULL;
2163 //Check if the function is set correctly
2164 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
2166 GEOMImpl_IShapes aSI (aFunction);
2168 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
2169 if (aRefShape.IsNull()) return NULL;
2171 aSI.SetBase(aRefShape);
2173 //Compute the sub-shape value
2176 if (!GetSolver()->ComputeFunction(aFunction)) {
2177 SetErrorCode("Shape driver failed to reverse shape");
2181 catch (Standard_Failure) {
2182 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2183 SetErrorCode(aFail->GetMessageString());
2187 //Make a Python command
2188 GEOM::TPythonDump(aFunction) << aReversed
2189 << " = geompy.ChangeOrientation(" << theShape << ")";
2194 Handle(GEOM_Object) aReversed;
2196 GEOM_Engine* anEngine = GetEngine();
2197 //GEOMImpl_Gen* aGen = dynamic_cast<GEOMImpl_Gen*>(anEngine);
2198 GEOMImpl_Gen* aGen = (GEOMImpl_Gen*)anEngine;
2201 GEOMImpl_IHealingOperations* anIHealingOperations =
2202 aGen->GetIHealingOperations(GetDocID());
2203 aReversed = anIHealingOperations->ChangeOrientationCopy(theShape);
2204 SetErrorCode(anIHealingOperations->GetErrorCode());
2210 //=============================================================================
2214 //=============================================================================
2215 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetFreeFacesIDs
2216 (Handle(GEOM_Object) theShape)
2220 if (theShape.IsNull()) return NULL;
2221 TopoDS_Shape aShape = theShape->GetValue();
2222 if (aShape.IsNull()) return NULL;
2224 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
2226 TopTools_IndexedDataMapOfShapeListOfShape mapFaceBlocks;
2227 GEOMImpl_Block6Explorer::MapShapesAndAncestors
2228 (aShape, TopAbs_FACE, TopAbs_SOLID, mapFaceBlocks);
2230 Standard_Integer ind = 1, nbFaces = mapFaceBlocks.Extent();
2233 SetErrorCode("The given shape has no faces");
2237 TopTools_IndexedMapOfShape anIndices;
2238 TopExp::MapShapes(aShape, anIndices);
2240 Standard_Integer id;
2241 for (; ind <= nbFaces; ind++) {
2242 if (mapFaceBlocks.FindFromIndex(ind).Extent() != 2) {
2243 id = anIndices.FindIndex(mapFaceBlocks.FindKey(ind));
2248 //The explode doesn't change object so no new function is required.
2249 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
2251 //Make a Python command
2252 GEOM::TPythonDump(aFunction, /*append=*/true)
2253 << "listFreeFacesIDs = geompy.GetFreeFacesIDs(" << theShape << ")";
2259 //=======================================================================
2260 //function : GetSharedShapes
2262 //=======================================================================
2263 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetSharedShapes
2264 (Handle(GEOM_Object) theShape1,
2265 Handle(GEOM_Object) theShape2,
2266 const Standard_Integer theShapeType)
2270 if (theShape1.IsNull() || theShape2.IsNull()) return NULL;
2272 TopoDS_Shape aShape1 = theShape1->GetValue();
2273 TopoDS_Shape aShape2 = theShape2->GetValue();
2275 if (aShape1.IsNull() || aShape2.IsNull()) return NULL;
2277 TopTools_IndexedMapOfShape anIndices;
2278 TopExp::MapShapes(aShape1, anIndices);
2279 Handle(TColStd_HArray1OfInteger) anArray;
2281 TopTools_IndexedMapOfShape mapShape1;
2282 TopExp::MapShapes(aShape1, TopAbs_ShapeEnum(theShapeType), mapShape1);
2284 Handle(GEOM_Object) anObj;
2285 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
2286 TCollection_AsciiString anAsciiList, anEntry;
2288 TopTools_MapOfShape mapShape2;
2289 TopExp_Explorer exp (aShape2, TopAbs_ShapeEnum(theShapeType));
2290 for (; exp.More(); exp.Next()) {
2291 TopoDS_Shape aSS = exp.Current();
2292 if (mapShape2.Add(aSS) && mapShape1.Contains(aSS)) {
2293 anArray = new TColStd_HArray1OfInteger(1,1);
2294 anArray->SetValue(1, anIndices.FindIndex(aSS));
2295 anObj = GetEngine()->AddSubShape(theShape1, anArray);
2296 aSeq->Append(anObj);
2298 // for python command
2299 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
2300 anAsciiList += anEntry;
2305 if (aSeq->IsEmpty()) {
2306 SetErrorCode(NOT_FOUND_ANY);
2310 //Make a Python command
2311 anAsciiList.Trunc(anAsciiList.Length() - 1);
2313 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2315 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
2316 << "] = geompy.GetSharedShapes(" << theShape1 << ", "
2317 << theShape2 << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
2323 //=======================================================================
2324 //function : GetSharedShapes
2327 // NOTE on the implementation
2329 // 1) Resulting sub-shapes are published as a children of the 1st input shape
2330 // from theShapes list. Due to this reason only direct sub-shapes of the 1st
2331 // shape can be contained in the result of the operation (i.e. shares between
2332 // 2nd/3rd, etc couples cannot be retrieved.
2333 // 2) An exception from above case is when a single compound is specified as an
2334 // input. In this case we search shares between its top-level content, so we
2335 // are able to search shares between all possible couples of shapes.
2336 // 3) Parameter theMultiShare controls what types of shares to search:
2337 // - True: get sub-shapes that are shared between ALL input shapes;
2338 // - False: get shares between couples of input sub-shapes (see points 1 and 2).
2340 // Thus, we have the following cases:
2341 // [1] theShapes = N shapes (N>1), theMultiShare = True
2342 // Result: sub-shapes that are shared by all theShapes
2343 // [2] theShapes = N shapes (N>1), theMultiShare = False
2344 // Result: sub-shapes of 1st shape from theShapes that are shared with any shape
2346 // [3] theShapes = 1 shape, theMultiShare = True
2347 // Result: sub-shapes that are shared by all top-level sub-objects of theShapes[0]
2348 // [4] theShapes = 1 shape, theMultiShare = False
2349 // Result: sub-shapes of all possible couples of all top-level sub-objects of
2351 //=======================================================================
2352 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetSharedShapes
2353 (std::list<Handle(GEOM_Object)> & theShapes,
2354 const Standard_Integer theShapeType,
2355 const bool theMultiShare)
2359 int aLen = theShapes.size();
2360 if (aLen < 1) return NULL;
2362 std::list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
2364 // main object is always first in the input list
2365 // it is the object from which sub-shapes indices are taken
2366 // and where results are published
2367 Handle(GEOM_Object) aMainObj = *it;
2368 Handle(GEOM_Function) aMainShape = aMainObj->GetLastFunction();
2370 // collect all shapes from the input list (including first one) for processing
2371 TopTools_SequenceOfShape shapeSeq;
2372 for (; it != theShapes.end(); it++) {
2373 Handle(GEOM_Function) aRefShape = (*it)->GetLastFunction();
2374 if (aRefShape.IsNull()) {
2375 SetErrorCode("NULL shape for GetSharedShapes");
2378 TopoDS_Shape aShape = aRefShape->GetValue();
2379 if (aShape.IsNull()) {
2380 SetErrorCode("NULL shape for GetSharedShapes");
2383 shapeSeq.Append( aShape );
2386 // if only single shape is specified as input
2387 // collect all ites top-level sub-shapes for processing
2388 if ( shapeSeq.Length() == 1 )
2390 TopoDS_Shape aShape = shapeSeq.First();
2392 for ( TopoDS_Iterator it( aShape ); it.More(); it.Next() )
2393 shapeSeq.Append( it.Value() );
2396 // map all sub-shapes in a main shape to their indices
2397 TopTools_IndexedMapOfShape anIndices;
2398 TopExp::MapShapes(aMainShape->GetValue(), anIndices);
2399 TopTools_MapOfShape mapShape;
2401 // find shared shapes
2403 // here we will collect all shares
2404 TopTools_ListOfShape aShared;
2406 // number of iterations
2407 int nbIters = theMultiShare || theShapes.size() > 1 ? 1 : shapeSeq.Length()-1;
2408 // numShares factor to search (i.e. by what nb of shapes each found sub-shape should be shared)
2409 int nbShares = theMultiShare ? shapeSeq.Length()-1 : 1;
2411 for ( int iter = 1; iter <= nbIters; iter++) {
2412 for ( int ind = iter+1; ind <= shapeSeq.Length(); ind++) {
2413 if ( ind-1+nbShares > shapeSeq.Length() ) break;
2414 TopoDS_Compound aCurrSelection;
2415 TopoDS_Shape aShape1 = shapeSeq.Value( iter );
2416 TopTools_IndexedMapOfShape mapSelected;
2417 TopExp::MapShapes(aShape1, TopAbs_ShapeEnum(theShapeType), mapSelected);
2418 for ( int s = 0; s < nbShares; s++ ) {
2420 TopoDS_Compound aCompound;
2421 B.MakeCompound(aCompound);
2422 const TopoDS_Shape& aShape2 = shapeSeq.Value( ind+s );
2423 TopTools_MapOfShape mapShape2;
2424 TopExp_Explorer exp (aShape2, TopAbs_ShapeEnum(theShapeType));
2425 for (; exp.More(); exp.Next()) {
2426 const TopoDS_Shape& aSS = exp.Current();
2427 if (mapShape2.Add(aSS) && mapSelected.Contains(aSS)) {
2428 B.Add(aCompound, aSS);
2431 mapSelected.Clear();
2432 aCurrSelection = aCompound;
2433 TopExp::MapShapes(aCurrSelection, TopAbs_ShapeEnum(theShapeType), mapSelected);
2435 TopoDS_Iterator itSel(aCurrSelection, Standard_True, Standard_True);
2436 for (; itSel.More(); itSel.Next()) {
2437 const TopoDS_Shape& aSS = itSel.Value();
2438 if (mapShape.Add(aSS) )
2439 aShared.Append(aSS);
2444 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
2446 if (aShared.IsEmpty()){
2447 SetErrorCode(NOT_FOUND_ANY);
2451 // create GEOM_Object for each found shared shape (collected in aShared)
2452 TCollection_AsciiString anAsciiList;
2453 Handle(GEOM_Object) anObj;
2454 TopTools_ListIteratorOfListOfShape itSub (aShared);
2455 for (; itSub.More(); itSub.Next()) {
2456 TopoDS_Shape aValue = itSub.Value();
2457 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
2458 anArray->SetValue(1, anIndices.FindIndex(aValue));
2459 anObj = GetEngine()->AddSubShape(aMainObj, anArray);
2460 aSeq->Append(anObj);
2462 // for python command
2463 TCollection_AsciiString anEntry;
2464 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
2465 anAsciiList += anEntry;
2469 // make a Python command
2470 anAsciiList.Trunc(anAsciiList.Length() - 1);
2472 GEOM::TPythonDump pd (anObj->GetLastFunction());
2473 pd << "[" << anAsciiList.ToCString()
2474 << "] = geompy.GetSharedShapesMulti(";
2479 it = theShapes.begin();
2481 while (it != theShapes.end()) {
2482 pd << ", " << (*it++);
2487 pd << ", " << TopAbs_ShapeEnum(theShapeType) << ", " << theMultiShare << ")";
2493 //=============================================================================
2497 //=============================================================================
2498 static GEOM::TPythonDump& operator<< (GEOM::TPythonDump& theDump,
2499 const GEOMAlgo_State theState)
2502 case GEOMAlgo_ST_IN:
2503 theDump << "GEOM.ST_IN";
2505 case GEOMAlgo_ST_OUT:
2506 theDump << "GEOM.ST_OUT";
2508 case GEOMAlgo_ST_ON:
2509 theDump << "GEOM.ST_ON";
2511 case GEOMAlgo_ST_ONIN:
2512 theDump << "GEOM.ST_ONIN";
2514 case GEOMAlgo_ST_ONOUT:
2515 theDump << "GEOM.ST_ONOUT";
2518 theDump << "GEOM.ST_UNKNOWN";
2524 //=======================================================================
2525 //function : checkTypeShapesOn
2527 * \brief Checks if theShapeType parameter of GetShapesOnXXX() is OK
2528 * \param theShapeType - the shape type to check
2529 * \retval bool - result of the check
2531 //=======================================================================
2532 bool GEOMImpl_IShapesOperations::checkTypeShapesOn(const Standard_Integer theShapeType)
2534 if (theShapeType != TopAbs_VERTEX &&
2535 theShapeType != TopAbs_EDGE &&
2536 theShapeType != TopAbs_FACE &&
2537 theShapeType != TopAbs_SOLID) {
2538 SetErrorCode("Only solids, vertices, edges or faces can be found by this method");
2544 //=======================================================================
2545 //function : makePlane
2547 * \brief Creates Geom_Plane
2548 * \param theAx1 - shape object defining plane parameters
2549 * \retval Handle(Geom_Surface) - resulting surface
2551 //=======================================================================
2552 Handle(Geom_Surface) GEOMImpl_IShapesOperations::makePlane(const TopoDS_Shape& anAx1)
2554 if (anAx1.ShapeType() != TopAbs_EDGE) return NULL;
2555 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
2556 TopoDS_Vertex V1, V2;
2557 TopExp::Vertices(anEdge, V1, V2, Standard_True);
2558 if (V1.IsNull() || V2.IsNull()) {
2559 SetErrorCode("Bad edge given for the plane normal vector");
2562 gp_Pnt aLoc = BRep_Tool::Pnt(V1);
2563 gp_Vec aVec (aLoc, BRep_Tool::Pnt(V2));
2564 if (aVec.Magnitude() < Precision::Confusion()) {
2565 SetErrorCode("Vector with null magnitude given");
2568 return new Geom_Plane(aLoc, aVec);
2571 //=======================================================================
2572 //function : makeCylinder
2574 * \brief Creates Geom_CylindricalSurface
2575 * \param theAx1 - edge defining cylinder axis
2576 * \param theRadius - cylinder radius
2577 * \retval Handle(Geom_Surface) - resulting surface
2579 //=======================================================================
2580 Handle(Geom_Surface) GEOMImpl_IShapesOperations::makeCylinder(const TopoDS_Shape& anAxis,
2581 const Standard_Real theRadius)
2583 //Axis of the cylinder
2584 if (anAxis.ShapeType() != TopAbs_EDGE) {
2585 SetErrorCode("Not an edge given for the axis");
2588 TopoDS_Edge anEdge = TopoDS::Edge(anAxis);
2589 TopoDS_Vertex V1, V2;
2590 TopExp::Vertices(anEdge, V1, V2, Standard_True);
2591 if (V1.IsNull() || V2.IsNull()) {
2592 SetErrorCode("Bad edge given for the axis");
2595 gp_Pnt aLoc = BRep_Tool::Pnt(V1);
2596 gp_Vec aVec (aLoc, BRep_Tool::Pnt(V2));
2597 if (aVec.Magnitude() < Precision::Confusion()) {
2598 SetErrorCode("Vector with null magnitude given");
2602 gp_Ax3 anAx3 (aLoc, aVec);
2603 return new Geom_CylindricalSurface(anAx3, theRadius);
2606 //=======================================================================
2607 //function : getShapesOnBoxIDs
2609 * \brief Find IDs of sub-shapes complying with given status about surface
2610 * \param theBox - the box to check state of sub-shapes against
2611 * \param theShape - the shape to explore
2612 * \param theShapeType - type of sub-shape of theShape
2613 * \param theState - required state
2614 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
2616 //=======================================================================
2617 Handle(TColStd_HSequenceOfInteger)
2618 GEOMImpl_IShapesOperations::getShapesOnBoxIDs(const Handle(GEOM_Object)& theBox,
2619 const Handle(GEOM_Object)& theShape,
2620 const Standard_Integer theShapeType,
2621 GEOMAlgo_State theState)
2623 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
2625 TopoDS_Shape aBox = theBox->GetValue();
2626 TopoDS_Shape aShape = theShape->GetValue();
2628 // Check presence of triangulation, build if need
2629 if (theShapeType != TopAbs_VERTEX && !GEOMUtils::CheckTriangulation(aShape)) {
2630 SetErrorCode("Cannot build triangulation on the shape");
2635 GEOMAlgo_FinderShapeOn2 aFinder;
2636 Standard_Real aTol = 0.0001; // default value
2638 Handle(GEOMAlgo_ClsfBox) aClsfBox = new GEOMAlgo_ClsfBox;
2639 aClsfBox->SetBox(aBox);
2641 aFinder.SetShape(aShape);
2642 aFinder.SetTolerance(aTol);
2643 aFinder.SetClsf(aClsfBox);
2644 aFinder.SetShapeType( (TopAbs_ShapeEnum)theShapeType );
2645 aFinder.SetState(theState);
2648 // Interprete results
2649 Standard_Integer iErr = aFinder.ErrorStatus();
2650 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn2.cxx
2652 MESSAGE(" iErr : " << iErr);
2653 TCollection_AsciiString aMsg (" iErr : ");
2654 aMsg += TCollection_AsciiString(iErr);
2658 Standard_Integer iWrn = aFinder.WarningStatus();
2659 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn2.cxx
2661 MESSAGE(" *** iWrn : " << iWrn);
2664 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
2666 if (listSS.Extent() < 1) {
2667 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
2668 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
2672 // Fill sequence of object IDs
2673 aSeqOfIDs = new TColStd_HSequenceOfInteger;
2675 TopTools_IndexedMapOfShape anIndices;
2676 TopExp::MapShapes(aShape, anIndices);
2678 TopTools_ListIteratorOfListOfShape itSub (listSS);
2679 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
2680 int id = anIndices.FindIndex(itSub.Value());
2681 aSeqOfIDs->Append(id);
2687 //=======================================================================
2688 //function : GetShapesOnBoxIDs
2690 * \brief Find sub-shapes complying with given status about surface
2691 * \param theBox - the box to check state of sub-shapes against
2692 * \param theShape - the shape to explore
2693 * \param theShapeType - type of sub-shape of theShape
2694 * \param theState - required state
2695 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
2697 //=======================================================================
2698 Handle(TColStd_HSequenceOfInteger)
2699 GEOMImpl_IShapesOperations::GetShapesOnBoxIDs(const Handle(GEOM_Object)& theBox,
2700 const Handle(GEOM_Object)& theShape,
2701 const Standard_Integer theShapeType,
2702 GEOMAlgo_State theState)
2704 // Find sub-shapes ids
2705 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2706 getShapesOnBoxIDs (theBox, theShape, theShapeType, theState);
2707 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2710 // The GetShapesOnBox() doesn't change object so no new function is required.
2711 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theBox)->GetLastFunction();
2713 // Make a Python command
2714 GEOM::TPythonDump(aFunction, /*append=*/true)
2715 << "listShapesOnBoxIDs = geompy.GetShapesOnBoxIDs("
2718 << TopAbs_ShapeEnum(theShapeType) << ", "
2725 //=======================================================================
2726 //function : GetShapesOnBox
2728 * \brief Find sub-shapes complying with given status about surface
2729 * \param theBox - the box to check state of sub-shapes against
2730 * \param theShape - the shape to explore
2731 * \param theShapeType - type of sub-shape of theShape
2732 * \param theState - required state
2733 * \retval Handle(TColStd_HSequenceOfTransient) - found sub-shapes
2735 //=======================================================================
2736 Handle(TColStd_HSequenceOfTransient)
2737 GEOMImpl_IShapesOperations::GetShapesOnBox(const Handle(GEOM_Object)& theBox,
2738 const Handle(GEOM_Object)& theShape,
2739 const Standard_Integer theShapeType,
2740 GEOMAlgo_State theState)
2742 // Find sub-shapes ids
2743 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2744 getShapesOnBoxIDs (theBox, theShape, theShapeType, theState);
2745 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2748 // Find objects by indices
2749 TCollection_AsciiString anAsciiList;
2750 Handle(TColStd_HSequenceOfTransient) aSeq;
2751 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
2752 if ( aSeq.IsNull() || aSeq->IsEmpty() )
2755 // Make a Python command
2757 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2758 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2760 GEOM::TPythonDump(aFunction)
2761 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnBox("
2764 << TopAbs_ShapeEnum(theShapeType) << ", "
2771 //=======================================================================
2772 //function : getShapesOnShapeIDs
2774 * \brief Find IDs of sub-shapes complying with given status about surface
2775 * \param theCheckShape - the shape to check state of sub-shapes against
2776 * \param theShape - the shape to explore
2777 * \param theShapeType - type of sub-shape of theShape
2778 * \param theState - required state
2779 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
2781 //=======================================================================
2782 Handle(TColStd_HSequenceOfInteger)
2783 GEOMImpl_IShapesOperations::getShapesOnShapeIDs
2784 (const Handle(GEOM_Object)& theCheckShape,
2785 const Handle(GEOM_Object)& theShape,
2786 const Standard_Integer theShapeType,
2787 GEOMAlgo_State theState)
2789 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
2791 TopoDS_Shape aCheckShape = theCheckShape->GetValue();
2792 TopoDS_Shape aShape = theShape->GetValue();
2793 TopTools_ListOfShape res;
2795 // Check presence of triangulation, build if need
2796 if (theShapeType != TopAbs_VERTEX && !GEOMUtils::CheckTriangulation(aShape)) {
2797 SetErrorCode("Cannot build triangulation on the shape");
2801 // Compute classification tolerance.
2802 TopTools_IndexedMapOfShape aMapVtx;
2803 Standard_Real aTol = Precision::Confusion();
2805 TopExp::MapShapes(aShape, TopAbs_VERTEX, aMapVtx);
2808 Standard_Integer aNbVtx = aMapVtx.Extent();
2810 for (i = 1; i <= aNbVtx; ++i) {
2811 const TopoDS_Vertex aVtx = TopoDS::Vertex(aMapVtx.FindKey(i));
2812 const Standard_Real aVtxTol = BRep_Tool::Tolerance(aVtx);
2814 if (aTol < aVtxTol) {
2819 // Bound the tolerance value.
2820 if (aTol > 0.0001) {
2825 GEOMAlgo_FinderShapeOn2 aFinder;
2827 Handle(GEOMAlgo_ClsfSolid) aClsfSolid = new GEOMAlgo_ClsfSolid;
2828 aClsfSolid->SetShape(aCheckShape);
2830 aFinder.SetShape(aShape);
2831 aFinder.SetTolerance(aTol);
2832 aFinder.SetClsf(aClsfSolid);
2833 aFinder.SetShapeType( (TopAbs_ShapeEnum)theShapeType );
2834 aFinder.SetState(theState);
2837 // Interprete results
2838 Standard_Integer iErr = aFinder.ErrorStatus();
2839 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn2.cxx
2842 SetErrorCode("theCheckShape must be a solid");
2845 MESSAGE(" iErr : " << iErr);
2846 TCollection_AsciiString aMsg (" iErr : ");
2847 aMsg += TCollection_AsciiString(iErr);
2852 Standard_Integer iWrn = aFinder.WarningStatus();
2853 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn2.cxx
2855 MESSAGE(" *** iWrn : " << iWrn);
2858 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
2860 if (listSS.Extent() < 1) {
2861 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
2862 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
2865 // Fill sequence of object IDs
2866 aSeqOfIDs = new TColStd_HSequenceOfInteger;
2868 TopTools_IndexedMapOfShape anIndices;
2869 TopExp::MapShapes(aShape, anIndices);
2871 TopTools_ListIteratorOfListOfShape itSub (listSS);
2872 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
2873 int id = anIndices.FindIndex(itSub.Value());
2874 aSeqOfIDs->Append(id);
2880 //=======================================================================
2881 //function : GetShapesOnShapeIDs
2883 * \brief Find sub-shapes complying with given status about surface
2884 * \param theCheckShape - the shape to check state of sub-shapes against
2885 * \param theShape - the shape to explore
2886 * \param theShapeType - type of sub-shape of theShape
2887 * \param theState - required state
2888 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
2890 //=======================================================================
2891 Handle(TColStd_HSequenceOfInteger)
2892 GEOMImpl_IShapesOperations::GetShapesOnShapeIDs
2893 (const Handle(GEOM_Object)& theCheckShape,
2894 const Handle(GEOM_Object)& theShape,
2895 const Standard_Integer theShapeType,
2896 GEOMAlgo_State theState)
2898 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2899 getShapesOnShapeIDs (theCheckShape, theShape, theShapeType, theState);
2901 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2904 // The GetShapesOnShape() doesn't change object so no new function is required.
2905 Handle(GEOM_Function) aFunction =
2906 GEOM::GetCreatedLast(theShape,theCheckShape)->GetLastFunction();
2908 // Make a Python command
2909 GEOM::TPythonDump(aFunction, /*append=*/true)
2910 << "listShapesOnBoxIDs = geompy.GetShapesOnShapeIDs("
2911 << theCheckShape << ", "
2913 << TopAbs_ShapeEnum(theShapeType) << ", "
2920 //=======================================================================
2921 //function : GetShapesOnShape
2923 * \brief Find sub-shapes complying with given status about surface
2924 * \param theCheckShape - the shape to check state of sub-shapes against
2925 * \param theShape - the shape to explore
2926 * \param theShapeType - type of sub-shape of theShape
2927 * \param theState - required state
2928 * \retval Handle(TColStd_HSequenceOfTransient) - found sub-shapes
2930 //=======================================================================
2931 Handle(TColStd_HSequenceOfTransient)
2932 GEOMImpl_IShapesOperations::GetShapesOnShape
2933 (const Handle(GEOM_Object)& theCheckShape,
2934 const Handle(GEOM_Object)& theShape,
2935 const Standard_Integer theShapeType,
2936 GEOMAlgo_State theState)
2938 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2939 getShapesOnShapeIDs (theCheckShape, theShape, theShapeType, theState);
2940 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2943 // Find objects by indices
2944 TCollection_AsciiString anAsciiList;
2945 Handle(TColStd_HSequenceOfTransient) aSeq;
2946 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
2948 if ( aSeq.IsNull() || aSeq->IsEmpty() )
2951 // Make a Python command
2953 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2954 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2956 GEOM::TPythonDump(aFunction)
2957 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnShape("
2958 << theCheckShape << ", "
2960 << TopAbs_ShapeEnum(theShapeType) << ", "
2967 //=======================================================================
2968 //function : GetShapesOnShapeAsCompound
2969 //=======================================================================
2970 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetShapesOnShapeAsCompound
2971 (const Handle(GEOM_Object)& theCheckShape,
2972 const Handle(GEOM_Object)& theShape,
2973 const Standard_Integer theShapeType,
2974 GEOMAlgo_State theState)
2976 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2977 getShapesOnShapeIDs (theCheckShape, theShape, theShapeType, theState);
2979 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2982 // Find objects by indices
2983 TCollection_AsciiString anAsciiList;
2984 Handle(TColStd_HSequenceOfTransient) aSeq;
2985 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
2987 if ( aSeq.IsNull() || aSeq->IsEmpty() )
2990 TopoDS_Compound aCompound;
2992 B.MakeCompound(aCompound);
2994 for(; i<=aSeq->Length(); i++) {
2995 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(aSeq->Value(i));
2996 TopoDS_Shape aShape_i = anObj->GetValue();
2997 B.Add(aCompound,aShape_i);
3000 //Add a new result object
3001 Handle(GEOM_Object) aRes = GetEngine()->AddObject(GetDocID(), GEOM_SHAPES_ON_SHAPE);
3002 Handle(GEOM_Function) aFunction =
3003 aRes->AddFunction(GEOMImpl_ShapeDriver::GetID(), SHAPES_ON_SHAPE);
3004 aFunction->SetValue(aCompound);
3007 aSeq->Append( theCheckShape->GetLastFunction() );
3008 aSeq->Append( theShape->GetLastFunction() );
3010 GEOMImpl_IShapes aCI( aFunction );
3011 aCI.SetShapes( aSeq );
3012 aCI.SetSubShapeType( theShapeType );
3013 aCI.SetTolerance( theState );
3015 GEOM::TPythonDump(aFunction)
3016 << aRes << " = geompy.GetShapesOnShapeAsCompound("
3017 << theCheckShape << ", "
3019 << TopAbs_ShapeEnum(theShapeType) << ", "
3027 //=============================================================================
3029 * GetSubShapeEdgeSorted
3031 //=============================================================================
3032 Handle(TColStd_HSequenceOfTransient)
3033 GEOMImpl_IShapesOperations::GetSubShapeEdgeSorted
3034 (const Handle(GEOM_Object) &theShape,
3035 const Handle(GEOM_Object) &theStartPoint)
3037 // Get the sorted edges indices.
3038 Handle(TColStd_HSequenceOfInteger) aSortedIDs =
3039 getSubShapeEdgeSortedIDs(theShape, theStartPoint);
3041 // Get object by indices.
3042 TCollection_AsciiString anAsciiList;
3043 Handle(TColStd_HSequenceOfTransient) aSeq =
3044 getObjectsShapesOn(theShape, aSortedIDs, anAsciiList);
3046 if (aSeq.IsNull() || aSeq->IsEmpty()) {
3047 SetErrorCode("Empty sequence of edges");
3051 // Make a Python command
3052 Handle(GEOM_Object) anObj =
3053 Handle(GEOM_Object)::DownCast(aSeq->Value(1));
3054 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
3056 GEOM::TPythonDump(aFunction)
3057 << "[" << anAsciiList.ToCString() << "] = geompy.GetSubShapeEdgeSorted("
3058 << theShape << ", " << theStartPoint << ")";
3065 //=======================================================================
3066 //function : getShapesOnSurfaceIDs
3068 * \brief Find IDs of sub-shapes complying with given status about surface
3069 * \param theSurface - the surface to check state of sub-shapes against
3070 * \param theShape - the shape to explore
3071 * \param theShapeType - type of sub-shape of theShape
3072 * \param theState - required state
3073 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
3075 //=======================================================================
3076 Handle(TColStd_HSequenceOfInteger)
3077 GEOMImpl_IShapesOperations::getShapesOnSurfaceIDs(const Handle(Geom_Surface)& theSurface,
3078 const TopoDS_Shape& theShape,
3079 TopAbs_ShapeEnum theShapeType,
3080 GEOMAlgo_State theState)
3082 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
3084 // Check presence of triangulation, build if need
3085 if (theShapeType != TopAbs_VERTEX &&
3086 !GEOMUtils::CheckTriangulation(theShape)) {
3087 SetErrorCode("Cannot build triangulation on the shape");
3091 // BEGIN: Mantis issue 0020961: Error on a pipe T-Shape
3092 // Compute tolerance
3093 Standard_Real T, VertMax = -RealLast();
3096 for (TopExp_Explorer ExV (theShape, TopAbs_VERTEX); ExV.More(); ExV.Next()) {
3097 TopoDS_Vertex Vertex = TopoDS::Vertex(ExV.Current());
3098 T = BRep_Tool::Tolerance(Vertex);
3103 catch (Standard_Failure) {
3104 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
3105 SetErrorCode(aFail->GetMessageString());
3108 // END: Mantis issue 0020961
3111 GEOMAlgo_FinderShapeOn2 aFinder;
3112 Handle(GEOMAlgo_ClsfSurf) aClsfSurf = new GEOMAlgo_ClsfSurf;
3113 Standard_Real aTol = VertMax; // Mantis issue 0020961
3115 aClsfSurf->SetSurface(theSurface);
3116 aFinder.SetShape(theShape);
3117 aFinder.SetTolerance(aTol);
3118 aFinder.SetClsf(aClsfSurf);
3119 aFinder.SetShapeType(theShapeType);
3120 aFinder.SetState(theState);
3122 // Sets the minimal number of inner points for the faces that do not have own
3123 // inner points at all (for e.g. rectangular planar faces have just 2 triangles).
3125 aFinder.SetNbPntsMin(3);
3126 // Sets the maximal number of inner points for edges or faces.
3127 // It is usefull for the cases when this number is very big (e.g =2000) to improve
3128 // the performance. If this value =0, all inner points will be taken into account.
3130 aFinder.SetNbPntsMax(100);
3134 // Interprete results
3135 Standard_Integer iErr = aFinder.ErrorStatus();
3136 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn2.cxx
3138 MESSAGE(" iErr : " << iErr);
3139 TCollection_AsciiString aMsg (" iErr : ");
3140 aMsg += TCollection_AsciiString(iErr);
3144 Standard_Integer iWrn = aFinder.WarningStatus();
3145 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn2.cxx
3147 MESSAGE(" *** iWrn : " << iWrn);
3150 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
3152 if (listSS.Extent() < 1) {
3153 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
3154 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
3158 // Fill sequence of object IDs
3159 aSeqOfIDs = new TColStd_HSequenceOfInteger;
3161 TopTools_IndexedMapOfShape anIndices;
3162 TopExp::MapShapes(theShape, anIndices);
3164 TopTools_ListIteratorOfListOfShape itSub (listSS);
3165 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
3166 int id = anIndices.FindIndex(itSub.Value());
3167 aSeqOfIDs->Append(id);
3173 //=======================================================================
3174 //function : getObjectsShapesOn
3176 * \brief Find shape objects and their entries by their ids
3177 * \param theShapeIDs - incoming shape ids
3178 * \param theShapeEntries - outgoing entries like "entry1, entry2, ..."
3179 * \retval Handle(TColStd_HSequenceOfTransient) - found shape objects
3181 //=======================================================================
3182 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::
3183 getObjectsShapesOn(const Handle(GEOM_Object)& theShape,
3184 const Handle(TColStd_HSequenceOfInteger)& theShapeIDs,
3185 TCollection_AsciiString & theShapeEntries)
3187 Handle(TColStd_HSequenceOfTransient) aSeq;
3189 if ( !theShapeIDs.IsNull() && theShapeIDs->Length() > 0 )
3191 aSeq = new TColStd_HSequenceOfTransient;
3192 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
3193 TCollection_AsciiString anEntry;
3194 for ( int i = 1; i <= theShapeIDs->Length(); ++i )
3196 anArray->SetValue(1, theShapeIDs->Value( i ));
3197 Handle(GEOM_Object) anObj = GetEngine()->AddSubShape(theShape, anArray);
3198 aSeq->Append( anObj );
3200 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
3201 if ( i != 1 ) theShapeEntries += ",";
3202 theShapeEntries += anEntry;
3208 //=============================================================================
3210 * getSubShapeEdgeSortedIDs
3212 //=============================================================================
3213 Handle(TColStd_HSequenceOfInteger)
3214 GEOMImpl_IShapesOperations::getSubShapeEdgeSortedIDs
3215 (const Handle(GEOM_Object) &theShape,
3216 const Handle(GEOM_Object) &theStartPoint)
3218 Handle(TColStd_HSequenceOfInteger) aResult;
3220 if (theShape.IsNull() || theStartPoint.IsNull()) {
3221 SetErrorCode("NULL GEOM object");
3225 const TopoDS_Shape aShape = theShape->GetValue();
3226 const TopoDS_Shape aStartPoint = theStartPoint->GetValue();
3228 if (aShape.IsNull() || aStartPoint.IsNull()) {
3229 SetErrorCode("NULL Shape");
3233 if (aStartPoint.ShapeType() != TopAbs_VERTEX) {
3234 SetErrorCode("Starting point is not a vertex");
3238 TopExp_Explorer anExp(aShape, TopAbs_EDGE);
3239 TopTools_MapOfShape aMapFence;
3240 TopTools_ListOfShape anEdges;
3242 for (; anExp.More(); anExp.Next()) {
3243 const TopoDS_Shape &anEdge = anExp.Current();
3245 if (aMapFence.Add(anEdge)) {
3246 anEdges.Append(anEdge);
3250 if (anEdges.IsEmpty()) {
3251 SetErrorCode("Shape doesn't contain edges");
3255 // Step 1: Sort edges
3256 GEOMUtils::SortShapes(anEdges, Standard_False);
3258 TopTools_ListIteratorOfListOfShape anIter(anEdges);
3259 TopoDS_Vertex aV[2];
3260 TopTools_DataMapOfShapeListOfShape aMapVE;
3262 // Step 2: Fill the map vertex - list of edges.
3263 for (; anIter.More(); anIter.Next()) {
3264 TopoDS_Edge anEdge = TopoDS::Edge(anIter.Value());
3266 TopExp::Vertices(anEdge, aV[0], aV[1]);
3268 const Standard_Integer aNbV = aV[0].IsSame(aV[1]) ? 1 : 2;
3271 for (i = 0; i < aNbV; ++i) {
3272 if (aV[i].IsNull() == Standard_False) {
3273 if (!aMapVE.IsBound(aV[i])) {
3274 // There is no this vertex in the map.
3275 aMapVE.Bind(aV[i], TopTools_ListOfShape());
3278 // Add the edge to the list bound with the vertex aV[i].
3279 TopTools_ListOfShape &aLEdges = aMapVE.ChangeFind(aV[i]);
3281 aLEdges.Append(anEdge);
3286 // Step 3: Find starting point in aMapVE.
3287 TopoDS_Vertex aStartVtx = TopoDS::Vertex(aStartPoint);
3289 if (!aMapVE.IsBound(aStartVtx)) {
3290 aStartVtx = getSameVertex(aShape, aStartVtx);
3292 if (aStartVtx.IsNull()) {
3293 SetErrorCode("Invalid Starting point");
3298 TopTools_IndexedMapOfShape anIndices;
3299 TopTools_MapOfShape aMapVFence;
3300 TopoDS_Shape aCurVtx = aStartVtx;
3301 TopoDS_Edge aCurEdge =
3302 TopoDS::Edge(aMapVE.Find(aCurVtx).First());
3304 aResult = new TColStd_HSequenceOfInteger;
3305 TopExp::MapShapes(aShape, anIndices);
3307 // Step 4: Fill the list of sorted edges.
3308 while (aMapVFence.Add(aCurVtx)) {
3309 // Append the ID of the current edge to the list of sorted.
3310 aResult->Append(anIndices.FindIndex(aCurEdge));
3311 TopExp::Vertices(aCurEdge, aV[0], aV[1]);
3313 // Get the next vertex.
3314 if (aCurVtx.IsSame(aV[0])) {
3315 if (aCurVtx.IsSame(aV[1])) {
3316 // There is no next vertex.
3325 if (aCurVtx.IsNull()) {
3326 // There is no next vertex.
3330 // Get the next edge.
3331 const TopTools_ListOfShape &aLEdges = aMapVE.Find(aCurVtx);
3332 TopTools_ListIteratorOfListOfShape anEIter(aLEdges);
3334 for (; anEIter.More(); anEIter.Next()) {
3335 const TopoDS_Shape &aLocalEdge = anEIter.Value();
3337 if (aLocalEdge.IsNull() == Standard_False) {
3338 if (!aCurEdge.IsSame(aLocalEdge)) {
3339 aCurEdge = TopoDS::Edge(aLocalEdge);
3345 if (!anEIter.More()) {
3346 // There is no next edge.
3354 //=======================================================================
3355 //function : getShapesOnSurface
3357 * \brief Find sub-shapes complying with given status about surface
3358 * \param theSurface - the surface to check state of sub-shapes against
3359 * \param theShape - the shape to explore
3360 * \param theShapeType - type of sub-shape of theShape
3361 * \param theState - required state
3362 * \param theShapeEntries - outgoing entries like "entry1, entry2, ..."
3363 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
3365 //=======================================================================
3366 Handle(TColStd_HSequenceOfTransient)
3367 GEOMImpl_IShapesOperations::getShapesOnSurface(const Handle(Geom_Surface)& theSurface,
3368 const Handle(GEOM_Object)& theShape,
3369 TopAbs_ShapeEnum theShapeType,
3370 GEOMAlgo_State theState,
3371 TCollection_AsciiString & theShapeEntries)
3373 // Find sub-shapes ids
3374 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
3375 getShapesOnSurfaceIDs (theSurface, theShape->GetValue(), theShapeType, theState);
3376 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
3379 return getObjectsShapesOn( theShape, aSeqOfIDs, theShapeEntries );
3382 //=============================================================================
3386 //=============================================================================
3387 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnPlane
3388 (const Handle(GEOM_Object)& theShape,
3389 const Standard_Integer theShapeType,
3390 const Handle(GEOM_Object)& theAx1,
3391 const GEOMAlgo_State theState)
3395 if (theShape.IsNull() || theAx1.IsNull()) return NULL;
3397 TopoDS_Shape aShape = theShape->GetValue();
3398 TopoDS_Shape anAx1 = theAx1->GetValue();
3400 if (aShape.IsNull() || anAx1.IsNull()) return NULL;
3402 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3403 if ( !checkTypeShapesOn( theShapeType ))
3407 Handle(Geom_Surface) aPlane = makePlane( anAx1 );
3408 if ( aPlane.IsNull() )
3412 TCollection_AsciiString anAsciiList;
3413 Handle(TColStd_HSequenceOfTransient) aSeq;
3414 aSeq = getShapesOnSurface( aPlane, theShape, aShapeType, theState, anAsciiList );
3415 if ( aSeq.IsNull() || aSeq->Length() == 0 )
3418 // Make a Python command
3420 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
3421 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
3423 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
3424 << "] = geompy.GetShapesOnPlane(" << theShape << ", "
3425 << aShapeType << ", " << theAx1 << ", " << theState << ")";
3431 //=============================================================================
3433 * GetShapesOnPlaneWithLocation
3435 //=============================================================================
3436 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnPlaneWithLocation
3437 (const Handle(GEOM_Object)& theShape,
3438 const Standard_Integer theShapeType,
3439 const Handle(GEOM_Object)& theAx1,
3440 const Handle(GEOM_Object)& thePnt,
3441 const GEOMAlgo_State theState)
3445 if (theShape.IsNull() || theAx1.IsNull() || thePnt.IsNull()) return NULL;
3447 TopoDS_Shape aShape = theShape->GetValue();
3448 TopoDS_Shape anAx1 = theAx1->GetValue();
3449 TopoDS_Shape anPnt = thePnt->GetValue();
3451 if (aShape.IsNull() || anAx1.IsNull() || anPnt.IsNull()) return NULL;
3453 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3454 if ( !checkTypeShapesOn( theShapeType ))
3458 if ( anAx1.ShapeType() != TopAbs_EDGE || anPnt.ShapeType() != TopAbs_VERTEX ) return NULL;
3459 TopoDS_Vertex V1, V2, V3;
3460 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
3461 TopExp::Vertices(anEdge, V1, V2, Standard_True);
3463 if (V1.IsNull() || V2.IsNull()) {
3464 SetErrorCode("Bad edge given for the plane normal vector");
3467 V3 = TopoDS::Vertex(anPnt);
3470 SetErrorCode("Bad vertex given for the plane location");
3473 gp_Pnt aLoc = BRep_Tool::Pnt(V3);
3474 gp_Vec aVec(BRep_Tool::Pnt(V1),BRep_Tool::Pnt(V2));
3476 if (aVec.Magnitude() < Precision::Confusion()) {
3477 SetErrorCode("Vector with null magnitude given");
3480 Handle(Geom_Surface) aPlane = new Geom_Plane(aLoc, aVec);
3482 if ( aPlane.IsNull() )
3486 TCollection_AsciiString anAsciiList;
3487 Handle(TColStd_HSequenceOfTransient) aSeq;
3488 aSeq = getShapesOnSurface( aPlane, theShape, aShapeType, theState, anAsciiList );
3489 if ( aSeq.IsNull() || aSeq->Length() == 0 )
3492 // Make a Python command
3494 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
3495 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
3497 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
3498 << "] = geompy.GetShapesOnPlaneWithLocation(" << theShape << ", "
3499 << aShapeType << ", " << theAx1 << ", "<< thePnt <<", " << theState << ")";
3505 //=============================================================================
3507 * GetShapesOnCylinder
3509 //=============================================================================
3510 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnCylinder
3511 (const Handle(GEOM_Object)& theShape,
3512 const Standard_Integer theShapeType,
3513 const Handle(GEOM_Object)& theAxis,
3514 const Standard_Real theRadius,
3515 const GEOMAlgo_State theState)
3519 if (theShape.IsNull() || theAxis.IsNull()) return NULL;
3521 TopoDS_Shape aShape = theShape->GetValue();
3522 TopoDS_Shape anAxis = theAxis->GetValue();
3524 if (aShape.IsNull() || anAxis.IsNull()) return NULL;
3526 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3527 if ( !checkTypeShapesOn( aShapeType ))
3530 // Create a cylinder surface
3531 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
3532 if ( aCylinder.IsNull() )
3536 TCollection_AsciiString anAsciiList;
3537 Handle(TColStd_HSequenceOfTransient) aSeq;
3538 aSeq = getShapesOnSurface( aCylinder, theShape, aShapeType, theState, anAsciiList );
3539 if ( aSeq.IsNull() || aSeq->Length() == 0 )
3542 // Make a Python command
3544 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
3545 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
3547 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
3548 << "] = geompy.GetShapesOnCylinder(" << theShape << ", " << aShapeType
3549 << ", " << theAxis << ", " << theRadius << ", " << theState << ")";
3555 //=============================================================================
3557 * GetShapesOnCylinderWithLocation
3559 //=============================================================================
3560 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnCylinderWithLocation
3561 (const Handle(GEOM_Object)& theShape,
3562 const Standard_Integer theShapeType,
3563 const Handle(GEOM_Object)& theAxis,
3564 const Handle(GEOM_Object)& thePnt,
3565 const Standard_Real theRadius,
3566 const GEOMAlgo_State theState)
3570 if (theShape.IsNull() || theAxis.IsNull() || thePnt.IsNull()) return NULL;
3572 TopoDS_Shape aShape = theShape->GetValue();
3573 TopoDS_Shape anAxis = theAxis->GetValue();
3574 TopoDS_Shape aPnt = thePnt->GetValue();
3576 if (aShape.IsNull() || anAxis.IsNull() || aPnt.IsNull()) return NULL;
3578 if (aPnt.ShapeType() != TopAbs_VERTEX )
3580 SetErrorCode("Bottom location point must be vertex");
3584 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3585 if ( !checkTypeShapesOn( aShapeType ))
3588 // Create a cylinder surface
3589 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
3590 if ( aCylinder.IsNull() )
3593 // translate the surface
3594 Handle(Geom_CylindricalSurface) aCylSurface =
3595 Handle(Geom_CylindricalSurface)::DownCast( aCylinder );
3596 if ( aCylSurface.IsNull() )
3598 SetErrorCode("Unexpected surface type instead of Geom_CylindricalSurface");
3601 gp_Pnt fromLoc = aCylSurface->Cylinder().Location();
3602 gp_Pnt toLoc = BRep_Tool::Pnt( TopoDS::Vertex( aPnt ));
3603 aCylinder->Translate( fromLoc, toLoc );
3606 TCollection_AsciiString anAsciiList;
3607 Handle(TColStd_HSequenceOfTransient) aSeq;
3608 aSeq = getShapesOnSurface( aCylinder, theShape, aShapeType, theState, anAsciiList );
3609 if ( aSeq.IsNull() || aSeq->Length() == 0 )
3612 // Make a Python command
3614 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
3615 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
3617 GEOM::TPythonDump(aFunction)
3618 << "[" << anAsciiList.ToCString()
3619 << "] = geompy.GetShapesOnCylinderWithLocation(" << theShape << ", " << aShapeType << ", "
3620 << theAxis << ", " << thePnt << ", " << theRadius << ", " << theState << ")";
3626 //=============================================================================
3630 //=============================================================================
3631 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnSphere
3632 (const Handle(GEOM_Object)& theShape,
3633 const Standard_Integer theShapeType,
3634 const Handle(GEOM_Object)& theCenter,
3635 const Standard_Real theRadius,
3636 const GEOMAlgo_State theState)
3640 if (theShape.IsNull() || theCenter.IsNull()) return NULL;
3642 TopoDS_Shape aShape = theShape->GetValue();
3643 TopoDS_Shape aCenter = theCenter->GetValue();
3645 if (aShape.IsNull() || aCenter.IsNull()) return NULL;
3647 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3648 if ( !checkTypeShapesOn( aShapeType ))
3651 // Center of the sphere
3652 if (aCenter.ShapeType() != TopAbs_VERTEX) return NULL;
3653 gp_Pnt aLoc = BRep_Tool::Pnt(TopoDS::Vertex(aCenter));
3655 gp_Ax3 anAx3 (aLoc, gp::DZ());
3656 Handle(Geom_SphericalSurface) aSphere =
3657 new Geom_SphericalSurface(anAx3, theRadius);
3660 TCollection_AsciiString anAsciiList;
3661 Handle(TColStd_HSequenceOfTransient) aSeq;
3662 aSeq = getShapesOnSurface( aSphere, theShape, aShapeType, theState, anAsciiList );
3663 if ( aSeq.IsNull() || aSeq->Length() == 0 )
3666 // Make a Python command
3668 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
3669 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
3671 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
3672 << "] = geompy.GetShapesOnSphere(" << theShape << ", " << aShapeType
3673 << ", " << theCenter << ", " << theRadius << ", " << theState << ")";
3679 //=============================================================================
3681 * GetShapesOnPlaneIDs
3683 //=============================================================================
3684 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnPlaneIDs
3685 (const Handle(GEOM_Object)& theShape,
3686 const Standard_Integer theShapeType,
3687 const Handle(GEOM_Object)& theAx1,
3688 const GEOMAlgo_State theState)
3692 if (theShape.IsNull() || theAx1.IsNull()) return NULL;
3694 TopoDS_Shape aShape = theShape->GetValue();
3695 TopoDS_Shape anAx1 = theAx1->GetValue();
3697 if (aShape.IsNull() || anAx1.IsNull()) return NULL;
3699 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3700 if ( !checkTypeShapesOn( aShapeType ))
3704 Handle(Geom_Surface) aPlane = makePlane( anAx1 );
3705 if ( aPlane.IsNull() )
3709 Handle(TColStd_HSequenceOfInteger) aSeq;
3710 aSeq = getShapesOnSurfaceIDs( aPlane, aShape, aShapeType, theState );
3712 // The GetShapesOnPlaneIDs() doesn't change object so no new function is required.
3713 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAx1)->GetLastFunction();
3715 // Make a Python command
3716 GEOM::TPythonDump(aFunction, /*append=*/true)
3717 << "listShapesOnPlane = geompy.GetShapesOnPlaneIDs"
3718 << "(" << theShape << "," << aShapeType << "," << theAx1 << "," << theState << ")";
3724 //=============================================================================
3726 * GetShapesOnPlaneWithLocationIDs
3728 //=============================================================================
3729 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnPlaneWithLocationIDs
3730 (const Handle(GEOM_Object)& theShape,
3731 const Standard_Integer theShapeType,
3732 const Handle(GEOM_Object)& theAx1,
3733 const Handle(GEOM_Object)& thePnt,
3734 const GEOMAlgo_State theState)
3738 if (theShape.IsNull() || theAx1.IsNull() || thePnt.IsNull()) return NULL;
3740 TopoDS_Shape aShape = theShape->GetValue();
3741 TopoDS_Shape anAx1 = theAx1->GetValue();
3742 TopoDS_Shape anPnt = thePnt->GetValue();
3744 if (aShape.IsNull() || anAx1.IsNull() || anPnt.IsNull()) return NULL;
3746 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3747 if ( !checkTypeShapesOn( aShapeType ))
3751 if (anAx1.ShapeType() != TopAbs_EDGE || anPnt.ShapeType() != TopAbs_VERTEX) return NULL;
3752 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
3753 TopoDS_Vertex V1, V2, V3;
3754 TopExp::Vertices(anEdge, V1, V2, Standard_True);
3755 if (V1.IsNull() || V2.IsNull()) {
3756 SetErrorCode("Bad edge given for the plane normal vector");
3759 V3 = TopoDS::Vertex(anPnt);
3761 SetErrorCode("Bad vertex given for the plane location");
3764 gp_Pnt aLoc = BRep_Tool::Pnt(V3);
3765 gp_Vec aVec(BRep_Tool::Pnt(V1),BRep_Tool::Pnt(V2));
3766 if (aVec.Magnitude() < Precision::Confusion()) {
3767 SetErrorCode("Vector with null magnitude given");
3771 Handle(Geom_Surface) aPlane = new Geom_Plane(aLoc, aVec);
3772 if ( aPlane.IsNull() )
3776 Handle(TColStd_HSequenceOfInteger) aSeq;
3777 aSeq = getShapesOnSurfaceIDs( aPlane, aShape, aShapeType, theState );
3779 // The GetShapesOnPlaneIDs() doesn't change object so no new function is required.
3780 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAx1)->GetLastFunction();
3782 // Make a Python command
3783 GEOM::TPythonDump(aFunction, /*append=*/true)
3784 << "listShapesOnPlane = geompy.GetShapesOnPlaneWithLocationIDs"
3785 << "(" << theShape << ", " << aShapeType << ", " << theAx1 << ", "<< thePnt << ", " << theState << ")";
3791 //=============================================================================
3793 * GetShapesOnCylinderIDs
3795 //=============================================================================
3796 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnCylinderIDs
3797 (const Handle(GEOM_Object)& theShape,
3798 const Standard_Integer theShapeType,
3799 const Handle(GEOM_Object)& theAxis,
3800 const Standard_Real theRadius,
3801 const GEOMAlgo_State theState)
3805 if (theShape.IsNull() || theAxis.IsNull()) return NULL;
3807 TopoDS_Shape aShape = theShape->GetValue();
3808 TopoDS_Shape anAxis = theAxis->GetValue();
3810 if (aShape.IsNull() || anAxis.IsNull()) return NULL;
3812 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3813 if ( !checkTypeShapesOn( aShapeType ))
3816 // Create a cylinder surface
3817 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
3818 if ( aCylinder.IsNull() )
3822 Handle(TColStd_HSequenceOfInteger) aSeq;
3823 aSeq = getShapesOnSurfaceIDs( aCylinder, aShape, aShapeType, theState );
3825 // The GetShapesOnCylinder() doesn't change object so no new function is required.
3826 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAxis)->GetLastFunction();
3828 // Make a Python command
3829 GEOM::TPythonDump(aFunction, /*append=*/true)
3830 << "listShapesOnCylinder = geompy.GetShapesOnCylinderIDs"
3831 << "(" << theShape << ", " << aShapeType << ", " << theAxis << ", "
3832 << theRadius << ", " << theState << ")";
3838 //=============================================================================
3840 * GetShapesOnCylinderWithLocationIDs
3842 //=============================================================================
3843 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnCylinderWithLocationIDs
3844 (const Handle(GEOM_Object)& theShape,
3845 const Standard_Integer theShapeType,
3846 const Handle(GEOM_Object)& theAxis,
3847 const Handle(GEOM_Object)& thePnt,
3848 const Standard_Real theRadius,
3849 const GEOMAlgo_State theState)
3853 if (theShape.IsNull() || theAxis.IsNull() || thePnt.IsNull()) return NULL;
3855 TopoDS_Shape aShape = theShape->GetValue();
3856 TopoDS_Shape anAxis = theAxis->GetValue();
3857 TopoDS_Shape aPnt = thePnt->GetValue();
3859 if (aShape.IsNull() || anAxis.IsNull() || aPnt.IsNull()) return NULL;
3861 if (aPnt.ShapeType() != TopAbs_VERTEX )
3863 SetErrorCode("Bottom location point must be vertex");
3867 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3868 if ( !checkTypeShapesOn( aShapeType ))
3871 // Create a cylinder surface
3872 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
3873 if ( aCylinder.IsNull() )
3876 // translate the surface
3877 Handle(Geom_CylindricalSurface) aCylSurface =
3878 Handle(Geom_CylindricalSurface)::DownCast( aCylinder );
3879 if ( aCylSurface.IsNull() )
3881 SetErrorCode("Unexpected surface type instead of Geom_CylindricalSurface");
3884 gp_Pnt fromLoc = aCylSurface->Cylinder().Location();
3885 gp_Pnt toLoc = BRep_Tool::Pnt( TopoDS::Vertex( aPnt ));
3886 aCylinder->Translate( fromLoc, toLoc );
3889 Handle(TColStd_HSequenceOfInteger) aSeq;
3890 aSeq = getShapesOnSurfaceIDs( aCylinder, aShape, aShapeType, theState );
3892 // The GetShapesOnCylinder() doesn't change object so no new function is required.
3893 Handle(GEOM_Function) aFunction =
3894 GEOM::GetCreatedLast(theShape, GEOM::GetCreatedLast(thePnt,theAxis))->GetLastFunction();
3896 // Make a Python command
3897 GEOM::TPythonDump(aFunction, /*append=*/true)
3898 << "listShapesOnCylinder = geompy.GetShapesOnCylinderWithLocationIDs"
3899 << "(" << theShape << ", " << aShapeType << ", " << theAxis << ", "
3900 << thePnt << ", " << theRadius << ", " << theState << ")";
3906 //=============================================================================
3908 * GetShapesOnSphereIDs
3910 //=============================================================================
3911 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnSphereIDs
3912 (const Handle(GEOM_Object)& theShape,
3913 const Standard_Integer theShapeType,
3914 const Handle(GEOM_Object)& theCenter,
3915 const Standard_Real theRadius,
3916 const GEOMAlgo_State theState)
3920 if (theShape.IsNull() || theCenter.IsNull()) return NULL;
3922 TopoDS_Shape aShape = theShape->GetValue();
3923 TopoDS_Shape aCenter = theCenter->GetValue();
3925 if (aShape.IsNull() || aCenter.IsNull()) return NULL;
3927 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3928 if ( !checkTypeShapesOn( aShapeType ))
3931 // Center of the sphere
3932 if (aCenter.ShapeType() != TopAbs_VERTEX) return NULL;
3933 gp_Pnt aLoc = BRep_Tool::Pnt(TopoDS::Vertex(aCenter));
3935 gp_Ax3 anAx3 (aLoc, gp::DZ());
3936 Handle(Geom_SphericalSurface) aSphere =
3937 new Geom_SphericalSurface(anAx3, theRadius);
3940 Handle(TColStd_HSequenceOfInteger) aSeq;
3941 aSeq = getShapesOnSurfaceIDs( aSphere, aShape, aShapeType, theState );
3943 // The GetShapesOnSphere() doesn't change object so no new function is required.
3944 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theCenter)->GetLastFunction();
3946 // Make a Python command
3947 GEOM::TPythonDump(aFunction, /*append=*/true)
3948 << "listShapesOnCylinder = geompy.GetShapesOnSphereIDs"
3949 << "(" << theShape << ", " << aShapeType << ", " << theCenter << ", "
3950 << theRadius << ", " << theState << ")";
3956 //=======================================================================
3957 //function : getShapesOnQuadrangleIDs
3959 * \brief Find IDs of sub-shapes complying with given status about quadrangle
3960 * \param theShape - the shape to explore
3961 * \param theShapeType - type of sub-shape of theShape
3962 * \param theTopLeftPoint - top left quadrangle corner
3963 * \param theTopRigthPoint - top right quadrangle corner
3964 * \param theBottomLeftPoint - bottom left quadrangle corner
3965 * \param theBottomRigthPoint - bottom right quadrangle corner
3966 * \param theState - required state
3967 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
3969 //=======================================================================
3970 Handle(TColStd_HSequenceOfInteger)
3971 GEOMImpl_IShapesOperations::getShapesOnQuadrangleIDs (const Handle(GEOM_Object)& theShape,
3972 const Standard_Integer theShapeType,
3973 const Handle(GEOM_Object)& theTopLeftPoint,
3974 const Handle(GEOM_Object)& theTopRigthPoint,
3975 const Handle(GEOM_Object)& theBottomLeftPoint,
3976 const Handle(GEOM_Object)& theBottomRigthPoint,
3977 const GEOMAlgo_State theState)
3981 if ( theShape.IsNull() ||
3982 theTopLeftPoint.IsNull() ||
3983 theTopRigthPoint.IsNull() ||
3984 theBottomLeftPoint.IsNull() ||
3985 theBottomRigthPoint.IsNull() )
3988 TopoDS_Shape aShape = theShape->GetValue();
3989 TopoDS_Shape aTL = theTopLeftPoint->GetValue();
3990 TopoDS_Shape aTR = theTopRigthPoint->GetValue();
3991 TopoDS_Shape aBL = theBottomLeftPoint->GetValue();
3992 TopoDS_Shape aBR = theBottomRigthPoint->GetValue();
3994 if (aShape.IsNull() ||
3999 aTL.ShapeType() != TopAbs_VERTEX ||
4000 aTR.ShapeType() != TopAbs_VERTEX ||
4001 aBL.ShapeType() != TopAbs_VERTEX ||
4002 aBR.ShapeType() != TopAbs_VERTEX )
4005 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
4006 if ( !checkTypeShapesOn( aShapeType ))
4009 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
4011 // Check presence of triangulation, build if need
4012 if (theShapeType != TopAbs_VERTEX && !GEOMUtils::CheckTriangulation(aShape)) {
4013 SetErrorCode("Cannot build triangulation on the shape");
4018 gp_Pnt aPntTL = BRep_Tool::Pnt(TopoDS::Vertex(aTL));
4019 gp_Pnt aPntTR = BRep_Tool::Pnt(TopoDS::Vertex(aTR));
4020 gp_Pnt aPntBL = BRep_Tool::Pnt(TopoDS::Vertex(aBL));
4021 gp_Pnt aPntBR = BRep_Tool::Pnt(TopoDS::Vertex(aBR));
4023 GEOMAlgo_FinderShapeOn2 aFinder;
4024 Handle(GEOMAlgo_ClsfQuad) aClsfQuad = new GEOMAlgo_ClsfQuad;
4026 Standard_Real aTol = 0.0001; // default value
4028 aClsfQuad->SetCorners(aPntTL, aPntTR, aPntBL, aPntBR);
4029 aFinder.SetShape(aShape);
4030 aFinder.SetTolerance(aTol);
4031 aFinder.SetClsf(aClsfQuad);
4032 aFinder.SetShapeType(aShapeType);
4033 aFinder.SetState(theState);
4035 // Sets the minimal number of inner points for the faces that do not have own
4036 // inner points at all (for e.g. rectangular planar faces have just 2 triangles).
4038 aFinder.SetNbPntsMin(3);
4039 // Sets the maximal number of inner points for edges or faces.
4040 // It is usefull for the cases when this number is very big (e.g =2000) to improve
4041 // the performance. If this value =0, all inner points will be taken into account.
4043 aFinder.SetNbPntsMax(100);
4047 // Interprete results
4048 Standard_Integer iErr = aFinder.ErrorStatus();
4049 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn2.cxx
4051 MESSAGE(" iErr : " << iErr);
4052 TCollection_AsciiString aMsg (" iErr : ");
4053 aMsg += TCollection_AsciiString(iErr);
4057 Standard_Integer iWrn = aFinder.WarningStatus();
4058 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn2.cxx
4060 MESSAGE(" *** iWrn : " << iWrn);
4063 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
4065 if (listSS.Extent() < 1) {
4066 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
4067 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
4071 // Fill sequence of object IDs
4072 aSeqOfIDs = new TColStd_HSequenceOfInteger;
4074 TopTools_IndexedMapOfShape anIndices;
4075 TopExp::MapShapes(aShape, anIndices);
4077 TopTools_ListIteratorOfListOfShape itSub (listSS);
4078 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
4079 int id = anIndices.FindIndex(itSub.Value());
4080 aSeqOfIDs->Append(id);
4085 //=======================================================================
4086 //function : GetShapesOnQuadrangle
4088 * \brief Find sub-shapes complying with given status about quadrangle
4089 * \param theShape - the shape to explore
4090 * \param theShapeType - type of sub-shape of theShape
4091 * \param theTopLeftPoint - top left quadrangle corner
4092 * \param theTopRigthPoint - top right quadrangle corner
4093 * \param theBottomLeftPoint - bottom left quadrangle corner
4094 * \param theBottomRigthPoint - bottom right quadrangle corner
4095 * \param theState - required state
4096 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
4098 //=======================================================================
4099 Handle(TColStd_HSequenceOfTransient)
4100 GEOMImpl_IShapesOperations::GetShapesOnQuadrangle (const Handle(GEOM_Object)& theShape,
4101 const Standard_Integer theShapeType,
4102 const Handle(GEOM_Object)& theTopLeftPoint,
4103 const Handle(GEOM_Object)& theTopRigthPoint,
4104 const Handle(GEOM_Object)& theBottomLeftPoint,
4105 const Handle(GEOM_Object)& theBottomRigthPoint,
4106 const GEOMAlgo_State theState)
4109 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
4110 getShapesOnQuadrangleIDs( theShape,
4115 theBottomRigthPoint,
4117 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->IsEmpty() )
4120 // Find objects by indices
4121 TCollection_AsciiString anAsciiList;
4122 Handle(TColStd_HSequenceOfTransient) aSeq;
4123 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
4124 if ( aSeq.IsNull() || aSeq->IsEmpty() )
4127 // Make a Python command
4129 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
4130 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
4132 GEOM::TPythonDump(aFunction)
4133 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnQuadrangle("
4135 << TopAbs_ShapeEnum(theShapeType) << ", "
4136 << theTopLeftPoint << ", "
4137 << theTopRigthPoint << ", "
4138 << theBottomLeftPoint << ", "
4139 << theBottomRigthPoint << ", "
4146 //=======================================================================
4147 //function : GetShapesOnQuadrangleIDs
4149 * \brief Find IDs of sub-shapes complying with given status about quadrangle
4150 * \param theShape - the shape to explore
4151 * \param theShapeType - type of sub-shape of theShape
4152 * \param theTopLeftPoint - top left quadrangle corner
4153 * \param theTopRigthPoint - top right quadrangle corner
4154 * \param theBottomLeftPoint - bottom left quadrangle corner
4155 * \param theBottomRigthPoint - bottom right quadrangle corner
4156 * \param theState - required state
4157 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
4159 //=======================================================================
4160 Handle(TColStd_HSequenceOfInteger)
4161 GEOMImpl_IShapesOperations::GetShapesOnQuadrangleIDs (const Handle(GEOM_Object)& theShape,
4162 const Standard_Integer theShapeType,
4163 const Handle(GEOM_Object)& theTopLeftPoint,
4164 const Handle(GEOM_Object)& theTopRigthPoint,
4165 const Handle(GEOM_Object)& theBottomLeftPoint,
4166 const Handle(GEOM_Object)& theBottomRigthPoint,
4167 const GEOMAlgo_State theState)
4170 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
4171 getShapesOnQuadrangleIDs( theShape,
4176 theBottomRigthPoint,
4178 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->IsEmpty() )
4181 // Make a Python command
4183 // The GetShapesOnCylinder() doesn't change object so no new function is required.
4184 Handle(GEOM_Object) lastObj = GEOM::GetCreatedLast(theShape,theTopLeftPoint);
4185 lastObj = GEOM::GetCreatedLast(lastObj,theTopRigthPoint);
4186 lastObj = GEOM::GetCreatedLast(lastObj,theBottomRigthPoint);
4187 lastObj = GEOM::GetCreatedLast(lastObj,theBottomLeftPoint);
4188 Handle(GEOM_Function) aFunction = lastObj->GetLastFunction();
4190 GEOM::TPythonDump(aFunction, /*append=*/true)
4191 << "listShapesOnQuadrangle = geompy.GetShapesOnQuadrangleIDs("
4193 << TopAbs_ShapeEnum(theShapeType) << ", "
4194 << theTopLeftPoint << ", "
4195 << theTopRigthPoint << ", "
4196 << theBottomLeftPoint << ", "
4197 << theBottomRigthPoint << ", "
4204 //=============================================================================
4209 //=============================================================================
4210 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlace (Handle(GEOM_Object) theShapeWhere,
4211 Handle(GEOM_Object) theShapeWhat)
4215 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
4217 TopoDS_Shape aWhere = theShapeWhere->GetValue();
4218 TopoDS_Shape aWhat = theShapeWhat->GetValue();
4220 if (aWhere.IsNull() || aWhat.IsNull()) {
4221 SetErrorCode("Error: aWhere and aWhat TopoDS_Shape are Null.");
4225 // Searching for the sub-shapes inside the ShapeWhere shape
4226 GEOMAlgo_GetInPlace aGIP;
4228 if (!GEOMAlgo_GetInPlaceAPI::GetInPlace(aWhere, aWhat, aGIP)) {
4229 SetErrorCode("Error in GEOMAlgo_GetInPlace");
4233 // Add direct result.
4234 TopTools_ListOfShape aLSA;
4235 const TopoDS_Shape &aShapeResult = aGIP.Result();
4236 TopTools_MapOfShape aMFence;
4237 TopTools_IndexedMapOfShape aWhereIndices;
4238 Standard_Integer aShapeType = -1;
4240 TopExp::MapShapes(aWhere, aWhereIndices);
4242 if (aShapeResult.IsNull() == Standard_False) {
4243 TopoDS_Iterator anIt(aShapeResult);
4244 Standard_Boolean isFirst = Standard_True;
4246 for (; anIt.More(); anIt.Next()) {
4247 const TopoDS_Shape &aPart = anIt.Value();
4249 if(aWhereIndices.Contains(aPart) && aMFence.Add(aPart)) {
4250 const TopAbs_ShapeEnum aType = aPart.ShapeType();
4252 if (aShapeType == -1) {
4255 } else if (aShapeType != TopAbs_SHAPE && aShapeType != aType) {
4257 aShapeType = TopAbs_SHAPE;
4265 if (aLSA.Extent() == 0) {
4266 SetErrorCode(NOT_FOUND_ANY); // Not found any Results
4270 Handle(TColStd_HArray1OfInteger) aModifiedArray = new TColStd_HArray1OfInteger (1, aLSA.Extent());
4271 TopTools_ListIteratorOfListOfShape anIterModif (aLSA);
4272 for (Standard_Integer imod = 1; anIterModif.More(); anIterModif.Next(), imod++) {
4273 aModifiedArray->SetValue(imod, aWhereIndices.FindIndex(anIterModif.Value()));
4277 Handle(GEOM_Object) aResult = GetEngine()->AddSubShape(theShapeWhere, aModifiedArray);
4278 if (aResult.IsNull()) {
4279 SetErrorCode("Error in algorithm: result found, but cannot be returned.");
4283 const Standard_Boolean isSameType = (aShapeType != TopAbs_SHAPE);
4285 if ((aModifiedArray->Length() > 1 && isSameType) ||
4286 theShapeWhat->GetType() == GEOM_GROUP) {
4288 aResult->SetType(GEOM_GROUP);
4290 //Set a sub-shape type
4291 TopoDS_Shape aFirstFound = aLSA.First();
4292 TopAbs_ShapeEnum aShapeType = aFirstFound.ShapeType();
4294 TDF_Label aFreeLabel = aResult->GetFreeLabel();
4295 TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aShapeType);
4298 //Make a Python command
4299 Handle(GEOM_Function) aFunction = aResult->GetFunction(1);
4301 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetInPlace("
4302 << theShapeWhere << ", " << theShapeWhat << ", True)";
4308 //=============================================================================
4310 * case GetInPlaceOld:
4313 //=============================================================================
4314 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlaceOld
4315 (Handle(GEOM_Object) theShapeWhere,
4316 Handle(GEOM_Object) theShapeWhat)
4320 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
4322 TopoDS_Shape aWhere = theShapeWhere->GetValue();
4323 TopoDS_Shape aWhat = theShapeWhat->GetValue();
4324 TopTools_ListOfShape aModifiedList;
4325 const Standard_Integer iErr =
4326 GEOMAlgo_GetInPlaceAPI::GetInPlaceOld(aWhere, aWhat, aModifiedList);
4331 SetErrorCode("Error: aWhere and aWhat TopoDS_Shape are Null.");
4335 ("Error: An attempt to extract a shape of not supported type.");
4338 SetErrorCode(NOT_FOUND_ANY);
4341 SetErrorCode("Shape driver failed");
4348 TopTools_IndexedMapOfShape aWhereIndices;
4349 TopExp::MapShapes(aWhere, aWhereIndices);
4351 Handle(TColStd_HArray1OfInteger) aModifiedArray =
4352 new TColStd_HArray1OfInteger (1, aModifiedList.Extent());
4353 TopTools_ListIteratorOfListOfShape anIterModif (aModifiedList);
4354 Standard_Integer imod;
4355 Standard_Integer aShapeType = -1;
4357 for (imod = 1; anIterModif.More(); anIterModif.Next(), imod++) {
4358 const Standard_Integer anIndex =
4359 aWhereIndices.FindIndex(anIterModif.Value());
4360 const TopAbs_ShapeEnum aType = anIterModif.Value().ShapeType();
4362 if (aShapeType == -1) {
4365 } else if (aShapeType != TopAbs_SHAPE && aShapeType != aType) {
4367 aShapeType = TopAbs_SHAPE;
4370 aModifiedArray->SetValue(imod, anIndex);
4374 Handle(GEOM_Object) aResult =
4375 GetEngine()->AddSubShape(theShapeWhere, aModifiedArray);
4377 if (aResult.IsNull()) {
4378 SetErrorCode("Error in algorithm: result found, but cannot be returned.");
4382 const Standard_Boolean isSameType = (aShapeType != TopAbs_SHAPE);
4384 if ((aModifiedArray->Length() > 1 && isSameType) ||
4385 theShapeWhat->GetType() == GEOM_GROUP) {
4387 aResult->SetType(GEOM_GROUP);
4389 //Set a sub-shape type
4390 TopoDS_Shape aFirstFound = aWhereIndices.FindKey(aModifiedArray->Value(1));
4391 TopAbs_ShapeEnum aShapeType = aFirstFound.ShapeType();
4393 TDF_Label aFreeLabel = aResult->GetFreeLabel();
4394 TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aShapeType);
4397 //Make a Python command
4398 Handle(GEOM_Function) aFunction = aResult->GetFunction(1);
4400 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetInPlace("
4401 << theShapeWhere << ", " << theShapeWhat << ", False)";
4408 //=======================================================================
4409 //function : GetInPlaceByHistory
4411 //=======================================================================
4412 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlaceByHistory
4413 (Handle(GEOM_Object) theShapeWhere,
4414 Handle(GEOM_Object) theShapeWhat)
4418 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
4420 TopoDS_Shape aWhere = theShapeWhere->GetValue();
4421 TopoDS_Shape aWhat = theShapeWhat->GetValue();
4423 if (aWhere.IsNull() || aWhat.IsNull()) return NULL;
4425 Handle(GEOM_Function) aWhereFunction = theShapeWhere->GetLastFunction();
4426 if (aWhereFunction.IsNull()) return NULL;
4428 //Fill array of indices
4429 TopTools_IndexedMapOfShape aWhereIndices;
4431 TopExp::MapShapes(aWhere, aWhereIndices);
4434 TopTools_ListOfShape aModifiedList;
4435 bool isFound = GEOMAlgo_GetInPlaceAPI::GetInPlaceByHistory
4436 (aWhereFunction, aWhereIndices, aWhat, aModifiedList);
4438 if (!isFound || aModifiedList.Extent() < 1) {
4439 SetErrorCode("Error: No history found for the sought shape or its sub-shapes.");
4443 Handle(TColStd_HArray1OfInteger) aModifiedArray =
4444 new TColStd_HArray1OfInteger (1, aModifiedList.Extent());
4445 TopTools_ListIteratorOfListOfShape anIterModif (aModifiedList);
4446 Standard_Integer imod;
4447 Standard_Integer aShapeType = -1;
4449 for (imod = 1; anIterModif.More(); anIterModif.Next(), imod++) {
4450 const Standard_Integer anIndex =
4451 aWhereIndices.FindIndex(anIterModif.Value());
4452 const TopAbs_ShapeEnum aType = anIterModif.Value().ShapeType();
4454 if (aShapeType == -1) {
4457 } else if (aShapeType != TopAbs_SHAPE && aShapeType != aType) {
4459 aShapeType = TopAbs_SHAPE;
4462 aModifiedArray->SetValue(imod, anIndex);
4466 Handle(GEOM_Object) aResult = GetEngine()->AddSubShape(theShapeWhere, aModifiedArray);
4467 if (aResult.IsNull()) {
4468 SetErrorCode("Error in algorithm: result found, but cannot be returned.");
4472 const Standard_Boolean isSameType = (aShapeType != TopAbs_SHAPE);
4474 if ((aModifiedArray->Length() > 1 && isSameType) ||
4475 theShapeWhat->GetType() == GEOM_GROUP) {
4477 aResult->SetType(GEOM_GROUP);
4479 //Set a sub-shape type
4480 TopoDS_Shape aFirstFound = aWhereIndices.FindKey(aModifiedArray->Value(1));
4481 TopAbs_ShapeEnum aShapeType = aFirstFound.ShapeType();
4483 TDF_Label aFreeLabel = aResult->GetFreeLabel();
4484 TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aShapeType);
4487 //Make a Python command
4488 Handle(GEOM_Function) aFunction = aResult->GetFunction(1);
4490 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetInPlaceByHistory("
4491 << theShapeWhere << ", " << theShapeWhat << ")";
4497 //=======================================================================
4498 //function : isSameEdge
4499 //purpose : Returns True if two edges coincide
4500 //=======================================================================
4501 static bool isSameEdge(const TopoDS_Edge& theEdge1, const TopoDS_Edge& theEdge2)
4503 TopoDS_Vertex V11, V12, V21, V22;
4504 TopExp::Vertices(theEdge1, V11, V12);
4505 TopExp::Vertices(theEdge2, V21, V22);
4506 gp_Pnt P11 = BRep_Tool::Pnt(V11);
4507 gp_Pnt P12 = BRep_Tool::Pnt(V12);
4508 gp_Pnt P21 = BRep_Tool::Pnt(V21);
4509 gp_Pnt P22 = BRep_Tool::Pnt(V22);
4510 bool coincide = false;
4512 //Check that ends of edges coincide
4513 if(P11.Distance(P21) <= MAX_TOLERANCE) {
4514 if(P12.Distance(P22) <= MAX_TOLERANCE) coincide = true;
4516 else if(P11.Distance(P22) <= MAX_TOLERANCE) {
4517 if(P12.Distance(P21) <= MAX_TOLERANCE) coincide = true;
4520 if(!coincide) return false;
4522 if (BRep_Tool::Degenerated(theEdge1))
4523 if (BRep_Tool::Degenerated(theEdge2)) return true;
4526 if (BRep_Tool::Degenerated(theEdge2)) return false;
4528 double U11, U12, U21, U22;
4529 Handle(Geom_Curve) C1 = BRep_Tool::Curve(theEdge1, U11, U12);
4530 Handle(Geom_Curve) C2 = BRep_Tool::Curve(theEdge2, U21, U22);
4532 //Check that both edges has the same geometry
4533 double range = U12-U11;
4534 double U = U11+ range/3.0;
4535 gp_Pnt P1 = C1->Value(U); //Compute a point on one third of the edge's length
4536 U = U11+range*2.0/3.0;
4537 gp_Pnt P2 = C1->Value(U); //Compute a point on two thirds of the edge's length
4539 if(!GeomLib_Tool::Parameter(C2, P1, MAX_TOLERANCE, U) || U < U21 || U > U22)
4542 if(P1.Distance(C2->Value(U)) > MAX_TOLERANCE) return false;
4544 if(!GeomLib_Tool::Parameter(C2, P2, MAX_TOLERANCE, U) || U < U21 || U > U22)
4547 if(P2.Distance(C2->Value(U)) > MAX_TOLERANCE) return false;
4552 #include <TopoDS_TShape.hxx>
4553 //=======================================================================
4554 //function : isSameFace
4555 //purpose : Returns True if two faces coincide
4556 //=======================================================================
4557 static bool isSameFace(const TopoDS_Face& theFace1, const TopoDS_Face& theFace2)
4559 TopExp_Explorer E(theFace1, TopAbs_EDGE);
4560 TopTools_ListOfShape LS1, LS2;
4561 for(; E.More(); E.Next()) LS1.Append(E.Current());
4563 E.Init(theFace2, TopAbs_EDGE);
4564 for(; E.More(); E.Next()) LS2.Append(E.Current());
4566 //Compare the number of edges in the faces
4567 if(LS1.Extent() != LS2.Extent()) return false;
4569 double aMin = RealFirst(), aMax = RealLast();
4570 double xminB1=aMax, yminB1=aMax, zminB1=aMax, xminB2=aMax, yminB2=aMax, zminB2=aMax;
4571 double xmaxB1=aMin, ymaxB1=aMin, zmaxB1=aMin, xmaxB2=aMin, ymaxB2=aMin, zmaxB2=aMin;
4573 for(E.Init(theFace1, TopAbs_VERTEX); E.More(); E.Next()) {
4574 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4575 if(P.X() < xminB1) xminB1 = P.X();
4576 if(P.Y() < yminB1) yminB1 = P.Y();
4577 if(P.Z() < zminB1) zminB1 = P.Z();
4578 if(P.X() > xmaxB1) xmaxB1 = P.X();
4579 if(P.Y() > ymaxB1) ymaxB1 = P.Y();
4580 if(P.Z() > zmaxB1) zmaxB1 = P.Z();
4583 for(E.Init(theFace2, TopAbs_VERTEX); E.More(); E.Next()) {
4584 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4585 if(P.X() < xminB2) xminB2 = P.X();
4586 if(P.Y() < yminB2) yminB2 = P.Y();
4587 if(P.Z() < zminB2) zminB2 = P.Z();
4588 if(P.X() > xmaxB2) xmaxB2 = P.X();
4589 if(P.Y() > ymaxB2) ymaxB2 = P.Y();
4590 if(P.Z() > zmaxB2) zmaxB2 = P.Z();
4593 //Compare the bounding boxes of both faces
4594 if(gp_Pnt(xminB1, yminB1, zminB1).Distance(gp_Pnt(xminB2, yminB2, zminB2)) > MAX_TOLERANCE)
4597 if(gp_Pnt(xmaxB1, ymaxB1, zmaxB1).Distance(gp_Pnt(xmaxB2, ymaxB2, zmaxB2)) > MAX_TOLERANCE)
4600 Handle(Geom_Surface) S1 = BRep_Tool::Surface(theFace1);
4601 Handle(Geom_Surface) S2 = BRep_Tool::Surface(theFace2);
4603 //Check if there a coincidence of two surfaces at least in two points
4604 double U11, U12, V11, V12, U21, U22, V21, V22;
4605 BRepTools::UVBounds(theFace1, U11, U12, V11, V12);
4606 BRepTools::UVBounds(theFace2, U21, U22, V21, V22);
4608 double rangeU = U12-U11;
4609 double rangeV = V12-V11;
4610 double U = U11 + rangeU/3.0;
4611 double V = V11 + rangeV/3.0;
4612 gp_Pnt P1 = S1->Value(U, V);
4613 U = U11+rangeU*2.0/3.0;
4614 V = V11+rangeV*2.0/3.0;
4615 gp_Pnt P2 = S1->Value(U, V);
4617 if (!GeomLib_Tool::Parameters(S2, P1, MAX_TOLERANCE, U, V) || U < U21 || U > U22 || V < V21 || V > V22)
4620 if (P1.Distance(S2->Value(U,V)) > MAX_TOLERANCE) return false;
4622 if (!GeomLib_Tool::Parameters(S2, P2, MAX_TOLERANCE, U, V) || U < U21 || U > U22 || V < V21 || V > V22)
4625 if (P2.Distance(S2->Value(U, V)) > MAX_TOLERANCE) return false;
4627 //Check that each edge of the Face1 has a counterpart in the Face2
4628 TopTools_MapOfOrientedShape aMap;
4629 TopTools_ListIteratorOfListOfShape LSI1(LS1);
4630 for(; LSI1.More(); LSI1.Next()) {
4631 TopoDS_Edge E = TopoDS::Edge(LSI1.Value());
4632 bool isFound = false;
4633 TopTools_ListIteratorOfListOfShape LSI2(LS2);
4634 for(; LSI2.More(); LSI2.Next()) {
4635 TopoDS_Shape aValue = LSI2.Value();
4636 if(aMap.Contains(aValue)) continue; //To avoid checking already found edge several times
4637 if(isSameEdge(E, TopoDS::Edge(aValue))) {
4643 if(!isFound) return false;
4649 //=======================================================================
4650 //function : isSameSolid
4651 //purpose : Returns True if two solids coincide
4652 //=======================================================================
4653 bool isSameSolid(const TopoDS_Solid& theSolid1, const TopoDS_Solid& theSolid2)
4655 TopExp_Explorer E(theSolid1, TopAbs_FACE);
4656 TopTools_ListOfShape LS1, LS2;
4657 for(; E.More(); E.Next()) LS1.Append(E.Current());
4658 E.Init(theSolid2, TopAbs_FACE);
4659 for(; E.More(); E.Next()) LS2.Append(E.Current());
4661 if(LS1.Extent() != LS2.Extent()) return false;
4663 double aMin = RealFirst(), aMax = RealLast();
4664 double xminB1=aMax, yminB1=aMax, zminB1=aMax, xminB2=aMax, yminB2=aMax, zminB2=aMax;
4665 double xmaxB1=aMin, ymaxB1=aMin, zmaxB1=aMin, xmaxB2=aMin, ymaxB2=aMin, zmaxB2=aMin;
4667 for(E.Init(theSolid1, TopAbs_VERTEX); E.More(); E.Next()) {
4668 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4669 if(P.X() < xminB1) xminB1 = P.X();
4670 if(P.Y() < yminB1) yminB1 = P.Y();
4671 if(P.Z() < zminB1) zminB1 = P.Z();
4672 if(P.X() > xmaxB1) xmaxB1 = P.X();
4673 if(P.Y() > ymaxB1) ymaxB1 = P.Y();
4674 if(P.Z() > zmaxB1) zmaxB1 = P.Z();
4677 for(E.Init(theSolid2, TopAbs_VERTEX); E.More(); E.Next()) {
4678 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4679 if(P.X() < xminB2) xminB2 = P.X();
4680 if(P.Y() < yminB2) yminB2 = P.Y();
4681 if(P.Z() < zminB2) zminB2 = P.Z();
4682 if(P.X() > xmaxB2) xmaxB2 = P.X();
4683 if(P.Y() > ymaxB2) ymaxB2 = P.Y();
4684 if(P.Z() > zmaxB2) zmaxB2 = P.Z();
4687 //Compare the bounding boxes of both solids
4688 if(gp_Pnt(xminB1, yminB1, zminB1).Distance(gp_Pnt(xminB2, yminB2, zminB2)) > MAX_TOLERANCE)
4691 if(gp_Pnt(xmaxB1, ymaxB1, zmaxB1).Distance(gp_Pnt(xmaxB2, ymaxB2, zmaxB2)) > MAX_TOLERANCE)
4694 //Check that each face of the Solid1 has a counterpart in the Solid2
4695 TopTools_MapOfOrientedShape aMap;
4696 TopTools_ListIteratorOfListOfShape LSI1(LS1);
4697 for(; LSI1.More(); LSI1.Next()) {
4698 TopoDS_Face F = TopoDS::Face(LSI1.Value());
4699 bool isFound = false;
4700 TopTools_ListIteratorOfListOfShape LSI2(LS2);
4701 for(; LSI2.More(); LSI2.Next()) {
4702 if(aMap.Contains(LSI2.Value())) continue; //To avoid checking already found faces several times
4703 if(isSameFace(F, TopoDS::Face(LSI2.Value()))) {
4704 aMap.Add(LSI2.Value());
4709 if(!isFound) return false;
4715 //=======================================================================
4716 //function : GetSame
4718 //=======================================================================
4719 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetSame(const Handle(GEOM_Object)& theShapeWhere,
4720 const Handle(GEOM_Object)& theShapeWhat)
4723 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
4725 TopoDS_Shape aWhere = theShapeWhere->GetValue();
4726 TopoDS_Shape aWhat = theShapeWhat->GetValue();
4728 if (aWhere.IsNull() || aWhat.IsNull()) return NULL;
4731 bool isFound = false;
4732 TopoDS_Shape aSubShape;
4733 TopTools_MapOfShape aMap;
4735 if (aWhat.ShapeType() == TopAbs_COMPOUND || aWhat.ShapeType() == TopAbs_COMPSOLID) {
4736 TopoDS_Iterator It (aWhat, Standard_True, Standard_True);
4737 if (It.More()) aWhat = It.Value();
4740 SetErrorCode("Compounds of two or more shapes are not allowed for aWhat argument");
4745 switch (aWhat.ShapeType()) {
4746 case TopAbs_VERTEX: {
4747 aSubShape = getSameVertex(aWhere, TopoDS::Vertex(aWhat));
4748 isFound = !aSubShape.IsNull();
4752 TopoDS_Edge anEdge = TopoDS::Edge(aWhat);
4753 TopExp_Explorer E(aWhere, TopAbs_EDGE);
4754 for(; E.More(); E.Next()) {
4755 if(!aMap.Add(E.Current())) continue;
4756 if(isSameEdge(anEdge, TopoDS::Edge(E.Current()))) {
4757 aSubShape = E.Current();
4765 TopoDS_Face aFace = TopoDS::Face(aWhat);
4766 TopExp_Explorer E(aWhere, TopAbs_FACE);
4767 for(; E.More(); E.Next()) {
4768 if(!aMap.Add(E.Current())) continue;
4769 if(isSameFace(aFace, TopoDS::Face(E.Current()))) {
4770 aSubShape = E.Current();
4777 case TopAbs_SOLID: {
4778 TopoDS_Solid aSolid = TopoDS::Solid(aWhat);
4779 TopExp_Explorer E(aWhere, TopAbs_SOLID);
4780 for(; E.More(); E.Next()) {
4781 if(!aMap.Add(E.Current())) continue;
4782 if(isSameSolid(aSolid, TopoDS::Solid(E.Current()))) {
4783 aSubShape = E.Current();
4795 TopTools_IndexedMapOfShape anIndices;
4796 TopExp::MapShapes(aWhere, anIndices);
4797 if (anIndices.Contains(aSubShape))
4798 anIndex = anIndices.FindIndex(aSubShape);
4801 if (anIndex < 0) return NULL;
4803 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
4805 anArray->SetValue(1, anIndex);
4807 Handle(GEOM_Object) aResult = GetEngine()->AddSubShape(theShapeWhere, anArray);
4808 Handle(GEOM_Function) aFunction = aResult->GetLastFunction();
4810 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetSame("
4811 << theShapeWhere << ", " << theShapeWhat << ")";
4819 //=======================================================================
4820 //function : GetSameIDs
4822 //=======================================================================
4823 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetSameIDs
4824 (const Handle(GEOM_Object)& theShapeWhere,
4825 const Handle(GEOM_Object)& theShapeWhat)
4828 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
4830 TopoDS_Shape aWhere = theShapeWhere->GetValue();
4831 TopoDS_Shape aWhat = theShapeWhat->GetValue();
4833 if (aWhere.IsNull() || aWhat.IsNull()) return NULL;
4835 TopTools_ListOfShape listShape;
4836 TopTools_MapOfShape aMap;
4838 if (aWhat.ShapeType() == TopAbs_COMPOUND || aWhat.ShapeType() == TopAbs_COMPSOLID) {
4839 TopoDS_Iterator It (aWhat, Standard_True, Standard_True);
4840 if (It.More()) aWhat = It.Value();
4843 SetErrorCode("Compounds of two or more shapes are not allowed for aWhat argument");
4848 switch (aWhat.ShapeType()) {
4849 case TopAbs_VERTEX: {
4850 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(aWhat));
4851 TopExp_Explorer E(aWhere, TopAbs_VERTEX);
4852 for(; E.More(); E.Next()) {
4853 if(!aMap.Add(E.Current())) continue;
4854 gp_Pnt P2 = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4855 if(P.Distance(P2) <= MAX_TOLERANCE) {
4856 listShape.Append(E.Current());
4862 TopoDS_Edge anEdge = TopoDS::Edge(aWhat);
4863 TopExp_Explorer E(aWhere, TopAbs_EDGE);
4864 for(; E.More(); E.Next()) {
4865 if(!aMap.Add(E.Current())) continue;
4866 if(isSameEdge(anEdge, TopoDS::Edge(E.Current()))) {
4867 listShape.Append(E.Current());
4873 TopoDS_Face aFace = TopoDS::Face(aWhat);
4874 TopExp_Explorer E(aWhere, TopAbs_FACE);
4875 for(; E.More(); E.Next()) {
4876 if(!aMap.Add(E.Current())) continue;
4877 if(isSameFace(aFace, TopoDS::Face(E.Current()))) {
4878 listShape.Append(E.Current());
4883 case TopAbs_SOLID: {
4884 TopoDS_Solid aSolid = TopoDS::Solid(aWhat);
4885 TopExp_Explorer E(aWhere, TopAbs_SOLID);
4886 for(; E.More(); E.Next()) {
4887 if(!aMap.Add(E.Current())) continue;
4888 if(isSameSolid(aSolid, TopoDS::Solid(E.Current()))) {
4889 listShape.Append(E.Current());
4898 if ( !listShape.IsEmpty() ) {
4899 TopTools_IndexedMapOfShape anIndices;
4900 TopExp::MapShapes(aWhere, anIndices);
4901 TopTools_ListIteratorOfListOfShape itSub (listShape);
4902 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
4903 for (; itSub.More(); itSub.Next()) {
4904 if (anIndices.Contains(itSub.Value()))
4905 aSeq->Append(anIndices.FindIndex(itSub.Value()));
4908 // The GetSameIDs() doesn't change object so no new function is required.
4909 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShapeWhere,theShapeWhat)->GetLastFunction();
4911 // Make a Python command
4912 GEOM::TPythonDump(aFunction, /*append=*/true)
4913 << "listSameIDs = geompy.GetSameIDs("
4914 << theShapeWhere << ", "
4915 << theShapeWhat << ")";
4918 SetErrorCode(NOT_FOUND_ANY);
4923 //=======================================================================
4924 //function : ExtendEdge
4926 //=======================================================================
4927 Handle(GEOM_Object) GEOMImpl_IShapesOperations::ExtendEdge
4928 (const Handle(GEOM_Object) &theEdge,
4929 const Standard_Real theMin,
4930 const Standard_Real theMax)
4934 if (theEdge.IsNull()) {
4938 //Add a new Edge object
4939 Handle(GEOM_Object) aResEdge = GetEngine()->AddObject(GetDocID(), GEOM_EDGE);
4941 //Add a new Vector function
4942 Handle(GEOM_Function) aFunction =
4943 aResEdge->AddFunction(GEOMImpl_ShapeDriver::GetID(), EDGE_UV);
4945 //Check if the function is set correctly
4946 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) {
4950 GEOMImpl_IShapeExtend aCI (aFunction);
4952 Handle(GEOM_Function) anEdge = theEdge->GetLastFunction();
4954 if (anEdge.IsNull()) {
4958 aCI.SetShape(anEdge);
4959 aCI.SetUMin(theMin);
4960 aCI.SetUMax(theMax);
4962 //Compute the Edge value
4965 if (!GetSolver()->ComputeFunction(aFunction)) {
4966 SetErrorCode("Shape driver failed");
4971 catch (Standard_Failure) {
4972 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
4973 SetErrorCode(aFail->GetMessageString());
4978 //Make a Python command
4979 GEOM::TPythonDump(aFunction)
4980 << aResEdge << " = geompy.ExtendEdge("
4981 << theEdge << ", " << theMin << ", " << theMax << ")";
4988 //=======================================================================
4989 //function : ExtendFace
4991 //=======================================================================
4992 Handle(GEOM_Object) GEOMImpl_IShapesOperations::ExtendFace
4993 (const Handle(GEOM_Object) &theFace,
4994 const Standard_Real theUMin,
4995 const Standard_Real theUMax,
4996 const Standard_Real theVMin,
4997 const Standard_Real theVMax)
5001 if (theFace.IsNull()) {
5005 //Add a new Face object
5006 Handle(GEOM_Object) aResFace = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
5008 //Add a new Vector function
5009 Handle(GEOM_Function) aFunction =
5010 aResFace->AddFunction(GEOMImpl_ShapeDriver::GetID(), FACE_UV);
5012 //Check if the function is set correctly
5013 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) {
5017 GEOMImpl_IShapeExtend aCI (aFunction);
5019 Handle(GEOM_Function) aFace = theFace->GetLastFunction();
5021 if (aFace.IsNull()) {
5025 aCI.SetShape(aFace);
5026 aCI.SetUMin(theUMin);
5027 aCI.SetUMax(theUMax);
5028 aCI.SetVMin(theVMin);
5029 aCI.SetVMax(theVMax);
5031 //Compute the Face value
5034 if (!GetSolver()->ComputeFunction(aFunction)) {
5035 SetErrorCode("Shape driver failed");
5040 catch (Standard_Failure) {
5041 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
5042 SetErrorCode(aFail->GetMessageString());
5047 //Make a Python command
5048 GEOM::TPythonDump(aFunction)
5049 << aResFace << " = geompy.ExtendFace("
5050 << theFace << ", " << theUMin << ", " << theUMax << ", "
5051 << theVMin << ", " << theVMax << ")";
5058 //=======================================================================
5059 //function : MakeSurfaceFromFace
5061 //=======================================================================
5062 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeSurfaceFromFace
5063 (const Handle(GEOM_Object) &theFace)
5067 if (theFace.IsNull()) {
5071 //Add a new Face object
5072 Handle(GEOM_Object) aResFace = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
5074 //Add a new Vector function
5075 Handle(GEOM_Function) aFunction =
5076 aResFace->AddFunction(GEOMImpl_ShapeDriver::GetID(), SURFACE_FROM_FACE);
5078 //Check if the function is set correctly
5079 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) {
5083 GEOMImpl_IShapeExtend aCI (aFunction);
5085 Handle(GEOM_Function) aFace = theFace->GetLastFunction();
5087 if (aFace.IsNull()) {
5091 aCI.SetShape(aFace);
5093 //Compute the Face value
5096 if (!GetSolver()->ComputeFunction(aFunction)) {
5097 SetErrorCode("Shape driver failed");
5102 catch (Standard_Failure) {
5103 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
5104 SetErrorCode(aFail->GetMessageString());
5109 //Make a Python command
5110 GEOM::TPythonDump(aFunction)
5111 << aResFace << " = geompy.MakeSurfaceFromFace("