1 // Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 // File : GEOMImpl_IShapesOperations.cxx
25 // Author : modified by Lioka RAZAFINDRAZAKA (CEA) 22/06/2007
28 //#include <Standard_Stream.hxx>
30 #include "GEOMImpl_IShapesOperations.hxx"
32 #include "GEOMImpl_Types.hxx"
34 #include "GEOMImpl_VectorDriver.hxx"
35 #include "GEOMImpl_ShapeDriver.hxx"
36 #include "GEOMImpl_GlueDriver.hxx"
37 #include "GEOMImpl_FillingDriver.hxx"
39 #include "GEOMImpl_IVector.hxx"
40 #include "GEOMImpl_IShapes.hxx"
41 #include "GEOMImpl_IShapeExtend.hxx"
42 #include "GEOMImpl_IGlue.hxx"
43 #include "GEOMImpl_IFilling.hxx"
45 #include "GEOMImpl_Block6Explorer.hxx"
46 #include "GEOMImpl_IHealingOperations.hxx"
48 #include "GEOMImpl_Gen.hxx"
50 #include "GEOM_Function.hxx"
51 #include "GEOM_ISubShape.hxx"
52 #include "GEOM_PythonDump.hxx"
54 #include "GEOMUtils.hxx"
56 #include "GEOMAlgo_ClsfBox.hxx"
57 #include "GEOMAlgo_ClsfQuad.hxx"
58 #include "GEOMAlgo_ClsfSolid.hxx"
59 #include "GEOMAlgo_ClsfSurf.hxx"
60 #include "GEOMAlgo_FinderShapeOn2.hxx"
61 #include "GEOMAlgo_GetInPlace.hxx"
62 #include "GEOMAlgo_GetInPlaceAPI.hxx"
63 #include "GEOMAlgo_GlueDetector.hxx"
65 #include <utilities.h>
67 #include <BRepAdaptor_Curve.hxx>
68 #include <BRepAdaptor_Surface.hxx>
69 #include <BRepTools.hxx>
70 #include <BRep_Builder.hxx>
71 #include <BRep_Tool.hxx>
72 #include <GeomLib_Tool.hxx>
73 #include <Geom_CylindricalSurface.hxx>
74 #include <Geom_Plane.hxx>
75 #include <Geom_SphericalSurface.hxx>
76 #include <Geom_Surface.hxx>
77 #include <Precision.hxx>
78 #include <TColStd_HArray1OfInteger.hxx>
79 #include <TDF_Tool.hxx>
80 #include <TDataStd_Integer.hxx>
81 #include <TDataStd_ListIteratorOfListOfExtendedString.hxx>
83 #include <TopExp_Explorer.hxx>
84 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
85 #include <TopTools_IndexedMapOfShape.hxx>
86 #include <TopTools_ListIteratorOfListOfShape.hxx>
87 #include <TopTools_MapOfOrientedShape.hxx>
88 #include <TopTools_MapOfShape.hxx>
89 #include <TopTools_SequenceOfShape.hxx>
91 #include <TopoDS_Compound.hxx>
92 #include <TopoDS_Edge.hxx>
93 #include <TopoDS_Face.hxx>
94 #include <TopoDS_Iterator.hxx>
95 #include <TopoDS_Shape.hxx>
96 #include <TopoDS_Solid.hxx>
97 #include <TopoDS_Vertex.hxx>
98 #include <gp_Cylinder.hxx>
103 #include <Standard_Failure.hxx>
104 #include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
108 void AddFlatSubShapes(const TopoDS_Shape& S, TopTools_ListOfShape& L, TopTools_MapOfShape& M)
110 if (S.ShapeType() != TopAbs_COMPOUND) {
114 TopoDS_Iterator It(S, Standard_True, Standard_True);
115 for (; It.More(); It.Next()) {
116 TopoDS_Shape SS = It.Value();
118 AddFlatSubShapes(SS, L, M);
126 const double MAX_TOLERANCE = 1.e-7;
129 * \brief Returns the vertex from theWhere shape that is coincident with
132 * \param theWhere the shape where the coinsident vertex is searched.
133 * \param theVertex the vertex to be searched.
134 * \return the coincident vertex if it is found. Otherwise null object.
136 static TopoDS_Vertex getSameVertex(const TopoDS_Shape &theWhere,
137 const TopoDS_Vertex &theVertex)
139 TopoDS_Vertex aResult;
140 gp_Pnt aPoint = BRep_Tool::Pnt(theVertex);
141 TopExp_Explorer anExp(theWhere, TopAbs_VERTEX);
142 TopTools_MapOfShape aMap;
144 for(; anExp.More(); anExp.Next()) {
145 const TopoDS_Shape &aLocalShape = anExp.Current();
147 if(!aMap.Add(aLocalShape)) {
151 TopoDS_Vertex aVertex = TopoDS::Vertex(aLocalShape);
152 gp_Pnt aPoint2 = BRep_Tool::Pnt(aVertex);
154 if(aPoint.Distance(aPoint2) <= MAX_TOLERANCE) {
162 } // end of namespace
164 //=============================================================================
168 //=============================================================================
169 GEOMImpl_IShapesOperations::GEOMImpl_IShapesOperations (GEOM_Engine* theEngine, int theDocID)
170 : GEOM_IOperations(theEngine, theDocID)
172 MESSAGE("GEOMImpl_IShapesOperations::GEOMImpl_IShapesOperations");
175 //=============================================================================
179 //=============================================================================
180 GEOMImpl_IShapesOperations::~GEOMImpl_IShapesOperations()
182 MESSAGE("GEOMImpl_IShapesOperations::~GEOMImpl_IShapesOperations");
185 //=============================================================================
189 //=============================================================================
190 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeEdge
191 (Handle(GEOM_Object) thePnt1, Handle(GEOM_Object) thePnt2)
195 if (thePnt1.IsNull() || thePnt2.IsNull()) return NULL;
197 //Add a new Edge object
198 Handle(GEOM_Object) anEdge = GetEngine()->AddObject(GetDocID(), GEOM_EDGE);
200 //Add a new Vector function
201 Handle(GEOM_Function) aFunction =
202 anEdge->AddFunction(GEOMImpl_VectorDriver::GetID(), VECTOR_TWO_PNT);
204 //Check if the function is set correctly
205 if (aFunction->GetDriverGUID() != GEOMImpl_VectorDriver::GetID()) return NULL;
207 GEOMImpl_IVector aPI (aFunction);
209 Handle(GEOM_Function) aRef1 = thePnt1->GetLastFunction();
210 Handle(GEOM_Function) aRef2 = thePnt2->GetLastFunction();
211 if (aRef1.IsNull() || aRef2.IsNull()) return NULL;
213 aPI.SetPoint1(aRef1);
214 aPI.SetPoint2(aRef2);
216 //Compute the Edge value
219 if (!GetSolver()->ComputeFunction(aFunction)) {
220 SetErrorCode("Vector driver failed");
224 catch (Standard_Failure) {
225 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
226 SetErrorCode(aFail->GetMessageString());
230 //Make a Python command
231 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdge("
232 << thePnt1 << ", " << thePnt2 << ")";
238 //=============================================================================
240 * MakeEdgeOnCurveByLength
242 //=============================================================================
243 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeEdgeOnCurveByLength
244 (Handle(GEOM_Object) theRefCurve,
245 const Standard_Real theLength,
246 Handle(GEOM_Object) theStartPoint)
250 if (theRefCurve.IsNull()) return NULL;
252 //Add a new Edge object
253 Handle(GEOM_Object) anEdge = GetEngine()->AddObject(GetDocID(), GEOM_EDGE);
255 //Add a new Vector function
256 Handle(GEOM_Function) aFunction =
257 anEdge->AddFunction(GEOMImpl_ShapeDriver::GetID(), EDGE_CURVE_LENGTH);
259 //Check if the function is set correctly
260 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
262 GEOMImpl_IVector aPI (aFunction);
264 Handle(GEOM_Function) aRef1 = theRefCurve->GetLastFunction();
265 if (aRef1.IsNull()) return NULL;
266 aPI.SetPoint1(aRef1);
268 if (!theStartPoint.IsNull()) {
269 Handle(GEOM_Function) aRef2 = theStartPoint->GetLastFunction();
270 aPI.SetPoint2(aRef2);
273 aPI.SetParameter(theLength);
275 //Compute the Edge value
278 if (!GetSolver()->ComputeFunction(aFunction)) {
279 SetErrorCode("Vector driver failed");
283 catch (Standard_Failure) {
284 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
285 SetErrorCode(aFail->GetMessageString());
289 //Make a Python command
290 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdgeOnCurveByLength("
291 << theRefCurve << ", " << theLength << ", " << theStartPoint << ")";
297 //=============================================================================
301 //=============================================================================
302 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeEdgeWire
303 (Handle(GEOM_Object) theWire,
304 const Standard_Real theLinearTolerance,
305 const Standard_Real theAngularTolerance)
309 if (theWire.IsNull()) return NULL;
311 //Add a new Edge object
312 Handle(GEOM_Object) anEdge = GetEngine()->AddObject(GetDocID(), GEOM_EDGE);
314 //Add a new Vector function
315 Handle(GEOM_Function) aFunction =
316 anEdge->AddFunction(GEOMImpl_ShapeDriver::GetID(), EDGE_WIRE);
318 //Check if the function is set correctly
319 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
321 GEOMImpl_IShapes aCI (aFunction);
323 Handle(GEOM_Function) aWire = theWire->GetLastFunction();
325 if (aWire.IsNull()) return NULL;
328 aCI.SetTolerance(theLinearTolerance);
329 aCI.SetAngularTolerance(theAngularTolerance);
331 //Compute the Edge value
334 if (!GetSolver()->ComputeFunction(aFunction)) {
335 SetErrorCode("Shape driver failed");
339 catch (Standard_Failure) {
340 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
341 SetErrorCode(aFail->GetMessageString());
345 const double DEF_LIN_TOL = Precision::Confusion();
346 const double DEF_ANG_TOL = Precision::Angular();
347 //Make a Python command
348 if ( theAngularTolerance == DEF_ANG_TOL ) {
349 if ( theLinearTolerance == DEF_LIN_TOL )
350 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdgeWire("
353 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdgeWire("
354 << theWire << ", " << theLinearTolerance << ")";
357 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdgeWire("
358 << theWire << ", " << theLinearTolerance << ", "
359 << theAngularTolerance << ")";
366 //=============================================================================
370 //=============================================================================
371 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeWire
372 (std::list<Handle(GEOM_Object)> theShapes,
373 const Standard_Real theTolerance)
378 Handle(GEOM_Object) aWire = GetEngine()->AddObject(GetDocID(), GEOM_WIRE);
381 Handle(GEOM_Function) aFunction =
382 aWire->AddFunction(GEOMImpl_ShapeDriver::GetID(), WIRE_EDGES);
383 if (aFunction.IsNull()) return NULL;
385 //Check if the function is set correctly
386 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
388 GEOMImpl_IShapes aCI (aFunction);
389 aCI.SetTolerance(theTolerance);
391 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
394 std::list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
395 for (; it != theShapes.end(); it++) {
396 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
397 if (aRefSh.IsNull()) {
398 SetErrorCode("NULL argument shape for the shape construction");
401 aShapesSeq->Append(aRefSh);
403 aCI.SetShapes(aShapesSeq);
408 if (!GetSolver()->ComputeFunction(aFunction)) {
409 SetErrorCode("Shape driver failed");
413 catch (Standard_Failure) {
414 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
415 SetErrorCode(aFail->GetMessageString());
419 //Make a Python command
420 GEOM::TPythonDump pd (aFunction);
421 pd << aWire << " = geompy.MakeWire([";
424 it = theShapes.begin();
425 if (it != theShapes.end()) {
427 while (it != theShapes.end()) {
428 pd << ", " << (*it++);
431 pd << "], " << theTolerance << ")";
437 //=============================================================================
441 //=============================================================================
442 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFace (Handle(GEOM_Object) theWire,
443 const bool isPlanarWanted)
447 if (theWire.IsNull()) return NULL;
449 //Add a new Face object
450 Handle(GEOM_Object) aFace = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
452 //Add a new Shape function for creation of a face from a wire
453 Handle(GEOM_Function) aFunction =
454 aFace->AddFunction(GEOMImpl_ShapeDriver::GetID(), FACE_WIRE);
455 if (aFunction.IsNull()) return NULL;
457 //Check if the function is set correctly
458 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
460 GEOMImpl_IShapes aCI (aFunction);
462 Handle(GEOM_Function) aRefWire = theWire->GetLastFunction();
464 if (aRefWire.IsNull()) return NULL;
466 aCI.SetBase(aRefWire);
467 aCI.SetIsPlanar(isPlanarWanted);
469 //Compute the Face value
470 Standard_Boolean isWarning = Standard_False;
473 if (!GetSolver()->ComputeFunction(aFunction)) {
474 SetErrorCode("Shape driver failed to compute a face");
478 catch (Standard_Failure) {
479 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
480 SetErrorCode(aFail->GetMessageString());
481 // to provide warning
482 if (!aFunction->GetValue().IsNull()) {
483 isWarning = Standard_True;
489 //Make a Python command
490 GEOM::TPythonDump(aFunction) << aFace << " = geompy.MakeFace("
491 << theWire << ", " << (int)isPlanarWanted << ")";
493 // to provide warning
494 if (!isWarning) SetErrorCode(OK);
498 //=============================================================================
502 //=============================================================================
503 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFaceWires
504 (std::list<Handle(GEOM_Object)> theShapes,
505 const bool isPlanarWanted)
510 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
513 Handle(GEOM_Function) aFunction =
514 aShape->AddFunction(GEOMImpl_ShapeDriver::GetID(), FACE_WIRES);
515 if (aFunction.IsNull()) return NULL;
517 //Check if the function is set correctly
518 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
520 GEOMImpl_IShapes aCI (aFunction);
522 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
525 std::list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
526 for (; it != theShapes.end(); it++) {
527 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
528 if (aRefSh.IsNull()) {
529 SetErrorCode("NULL argument shape for the face construction");
532 aShapesSeq->Append(aRefSh);
534 aCI.SetShapes(aShapesSeq);
536 aCI.SetIsPlanar(isPlanarWanted);
539 Standard_Boolean isWarning = Standard_False;
542 if (!GetSolver()->ComputeFunction(aFunction)) {
543 SetErrorCode("Shape driver failed");
547 catch (Standard_Failure) {
548 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
549 SetErrorCode(aFail->GetMessageString());
550 // to provide warning
551 if (!aFunction->GetValue().IsNull()) {
552 isWarning = Standard_True;
558 //Make a Python command
559 GEOM::TPythonDump pd (aFunction);
560 pd << aShape << " = geompy.MakeFaceWires([";
563 it = theShapes.begin();
564 if (it != theShapes.end()) {
566 while (it != theShapes.end()) {
567 pd << ", " << (*it++);
570 pd << "], " << (int)isPlanarWanted << ")";
572 // to provide warning
573 if (!isWarning) SetErrorCode(OK);
577 //=============================================================================
579 * MakeFaceFromSurface
581 //=============================================================================
582 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFaceFromSurface
583 (Handle(GEOM_Object) theFace,
584 Handle(GEOM_Object) theWire)
589 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
592 Handle(GEOM_Function) aFunction =
593 aShape->AddFunction(GEOMImpl_ShapeDriver::GetID(), FACE_FROM_SURFACE);
595 if (aFunction.IsNull()) {
599 //Check if the function is set correctly
600 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) {
604 GEOMImpl_IShapes aCI (aFunction);
605 Handle(TColStd_HSequenceOfTransient) aShapesSeq =
606 new TColStd_HSequenceOfTransient;
607 Handle(GEOM_Function) aRefFace = theFace->GetLastFunction();
608 Handle(GEOM_Function) aRefWire = theWire->GetLastFunction();
610 if (aRefFace.IsNull()) {
611 SetErrorCode("NULL argument face for the face construction");
615 if (aRefWire.IsNull()) {
616 SetErrorCode("NULL argument wire for the face construction");
620 aShapesSeq->Append(aRefFace);
621 aShapesSeq->Append(aRefWire);
623 aCI.SetShapes(aShapesSeq);
628 if (!GetSolver()->ComputeFunction(aFunction)) {
629 SetErrorCode("Shape driver failed");
633 catch (Standard_Failure) {
634 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
635 SetErrorCode(aFail->GetMessageString());
639 //Make a Python command
640 GEOM::TPythonDump (aFunction) << aShape
641 << " = geompy.MakeFaceFromSurface(" << theFace << ", " << theWire << ")";
648 //=============================================================================
650 * MakeFaceWithConstraints
652 //=============================================================================
653 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFaceWithConstraints
654 (std::list<Handle(GEOM_Object)> theConstraints)
659 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_FILLING);
662 Handle(GEOM_Function) aFunction =
663 aShape->AddFunction(GEOMImpl_FillingDriver::GetID(), FILLING_ON_CONSTRAINTS);
664 if (aFunction.IsNull()) return NULL;
666 //Check if the function is set correctly
667 if (aFunction->GetDriverGUID() != GEOMImpl_FillingDriver::GetID()) return NULL;
669 GEOMImpl_IFilling aCI (aFunction);
670 Handle(TColStd_HSequenceOfTransient) aConstraints = new TColStd_HSequenceOfTransient;
673 std::list<Handle(GEOM_Object)>::iterator it = theConstraints.begin();
674 while (it != theConstraints.end()) {
675 Handle(GEOM_Object) anObject = (*it);
676 if ( anObject.IsNull() || anObject->GetValue().ShapeType() != TopAbs_EDGE ) {
677 SetErrorCode("NULL argument edge for the face construction");
680 Handle(GEOM_Function) aRefSh = anObject->GetLastFunction();
681 aConstraints->Append(aRefSh);
683 if ( it != theConstraints.end() ) {
684 Handle(GEOM_Object) aFace = (*it);
685 if ( aFace.IsNull() ) {
686 // null constraint face - it is a valid case
690 if ( aFace->GetValue().ShapeType() != TopAbs_FACE )
691 // constraint face can be omitted - it is a valid case
693 if ( IsSubShapeBelongsTo( anObject, 0, aFace, 0 ) ) {
695 aRefSh = aFace->GetLastFunction();
696 aConstraints->Append(aRefSh);
701 SetErrorCode("Face is NULL or not connected to the Edge");
706 aCI.SetShapes( aConstraints );
709 Standard_Boolean isWarning = Standard_False;
712 if (!GetSolver()->ComputeFunction(aFunction)) {
713 SetErrorCode("Shape driver failed");
717 catch (Standard_Failure) {
718 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
719 SetErrorCode(aFail->GetMessageString());
720 // to provide warning
721 if (!aFunction->GetValue().IsNull()) {
722 isWarning = Standard_True;
728 //Make a Python command
729 GEOM::TPythonDump pd (aFunction);
730 pd << aShape << " = geompy.MakeFaceWithConstraints([";
733 it = theConstraints.begin();
734 if (it != theConstraints.end() ) {
736 while (it != theConstraints.end()) {
737 Handle(GEOM_Object) anObject = (*it++);
738 if( !anObject.IsNull() )
739 pd << ", " << anObject;
744 // to provide warning
745 if (!isWarning) SetErrorCode(OK);
749 //=============================================================================
753 //=============================================================================
754 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeShell
755 (std::list<Handle(GEOM_Object)> theShapes)
757 return MakeShape(theShapes, GEOM_SHELL, SHELL_FACES, "MakeShell");
760 //=============================================================================
764 //=============================================================================
765 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeSolidShells
766 (std::list<Handle(GEOM_Object)> theShapes)
768 return MakeShape(theShapes, GEOM_SOLID, SOLID_SHELLS, "MakeSolid");
771 //=============================================================================
775 //=============================================================================
776 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeCompound
777 (std::list<Handle(GEOM_Object)> theShapes)
779 return MakeShape(theShapes, GEOM_COMPOUND, COMPOUND_SHAPES, "MakeCompound");
782 //=============================================================================
786 //=============================================================================
787 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeShape
788 (std::list<Handle(GEOM_Object)> theShapes,
789 const Standard_Integer theObjectType,
790 const Standard_Integer theFunctionType,
791 const TCollection_AsciiString& theMethodName)
796 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), theObjectType);
799 Handle(GEOM_Function) aFunction =
800 aShape->AddFunction(GEOMImpl_ShapeDriver::GetID(), theFunctionType);
801 if (aFunction.IsNull()) return NULL;
803 //Check if the function is set correctly
804 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
806 GEOMImpl_IShapes aCI (aFunction);
808 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
811 std::list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
812 for (; it != theShapes.end(); it++) {
813 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
814 if (aRefSh.IsNull()) {
815 SetErrorCode("NULL argument shape for the shape construction");
818 aShapesSeq->Append(aRefSh);
820 aCI.SetShapes(aShapesSeq);
825 if (!GetSolver()->ComputeFunction(aFunction)) {
826 SetErrorCode("Shape driver failed");
830 catch (Standard_Failure) {
831 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
832 SetErrorCode(aFail->GetMessageString());
836 //Make a Python command
837 GEOM::TPythonDump pd (aFunction);
838 pd << aShape << " = geompy." << theMethodName.ToCString() << "([";
841 it = theShapes.begin();
842 if (it != theShapes.end()) {
844 while (it != theShapes.end()) {
845 pd << ", " << (*it++);
854 //=============================================================================
856 * MakeSolidFromConnectedFaces
858 //=============================================================================
859 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeSolidFromConnectedFaces
860 (std::list<Handle(GEOM_Object)> theFacesOrShells,
861 const Standard_Boolean isIntersect)
866 Handle(GEOM_Object) aSolid = GetEngine()->AddObject(GetDocID(), GEOM_SOLID);
869 Handle(GEOM_Function) aFunction =
870 aSolid->AddFunction(GEOMImpl_ShapeDriver::GetID(), SOLID_FACES);
871 if (aFunction.IsNull()) return NULL;
873 //Check if the function is set correctly
874 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
876 GEOMImpl_IShapes aCI (aFunction);
878 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
881 std::list<Handle(GEOM_Object)>::iterator it = theFacesOrShells.begin();
882 for (; it != theFacesOrShells.end(); it++) {
883 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
884 if (aRefSh.IsNull()) {
885 SetErrorCode("NULL argument shape for the shape construction");
888 aShapesSeq->Append(aRefSh);
890 aCI.SetShapes(aShapesSeq);
891 aCI.SetIsIntersect(isIntersect);
896 if (!GetSolver()->ComputeFunction(aFunction)) {
897 SetErrorCode("Shape driver failed");
901 catch (Standard_Failure) {
902 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
903 SetErrorCode(aFail->GetMessageString());
907 //Make a Python command
908 GEOM::TPythonDump pd (aFunction);
909 pd << aSolid << " = geompy.MakeSolidFromConnectedFaces([";
912 it = theFacesOrShells.begin();
913 if (it != theFacesOrShells.end()) {
915 while (it != theFacesOrShells.end()) {
916 pd << ", " << (*it++);
919 pd << "]," << (isIntersect ? "True" : "False") << ")";
925 //=============================================================================
929 //=============================================================================
931 GEOMImpl_IShapesOperations::MakeGlueFaces (std::list< Handle(GEOM_Object) >& theShapes,
932 const Standard_Real theTolerance,
933 const Standard_Boolean doKeepNonSolids)
937 Handle(TColStd_HSequenceOfTransient) objects = GEOM_Object::GetLastFunctions( theShapes );
938 if ( objects.IsNull() || objects->IsEmpty() ) {
939 SetErrorCode("NULL argument shape");
943 //Add a new Glued object
944 Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
946 //Add a new Glue function
947 Handle(GEOM_Function) aFunction;
948 aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_FACES);
949 if (aFunction.IsNull()) return NULL;
951 //Check if the function is set correctly
952 if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
954 GEOMImpl_IGlue aCI (aFunction);
956 aCI.SetBase( objects );
957 aCI.SetTolerance(theTolerance);
958 aCI.SetKeepNonSolids(doKeepNonSolids);
960 //Compute the sub-shape value
961 Standard_Boolean isWarning = Standard_False;
964 if (!GetSolver()->ComputeFunction(aFunction)) {
965 SetErrorCode("Shape driver failed to glue faces");
969 catch (Standard_Failure) {
970 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
971 SetErrorCode(aFail->GetMessageString());
972 // to provide warning
973 if (!aFunction->GetValue().IsNull()) {
974 isWarning = Standard_True;
980 //Make a Python command
981 GEOM::TPythonDump(aFunction) << aGlued << " = geompy.MakeGlueFaces("
982 << theShapes << ", " << theTolerance << ")";
984 // to provide warning
985 if (!isWarning) SetErrorCode(OK);
989 //=============================================================================
993 //=============================================================================
995 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetGlueFaces
996 (Handle(GEOM_Object) theShape,
997 const Standard_Real theTolerance)
1001 if (theShape.IsNull()) return NULL;
1002 TopoDS_Shape aShape = theShape->GetValue();
1003 if (aShape.IsNull()) return NULL;
1005 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1007 Standard_Integer iErr;
1009 GEOMAlgo_Gluer1 aGluer;
1010 GEOMAlgo_ListIteratorOfListOfCoupleOfShapes aItCS;
1011 GEOMAlgo_CoupleOfShapes aCS;
1012 GEOMAlgo_ListOfCoupleOfShapes aLCS;
1014 //aGluer = new GEOMAlgo_Gluer1;
1015 aGluer.SetShape(aShape);
1016 aGluer.SetTolerance(theTolerance);
1018 iErr = aGluer.ErrorStatus();
1019 if (iErr) return NULL;
1021 TopTools_ListOfShape listShape;
1022 const GEOMAlgo_ListOfCoupleOfShapes& aLCSG = aGluer.GluedFaces();
1024 aItCS.Initialize(aLCSG);
1025 for (; aItCS.More(); aItCS.Next()) {
1026 const GEOMAlgo_CoupleOfShapes& aCSG = aItCS.Value();
1027 listShape.Append(aCSG.Shape1());
1030 TopTools_ListIteratorOfListOfShape itSub (listShape);
1031 TCollection_AsciiString anAsciiList, anEntry;
1032 TopTools_IndexedMapOfShape anIndices;
1033 TopExp::MapShapes(aShape, anIndices);
1034 Handle(TColStd_HArray1OfInteger) anArray;
1035 Handle(GEOM_Object) anObj;
1036 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
1037 TopoDS_Shape aValue = itSub.Value();
1038 anArray = new TColStd_HArray1OfInteger(1,1);
1039 anArray->SetValue(1, anIndices.FindIndex(aValue));
1040 anObj = GetEngine()->AddSubShape(theShape, anArray);
1041 if (!anObj.IsNull()) {
1042 aSeq->Append(anObj);
1044 // for python command
1045 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
1046 anAsciiList += anEntry;
1051 //Make a Python command
1052 if( anAsciiList.Length() > 0 ) {
1053 anAsciiList.Trunc(anAsciiList.Length() - 1);
1054 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
1055 GEOM::TPythonDump pd (aFunction, true);
1056 pd << "[" << anAsciiList.ToCString();
1057 pd << "] = geompy.GetGlueFaces(" << theShape << ", " << theTolerance << ")";
1066 //=============================================================================
1068 * MakeGlueFacesByList
1070 //=============================================================================
1072 GEOMImpl_IShapesOperations::MakeGlueFacesByList(std::list< Handle(GEOM_Object) >& theShapes,
1073 const Standard_Real theTolerance,
1074 std::list<Handle(GEOM_Object)> & theFaces,
1075 const Standard_Boolean doKeepNonSolids,
1076 const Standard_Boolean doGlueAllEdges)
1080 Handle(TColStd_HSequenceOfTransient) objects = GEOM_Object::GetLastFunctions( theShapes );
1081 if ( objects.IsNull() || objects->IsEmpty() ) {
1082 SetErrorCode("NULL argument shape");
1085 Handle(TColStd_HSequenceOfTransient) aFaces = GEOM_Object::GetLastFunctions( theFaces );
1086 if ( aFaces.IsNull() ) {
1087 SetErrorCode("NULL argument shape for the shape construction");
1091 //Add a new Glued object
1092 Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
1094 //Add a new Glue function
1095 Handle(GEOM_Function) aFunction;
1096 aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_FACES_BY_LIST);
1097 if (aFunction.IsNull()) return NULL;
1099 //Check if the function is set correctly
1100 if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
1102 GEOMImpl_IGlue aCI (aFunction);
1104 aCI.SetBase( objects );
1105 aCI.SetTolerance(theTolerance);
1106 aCI.SetKeepNonSolids(doKeepNonSolids);
1107 aCI.SetGlueAllEdges(doGlueAllEdges);
1108 aCI.SetFaces(aFaces);
1110 //Compute the sub-shape value
1111 Standard_Boolean isWarning = Standard_False;
1114 if (!GetSolver()->ComputeFunction(aFunction)) {
1115 SetErrorCode("Shape driver failed to glue faces");
1119 catch (Standard_Failure) {
1120 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1121 SetErrorCode(aFail->GetMessageString());
1122 // to provide warning
1123 if (!aFunction->GetValue().IsNull()) {
1124 isWarning = Standard_True;
1130 //Make a Python command
1132 GEOM::TPythonDump pd(aFunction);
1133 pd << aGlued << " = geompy.MakeGlueFacesByList("
1134 << theShapes << ", " << theTolerance << ", " << theFaces << ", "
1135 << (bool)doKeepNonSolids << ", " << (bool)doGlueAllEdges << ")";
1137 // to provide warning
1138 if (!isWarning) SetErrorCode(OK);
1142 //=============================================================================
1146 //=============================================================================
1148 GEOMImpl_IShapesOperations::MakeGlueEdges (std::list< Handle(GEOM_Object) >& theShapes,
1149 const Standard_Real theTolerance)
1153 Handle(TColStd_HSequenceOfTransient) objects = GEOM_Object::GetLastFunctions( theShapes );
1154 if ( objects.IsNull() || objects->IsEmpty() ) {
1155 SetErrorCode("NULL argument shape");
1159 //Add a new Glued object
1160 Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
1162 //Add a new Glue function
1163 Handle(GEOM_Function) aFunction;
1164 aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_EDGES);
1165 if (aFunction.IsNull()) return NULL;
1167 //Check if the function is set correctly
1168 if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
1170 GEOMImpl_IGlue aCI (aFunction);
1172 aCI.SetBase( objects );
1173 aCI.SetTolerance(theTolerance);
1174 aCI.SetKeepNonSolids(true);
1176 //Compute the sub-shape value
1177 Standard_Boolean isWarning = Standard_False;
1180 if (!GetSolver()->ComputeFunction(aFunction)) {
1181 SetErrorCode("Shape driver failed to glue edges");
1185 catch (Standard_Failure) {
1186 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1187 SetErrorCode(aFail->GetMessageString());
1188 // to provide warning
1189 if (!aFunction->GetValue().IsNull()) {
1190 isWarning = Standard_True;
1196 //Make a Python command
1197 GEOM::TPythonDump(aFunction) << aGlued << " = geompy.MakeGlueEdges("
1198 << theShapes << ", " << theTolerance << ")";
1200 // to provide warning
1201 if (!isWarning) SetErrorCode(OK);
1205 //=============================================================================
1209 //=============================================================================
1210 Handle(TColStd_HSequenceOfTransient)
1211 GEOMImpl_IShapesOperations::GetGlueShapes (std::list< Handle(GEOM_Object) >& theShapes,
1212 const Standard_Real theTolerance,
1213 const TopAbs_ShapeEnum theType)
1217 TopoDS_Shape aShape;
1218 TopTools_SequenceOfShape shapes;
1219 std::list< Handle(GEOM_Object) >::iterator s = theShapes.begin();
1220 Handle(GEOM_Object) lastCreatedGO;
1221 for ( ; s != theShapes.end(); ++s )
1223 Handle(GEOM_Object) go = *s;
1224 if ( go.IsNull() ) return NULL;
1225 aShape = go->GetValue();
1226 if ( aShape.IsNull() ) return NULL;
1227 shapes.Append( aShape );
1228 lastCreatedGO = GEOM::GetCreatedLast( lastCreatedGO, go );
1230 if ( shapes.Length() > 1 )
1232 TopoDS_Compound compound;
1233 BRep_Builder builder;
1234 builder.MakeCompound( compound );
1235 for ( int i = 1; i <= shapes.Length(); ++i )
1236 builder.Add( compound, shapes( i ) );
1241 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1243 GEOMAlgo_GlueDetector aGluer;
1244 aGluer.SetArgument(aShape);
1245 aGluer.SetTolerance(theTolerance);
1247 Standard_Integer iErr = aGluer.ErrorStatus();
1248 if (iErr) return NULL;
1250 std::vector< TopTools_IndexedMapOfShape* > anIndices( shapes.Length(), NULL );
1251 Handle(TColStd_HArray1OfInteger) anArray;
1252 Handle(GEOM_Object) anObj;
1254 TopTools_ListOfShape listOnePerSet;
1256 const TopTools_DataMapOfShapeListOfShape& aImages = aGluer.Images();
1257 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape aItDMSLS (aImages);
1258 for (int index = 1; aItDMSLS.More(); aItDMSLS.Next(), ++index) {
1260 //const TopoDS_Shape& aSkey = aItDMSLS.Key();
1262 // list of shapes of the argument that can be glued
1263 const TopTools_ListOfShape& aLSD = aItDMSLS.Value();
1265 //listShape.Append(aLSD.First());
1266 TopoDS_Shape aValue = aLSD.First();
1268 if (aValue.ShapeType() == theType) {
1269 listOnePerSet.Append(aValue);
1273 // for stable order of returned entities
1274 GEOMUtils::SortShapes(listOnePerSet, Standard_False);
1276 TopTools_ListIteratorOfListOfShape aListIt (listOnePerSet);
1277 for (; aListIt.More(); aListIt.Next())
1279 TopoDS_Shape aValue = aListIt.Value();
1280 // find a shape to add aValue as a sub-shape
1282 s = theShapes.begin();
1283 for ( int i = 0; i < shapes.Length(); ++i, ++s )
1285 Handle(GEOM_Object) object = *s;
1286 if ( !anIndices[i] ) {
1287 anIndices[i] = new TopTools_IndexedMapOfShape;
1288 TopExp::MapShapes( object->GetValue(), *anIndices[i]);
1290 if (int index = anIndices[i]->FindIndex( aValue )) {
1291 anArray = new TColStd_HArray1OfInteger(1,1);
1292 anArray->SetValue(1, index);
1293 anObj = GetEngine()->AddSubShape( object, anArray);
1297 if (!anObj.IsNull())
1298 aSeq->Append(anObj);
1300 for ( size_t i = 0 ; i < anIndices.size(); ++i )
1301 delete anIndices[i];
1303 // Make a Python command
1304 if ( aSeq->Length() > 0)
1306 Handle(GEOM_Function) aFunction = lastCreatedGO->GetLastFunction();
1307 GEOM::TPythonDump pd (aFunction, /*append=*/true);
1309 << " = geompy." << (theType == TopAbs_FACE ? "GetGlueFaces" : "GetGlueEdges" )
1310 << "( " << theShapes << ", " << theTolerance << ")";
1318 //=============================================================================
1320 * MakeGlueEdgesByList
1322 //=============================================================================
1324 GEOMImpl_IShapesOperations::MakeGlueEdgesByList (std::list< Handle(GEOM_Object) >& theShapes,
1325 const Standard_Real theTolerance,
1326 std::list<Handle(GEOM_Object)>& theEdges)
1330 Handle(TColStd_HSequenceOfTransient) objects = GEOM_Object::GetLastFunctions( theShapes );
1331 if ( objects.IsNull() || objects->IsEmpty() ) {
1332 SetErrorCode("NULL argument shape");
1335 Handle(TColStd_HSequenceOfTransient) anEdges = GEOM_Object::GetLastFunctions( theEdges );
1336 if ( anEdges.IsNull() ) {
1337 SetErrorCode("NULL argument shape for the shape construction");
1340 //Add a new Glued object
1341 Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
1343 //Add a new Glue function
1344 Handle(GEOM_Function) aFunction;
1345 aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_EDGES_BY_LIST);
1346 if (aFunction.IsNull()) return NULL;
1348 //Check if the function is set correctly
1349 if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
1351 GEOMImpl_IGlue aCI (aFunction);
1353 aCI.SetBase( objects );
1354 aCI.SetTolerance(theTolerance);
1355 aCI.SetKeepNonSolids(true);
1356 aCI.SetFaces(anEdges);
1358 //Compute the sub-shape value
1359 Standard_Boolean isWarning = Standard_False;
1362 if (!GetSolver()->ComputeFunction(aFunction)) {
1363 SetErrorCode("Shape driver failed to glue edges");
1367 catch (Standard_Failure) {
1368 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1369 SetErrorCode(aFail->GetMessageString());
1370 // to provide warning
1371 if (!aFunction->GetValue().IsNull()) {
1372 isWarning = Standard_True;
1378 //Make a Python command
1380 GEOM::TPythonDump pd (aFunction);
1381 pd << aGlued << " = geompy.MakeGlueEdgesByList("
1382 << theShapes << ", " << theTolerance << ", " << theEdges << " )";
1384 // to provide warning
1385 if (!isWarning) SetErrorCode(OK);
1389 //=============================================================================
1391 * GetExistingSubObjects
1393 //=============================================================================
1394 Handle(TColStd_HSequenceOfTransient)
1395 GEOMImpl_IShapesOperations::GetExistingSubObjects(Handle(GEOM_Object) theShape,
1396 const Standard_Boolean theGroupsOnly)
1398 // note: this method does not return fields
1400 Standard_Integer types = theGroupsOnly ? Groups : Groups|SubShapes;
1401 Handle(TColStd_HSequenceOfTransient) results = GetExistingSubObjects(theShape, types);
1403 if (results->Length() > 0) {
1404 //Make a Python command
1405 TCollection_AsciiString anAsciiList;
1406 for (int i = 1; i <= results->Length(); i++)
1408 Handle(GEOM_BaseObject) obj = Handle(GEOM_BaseObject)::DownCast( results->Value(i));
1409 obj->GetEntryString();
1410 if ( i < results->Length() )
1414 GEOM::TPythonDump pd (theShape->GetLastFunction(), /*append=*/true);
1415 pd << "[" << anAsciiList.ToCString();
1416 pd << "] = geompy.GetExistingSubObjects(";
1417 pd << theShape << ", " << (bool)theGroupsOnly << ")";
1423 Handle(TColStd_HSequenceOfTransient)
1424 GEOMImpl_IShapesOperations::GetExistingSubObjects(Handle(GEOM_Object) theShape,
1425 const Standard_Integer theTypes)
1429 if (theShape.IsNull()) return NULL;
1431 Handle(GEOM_Function) aMainShape = theShape->GetLastFunction();
1432 if (aMainShape.IsNull()) return NULL;
1434 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1435 SetErrorCode(NOT_FOUND_ANY);
1437 if (!aMainShape->HasSubShapeReferences()) return aSeq;
1438 const TDataStd_ListOfExtendedString& aListEntries = aMainShape->GetSubShapeReferences();
1439 if (aListEntries.IsEmpty()) return aSeq;
1443 TDataStd_ListIteratorOfListOfExtendedString anIt (aListEntries);
1444 for (; anIt.More(); anIt.Next()) {
1445 TCollection_ExtendedString anEntry = anIt.Value();
1446 Standard_Integer aStrLen = anEntry.LengthOfCString();
1447 char* anEntryStr = new char[aStrLen+1];
1448 anEntry.ToUTF8CString(anEntryStr);
1449 Handle(GEOM_BaseObject) anObj = GetEngine()->GetObject(GetDocID(), anEntryStr, false);
1450 if (!anObj.IsNull() ) {
1451 bool isGroup = anObj->IsKind(STANDARD_TYPE(GEOM_Object)) && anObj->GetType() == GEOM_GROUP;
1452 bool isSubShape = anObj->IsKind(STANDARD_TYPE(GEOM_Object)) && anObj->GetType() != GEOM_GROUP;
1453 bool isField = anObj->IsKind(STANDARD_TYPE(GEOM_Field));
1454 if (theTypes & Groups && isGroup ||
1455 theTypes & SubShapes && isSubShape ||
1456 theTypes & Fields && isField) {
1457 aSeq->Append(anObj);
1460 delete [] anEntryStr;
1463 if (aSeq->Length() == 0) {
1464 SetErrorCode(NOT_FOUND_ANY);
1473 //=============================================================================
1477 //=============================================================================
1478 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::MakeExplode
1479 (Handle(GEOM_Object) theShape,
1480 const Standard_Integer theShapeType,
1481 const Standard_Boolean isSorted,
1482 const ExplodeType theExplodeType)
1486 if (theShape.IsNull()) return NULL;
1487 TopoDS_Shape aShape = theShape->GetValue();
1488 if (aShape.IsNull()) return NULL;
1490 Handle(GEOM_Function) aMainShape = theShape->GetLastFunction();
1492 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1493 Handle(GEOM_Object) anObj;
1494 TopTools_MapOfShape mapShape;
1495 TopTools_ListOfShape listShape;
1497 if (aShape.ShapeType() == TopAbs_COMPOUND &&
1498 (theShapeType == TopAbs_SHAPE || theShapeType == TopAbs_FLAT || theShapeType == TopAbs_COMPOUND))
1500 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
1501 for (; It.More(); It.Next()) {
1502 TopoDS_Shape SS = It.Value();
1503 if (mapShape.Add(SS)) {
1504 if (theShapeType == TopAbs_FLAT) {
1505 AddFlatSubShapes(SS, listShape, mapShape);
1507 else if (theShapeType == TopAbs_SHAPE || theShapeType == SS.ShapeType()) {
1508 listShape.Append(SS);
1510 // VSR: for EXPLODE_NEW_INCLUDE_MAIN and EXPLODE_OLD_INCLUDE_MAIN:
1511 // it seems it is necessary to add top-level shape if theShapeType == TopAbs_COMPOUND
1515 else if (theExplodeType != EXPLODE_NEW_EXCLUDE_MAIN || aShape.ShapeType() != theShapeType) // issue 0021079
1517 TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
1518 for (; exp.More(); exp.Next())
1519 if (mapShape.Add(exp.Current()))
1520 listShape.Append(exp.Current());
1523 if (listShape.IsEmpty()){
1524 //SetErrorCode("The given shape has no sub-shapes of the requested type");
1525 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
1530 bool isOldSorting = false;
1531 if (theExplodeType == EXPLODE_OLD_INCLUDE_MAIN)
1532 isOldSorting = true;
1533 GEOMUtils::SortShapes(listShape, isOldSorting);
1536 TopTools_IndexedMapOfShape anIndices;
1537 TopExp::MapShapes(aShape, anIndices);
1538 Handle(TColStd_HArray1OfInteger) anArray;
1540 TopTools_ListIteratorOfListOfShape itSub (listShape);
1541 TCollection_AsciiString anAsciiList, anEntry;
1542 for (int index = 1; itSub.More(); itSub.Next(), ++index)
1544 TopoDS_Shape aValue = itSub.Value();
1545 anArray = new TColStd_HArray1OfInteger(1,1);
1546 anArray->SetValue(1, anIndices.FindIndex(aValue));
1548 //anObj = GetEngine()->AddSubShape(theShape, anArray);
1550 anObj = GetEngine()->AddObject(GetDocID(), GEOM_SUBSHAPE);
1551 Handle(GEOM_Function) aFunction = anObj->AddFunction(GEOM_Object::GetSubShapeID(), 1);
1552 if (aFunction.IsNull()) return aSeq;
1554 GEOM_ISubShape aSSI (aFunction);
1555 aSSI.SetMainShape(aMainShape);
1556 aSSI.SetIndices(anArray);
1558 // Set function value directly, as we know it.
1559 // Usage of Solver here would lead to significant loss of time,
1560 // because GEOM_SubShapeDriver will build TopTools_IndexedMapOfShape
1561 // on the main shape for each being calculated sub-shape separately.
1562 aFunction->SetValue(aValue);
1564 // Put this subshape in the list of sub-shapes of theMainShape
1565 aMainShape->AddSubShapeReference(aFunction);
1567 if (!anObj.IsNull()) {
1568 aSeq->Append(anObj);
1570 // for python command
1571 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
1572 anAsciiList += anEntry;
1577 //Make a Python command
1578 anAsciiList.Trunc(anAsciiList.Length() - 1);
1580 GEOM::TPythonDump pd (aMainShape, /*append=*/true);
1581 pd << "[" << anAsciiList.ToCString() << "] = geompy.";
1582 switch (theExplodeType) {
1583 case EXPLODE_NEW_EXCLUDE_MAIN:
1584 pd << "ExtractShapes(" << theShape << ", "
1585 << TopAbs_ShapeEnum(theShapeType) << ", " << (isSorted ? "True" : "False") << ")";
1587 case EXPLODE_NEW_INCLUDE_MAIN:
1588 pd << "SubShapeAll" << (isSorted ? "SortedCentres(" : "(")
1589 << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
1591 case EXPLODE_OLD_INCLUDE_MAIN:
1592 pd << "SubShapeAll" << (isSorted ? "Sorted(" : "(")
1593 << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
1602 //=============================================================================
1606 //=============================================================================
1607 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::SubShapeAllIDs
1608 (Handle(GEOM_Object) theShape,
1609 const Standard_Integer theShapeType,
1610 const Standard_Boolean isSorted,
1611 const ExplodeType theExplodeType)
1615 if (theShape.IsNull()) return NULL;
1616 TopoDS_Shape aShape = theShape->GetValue();
1617 if (aShape.IsNull()) return NULL;
1619 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
1620 TopTools_MapOfShape mapShape;
1621 TopTools_ListOfShape listShape;
1623 if (aShape.ShapeType() == TopAbs_COMPOUND &&
1624 (theShapeType == TopAbs_SHAPE || theShapeType == TopAbs_FLAT || theShapeType == TopAbs_COMPOUND))
1626 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
1627 for (; It.More(); It.Next()) {
1628 TopoDS_Shape SS = It.Value();
1629 if (mapShape.Add(SS)) {
1630 if (theShapeType == TopAbs_FLAT) {
1631 AddFlatSubShapes(SS, listShape, mapShape);
1633 else if (theShapeType == TopAbs_SHAPE || theShapeType == SS.ShapeType()) {
1634 listShape.Append(SS);
1639 else if (theExplodeType != EXPLODE_NEW_EXCLUDE_MAIN || aShape.ShapeType() != theShapeType) // issue 0021079
1641 TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
1642 for (; exp.More(); exp.Next())
1643 if (mapShape.Add(exp.Current()))
1644 listShape.Append(exp.Current());
1647 if (listShape.IsEmpty()) {
1648 //SetErrorCode("The given shape has no sub-shapes of the requested type");
1649 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
1654 bool isOldSorting = false;
1655 if (theExplodeType == EXPLODE_OLD_INCLUDE_MAIN)
1656 isOldSorting = true;
1657 GEOMUtils::SortShapes(listShape, isOldSorting);
1660 TopTools_IndexedMapOfShape anIndices;
1661 TopExp::MapShapes(aShape, anIndices);
1662 Handle(TColStd_HArray1OfInteger) anArray;
1664 TopTools_ListIteratorOfListOfShape itSub (listShape);
1665 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
1666 TopoDS_Shape aValue = itSub.Value();
1667 aSeq->Append(anIndices.FindIndex(aValue));
1670 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
1672 //Make a Python command
1673 GEOM::TPythonDump pd (aFunction, /*append=*/true);
1674 pd << "listSubShapeIDs = geompy.SubShapeAll";
1675 switch (theExplodeType) {
1676 case EXPLODE_NEW_EXCLUDE_MAIN:
1678 case EXPLODE_NEW_INCLUDE_MAIN:
1679 pd << (isSorted ? "SortedCentresIDs(" : "IDs(")
1680 << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
1682 case EXPLODE_OLD_INCLUDE_MAIN:
1683 pd << (isSorted ? "SortedIDs(" : "IDs(")
1684 << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
1693 //=============================================================================
1697 //=============================================================================
1698 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetSubShape
1699 (Handle(GEOM_Object) theMainShape,
1700 const Standard_Integer theID)
1704 if (theMainShape.IsNull()) return NULL;
1706 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
1707 anArray->SetValue(1, theID);
1708 Handle(GEOM_Object) anObj = GetEngine()->AddSubShape(theMainShape, anArray,true);
1709 if (anObj.IsNull()) {
1710 SetErrorCode("Can not get a sub-shape with the given ID");
1714 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1716 //Make a Python command
1717 GEOM::TPythonDump(aFunction) << anObj << " = geompy.GetSubShape("
1718 << theMainShape << ", [" << theID << "])";
1724 //=============================================================================
1728 //=============================================================================
1729 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::MakeSubShapes
1730 (Handle(GEOM_Object) theMainShape,
1731 Handle(TColStd_HArray1OfInteger) theIndices)
1735 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1737 if (!theIndices->Length()) {
1738 SetErrorCode(NOT_FOUND_ANY);
1742 if (theMainShape.IsNull()) return NULL;
1743 TopoDS_Shape aShape = theMainShape->GetValue();
1744 if (aShape.IsNull()) return NULL;
1746 Handle(GEOM_Function) aMainShape = theMainShape->GetLastFunction();
1748 TopTools_IndexedMapOfShape anIndices;
1749 TopExp::MapShapes(aShape, anIndices);
1751 Handle(TColStd_HArray1OfInteger) anArray;
1752 Handle(GEOM_Object) anObj;
1754 TCollection_AsciiString anAsciiList, anEntry;
1755 Standard_Integer i, low = theIndices->Lower(), up = theIndices->Upper();
1756 for (i = low; i <= up; i++) {
1757 int id = theIndices->Value(i);
1758 if (1 <= id && id <= anIndices.Extent()) {
1759 TopoDS_Shape aValue = anIndices.FindKey(id);
1760 anArray = new TColStd_HArray1OfInteger(1,1);
1761 anArray->SetValue(1, id);
1763 anObj = GetEngine()->AddObject(GetDocID(), GEOM_SUBSHAPE);
1764 if (!anObj.IsNull()) {
1765 Handle(GEOM_Function) aFunction = anObj->AddFunction(GEOM_Object::GetSubShapeID(), 1);
1766 if (aFunction.IsNull()) return aSeq;
1768 GEOM_ISubShape aSSI (aFunction);
1769 aSSI.SetMainShape(aMainShape);
1770 aSSI.SetIndices(anArray);
1772 // Set function value directly, as we know it.
1773 // Usage of Solver here would lead to significant loss of time,
1774 // because GEOM_SubShapeDriver will build TopTools_IndexedMapOfShape
1775 // on the main shape for each being calculated sub-shape separately.
1776 aFunction->SetValue(aValue);
1778 // Put this sub-shape in the list of sub-shapes of theMainShape
1779 aMainShape->AddSubShapeReference(aFunction);
1781 aSeq->Append(anObj);
1783 // for python command
1784 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
1785 anAsciiList += anEntry;
1791 //Make a Python command
1792 anAsciiList.Trunc(anAsciiList.Length() - 1);
1794 GEOM::TPythonDump pd (aMainShape, /*append=*/true);
1795 pd << "[" << anAsciiList.ToCString() << "] = geompy.SubShapes("
1796 << theMainShape << ", [" ;
1797 for (i = low; i <= up - 1; i++) {
1798 pd << theIndices->Value(i) << ", ";
1800 pd << theIndices->Value(up) << "])";
1807 //=============================================================================
1811 //=============================================================================
1812 Standard_Integer GEOMImpl_IShapesOperations::GetSubShapeIndex (Handle(GEOM_Object) theMainShape,
1813 Handle(GEOM_Object) theSubShape)
1817 TopoDS_Shape aMainShape = theMainShape->GetValue();
1818 TopoDS_Shape aSubShape = theSubShape->GetValue();
1820 if (aMainShape.IsNull() || aSubShape.IsNull()) return -1;
1822 TopTools_IndexedMapOfShape anIndices;
1823 TopExp::MapShapes(aMainShape, anIndices);
1824 // if (anIndices.Contains(aSubShape)) {
1825 // SetErrorCode(OK);
1826 // return anIndices.FindIndex(aSubShape);
1828 int id = anIndices.FindIndex(aSubShape);
1839 //=============================================================================
1841 * GetSubShapeIndices
1843 //=============================================================================
1844 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetSubShapesIndices (Handle(GEOM_Object) theMainShape,
1845 std::list<Handle(GEOM_Object)> theSubShapes)
1847 MESSAGE("GEOMImpl_IShapesOperations::GetSubShapesIndices")
1850 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
1852 TopoDS_Shape aMainShape = theMainShape->GetValue();
1853 if (aMainShape.IsNull())
1855 MESSAGE("NULL main shape")
1859 TopTools_IndexedMapOfShape anIndices;
1860 TopExp::MapShapes(aMainShape, anIndices);
1862 std::list<Handle(GEOM_Object)>::iterator it;
1863 for (it=theSubShapes.begin(); it != theSubShapes.end(); ++it)
1865 TopoDS_Shape aSubShape = (*it)->GetValue();
1866 if (aSubShape.IsNull())
1868 MESSAGE("NULL subshape")
1871 int id = anIndices.FindIndex(aSubShape);
1880 //=============================================================================
1884 //=============================================================================
1885 Standard_Integer GEOMImpl_IShapesOperations::GetTopologyIndex (Handle(GEOM_Object) theMainShape,
1886 Handle(GEOM_Object) theSubShape)
1890 TopoDS_Shape aMainShape = theMainShape->GetValue();
1891 TopoDS_Shape aSubShape = theSubShape->GetValue();
1893 if (aMainShape.IsNull() || aSubShape.IsNull()) {
1894 SetErrorCode("Null argument shape given");
1899 if (aSubShape.ShapeType() == TopAbs_COMPOUND) {
1901 TopTools_ListOfShape CL;
1902 CL.Append(aMainShape);
1903 TopTools_ListIteratorOfListOfShape itC;
1904 for (itC.Initialize(CL); itC.More(); itC.Next()) {
1905 for (it.Initialize(itC.Value()); it.More(); it.Next()) {
1906 if (it.Value().ShapeType() == TopAbs_COMPOUND) {
1907 if (it.Value().IsSame(aSubShape))
1911 CL.Append(it.Value());
1916 TopExp_Explorer anExp (aMainShape, aSubShape.ShapeType());
1917 TopTools_MapOfShape M;
1918 for (; anExp.More(); anExp.Next()) {
1919 if (M.Add(anExp.Current())) {
1920 if (anExp.Current().IsSame(aSubShape))
1927 SetErrorCode("The sub-shape does not belong to the main shape");
1931 //=============================================================================
1933 * GetShapeTypeString
1935 //=============================================================================
1936 TCollection_AsciiString GEOMImpl_IShapesOperations::GetShapeTypeString (Handle(GEOM_Object) theShape)
1940 TCollection_AsciiString aTypeName ("Null Shape");
1942 TopoDS_Shape aShape = theShape->GetValue();
1943 if (aShape.IsNull())
1946 switch (aShape.ShapeType() )
1948 case TopAbs_COMPOUND:
1949 aTypeName = "Compound";
1951 case TopAbs_COMPSOLID:
1952 aTypeName = "Compound Solid";
1955 aTypeName = "Solid";
1958 aTypeName = "Shell";
1962 BRepAdaptor_Surface surf (TopoDS::Face(aShape));
1963 if (surf.GetType() == GeomAbs_Plane)
1964 aTypeName = "Plane";
1965 else if (surf.GetType() == GeomAbs_Cylinder)
1966 aTypeName = "Cylindrical Face";
1967 else if (surf.GetType() == GeomAbs_Sphere)
1968 aTypeName = "Spherical Face";
1969 else if (surf.GetType() == GeomAbs_Torus)
1970 aTypeName = "Toroidal Face";
1971 else if (surf.GetType() == GeomAbs_Cone)
1972 aTypeName = "Conical Face";
1974 aTypeName = "GEOM::FACE";
1982 BRepAdaptor_Curve curv (TopoDS::Edge(aShape));
1983 if (curv.GetType() == GeomAbs_Line) {
1984 if ((Abs(curv.FirstParameter()) >= 1E6) ||
1985 (Abs(curv.LastParameter()) >= 1E6))
1989 } else if (curv.GetType() == GeomAbs_Circle) {
1990 if (curv.IsClosed())
1991 aTypeName = "Circle";
2000 aTypeName = "Vertex";
2003 aTypeName = "Shape";
2006 aTypeName = "Shape of unknown type";
2012 //=============================================================================
2014 * IsSubShapeBelongsTo
2016 //=============================================================================
2017 Standard_Boolean GEOMImpl_IShapesOperations::IsSubShapeBelongsTo( Handle(GEOM_Object) theSubObject,
2018 const Standard_Integer theSubObjectIndex,
2019 Handle(GEOM_Object) theObject,
2020 const Standard_Integer theObjectIndex)
2022 if ( theObject.IsNull() || theSubObject.IsNull() )
2025 TopoDS_Shape shape = theObject->GetValue();
2026 TopoDS_Shape subShape = theSubObject->GetValue();
2028 if ( shape.IsNull() || subShape.IsNull() )
2031 TopTools_IndexedMapOfShape anIndices;
2032 if ( theObjectIndex > 0 ) {
2033 TopExp::MapShapes( shape, anIndices );
2034 shape = anIndices.FindKey(theObjectIndex);
2036 if ( theSubObjectIndex > 0 ) {
2037 TopExp::MapShapes( subShape, anIndices );
2038 subShape = anIndices.FindKey(theSubObjectIndex);
2041 TopExp::MapShapes( shape, anIndices );
2042 return anIndices.Contains( subShape );
2045 //=============================================================================
2049 //=============================================================================
2050 Standard_Integer GEOMImpl_IShapesOperations::NumberOfSubShapes
2051 (Handle(GEOM_Object) theShape,
2052 const Standard_Integer theShapeType)
2055 Standard_Integer nbShapes = 0;
2057 if (theShape.IsNull()) return -1;
2058 TopoDS_Shape aShape = theShape->GetValue();
2059 if (aShape.IsNull()) return -1;
2062 TopTools_MapOfShape mapShape;
2064 if (aShape.ShapeType() == TopAbs_COMPOUND &&
2065 (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
2066 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPSOLID ||
2067 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPOUND)) {
2068 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
2069 for (; It.More(); It.Next()) {
2070 if (mapShape.Add(It.Value())) {
2071 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
2072 TopAbs_ShapeEnum(theShapeType) == It.Value().ShapeType()) {
2078 TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
2079 for (; exp.More(); exp.Next())
2080 if (mapShape.Add(exp.Current()))
2086 if (theShapeType == TopAbs_FLAT) {
2087 TopTools_MapOfShape aMapOfShape;
2088 TopTools_ListOfShape aListOfShape;
2089 AddFlatSubShapes(aShape, aListOfShape, aMapOfShape);
2090 nbShapes = aListOfShape.Extent();
2094 int iType, nbTypes [TopAbs_SHAPE];
2095 for (iType = 0; iType < TopAbs_SHAPE; ++iType)
2097 nbTypes[aShape.ShapeType()]++;
2099 TopTools_MapOfShape aMapOfShape;
2100 aMapOfShape.Add(aShape);
2101 TopTools_ListOfShape aListOfShape;
2102 aListOfShape.Append(aShape);
2104 TopTools_ListIteratorOfListOfShape itL (aListOfShape);
2105 for (; itL.More(); itL.Next()) {
2106 TopoDS_Iterator it (itL.Value());
2107 for (; it.More(); it.Next()) {
2108 TopoDS_Shape s = it.Value();
2109 if (aMapOfShape.Add(s)) {
2110 aListOfShape.Append(s);
2111 nbTypes[s.ShapeType()]++;
2116 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE)
2117 nbShapes = aMapOfShape.Extent();
2119 nbShapes = nbTypes[theShapeType];
2122 catch (Standard_Failure) {
2123 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2124 SetErrorCode(aFail->GetMessageString());
2132 //=============================================================================
2136 //=============================================================================
2137 Handle(GEOM_Object) GEOMImpl_IShapesOperations::ReverseShape(Handle(GEOM_Object) theShape)
2141 if (theShape.IsNull()) return NULL;
2144 //Add a new reversed object
2145 Handle(GEOM_Object) aReversed = GetEngine()->AddObject(GetDocID(), theShape->GetType());
2147 //Add a new Revese function
2148 Handle(GEOM_Function) aFunction;
2149 aFunction = aReversed->AddFunction(GEOMImpl_ShapeDriver::GetID(), REVERSE_ORIENTATION);
2150 if (aFunction.IsNull()) return NULL;
2152 //Check if the function is set correctly
2153 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
2155 GEOMImpl_IShapes aSI (aFunction);
2157 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
2158 if (aRefShape.IsNull()) return NULL;
2160 aSI.SetBase(aRefShape);
2162 //Compute the sub-shape value
2165 if (!GetSolver()->ComputeFunction(aFunction)) {
2166 SetErrorCode("Shape driver failed to reverse shape");
2170 catch (Standard_Failure) {
2171 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2172 SetErrorCode(aFail->GetMessageString());
2176 //Make a Python command
2177 GEOM::TPythonDump(aFunction) << aReversed
2178 << " = geompy.ChangeOrientation(" << theShape << ")";
2183 Handle(GEOM_Object) aReversed;
2185 GEOM_Engine* anEngine = GetEngine();
2186 //GEOMImpl_Gen* aGen = dynamic_cast<GEOMImpl_Gen*>(anEngine);
2187 GEOMImpl_Gen* aGen = (GEOMImpl_Gen*)anEngine;
2190 GEOMImpl_IHealingOperations* anIHealingOperations =
2191 aGen->GetIHealingOperations(GetDocID());
2192 aReversed = anIHealingOperations->ChangeOrientationCopy(theShape);
2193 SetErrorCode(anIHealingOperations->GetErrorCode());
2199 //=============================================================================
2203 //=============================================================================
2204 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetFreeFacesIDs
2205 (Handle(GEOM_Object) theShape)
2209 if (theShape.IsNull()) return NULL;
2210 TopoDS_Shape aShape = theShape->GetValue();
2211 if (aShape.IsNull()) return NULL;
2213 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
2215 TopTools_IndexedDataMapOfShapeListOfShape mapFaceBlocks;
2216 GEOMImpl_Block6Explorer::MapShapesAndAncestors
2217 (aShape, TopAbs_FACE, TopAbs_SOLID, mapFaceBlocks);
2219 Standard_Integer ind = 1, nbFaces = mapFaceBlocks.Extent();
2222 SetErrorCode("The given shape has no faces");
2226 TopTools_IndexedMapOfShape anIndices;
2227 TopExp::MapShapes(aShape, anIndices);
2229 Standard_Integer id;
2230 for (; ind <= nbFaces; ind++) {
2231 if (mapFaceBlocks.FindFromIndex(ind).Extent() != 2) {
2232 id = anIndices.FindIndex(mapFaceBlocks.FindKey(ind));
2237 //The explode doesn't change object so no new function is required.
2238 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
2240 //Make a Python command
2241 GEOM::TPythonDump(aFunction, /*append=*/true)
2242 << "listFreeFacesIDs = geompy.GetFreeFacesIDs(" << theShape << ")";
2248 //=======================================================================
2249 //function : GetSharedShapes
2251 //=======================================================================
2252 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetSharedShapes
2253 (Handle(GEOM_Object) theShape1,
2254 Handle(GEOM_Object) theShape2,
2255 const Standard_Integer theShapeType)
2259 if (theShape1.IsNull() || theShape2.IsNull()) return NULL;
2261 TopoDS_Shape aShape1 = theShape1->GetValue();
2262 TopoDS_Shape aShape2 = theShape2->GetValue();
2264 if (aShape1.IsNull() || aShape2.IsNull()) return NULL;
2266 TopTools_IndexedMapOfShape anIndices;
2267 TopExp::MapShapes(aShape1, anIndices);
2268 Handle(TColStd_HArray1OfInteger) anArray;
2270 TopTools_IndexedMapOfShape mapShape1;
2271 TopExp::MapShapes(aShape1, TopAbs_ShapeEnum(theShapeType), mapShape1);
2273 Handle(GEOM_Object) anObj;
2274 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
2275 TCollection_AsciiString anAsciiList, anEntry;
2277 TopTools_MapOfShape mapShape2;
2278 TopExp_Explorer exp (aShape2, TopAbs_ShapeEnum(theShapeType));
2279 for (; exp.More(); exp.Next()) {
2280 TopoDS_Shape aSS = exp.Current();
2281 if (mapShape2.Add(aSS) && mapShape1.Contains(aSS)) {
2282 anArray = new TColStd_HArray1OfInteger(1,1);
2283 anArray->SetValue(1, anIndices.FindIndex(aSS));
2284 anObj = GetEngine()->AddSubShape(theShape1, anArray);
2285 aSeq->Append(anObj);
2287 // for python command
2288 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
2289 anAsciiList += anEntry;
2294 if (aSeq->IsEmpty()) {
2295 SetErrorCode(NOT_FOUND_ANY);
2299 //Make a Python command
2300 anAsciiList.Trunc(anAsciiList.Length() - 1);
2302 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2304 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
2305 << "] = geompy.GetSharedShapes(" << theShape1 << ", "
2306 << theShape2 << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
2312 //=======================================================================
2313 //function : GetSharedShapes
2316 // NOTE on the implementation
2318 // 1) Resulting sub-shapes are published as a children of the 1st input shape
2319 // from theShapes list. Due to this reason only direct sub-shapes of the 1st
2320 // shape can be contained in the result of the operation (i.e. shares between
2321 // 2nd/3rd, etc couples cannot be retrieved.
2322 // 2) An exception from above case is when a single compound is specified as an
2323 // input. In this case we search shares between its top-level content, so we
2324 // are able to search shares between all possible couples of shapes.
2325 // 3) Parameter theMultiShare controls what types of shares to search:
2326 // - True: get sub-shapes that are shared between ALL input shapes;
2327 // - False: get shares between couples of input sub-shapes (see points 1 and 2).
2329 // Thus, we have the following cases:
2330 // [1] theShapes = N shapes (N>1), theMultiShare = True
2331 // Result: sub-shapes that are shared by all theShapes
2332 // [2] theShapes = N shapes (N>1), theMultiShare = False
2333 // Result: sub-shapes of 1st shape from theShapes that are shared with any shape
2335 // [3] theShapes = 1 shape, theMultiShare = True
2336 // Result: sub-shapes that are shared by all top-level sub-objects of theShapes[0]
2337 // [4] theShapes = 1 shape, theMultiShare = False
2338 // Result: sub-shapes of all possible couples of all top-level sub-objects of
2340 //=======================================================================
2341 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetSharedShapes
2342 (std::list<Handle(GEOM_Object)> & theShapes,
2343 const Standard_Integer theShapeType,
2344 const bool theMultiShare)
2348 int aLen = theShapes.size();
2349 if (aLen < 1) return NULL;
2351 std::list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
2353 // main object is always first in the input list
2354 // it is the object from which sub-shapes indices are taken
2355 // and where results are published
2356 Handle(GEOM_Object) aMainObj = *it;
2357 Handle(GEOM_Function) aMainShape = aMainObj->GetLastFunction();
2359 // collect all shapes from the input list (including first one) for processing
2360 TopTools_SequenceOfShape shapeSeq;
2361 for (; it != theShapes.end(); it++) {
2362 Handle(GEOM_Function) aRefShape = (*it)->GetLastFunction();
2363 if (aRefShape.IsNull()) {
2364 SetErrorCode("NULL shape for GetSharedShapes");
2367 TopoDS_Shape aShape = aRefShape->GetValue();
2368 if (aShape.IsNull()) {
2369 SetErrorCode("NULL shape for GetSharedShapes");
2372 shapeSeq.Append( aShape );
2375 // if only single shape is specified as input
2376 // collect all ites top-level sub-shapes for processing
2377 if ( shapeSeq.Length() == 1 )
2379 TopoDS_Shape aShape = shapeSeq.First();
2381 for ( TopoDS_Iterator it( aShape ); it.More(); it.Next() )
2382 shapeSeq.Append( it.Value() );
2385 // map all sub-shapes in a main shape to their indices
2386 TopTools_IndexedMapOfShape anIndices;
2387 TopExp::MapShapes(aMainShape->GetValue(), anIndices);
2388 TopTools_MapOfShape mapShape;
2390 // find shared shapes
2392 // here we will collect all shares
2393 TopTools_ListOfShape aShared;
2395 // number of iterations
2396 int nbIters = theMultiShare || theShapes.size() > 1 ? 1 : shapeSeq.Length()-1;
2397 // numShares factor to search (i.e. by what nb of shapes each found sub-shape should be shared)
2398 int nbShares = theMultiShare ? shapeSeq.Length()-1 : 1;
2400 for ( int iter = 1; iter <= nbIters; iter++) {
2401 for ( int ind = iter+1; ind <= shapeSeq.Length(); ind++) {
2402 if ( ind-1+nbShares > shapeSeq.Length() ) break;
2403 TopoDS_Compound aCurrSelection;
2404 TopoDS_Shape aShape1 = shapeSeq.Value( iter );
2405 TopTools_IndexedMapOfShape mapSelected;
2406 TopExp::MapShapes(aShape1, TopAbs_ShapeEnum(theShapeType), mapSelected);
2407 for ( int s = 0; s < nbShares; s++ ) {
2409 TopoDS_Compound aCompound;
2410 B.MakeCompound(aCompound);
2411 const TopoDS_Shape& aShape2 = shapeSeq.Value( ind+s );
2412 TopTools_MapOfShape mapShape2;
2413 TopExp_Explorer exp (aShape2, TopAbs_ShapeEnum(theShapeType));
2414 for (; exp.More(); exp.Next()) {
2415 const TopoDS_Shape& aSS = exp.Current();
2416 if (mapShape2.Add(aSS) && mapSelected.Contains(aSS)) {
2417 B.Add(aCompound, aSS);
2420 mapSelected.Clear();
2421 aCurrSelection = aCompound;
2422 TopExp::MapShapes(aCurrSelection, TopAbs_ShapeEnum(theShapeType), mapSelected);
2424 TopoDS_Iterator itSel(aCurrSelection, Standard_True, Standard_True);
2425 for (; itSel.More(); itSel.Next()) {
2426 const TopoDS_Shape& aSS = itSel.Value();
2427 if (mapShape.Add(aSS) )
2428 aShared.Append(aSS);
2433 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
2435 if (aShared.IsEmpty()){
2436 SetErrorCode(NOT_FOUND_ANY);
2440 // create GEOM_Object for each found shared shape (collected in aShared)
2441 TCollection_AsciiString anAsciiList;
2442 Handle(GEOM_Object) anObj;
2443 TopTools_ListIteratorOfListOfShape itSub (aShared);
2444 for (; itSub.More(); itSub.Next()) {
2445 TopoDS_Shape aValue = itSub.Value();
2446 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
2447 anArray->SetValue(1, anIndices.FindIndex(aValue));
2448 anObj = GetEngine()->AddSubShape(aMainObj, anArray);
2449 aSeq->Append(anObj);
2451 // for python command
2452 TCollection_AsciiString anEntry;
2453 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
2454 anAsciiList += anEntry;
2458 // make a Python command
2459 anAsciiList.Trunc(anAsciiList.Length() - 1);
2461 GEOM::TPythonDump pd (anObj->GetLastFunction());
2462 pd << "[" << anAsciiList.ToCString()
2463 << "] = geompy.GetSharedShapesMulti(";
2468 it = theShapes.begin();
2470 while (it != theShapes.end()) {
2471 pd << ", " << (*it++);
2476 pd << ", " << TopAbs_ShapeEnum(theShapeType) << ", " << theMultiShare << ")";
2482 //=============================================================================
2486 //=============================================================================
2487 static GEOM::TPythonDump& operator<< (GEOM::TPythonDump& theDump,
2488 const GEOMAlgo_State theState)
2491 case GEOMAlgo_ST_IN:
2492 theDump << "GEOM.ST_IN";
2494 case GEOMAlgo_ST_OUT:
2495 theDump << "GEOM.ST_OUT";
2497 case GEOMAlgo_ST_ON:
2498 theDump << "GEOM.ST_ON";
2500 case GEOMAlgo_ST_ONIN:
2501 theDump << "GEOM.ST_ONIN";
2503 case GEOMAlgo_ST_ONOUT:
2504 theDump << "GEOM.ST_ONOUT";
2507 theDump << "GEOM.ST_UNKNOWN";
2513 //=======================================================================
2514 //function : checkTypeShapesOn
2516 * \brief Checks if theShapeType parameter of GetShapesOnXXX() is OK
2517 * \param theShapeType - the shape type to check
2518 * \retval bool - result of the check
2520 //=======================================================================
2521 bool GEOMImpl_IShapesOperations::checkTypeShapesOn(const Standard_Integer theShapeType)
2523 if (theShapeType != TopAbs_VERTEX &&
2524 theShapeType != TopAbs_EDGE &&
2525 theShapeType != TopAbs_FACE &&
2526 theShapeType != TopAbs_SOLID) {
2527 SetErrorCode("Only solids, vertices, edges or faces can be found by this method");
2533 //=======================================================================
2534 //function : makePlane
2536 * \brief Creates Geom_Plane
2537 * \param theAx1 - shape object defining plane parameters
2538 * \retval Handle(Geom_Surface) - resulting surface
2540 //=======================================================================
2541 Handle(Geom_Surface) GEOMImpl_IShapesOperations::makePlane(const TopoDS_Shape& anAx1)
2543 if (anAx1.ShapeType() != TopAbs_EDGE) return NULL;
2544 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
2545 TopoDS_Vertex V1, V2;
2546 TopExp::Vertices(anEdge, V1, V2, Standard_True);
2547 if (V1.IsNull() || V2.IsNull()) {
2548 SetErrorCode("Bad edge given for the plane normal vector");
2551 gp_Pnt aLoc = BRep_Tool::Pnt(V1);
2552 gp_Vec aVec (aLoc, BRep_Tool::Pnt(V2));
2553 if (aVec.Magnitude() < Precision::Confusion()) {
2554 SetErrorCode("Vector with null magnitude given");
2557 return new Geom_Plane(aLoc, aVec);
2560 //=======================================================================
2561 //function : makeCylinder
2563 * \brief Creates Geom_CylindricalSurface
2564 * \param theAx1 - edge defining cylinder axis
2565 * \param theRadius - cylinder radius
2566 * \retval Handle(Geom_Surface) - resulting surface
2568 //=======================================================================
2569 Handle(Geom_Surface) GEOMImpl_IShapesOperations::makeCylinder(const TopoDS_Shape& anAxis,
2570 const Standard_Real theRadius)
2572 //Axis of the cylinder
2573 if (anAxis.ShapeType() != TopAbs_EDGE) {
2574 SetErrorCode("Not an edge given for the axis");
2577 TopoDS_Edge anEdge = TopoDS::Edge(anAxis);
2578 TopoDS_Vertex V1, V2;
2579 TopExp::Vertices(anEdge, V1, V2, Standard_True);
2580 if (V1.IsNull() || V2.IsNull()) {
2581 SetErrorCode("Bad edge given for the axis");
2584 gp_Pnt aLoc = BRep_Tool::Pnt(V1);
2585 gp_Vec aVec (aLoc, BRep_Tool::Pnt(V2));
2586 if (aVec.Magnitude() < Precision::Confusion()) {
2587 SetErrorCode("Vector with null magnitude given");
2591 gp_Ax3 anAx3 (aLoc, aVec);
2592 return new Geom_CylindricalSurface(anAx3, theRadius);
2595 //=======================================================================
2596 //function : getShapesOnBoxIDs
2598 * \brief Find IDs of sub-shapes complying with given status about surface
2599 * \param theBox - the box to check state of sub-shapes against
2600 * \param theShape - the shape to explore
2601 * \param theShapeType - type of sub-shape of theShape
2602 * \param theState - required state
2603 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
2605 //=======================================================================
2606 Handle(TColStd_HSequenceOfInteger)
2607 GEOMImpl_IShapesOperations::getShapesOnBoxIDs(const Handle(GEOM_Object)& theBox,
2608 const Handle(GEOM_Object)& theShape,
2609 const Standard_Integer theShapeType,
2610 GEOMAlgo_State theState)
2612 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
2614 TopoDS_Shape aBox = theBox->GetValue();
2615 TopoDS_Shape aShape = theShape->GetValue();
2617 // Check presence of triangulation, build if need
2618 if (!GEOMUtils::CheckTriangulation(aShape)) {
2619 SetErrorCode("Cannot build triangulation on the shape");
2624 GEOMAlgo_FinderShapeOn2 aFinder;
2625 Standard_Real aTol = 0.0001; // default value
2627 Handle(GEOMAlgo_ClsfBox) aClsfBox = new GEOMAlgo_ClsfBox;
2628 aClsfBox->SetBox(aBox);
2630 aFinder.SetShape(aShape);
2631 aFinder.SetTolerance(aTol);
2632 aFinder.SetClsf(aClsfBox);
2633 aFinder.SetShapeType( (TopAbs_ShapeEnum)theShapeType );
2634 aFinder.SetState(theState);
2637 // Interprete results
2638 Standard_Integer iErr = aFinder.ErrorStatus();
2639 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn2.cxx
2641 MESSAGE(" iErr : " << iErr);
2642 TCollection_AsciiString aMsg (" iErr : ");
2643 aMsg += TCollection_AsciiString(iErr);
2647 Standard_Integer iWrn = aFinder.WarningStatus();
2648 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn2.cxx
2650 MESSAGE(" *** iWrn : " << iWrn);
2653 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
2655 if (listSS.Extent() < 1) {
2656 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
2657 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
2661 // Fill sequence of object IDs
2662 aSeqOfIDs = new TColStd_HSequenceOfInteger;
2664 TopTools_IndexedMapOfShape anIndices;
2665 TopExp::MapShapes(aShape, anIndices);
2667 TopTools_ListIteratorOfListOfShape itSub (listSS);
2668 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
2669 int id = anIndices.FindIndex(itSub.Value());
2670 aSeqOfIDs->Append(id);
2676 //=======================================================================
2677 //function : GetShapesOnBoxIDs
2679 * \brief Find sub-shapes complying with given status about surface
2680 * \param theBox - the box to check state of sub-shapes against
2681 * \param theShape - the shape to explore
2682 * \param theShapeType - type of sub-shape of theShape
2683 * \param theState - required state
2684 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
2686 //=======================================================================
2687 Handle(TColStd_HSequenceOfInteger)
2688 GEOMImpl_IShapesOperations::GetShapesOnBoxIDs(const Handle(GEOM_Object)& theBox,
2689 const Handle(GEOM_Object)& theShape,
2690 const Standard_Integer theShapeType,
2691 GEOMAlgo_State theState)
2693 // Find sub-shapes ids
2694 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2695 getShapesOnBoxIDs (theBox, theShape, theShapeType, theState);
2696 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2699 // The GetShapesOnBox() doesn't change object so no new function is required.
2700 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theBox)->GetLastFunction();
2702 // Make a Python command
2703 GEOM::TPythonDump(aFunction, /*append=*/true)
2704 << "listShapesOnBoxIDs = geompy.GetShapesOnBoxIDs("
2707 << TopAbs_ShapeEnum(theShapeType) << ", "
2714 //=======================================================================
2715 //function : GetShapesOnBox
2717 * \brief Find sub-shapes complying with given status about surface
2718 * \param theBox - the box to check state of sub-shapes against
2719 * \param theShape - the shape to explore
2720 * \param theShapeType - type of sub-shape of theShape
2721 * \param theState - required state
2722 * \retval Handle(TColStd_HSequenceOfTransient) - found sub-shapes
2724 //=======================================================================
2725 Handle(TColStd_HSequenceOfTransient)
2726 GEOMImpl_IShapesOperations::GetShapesOnBox(const Handle(GEOM_Object)& theBox,
2727 const Handle(GEOM_Object)& theShape,
2728 const Standard_Integer theShapeType,
2729 GEOMAlgo_State theState)
2731 // Find sub-shapes ids
2732 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2733 getShapesOnBoxIDs (theBox, theShape, theShapeType, theState);
2734 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2737 // Find objects by indices
2738 TCollection_AsciiString anAsciiList;
2739 Handle(TColStd_HSequenceOfTransient) aSeq;
2740 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
2741 if ( aSeq.IsNull() || aSeq->IsEmpty() )
2744 // Make a Python command
2746 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2747 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2749 GEOM::TPythonDump(aFunction)
2750 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnBox("
2753 << TopAbs_ShapeEnum(theShapeType) << ", "
2760 //=======================================================================
2761 //function : getShapesOnShapeIDs
2763 * \brief Find IDs of sub-shapes complying with given status about surface
2764 * \param theCheckShape - the shape to check state of sub-shapes against
2765 * \param theShape - the shape to explore
2766 * \param theShapeType - type of sub-shape of theShape
2767 * \param theState - required state
2768 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
2770 //=======================================================================
2771 Handle(TColStd_HSequenceOfInteger)
2772 GEOMImpl_IShapesOperations::getShapesOnShapeIDs
2773 (const Handle(GEOM_Object)& theCheckShape,
2774 const Handle(GEOM_Object)& theShape,
2775 const Standard_Integer theShapeType,
2776 GEOMAlgo_State theState)
2778 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
2780 TopoDS_Shape aCheckShape = theCheckShape->GetValue();
2781 TopoDS_Shape aShape = theShape->GetValue();
2782 TopTools_ListOfShape res;
2784 // Check presence of triangulation, build if need
2785 if (!GEOMUtils::CheckTriangulation(aShape)) {
2786 SetErrorCode("Cannot build triangulation on the shape");
2790 // Compute classification tolerance.
2791 TopTools_IndexedMapOfShape aMapVtx;
2792 Standard_Real aTol = Precision::Confusion();
2794 TopExp::MapShapes(aShape, TopAbs_VERTEX, aMapVtx);
2797 Standard_Integer aNbVtx = aMapVtx.Extent();
2799 for (i = 1; i <= aNbVtx; ++i) {
2800 const TopoDS_Vertex aVtx = TopoDS::Vertex(aMapVtx.FindKey(i));
2801 const Standard_Real aVtxTol = BRep_Tool::Tolerance(aVtx);
2803 if (aTol < aVtxTol) {
2808 // Bound the tolerance value.
2809 if (aTol > 0.0001) {
2814 GEOMAlgo_FinderShapeOn2 aFinder;
2816 Handle(GEOMAlgo_ClsfSolid) aClsfSolid = new GEOMAlgo_ClsfSolid;
2817 aClsfSolid->SetShape(aCheckShape);
2819 aFinder.SetShape(aShape);
2820 aFinder.SetTolerance(aTol);
2821 aFinder.SetClsf(aClsfSolid);
2822 aFinder.SetShapeType( (TopAbs_ShapeEnum)theShapeType );
2823 aFinder.SetState(theState);
2826 // Interprete results
2827 Standard_Integer iErr = aFinder.ErrorStatus();
2828 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn2.cxx
2831 SetErrorCode("theCheckShape must be a solid");
2834 MESSAGE(" iErr : " << iErr);
2835 TCollection_AsciiString aMsg (" iErr : ");
2836 aMsg += TCollection_AsciiString(iErr);
2841 Standard_Integer iWrn = aFinder.WarningStatus();
2842 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn2.cxx
2844 MESSAGE(" *** iWrn : " << iWrn);
2847 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
2849 if (listSS.Extent() < 1) {
2850 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
2851 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
2854 // Fill sequence of object IDs
2855 aSeqOfIDs = new TColStd_HSequenceOfInteger;
2857 TopTools_IndexedMapOfShape anIndices;
2858 TopExp::MapShapes(aShape, anIndices);
2860 TopTools_ListIteratorOfListOfShape itSub (listSS);
2861 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
2862 int id = anIndices.FindIndex(itSub.Value());
2863 aSeqOfIDs->Append(id);
2869 //=======================================================================
2870 //function : GetShapesOnShapeIDs
2872 * \brief Find sub-shapes complying with given status about surface
2873 * \param theCheckShape - the shape to check state of sub-shapes against
2874 * \param theShape - the shape to explore
2875 * \param theShapeType - type of sub-shape of theShape
2876 * \param theState - required state
2877 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
2879 //=======================================================================
2880 Handle(TColStd_HSequenceOfInteger)
2881 GEOMImpl_IShapesOperations::GetShapesOnShapeIDs
2882 (const Handle(GEOM_Object)& theCheckShape,
2883 const Handle(GEOM_Object)& theShape,
2884 const Standard_Integer theShapeType,
2885 GEOMAlgo_State theState)
2887 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2888 getShapesOnShapeIDs (theCheckShape, theShape, theShapeType, theState);
2890 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2893 // The GetShapesOnShape() doesn't change object so no new function is required.
2894 Handle(GEOM_Function) aFunction =
2895 GEOM::GetCreatedLast(theShape,theCheckShape)->GetLastFunction();
2897 // Make a Python command
2898 GEOM::TPythonDump(aFunction, /*append=*/true)
2899 << "listShapesOnBoxIDs = geompy.GetShapesOnShapeIDs("
2900 << theCheckShape << ", "
2902 << TopAbs_ShapeEnum(theShapeType) << ", "
2909 //=======================================================================
2910 //function : GetShapesOnShape
2912 * \brief Find sub-shapes complying with given status about surface
2913 * \param theCheckShape - the shape to check state of sub-shapes against
2914 * \param theShape - the shape to explore
2915 * \param theShapeType - type of sub-shape of theShape
2916 * \param theState - required state
2917 * \retval Handle(TColStd_HSequenceOfTransient) - found sub-shapes
2919 //=======================================================================
2920 Handle(TColStd_HSequenceOfTransient)
2921 GEOMImpl_IShapesOperations::GetShapesOnShape
2922 (const Handle(GEOM_Object)& theCheckShape,
2923 const Handle(GEOM_Object)& theShape,
2924 const Standard_Integer theShapeType,
2925 GEOMAlgo_State theState)
2927 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2928 getShapesOnShapeIDs (theCheckShape, theShape, theShapeType, theState);
2929 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2932 // Find objects by indices
2933 TCollection_AsciiString anAsciiList;
2934 Handle(TColStd_HSequenceOfTransient) aSeq;
2935 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
2937 if ( aSeq.IsNull() || aSeq->IsEmpty() )
2940 // Make a Python command
2942 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2943 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2945 GEOM::TPythonDump(aFunction)
2946 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnShape("
2947 << theCheckShape << ", "
2949 << TopAbs_ShapeEnum(theShapeType) << ", "
2956 //=======================================================================
2957 //function : GetShapesOnShapeAsCompound
2958 //=======================================================================
2959 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetShapesOnShapeAsCompound
2960 (const Handle(GEOM_Object)& theCheckShape,
2961 const Handle(GEOM_Object)& theShape,
2962 const Standard_Integer theShapeType,
2963 GEOMAlgo_State theState)
2965 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2966 getShapesOnShapeIDs (theCheckShape, theShape, theShapeType, theState);
2968 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2971 // Find objects by indices
2972 TCollection_AsciiString anAsciiList;
2973 Handle(TColStd_HSequenceOfTransient) aSeq;
2974 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
2976 if ( aSeq.IsNull() || aSeq->IsEmpty() )
2979 TopoDS_Compound aCompound;
2981 B.MakeCompound(aCompound);
2983 for(; i<=aSeq->Length(); i++) {
2984 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(aSeq->Value(i));
2985 TopoDS_Shape aShape_i = anObj->GetValue();
2986 B.Add(aCompound,aShape_i);
2989 //Add a new result object
2990 Handle(GEOM_Object) aRes = GetEngine()->AddObject(GetDocID(), GEOM_SHAPES_ON_SHAPE);
2991 Handle(GEOM_Function) aFunction =
2992 aRes->AddFunction(GEOMImpl_ShapeDriver::GetID(), SHAPES_ON_SHAPE);
2993 aFunction->SetValue(aCompound);
2996 aSeq->Append( theCheckShape->GetLastFunction() );
2997 aSeq->Append( theShape->GetLastFunction() );
2999 GEOMImpl_IShapes aCI( aFunction );
3000 aCI.SetShapes( aSeq );
3001 aCI.SetSubShapeType( theShapeType );
3002 aCI.SetTolerance( theState );
3004 GEOM::TPythonDump(aFunction)
3005 << aRes << " = geompy.GetShapesOnShapeAsCompound("
3006 << theCheckShape << ", "
3008 << TopAbs_ShapeEnum(theShapeType) << ", "
3016 //=============================================================================
3018 * GetSubShapeEdgeSorted
3020 //=============================================================================
3021 Handle(TColStd_HSequenceOfTransient)
3022 GEOMImpl_IShapesOperations::GetSubShapeEdgeSorted
3023 (const Handle(GEOM_Object) &theShape,
3024 const Handle(GEOM_Object) &theStartPoint)
3026 // Get the sorted edges indices.
3027 Handle(TColStd_HSequenceOfInteger) aSortedIDs =
3028 getSubShapeEdgeSortedIDs(theShape, theStartPoint);
3030 // Get object by indices.
3031 TCollection_AsciiString anAsciiList;
3032 Handle(TColStd_HSequenceOfTransient) aSeq =
3033 getObjectsShapesOn(theShape, aSortedIDs, anAsciiList);
3035 if (aSeq.IsNull() || aSeq->IsEmpty()) {
3036 SetErrorCode("Empty sequence of edges");
3040 // Make a Python command
3041 Handle(GEOM_Object) anObj =
3042 Handle(GEOM_Object)::DownCast(aSeq->Value(1));
3043 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
3045 GEOM::TPythonDump(aFunction)
3046 << "[" << anAsciiList.ToCString() << "] = geompy.GetSubShapeEdgeSorted("
3047 << theShape << ", " << theStartPoint << ")";
3054 //=======================================================================
3055 //function : getShapesOnSurfaceIDs
3057 * \brief Find IDs of sub-shapes complying with given status about surface
3058 * \param theSurface - the surface to check state of sub-shapes against
3059 * \param theShape - the shape to explore
3060 * \param theShapeType - type of sub-shape of theShape
3061 * \param theState - required state
3062 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
3064 //=======================================================================
3065 Handle(TColStd_HSequenceOfInteger)
3066 GEOMImpl_IShapesOperations::getShapesOnSurfaceIDs(const Handle(Geom_Surface)& theSurface,
3067 const TopoDS_Shape& theShape,
3068 TopAbs_ShapeEnum theShapeType,
3069 GEOMAlgo_State theState)
3071 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
3073 // Check presence of triangulation, build if need
3074 if (!GEOMUtils::CheckTriangulation(theShape)) {
3075 SetErrorCode("Cannot build triangulation on the shape");
3079 // BEGIN: Mantis issue 0020961: Error on a pipe T-Shape
3080 // Compute tolerance
3081 Standard_Real T, VertMax = -RealLast();
3084 for (TopExp_Explorer ExV (theShape, TopAbs_VERTEX); ExV.More(); ExV.Next()) {
3085 TopoDS_Vertex Vertex = TopoDS::Vertex(ExV.Current());
3086 T = BRep_Tool::Tolerance(Vertex);
3091 catch (Standard_Failure) {
3092 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
3093 SetErrorCode(aFail->GetMessageString());
3096 // END: Mantis issue 0020961
3099 GEOMAlgo_FinderShapeOn2 aFinder;
3100 Handle(GEOMAlgo_ClsfSurf) aClsfSurf = new GEOMAlgo_ClsfSurf;
3101 Standard_Real aTol = VertMax; // Mantis issue 0020961
3103 aClsfSurf->SetSurface(theSurface);
3104 aFinder.SetShape(theShape);
3105 aFinder.SetTolerance(aTol);
3106 aFinder.SetClsf(aClsfSurf);
3107 aFinder.SetShapeType(theShapeType);
3108 aFinder.SetState(theState);
3110 // Sets the minimal number of inner points for the faces that do not have own
3111 // inner points at all (for e.g. rectangular planar faces have just 2 triangles).
3113 aFinder.SetNbPntsMin(3);
3114 // Sets the maximal number of inner points for edges or faces.
3115 // It is usefull for the cases when this number is very big (e.g =2000) to improve
3116 // the performance. If this value =0, all inner points will be taken into account.
3118 aFinder.SetNbPntsMax(100);
3122 // Interprete results
3123 Standard_Integer iErr = aFinder.ErrorStatus();
3124 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn2.cxx
3126 MESSAGE(" iErr : " << iErr);
3127 TCollection_AsciiString aMsg (" iErr : ");
3128 aMsg += TCollection_AsciiString(iErr);
3132 Standard_Integer iWrn = aFinder.WarningStatus();
3133 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn2.cxx
3135 MESSAGE(" *** iWrn : " << iWrn);
3138 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
3140 if (listSS.Extent() < 1) {
3141 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
3142 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
3146 // Fill sequence of object IDs
3147 aSeqOfIDs = new TColStd_HSequenceOfInteger;
3149 TopTools_IndexedMapOfShape anIndices;
3150 TopExp::MapShapes(theShape, anIndices);
3152 TopTools_ListIteratorOfListOfShape itSub (listSS);
3153 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
3154 int id = anIndices.FindIndex(itSub.Value());
3155 aSeqOfIDs->Append(id);
3161 //=======================================================================
3162 //function : getObjectsShapesOn
3164 * \brief Find shape objects and their entries by their ids
3165 * \param theShapeIDs - incoming shape ids
3166 * \param theShapeEntries - outgoing entries like "entry1, entry2, ..."
3167 * \retval Handle(TColStd_HSequenceOfTransient) - found shape objects
3169 //=======================================================================
3170 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::
3171 getObjectsShapesOn(const Handle(GEOM_Object)& theShape,
3172 const Handle(TColStd_HSequenceOfInteger)& theShapeIDs,
3173 TCollection_AsciiString & theShapeEntries)
3175 Handle(TColStd_HSequenceOfTransient) aSeq;
3177 if ( !theShapeIDs.IsNull() && theShapeIDs->Length() > 0 )
3179 aSeq = new TColStd_HSequenceOfTransient;
3180 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
3181 TCollection_AsciiString anEntry;
3182 for ( int i = 1; i <= theShapeIDs->Length(); ++i )
3184 anArray->SetValue(1, theShapeIDs->Value( i ));
3185 Handle(GEOM_Object) anObj = GetEngine()->AddSubShape(theShape, anArray);
3186 aSeq->Append( anObj );
3188 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
3189 if ( i != 1 ) theShapeEntries += ",";
3190 theShapeEntries += anEntry;
3196 //=============================================================================
3198 * getSubShapeEdgeSortedIDs
3200 //=============================================================================
3201 Handle(TColStd_HSequenceOfInteger)
3202 GEOMImpl_IShapesOperations::getSubShapeEdgeSortedIDs
3203 (const Handle(GEOM_Object) &theShape,
3204 const Handle(GEOM_Object) &theStartPoint)
3206 Handle(TColStd_HSequenceOfInteger) aResult;
3208 if (theShape.IsNull() || theStartPoint.IsNull()) {
3209 SetErrorCode("NULL GEOM object");
3213 const TopoDS_Shape aShape = theShape->GetValue();
3214 const TopoDS_Shape aStartPoint = theStartPoint->GetValue();
3216 if (aShape.IsNull() || aStartPoint.IsNull()) {
3217 SetErrorCode("NULL Shape");
3221 if (aStartPoint.ShapeType() != TopAbs_VERTEX) {
3222 SetErrorCode("Starting point is not a vertex");
3226 TopExp_Explorer anExp(aShape, TopAbs_EDGE);
3227 TopTools_MapOfShape aMapFence;
3228 TopTools_ListOfShape anEdges;
3230 for (; anExp.More(); anExp.Next()) {
3231 const TopoDS_Shape &anEdge = anExp.Current();
3233 if (aMapFence.Add(anEdge)) {
3234 anEdges.Append(anEdge);
3238 if (anEdges.IsEmpty()) {
3239 SetErrorCode("Shape doesn't contain edges");
3243 // Step 1: Sort edges
3244 GEOMUtils::SortShapes(anEdges, Standard_False);
3246 TopTools_ListIteratorOfListOfShape anIter(anEdges);
3247 TopoDS_Vertex aV[2];
3248 TopTools_DataMapOfShapeListOfShape aMapVE;
3250 // Step 2: Fill the map vertex - list of edges.
3251 for (; anIter.More(); anIter.Next()) {
3252 TopoDS_Edge anEdge = TopoDS::Edge(anIter.Value());
3254 TopExp::Vertices(anEdge, aV[0], aV[1]);
3256 const Standard_Integer aNbV = aV[0].IsSame(aV[1]) ? 1 : 2;
3259 for (i = 0; i < aNbV; ++i) {
3260 if (aV[i].IsNull() == Standard_False) {
3261 if (!aMapVE.IsBound(aV[i])) {
3262 // There is no this vertex in the map.
3263 aMapVE.Bind(aV[i], TopTools_ListOfShape());
3266 // Add the edge to the list bound with the vertex aV[i].
3267 TopTools_ListOfShape &aLEdges = aMapVE.ChangeFind(aV[i]);
3269 aLEdges.Append(anEdge);
3274 // Step 3: Find starting point in aMapVE.
3275 TopoDS_Vertex aStartVtx = TopoDS::Vertex(aStartPoint);
3277 if (!aMapVE.IsBound(aStartVtx)) {
3278 aStartVtx = getSameVertex(aShape, aStartVtx);
3280 if (aStartVtx.IsNull()) {
3281 SetErrorCode("Invalid Starting point");
3286 TopTools_IndexedMapOfShape anIndices;
3287 TopTools_MapOfShape aMapVFence;
3288 TopoDS_Shape aCurVtx = aStartVtx;
3289 TopoDS_Edge aCurEdge =
3290 TopoDS::Edge(aMapVE.Find(aCurVtx).First());
3292 aResult = new TColStd_HSequenceOfInteger;
3293 TopExp::MapShapes(aShape, anIndices);
3295 // Step 4: Fill the list of sorted edges.
3296 while (aMapVFence.Add(aCurVtx)) {
3297 // Append the ID of the current edge to the list of sorted.
3298 aResult->Append(anIndices.FindIndex(aCurEdge));
3299 TopExp::Vertices(aCurEdge, aV[0], aV[1]);
3301 // Get the next vertex.
3302 if (aCurVtx.IsSame(aV[0])) {
3303 if (aCurVtx.IsSame(aV[1])) {
3304 // There is no next vertex.
3313 if (aCurVtx.IsNull()) {
3314 // There is no next vertex.
3318 // Get the next edge.
3319 const TopTools_ListOfShape &aLEdges = aMapVE.Find(aCurVtx);
3320 TopTools_ListIteratorOfListOfShape anEIter(aLEdges);
3322 for (; anEIter.More(); anEIter.Next()) {
3323 const TopoDS_Shape &aLocalEdge = anEIter.Value();
3325 if (aLocalEdge.IsNull() == Standard_False) {
3326 if (!aCurEdge.IsSame(aLocalEdge)) {
3327 aCurEdge = TopoDS::Edge(aLocalEdge);
3333 if (!anEIter.More()) {
3334 // There is no next edge.
3342 //=======================================================================
3343 //function : getShapesOnSurface
3345 * \brief Find sub-shapes complying with given status about surface
3346 * \param theSurface - the surface to check state of sub-shapes against
3347 * \param theShape - the shape to explore
3348 * \param theShapeType - type of sub-shape of theShape
3349 * \param theState - required state
3350 * \param theShapeEntries - outgoing entries like "entry1, entry2, ..."
3351 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
3353 //=======================================================================
3354 Handle(TColStd_HSequenceOfTransient)
3355 GEOMImpl_IShapesOperations::getShapesOnSurface(const Handle(Geom_Surface)& theSurface,
3356 const Handle(GEOM_Object)& theShape,
3357 TopAbs_ShapeEnum theShapeType,
3358 GEOMAlgo_State theState,
3359 TCollection_AsciiString & theShapeEntries)
3361 // Find sub-shapes ids
3362 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
3363 getShapesOnSurfaceIDs (theSurface, theShape->GetValue(), theShapeType, theState);
3364 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
3367 return getObjectsShapesOn( theShape, aSeqOfIDs, theShapeEntries );
3370 //=============================================================================
3374 //=============================================================================
3375 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnPlane
3376 (const Handle(GEOM_Object)& theShape,
3377 const Standard_Integer theShapeType,
3378 const Handle(GEOM_Object)& theAx1,
3379 const GEOMAlgo_State theState)
3383 if (theShape.IsNull() || theAx1.IsNull()) return NULL;
3385 TopoDS_Shape aShape = theShape->GetValue();
3386 TopoDS_Shape anAx1 = theAx1->GetValue();
3388 if (aShape.IsNull() || anAx1.IsNull()) return NULL;
3390 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3391 if ( !checkTypeShapesOn( theShapeType ))
3395 Handle(Geom_Surface) aPlane = makePlane( anAx1 );
3396 if ( aPlane.IsNull() )
3400 TCollection_AsciiString anAsciiList;
3401 Handle(TColStd_HSequenceOfTransient) aSeq;
3402 aSeq = getShapesOnSurface( aPlane, theShape, aShapeType, theState, anAsciiList );
3403 if ( aSeq.IsNull() || aSeq->Length() == 0 )
3406 // Make a Python command
3408 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
3409 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
3411 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
3412 << "] = geompy.GetShapesOnPlane(" << theShape << ", "
3413 << aShapeType << ", " << theAx1 << ", " << theState << ")";
3419 //=============================================================================
3421 * GetShapesOnPlaneWithLocation
3423 //=============================================================================
3424 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnPlaneWithLocation
3425 (const Handle(GEOM_Object)& theShape,
3426 const Standard_Integer theShapeType,
3427 const Handle(GEOM_Object)& theAx1,
3428 const Handle(GEOM_Object)& thePnt,
3429 const GEOMAlgo_State theState)
3433 if (theShape.IsNull() || theAx1.IsNull() || thePnt.IsNull()) return NULL;
3435 TopoDS_Shape aShape = theShape->GetValue();
3436 TopoDS_Shape anAx1 = theAx1->GetValue();
3437 TopoDS_Shape anPnt = thePnt->GetValue();
3439 if (aShape.IsNull() || anAx1.IsNull() || anPnt.IsNull()) return NULL;
3441 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3442 if ( !checkTypeShapesOn( theShapeType ))
3446 if ( anAx1.ShapeType() != TopAbs_EDGE || anPnt.ShapeType() != TopAbs_VERTEX ) return NULL;
3447 TopoDS_Vertex V1, V2, V3;
3448 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
3449 TopExp::Vertices(anEdge, V1, V2, Standard_True);
3451 if (V1.IsNull() || V2.IsNull()) {
3452 SetErrorCode("Bad edge given for the plane normal vector");
3455 V3 = TopoDS::Vertex(anPnt);
3458 SetErrorCode("Bad vertex given for the plane location");
3461 gp_Pnt aLoc = BRep_Tool::Pnt(V3);
3462 gp_Vec aVec(BRep_Tool::Pnt(V1),BRep_Tool::Pnt(V2));
3464 if (aVec.Magnitude() < Precision::Confusion()) {
3465 SetErrorCode("Vector with null magnitude given");
3468 Handle(Geom_Surface) aPlane = new Geom_Plane(aLoc, aVec);
3470 if ( aPlane.IsNull() )
3474 TCollection_AsciiString anAsciiList;
3475 Handle(TColStd_HSequenceOfTransient) aSeq;
3476 aSeq = getShapesOnSurface( aPlane, theShape, aShapeType, theState, anAsciiList );
3477 if ( aSeq.IsNull() || aSeq->Length() == 0 )
3480 // Make a Python command
3482 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
3483 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
3485 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
3486 << "] = geompy.GetShapesOnPlaneWithLocation(" << theShape << ", "
3487 << aShapeType << ", " << theAx1 << ", "<< thePnt <<", " << theState << ")";
3493 //=============================================================================
3495 * GetShapesOnCylinder
3497 //=============================================================================
3498 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnCylinder
3499 (const Handle(GEOM_Object)& theShape,
3500 const Standard_Integer theShapeType,
3501 const Handle(GEOM_Object)& theAxis,
3502 const Standard_Real theRadius,
3503 const GEOMAlgo_State theState)
3507 if (theShape.IsNull() || theAxis.IsNull()) return NULL;
3509 TopoDS_Shape aShape = theShape->GetValue();
3510 TopoDS_Shape anAxis = theAxis->GetValue();
3512 if (aShape.IsNull() || anAxis.IsNull()) return NULL;
3514 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3515 if ( !checkTypeShapesOn( aShapeType ))
3518 // Create a cylinder surface
3519 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
3520 if ( aCylinder.IsNull() )
3524 TCollection_AsciiString anAsciiList;
3525 Handle(TColStd_HSequenceOfTransient) aSeq;
3526 aSeq = getShapesOnSurface( aCylinder, theShape, aShapeType, theState, anAsciiList );
3527 if ( aSeq.IsNull() || aSeq->Length() == 0 )
3530 // Make a Python command
3532 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
3533 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
3535 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
3536 << "] = geompy.GetShapesOnCylinder(" << theShape << ", " << aShapeType
3537 << ", " << theAxis << ", " << theRadius << ", " << theState << ")";
3543 //=============================================================================
3545 * GetShapesOnCylinderWithLocation
3547 //=============================================================================
3548 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnCylinderWithLocation
3549 (const Handle(GEOM_Object)& theShape,
3550 const Standard_Integer theShapeType,
3551 const Handle(GEOM_Object)& theAxis,
3552 const Handle(GEOM_Object)& thePnt,
3553 const Standard_Real theRadius,
3554 const GEOMAlgo_State theState)
3558 if (theShape.IsNull() || theAxis.IsNull() || thePnt.IsNull()) return NULL;
3560 TopoDS_Shape aShape = theShape->GetValue();
3561 TopoDS_Shape anAxis = theAxis->GetValue();
3562 TopoDS_Shape aPnt = thePnt->GetValue();
3564 if (aShape.IsNull() || anAxis.IsNull() || aPnt.IsNull()) return NULL;
3566 if (aPnt.ShapeType() != TopAbs_VERTEX )
3568 SetErrorCode("Bottom location point must be vertex");
3572 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3573 if ( !checkTypeShapesOn( aShapeType ))
3576 // Create a cylinder surface
3577 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
3578 if ( aCylinder.IsNull() )
3581 // translate the surface
3582 Handle(Geom_CylindricalSurface) aCylSurface =
3583 Handle(Geom_CylindricalSurface)::DownCast( aCylinder );
3584 if ( aCylSurface.IsNull() )
3586 SetErrorCode("Unexpected surface type instead of Geom_CylindricalSurface");
3589 gp_Pnt fromLoc = aCylSurface->Cylinder().Location();
3590 gp_Pnt toLoc = BRep_Tool::Pnt( TopoDS::Vertex( aPnt ));
3591 aCylinder->Translate( fromLoc, toLoc );
3594 TCollection_AsciiString anAsciiList;
3595 Handle(TColStd_HSequenceOfTransient) aSeq;
3596 aSeq = getShapesOnSurface( aCylinder, theShape, aShapeType, theState, anAsciiList );
3597 if ( aSeq.IsNull() || aSeq->Length() == 0 )
3600 // Make a Python command
3602 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
3603 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
3605 GEOM::TPythonDump(aFunction)
3606 << "[" << anAsciiList.ToCString()
3607 << "] = geompy.GetShapesOnCylinderWithLocation(" << theShape << ", " << aShapeType << ", "
3608 << theAxis << ", " << thePnt << ", " << theRadius << ", " << theState << ")";
3614 //=============================================================================
3618 //=============================================================================
3619 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnSphere
3620 (const Handle(GEOM_Object)& theShape,
3621 const Standard_Integer theShapeType,
3622 const Handle(GEOM_Object)& theCenter,
3623 const Standard_Real theRadius,
3624 const GEOMAlgo_State theState)
3628 if (theShape.IsNull() || theCenter.IsNull()) return NULL;
3630 TopoDS_Shape aShape = theShape->GetValue();
3631 TopoDS_Shape aCenter = theCenter->GetValue();
3633 if (aShape.IsNull() || aCenter.IsNull()) return NULL;
3635 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3636 if ( !checkTypeShapesOn( aShapeType ))
3639 // Center of the sphere
3640 if (aCenter.ShapeType() != TopAbs_VERTEX) return NULL;
3641 gp_Pnt aLoc = BRep_Tool::Pnt(TopoDS::Vertex(aCenter));
3643 gp_Ax3 anAx3 (aLoc, gp::DZ());
3644 Handle(Geom_SphericalSurface) aSphere =
3645 new Geom_SphericalSurface(anAx3, theRadius);
3648 TCollection_AsciiString anAsciiList;
3649 Handle(TColStd_HSequenceOfTransient) aSeq;
3650 aSeq = getShapesOnSurface( aSphere, theShape, aShapeType, theState, anAsciiList );
3651 if ( aSeq.IsNull() || aSeq->Length() == 0 )
3654 // Make a Python command
3656 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
3657 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
3659 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
3660 << "] = geompy.GetShapesOnSphere(" << theShape << ", " << aShapeType
3661 << ", " << theCenter << ", " << theRadius << ", " << theState << ")";
3667 //=============================================================================
3669 * GetShapesOnPlaneIDs
3671 //=============================================================================
3672 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnPlaneIDs
3673 (const Handle(GEOM_Object)& theShape,
3674 const Standard_Integer theShapeType,
3675 const Handle(GEOM_Object)& theAx1,
3676 const GEOMAlgo_State theState)
3680 if (theShape.IsNull() || theAx1.IsNull()) return NULL;
3682 TopoDS_Shape aShape = theShape->GetValue();
3683 TopoDS_Shape anAx1 = theAx1->GetValue();
3685 if (aShape.IsNull() || anAx1.IsNull()) return NULL;
3687 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3688 if ( !checkTypeShapesOn( aShapeType ))
3692 Handle(Geom_Surface) aPlane = makePlane( anAx1 );
3693 if ( aPlane.IsNull() )
3697 Handle(TColStd_HSequenceOfInteger) aSeq;
3698 aSeq = getShapesOnSurfaceIDs( aPlane, aShape, aShapeType, theState );
3700 // The GetShapesOnPlaneIDs() doesn't change object so no new function is required.
3701 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAx1)->GetLastFunction();
3703 // Make a Python command
3704 GEOM::TPythonDump(aFunction, /*append=*/true)
3705 << "listShapesOnPlane = geompy.GetShapesOnPlaneIDs"
3706 << "(" << theShape << "," << aShapeType << "," << theAx1 << "," << theState << ")";
3712 //=============================================================================
3714 * GetShapesOnPlaneWithLocationIDs
3716 //=============================================================================
3717 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnPlaneWithLocationIDs
3718 (const Handle(GEOM_Object)& theShape,
3719 const Standard_Integer theShapeType,
3720 const Handle(GEOM_Object)& theAx1,
3721 const Handle(GEOM_Object)& thePnt,
3722 const GEOMAlgo_State theState)
3726 if (theShape.IsNull() || theAx1.IsNull() || thePnt.IsNull()) return NULL;
3728 TopoDS_Shape aShape = theShape->GetValue();
3729 TopoDS_Shape anAx1 = theAx1->GetValue();
3730 TopoDS_Shape anPnt = thePnt->GetValue();
3732 if (aShape.IsNull() || anAx1.IsNull() || anPnt.IsNull()) return NULL;
3734 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3735 if ( !checkTypeShapesOn( aShapeType ))
3739 if (anAx1.ShapeType() != TopAbs_EDGE || anPnt.ShapeType() != TopAbs_VERTEX) return NULL;
3740 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
3741 TopoDS_Vertex V1, V2, V3;
3742 TopExp::Vertices(anEdge, V1, V2, Standard_True);
3743 if (V1.IsNull() || V2.IsNull()) {
3744 SetErrorCode("Bad edge given for the plane normal vector");
3747 V3 = TopoDS::Vertex(anPnt);
3749 SetErrorCode("Bad vertex given for the plane location");
3752 gp_Pnt aLoc = BRep_Tool::Pnt(V3);
3753 gp_Vec aVec(BRep_Tool::Pnt(V1),BRep_Tool::Pnt(V2));
3754 if (aVec.Magnitude() < Precision::Confusion()) {
3755 SetErrorCode("Vector with null magnitude given");
3759 Handle(Geom_Surface) aPlane = new Geom_Plane(aLoc, aVec);
3760 if ( aPlane.IsNull() )
3764 Handle(TColStd_HSequenceOfInteger) aSeq;
3765 aSeq = getShapesOnSurfaceIDs( aPlane, aShape, aShapeType, theState );
3767 // The GetShapesOnPlaneIDs() doesn't change object so no new function is required.
3768 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAx1)->GetLastFunction();
3770 // Make a Python command
3771 GEOM::TPythonDump(aFunction, /*append=*/true)
3772 << "listShapesOnPlane = geompy.GetShapesOnPlaneWithLocationIDs"
3773 << "(" << theShape << ", " << aShapeType << ", " << theAx1 << ", "<< thePnt << ", " << theState << ")";
3779 //=============================================================================
3781 * GetShapesOnCylinderIDs
3783 //=============================================================================
3784 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnCylinderIDs
3785 (const Handle(GEOM_Object)& theShape,
3786 const Standard_Integer theShapeType,
3787 const Handle(GEOM_Object)& theAxis,
3788 const Standard_Real theRadius,
3789 const GEOMAlgo_State theState)
3793 if (theShape.IsNull() || theAxis.IsNull()) return NULL;
3795 TopoDS_Shape aShape = theShape->GetValue();
3796 TopoDS_Shape anAxis = theAxis->GetValue();
3798 if (aShape.IsNull() || anAxis.IsNull()) return NULL;
3800 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3801 if ( !checkTypeShapesOn( aShapeType ))
3804 // Create a cylinder surface
3805 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
3806 if ( aCylinder.IsNull() )
3810 Handle(TColStd_HSequenceOfInteger) aSeq;
3811 aSeq = getShapesOnSurfaceIDs( aCylinder, aShape, aShapeType, theState );
3813 // The GetShapesOnCylinder() doesn't change object so no new function is required.
3814 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAxis)->GetLastFunction();
3816 // Make a Python command
3817 GEOM::TPythonDump(aFunction, /*append=*/true)
3818 << "listShapesOnCylinder = geompy.GetShapesOnCylinderIDs"
3819 << "(" << theShape << ", " << aShapeType << ", " << theAxis << ", "
3820 << theRadius << ", " << theState << ")";
3826 //=============================================================================
3828 * GetShapesOnCylinderWithLocationIDs
3830 //=============================================================================
3831 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnCylinderWithLocationIDs
3832 (const Handle(GEOM_Object)& theShape,
3833 const Standard_Integer theShapeType,
3834 const Handle(GEOM_Object)& theAxis,
3835 const Handle(GEOM_Object)& thePnt,
3836 const Standard_Real theRadius,
3837 const GEOMAlgo_State theState)
3841 if (theShape.IsNull() || theAxis.IsNull() || thePnt.IsNull()) return NULL;
3843 TopoDS_Shape aShape = theShape->GetValue();
3844 TopoDS_Shape anAxis = theAxis->GetValue();
3845 TopoDS_Shape aPnt = thePnt->GetValue();
3847 if (aShape.IsNull() || anAxis.IsNull() || aPnt.IsNull()) return NULL;
3849 if (aPnt.ShapeType() != TopAbs_VERTEX )
3851 SetErrorCode("Bottom location point must be vertex");
3855 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3856 if ( !checkTypeShapesOn( aShapeType ))
3859 // Create a cylinder surface
3860 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
3861 if ( aCylinder.IsNull() )
3864 // translate the surface
3865 Handle(Geom_CylindricalSurface) aCylSurface =
3866 Handle(Geom_CylindricalSurface)::DownCast( aCylinder );
3867 if ( aCylSurface.IsNull() )
3869 SetErrorCode("Unexpected surface type instead of Geom_CylindricalSurface");
3872 gp_Pnt fromLoc = aCylSurface->Cylinder().Location();
3873 gp_Pnt toLoc = BRep_Tool::Pnt( TopoDS::Vertex( aPnt ));
3874 aCylinder->Translate( fromLoc, toLoc );
3877 Handle(TColStd_HSequenceOfInteger) aSeq;
3878 aSeq = getShapesOnSurfaceIDs( aCylinder, aShape, aShapeType, theState );
3880 // The GetShapesOnCylinder() doesn't change object so no new function is required.
3881 Handle(GEOM_Function) aFunction =
3882 GEOM::GetCreatedLast(theShape, GEOM::GetCreatedLast(thePnt,theAxis))->GetLastFunction();
3884 // Make a Python command
3885 GEOM::TPythonDump(aFunction, /*append=*/true)
3886 << "listShapesOnCylinder = geompy.GetShapesOnCylinderWithLocationIDs"
3887 << "(" << theShape << ", " << aShapeType << ", " << theAxis << ", "
3888 << thePnt << ", " << theRadius << ", " << theState << ")";
3894 //=============================================================================
3896 * GetShapesOnSphereIDs
3898 //=============================================================================
3899 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnSphereIDs
3900 (const Handle(GEOM_Object)& theShape,
3901 const Standard_Integer theShapeType,
3902 const Handle(GEOM_Object)& theCenter,
3903 const Standard_Real theRadius,
3904 const GEOMAlgo_State theState)
3908 if (theShape.IsNull() || theCenter.IsNull()) return NULL;
3910 TopoDS_Shape aShape = theShape->GetValue();
3911 TopoDS_Shape aCenter = theCenter->GetValue();
3913 if (aShape.IsNull() || aCenter.IsNull()) return NULL;
3915 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3916 if ( !checkTypeShapesOn( aShapeType ))
3919 // Center of the sphere
3920 if (aCenter.ShapeType() != TopAbs_VERTEX) return NULL;
3921 gp_Pnt aLoc = BRep_Tool::Pnt(TopoDS::Vertex(aCenter));
3923 gp_Ax3 anAx3 (aLoc, gp::DZ());
3924 Handle(Geom_SphericalSurface) aSphere =
3925 new Geom_SphericalSurface(anAx3, theRadius);
3928 Handle(TColStd_HSequenceOfInteger) aSeq;
3929 aSeq = getShapesOnSurfaceIDs( aSphere, aShape, aShapeType, theState );
3931 // The GetShapesOnSphere() doesn't change object so no new function is required.
3932 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theCenter)->GetLastFunction();
3934 // Make a Python command
3935 GEOM::TPythonDump(aFunction, /*append=*/true)
3936 << "listShapesOnCylinder = geompy.GetShapesOnSphereIDs"
3937 << "(" << theShape << ", " << aShapeType << ", " << theCenter << ", "
3938 << theRadius << ", " << theState << ")";
3944 //=======================================================================
3945 //function : getShapesOnQuadrangleIDs
3947 * \brief Find IDs of sub-shapes complying with given status about quadrangle
3948 * \param theShape - the shape to explore
3949 * \param theShapeType - type of sub-shape of theShape
3950 * \param theTopLeftPoint - top left quadrangle corner
3951 * \param theTopRigthPoint - top right quadrangle corner
3952 * \param theBottomLeftPoint - bottom left quadrangle corner
3953 * \param theBottomRigthPoint - bottom right quadrangle corner
3954 * \param theState - required state
3955 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
3957 //=======================================================================
3958 Handle(TColStd_HSequenceOfInteger)
3959 GEOMImpl_IShapesOperations::getShapesOnQuadrangleIDs (const Handle(GEOM_Object)& theShape,
3960 const Standard_Integer theShapeType,
3961 const Handle(GEOM_Object)& theTopLeftPoint,
3962 const Handle(GEOM_Object)& theTopRigthPoint,
3963 const Handle(GEOM_Object)& theBottomLeftPoint,
3964 const Handle(GEOM_Object)& theBottomRigthPoint,
3965 const GEOMAlgo_State theState)
3969 if ( theShape.IsNull() ||
3970 theTopLeftPoint.IsNull() ||
3971 theTopRigthPoint.IsNull() ||
3972 theBottomLeftPoint.IsNull() ||
3973 theBottomRigthPoint.IsNull() )
3976 TopoDS_Shape aShape = theShape->GetValue();
3977 TopoDS_Shape aTL = theTopLeftPoint->GetValue();
3978 TopoDS_Shape aTR = theTopRigthPoint->GetValue();
3979 TopoDS_Shape aBL = theBottomLeftPoint->GetValue();
3980 TopoDS_Shape aBR = theBottomRigthPoint->GetValue();
3982 if (aShape.IsNull() ||
3987 aTL.ShapeType() != TopAbs_VERTEX ||
3988 aTR.ShapeType() != TopAbs_VERTEX ||
3989 aBL.ShapeType() != TopAbs_VERTEX ||
3990 aBR.ShapeType() != TopAbs_VERTEX )
3993 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3994 if ( !checkTypeShapesOn( aShapeType ))
3997 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
3999 // Check presence of triangulation, build if need
4000 if (!GEOMUtils::CheckTriangulation(aShape)) {
4001 SetErrorCode("Cannot build triangulation on the shape");
4006 gp_Pnt aPntTL = BRep_Tool::Pnt(TopoDS::Vertex(aTL));
4007 gp_Pnt aPntTR = BRep_Tool::Pnt(TopoDS::Vertex(aTR));
4008 gp_Pnt aPntBL = BRep_Tool::Pnt(TopoDS::Vertex(aBL));
4009 gp_Pnt aPntBR = BRep_Tool::Pnt(TopoDS::Vertex(aBR));
4011 GEOMAlgo_FinderShapeOn2 aFinder;
4012 Handle(GEOMAlgo_ClsfQuad) aClsfQuad = new GEOMAlgo_ClsfQuad;
4014 Standard_Real aTol = 0.0001; // default value
4016 aClsfQuad->SetCorners(aPntTL, aPntTR, aPntBL, aPntBR);
4017 aFinder.SetShape(aShape);
4018 aFinder.SetTolerance(aTol);
4019 aFinder.SetClsf(aClsfQuad);
4020 aFinder.SetShapeType(aShapeType);
4021 aFinder.SetState(theState);
4023 // Sets the minimal number of inner points for the faces that do not have own
4024 // inner points at all (for e.g. rectangular planar faces have just 2 triangles).
4026 aFinder.SetNbPntsMin(3);
4027 // Sets the maximal number of inner points for edges or faces.
4028 // It is usefull for the cases when this number is very big (e.g =2000) to improve
4029 // the performance. If this value =0, all inner points will be taken into account.
4031 aFinder.SetNbPntsMax(100);
4035 // Interprete results
4036 Standard_Integer iErr = aFinder.ErrorStatus();
4037 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn2.cxx
4039 MESSAGE(" iErr : " << iErr);
4040 TCollection_AsciiString aMsg (" iErr : ");
4041 aMsg += TCollection_AsciiString(iErr);
4045 Standard_Integer iWrn = aFinder.WarningStatus();
4046 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn2.cxx
4048 MESSAGE(" *** iWrn : " << iWrn);
4051 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
4053 if (listSS.Extent() < 1) {
4054 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
4055 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
4059 // Fill sequence of object IDs
4060 aSeqOfIDs = new TColStd_HSequenceOfInteger;
4062 TopTools_IndexedMapOfShape anIndices;
4063 TopExp::MapShapes(aShape, anIndices);
4065 TopTools_ListIteratorOfListOfShape itSub (listSS);
4066 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
4067 int id = anIndices.FindIndex(itSub.Value());
4068 aSeqOfIDs->Append(id);
4073 //=======================================================================
4074 //function : GetShapesOnQuadrangle
4076 * \brief Find sub-shapes complying with given status about quadrangle
4077 * \param theShape - the shape to explore
4078 * \param theShapeType - type of sub-shape of theShape
4079 * \param theTopLeftPoint - top left quadrangle corner
4080 * \param theTopRigthPoint - top right quadrangle corner
4081 * \param theBottomLeftPoint - bottom left quadrangle corner
4082 * \param theBottomRigthPoint - bottom right quadrangle corner
4083 * \param theState - required state
4084 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
4086 //=======================================================================
4087 Handle(TColStd_HSequenceOfTransient)
4088 GEOMImpl_IShapesOperations::GetShapesOnQuadrangle (const Handle(GEOM_Object)& theShape,
4089 const Standard_Integer theShapeType,
4090 const Handle(GEOM_Object)& theTopLeftPoint,
4091 const Handle(GEOM_Object)& theTopRigthPoint,
4092 const Handle(GEOM_Object)& theBottomLeftPoint,
4093 const Handle(GEOM_Object)& theBottomRigthPoint,
4094 const GEOMAlgo_State theState)
4097 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
4098 getShapesOnQuadrangleIDs( theShape,
4103 theBottomRigthPoint,
4105 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->IsEmpty() )
4108 // Find objects by indices
4109 TCollection_AsciiString anAsciiList;
4110 Handle(TColStd_HSequenceOfTransient) aSeq;
4111 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
4112 if ( aSeq.IsNull() || aSeq->IsEmpty() )
4115 // Make a Python command
4117 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
4118 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
4120 GEOM::TPythonDump(aFunction)
4121 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnQuadrangle("
4123 << TopAbs_ShapeEnum(theShapeType) << ", "
4124 << theTopLeftPoint << ", "
4125 << theTopRigthPoint << ", "
4126 << theBottomLeftPoint << ", "
4127 << theBottomRigthPoint << ", "
4134 //=======================================================================
4135 //function : GetShapesOnQuadrangleIDs
4137 * \brief Find IDs of sub-shapes complying with given status about quadrangle
4138 * \param theShape - the shape to explore
4139 * \param theShapeType - type of sub-shape of theShape
4140 * \param theTopLeftPoint - top left quadrangle corner
4141 * \param theTopRigthPoint - top right quadrangle corner
4142 * \param theBottomLeftPoint - bottom left quadrangle corner
4143 * \param theBottomRigthPoint - bottom right quadrangle corner
4144 * \param theState - required state
4145 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
4147 //=======================================================================
4148 Handle(TColStd_HSequenceOfInteger)
4149 GEOMImpl_IShapesOperations::GetShapesOnQuadrangleIDs (const Handle(GEOM_Object)& theShape,
4150 const Standard_Integer theShapeType,
4151 const Handle(GEOM_Object)& theTopLeftPoint,
4152 const Handle(GEOM_Object)& theTopRigthPoint,
4153 const Handle(GEOM_Object)& theBottomLeftPoint,
4154 const Handle(GEOM_Object)& theBottomRigthPoint,
4155 const GEOMAlgo_State theState)
4158 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
4159 getShapesOnQuadrangleIDs( theShape,
4164 theBottomRigthPoint,
4166 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->IsEmpty() )
4169 // Make a Python command
4171 // The GetShapesOnCylinder() doesn't change object so no new function is required.
4172 Handle(GEOM_Object) lastObj = GEOM::GetCreatedLast(theShape,theTopLeftPoint);
4173 lastObj = GEOM::GetCreatedLast(lastObj,theTopRigthPoint);
4174 lastObj = GEOM::GetCreatedLast(lastObj,theBottomRigthPoint);
4175 lastObj = GEOM::GetCreatedLast(lastObj,theBottomLeftPoint);
4176 Handle(GEOM_Function) aFunction = lastObj->GetLastFunction();
4178 GEOM::TPythonDump(aFunction, /*append=*/true)
4179 << "listShapesOnQuadrangle = geompy.GetShapesOnQuadrangleIDs("
4181 << TopAbs_ShapeEnum(theShapeType) << ", "
4182 << theTopLeftPoint << ", "
4183 << theTopRigthPoint << ", "
4184 << theBottomLeftPoint << ", "
4185 << theBottomRigthPoint << ", "
4192 //=============================================================================
4197 //=============================================================================
4198 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlace (Handle(GEOM_Object) theShapeWhere,
4199 Handle(GEOM_Object) theShapeWhat)
4203 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
4205 TopoDS_Shape aWhere = theShapeWhere->GetValue();
4206 TopoDS_Shape aWhat = theShapeWhat->GetValue();
4208 if (aWhere.IsNull() || aWhat.IsNull()) {
4209 SetErrorCode("Error: aWhere and aWhat TopoDS_Shape are Null.");
4213 // Searching for the sub-shapes inside the ShapeWhere shape
4214 GEOMAlgo_GetInPlace aGIP;
4216 if (!GEOMAlgo_GetInPlaceAPI::GetInPlace(aWhere, aWhat, aGIP)) {
4217 SetErrorCode("Error in GEOMAlgo_GetInPlace");
4221 // Add direct result.
4222 TopTools_ListOfShape aLSA;
4223 const TopoDS_Shape &aShapeResult = aGIP.Result();
4224 TopTools_MapOfShape aMFence;
4225 TopTools_IndexedMapOfShape aWhereIndices;
4226 Standard_Integer aShapeType = -1;
4228 TopExp::MapShapes(aWhere, aWhereIndices);
4230 if (aShapeResult.IsNull() == Standard_False) {
4231 TopoDS_Iterator anIt(aShapeResult);
4232 Standard_Boolean isFirst = Standard_True;
4234 for (; anIt.More(); anIt.Next()) {
4235 const TopoDS_Shape &aPart = anIt.Value();
4237 if(aWhereIndices.Contains(aPart) && aMFence.Add(aPart)) {
4238 const TopAbs_ShapeEnum aType = aPart.ShapeType();
4240 if (aShapeType == -1) {
4243 } else if (aShapeType != TopAbs_SHAPE && aShapeType != aType) {
4245 aShapeType = TopAbs_SHAPE;
4253 if (aLSA.Extent() == 0) {
4254 SetErrorCode(NOT_FOUND_ANY); // Not found any Results
4258 Handle(TColStd_HArray1OfInteger) aModifiedArray = new TColStd_HArray1OfInteger (1, aLSA.Extent());
4259 TopTools_ListIteratorOfListOfShape anIterModif (aLSA);
4260 for (Standard_Integer imod = 1; anIterModif.More(); anIterModif.Next(), imod++) {
4261 aModifiedArray->SetValue(imod, aWhereIndices.FindIndex(anIterModif.Value()));
4265 Handle(GEOM_Object) aResult = GetEngine()->AddSubShape(theShapeWhere, aModifiedArray);
4266 if (aResult.IsNull()) {
4267 SetErrorCode("Error in algorithm: result found, but cannot be returned.");
4271 const Standard_Boolean isSameType = (aShapeType != TopAbs_SHAPE);
4273 if ((aModifiedArray->Length() > 1 && isSameType) ||
4274 theShapeWhat->GetType() == GEOM_GROUP) {
4276 aResult->SetType(GEOM_GROUP);
4278 //Set a sub-shape type
4279 TopoDS_Shape aFirstFound = aLSA.First();
4280 TopAbs_ShapeEnum aShapeType = aFirstFound.ShapeType();
4282 TDF_Label aFreeLabel = aResult->GetFreeLabel();
4283 TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aShapeType);
4286 //Make a Python command
4287 Handle(GEOM_Function) aFunction = aResult->GetFunction(1);
4289 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetInPlace("
4290 << theShapeWhere << ", " << theShapeWhat << ", True)";
4296 //=============================================================================
4298 * case GetInPlaceOld:
4301 //=============================================================================
4302 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlaceOld
4303 (Handle(GEOM_Object) theShapeWhere,
4304 Handle(GEOM_Object) theShapeWhat)
4308 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
4310 TopoDS_Shape aWhere = theShapeWhere->GetValue();
4311 TopoDS_Shape aWhat = theShapeWhat->GetValue();
4312 TopTools_ListOfShape aModifiedList;
4313 const Standard_Integer iErr =
4314 GEOMAlgo_GetInPlaceAPI::GetInPlaceOld(aWhere, aWhat, aModifiedList);
4319 SetErrorCode("Error: aWhere and aWhat TopoDS_Shape are Null.");
4323 ("Error: An attempt to extract a shape of not supported type.");
4326 SetErrorCode(NOT_FOUND_ANY);
4329 SetErrorCode("Shape driver failed");
4336 TopTools_IndexedMapOfShape aWhereIndices;
4337 TopExp::MapShapes(aWhere, aWhereIndices);
4339 Handle(TColStd_HArray1OfInteger) aModifiedArray =
4340 new TColStd_HArray1OfInteger (1, aModifiedList.Extent());
4341 TopTools_ListIteratorOfListOfShape anIterModif (aModifiedList);
4342 Standard_Integer imod;
4343 Standard_Integer aShapeType = -1;
4345 for (imod = 1; anIterModif.More(); anIterModif.Next(), imod++) {
4346 const Standard_Integer anIndex =
4347 aWhereIndices.FindIndex(anIterModif.Value());
4348 const TopAbs_ShapeEnum aType = anIterModif.Value().ShapeType();
4350 if (aShapeType == -1) {
4353 } else if (aShapeType != TopAbs_SHAPE && aShapeType != aType) {
4355 aShapeType = TopAbs_SHAPE;
4358 aModifiedArray->SetValue(imod, anIndex);
4362 Handle(GEOM_Object) aResult =
4363 GetEngine()->AddSubShape(theShapeWhere, aModifiedArray);
4365 if (aResult.IsNull()) {
4366 SetErrorCode("Error in algorithm: result found, but cannot be returned.");
4370 const Standard_Boolean isSameType = (aShapeType != TopAbs_SHAPE);
4372 if ((aModifiedArray->Length() > 1 && isSameType) ||
4373 theShapeWhat->GetType() == GEOM_GROUP) {
4375 aResult->SetType(GEOM_GROUP);
4377 //Set a sub-shape type
4378 TopoDS_Shape aFirstFound = aWhereIndices.FindKey(aModifiedArray->Value(1));
4379 TopAbs_ShapeEnum aShapeType = aFirstFound.ShapeType();
4381 TDF_Label aFreeLabel = aResult->GetFreeLabel();
4382 TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aShapeType);
4385 //Make a Python command
4386 Handle(GEOM_Function) aFunction = aResult->GetFunction(1);
4388 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetInPlace("
4389 << theShapeWhere << ", " << theShapeWhat << ", False)";
4396 //=======================================================================
4397 //function : GetInPlaceByHistory
4399 //=======================================================================
4400 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlaceByHistory
4401 (Handle(GEOM_Object) theShapeWhere,
4402 Handle(GEOM_Object) theShapeWhat)
4406 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
4408 TopoDS_Shape aWhere = theShapeWhere->GetValue();
4409 TopoDS_Shape aWhat = theShapeWhat->GetValue();
4411 if (aWhere.IsNull() || aWhat.IsNull()) return NULL;
4413 Handle(GEOM_Function) aWhereFunction = theShapeWhere->GetLastFunction();
4414 if (aWhereFunction.IsNull()) return NULL;
4416 //Fill array of indices
4417 TopTools_IndexedMapOfShape aWhereIndices;
4419 TopExp::MapShapes(aWhere, aWhereIndices);
4422 TopTools_ListOfShape aModifiedList;
4423 bool isFound = GEOMAlgo_GetInPlaceAPI::GetInPlaceByHistory
4424 (aWhereFunction, aWhereIndices, aWhat, aModifiedList);
4426 if (!isFound || aModifiedList.Extent() < 1) {
4427 SetErrorCode("Error: No history found for the sought shape or its sub-shapes.");
4431 Handle(TColStd_HArray1OfInteger) aModifiedArray =
4432 new TColStd_HArray1OfInteger (1, aModifiedList.Extent());
4433 TopTools_ListIteratorOfListOfShape anIterModif (aModifiedList);
4434 Standard_Integer imod;
4435 Standard_Integer aShapeType = -1;
4437 for (imod = 1; anIterModif.More(); anIterModif.Next(), imod++) {
4438 const Standard_Integer anIndex =
4439 aWhereIndices.FindIndex(anIterModif.Value());
4440 const TopAbs_ShapeEnum aType = anIterModif.Value().ShapeType();
4442 if (aShapeType == -1) {
4445 } else if (aShapeType != TopAbs_SHAPE && aShapeType != aType) {
4447 aShapeType = TopAbs_SHAPE;
4450 aModifiedArray->SetValue(imod, anIndex);
4454 Handle(GEOM_Object) aResult = GetEngine()->AddSubShape(theShapeWhere, aModifiedArray);
4455 if (aResult.IsNull()) {
4456 SetErrorCode("Error in algorithm: result found, but cannot be returned.");
4460 const Standard_Boolean isSameType = (aShapeType != TopAbs_SHAPE);
4462 if ((aModifiedArray->Length() > 1 && isSameType) ||
4463 theShapeWhat->GetType() == GEOM_GROUP) {
4465 aResult->SetType(GEOM_GROUP);
4467 //Set a sub-shape type
4468 TopoDS_Shape aFirstFound = aWhereIndices.FindKey(aModifiedArray->Value(1));
4469 TopAbs_ShapeEnum aShapeType = aFirstFound.ShapeType();
4471 TDF_Label aFreeLabel = aResult->GetFreeLabel();
4472 TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aShapeType);
4475 //Make a Python command
4476 Handle(GEOM_Function) aFunction = aResult->GetFunction(1);
4478 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetInPlaceByHistory("
4479 << theShapeWhere << ", " << theShapeWhat << ")";
4485 //=======================================================================
4486 //function : isSameEdge
4487 //purpose : Returns True if two edges coincide
4488 //=======================================================================
4489 static bool isSameEdge(const TopoDS_Edge& theEdge1, const TopoDS_Edge& theEdge2)
4491 TopoDS_Vertex V11, V12, V21, V22;
4492 TopExp::Vertices(theEdge1, V11, V12);
4493 TopExp::Vertices(theEdge2, V21, V22);
4494 gp_Pnt P11 = BRep_Tool::Pnt(V11);
4495 gp_Pnt P12 = BRep_Tool::Pnt(V12);
4496 gp_Pnt P21 = BRep_Tool::Pnt(V21);
4497 gp_Pnt P22 = BRep_Tool::Pnt(V22);
4498 bool coincide = false;
4500 //Check that ends of edges coincide
4501 if(P11.Distance(P21) <= MAX_TOLERANCE) {
4502 if(P12.Distance(P22) <= MAX_TOLERANCE) coincide = true;
4504 else if(P11.Distance(P22) <= MAX_TOLERANCE) {
4505 if(P12.Distance(P21) <= MAX_TOLERANCE) coincide = true;
4508 if(!coincide) return false;
4510 if (BRep_Tool::Degenerated(theEdge1))
4511 if (BRep_Tool::Degenerated(theEdge2)) return true;
4514 if (BRep_Tool::Degenerated(theEdge2)) return false;
4516 double U11, U12, U21, U22;
4517 Handle(Geom_Curve) C1 = BRep_Tool::Curve(theEdge1, U11, U12);
4518 Handle(Geom_Curve) C2 = BRep_Tool::Curve(theEdge2, U21, U22);
4520 //Check that both edges has the same geometry
4521 double range = U12-U11;
4522 double U = U11+ range/3.0;
4523 gp_Pnt P1 = C1->Value(U); //Compute a point on one third of the edge's length
4524 U = U11+range*2.0/3.0;
4525 gp_Pnt P2 = C1->Value(U); //Compute a point on two thirds of the edge's length
4527 if(!GeomLib_Tool::Parameter(C2, P1, MAX_TOLERANCE, U) || U < U21 || U > U22)
4530 if(P1.Distance(C2->Value(U)) > MAX_TOLERANCE) return false;
4532 if(!GeomLib_Tool::Parameter(C2, P2, MAX_TOLERANCE, U) || U < U21 || U > U22)
4535 if(P2.Distance(C2->Value(U)) > MAX_TOLERANCE) return false;
4540 #include <TopoDS_TShape.hxx>
4541 //=======================================================================
4542 //function : isSameFace
4543 //purpose : Returns True if two faces coincide
4544 //=======================================================================
4545 static bool isSameFace(const TopoDS_Face& theFace1, const TopoDS_Face& theFace2)
4547 TopExp_Explorer E(theFace1, TopAbs_EDGE);
4548 TopTools_ListOfShape LS1, LS2;
4549 for(; E.More(); E.Next()) LS1.Append(E.Current());
4551 E.Init(theFace2, TopAbs_EDGE);
4552 for(; E.More(); E.Next()) LS2.Append(E.Current());
4554 //Compare the number of edges in the faces
4555 if(LS1.Extent() != LS2.Extent()) return false;
4557 double aMin = RealFirst(), aMax = RealLast();
4558 double xminB1=aMax, yminB1=aMax, zminB1=aMax, xminB2=aMax, yminB2=aMax, zminB2=aMax;
4559 double xmaxB1=aMin, ymaxB1=aMin, zmaxB1=aMin, xmaxB2=aMin, ymaxB2=aMin, zmaxB2=aMin;
4561 for(E.Init(theFace1, TopAbs_VERTEX); E.More(); E.Next()) {
4562 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4563 if(P.X() < xminB1) xminB1 = P.X();
4564 if(P.Y() < yminB1) yminB1 = P.Y();
4565 if(P.Z() < zminB1) zminB1 = P.Z();
4566 if(P.X() > xmaxB1) xmaxB1 = P.X();
4567 if(P.Y() > ymaxB1) ymaxB1 = P.Y();
4568 if(P.Z() > zmaxB1) zmaxB1 = P.Z();
4571 for(E.Init(theFace2, TopAbs_VERTEX); E.More(); E.Next()) {
4572 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4573 if(P.X() < xminB2) xminB2 = P.X();
4574 if(P.Y() < yminB2) yminB2 = P.Y();
4575 if(P.Z() < zminB2) zminB2 = P.Z();
4576 if(P.X() > xmaxB2) xmaxB2 = P.X();
4577 if(P.Y() > ymaxB2) ymaxB2 = P.Y();
4578 if(P.Z() > zmaxB2) zmaxB2 = P.Z();
4581 //Compare the bounding boxes of both faces
4582 if(gp_Pnt(xminB1, yminB1, zminB1).Distance(gp_Pnt(xminB2, yminB2, zminB2)) > MAX_TOLERANCE)
4585 if(gp_Pnt(xmaxB1, ymaxB1, zmaxB1).Distance(gp_Pnt(xmaxB2, ymaxB2, zmaxB2)) > MAX_TOLERANCE)
4588 Handle(Geom_Surface) S1 = BRep_Tool::Surface(theFace1);
4589 Handle(Geom_Surface) S2 = BRep_Tool::Surface(theFace2);
4591 //Check if there a coincidence of two surfaces at least in two points
4592 double U11, U12, V11, V12, U21, U22, V21, V22;
4593 BRepTools::UVBounds(theFace1, U11, U12, V11, V12);
4594 BRepTools::UVBounds(theFace2, U21, U22, V21, V22);
4596 double rangeU = U12-U11;
4597 double rangeV = V12-V11;
4598 double U = U11 + rangeU/3.0;
4599 double V = V11 + rangeV/3.0;
4600 gp_Pnt P1 = S1->Value(U, V);
4601 U = U11+rangeU*2.0/3.0;
4602 V = V11+rangeV*2.0/3.0;
4603 gp_Pnt P2 = S1->Value(U, V);
4605 if (!GeomLib_Tool::Parameters(S2, P1, MAX_TOLERANCE, U, V) || U < U21 || U > U22 || V < V21 || V > V22)
4608 if (P1.Distance(S2->Value(U,V)) > MAX_TOLERANCE) return false;
4610 if (!GeomLib_Tool::Parameters(S2, P2, MAX_TOLERANCE, U, V) || U < U21 || U > U22 || V < V21 || V > V22)
4613 if (P2.Distance(S2->Value(U, V)) > MAX_TOLERANCE) return false;
4615 //Check that each edge of the Face1 has a counterpart in the Face2
4616 TopTools_MapOfOrientedShape aMap;
4617 TopTools_ListIteratorOfListOfShape LSI1(LS1);
4618 for(; LSI1.More(); LSI1.Next()) {
4619 TopoDS_Edge E = TopoDS::Edge(LSI1.Value());
4620 bool isFound = false;
4621 TopTools_ListIteratorOfListOfShape LSI2(LS2);
4622 for(; LSI2.More(); LSI2.Next()) {
4623 TopoDS_Shape aValue = LSI2.Value();
4624 if(aMap.Contains(aValue)) continue; //To avoid checking already found edge several times
4625 if(isSameEdge(E, TopoDS::Edge(aValue))) {
4631 if(!isFound) return false;
4637 //=======================================================================
4638 //function : isSameSolid
4639 //purpose : Returns True if two solids coincide
4640 //=======================================================================
4641 bool isSameSolid(const TopoDS_Solid& theSolid1, const TopoDS_Solid& theSolid2)
4643 TopExp_Explorer E(theSolid1, TopAbs_FACE);
4644 TopTools_ListOfShape LS1, LS2;
4645 for(; E.More(); E.Next()) LS1.Append(E.Current());
4646 E.Init(theSolid2, TopAbs_FACE);
4647 for(; E.More(); E.Next()) LS2.Append(E.Current());
4649 if(LS1.Extent() != LS2.Extent()) return false;
4651 double aMin = RealFirst(), aMax = RealLast();
4652 double xminB1=aMax, yminB1=aMax, zminB1=aMax, xminB2=aMax, yminB2=aMax, zminB2=aMax;
4653 double xmaxB1=aMin, ymaxB1=aMin, zmaxB1=aMin, xmaxB2=aMin, ymaxB2=aMin, zmaxB2=aMin;
4655 for(E.Init(theSolid1, TopAbs_VERTEX); E.More(); E.Next()) {
4656 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4657 if(P.X() < xminB1) xminB1 = P.X();
4658 if(P.Y() < yminB1) yminB1 = P.Y();
4659 if(P.Z() < zminB1) zminB1 = P.Z();
4660 if(P.X() > xmaxB1) xmaxB1 = P.X();
4661 if(P.Y() > ymaxB1) ymaxB1 = P.Y();
4662 if(P.Z() > zmaxB1) zmaxB1 = P.Z();
4665 for(E.Init(theSolid2, TopAbs_VERTEX); E.More(); E.Next()) {
4666 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4667 if(P.X() < xminB2) xminB2 = P.X();
4668 if(P.Y() < yminB2) yminB2 = P.Y();
4669 if(P.Z() < zminB2) zminB2 = P.Z();
4670 if(P.X() > xmaxB2) xmaxB2 = P.X();
4671 if(P.Y() > ymaxB2) ymaxB2 = P.Y();
4672 if(P.Z() > zmaxB2) zmaxB2 = P.Z();
4675 //Compare the bounding boxes of both solids
4676 if(gp_Pnt(xminB1, yminB1, zminB1).Distance(gp_Pnt(xminB2, yminB2, zminB2)) > MAX_TOLERANCE)
4679 if(gp_Pnt(xmaxB1, ymaxB1, zmaxB1).Distance(gp_Pnt(xmaxB2, ymaxB2, zmaxB2)) > MAX_TOLERANCE)
4682 //Check that each face of the Solid1 has a counterpart in the Solid2
4683 TopTools_MapOfOrientedShape aMap;
4684 TopTools_ListIteratorOfListOfShape LSI1(LS1);
4685 for(; LSI1.More(); LSI1.Next()) {
4686 TopoDS_Face F = TopoDS::Face(LSI1.Value());
4687 bool isFound = false;
4688 TopTools_ListIteratorOfListOfShape LSI2(LS2);
4689 for(; LSI2.More(); LSI2.Next()) {
4690 if(aMap.Contains(LSI2.Value())) continue; //To avoid checking already found faces several times
4691 if(isSameFace(F, TopoDS::Face(LSI2.Value()))) {
4692 aMap.Add(LSI2.Value());
4697 if(!isFound) return false;
4703 //=======================================================================
4704 //function : GetSame
4706 //=======================================================================
4707 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetSame(const Handle(GEOM_Object)& theShapeWhere,
4708 const Handle(GEOM_Object)& theShapeWhat)
4711 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
4713 TopoDS_Shape aWhere = theShapeWhere->GetValue();
4714 TopoDS_Shape aWhat = theShapeWhat->GetValue();
4716 if (aWhere.IsNull() || aWhat.IsNull()) return NULL;
4719 bool isFound = false;
4720 TopoDS_Shape aSubShape;
4721 TopTools_MapOfShape aMap;
4723 if (aWhat.ShapeType() == TopAbs_COMPOUND || aWhat.ShapeType() == TopAbs_COMPSOLID) {
4724 TopoDS_Iterator It (aWhat, Standard_True, Standard_True);
4725 if (It.More()) aWhat = It.Value();
4728 SetErrorCode("Compounds of two or more shapes are not allowed for aWhat argument");
4733 switch (aWhat.ShapeType()) {
4734 case TopAbs_VERTEX: {
4735 aSubShape = getSameVertex(aWhere, TopoDS::Vertex(aWhat));
4736 isFound = !aSubShape.IsNull();
4740 TopoDS_Edge anEdge = TopoDS::Edge(aWhat);
4741 TopExp_Explorer E(aWhere, TopAbs_EDGE);
4742 for(; E.More(); E.Next()) {
4743 if(!aMap.Add(E.Current())) continue;
4744 if(isSameEdge(anEdge, TopoDS::Edge(E.Current()))) {
4745 aSubShape = E.Current();
4753 TopoDS_Face aFace = TopoDS::Face(aWhat);
4754 TopExp_Explorer E(aWhere, TopAbs_FACE);
4755 for(; E.More(); E.Next()) {
4756 if(!aMap.Add(E.Current())) continue;
4757 if(isSameFace(aFace, TopoDS::Face(E.Current()))) {
4758 aSubShape = E.Current();
4765 case TopAbs_SOLID: {
4766 TopoDS_Solid aSolid = TopoDS::Solid(aWhat);
4767 TopExp_Explorer E(aWhere, TopAbs_SOLID);
4768 for(; E.More(); E.Next()) {
4769 if(!aMap.Add(E.Current())) continue;
4770 if(isSameSolid(aSolid, TopoDS::Solid(E.Current()))) {
4771 aSubShape = E.Current();
4783 TopTools_IndexedMapOfShape anIndices;
4784 TopExp::MapShapes(aWhere, anIndices);
4785 if (anIndices.Contains(aSubShape))
4786 anIndex = anIndices.FindIndex(aSubShape);
4789 if (anIndex < 0) return NULL;
4791 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
4793 anArray->SetValue(1, anIndex);
4795 Handle(GEOM_Object) aResult = GetEngine()->AddSubShape(theShapeWhere, anArray);
4796 Handle(GEOM_Function) aFunction = aResult->GetLastFunction();
4798 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetSame("
4799 << theShapeWhere << ", " << theShapeWhat << ")";
4807 //=======================================================================
4808 //function : GetSameIDs
4810 //=======================================================================
4811 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetSameIDs
4812 (const Handle(GEOM_Object)& theShapeWhere,
4813 const Handle(GEOM_Object)& theShapeWhat)
4816 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
4818 TopoDS_Shape aWhere = theShapeWhere->GetValue();
4819 TopoDS_Shape aWhat = theShapeWhat->GetValue();
4821 if (aWhere.IsNull() || aWhat.IsNull()) return NULL;
4823 TopTools_ListOfShape listShape;
4824 TopTools_MapOfShape aMap;
4826 if (aWhat.ShapeType() == TopAbs_COMPOUND || aWhat.ShapeType() == TopAbs_COMPSOLID) {
4827 TopoDS_Iterator It (aWhat, Standard_True, Standard_True);
4828 if (It.More()) aWhat = It.Value();
4831 SetErrorCode("Compounds of two or more shapes are not allowed for aWhat argument");
4836 switch (aWhat.ShapeType()) {
4837 case TopAbs_VERTEX: {
4838 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(aWhat));
4839 TopExp_Explorer E(aWhere, TopAbs_VERTEX);
4840 for(; E.More(); E.Next()) {
4841 if(!aMap.Add(E.Current())) continue;
4842 gp_Pnt P2 = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4843 if(P.Distance(P2) <= MAX_TOLERANCE) {
4844 listShape.Append(E.Current());
4850 TopoDS_Edge anEdge = TopoDS::Edge(aWhat);
4851 TopExp_Explorer E(aWhere, TopAbs_EDGE);
4852 for(; E.More(); E.Next()) {
4853 if(!aMap.Add(E.Current())) continue;
4854 if(isSameEdge(anEdge, TopoDS::Edge(E.Current()))) {
4855 listShape.Append(E.Current());
4861 TopoDS_Face aFace = TopoDS::Face(aWhat);
4862 TopExp_Explorer E(aWhere, TopAbs_FACE);
4863 for(; E.More(); E.Next()) {
4864 if(!aMap.Add(E.Current())) continue;
4865 if(isSameFace(aFace, TopoDS::Face(E.Current()))) {
4866 listShape.Append(E.Current());
4871 case TopAbs_SOLID: {
4872 TopoDS_Solid aSolid = TopoDS::Solid(aWhat);
4873 TopExp_Explorer E(aWhere, TopAbs_SOLID);
4874 for(; E.More(); E.Next()) {
4875 if(!aMap.Add(E.Current())) continue;
4876 if(isSameSolid(aSolid, TopoDS::Solid(E.Current()))) {
4877 listShape.Append(E.Current());
4886 if ( !listShape.IsEmpty() ) {
4887 TopTools_IndexedMapOfShape anIndices;
4888 TopExp::MapShapes(aWhere, anIndices);
4889 TopTools_ListIteratorOfListOfShape itSub (listShape);
4890 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
4891 for (; itSub.More(); itSub.Next()) {
4892 if (anIndices.Contains(itSub.Value()))
4893 aSeq->Append(anIndices.FindIndex(itSub.Value()));
4896 // The GetSameIDs() doesn't change object so no new function is required.
4897 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShapeWhere,theShapeWhat)->GetLastFunction();
4899 // Make a Python command
4900 GEOM::TPythonDump(aFunction, /*append=*/true)
4901 << "listSameIDs = geompy.GetSameIDs("
4902 << theShapeWhere << ", "
4903 << theShapeWhat << ")";
4906 SetErrorCode(NOT_FOUND_ANY);
4911 //=======================================================================
4912 //function : ExtendEdge
4914 //=======================================================================
4915 Handle(GEOM_Object) GEOMImpl_IShapesOperations::ExtendEdge
4916 (const Handle(GEOM_Object) &theEdge,
4917 const Standard_Real theMin,
4918 const Standard_Real theMax)
4922 if (theEdge.IsNull()) {
4926 //Add a new Edge object
4927 Handle(GEOM_Object) aResEdge = GetEngine()->AddObject(GetDocID(), GEOM_EDGE);
4929 //Add a new Vector function
4930 Handle(GEOM_Function) aFunction =
4931 aResEdge->AddFunction(GEOMImpl_ShapeDriver::GetID(), EDGE_UV);
4933 //Check if the function is set correctly
4934 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) {
4938 GEOMImpl_IShapeExtend aCI (aFunction);
4940 Handle(GEOM_Function) anEdge = theEdge->GetLastFunction();
4942 if (anEdge.IsNull()) {
4946 aCI.SetShape(anEdge);
4947 aCI.SetUMin(theMin);
4948 aCI.SetUMax(theMax);
4950 //Compute the Edge value
4953 if (!GetSolver()->ComputeFunction(aFunction)) {
4954 SetErrorCode("Shape driver failed");
4959 catch (Standard_Failure) {
4960 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
4961 SetErrorCode(aFail->GetMessageString());
4966 //Make a Python command
4967 GEOM::TPythonDump(aFunction)
4968 << aResEdge << " = geompy.ExtendEdge("
4969 << theEdge << ", " << theMin << ", " << theMax << ")";
4976 //=======================================================================
4977 //function : ExtendFace
4979 //=======================================================================
4980 Handle(GEOM_Object) GEOMImpl_IShapesOperations::ExtendFace
4981 (const Handle(GEOM_Object) &theFace,
4982 const Standard_Real theUMin,
4983 const Standard_Real theUMax,
4984 const Standard_Real theVMin,
4985 const Standard_Real theVMax)
4989 if (theFace.IsNull()) {
4993 //Add a new Face object
4994 Handle(GEOM_Object) aResFace = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
4996 //Add a new Vector function
4997 Handle(GEOM_Function) aFunction =
4998 aResFace->AddFunction(GEOMImpl_ShapeDriver::GetID(), FACE_UV);
5000 //Check if the function is set correctly
5001 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) {
5005 GEOMImpl_IShapeExtend aCI (aFunction);
5007 Handle(GEOM_Function) aFace = theFace->GetLastFunction();
5009 if (aFace.IsNull()) {
5013 aCI.SetShape(aFace);
5014 aCI.SetUMin(theUMin);
5015 aCI.SetUMax(theUMax);
5016 aCI.SetVMin(theVMin);
5017 aCI.SetVMax(theVMax);
5019 //Compute the Face value
5022 if (!GetSolver()->ComputeFunction(aFunction)) {
5023 SetErrorCode("Shape driver failed");
5028 catch (Standard_Failure) {
5029 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
5030 SetErrorCode(aFail->GetMessageString());
5035 //Make a Python command
5036 GEOM::TPythonDump(aFunction)
5037 << aResFace << " = geompy.ExtendFace("
5038 << theFace << ", " << theUMin << ", " << theUMax << ", "
5039 << theVMin << ", " << theVMax << ")";
5046 //=======================================================================
5047 //function : MakeSurfaceFromFace
5049 //=======================================================================
5050 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeSurfaceFromFace
5051 (const Handle(GEOM_Object) &theFace)
5055 if (theFace.IsNull()) {
5059 //Add a new Face object
5060 Handle(GEOM_Object) aResFace = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
5062 //Add a new Vector function
5063 Handle(GEOM_Function) aFunction =
5064 aResFace->AddFunction(GEOMImpl_ShapeDriver::GetID(), SURFACE_FROM_FACE);
5066 //Check if the function is set correctly
5067 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) {
5071 GEOMImpl_IShapeExtend aCI (aFunction);
5073 Handle(GEOM_Function) aFace = theFace->GetLastFunction();
5075 if (aFace.IsNull()) {
5079 aCI.SetShape(aFace);
5081 //Compute the Face value
5084 if (!GetSolver()->ComputeFunction(aFunction)) {
5085 SetErrorCode("Shape driver failed");
5090 catch (Standard_Failure) {
5091 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
5092 SetErrorCode(aFail->GetMessageString());
5097 //Make a Python command
5098 GEOM::TPythonDump(aFunction)
5099 << aResFace << " = geompy.MakeSurfaceFromFace("