1 // Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 // File : GEOMImpl_IShapesOperations.cxx
25 // Author : modified by Lioka RAZAFINDRAZAKA (CEA) 22/06/2007
28 //#include <Standard_Stream.hxx>
30 #include "GEOMImpl_IShapesOperations.hxx"
32 #include "GEOMImpl_Types.hxx"
34 #include "GEOMImpl_VectorDriver.hxx"
35 #include "GEOMImpl_ShapeDriver.hxx"
36 #include "GEOMImpl_GlueDriver.hxx"
37 #include "GEOMImpl_FillingDriver.hxx"
39 #include "GEOMImpl_IVector.hxx"
40 #include "GEOMImpl_IShapes.hxx"
41 #include "GEOMImpl_IShapeExtend.hxx"
42 #include "GEOMImpl_IGlue.hxx"
43 #include "GEOMImpl_IFilling.hxx"
45 #include "GEOMImpl_Block6Explorer.hxx"
46 #include "GEOMImpl_IHealingOperations.hxx"
48 #include "GEOMImpl_Gen.hxx"
50 #include "GEOM_Function.hxx"
51 #include "GEOM_ISubShape.hxx"
52 #include "GEOM_PythonDump.hxx"
54 #include "GEOMUtils.hxx"
56 #include "GEOMAlgo_ClsfBox.hxx"
57 #include "GEOMAlgo_ClsfQuad.hxx"
58 #include "GEOMAlgo_ClsfSolid.hxx"
59 #include "GEOMAlgo_ClsfSurf.hxx"
60 #include "GEOMAlgo_FinderShapeOn2.hxx"
61 #include "GEOMAlgo_GetInPlace.hxx"
62 #include "GEOMAlgo_GetInPlaceAPI.hxx"
63 #include "GEOMAlgo_GlueDetector.hxx"
65 #include <utilities.h>
67 #include <BRepAdaptor_Curve.hxx>
68 #include <BRepAdaptor_Surface.hxx>
69 #include <BRepTools.hxx>
70 #include <BRep_Builder.hxx>
71 #include <BRep_Tool.hxx>
72 #include <GeomLib_Tool.hxx>
73 #include <Geom_CylindricalSurface.hxx>
74 #include <Geom_Plane.hxx>
75 #include <Geom_SphericalSurface.hxx>
76 #include <Geom_Surface.hxx>
77 #include <Precision.hxx>
78 #include <TColStd_HArray1OfInteger.hxx>
79 #include <TDF_Tool.hxx>
80 #include <TDataStd_Integer.hxx>
81 #include <TDataStd_ListIteratorOfListOfExtendedString.hxx>
83 #include <TopExp_Explorer.hxx>
84 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
85 #include <TopTools_IndexedMapOfShape.hxx>
86 #include <TopTools_ListIteratorOfListOfShape.hxx>
87 #include <TopTools_MapOfOrientedShape.hxx>
88 #include <TopTools_MapOfShape.hxx>
89 #include <TopTools_SequenceOfShape.hxx>
91 #include <TopoDS_Compound.hxx>
92 #include <TopoDS_Edge.hxx>
93 #include <TopoDS_Face.hxx>
94 #include <TopoDS_Iterator.hxx>
95 #include <TopoDS_Shape.hxx>
96 #include <TopoDS_Solid.hxx>
97 #include <TopoDS_Vertex.hxx>
98 #include <gp_Cylinder.hxx>
103 #include <Standard_Failure.hxx>
104 #include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
108 void AddFlatSubShapes(const TopoDS_Shape& S, TopTools_ListOfShape& L, TopTools_MapOfShape& M)
110 if (S.ShapeType() != TopAbs_COMPOUND) {
114 TopoDS_Iterator It(S, Standard_True, Standard_True);
115 for (; It.More(); It.Next()) {
116 TopoDS_Shape SS = It.Value();
118 AddFlatSubShapes(SS, L, M);
126 const double MAX_TOLERANCE = 1.e-7;
129 * \brief Returns the vertex from theWhere shape that is coincident with
132 * \param theWhere the shape where the coinsident vertex is searched.
133 * \param theVertex the vertex to be searched.
134 * \return the coincident vertex if it is found. Otherwise null object.
136 static TopoDS_Vertex getSameVertex(const TopoDS_Shape &theWhere,
137 const TopoDS_Vertex &theVertex)
139 TopoDS_Vertex aResult;
140 gp_Pnt aPoint = BRep_Tool::Pnt(theVertex);
141 TopExp_Explorer anExp(theWhere, TopAbs_VERTEX);
142 TopTools_MapOfShape aMap;
144 for(; anExp.More(); anExp.Next()) {
145 const TopoDS_Shape &aLocalShape = anExp.Current();
147 if(!aMap.Add(aLocalShape)) {
151 TopoDS_Vertex aVertex = TopoDS::Vertex(aLocalShape);
152 gp_Pnt aPoint2 = BRep_Tool::Pnt(aVertex);
154 if(aPoint.Distance(aPoint2) <= MAX_TOLERANCE) {
162 } // end of namespace
164 //=============================================================================
168 //=============================================================================
169 GEOMImpl_IShapesOperations::GEOMImpl_IShapesOperations (GEOM_Engine* theEngine, int theDocID)
170 : GEOM_IOperations(theEngine, theDocID)
172 MESSAGE("GEOMImpl_IShapesOperations::GEOMImpl_IShapesOperations");
175 //=============================================================================
179 //=============================================================================
180 GEOMImpl_IShapesOperations::~GEOMImpl_IShapesOperations()
182 MESSAGE("GEOMImpl_IShapesOperations::~GEOMImpl_IShapesOperations");
185 //=============================================================================
189 //=============================================================================
190 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeEdge
191 (Handle(GEOM_Object) thePnt1, Handle(GEOM_Object) thePnt2)
195 if (thePnt1.IsNull() || thePnt2.IsNull()) return NULL;
197 //Add a new Edge object
198 Handle(GEOM_Object) anEdge = GetEngine()->AddObject(GetDocID(), GEOM_EDGE);
200 //Add a new Vector function
201 Handle(GEOM_Function) aFunction =
202 anEdge->AddFunction(GEOMImpl_VectorDriver::GetID(), VECTOR_TWO_PNT);
204 //Check if the function is set correctly
205 if (aFunction->GetDriverGUID() != GEOMImpl_VectorDriver::GetID()) return NULL;
207 GEOMImpl_IVector aPI (aFunction);
209 Handle(GEOM_Function) aRef1 = thePnt1->GetLastFunction();
210 Handle(GEOM_Function) aRef2 = thePnt2->GetLastFunction();
211 if (aRef1.IsNull() || aRef2.IsNull()) return NULL;
213 aPI.SetPoint1(aRef1);
214 aPI.SetPoint2(aRef2);
216 //Compute the Edge value
219 if (!GetSolver()->ComputeFunction(aFunction)) {
220 SetErrorCode("Vector driver failed");
224 catch (Standard_Failure) {
225 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
226 SetErrorCode(aFail->GetMessageString());
230 //Make a Python command
231 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdge("
232 << thePnt1 << ", " << thePnt2 << ")";
238 //=============================================================================
240 * MakeEdgeOnCurveByLength
242 //=============================================================================
243 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeEdgeOnCurveByLength
244 (Handle(GEOM_Object) theRefCurve,
245 const Standard_Real theLength,
246 Handle(GEOM_Object) theStartPoint)
250 if (theRefCurve.IsNull()) return NULL;
252 //Add a new Edge object
253 Handle(GEOM_Object) anEdge = GetEngine()->AddObject(GetDocID(), GEOM_EDGE);
255 //Add a new Vector function
256 Handle(GEOM_Function) aFunction =
257 anEdge->AddFunction(GEOMImpl_ShapeDriver::GetID(), EDGE_CURVE_LENGTH);
259 //Check if the function is set correctly
260 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
262 GEOMImpl_IVector aPI (aFunction);
264 Handle(GEOM_Function) aRef1 = theRefCurve->GetLastFunction();
265 if (aRef1.IsNull()) return NULL;
266 aPI.SetPoint1(aRef1);
268 if (!theStartPoint.IsNull()) {
269 Handle(GEOM_Function) aRef2 = theStartPoint->GetLastFunction();
270 aPI.SetPoint2(aRef2);
273 aPI.SetParameter(theLength);
275 //Compute the Edge value
278 if (!GetSolver()->ComputeFunction(aFunction)) {
279 SetErrorCode("Vector driver failed");
283 catch (Standard_Failure) {
284 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
285 SetErrorCode(aFail->GetMessageString());
289 //Make a Python command
290 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdgeOnCurveByLength("
291 << theRefCurve << ", " << theLength << ", " << theStartPoint << ")";
297 //=============================================================================
301 //=============================================================================
302 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeEdgeWire
303 (Handle(GEOM_Object) theWire,
304 const Standard_Real theLinearTolerance,
305 const Standard_Real theAngularTolerance)
309 if (theWire.IsNull()) return NULL;
311 //Add a new Edge object
312 Handle(GEOM_Object) anEdge = GetEngine()->AddObject(GetDocID(), GEOM_EDGE);
314 //Add a new Vector function
315 Handle(GEOM_Function) aFunction =
316 anEdge->AddFunction(GEOMImpl_ShapeDriver::GetID(), EDGE_WIRE);
318 //Check if the function is set correctly
319 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
321 GEOMImpl_IShapes aCI (aFunction);
323 Handle(GEOM_Function) aWire = theWire->GetLastFunction();
325 if (aWire.IsNull()) return NULL;
328 aCI.SetTolerance(theLinearTolerance);
329 aCI.SetAngularTolerance(theAngularTolerance);
331 //Compute the Edge value
334 if (!GetSolver()->ComputeFunction(aFunction)) {
335 SetErrorCode("Shape driver failed");
339 catch (Standard_Failure) {
340 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
341 SetErrorCode(aFail->GetMessageString());
345 const double DEF_LIN_TOL = Precision::Confusion();
346 const double DEF_ANG_TOL = Precision::Angular();
347 //Make a Python command
348 if ( theAngularTolerance == DEF_ANG_TOL ) {
349 if ( theLinearTolerance == DEF_LIN_TOL )
350 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdgeWire("
353 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdgeWire("
354 << theWire << ", " << theLinearTolerance << ")";
357 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdgeWire("
358 << theWire << ", " << theLinearTolerance << ", "
359 << theAngularTolerance << ")";
366 //=============================================================================
370 //=============================================================================
371 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeWire
372 (std::list<Handle(GEOM_Object)> theShapes,
373 const Standard_Real theTolerance)
378 Handle(GEOM_Object) aWire = GetEngine()->AddObject(GetDocID(), GEOM_WIRE);
381 Handle(GEOM_Function) aFunction =
382 aWire->AddFunction(GEOMImpl_ShapeDriver::GetID(), WIRE_EDGES);
383 if (aFunction.IsNull()) return NULL;
385 //Check if the function is set correctly
386 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
388 GEOMImpl_IShapes aCI (aFunction);
389 aCI.SetTolerance(theTolerance);
391 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
394 std::list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
395 for (; it != theShapes.end(); it++) {
396 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
397 if (aRefSh.IsNull()) {
398 SetErrorCode("NULL argument shape for the shape construction");
401 aShapesSeq->Append(aRefSh);
403 aCI.SetShapes(aShapesSeq);
408 if (!GetSolver()->ComputeFunction(aFunction)) {
409 SetErrorCode("Shape driver failed");
413 catch (Standard_Failure) {
414 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
415 SetErrorCode(aFail->GetMessageString());
419 //Make a Python command
420 GEOM::TPythonDump pd (aFunction);
421 pd << aWire << " = geompy.MakeWire([";
424 it = theShapes.begin();
425 if (it != theShapes.end()) {
427 while (it != theShapes.end()) {
428 pd << ", " << (*it++);
431 pd << "], " << theTolerance << ")";
437 //=============================================================================
441 //=============================================================================
442 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFace (Handle(GEOM_Object) theWire,
443 const bool isPlanarWanted)
447 if (theWire.IsNull()) return NULL;
449 //Add a new Face object
450 Handle(GEOM_Object) aFace = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
452 //Add a new Shape function for creation of a face from a wire
453 Handle(GEOM_Function) aFunction =
454 aFace->AddFunction(GEOMImpl_ShapeDriver::GetID(), FACE_WIRE);
455 if (aFunction.IsNull()) return NULL;
457 //Check if the function is set correctly
458 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
460 GEOMImpl_IShapes aCI (aFunction);
462 Handle(GEOM_Function) aRefWire = theWire->GetLastFunction();
464 if (aRefWire.IsNull()) return NULL;
466 aCI.SetBase(aRefWire);
467 aCI.SetIsPlanar(isPlanarWanted);
469 //Compute the Face value
470 Standard_Boolean isWarning = Standard_False;
473 if (!GetSolver()->ComputeFunction(aFunction)) {
474 SetErrorCode("Shape driver failed to compute a face");
478 catch (Standard_Failure) {
479 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
480 SetErrorCode(aFail->GetMessageString());
481 // to provide warning
482 if (!aFunction->GetValue().IsNull()) {
483 isWarning = Standard_True;
489 //Make a Python command
490 GEOM::TPythonDump(aFunction) << aFace << " = geompy.MakeFace("
491 << theWire << ", " << (int)isPlanarWanted << ")";
493 // to provide warning
494 if (!isWarning) SetErrorCode(OK);
498 //=============================================================================
502 //=============================================================================
503 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFaceWires
504 (std::list<Handle(GEOM_Object)> theShapes,
505 const bool isPlanarWanted)
510 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
513 Handle(GEOM_Function) aFunction =
514 aShape->AddFunction(GEOMImpl_ShapeDriver::GetID(), FACE_WIRES);
515 if (aFunction.IsNull()) return NULL;
517 //Check if the function is set correctly
518 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
520 GEOMImpl_IShapes aCI (aFunction);
522 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
525 std::list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
526 for (; it != theShapes.end(); it++) {
527 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
528 if (aRefSh.IsNull()) {
529 SetErrorCode("NULL argument shape for the face construction");
532 aShapesSeq->Append(aRefSh);
534 aCI.SetShapes(aShapesSeq);
536 aCI.SetIsPlanar(isPlanarWanted);
539 Standard_Boolean isWarning = Standard_False;
542 if (!GetSolver()->ComputeFunction(aFunction)) {
543 SetErrorCode("Shape driver failed");
547 catch (Standard_Failure) {
548 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
549 SetErrorCode(aFail->GetMessageString());
550 // to provide warning
551 if (!aFunction->GetValue().IsNull()) {
552 isWarning = Standard_True;
558 //Make a Python command
559 GEOM::TPythonDump pd (aFunction);
560 pd << aShape << " = geompy.MakeFaceWires([";
563 it = theShapes.begin();
564 if (it != theShapes.end()) {
566 while (it != theShapes.end()) {
567 pd << ", " << (*it++);
570 pd << "], " << (int)isPlanarWanted << ")";
572 // to provide warning
573 if (!isWarning) SetErrorCode(OK);
577 //=============================================================================
579 * MakeFaceFromSurface
581 //=============================================================================
582 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFaceFromSurface
583 (Handle(GEOM_Object) theFace,
584 Handle(GEOM_Object) theWire)
589 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
592 Handle(GEOM_Function) aFunction =
593 aShape->AddFunction(GEOMImpl_ShapeDriver::GetID(), FACE_FROM_SURFACE);
595 if (aFunction.IsNull()) {
599 //Check if the function is set correctly
600 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) {
604 GEOMImpl_IShapes aCI (aFunction);
605 Handle(TColStd_HSequenceOfTransient) aShapesSeq =
606 new TColStd_HSequenceOfTransient;
607 Handle(GEOM_Function) aRefFace = theFace->GetLastFunction();
608 Handle(GEOM_Function) aRefWire = theWire->GetLastFunction();
610 if (aRefFace.IsNull()) {
611 SetErrorCode("NULL argument face for the face construction");
615 if (aRefWire.IsNull()) {
616 SetErrorCode("NULL argument wire for the face construction");
620 aShapesSeq->Append(aRefFace);
621 aShapesSeq->Append(aRefWire);
623 aCI.SetShapes(aShapesSeq);
628 if (!GetSolver()->ComputeFunction(aFunction)) {
629 SetErrorCode("Shape driver failed");
633 catch (Standard_Failure) {
634 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
635 SetErrorCode(aFail->GetMessageString());
639 //Make a Python command
640 GEOM::TPythonDump (aFunction) << aShape
641 << " = geompy.MakeFaceFromSurface(" << theFace << ", " << theWire << ")";
648 //=============================================================================
650 * MakeFaceWithConstraints
652 //=============================================================================
653 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFaceWithConstraints
654 (std::list<Handle(GEOM_Object)> theConstraints)
659 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_FILLING);
662 Handle(GEOM_Function) aFunction =
663 aShape->AddFunction(GEOMImpl_FillingDriver::GetID(), FILLING_ON_CONSTRAINTS);
664 if (aFunction.IsNull()) return NULL;
666 //Check if the function is set correctly
667 if (aFunction->GetDriverGUID() != GEOMImpl_FillingDriver::GetID()) return NULL;
669 GEOMImpl_IFilling aCI (aFunction);
670 Handle(TColStd_HSequenceOfTransient) aConstraints = new TColStd_HSequenceOfTransient;
673 std::list<Handle(GEOM_Object)>::iterator it = theConstraints.begin();
674 while (it != theConstraints.end()) {
675 Handle(GEOM_Object) anObject = (*it);
676 if ( anObject.IsNull() || anObject->GetValue().ShapeType() != TopAbs_EDGE ) {
677 SetErrorCode("NULL argument edge for the face construction");
680 Handle(GEOM_Function) aRefSh = anObject->GetLastFunction();
681 aConstraints->Append(aRefSh);
683 if ( it != theConstraints.end() ) {
684 Handle(GEOM_Object) aFace = (*it);
685 if ( aFace.IsNull() ) {
686 // null constraint face - it is a valid case
690 if ( aFace->GetValue().ShapeType() != TopAbs_FACE )
691 // constraint face can be omitted - it is a valid case
693 // Keep the old error code as IsSubShapeBelongsTo changes it.
694 TCollection_AsciiString anOldCode = GetErrorCode();
696 if ( IsSubShapeBelongsTo( anObject, 0, aFace, 0 ) ) {
698 SetErrorCode(anOldCode);
699 aRefSh = aFace->GetLastFunction();
700 aConstraints->Append(aRefSh);
705 SetErrorCode("Face is NULL or not connected to the Edge");
710 aCI.SetShapes( aConstraints );
713 Standard_Boolean isWarning = Standard_False;
716 if (!GetSolver()->ComputeFunction(aFunction)) {
717 SetErrorCode("Shape driver failed");
721 catch (Standard_Failure) {
722 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
723 SetErrorCode(aFail->GetMessageString());
724 // to provide warning
725 if (!aFunction->GetValue().IsNull()) {
726 isWarning = Standard_True;
732 //Make a Python command
733 GEOM::TPythonDump pd (aFunction);
734 pd << aShape << " = geompy.MakeFaceWithConstraints([";
737 it = theConstraints.begin();
738 if (it != theConstraints.end() ) {
740 while (it != theConstraints.end()) {
741 Handle(GEOM_Object) anObject = (*it++);
742 if( !anObject.IsNull() )
743 pd << ", " << anObject;
748 // to provide warning
749 if (!isWarning) SetErrorCode(OK);
753 //=============================================================================
757 //=============================================================================
758 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeShell
759 (std::list<Handle(GEOM_Object)> theShapes)
761 return MakeShape(theShapes, GEOM_SHELL, SHELL_FACES, "MakeShell");
764 //=============================================================================
768 //=============================================================================
769 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeSolidShells
770 (std::list<Handle(GEOM_Object)> theShapes)
772 return MakeShape(theShapes, GEOM_SOLID, SOLID_SHELLS, "MakeSolid");
775 //=============================================================================
779 //=============================================================================
780 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeCompound
781 (std::list<Handle(GEOM_Object)> theShapes)
783 return MakeShape(theShapes, GEOM_COMPOUND, COMPOUND_SHAPES, "MakeCompound");
786 //=============================================================================
790 //=============================================================================
791 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeShape
792 (std::list<Handle(GEOM_Object)> theShapes,
793 const Standard_Integer theObjectType,
794 const Standard_Integer theFunctionType,
795 const TCollection_AsciiString& theMethodName)
800 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), theObjectType);
803 Handle(GEOM_Function) aFunction =
804 aShape->AddFunction(GEOMImpl_ShapeDriver::GetID(), theFunctionType);
805 if (aFunction.IsNull()) return NULL;
807 //Check if the function is set correctly
808 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
810 GEOMImpl_IShapes aCI (aFunction);
812 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
815 std::list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
816 for (; it != theShapes.end(); it++) {
817 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
818 if (aRefSh.IsNull()) {
819 SetErrorCode("NULL argument shape for the shape construction");
822 aShapesSeq->Append(aRefSh);
824 aCI.SetShapes(aShapesSeq);
829 if (!GetSolver()->ComputeFunction(aFunction)) {
830 SetErrorCode("Shape driver failed");
834 catch (Standard_Failure) {
835 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
836 SetErrorCode(aFail->GetMessageString());
840 //Make a Python command
841 GEOM::TPythonDump pd (aFunction);
842 pd << aShape << " = geompy." << theMethodName.ToCString() << "([";
845 it = theShapes.begin();
846 if (it != theShapes.end()) {
848 while (it != theShapes.end()) {
849 pd << ", " << (*it++);
858 //=============================================================================
860 * MakeSolidFromConnectedFaces
862 //=============================================================================
863 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeSolidFromConnectedFaces
864 (std::list<Handle(GEOM_Object)> theFacesOrShells,
865 const Standard_Boolean isIntersect)
870 Handle(GEOM_Object) aSolid = GetEngine()->AddObject(GetDocID(), GEOM_SOLID);
873 Handle(GEOM_Function) aFunction =
874 aSolid->AddFunction(GEOMImpl_ShapeDriver::GetID(), SOLID_FACES);
875 if (aFunction.IsNull()) return NULL;
877 //Check if the function is set correctly
878 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
880 GEOMImpl_IShapes aCI (aFunction);
882 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
885 std::list<Handle(GEOM_Object)>::iterator it = theFacesOrShells.begin();
886 for (; it != theFacesOrShells.end(); it++) {
887 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
888 if (aRefSh.IsNull()) {
889 SetErrorCode("NULL argument shape for the shape construction");
892 aShapesSeq->Append(aRefSh);
894 aCI.SetShapes(aShapesSeq);
895 aCI.SetIsIntersect(isIntersect);
900 if (!GetSolver()->ComputeFunction(aFunction)) {
901 SetErrorCode("Shape driver failed");
905 catch (Standard_Failure) {
906 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
907 SetErrorCode(aFail->GetMessageString());
911 //Make a Python command
912 GEOM::TPythonDump pd (aFunction);
913 pd << aSolid << " = geompy.MakeSolidFromConnectedFaces([";
916 it = theFacesOrShells.begin();
917 if (it != theFacesOrShells.end()) {
919 while (it != theFacesOrShells.end()) {
920 pd << ", " << (*it++);
923 pd << "]," << (isIntersect ? "True" : "False") << ")";
929 //=============================================================================
933 //=============================================================================
935 GEOMImpl_IShapesOperations::MakeGlueFaces (std::list< Handle(GEOM_Object) >& theShapes,
936 const Standard_Real theTolerance,
937 const Standard_Boolean doKeepNonSolids)
941 Handle(TColStd_HSequenceOfTransient) objects = GEOM_Object::GetLastFunctions( theShapes );
942 if ( objects.IsNull() || objects->IsEmpty() ) {
943 SetErrorCode("NULL argument shape");
947 //Add a new Glued object
948 Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
950 //Add a new Glue function
951 Handle(GEOM_Function) aFunction;
952 aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_FACES);
953 if (aFunction.IsNull()) return NULL;
955 //Check if the function is set correctly
956 if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
958 GEOMImpl_IGlue aCI (aFunction);
960 aCI.SetBase( objects );
961 aCI.SetTolerance(theTolerance);
962 aCI.SetKeepNonSolids(doKeepNonSolids);
964 //Compute the sub-shape value
965 Standard_Boolean isWarning = Standard_False;
968 if (!GetSolver()->ComputeFunction(aFunction)) {
969 SetErrorCode("Shape driver failed to glue faces");
973 catch (Standard_Failure) {
974 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
975 SetErrorCode(aFail->GetMessageString());
976 // to provide warning
977 if (!aFunction->GetValue().IsNull()) {
978 isWarning = Standard_True;
984 //Make a Python command
985 GEOM::TPythonDump(aFunction) << aGlued << " = geompy.MakeGlueFaces("
986 << theShapes << ", " << theTolerance << ")";
988 // to provide warning
989 if (!isWarning) SetErrorCode(OK);
993 //=============================================================================
997 //=============================================================================
999 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetGlueFaces
1000 (Handle(GEOM_Object) theShape,
1001 const Standard_Real theTolerance)
1005 if (theShape.IsNull()) return NULL;
1006 TopoDS_Shape aShape = theShape->GetValue();
1007 if (aShape.IsNull()) return NULL;
1009 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1011 Standard_Integer iErr;
1013 GEOMAlgo_Gluer1 aGluer;
1014 GEOMAlgo_ListIteratorOfListOfCoupleOfShapes aItCS;
1015 GEOMAlgo_CoupleOfShapes aCS;
1016 GEOMAlgo_ListOfCoupleOfShapes aLCS;
1018 //aGluer = new GEOMAlgo_Gluer1;
1019 aGluer.SetShape(aShape);
1020 aGluer.SetTolerance(theTolerance);
1022 iErr = aGluer.ErrorStatus();
1023 if (iErr) return NULL;
1025 TopTools_ListOfShape listShape;
1026 const GEOMAlgo_ListOfCoupleOfShapes& aLCSG = aGluer.GluedFaces();
1028 aItCS.Initialize(aLCSG);
1029 for (; aItCS.More(); aItCS.Next()) {
1030 const GEOMAlgo_CoupleOfShapes& aCSG = aItCS.Value();
1031 listShape.Append(aCSG.Shape1());
1034 TopTools_ListIteratorOfListOfShape itSub (listShape);
1035 TCollection_AsciiString anAsciiList, anEntry;
1036 TopTools_IndexedMapOfShape anIndices;
1037 TopExp::MapShapes(aShape, anIndices);
1038 Handle(TColStd_HArray1OfInteger) anArray;
1039 Handle(GEOM_Object) anObj;
1040 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
1041 TopoDS_Shape aValue = itSub.Value();
1042 anArray = new TColStd_HArray1OfInteger(1,1);
1043 anArray->SetValue(1, anIndices.FindIndex(aValue));
1044 anObj = GetEngine()->AddSubShape(theShape, anArray);
1045 if (!anObj.IsNull()) {
1046 aSeq->Append(anObj);
1048 // for python command
1049 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
1050 anAsciiList += anEntry;
1055 //Make a Python command
1056 if( anAsciiList.Length() > 0 ) {
1057 anAsciiList.Trunc(anAsciiList.Length() - 1);
1058 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
1059 GEOM::TPythonDump pd (aFunction, true);
1060 pd << "[" << anAsciiList.ToCString();
1061 pd << "] = geompy.GetGlueFaces(" << theShape << ", " << theTolerance << ")";
1070 //=============================================================================
1072 * MakeGlueFacesByList
1074 //=============================================================================
1076 GEOMImpl_IShapesOperations::MakeGlueFacesByList(std::list< Handle(GEOM_Object) >& theShapes,
1077 const Standard_Real theTolerance,
1078 std::list<Handle(GEOM_Object)> & theFaces,
1079 const Standard_Boolean doKeepNonSolids,
1080 const Standard_Boolean doGlueAllEdges)
1084 Handle(TColStd_HSequenceOfTransient) objects = GEOM_Object::GetLastFunctions( theShapes );
1085 if ( objects.IsNull() || objects->IsEmpty() ) {
1086 SetErrorCode("NULL argument shape");
1089 Handle(TColStd_HSequenceOfTransient) aFaces = GEOM_Object::GetLastFunctions( theFaces );
1090 if ( aFaces.IsNull() ) {
1091 SetErrorCode("NULL argument shape for the shape construction");
1095 //Add a new Glued object
1096 Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
1098 //Add a new Glue function
1099 Handle(GEOM_Function) aFunction;
1100 aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_FACES_BY_LIST);
1101 if (aFunction.IsNull()) return NULL;
1103 //Check if the function is set correctly
1104 if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
1106 GEOMImpl_IGlue aCI (aFunction);
1108 aCI.SetBase( objects );
1109 aCI.SetTolerance(theTolerance);
1110 aCI.SetKeepNonSolids(doKeepNonSolids);
1111 aCI.SetGlueAllEdges(doGlueAllEdges);
1112 aCI.SetFaces(aFaces);
1114 //Compute the sub-shape value
1115 Standard_Boolean isWarning = Standard_False;
1118 if (!GetSolver()->ComputeFunction(aFunction)) {
1119 SetErrorCode("Shape driver failed to glue faces");
1123 catch (Standard_Failure) {
1124 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1125 SetErrorCode(aFail->GetMessageString());
1126 // to provide warning
1127 if (!aFunction->GetValue().IsNull()) {
1128 isWarning = Standard_True;
1134 //Make a Python command
1136 GEOM::TPythonDump pd(aFunction);
1137 pd << aGlued << " = geompy.MakeGlueFacesByList("
1138 << theShapes << ", " << theTolerance << ", " << theFaces << ", "
1139 << (bool)doKeepNonSolids << ", " << (bool)doGlueAllEdges << ")";
1141 // to provide warning
1142 if (!isWarning) SetErrorCode(OK);
1146 //=============================================================================
1150 //=============================================================================
1152 GEOMImpl_IShapesOperations::MakeGlueEdges (std::list< Handle(GEOM_Object) >& theShapes,
1153 const Standard_Real theTolerance)
1157 Handle(TColStd_HSequenceOfTransient) objects = GEOM_Object::GetLastFunctions( theShapes );
1158 if ( objects.IsNull() || objects->IsEmpty() ) {
1159 SetErrorCode("NULL argument shape");
1163 //Add a new Glued object
1164 Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
1166 //Add a new Glue function
1167 Handle(GEOM_Function) aFunction;
1168 aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_EDGES);
1169 if (aFunction.IsNull()) return NULL;
1171 //Check if the function is set correctly
1172 if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
1174 GEOMImpl_IGlue aCI (aFunction);
1176 aCI.SetBase( objects );
1177 aCI.SetTolerance(theTolerance);
1178 aCI.SetKeepNonSolids(true);
1180 //Compute the sub-shape value
1181 Standard_Boolean isWarning = Standard_False;
1184 if (!GetSolver()->ComputeFunction(aFunction)) {
1185 SetErrorCode("Shape driver failed to glue edges");
1189 catch (Standard_Failure) {
1190 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1191 SetErrorCode(aFail->GetMessageString());
1192 // to provide warning
1193 if (!aFunction->GetValue().IsNull()) {
1194 isWarning = Standard_True;
1200 //Make a Python command
1201 GEOM::TPythonDump(aFunction) << aGlued << " = geompy.MakeGlueEdges("
1202 << theShapes << ", " << theTolerance << ")";
1204 // to provide warning
1205 if (!isWarning) SetErrorCode(OK);
1209 //=============================================================================
1213 //=============================================================================
1214 Handle(TColStd_HSequenceOfTransient)
1215 GEOMImpl_IShapesOperations::GetGlueShapes (std::list< Handle(GEOM_Object) >& theShapes,
1216 const Standard_Real theTolerance,
1217 const TopAbs_ShapeEnum theType)
1221 TopoDS_Shape aShape;
1222 TopTools_SequenceOfShape shapes;
1223 std::list< Handle(GEOM_Object) >::iterator s = theShapes.begin();
1224 Handle(GEOM_Object) lastCreatedGO;
1225 for ( ; s != theShapes.end(); ++s )
1227 Handle(GEOM_Object) go = *s;
1228 if ( go.IsNull() ) return NULL;
1229 aShape = go->GetValue();
1230 if ( aShape.IsNull() ) return NULL;
1231 shapes.Append( aShape );
1232 lastCreatedGO = GEOM::GetCreatedLast( lastCreatedGO, go );
1234 if ( shapes.Length() > 1 )
1236 TopoDS_Compound compound;
1237 BRep_Builder builder;
1238 builder.MakeCompound( compound );
1239 for ( int i = 1; i <= shapes.Length(); ++i )
1240 builder.Add( compound, shapes( i ) );
1245 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1247 GEOMAlgo_GlueDetector aGluer;
1248 aGluer.SetArgument(aShape);
1249 aGluer.SetTolerance(theTolerance);
1251 Standard_Integer iErr = aGluer.ErrorStatus();
1252 if (iErr) return NULL;
1254 std::vector< TopTools_IndexedMapOfShape* > anIndices( shapes.Length(), NULL );
1255 Handle(TColStd_HArray1OfInteger) anArray;
1256 Handle(GEOM_Object) anObj;
1258 TopTools_ListOfShape listOnePerSet;
1260 const TopTools_DataMapOfShapeListOfShape& aImages = aGluer.Images();
1261 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape aItDMSLS (aImages);
1262 for (int index = 1; aItDMSLS.More(); aItDMSLS.Next(), ++index) {
1264 //const TopoDS_Shape& aSkey = aItDMSLS.Key();
1266 // list of shapes of the argument that can be glued
1267 const TopTools_ListOfShape& aLSD = aItDMSLS.Value();
1269 //listShape.Append(aLSD.First());
1270 TopoDS_Shape aValue = aLSD.First();
1272 if (aValue.ShapeType() == theType) {
1273 listOnePerSet.Append(aValue);
1277 // for stable order of returned entities
1278 GEOMUtils::SortShapes(listOnePerSet, Standard_False);
1280 TopTools_ListIteratorOfListOfShape aListIt (listOnePerSet);
1281 for (; aListIt.More(); aListIt.Next())
1283 TopoDS_Shape aValue = aListIt.Value();
1284 // find a shape to add aValue as a sub-shape
1286 s = theShapes.begin();
1287 for ( int i = 0; i < shapes.Length(); ++i, ++s )
1289 Handle(GEOM_Object) object = *s;
1290 if ( !anIndices[i] ) {
1291 anIndices[i] = new TopTools_IndexedMapOfShape;
1292 TopExp::MapShapes( object->GetValue(), *anIndices[i]);
1294 if (int index = anIndices[i]->FindIndex( aValue )) {
1295 anArray = new TColStd_HArray1OfInteger(1,1);
1296 anArray->SetValue(1, index);
1297 anObj = GetEngine()->AddSubShape( object, anArray);
1301 if (!anObj.IsNull())
1302 aSeq->Append(anObj);
1304 for ( size_t i = 0 ; i < anIndices.size(); ++i )
1305 delete anIndices[i];
1307 // Make a Python command
1308 if ( aSeq->Length() > 0)
1310 Handle(GEOM_Function) aFunction = lastCreatedGO->GetLastFunction();
1311 GEOM::TPythonDump pd (aFunction, /*append=*/true);
1313 << " = geompy." << (theType == TopAbs_FACE ? "GetGlueFaces" : "GetGlueEdges" )
1314 << "( " << theShapes << ", " << theTolerance << ")";
1322 //=============================================================================
1324 * MakeGlueEdgesByList
1326 //=============================================================================
1328 GEOMImpl_IShapesOperations::MakeGlueEdgesByList (std::list< Handle(GEOM_Object) >& theShapes,
1329 const Standard_Real theTolerance,
1330 std::list<Handle(GEOM_Object)>& theEdges)
1334 Handle(TColStd_HSequenceOfTransient) objects = GEOM_Object::GetLastFunctions( theShapes );
1335 if ( objects.IsNull() || objects->IsEmpty() ) {
1336 SetErrorCode("NULL argument shape");
1339 Handle(TColStd_HSequenceOfTransient) anEdges = GEOM_Object::GetLastFunctions( theEdges );
1340 if ( anEdges.IsNull() ) {
1341 SetErrorCode("NULL argument shape for the shape construction");
1344 //Add a new Glued object
1345 Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
1347 //Add a new Glue function
1348 Handle(GEOM_Function) aFunction;
1349 aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_EDGES_BY_LIST);
1350 if (aFunction.IsNull()) return NULL;
1352 //Check if the function is set correctly
1353 if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
1355 GEOMImpl_IGlue aCI (aFunction);
1357 aCI.SetBase( objects );
1358 aCI.SetTolerance(theTolerance);
1359 aCI.SetKeepNonSolids(true);
1360 aCI.SetFaces(anEdges);
1362 //Compute the sub-shape value
1363 Standard_Boolean isWarning = Standard_False;
1366 if (!GetSolver()->ComputeFunction(aFunction)) {
1367 SetErrorCode("Shape driver failed to glue edges");
1371 catch (Standard_Failure) {
1372 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1373 SetErrorCode(aFail->GetMessageString());
1374 // to provide warning
1375 if (!aFunction->GetValue().IsNull()) {
1376 isWarning = Standard_True;
1382 //Make a Python command
1384 GEOM::TPythonDump pd (aFunction);
1385 pd << aGlued << " = geompy.MakeGlueEdgesByList("
1386 << theShapes << ", " << theTolerance << ", " << theEdges << " )";
1388 // to provide warning
1389 if (!isWarning) SetErrorCode(OK);
1393 //=============================================================================
1395 * GetExistingSubObjects
1397 //=============================================================================
1398 Handle(TColStd_HSequenceOfTransient)
1399 GEOMImpl_IShapesOperations::GetExistingSubObjects(Handle(GEOM_Object) theShape,
1400 const Standard_Boolean theGroupsOnly)
1402 // note: this method does not return fields
1404 Standard_Integer types = theGroupsOnly ? Groups : Groups|SubShapes;
1405 Handle(TColStd_HSequenceOfTransient) results = GetExistingSubObjects(theShape, types);
1407 if (results->Length() > 0) {
1408 //Make a Python command
1409 TCollection_AsciiString anAsciiList;
1410 for (int i = 1; i <= results->Length(); i++)
1412 Handle(GEOM_BaseObject) obj = Handle(GEOM_BaseObject)::DownCast( results->Value(i));
1413 obj->GetEntryString();
1414 if ( i < results->Length() )
1418 GEOM::TPythonDump pd (theShape->GetLastFunction(), /*append=*/true);
1419 pd << "[" << anAsciiList.ToCString();
1420 pd << "] = geompy.GetExistingSubObjects(";
1421 pd << theShape << ", " << (bool)theGroupsOnly << ")";
1427 Handle(TColStd_HSequenceOfTransient)
1428 GEOMImpl_IShapesOperations::GetExistingSubObjects(Handle(GEOM_Object) theShape,
1429 const Standard_Integer theTypes)
1433 if (theShape.IsNull()) return NULL;
1435 Handle(GEOM_Function) aMainShape = theShape->GetLastFunction();
1436 if (aMainShape.IsNull()) return NULL;
1438 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1439 SetErrorCode(NOT_FOUND_ANY);
1441 if (!aMainShape->HasSubShapeReferences()) return aSeq;
1442 const TDataStd_ListOfExtendedString& aListEntries = aMainShape->GetSubShapeReferences();
1443 if (aListEntries.IsEmpty()) return aSeq;
1447 TDataStd_ListIteratorOfListOfExtendedString anIt (aListEntries);
1448 for (; anIt.More(); anIt.Next()) {
1449 TCollection_ExtendedString anEntry = anIt.Value();
1450 Standard_Integer aStrLen = anEntry.LengthOfCString();
1451 char* anEntryStr = new char[aStrLen+1];
1452 anEntry.ToUTF8CString(anEntryStr);
1453 Handle(GEOM_BaseObject) anObj = GetEngine()->GetObject(GetDocID(), anEntryStr, false);
1454 if (!anObj.IsNull() ) {
1455 bool isGroup = anObj->IsKind(STANDARD_TYPE(GEOM_Object)) && anObj->GetType() == GEOM_GROUP;
1456 bool isSubShape = anObj->IsKind(STANDARD_TYPE(GEOM_Object)) && anObj->GetType() != GEOM_GROUP;
1457 bool isField = anObj->IsKind(STANDARD_TYPE(GEOM_Field));
1458 if (theTypes & Groups && isGroup ||
1459 theTypes & SubShapes && isSubShape ||
1460 theTypes & Fields && isField) {
1461 aSeq->Append(anObj);
1464 delete [] anEntryStr;
1467 if (aSeq->Length() == 0) {
1468 SetErrorCode(NOT_FOUND_ANY);
1477 //=============================================================================
1481 //=============================================================================
1482 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::MakeExplode
1483 (Handle(GEOM_Object) theShape,
1484 const Standard_Integer theShapeType,
1485 const Standard_Boolean isSorted,
1486 const ExplodeType theExplodeType)
1490 if (theShape.IsNull()) return NULL;
1491 TopoDS_Shape aShape = theShape->GetValue();
1492 if (aShape.IsNull()) return NULL;
1494 Handle(GEOM_Function) aMainShape = theShape->GetLastFunction();
1496 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1497 Handle(GEOM_Object) anObj;
1498 TopTools_MapOfShape mapShape;
1499 TopTools_ListOfShape listShape;
1501 if (aShape.ShapeType() == TopAbs_COMPOUND &&
1502 (theShapeType == TopAbs_SHAPE || theShapeType == TopAbs_FLAT || theShapeType == TopAbs_COMPOUND))
1504 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
1505 for (; It.More(); It.Next()) {
1506 TopoDS_Shape SS = It.Value();
1507 if (mapShape.Add(SS)) {
1508 if (theShapeType == TopAbs_FLAT) {
1509 AddFlatSubShapes(SS, listShape, mapShape);
1511 else if (theShapeType == TopAbs_SHAPE || theShapeType == SS.ShapeType()) {
1512 listShape.Append(SS);
1514 // VSR: for EXPLODE_NEW_INCLUDE_MAIN and EXPLODE_OLD_INCLUDE_MAIN:
1515 // it seems it is necessary to add top-level shape if theShapeType == TopAbs_COMPOUND
1519 else if (theExplodeType != EXPLODE_NEW_EXCLUDE_MAIN || aShape.ShapeType() != theShapeType) // issue 0021079
1521 TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
1522 for (; exp.More(); exp.Next())
1523 if (mapShape.Add(exp.Current()))
1524 listShape.Append(exp.Current());
1527 if (listShape.IsEmpty()){
1528 //SetErrorCode("The given shape has no sub-shapes of the requested type");
1529 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
1534 bool isOldSorting = false;
1535 if (theExplodeType == EXPLODE_OLD_INCLUDE_MAIN)
1536 isOldSorting = true;
1537 GEOMUtils::SortShapes(listShape, isOldSorting);
1540 TopTools_IndexedMapOfShape anIndices;
1541 TopExp::MapShapes(aShape, anIndices);
1542 Handle(TColStd_HArray1OfInteger) anArray;
1544 TopTools_ListIteratorOfListOfShape itSub (listShape);
1545 TCollection_AsciiString anAsciiList, anEntry;
1546 for (int index = 1; itSub.More(); itSub.Next(), ++index)
1548 TopoDS_Shape aValue = itSub.Value();
1549 anArray = new TColStd_HArray1OfInteger(1,1);
1550 anArray->SetValue(1, anIndices.FindIndex(aValue));
1552 //anObj = GetEngine()->AddSubShape(theShape, anArray);
1554 anObj = GetEngine()->AddObject(GetDocID(), GEOM_SUBSHAPE);
1555 Handle(GEOM_Function) aFunction = anObj->AddFunction(GEOM_Object::GetSubShapeID(), 1);
1556 if (aFunction.IsNull()) return aSeq;
1558 GEOM_ISubShape aSSI (aFunction);
1559 aSSI.SetMainShape(aMainShape);
1560 aSSI.SetIndices(anArray);
1562 // Set function value directly, as we know it.
1563 // Usage of Solver here would lead to significant loss of time,
1564 // because GEOM_SubShapeDriver will build TopTools_IndexedMapOfShape
1565 // on the main shape for each being calculated sub-shape separately.
1566 aFunction->SetValue(aValue);
1568 // Put this subshape in the list of sub-shapes of theMainShape
1569 aMainShape->AddSubShapeReference(aFunction);
1571 if (!anObj.IsNull()) {
1572 aSeq->Append(anObj);
1574 // for python command
1575 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
1576 anAsciiList += anEntry;
1581 //Make a Python command
1582 anAsciiList.Trunc(anAsciiList.Length() - 1);
1584 GEOM::TPythonDump pd (aMainShape, /*append=*/true);
1585 pd << "[" << anAsciiList.ToCString() << "] = geompy.";
1586 switch (theExplodeType) {
1587 case EXPLODE_NEW_EXCLUDE_MAIN:
1588 pd << "ExtractShapes(" << theShape << ", "
1589 << TopAbs_ShapeEnum(theShapeType) << ", " << (isSorted ? "True" : "False") << ")";
1591 case EXPLODE_NEW_INCLUDE_MAIN:
1592 pd << "SubShapeAll" << (isSorted ? "SortedCentres(" : "(")
1593 << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
1595 case EXPLODE_OLD_INCLUDE_MAIN:
1596 pd << "SubShapeAll" << (isSorted ? "Sorted(" : "(")
1597 << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
1606 //=============================================================================
1610 //=============================================================================
1611 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::SubShapeAllIDs
1612 (Handle(GEOM_Object) theShape,
1613 const Standard_Integer theShapeType,
1614 const Standard_Boolean isSorted,
1615 const ExplodeType theExplodeType)
1619 if (theShape.IsNull()) return NULL;
1620 TopoDS_Shape aShape = theShape->GetValue();
1621 if (aShape.IsNull()) return NULL;
1623 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
1624 TopTools_MapOfShape mapShape;
1625 TopTools_ListOfShape listShape;
1627 if (aShape.ShapeType() == TopAbs_COMPOUND &&
1628 (theShapeType == TopAbs_SHAPE || theShapeType == TopAbs_FLAT || theShapeType == TopAbs_COMPOUND))
1630 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
1631 for (; It.More(); It.Next()) {
1632 TopoDS_Shape SS = It.Value();
1633 if (mapShape.Add(SS)) {
1634 if (theShapeType == TopAbs_FLAT) {
1635 AddFlatSubShapes(SS, listShape, mapShape);
1637 else if (theShapeType == TopAbs_SHAPE || theShapeType == SS.ShapeType()) {
1638 listShape.Append(SS);
1643 else if (theExplodeType != EXPLODE_NEW_EXCLUDE_MAIN || aShape.ShapeType() != theShapeType) // issue 0021079
1645 TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
1646 for (; exp.More(); exp.Next())
1647 if (mapShape.Add(exp.Current()))
1648 listShape.Append(exp.Current());
1651 if (listShape.IsEmpty()) {
1652 //SetErrorCode("The given shape has no sub-shapes of the requested type");
1653 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
1658 bool isOldSorting = false;
1659 if (theExplodeType == EXPLODE_OLD_INCLUDE_MAIN)
1660 isOldSorting = true;
1661 GEOMUtils::SortShapes(listShape, isOldSorting);
1664 TopTools_IndexedMapOfShape anIndices;
1665 TopExp::MapShapes(aShape, anIndices);
1666 Handle(TColStd_HArray1OfInteger) anArray;
1668 TopTools_ListIteratorOfListOfShape itSub (listShape);
1669 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
1670 TopoDS_Shape aValue = itSub.Value();
1671 aSeq->Append(anIndices.FindIndex(aValue));
1674 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
1676 //Make a Python command
1677 GEOM::TPythonDump pd (aFunction, /*append=*/true);
1678 pd << "listSubShapeIDs = geompy.SubShapeAll";
1679 switch (theExplodeType) {
1680 case EXPLODE_NEW_EXCLUDE_MAIN:
1682 case EXPLODE_NEW_INCLUDE_MAIN:
1683 pd << (isSorted ? "SortedCentresIDs(" : "IDs(")
1684 << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
1686 case EXPLODE_OLD_INCLUDE_MAIN:
1687 pd << (isSorted ? "SortedIDs(" : "IDs(")
1688 << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
1697 //=============================================================================
1701 //=============================================================================
1702 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetSubShape
1703 (Handle(GEOM_Object) theMainShape,
1704 const Standard_Integer theID)
1708 if (theMainShape.IsNull()) return NULL;
1710 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
1711 anArray->SetValue(1, theID);
1712 Handle(GEOM_Object) anObj = GetEngine()->AddSubShape(theMainShape, anArray,true);
1713 if (anObj.IsNull()) {
1714 SetErrorCode("Can not get a sub-shape with the given ID");
1718 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1720 //Make a Python command
1721 GEOM::TPythonDump(aFunction) << anObj << " = geompy.GetSubShape("
1722 << theMainShape << ", [" << theID << "])";
1728 //=============================================================================
1732 //=============================================================================
1733 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::MakeSubShapes
1734 (Handle(GEOM_Object) theMainShape,
1735 Handle(TColStd_HArray1OfInteger) theIndices)
1739 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1741 if (!theIndices->Length()) {
1742 SetErrorCode(NOT_FOUND_ANY);
1746 if (theMainShape.IsNull()) return NULL;
1747 TopoDS_Shape aShape = theMainShape->GetValue();
1748 if (aShape.IsNull()) return NULL;
1750 Handle(GEOM_Function) aMainShape = theMainShape->GetLastFunction();
1752 TopTools_IndexedMapOfShape anIndices;
1753 TopExp::MapShapes(aShape, anIndices);
1755 Handle(TColStd_HArray1OfInteger) anArray;
1756 Handle(GEOM_Object) anObj;
1758 TCollection_AsciiString anAsciiList, anEntry;
1759 Standard_Integer i, low = theIndices->Lower(), up = theIndices->Upper();
1760 for (i = low; i <= up; i++) {
1761 int id = theIndices->Value(i);
1762 if (1 <= id && id <= anIndices.Extent()) {
1763 TopoDS_Shape aValue = anIndices.FindKey(id);
1764 anArray = new TColStd_HArray1OfInteger(1,1);
1765 anArray->SetValue(1, id);
1767 anObj = GetEngine()->AddObject(GetDocID(), GEOM_SUBSHAPE);
1768 if (!anObj.IsNull()) {
1769 Handle(GEOM_Function) aFunction = anObj->AddFunction(GEOM_Object::GetSubShapeID(), 1);
1770 if (aFunction.IsNull()) return aSeq;
1772 GEOM_ISubShape aSSI (aFunction);
1773 aSSI.SetMainShape(aMainShape);
1774 aSSI.SetIndices(anArray);
1776 // Set function value directly, as we know it.
1777 // Usage of Solver here would lead to significant loss of time,
1778 // because GEOM_SubShapeDriver will build TopTools_IndexedMapOfShape
1779 // on the main shape for each being calculated sub-shape separately.
1780 aFunction->SetValue(aValue);
1782 // Put this sub-shape in the list of sub-shapes of theMainShape
1783 aMainShape->AddSubShapeReference(aFunction);
1785 aSeq->Append(anObj);
1787 // for python command
1788 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
1789 anAsciiList += anEntry;
1795 //Make a Python command
1796 anAsciiList.Trunc(anAsciiList.Length() - 1);
1798 GEOM::TPythonDump pd (aMainShape, /*append=*/true);
1799 pd << "[" << anAsciiList.ToCString() << "] = geompy.SubShapes("
1800 << theMainShape << ", [" ;
1801 for (i = low; i <= up - 1; i++) {
1802 pd << theIndices->Value(i) << ", ";
1804 pd << theIndices->Value(up) << "])";
1811 //=============================================================================
1815 //=============================================================================
1816 Standard_Integer GEOMImpl_IShapesOperations::GetSubShapeIndex (Handle(GEOM_Object) theMainShape,
1817 Handle(GEOM_Object) theSubShape)
1821 TopoDS_Shape aMainShape = theMainShape->GetValue();
1822 TopoDS_Shape aSubShape = theSubShape->GetValue();
1824 if (aMainShape.IsNull() || aSubShape.IsNull()) return -1;
1826 TopTools_IndexedMapOfShape anIndices;
1827 TopExp::MapShapes(aMainShape, anIndices);
1828 // if (anIndices.Contains(aSubShape)) {
1829 // SetErrorCode(OK);
1830 // return anIndices.FindIndex(aSubShape);
1832 int id = anIndices.FindIndex(aSubShape);
1843 //=============================================================================
1845 * GetSubShapeIndices
1847 //=============================================================================
1848 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetSubShapesIndices (Handle(GEOM_Object) theMainShape,
1849 std::list<Handle(GEOM_Object)> theSubShapes)
1851 MESSAGE("GEOMImpl_IShapesOperations::GetSubShapesIndices")
1854 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
1856 TopoDS_Shape aMainShape = theMainShape->GetValue();
1857 if (aMainShape.IsNull())
1859 MESSAGE("NULL main shape")
1863 TopTools_IndexedMapOfShape anIndices;
1864 TopExp::MapShapes(aMainShape, anIndices);
1866 std::list<Handle(GEOM_Object)>::iterator it;
1867 for (it=theSubShapes.begin(); it != theSubShapes.end(); ++it)
1869 TopoDS_Shape aSubShape = (*it)->GetValue();
1870 if (aSubShape.IsNull())
1872 MESSAGE("NULL subshape")
1875 int id = anIndices.FindIndex(aSubShape);
1884 //=============================================================================
1888 //=============================================================================
1889 Standard_Integer GEOMImpl_IShapesOperations::GetTopologyIndex (Handle(GEOM_Object) theMainShape,
1890 Handle(GEOM_Object) theSubShape)
1894 TopoDS_Shape aMainShape = theMainShape->GetValue();
1895 TopoDS_Shape aSubShape = theSubShape->GetValue();
1897 if (aMainShape.IsNull() || aSubShape.IsNull()) {
1898 SetErrorCode("Null argument shape given");
1903 if (aSubShape.ShapeType() == TopAbs_COMPOUND) {
1905 TopTools_ListOfShape CL;
1906 CL.Append(aMainShape);
1907 TopTools_ListIteratorOfListOfShape itC;
1908 for (itC.Initialize(CL); itC.More(); itC.Next()) {
1909 for (it.Initialize(itC.Value()); it.More(); it.Next()) {
1910 if (it.Value().ShapeType() == TopAbs_COMPOUND) {
1911 if (it.Value().IsSame(aSubShape))
1915 CL.Append(it.Value());
1920 TopExp_Explorer anExp (aMainShape, aSubShape.ShapeType());
1921 TopTools_MapOfShape M;
1922 for (; anExp.More(); anExp.Next()) {
1923 if (M.Add(anExp.Current())) {
1924 if (anExp.Current().IsSame(aSubShape))
1931 SetErrorCode("The sub-shape does not belong to the main shape");
1935 //=============================================================================
1937 * GetShapeTypeString
1939 //=============================================================================
1940 TCollection_AsciiString GEOMImpl_IShapesOperations::GetShapeTypeString (Handle(GEOM_Object) theShape)
1944 TCollection_AsciiString aTypeName ("Null Shape");
1946 TopoDS_Shape aShape = theShape->GetValue();
1947 if (aShape.IsNull())
1950 switch (aShape.ShapeType() )
1952 case TopAbs_COMPOUND:
1953 aTypeName = "Compound";
1955 case TopAbs_COMPSOLID:
1956 aTypeName = "Compound Solid";
1959 aTypeName = "Solid";
1962 aTypeName = "Shell";
1966 BRepAdaptor_Surface surf (TopoDS::Face(aShape));
1967 if (surf.GetType() == GeomAbs_Plane)
1968 aTypeName = "Plane";
1969 else if (surf.GetType() == GeomAbs_Cylinder)
1970 aTypeName = "Cylindrical Face";
1971 else if (surf.GetType() == GeomAbs_Sphere)
1972 aTypeName = "Spherical Face";
1973 else if (surf.GetType() == GeomAbs_Torus)
1974 aTypeName = "Toroidal Face";
1975 else if (surf.GetType() == GeomAbs_Cone)
1976 aTypeName = "Conical Face";
1978 aTypeName = "GEOM::FACE";
1986 BRepAdaptor_Curve curv (TopoDS::Edge(aShape));
1987 if (curv.GetType() == GeomAbs_Line) {
1988 if ((Abs(curv.FirstParameter()) >= 1E6) ||
1989 (Abs(curv.LastParameter()) >= 1E6))
1993 } else if (curv.GetType() == GeomAbs_Circle) {
1994 if (curv.IsClosed())
1995 aTypeName = "Circle";
2004 aTypeName = "Vertex";
2007 aTypeName = "Shape";
2010 aTypeName = "Shape of unknown type";
2016 //=============================================================================
2018 * IsSubShapeBelongsTo
2020 //=============================================================================
2021 Standard_Boolean GEOMImpl_IShapesOperations::IsSubShapeBelongsTo( Handle(GEOM_Object) theSubObject,
2022 const Standard_Integer theSubObjectIndex,
2023 Handle(GEOM_Object) theObject,
2024 const Standard_Integer theObjectIndex)
2028 if ( theObject.IsNull() || theSubObject.IsNull() )
2031 TopoDS_Shape shape = theObject->GetValue();
2032 TopoDS_Shape subShape = theSubObject->GetValue();
2034 if ( shape.IsNull() || subShape.IsNull() )
2037 TopTools_IndexedMapOfShape anIndices;
2038 if ( theObjectIndex > 0 ) {
2039 TopExp::MapShapes( shape, anIndices );
2040 shape = anIndices.FindKey(theObjectIndex);
2042 if ( theSubObjectIndex > 0 ) {
2043 TopExp::MapShapes( subShape, anIndices );
2044 subShape = anIndices.FindKey(theSubObjectIndex);
2047 TopExp::MapShapes( shape, anIndices );
2049 const Standard_Boolean isBelongTo = anIndices.Contains(subShape);
2056 //=============================================================================
2060 //=============================================================================
2061 Standard_Integer GEOMImpl_IShapesOperations::NumberOfSubShapes
2062 (Handle(GEOM_Object) theShape,
2063 const Standard_Integer theShapeType)
2066 Standard_Integer nbShapes = 0;
2068 if (theShape.IsNull()) return -1;
2069 TopoDS_Shape aShape = theShape->GetValue();
2070 if (aShape.IsNull()) return -1;
2073 TopTools_MapOfShape mapShape;
2075 if (aShape.ShapeType() == TopAbs_COMPOUND &&
2076 (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
2077 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPSOLID ||
2078 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPOUND)) {
2079 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
2080 for (; It.More(); It.Next()) {
2081 if (mapShape.Add(It.Value())) {
2082 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
2083 TopAbs_ShapeEnum(theShapeType) == It.Value().ShapeType()) {
2089 TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
2090 for (; exp.More(); exp.Next())
2091 if (mapShape.Add(exp.Current()))
2097 if (theShapeType == TopAbs_FLAT) {
2098 TopTools_MapOfShape aMapOfShape;
2099 TopTools_ListOfShape aListOfShape;
2100 AddFlatSubShapes(aShape, aListOfShape, aMapOfShape);
2101 nbShapes = aListOfShape.Extent();
2105 int iType, nbTypes [TopAbs_SHAPE];
2106 for (iType = 0; iType < TopAbs_SHAPE; ++iType)
2108 nbTypes[aShape.ShapeType()]++;
2110 TopTools_MapOfShape aMapOfShape;
2111 aMapOfShape.Add(aShape);
2112 TopTools_ListOfShape aListOfShape;
2113 aListOfShape.Append(aShape);
2115 TopTools_ListIteratorOfListOfShape itL (aListOfShape);
2116 for (; itL.More(); itL.Next()) {
2117 TopoDS_Iterator it (itL.Value());
2118 for (; it.More(); it.Next()) {
2119 TopoDS_Shape s = it.Value();
2120 if (aMapOfShape.Add(s)) {
2121 aListOfShape.Append(s);
2122 nbTypes[s.ShapeType()]++;
2127 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE)
2128 nbShapes = aMapOfShape.Extent();
2130 nbShapes = nbTypes[theShapeType];
2133 catch (Standard_Failure) {
2134 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2135 SetErrorCode(aFail->GetMessageString());
2143 //=============================================================================
2147 //=============================================================================
2148 Handle(GEOM_Object) GEOMImpl_IShapesOperations::ReverseShape(Handle(GEOM_Object) theShape)
2152 if (theShape.IsNull()) return NULL;
2155 //Add a new reversed object
2156 Handle(GEOM_Object) aReversed = GetEngine()->AddObject(GetDocID(), theShape->GetType());
2158 //Add a new Revese function
2159 Handle(GEOM_Function) aFunction;
2160 aFunction = aReversed->AddFunction(GEOMImpl_ShapeDriver::GetID(), REVERSE_ORIENTATION);
2161 if (aFunction.IsNull()) return NULL;
2163 //Check if the function is set correctly
2164 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
2166 GEOMImpl_IShapes aSI (aFunction);
2168 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
2169 if (aRefShape.IsNull()) return NULL;
2171 aSI.SetBase(aRefShape);
2173 //Compute the sub-shape value
2176 if (!GetSolver()->ComputeFunction(aFunction)) {
2177 SetErrorCode("Shape driver failed to reverse shape");
2181 catch (Standard_Failure) {
2182 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2183 SetErrorCode(aFail->GetMessageString());
2187 //Make a Python command
2188 GEOM::TPythonDump(aFunction) << aReversed
2189 << " = geompy.ChangeOrientation(" << theShape << ")";
2194 Handle(GEOM_Object) aReversed;
2196 GEOM_Engine* anEngine = GetEngine();
2197 //GEOMImpl_Gen* aGen = dynamic_cast<GEOMImpl_Gen*>(anEngine);
2198 GEOMImpl_Gen* aGen = (GEOMImpl_Gen*)anEngine;
2201 GEOMImpl_IHealingOperations* anIHealingOperations =
2202 aGen->GetIHealingOperations(GetDocID());
2203 aReversed = anIHealingOperations->ChangeOrientationCopy(theShape);
2204 SetErrorCode(anIHealingOperations->GetErrorCode());
2210 //=============================================================================
2214 //=============================================================================
2215 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetFreeFacesIDs
2216 (Handle(GEOM_Object) theShape)
2220 if (theShape.IsNull()) return NULL;
2221 TopoDS_Shape aShape = theShape->GetValue();
2222 if (aShape.IsNull()) return NULL;
2224 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
2226 TopTools_IndexedDataMapOfShapeListOfShape mapFaceBlocks;
2227 GEOMImpl_Block6Explorer::MapShapesAndAncestors
2228 (aShape, TopAbs_FACE, TopAbs_SOLID, mapFaceBlocks);
2230 Standard_Integer ind = 1, nbFaces = mapFaceBlocks.Extent();
2233 SetErrorCode("The given shape has no faces");
2237 TopTools_IndexedMapOfShape anIndices;
2238 TopExp::MapShapes(aShape, anIndices);
2240 Standard_Integer id;
2241 for (; ind <= nbFaces; ind++) {
2242 if (mapFaceBlocks.FindFromIndex(ind).Extent() != 2) {
2243 id = anIndices.FindIndex(mapFaceBlocks.FindKey(ind));
2248 //The explode doesn't change object so no new function is required.
2249 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
2251 //Make a Python command
2252 GEOM::TPythonDump(aFunction, /*append=*/true)
2253 << "listFreeFacesIDs = geompy.GetFreeFacesIDs(" << theShape << ")";
2259 //=======================================================================
2260 //function : GetSharedShapes
2262 //=======================================================================
2263 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetSharedShapes
2264 (Handle(GEOM_Object) theShape1,
2265 Handle(GEOM_Object) theShape2,
2266 const Standard_Integer theShapeType)
2270 if (theShape1.IsNull() || theShape2.IsNull()) return NULL;
2272 TopoDS_Shape aShape1 = theShape1->GetValue();
2273 TopoDS_Shape aShape2 = theShape2->GetValue();
2275 if (aShape1.IsNull() || aShape2.IsNull()) return NULL;
2277 TopTools_IndexedMapOfShape anIndices;
2278 TopExp::MapShapes(aShape1, anIndices);
2279 Handle(TColStd_HArray1OfInteger) anArray;
2281 TopTools_IndexedMapOfShape mapShape1;
2282 TopExp::MapShapes(aShape1, TopAbs_ShapeEnum(theShapeType), mapShape1);
2284 Handle(GEOM_Object) anObj;
2285 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
2286 TCollection_AsciiString anAsciiList, anEntry;
2288 TopTools_MapOfShape mapShape2;
2289 TopExp_Explorer exp (aShape2, TopAbs_ShapeEnum(theShapeType));
2290 for (; exp.More(); exp.Next()) {
2291 TopoDS_Shape aSS = exp.Current();
2292 if (mapShape2.Add(aSS) && mapShape1.Contains(aSS)) {
2293 anArray = new TColStd_HArray1OfInteger(1,1);
2294 anArray->SetValue(1, anIndices.FindIndex(aSS));
2295 anObj = GetEngine()->AddSubShape(theShape1, anArray);
2296 aSeq->Append(anObj);
2298 // for python command
2299 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
2300 anAsciiList += anEntry;
2305 if (aSeq->IsEmpty()) {
2306 SetErrorCode(NOT_FOUND_ANY);
2310 //Make a Python command
2311 anAsciiList.Trunc(anAsciiList.Length() - 1);
2313 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2315 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
2316 << "] = geompy.GetSharedShapes(" << theShape1 << ", "
2317 << theShape2 << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
2323 //=======================================================================
2324 //function : GetSharedShapes
2327 // NOTE on the implementation
2329 // 1) Resulting sub-shapes are published as a children of the 1st input shape
2330 // from theShapes list. Due to this reason only direct sub-shapes of the 1st
2331 // shape can be contained in the result of the operation (i.e. shares between
2332 // 2nd/3rd, etc couples cannot be retrieved.
2333 // 2) An exception from above case is when a single compound is specified as an
2334 // input. In this case we search shares between its top-level content, so we
2335 // are able to search shares between all possible couples of shapes.
2336 // 3) Parameter theMultiShare controls what types of shares to search:
2337 // - True: get sub-shapes that are shared between ALL input shapes;
2338 // - False: get shares between couples of input sub-shapes (see points 1 and 2).
2340 // Thus, we have the following cases:
2341 // [1] theShapes = N shapes (N>1), theMultiShare = True
2342 // Result: sub-shapes that are shared by all theShapes
2343 // [2] theShapes = N shapes (N>1), theMultiShare = False
2344 // Result: sub-shapes of 1st shape from theShapes that are shared with any shape
2346 // [3] theShapes = 1 shape, theMultiShare = True
2347 // Result: sub-shapes that are shared by all top-level sub-objects of theShapes[0]
2348 // [4] theShapes = 1 shape, theMultiShare = False
2349 // Result: sub-shapes of all possible couples of all top-level sub-objects of
2351 //=======================================================================
2352 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetSharedShapes
2353 (std::list<Handle(GEOM_Object)> & theShapes,
2354 const Standard_Integer theShapeType,
2355 const bool theMultiShare)
2359 int aLen = theShapes.size();
2360 if (aLen < 1) return NULL;
2362 std::list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
2364 // main object is always first in the input list
2365 // it is the object from which sub-shapes indices are taken
2366 // and where results are published
2367 Handle(GEOM_Object) aMainObj = *it;
2368 Handle(GEOM_Function) aMainShape = aMainObj->GetLastFunction();
2370 // collect all shapes from the input list (including first one) for processing
2371 TopTools_SequenceOfShape shapeSeq;
2372 for (; it != theShapes.end(); it++) {
2373 Handle(GEOM_Function) aRefShape = (*it)->GetLastFunction();
2374 if (aRefShape.IsNull()) {
2375 SetErrorCode("NULL shape for GetSharedShapes");
2378 TopoDS_Shape aShape = aRefShape->GetValue();
2379 if (aShape.IsNull()) {
2380 SetErrorCode("NULL shape for GetSharedShapes");
2383 shapeSeq.Append( aShape );
2386 // if only single shape is specified as input
2387 // collect all ites top-level sub-shapes for processing
2388 if ( shapeSeq.Length() == 1 )
2390 TopoDS_Shape aShape = shapeSeq.First();
2392 for ( TopoDS_Iterator it( aShape ); it.More(); it.Next() )
2393 shapeSeq.Append( it.Value() );
2396 // map all sub-shapes in a main shape to their indices
2397 TopTools_IndexedMapOfShape anIndices;
2398 TopExp::MapShapes(aMainShape->GetValue(), anIndices);
2399 TopTools_MapOfShape mapShape;
2401 // find shared shapes
2403 // here we will collect all shares
2404 TopTools_ListOfShape aShared;
2406 // number of iterations
2407 int nbIters = theMultiShare || theShapes.size() > 1 ? 1 : shapeSeq.Length()-1;
2408 // numShares factor to search (i.e. by what nb of shapes each found sub-shape should be shared)
2409 int nbShares = theMultiShare ? shapeSeq.Length()-1 : 1;
2411 for ( int iter = 1; iter <= nbIters; iter++) {
2412 for ( int ind = iter+1; ind <= shapeSeq.Length(); ind++) {
2413 if ( ind-1+nbShares > shapeSeq.Length() ) break;
2414 TopoDS_Compound aCurrSelection;
2415 TopoDS_Shape aShape1 = shapeSeq.Value( iter );
2416 TopTools_IndexedMapOfShape mapSelected;
2417 TopExp::MapShapes(aShape1, TopAbs_ShapeEnum(theShapeType), mapSelected);
2418 for ( int s = 0; s < nbShares; s++ ) {
2420 TopoDS_Compound aCompound;
2421 B.MakeCompound(aCompound);
2422 const TopoDS_Shape& aShape2 = shapeSeq.Value( ind+s );
2423 TopTools_MapOfShape mapShape2;
2424 TopExp_Explorer exp (aShape2, TopAbs_ShapeEnum(theShapeType));
2425 for (; exp.More(); exp.Next()) {
2426 const TopoDS_Shape& aSS = exp.Current();
2427 if (mapShape2.Add(aSS) && mapSelected.Contains(aSS)) {
2428 B.Add(aCompound, aSS);
2431 mapSelected.Clear();
2432 aCurrSelection = aCompound;
2433 TopExp::MapShapes(aCurrSelection, TopAbs_ShapeEnum(theShapeType), mapSelected);
2435 TopoDS_Iterator itSel(aCurrSelection, Standard_True, Standard_True);
2436 for (; itSel.More(); itSel.Next()) {
2437 const TopoDS_Shape& aSS = itSel.Value();
2438 if (mapShape.Add(aSS) )
2439 aShared.Append(aSS);
2444 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
2446 if (aShared.IsEmpty()){
2447 SetErrorCode(NOT_FOUND_ANY);
2451 // create GEOM_Object for each found shared shape (collected in aShared)
2452 TCollection_AsciiString anAsciiList;
2453 Handle(GEOM_Object) anObj;
2454 TopTools_ListIteratorOfListOfShape itSub (aShared);
2455 for (; itSub.More(); itSub.Next()) {
2456 TopoDS_Shape aValue = itSub.Value();
2457 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
2458 anArray->SetValue(1, anIndices.FindIndex(aValue));
2459 anObj = GetEngine()->AddSubShape(aMainObj, anArray);
2460 aSeq->Append(anObj);
2462 // for python command
2463 TCollection_AsciiString anEntry;
2464 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
2465 anAsciiList += anEntry;
2469 // make a Python command
2470 anAsciiList.Trunc(anAsciiList.Length() - 1);
2472 GEOM::TPythonDump pd (anObj->GetLastFunction());
2473 pd << "[" << anAsciiList.ToCString()
2474 << "] = geompy.GetSharedShapesMulti(";
2479 it = theShapes.begin();
2481 while (it != theShapes.end()) {
2482 pd << ", " << (*it++);
2487 pd << ", " << TopAbs_ShapeEnum(theShapeType) << ", " << theMultiShare << ")";
2493 //=============================================================================
2497 //=============================================================================
2498 static GEOM::TPythonDump& operator<< (GEOM::TPythonDump& theDump,
2499 const GEOMAlgo_State theState)
2502 case GEOMAlgo_ST_IN:
2503 theDump << "GEOM.ST_IN";
2505 case GEOMAlgo_ST_OUT:
2506 theDump << "GEOM.ST_OUT";
2508 case GEOMAlgo_ST_ON:
2509 theDump << "GEOM.ST_ON";
2511 case GEOMAlgo_ST_ONIN:
2512 theDump << "GEOM.ST_ONIN";
2514 case GEOMAlgo_ST_ONOUT:
2515 theDump << "GEOM.ST_ONOUT";
2518 theDump << "GEOM.ST_UNKNOWN";
2524 //=======================================================================
2525 //function : checkTypeShapesOn
2527 * \brief Checks if theShapeType parameter of GetShapesOnXXX() is OK
2528 * \param theShapeType - the shape type to check
2529 * \retval bool - result of the check
2531 //=======================================================================
2532 bool GEOMImpl_IShapesOperations::checkTypeShapesOn(const Standard_Integer theShapeType)
2534 if (theShapeType != TopAbs_VERTEX &&
2535 theShapeType != TopAbs_EDGE &&
2536 theShapeType != TopAbs_FACE &&
2537 theShapeType != TopAbs_SOLID) {
2538 SetErrorCode("Only solids, vertices, edges or faces can be found by this method");
2544 //=======================================================================
2545 //function : makePlane
2547 * \brief Creates Geom_Plane
2548 * \param theAx1 - shape object defining plane parameters
2549 * \retval Handle(Geom_Surface) - resulting surface
2551 //=======================================================================
2552 Handle(Geom_Surface) GEOMImpl_IShapesOperations::makePlane(const TopoDS_Shape& anAx1)
2554 if (anAx1.ShapeType() != TopAbs_EDGE) return NULL;
2555 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
2556 TopoDS_Vertex V1, V2;
2557 TopExp::Vertices(anEdge, V1, V2, Standard_True);
2558 if (V1.IsNull() || V2.IsNull()) {
2559 SetErrorCode("Bad edge given for the plane normal vector");
2562 gp_Pnt aLoc = BRep_Tool::Pnt(V1);
2563 gp_Vec aVec (aLoc, BRep_Tool::Pnt(V2));
2564 if (aVec.Magnitude() < Precision::Confusion()) {
2565 SetErrorCode("Vector with null magnitude given");
2568 return new Geom_Plane(aLoc, aVec);
2571 //=======================================================================
2572 //function : makeCylinder
2574 * \brief Creates Geom_CylindricalSurface
2575 * \param theAx1 - edge defining cylinder axis
2576 * \param theRadius - cylinder radius
2577 * \retval Handle(Geom_Surface) - resulting surface
2579 //=======================================================================
2580 Handle(Geom_Surface) GEOMImpl_IShapesOperations::makeCylinder(const TopoDS_Shape& anAxis,
2581 const Standard_Real theRadius)
2583 //Axis of the cylinder
2584 if (anAxis.ShapeType() != TopAbs_EDGE) {
2585 SetErrorCode("Not an edge given for the axis");
2588 TopoDS_Edge anEdge = TopoDS::Edge(anAxis);
2589 TopoDS_Vertex V1, V2;
2590 TopExp::Vertices(anEdge, V1, V2, Standard_True);
2591 if (V1.IsNull() || V2.IsNull()) {
2592 SetErrorCode("Bad edge given for the axis");
2595 gp_Pnt aLoc = BRep_Tool::Pnt(V1);
2596 gp_Vec aVec (aLoc, BRep_Tool::Pnt(V2));
2597 if (aVec.Magnitude() < Precision::Confusion()) {
2598 SetErrorCode("Vector with null magnitude given");
2602 gp_Ax3 anAx3 (aLoc, aVec);
2603 return new Geom_CylindricalSurface(anAx3, theRadius);
2606 //=======================================================================
2607 //function : getShapesOnBoxIDs
2609 * \brief Find IDs of sub-shapes complying with given status about surface
2610 * \param theBox - the box to check state of sub-shapes against
2611 * \param theShape - the shape to explore
2612 * \param theShapeType - type of sub-shape of theShape
2613 * \param theState - required state
2614 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
2616 //=======================================================================
2617 Handle(TColStd_HSequenceOfInteger)
2618 GEOMImpl_IShapesOperations::getShapesOnBoxIDs(const Handle(GEOM_Object)& theBox,
2619 const Handle(GEOM_Object)& theShape,
2620 const Standard_Integer theShapeType,
2621 GEOMAlgo_State theState)
2623 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
2625 TopoDS_Shape aBox = theBox->GetValue();
2626 TopoDS_Shape aShape = theShape->GetValue();
2628 // Check presence of triangulation, build if need
2629 if (!GEOMUtils::CheckTriangulation(aShape)) {
2630 SetErrorCode("Cannot build triangulation on the shape");
2635 GEOMAlgo_FinderShapeOn2 aFinder;
2636 Standard_Real aTol = 0.0001; // default value
2638 Handle(GEOMAlgo_ClsfBox) aClsfBox = new GEOMAlgo_ClsfBox;
2639 aClsfBox->SetBox(aBox);
2641 aFinder.SetShape(aShape);
2642 aFinder.SetTolerance(aTol);
2643 aFinder.SetClsf(aClsfBox);
2644 aFinder.SetShapeType( (TopAbs_ShapeEnum)theShapeType );
2645 aFinder.SetState(theState);
2648 // Interprete results
2649 Standard_Integer iErr = aFinder.ErrorStatus();
2650 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn2.cxx
2652 MESSAGE(" iErr : " << iErr);
2653 TCollection_AsciiString aMsg (" iErr : ");
2654 aMsg += TCollection_AsciiString(iErr);
2658 Standard_Integer iWrn = aFinder.WarningStatus();
2659 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn2.cxx
2661 MESSAGE(" *** iWrn : " << iWrn);
2664 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
2666 if (listSS.Extent() < 1) {
2667 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
2668 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
2672 // Fill sequence of object IDs
2673 aSeqOfIDs = new TColStd_HSequenceOfInteger;
2675 TopTools_IndexedMapOfShape anIndices;
2676 TopExp::MapShapes(aShape, anIndices);
2678 TopTools_ListIteratorOfListOfShape itSub (listSS);
2679 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
2680 int id = anIndices.FindIndex(itSub.Value());
2681 aSeqOfIDs->Append(id);
2687 //=======================================================================
2688 //function : GetShapesOnBoxIDs
2690 * \brief Find sub-shapes complying with given status about surface
2691 * \param theBox - the box to check state of sub-shapes against
2692 * \param theShape - the shape to explore
2693 * \param theShapeType - type of sub-shape of theShape
2694 * \param theState - required state
2695 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
2697 //=======================================================================
2698 Handle(TColStd_HSequenceOfInteger)
2699 GEOMImpl_IShapesOperations::GetShapesOnBoxIDs(const Handle(GEOM_Object)& theBox,
2700 const Handle(GEOM_Object)& theShape,
2701 const Standard_Integer theShapeType,
2702 GEOMAlgo_State theState)
2704 // Find sub-shapes ids
2705 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2706 getShapesOnBoxIDs (theBox, theShape, theShapeType, theState);
2707 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2710 // The GetShapesOnBox() doesn't change object so no new function is required.
2711 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theBox)->GetLastFunction();
2713 // Make a Python command
2714 GEOM::TPythonDump(aFunction, /*append=*/true)
2715 << "listShapesOnBoxIDs = geompy.GetShapesOnBoxIDs("
2718 << TopAbs_ShapeEnum(theShapeType) << ", "
2725 //=======================================================================
2726 //function : GetShapesOnBox
2728 * \brief Find sub-shapes complying with given status about surface
2729 * \param theBox - the box to check state of sub-shapes against
2730 * \param theShape - the shape to explore
2731 * \param theShapeType - type of sub-shape of theShape
2732 * \param theState - required state
2733 * \retval Handle(TColStd_HSequenceOfTransient) - found sub-shapes
2735 //=======================================================================
2736 Handle(TColStd_HSequenceOfTransient)
2737 GEOMImpl_IShapesOperations::GetShapesOnBox(const Handle(GEOM_Object)& theBox,
2738 const Handle(GEOM_Object)& theShape,
2739 const Standard_Integer theShapeType,
2740 GEOMAlgo_State theState)
2742 // Find sub-shapes ids
2743 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2744 getShapesOnBoxIDs (theBox, theShape, theShapeType, theState);
2745 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2748 // Find objects by indices
2749 TCollection_AsciiString anAsciiList;
2750 Handle(TColStd_HSequenceOfTransient) aSeq;
2751 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
2752 if ( aSeq.IsNull() || aSeq->IsEmpty() )
2755 // Make a Python command
2757 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2758 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2760 GEOM::TPythonDump(aFunction)
2761 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnBox("
2764 << TopAbs_ShapeEnum(theShapeType) << ", "
2771 //=======================================================================
2772 //function : getShapesOnShapeIDs
2774 * \brief Find IDs of sub-shapes complying with given status about surface
2775 * \param theCheckShape - the shape to check state of sub-shapes against
2776 * \param theShape - the shape to explore
2777 * \param theShapeType - type of sub-shape of theShape
2778 * \param theState - required state
2779 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
2781 //=======================================================================
2782 Handle(TColStd_HSequenceOfInteger)
2783 GEOMImpl_IShapesOperations::getShapesOnShapeIDs
2784 (const Handle(GEOM_Object)& theCheckShape,
2785 const Handle(GEOM_Object)& theShape,
2786 const Standard_Integer theShapeType,
2787 GEOMAlgo_State theState)
2789 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
2791 TopoDS_Shape aCheckShape = theCheckShape->GetValue();
2792 TopoDS_Shape aShape = theShape->GetValue();
2793 TopTools_ListOfShape res;
2795 // Check presence of triangulation, build if need
2796 if (!GEOMUtils::CheckTriangulation(aShape)) {
2797 SetErrorCode("Cannot build triangulation on the shape");
2801 // Compute classification tolerance.
2802 TopTools_IndexedMapOfShape aMapVtx;
2803 Standard_Real aTol = Precision::Confusion();
2805 TopExp::MapShapes(aShape, TopAbs_VERTEX, aMapVtx);
2808 Standard_Integer aNbVtx = aMapVtx.Extent();
2810 for (i = 1; i <= aNbVtx; ++i) {
2811 const TopoDS_Vertex aVtx = TopoDS::Vertex(aMapVtx.FindKey(i));
2812 const Standard_Real aVtxTol = BRep_Tool::Tolerance(aVtx);
2814 if (aTol < aVtxTol) {
2819 // Bound the tolerance value.
2820 if (aTol > 0.0001) {
2825 GEOMAlgo_FinderShapeOn2 aFinder;
2827 Handle(GEOMAlgo_ClsfSolid) aClsfSolid = new GEOMAlgo_ClsfSolid;
2828 aClsfSolid->SetShape(aCheckShape);
2830 aFinder.SetShape(aShape);
2831 aFinder.SetTolerance(aTol);
2832 aFinder.SetClsf(aClsfSolid);
2833 aFinder.SetShapeType( (TopAbs_ShapeEnum)theShapeType );
2834 aFinder.SetState(theState);
2837 // Interprete results
2838 Standard_Integer iErr = aFinder.ErrorStatus();
2839 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn2.cxx
2842 SetErrorCode("theCheckShape must be a solid");
2845 MESSAGE(" iErr : " << iErr);
2846 TCollection_AsciiString aMsg (" iErr : ");
2847 aMsg += TCollection_AsciiString(iErr);
2852 Standard_Integer iWrn = aFinder.WarningStatus();
2853 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn2.cxx
2855 MESSAGE(" *** iWrn : " << iWrn);
2858 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
2860 if (listSS.Extent() < 1) {
2861 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
2862 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
2865 // Fill sequence of object IDs
2866 aSeqOfIDs = new TColStd_HSequenceOfInteger;
2868 TopTools_IndexedMapOfShape anIndices;
2869 TopExp::MapShapes(aShape, anIndices);
2871 TopTools_ListIteratorOfListOfShape itSub (listSS);
2872 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
2873 int id = anIndices.FindIndex(itSub.Value());
2874 aSeqOfIDs->Append(id);
2880 //=======================================================================
2881 //function : GetShapesOnShapeIDs
2883 * \brief Find sub-shapes complying with given status about surface
2884 * \param theCheckShape - the shape to check state of sub-shapes against
2885 * \param theShape - the shape to explore
2886 * \param theShapeType - type of sub-shape of theShape
2887 * \param theState - required state
2888 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
2890 //=======================================================================
2891 Handle(TColStd_HSequenceOfInteger)
2892 GEOMImpl_IShapesOperations::GetShapesOnShapeIDs
2893 (const Handle(GEOM_Object)& theCheckShape,
2894 const Handle(GEOM_Object)& theShape,
2895 const Standard_Integer theShapeType,
2896 GEOMAlgo_State theState)
2898 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2899 getShapesOnShapeIDs (theCheckShape, theShape, theShapeType, theState);
2901 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2904 // The GetShapesOnShape() doesn't change object so no new function is required.
2905 Handle(GEOM_Function) aFunction =
2906 GEOM::GetCreatedLast(theShape,theCheckShape)->GetLastFunction();
2908 // Make a Python command
2909 GEOM::TPythonDump(aFunction, /*append=*/true)
2910 << "listShapesOnBoxIDs = geompy.GetShapesOnShapeIDs("
2911 << theCheckShape << ", "
2913 << TopAbs_ShapeEnum(theShapeType) << ", "
2920 //=======================================================================
2921 //function : GetShapesOnShape
2923 * \brief Find sub-shapes complying with given status about surface
2924 * \param theCheckShape - the shape to check state of sub-shapes against
2925 * \param theShape - the shape to explore
2926 * \param theShapeType - type of sub-shape of theShape
2927 * \param theState - required state
2928 * \retval Handle(TColStd_HSequenceOfTransient) - found sub-shapes
2930 //=======================================================================
2931 Handle(TColStd_HSequenceOfTransient)
2932 GEOMImpl_IShapesOperations::GetShapesOnShape
2933 (const Handle(GEOM_Object)& theCheckShape,
2934 const Handle(GEOM_Object)& theShape,
2935 const Standard_Integer theShapeType,
2936 GEOMAlgo_State theState)
2938 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2939 getShapesOnShapeIDs (theCheckShape, theShape, theShapeType, theState);
2940 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2943 // Find objects by indices
2944 TCollection_AsciiString anAsciiList;
2945 Handle(TColStd_HSequenceOfTransient) aSeq;
2946 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
2948 if ( aSeq.IsNull() || aSeq->IsEmpty() )
2951 // Make a Python command
2953 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2954 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2956 GEOM::TPythonDump(aFunction)
2957 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnShape("
2958 << theCheckShape << ", "
2960 << TopAbs_ShapeEnum(theShapeType) << ", "
2967 //=======================================================================
2968 //function : GetShapesOnShapeAsCompound
2969 //=======================================================================
2970 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetShapesOnShapeAsCompound
2971 (const Handle(GEOM_Object)& theCheckShape,
2972 const Handle(GEOM_Object)& theShape,
2973 const Standard_Integer theShapeType,
2974 GEOMAlgo_State theState)
2976 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2977 getShapesOnShapeIDs (theCheckShape, theShape, theShapeType, theState);
2979 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2982 // Find objects by indices
2983 TCollection_AsciiString anAsciiList;
2984 Handle(TColStd_HSequenceOfTransient) aSeq;
2985 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
2987 if ( aSeq.IsNull() || aSeq->IsEmpty() )
2990 TopoDS_Compound aCompound;
2992 B.MakeCompound(aCompound);
2994 for(; i<=aSeq->Length(); i++) {
2995 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(aSeq->Value(i));
2996 TopoDS_Shape aShape_i = anObj->GetValue();
2997 B.Add(aCompound,aShape_i);
3000 //Add a new result object
3001 Handle(GEOM_Object) aRes = GetEngine()->AddObject(GetDocID(), GEOM_SHAPES_ON_SHAPE);
3002 Handle(GEOM_Function) aFunction =
3003 aRes->AddFunction(GEOMImpl_ShapeDriver::GetID(), SHAPES_ON_SHAPE);
3004 aFunction->SetValue(aCompound);
3007 aSeq->Append( theCheckShape->GetLastFunction() );
3008 aSeq->Append( theShape->GetLastFunction() );
3010 GEOMImpl_IShapes aCI( aFunction );
3011 aCI.SetShapes( aSeq );
3012 aCI.SetSubShapeType( theShapeType );
3013 aCI.SetTolerance( theState );
3015 GEOM::TPythonDump(aFunction)
3016 << aRes << " = geompy.GetShapesOnShapeAsCompound("
3017 << theCheckShape << ", "
3019 << TopAbs_ShapeEnum(theShapeType) << ", "
3027 //=============================================================================
3029 * GetSubShapeEdgeSorted
3031 //=============================================================================
3032 Handle(TColStd_HSequenceOfTransient)
3033 GEOMImpl_IShapesOperations::GetSubShapeEdgeSorted
3034 (const Handle(GEOM_Object) &theShape,
3035 const Handle(GEOM_Object) &theStartPoint)
3037 // Get the sorted edges indices.
3038 Handle(TColStd_HSequenceOfInteger) aSortedIDs =
3039 getSubShapeEdgeSortedIDs(theShape, theStartPoint);
3041 // Get object by indices.
3042 TCollection_AsciiString anAsciiList;
3043 Handle(TColStd_HSequenceOfTransient) aSeq =
3044 getObjectsShapesOn(theShape, aSortedIDs, anAsciiList);
3046 if (aSeq.IsNull() || aSeq->IsEmpty()) {
3047 SetErrorCode("Empty sequence of edges");
3051 // Make a Python command
3052 Handle(GEOM_Object) anObj =
3053 Handle(GEOM_Object)::DownCast(aSeq->Value(1));
3054 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
3056 GEOM::TPythonDump(aFunction)
3057 << "[" << anAsciiList.ToCString() << "] = geompy.GetSubShapeEdgeSorted("
3058 << theShape << ", " << theStartPoint << ")";
3065 //=======================================================================
3066 //function : getShapesOnSurfaceIDs
3068 * \brief Find IDs of sub-shapes complying with given status about surface
3069 * \param theSurface - the surface to check state of sub-shapes against
3070 * \param theShape - the shape to explore
3071 * \param theShapeType - type of sub-shape of theShape
3072 * \param theState - required state
3073 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
3075 //=======================================================================
3076 Handle(TColStd_HSequenceOfInteger)
3077 GEOMImpl_IShapesOperations::getShapesOnSurfaceIDs(const Handle(Geom_Surface)& theSurface,
3078 const TopoDS_Shape& theShape,
3079 TopAbs_ShapeEnum theShapeType,
3080 GEOMAlgo_State theState)
3082 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
3084 // Check presence of triangulation, build if need
3085 if (!GEOMUtils::CheckTriangulation(theShape)) {
3086 SetErrorCode("Cannot build triangulation on the shape");
3090 // BEGIN: Mantis issue 0020961: Error on a pipe T-Shape
3091 // Compute tolerance
3092 Standard_Real T, VertMax = -RealLast();
3095 for (TopExp_Explorer ExV (theShape, TopAbs_VERTEX); ExV.More(); ExV.Next()) {
3096 TopoDS_Vertex Vertex = TopoDS::Vertex(ExV.Current());
3097 T = BRep_Tool::Tolerance(Vertex);
3102 catch (Standard_Failure) {
3103 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
3104 SetErrorCode(aFail->GetMessageString());
3107 // END: Mantis issue 0020961
3110 GEOMAlgo_FinderShapeOn2 aFinder;
3111 Handle(GEOMAlgo_ClsfSurf) aClsfSurf = new GEOMAlgo_ClsfSurf;
3112 Standard_Real aTol = VertMax; // Mantis issue 0020961
3114 aClsfSurf->SetSurface(theSurface);
3115 aFinder.SetShape(theShape);
3116 aFinder.SetTolerance(aTol);
3117 aFinder.SetClsf(aClsfSurf);
3118 aFinder.SetShapeType(theShapeType);
3119 aFinder.SetState(theState);
3121 // Sets the minimal number of inner points for the faces that do not have own
3122 // inner points at all (for e.g. rectangular planar faces have just 2 triangles).
3124 aFinder.SetNbPntsMin(3);
3125 // Sets the maximal number of inner points for edges or faces.
3126 // It is usefull for the cases when this number is very big (e.g =2000) to improve
3127 // the performance. If this value =0, all inner points will be taken into account.
3129 aFinder.SetNbPntsMax(100);
3133 // Interprete results
3134 Standard_Integer iErr = aFinder.ErrorStatus();
3135 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn2.cxx
3137 MESSAGE(" iErr : " << iErr);
3138 TCollection_AsciiString aMsg (" iErr : ");
3139 aMsg += TCollection_AsciiString(iErr);
3143 Standard_Integer iWrn = aFinder.WarningStatus();
3144 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn2.cxx
3146 MESSAGE(" *** iWrn : " << iWrn);
3149 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
3151 if (listSS.Extent() < 1) {
3152 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
3153 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
3157 // Fill sequence of object IDs
3158 aSeqOfIDs = new TColStd_HSequenceOfInteger;
3160 TopTools_IndexedMapOfShape anIndices;
3161 TopExp::MapShapes(theShape, anIndices);
3163 TopTools_ListIteratorOfListOfShape itSub (listSS);
3164 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
3165 int id = anIndices.FindIndex(itSub.Value());
3166 aSeqOfIDs->Append(id);
3172 //=======================================================================
3173 //function : getObjectsShapesOn
3175 * \brief Find shape objects and their entries by their ids
3176 * \param theShapeIDs - incoming shape ids
3177 * \param theShapeEntries - outgoing entries like "entry1, entry2, ..."
3178 * \retval Handle(TColStd_HSequenceOfTransient) - found shape objects
3180 //=======================================================================
3181 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::
3182 getObjectsShapesOn(const Handle(GEOM_Object)& theShape,
3183 const Handle(TColStd_HSequenceOfInteger)& theShapeIDs,
3184 TCollection_AsciiString & theShapeEntries)
3186 Handle(TColStd_HSequenceOfTransient) aSeq;
3188 if ( !theShapeIDs.IsNull() && theShapeIDs->Length() > 0 )
3190 aSeq = new TColStd_HSequenceOfTransient;
3191 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
3192 TCollection_AsciiString anEntry;
3193 for ( int i = 1; i <= theShapeIDs->Length(); ++i )
3195 anArray->SetValue(1, theShapeIDs->Value( i ));
3196 Handle(GEOM_Object) anObj = GetEngine()->AddSubShape(theShape, anArray);
3197 aSeq->Append( anObj );
3199 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
3200 if ( i != 1 ) theShapeEntries += ",";
3201 theShapeEntries += anEntry;
3207 //=============================================================================
3209 * getSubShapeEdgeSortedIDs
3211 //=============================================================================
3212 Handle(TColStd_HSequenceOfInteger)
3213 GEOMImpl_IShapesOperations::getSubShapeEdgeSortedIDs
3214 (const Handle(GEOM_Object) &theShape,
3215 const Handle(GEOM_Object) &theStartPoint)
3217 Handle(TColStd_HSequenceOfInteger) aResult;
3219 if (theShape.IsNull() || theStartPoint.IsNull()) {
3220 SetErrorCode("NULL GEOM object");
3224 const TopoDS_Shape aShape = theShape->GetValue();
3225 const TopoDS_Shape aStartPoint = theStartPoint->GetValue();
3227 if (aShape.IsNull() || aStartPoint.IsNull()) {
3228 SetErrorCode("NULL Shape");
3232 if (aStartPoint.ShapeType() != TopAbs_VERTEX) {
3233 SetErrorCode("Starting point is not a vertex");
3237 TopExp_Explorer anExp(aShape, TopAbs_EDGE);
3238 TopTools_MapOfShape aMapFence;
3239 TopTools_ListOfShape anEdges;
3241 for (; anExp.More(); anExp.Next()) {
3242 const TopoDS_Shape &anEdge = anExp.Current();
3244 if (aMapFence.Add(anEdge)) {
3245 anEdges.Append(anEdge);
3249 if (anEdges.IsEmpty()) {
3250 SetErrorCode("Shape doesn't contain edges");
3254 // Step 1: Sort edges
3255 GEOMUtils::SortShapes(anEdges, Standard_False);
3257 TopTools_ListIteratorOfListOfShape anIter(anEdges);
3258 TopoDS_Vertex aV[2];
3259 TopTools_DataMapOfShapeListOfShape aMapVE;
3261 // Step 2: Fill the map vertex - list of edges.
3262 for (; anIter.More(); anIter.Next()) {
3263 TopoDS_Edge anEdge = TopoDS::Edge(anIter.Value());
3265 TopExp::Vertices(anEdge, aV[0], aV[1]);
3267 const Standard_Integer aNbV = aV[0].IsSame(aV[1]) ? 1 : 2;
3270 for (i = 0; i < aNbV; ++i) {
3271 if (aV[i].IsNull() == Standard_False) {
3272 if (!aMapVE.IsBound(aV[i])) {
3273 // There is no this vertex in the map.
3274 aMapVE.Bind(aV[i], TopTools_ListOfShape());
3277 // Add the edge to the list bound with the vertex aV[i].
3278 TopTools_ListOfShape &aLEdges = aMapVE.ChangeFind(aV[i]);
3280 aLEdges.Append(anEdge);
3285 // Step 3: Find starting point in aMapVE.
3286 TopoDS_Vertex aStartVtx = TopoDS::Vertex(aStartPoint);
3288 if (!aMapVE.IsBound(aStartVtx)) {
3289 aStartVtx = getSameVertex(aShape, aStartVtx);
3291 if (aStartVtx.IsNull()) {
3292 SetErrorCode("Invalid Starting point");
3297 TopTools_IndexedMapOfShape anIndices;
3298 TopTools_MapOfShape aMapVFence;
3299 TopoDS_Shape aCurVtx = aStartVtx;
3300 TopoDS_Edge aCurEdge =
3301 TopoDS::Edge(aMapVE.Find(aCurVtx).First());
3303 aResult = new TColStd_HSequenceOfInteger;
3304 TopExp::MapShapes(aShape, anIndices);
3306 // Step 4: Fill the list of sorted edges.
3307 while (aMapVFence.Add(aCurVtx)) {
3308 // Append the ID of the current edge to the list of sorted.
3309 aResult->Append(anIndices.FindIndex(aCurEdge));
3310 TopExp::Vertices(aCurEdge, aV[0], aV[1]);
3312 // Get the next vertex.
3313 if (aCurVtx.IsSame(aV[0])) {
3314 if (aCurVtx.IsSame(aV[1])) {
3315 // There is no next vertex.
3324 if (aCurVtx.IsNull()) {
3325 // There is no next vertex.
3329 // Get the next edge.
3330 const TopTools_ListOfShape &aLEdges = aMapVE.Find(aCurVtx);
3331 TopTools_ListIteratorOfListOfShape anEIter(aLEdges);
3333 for (; anEIter.More(); anEIter.Next()) {
3334 const TopoDS_Shape &aLocalEdge = anEIter.Value();
3336 if (aLocalEdge.IsNull() == Standard_False) {
3337 if (!aCurEdge.IsSame(aLocalEdge)) {
3338 aCurEdge = TopoDS::Edge(aLocalEdge);
3344 if (!anEIter.More()) {
3345 // There is no next edge.
3353 //=======================================================================
3354 //function : getShapesOnSurface
3356 * \brief Find sub-shapes complying with given status about surface
3357 * \param theSurface - the surface to check state of sub-shapes against
3358 * \param theShape - the shape to explore
3359 * \param theShapeType - type of sub-shape of theShape
3360 * \param theState - required state
3361 * \param theShapeEntries - outgoing entries like "entry1, entry2, ..."
3362 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
3364 //=======================================================================
3365 Handle(TColStd_HSequenceOfTransient)
3366 GEOMImpl_IShapesOperations::getShapesOnSurface(const Handle(Geom_Surface)& theSurface,
3367 const Handle(GEOM_Object)& theShape,
3368 TopAbs_ShapeEnum theShapeType,
3369 GEOMAlgo_State theState,
3370 TCollection_AsciiString & theShapeEntries)
3372 // Find sub-shapes ids
3373 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
3374 getShapesOnSurfaceIDs (theSurface, theShape->GetValue(), theShapeType, theState);
3375 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
3378 return getObjectsShapesOn( theShape, aSeqOfIDs, theShapeEntries );
3381 //=============================================================================
3385 //=============================================================================
3386 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnPlane
3387 (const Handle(GEOM_Object)& theShape,
3388 const Standard_Integer theShapeType,
3389 const Handle(GEOM_Object)& theAx1,
3390 const GEOMAlgo_State theState)
3394 if (theShape.IsNull() || theAx1.IsNull()) return NULL;
3396 TopoDS_Shape aShape = theShape->GetValue();
3397 TopoDS_Shape anAx1 = theAx1->GetValue();
3399 if (aShape.IsNull() || anAx1.IsNull()) return NULL;
3401 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3402 if ( !checkTypeShapesOn( theShapeType ))
3406 Handle(Geom_Surface) aPlane = makePlane( anAx1 );
3407 if ( aPlane.IsNull() )
3411 TCollection_AsciiString anAsciiList;
3412 Handle(TColStd_HSequenceOfTransient) aSeq;
3413 aSeq = getShapesOnSurface( aPlane, theShape, aShapeType, theState, anAsciiList );
3414 if ( aSeq.IsNull() || aSeq->Length() == 0 )
3417 // Make a Python command
3419 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
3420 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
3422 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
3423 << "] = geompy.GetShapesOnPlane(" << theShape << ", "
3424 << aShapeType << ", " << theAx1 << ", " << theState << ")";
3430 //=============================================================================
3432 * GetShapesOnPlaneWithLocation
3434 //=============================================================================
3435 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnPlaneWithLocation
3436 (const Handle(GEOM_Object)& theShape,
3437 const Standard_Integer theShapeType,
3438 const Handle(GEOM_Object)& theAx1,
3439 const Handle(GEOM_Object)& thePnt,
3440 const GEOMAlgo_State theState)
3444 if (theShape.IsNull() || theAx1.IsNull() || thePnt.IsNull()) return NULL;
3446 TopoDS_Shape aShape = theShape->GetValue();
3447 TopoDS_Shape anAx1 = theAx1->GetValue();
3448 TopoDS_Shape anPnt = thePnt->GetValue();
3450 if (aShape.IsNull() || anAx1.IsNull() || anPnt.IsNull()) return NULL;
3452 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3453 if ( !checkTypeShapesOn( theShapeType ))
3457 if ( anAx1.ShapeType() != TopAbs_EDGE || anPnt.ShapeType() != TopAbs_VERTEX ) return NULL;
3458 TopoDS_Vertex V1, V2, V3;
3459 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
3460 TopExp::Vertices(anEdge, V1, V2, Standard_True);
3462 if (V1.IsNull() || V2.IsNull()) {
3463 SetErrorCode("Bad edge given for the plane normal vector");
3466 V3 = TopoDS::Vertex(anPnt);
3469 SetErrorCode("Bad vertex given for the plane location");
3472 gp_Pnt aLoc = BRep_Tool::Pnt(V3);
3473 gp_Vec aVec(BRep_Tool::Pnt(V1),BRep_Tool::Pnt(V2));
3475 if (aVec.Magnitude() < Precision::Confusion()) {
3476 SetErrorCode("Vector with null magnitude given");
3479 Handle(Geom_Surface) aPlane = new Geom_Plane(aLoc, aVec);
3481 if ( aPlane.IsNull() )
3485 TCollection_AsciiString anAsciiList;
3486 Handle(TColStd_HSequenceOfTransient) aSeq;
3487 aSeq = getShapesOnSurface( aPlane, theShape, aShapeType, theState, anAsciiList );
3488 if ( aSeq.IsNull() || aSeq->Length() == 0 )
3491 // Make a Python command
3493 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
3494 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
3496 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
3497 << "] = geompy.GetShapesOnPlaneWithLocation(" << theShape << ", "
3498 << aShapeType << ", " << theAx1 << ", "<< thePnt <<", " << theState << ")";
3504 //=============================================================================
3506 * GetShapesOnCylinder
3508 //=============================================================================
3509 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnCylinder
3510 (const Handle(GEOM_Object)& theShape,
3511 const Standard_Integer theShapeType,
3512 const Handle(GEOM_Object)& theAxis,
3513 const Standard_Real theRadius,
3514 const GEOMAlgo_State theState)
3518 if (theShape.IsNull() || theAxis.IsNull()) return NULL;
3520 TopoDS_Shape aShape = theShape->GetValue();
3521 TopoDS_Shape anAxis = theAxis->GetValue();
3523 if (aShape.IsNull() || anAxis.IsNull()) return NULL;
3525 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3526 if ( !checkTypeShapesOn( aShapeType ))
3529 // Create a cylinder surface
3530 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
3531 if ( aCylinder.IsNull() )
3535 TCollection_AsciiString anAsciiList;
3536 Handle(TColStd_HSequenceOfTransient) aSeq;
3537 aSeq = getShapesOnSurface( aCylinder, theShape, aShapeType, theState, anAsciiList );
3538 if ( aSeq.IsNull() || aSeq->Length() == 0 )
3541 // Make a Python command
3543 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
3544 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
3546 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
3547 << "] = geompy.GetShapesOnCylinder(" << theShape << ", " << aShapeType
3548 << ", " << theAxis << ", " << theRadius << ", " << theState << ")";
3554 //=============================================================================
3556 * GetShapesOnCylinderWithLocation
3558 //=============================================================================
3559 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnCylinderWithLocation
3560 (const Handle(GEOM_Object)& theShape,
3561 const Standard_Integer theShapeType,
3562 const Handle(GEOM_Object)& theAxis,
3563 const Handle(GEOM_Object)& thePnt,
3564 const Standard_Real theRadius,
3565 const GEOMAlgo_State theState)
3569 if (theShape.IsNull() || theAxis.IsNull() || thePnt.IsNull()) return NULL;
3571 TopoDS_Shape aShape = theShape->GetValue();
3572 TopoDS_Shape anAxis = theAxis->GetValue();
3573 TopoDS_Shape aPnt = thePnt->GetValue();
3575 if (aShape.IsNull() || anAxis.IsNull() || aPnt.IsNull()) return NULL;
3577 if (aPnt.ShapeType() != TopAbs_VERTEX )
3579 SetErrorCode("Bottom location point must be vertex");
3583 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3584 if ( !checkTypeShapesOn( aShapeType ))
3587 // Create a cylinder surface
3588 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
3589 if ( aCylinder.IsNull() )
3592 // translate the surface
3593 Handle(Geom_CylindricalSurface) aCylSurface =
3594 Handle(Geom_CylindricalSurface)::DownCast( aCylinder );
3595 if ( aCylSurface.IsNull() )
3597 SetErrorCode("Unexpected surface type instead of Geom_CylindricalSurface");
3600 gp_Pnt fromLoc = aCylSurface->Cylinder().Location();
3601 gp_Pnt toLoc = BRep_Tool::Pnt( TopoDS::Vertex( aPnt ));
3602 aCylinder->Translate( fromLoc, toLoc );
3605 TCollection_AsciiString anAsciiList;
3606 Handle(TColStd_HSequenceOfTransient) aSeq;
3607 aSeq = getShapesOnSurface( aCylinder, theShape, aShapeType, theState, anAsciiList );
3608 if ( aSeq.IsNull() || aSeq->Length() == 0 )
3611 // Make a Python command
3613 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
3614 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
3616 GEOM::TPythonDump(aFunction)
3617 << "[" << anAsciiList.ToCString()
3618 << "] = geompy.GetShapesOnCylinderWithLocation(" << theShape << ", " << aShapeType << ", "
3619 << theAxis << ", " << thePnt << ", " << theRadius << ", " << theState << ")";
3625 //=============================================================================
3629 //=============================================================================
3630 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnSphere
3631 (const Handle(GEOM_Object)& theShape,
3632 const Standard_Integer theShapeType,
3633 const Handle(GEOM_Object)& theCenter,
3634 const Standard_Real theRadius,
3635 const GEOMAlgo_State theState)
3639 if (theShape.IsNull() || theCenter.IsNull()) return NULL;
3641 TopoDS_Shape aShape = theShape->GetValue();
3642 TopoDS_Shape aCenter = theCenter->GetValue();
3644 if (aShape.IsNull() || aCenter.IsNull()) return NULL;
3646 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3647 if ( !checkTypeShapesOn( aShapeType ))
3650 // Center of the sphere
3651 if (aCenter.ShapeType() != TopAbs_VERTEX) return NULL;
3652 gp_Pnt aLoc = BRep_Tool::Pnt(TopoDS::Vertex(aCenter));
3654 gp_Ax3 anAx3 (aLoc, gp::DZ());
3655 Handle(Geom_SphericalSurface) aSphere =
3656 new Geom_SphericalSurface(anAx3, theRadius);
3659 TCollection_AsciiString anAsciiList;
3660 Handle(TColStd_HSequenceOfTransient) aSeq;
3661 aSeq = getShapesOnSurface( aSphere, theShape, aShapeType, theState, anAsciiList );
3662 if ( aSeq.IsNull() || aSeq->Length() == 0 )
3665 // Make a Python command
3667 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
3668 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
3670 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
3671 << "] = geompy.GetShapesOnSphere(" << theShape << ", " << aShapeType
3672 << ", " << theCenter << ", " << theRadius << ", " << theState << ")";
3678 //=============================================================================
3680 * GetShapesOnPlaneIDs
3682 //=============================================================================
3683 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnPlaneIDs
3684 (const Handle(GEOM_Object)& theShape,
3685 const Standard_Integer theShapeType,
3686 const Handle(GEOM_Object)& theAx1,
3687 const GEOMAlgo_State theState)
3691 if (theShape.IsNull() || theAx1.IsNull()) return NULL;
3693 TopoDS_Shape aShape = theShape->GetValue();
3694 TopoDS_Shape anAx1 = theAx1->GetValue();
3696 if (aShape.IsNull() || anAx1.IsNull()) return NULL;
3698 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3699 if ( !checkTypeShapesOn( aShapeType ))
3703 Handle(Geom_Surface) aPlane = makePlane( anAx1 );
3704 if ( aPlane.IsNull() )
3708 Handle(TColStd_HSequenceOfInteger) aSeq;
3709 aSeq = getShapesOnSurfaceIDs( aPlane, aShape, aShapeType, theState );
3711 // The GetShapesOnPlaneIDs() doesn't change object so no new function is required.
3712 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAx1)->GetLastFunction();
3714 // Make a Python command
3715 GEOM::TPythonDump(aFunction, /*append=*/true)
3716 << "listShapesOnPlane = geompy.GetShapesOnPlaneIDs"
3717 << "(" << theShape << "," << aShapeType << "," << theAx1 << "," << theState << ")";
3723 //=============================================================================
3725 * GetShapesOnPlaneWithLocationIDs
3727 //=============================================================================
3728 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnPlaneWithLocationIDs
3729 (const Handle(GEOM_Object)& theShape,
3730 const Standard_Integer theShapeType,
3731 const Handle(GEOM_Object)& theAx1,
3732 const Handle(GEOM_Object)& thePnt,
3733 const GEOMAlgo_State theState)
3737 if (theShape.IsNull() || theAx1.IsNull() || thePnt.IsNull()) return NULL;
3739 TopoDS_Shape aShape = theShape->GetValue();
3740 TopoDS_Shape anAx1 = theAx1->GetValue();
3741 TopoDS_Shape anPnt = thePnt->GetValue();
3743 if (aShape.IsNull() || anAx1.IsNull() || anPnt.IsNull()) return NULL;
3745 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3746 if ( !checkTypeShapesOn( aShapeType ))
3750 if (anAx1.ShapeType() != TopAbs_EDGE || anPnt.ShapeType() != TopAbs_VERTEX) return NULL;
3751 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
3752 TopoDS_Vertex V1, V2, V3;
3753 TopExp::Vertices(anEdge, V1, V2, Standard_True);
3754 if (V1.IsNull() || V2.IsNull()) {
3755 SetErrorCode("Bad edge given for the plane normal vector");
3758 V3 = TopoDS::Vertex(anPnt);
3760 SetErrorCode("Bad vertex given for the plane location");
3763 gp_Pnt aLoc = BRep_Tool::Pnt(V3);
3764 gp_Vec aVec(BRep_Tool::Pnt(V1),BRep_Tool::Pnt(V2));
3765 if (aVec.Magnitude() < Precision::Confusion()) {
3766 SetErrorCode("Vector with null magnitude given");
3770 Handle(Geom_Surface) aPlane = new Geom_Plane(aLoc, aVec);
3771 if ( aPlane.IsNull() )
3775 Handle(TColStd_HSequenceOfInteger) aSeq;
3776 aSeq = getShapesOnSurfaceIDs( aPlane, aShape, aShapeType, theState );
3778 // The GetShapesOnPlaneIDs() doesn't change object so no new function is required.
3779 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAx1)->GetLastFunction();
3781 // Make a Python command
3782 GEOM::TPythonDump(aFunction, /*append=*/true)
3783 << "listShapesOnPlane = geompy.GetShapesOnPlaneWithLocationIDs"
3784 << "(" << theShape << ", " << aShapeType << ", " << theAx1 << ", "<< thePnt << ", " << theState << ")";
3790 //=============================================================================
3792 * GetShapesOnCylinderIDs
3794 //=============================================================================
3795 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnCylinderIDs
3796 (const Handle(GEOM_Object)& theShape,
3797 const Standard_Integer theShapeType,
3798 const Handle(GEOM_Object)& theAxis,
3799 const Standard_Real theRadius,
3800 const GEOMAlgo_State theState)
3804 if (theShape.IsNull() || theAxis.IsNull()) return NULL;
3806 TopoDS_Shape aShape = theShape->GetValue();
3807 TopoDS_Shape anAxis = theAxis->GetValue();
3809 if (aShape.IsNull() || anAxis.IsNull()) return NULL;
3811 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3812 if ( !checkTypeShapesOn( aShapeType ))
3815 // Create a cylinder surface
3816 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
3817 if ( aCylinder.IsNull() )
3821 Handle(TColStd_HSequenceOfInteger) aSeq;
3822 aSeq = getShapesOnSurfaceIDs( aCylinder, aShape, aShapeType, theState );
3824 // The GetShapesOnCylinder() doesn't change object so no new function is required.
3825 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAxis)->GetLastFunction();
3827 // Make a Python command
3828 GEOM::TPythonDump(aFunction, /*append=*/true)
3829 << "listShapesOnCylinder = geompy.GetShapesOnCylinderIDs"
3830 << "(" << theShape << ", " << aShapeType << ", " << theAxis << ", "
3831 << theRadius << ", " << theState << ")";
3837 //=============================================================================
3839 * GetShapesOnCylinderWithLocationIDs
3841 //=============================================================================
3842 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnCylinderWithLocationIDs
3843 (const Handle(GEOM_Object)& theShape,
3844 const Standard_Integer theShapeType,
3845 const Handle(GEOM_Object)& theAxis,
3846 const Handle(GEOM_Object)& thePnt,
3847 const Standard_Real theRadius,
3848 const GEOMAlgo_State theState)
3852 if (theShape.IsNull() || theAxis.IsNull() || thePnt.IsNull()) return NULL;
3854 TopoDS_Shape aShape = theShape->GetValue();
3855 TopoDS_Shape anAxis = theAxis->GetValue();
3856 TopoDS_Shape aPnt = thePnt->GetValue();
3858 if (aShape.IsNull() || anAxis.IsNull() || aPnt.IsNull()) return NULL;
3860 if (aPnt.ShapeType() != TopAbs_VERTEX )
3862 SetErrorCode("Bottom location point must be vertex");
3866 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3867 if ( !checkTypeShapesOn( aShapeType ))
3870 // Create a cylinder surface
3871 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
3872 if ( aCylinder.IsNull() )
3875 // translate the surface
3876 Handle(Geom_CylindricalSurface) aCylSurface =
3877 Handle(Geom_CylindricalSurface)::DownCast( aCylinder );
3878 if ( aCylSurface.IsNull() )
3880 SetErrorCode("Unexpected surface type instead of Geom_CylindricalSurface");
3883 gp_Pnt fromLoc = aCylSurface->Cylinder().Location();
3884 gp_Pnt toLoc = BRep_Tool::Pnt( TopoDS::Vertex( aPnt ));
3885 aCylinder->Translate( fromLoc, toLoc );
3888 Handle(TColStd_HSequenceOfInteger) aSeq;
3889 aSeq = getShapesOnSurfaceIDs( aCylinder, aShape, aShapeType, theState );
3891 // The GetShapesOnCylinder() doesn't change object so no new function is required.
3892 Handle(GEOM_Function) aFunction =
3893 GEOM::GetCreatedLast(theShape, GEOM::GetCreatedLast(thePnt,theAxis))->GetLastFunction();
3895 // Make a Python command
3896 GEOM::TPythonDump(aFunction, /*append=*/true)
3897 << "listShapesOnCylinder = geompy.GetShapesOnCylinderWithLocationIDs"
3898 << "(" << theShape << ", " << aShapeType << ", " << theAxis << ", "
3899 << thePnt << ", " << theRadius << ", " << theState << ")";
3905 //=============================================================================
3907 * GetShapesOnSphereIDs
3909 //=============================================================================
3910 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnSphereIDs
3911 (const Handle(GEOM_Object)& theShape,
3912 const Standard_Integer theShapeType,
3913 const Handle(GEOM_Object)& theCenter,
3914 const Standard_Real theRadius,
3915 const GEOMAlgo_State theState)
3919 if (theShape.IsNull() || theCenter.IsNull()) return NULL;
3921 TopoDS_Shape aShape = theShape->GetValue();
3922 TopoDS_Shape aCenter = theCenter->GetValue();
3924 if (aShape.IsNull() || aCenter.IsNull()) return NULL;
3926 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3927 if ( !checkTypeShapesOn( aShapeType ))
3930 // Center of the sphere
3931 if (aCenter.ShapeType() != TopAbs_VERTEX) return NULL;
3932 gp_Pnt aLoc = BRep_Tool::Pnt(TopoDS::Vertex(aCenter));
3934 gp_Ax3 anAx3 (aLoc, gp::DZ());
3935 Handle(Geom_SphericalSurface) aSphere =
3936 new Geom_SphericalSurface(anAx3, theRadius);
3939 Handle(TColStd_HSequenceOfInteger) aSeq;
3940 aSeq = getShapesOnSurfaceIDs( aSphere, aShape, aShapeType, theState );
3942 // The GetShapesOnSphere() doesn't change object so no new function is required.
3943 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theCenter)->GetLastFunction();
3945 // Make a Python command
3946 GEOM::TPythonDump(aFunction, /*append=*/true)
3947 << "listShapesOnCylinder = geompy.GetShapesOnSphereIDs"
3948 << "(" << theShape << ", " << aShapeType << ", " << theCenter << ", "
3949 << theRadius << ", " << theState << ")";
3955 //=======================================================================
3956 //function : getShapesOnQuadrangleIDs
3958 * \brief Find IDs of sub-shapes complying with given status about quadrangle
3959 * \param theShape - the shape to explore
3960 * \param theShapeType - type of sub-shape of theShape
3961 * \param theTopLeftPoint - top left quadrangle corner
3962 * \param theTopRigthPoint - top right quadrangle corner
3963 * \param theBottomLeftPoint - bottom left quadrangle corner
3964 * \param theBottomRigthPoint - bottom right quadrangle corner
3965 * \param theState - required state
3966 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
3968 //=======================================================================
3969 Handle(TColStd_HSequenceOfInteger)
3970 GEOMImpl_IShapesOperations::getShapesOnQuadrangleIDs (const Handle(GEOM_Object)& theShape,
3971 const Standard_Integer theShapeType,
3972 const Handle(GEOM_Object)& theTopLeftPoint,
3973 const Handle(GEOM_Object)& theTopRigthPoint,
3974 const Handle(GEOM_Object)& theBottomLeftPoint,
3975 const Handle(GEOM_Object)& theBottomRigthPoint,
3976 const GEOMAlgo_State theState)
3980 if ( theShape.IsNull() ||
3981 theTopLeftPoint.IsNull() ||
3982 theTopRigthPoint.IsNull() ||
3983 theBottomLeftPoint.IsNull() ||
3984 theBottomRigthPoint.IsNull() )
3987 TopoDS_Shape aShape = theShape->GetValue();
3988 TopoDS_Shape aTL = theTopLeftPoint->GetValue();
3989 TopoDS_Shape aTR = theTopRigthPoint->GetValue();
3990 TopoDS_Shape aBL = theBottomLeftPoint->GetValue();
3991 TopoDS_Shape aBR = theBottomRigthPoint->GetValue();
3993 if (aShape.IsNull() ||
3998 aTL.ShapeType() != TopAbs_VERTEX ||
3999 aTR.ShapeType() != TopAbs_VERTEX ||
4000 aBL.ShapeType() != TopAbs_VERTEX ||
4001 aBR.ShapeType() != TopAbs_VERTEX )
4004 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
4005 if ( !checkTypeShapesOn( aShapeType ))
4008 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
4010 // Check presence of triangulation, build if need
4011 if (!GEOMUtils::CheckTriangulation(aShape)) {
4012 SetErrorCode("Cannot build triangulation on the shape");
4017 gp_Pnt aPntTL = BRep_Tool::Pnt(TopoDS::Vertex(aTL));
4018 gp_Pnt aPntTR = BRep_Tool::Pnt(TopoDS::Vertex(aTR));
4019 gp_Pnt aPntBL = BRep_Tool::Pnt(TopoDS::Vertex(aBL));
4020 gp_Pnt aPntBR = BRep_Tool::Pnt(TopoDS::Vertex(aBR));
4022 GEOMAlgo_FinderShapeOn2 aFinder;
4023 Handle(GEOMAlgo_ClsfQuad) aClsfQuad = new GEOMAlgo_ClsfQuad;
4025 Standard_Real aTol = 0.0001; // default value
4027 aClsfQuad->SetCorners(aPntTL, aPntTR, aPntBL, aPntBR);
4028 aFinder.SetShape(aShape);
4029 aFinder.SetTolerance(aTol);
4030 aFinder.SetClsf(aClsfQuad);
4031 aFinder.SetShapeType(aShapeType);
4032 aFinder.SetState(theState);
4034 // Sets the minimal number of inner points for the faces that do not have own
4035 // inner points at all (for e.g. rectangular planar faces have just 2 triangles).
4037 aFinder.SetNbPntsMin(3);
4038 // Sets the maximal number of inner points for edges or faces.
4039 // It is usefull for the cases when this number is very big (e.g =2000) to improve
4040 // the performance. If this value =0, all inner points will be taken into account.
4042 aFinder.SetNbPntsMax(100);
4046 // Interprete results
4047 Standard_Integer iErr = aFinder.ErrorStatus();
4048 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn2.cxx
4050 MESSAGE(" iErr : " << iErr);
4051 TCollection_AsciiString aMsg (" iErr : ");
4052 aMsg += TCollection_AsciiString(iErr);
4056 Standard_Integer iWrn = aFinder.WarningStatus();
4057 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn2.cxx
4059 MESSAGE(" *** iWrn : " << iWrn);
4062 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
4064 if (listSS.Extent() < 1) {
4065 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
4066 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
4070 // Fill sequence of object IDs
4071 aSeqOfIDs = new TColStd_HSequenceOfInteger;
4073 TopTools_IndexedMapOfShape anIndices;
4074 TopExp::MapShapes(aShape, anIndices);
4076 TopTools_ListIteratorOfListOfShape itSub (listSS);
4077 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
4078 int id = anIndices.FindIndex(itSub.Value());
4079 aSeqOfIDs->Append(id);
4084 //=======================================================================
4085 //function : GetShapesOnQuadrangle
4087 * \brief Find sub-shapes complying with given status about quadrangle
4088 * \param theShape - the shape to explore
4089 * \param theShapeType - type of sub-shape of theShape
4090 * \param theTopLeftPoint - top left quadrangle corner
4091 * \param theTopRigthPoint - top right quadrangle corner
4092 * \param theBottomLeftPoint - bottom left quadrangle corner
4093 * \param theBottomRigthPoint - bottom right quadrangle corner
4094 * \param theState - required state
4095 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
4097 //=======================================================================
4098 Handle(TColStd_HSequenceOfTransient)
4099 GEOMImpl_IShapesOperations::GetShapesOnQuadrangle (const Handle(GEOM_Object)& theShape,
4100 const Standard_Integer theShapeType,
4101 const Handle(GEOM_Object)& theTopLeftPoint,
4102 const Handle(GEOM_Object)& theTopRigthPoint,
4103 const Handle(GEOM_Object)& theBottomLeftPoint,
4104 const Handle(GEOM_Object)& theBottomRigthPoint,
4105 const GEOMAlgo_State theState)
4108 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
4109 getShapesOnQuadrangleIDs( theShape,
4114 theBottomRigthPoint,
4116 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->IsEmpty() )
4119 // Find objects by indices
4120 TCollection_AsciiString anAsciiList;
4121 Handle(TColStd_HSequenceOfTransient) aSeq;
4122 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
4123 if ( aSeq.IsNull() || aSeq->IsEmpty() )
4126 // Make a Python command
4128 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
4129 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
4131 GEOM::TPythonDump(aFunction)
4132 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnQuadrangle("
4134 << TopAbs_ShapeEnum(theShapeType) << ", "
4135 << theTopLeftPoint << ", "
4136 << theTopRigthPoint << ", "
4137 << theBottomLeftPoint << ", "
4138 << theBottomRigthPoint << ", "
4145 //=======================================================================
4146 //function : GetShapesOnQuadrangleIDs
4148 * \brief Find IDs of sub-shapes complying with given status about quadrangle
4149 * \param theShape - the shape to explore
4150 * \param theShapeType - type of sub-shape of theShape
4151 * \param theTopLeftPoint - top left quadrangle corner
4152 * \param theTopRigthPoint - top right quadrangle corner
4153 * \param theBottomLeftPoint - bottom left quadrangle corner
4154 * \param theBottomRigthPoint - bottom right quadrangle corner
4155 * \param theState - required state
4156 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
4158 //=======================================================================
4159 Handle(TColStd_HSequenceOfInteger)
4160 GEOMImpl_IShapesOperations::GetShapesOnQuadrangleIDs (const Handle(GEOM_Object)& theShape,
4161 const Standard_Integer theShapeType,
4162 const Handle(GEOM_Object)& theTopLeftPoint,
4163 const Handle(GEOM_Object)& theTopRigthPoint,
4164 const Handle(GEOM_Object)& theBottomLeftPoint,
4165 const Handle(GEOM_Object)& theBottomRigthPoint,
4166 const GEOMAlgo_State theState)
4169 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
4170 getShapesOnQuadrangleIDs( theShape,
4175 theBottomRigthPoint,
4177 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->IsEmpty() )
4180 // Make a Python command
4182 // The GetShapesOnCylinder() doesn't change object so no new function is required.
4183 Handle(GEOM_Object) lastObj = GEOM::GetCreatedLast(theShape,theTopLeftPoint);
4184 lastObj = GEOM::GetCreatedLast(lastObj,theTopRigthPoint);
4185 lastObj = GEOM::GetCreatedLast(lastObj,theBottomRigthPoint);
4186 lastObj = GEOM::GetCreatedLast(lastObj,theBottomLeftPoint);
4187 Handle(GEOM_Function) aFunction = lastObj->GetLastFunction();
4189 GEOM::TPythonDump(aFunction, /*append=*/true)
4190 << "listShapesOnQuadrangle = geompy.GetShapesOnQuadrangleIDs("
4192 << TopAbs_ShapeEnum(theShapeType) << ", "
4193 << theTopLeftPoint << ", "
4194 << theTopRigthPoint << ", "
4195 << theBottomLeftPoint << ", "
4196 << theBottomRigthPoint << ", "
4203 //=============================================================================
4208 //=============================================================================
4209 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlace (Handle(GEOM_Object) theShapeWhere,
4210 Handle(GEOM_Object) theShapeWhat)
4214 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
4216 TopoDS_Shape aWhere = theShapeWhere->GetValue();
4217 TopoDS_Shape aWhat = theShapeWhat->GetValue();
4219 if (aWhere.IsNull() || aWhat.IsNull()) {
4220 SetErrorCode("Error: aWhere and aWhat TopoDS_Shape are Null.");
4224 // Searching for the sub-shapes inside the ShapeWhere shape
4225 GEOMAlgo_GetInPlace aGIP;
4227 if (!GEOMAlgo_GetInPlaceAPI::GetInPlace(aWhere, aWhat, aGIP)) {
4228 SetErrorCode("Error in GEOMAlgo_GetInPlace");
4232 // Add direct result.
4233 TopTools_ListOfShape aLSA;
4234 const TopoDS_Shape &aShapeResult = aGIP.Result();
4235 TopTools_MapOfShape aMFence;
4236 TopTools_IndexedMapOfShape aWhereIndices;
4237 Standard_Integer aShapeType = -1;
4239 TopExp::MapShapes(aWhere, aWhereIndices);
4241 if (aShapeResult.IsNull() == Standard_False) {
4242 TopoDS_Iterator anIt(aShapeResult);
4243 Standard_Boolean isFirst = Standard_True;
4245 for (; anIt.More(); anIt.Next()) {
4246 const TopoDS_Shape &aPart = anIt.Value();
4248 if(aWhereIndices.Contains(aPart) && aMFence.Add(aPart)) {
4249 const TopAbs_ShapeEnum aType = aPart.ShapeType();
4251 if (aShapeType == -1) {
4254 } else if (aShapeType != TopAbs_SHAPE && aShapeType != aType) {
4256 aShapeType = TopAbs_SHAPE;
4264 if (aLSA.Extent() == 0) {
4265 SetErrorCode(NOT_FOUND_ANY); // Not found any Results
4269 Handle(TColStd_HArray1OfInteger) aModifiedArray = new TColStd_HArray1OfInteger (1, aLSA.Extent());
4270 TopTools_ListIteratorOfListOfShape anIterModif (aLSA);
4271 for (Standard_Integer imod = 1; anIterModif.More(); anIterModif.Next(), imod++) {
4272 aModifiedArray->SetValue(imod, aWhereIndices.FindIndex(anIterModif.Value()));
4276 Handle(GEOM_Object) aResult = GetEngine()->AddSubShape(theShapeWhere, aModifiedArray);
4277 if (aResult.IsNull()) {
4278 SetErrorCode("Error in algorithm: result found, but cannot be returned.");
4282 const Standard_Boolean isSameType = (aShapeType != TopAbs_SHAPE);
4284 if ((aModifiedArray->Length() > 1 && isSameType) ||
4285 theShapeWhat->GetType() == GEOM_GROUP) {
4287 aResult->SetType(GEOM_GROUP);
4289 //Set a sub-shape type
4290 TopoDS_Shape aFirstFound = aLSA.First();
4291 TopAbs_ShapeEnum aShapeType = aFirstFound.ShapeType();
4293 TDF_Label aFreeLabel = aResult->GetFreeLabel();
4294 TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aShapeType);
4297 //Make a Python command
4298 Handle(GEOM_Function) aFunction = aResult->GetFunction(1);
4300 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetInPlace("
4301 << theShapeWhere << ", " << theShapeWhat << ", True)";
4307 //=============================================================================
4309 * case GetInPlaceOld:
4312 //=============================================================================
4313 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlaceOld
4314 (Handle(GEOM_Object) theShapeWhere,
4315 Handle(GEOM_Object) theShapeWhat)
4319 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
4321 TopoDS_Shape aWhere = theShapeWhere->GetValue();
4322 TopoDS_Shape aWhat = theShapeWhat->GetValue();
4323 TopTools_ListOfShape aModifiedList;
4324 const Standard_Integer iErr =
4325 GEOMAlgo_GetInPlaceAPI::GetInPlaceOld(aWhere, aWhat, aModifiedList);
4330 SetErrorCode("Error: aWhere and aWhat TopoDS_Shape are Null.");
4334 ("Error: An attempt to extract a shape of not supported type.");
4337 SetErrorCode(NOT_FOUND_ANY);
4340 SetErrorCode("Shape driver failed");
4347 TopTools_IndexedMapOfShape aWhereIndices;
4348 TopExp::MapShapes(aWhere, aWhereIndices);
4350 Handle(TColStd_HArray1OfInteger) aModifiedArray =
4351 new TColStd_HArray1OfInteger (1, aModifiedList.Extent());
4352 TopTools_ListIteratorOfListOfShape anIterModif (aModifiedList);
4353 Standard_Integer imod;
4354 Standard_Integer aShapeType = -1;
4356 for (imod = 1; anIterModif.More(); anIterModif.Next(), imod++) {
4357 const Standard_Integer anIndex =
4358 aWhereIndices.FindIndex(anIterModif.Value());
4359 const TopAbs_ShapeEnum aType = anIterModif.Value().ShapeType();
4361 if (aShapeType == -1) {
4364 } else if (aShapeType != TopAbs_SHAPE && aShapeType != aType) {
4366 aShapeType = TopAbs_SHAPE;
4369 aModifiedArray->SetValue(imod, anIndex);
4373 Handle(GEOM_Object) aResult =
4374 GetEngine()->AddSubShape(theShapeWhere, aModifiedArray);
4376 if (aResult.IsNull()) {
4377 SetErrorCode("Error in algorithm: result found, but cannot be returned.");
4381 const Standard_Boolean isSameType = (aShapeType != TopAbs_SHAPE);
4383 if ((aModifiedArray->Length() > 1 && isSameType) ||
4384 theShapeWhat->GetType() == GEOM_GROUP) {
4386 aResult->SetType(GEOM_GROUP);
4388 //Set a sub-shape type
4389 TopoDS_Shape aFirstFound = aWhereIndices.FindKey(aModifiedArray->Value(1));
4390 TopAbs_ShapeEnum aShapeType = aFirstFound.ShapeType();
4392 TDF_Label aFreeLabel = aResult->GetFreeLabel();
4393 TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aShapeType);
4396 //Make a Python command
4397 Handle(GEOM_Function) aFunction = aResult->GetFunction(1);
4399 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetInPlace("
4400 << theShapeWhere << ", " << theShapeWhat << ", False)";
4407 //=======================================================================
4408 //function : GetInPlaceByHistory
4410 //=======================================================================
4411 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlaceByHistory
4412 (Handle(GEOM_Object) theShapeWhere,
4413 Handle(GEOM_Object) theShapeWhat)
4417 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
4419 TopoDS_Shape aWhere = theShapeWhere->GetValue();
4420 TopoDS_Shape aWhat = theShapeWhat->GetValue();
4422 if (aWhere.IsNull() || aWhat.IsNull()) return NULL;
4424 Handle(GEOM_Function) aWhereFunction = theShapeWhere->GetLastFunction();
4425 if (aWhereFunction.IsNull()) return NULL;
4427 //Fill array of indices
4428 TopTools_IndexedMapOfShape aWhereIndices;
4430 TopExp::MapShapes(aWhere, aWhereIndices);
4433 TopTools_ListOfShape aModifiedList;
4434 bool isFound = GEOMAlgo_GetInPlaceAPI::GetInPlaceByHistory
4435 (aWhereFunction, aWhereIndices, aWhat, aModifiedList);
4437 if (!isFound || aModifiedList.Extent() < 1) {
4438 SetErrorCode("Error: No history found for the sought shape or its sub-shapes.");
4442 Handle(TColStd_HArray1OfInteger) aModifiedArray =
4443 new TColStd_HArray1OfInteger (1, aModifiedList.Extent());
4444 TopTools_ListIteratorOfListOfShape anIterModif (aModifiedList);
4445 Standard_Integer imod;
4446 Standard_Integer aShapeType = -1;
4448 for (imod = 1; anIterModif.More(); anIterModif.Next(), imod++) {
4449 const Standard_Integer anIndex =
4450 aWhereIndices.FindIndex(anIterModif.Value());
4451 const TopAbs_ShapeEnum aType = anIterModif.Value().ShapeType();
4453 if (aShapeType == -1) {
4456 } else if (aShapeType != TopAbs_SHAPE && aShapeType != aType) {
4458 aShapeType = TopAbs_SHAPE;
4461 aModifiedArray->SetValue(imod, anIndex);
4465 Handle(GEOM_Object) aResult = GetEngine()->AddSubShape(theShapeWhere, aModifiedArray);
4466 if (aResult.IsNull()) {
4467 SetErrorCode("Error in algorithm: result found, but cannot be returned.");
4471 const Standard_Boolean isSameType = (aShapeType != TopAbs_SHAPE);
4473 if ((aModifiedArray->Length() > 1 && isSameType) ||
4474 theShapeWhat->GetType() == GEOM_GROUP) {
4476 aResult->SetType(GEOM_GROUP);
4478 //Set a sub-shape type
4479 TopoDS_Shape aFirstFound = aWhereIndices.FindKey(aModifiedArray->Value(1));
4480 TopAbs_ShapeEnum aShapeType = aFirstFound.ShapeType();
4482 TDF_Label aFreeLabel = aResult->GetFreeLabel();
4483 TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aShapeType);
4486 //Make a Python command
4487 Handle(GEOM_Function) aFunction = aResult->GetFunction(1);
4489 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetInPlaceByHistory("
4490 << theShapeWhere << ", " << theShapeWhat << ")";
4496 //=======================================================================
4497 //function : isSameEdge
4498 //purpose : Returns True if two edges coincide
4499 //=======================================================================
4500 static bool isSameEdge(const TopoDS_Edge& theEdge1, const TopoDS_Edge& theEdge2)
4502 TopoDS_Vertex V11, V12, V21, V22;
4503 TopExp::Vertices(theEdge1, V11, V12);
4504 TopExp::Vertices(theEdge2, V21, V22);
4505 gp_Pnt P11 = BRep_Tool::Pnt(V11);
4506 gp_Pnt P12 = BRep_Tool::Pnt(V12);
4507 gp_Pnt P21 = BRep_Tool::Pnt(V21);
4508 gp_Pnt P22 = BRep_Tool::Pnt(V22);
4509 bool coincide = false;
4511 //Check that ends of edges coincide
4512 if(P11.Distance(P21) <= MAX_TOLERANCE) {
4513 if(P12.Distance(P22) <= MAX_TOLERANCE) coincide = true;
4515 else if(P11.Distance(P22) <= MAX_TOLERANCE) {
4516 if(P12.Distance(P21) <= MAX_TOLERANCE) coincide = true;
4519 if(!coincide) return false;
4521 if (BRep_Tool::Degenerated(theEdge1))
4522 if (BRep_Tool::Degenerated(theEdge2)) return true;
4525 if (BRep_Tool::Degenerated(theEdge2)) return false;
4527 double U11, U12, U21, U22;
4528 Handle(Geom_Curve) C1 = BRep_Tool::Curve(theEdge1, U11, U12);
4529 Handle(Geom_Curve) C2 = BRep_Tool::Curve(theEdge2, U21, U22);
4531 //Check that both edges has the same geometry
4532 double range = U12-U11;
4533 double U = U11+ range/3.0;
4534 gp_Pnt P1 = C1->Value(U); //Compute a point on one third of the edge's length
4535 U = U11+range*2.0/3.0;
4536 gp_Pnt P2 = C1->Value(U); //Compute a point on two thirds of the edge's length
4538 if(!GeomLib_Tool::Parameter(C2, P1, MAX_TOLERANCE, U) || U < U21 || U > U22)
4541 if(P1.Distance(C2->Value(U)) > MAX_TOLERANCE) return false;
4543 if(!GeomLib_Tool::Parameter(C2, P2, MAX_TOLERANCE, U) || U < U21 || U > U22)
4546 if(P2.Distance(C2->Value(U)) > MAX_TOLERANCE) return false;
4551 #include <TopoDS_TShape.hxx>
4552 //=======================================================================
4553 //function : isSameFace
4554 //purpose : Returns True if two faces coincide
4555 //=======================================================================
4556 static bool isSameFace(const TopoDS_Face& theFace1, const TopoDS_Face& theFace2)
4558 TopExp_Explorer E(theFace1, TopAbs_EDGE);
4559 TopTools_ListOfShape LS1, LS2;
4560 for(; E.More(); E.Next()) LS1.Append(E.Current());
4562 E.Init(theFace2, TopAbs_EDGE);
4563 for(; E.More(); E.Next()) LS2.Append(E.Current());
4565 //Compare the number of edges in the faces
4566 if(LS1.Extent() != LS2.Extent()) return false;
4568 double aMin = RealFirst(), aMax = RealLast();
4569 double xminB1=aMax, yminB1=aMax, zminB1=aMax, xminB2=aMax, yminB2=aMax, zminB2=aMax;
4570 double xmaxB1=aMin, ymaxB1=aMin, zmaxB1=aMin, xmaxB2=aMin, ymaxB2=aMin, zmaxB2=aMin;
4572 for(E.Init(theFace1, TopAbs_VERTEX); E.More(); E.Next()) {
4573 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4574 if(P.X() < xminB1) xminB1 = P.X();
4575 if(P.Y() < yminB1) yminB1 = P.Y();
4576 if(P.Z() < zminB1) zminB1 = P.Z();
4577 if(P.X() > xmaxB1) xmaxB1 = P.X();
4578 if(P.Y() > ymaxB1) ymaxB1 = P.Y();
4579 if(P.Z() > zmaxB1) zmaxB1 = P.Z();
4582 for(E.Init(theFace2, TopAbs_VERTEX); E.More(); E.Next()) {
4583 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4584 if(P.X() < xminB2) xminB2 = P.X();
4585 if(P.Y() < yminB2) yminB2 = P.Y();
4586 if(P.Z() < zminB2) zminB2 = P.Z();
4587 if(P.X() > xmaxB2) xmaxB2 = P.X();
4588 if(P.Y() > ymaxB2) ymaxB2 = P.Y();
4589 if(P.Z() > zmaxB2) zmaxB2 = P.Z();
4592 //Compare the bounding boxes of both faces
4593 if(gp_Pnt(xminB1, yminB1, zminB1).Distance(gp_Pnt(xminB2, yminB2, zminB2)) > MAX_TOLERANCE)
4596 if(gp_Pnt(xmaxB1, ymaxB1, zmaxB1).Distance(gp_Pnt(xmaxB2, ymaxB2, zmaxB2)) > MAX_TOLERANCE)
4599 Handle(Geom_Surface) S1 = BRep_Tool::Surface(theFace1);
4600 Handle(Geom_Surface) S2 = BRep_Tool::Surface(theFace2);
4602 //Check if there a coincidence of two surfaces at least in two points
4603 double U11, U12, V11, V12, U21, U22, V21, V22;
4604 BRepTools::UVBounds(theFace1, U11, U12, V11, V12);
4605 BRepTools::UVBounds(theFace2, U21, U22, V21, V22);
4607 double rangeU = U12-U11;
4608 double rangeV = V12-V11;
4609 double U = U11 + rangeU/3.0;
4610 double V = V11 + rangeV/3.0;
4611 gp_Pnt P1 = S1->Value(U, V);
4612 U = U11+rangeU*2.0/3.0;
4613 V = V11+rangeV*2.0/3.0;
4614 gp_Pnt P2 = S1->Value(U, V);
4616 if (!GeomLib_Tool::Parameters(S2, P1, MAX_TOLERANCE, U, V) || U < U21 || U > U22 || V < V21 || V > V22)
4619 if (P1.Distance(S2->Value(U,V)) > MAX_TOLERANCE) return false;
4621 if (!GeomLib_Tool::Parameters(S2, P2, MAX_TOLERANCE, U, V) || U < U21 || U > U22 || V < V21 || V > V22)
4624 if (P2.Distance(S2->Value(U, V)) > MAX_TOLERANCE) return false;
4626 //Check that each edge of the Face1 has a counterpart in the Face2
4627 TopTools_MapOfOrientedShape aMap;
4628 TopTools_ListIteratorOfListOfShape LSI1(LS1);
4629 for(; LSI1.More(); LSI1.Next()) {
4630 TopoDS_Edge E = TopoDS::Edge(LSI1.Value());
4631 bool isFound = false;
4632 TopTools_ListIteratorOfListOfShape LSI2(LS2);
4633 for(; LSI2.More(); LSI2.Next()) {
4634 TopoDS_Shape aValue = LSI2.Value();
4635 if(aMap.Contains(aValue)) continue; //To avoid checking already found edge several times
4636 if(isSameEdge(E, TopoDS::Edge(aValue))) {
4642 if(!isFound) return false;
4648 //=======================================================================
4649 //function : isSameSolid
4650 //purpose : Returns True if two solids coincide
4651 //=======================================================================
4652 bool isSameSolid(const TopoDS_Solid& theSolid1, const TopoDS_Solid& theSolid2)
4654 TopExp_Explorer E(theSolid1, TopAbs_FACE);
4655 TopTools_ListOfShape LS1, LS2;
4656 for(; E.More(); E.Next()) LS1.Append(E.Current());
4657 E.Init(theSolid2, TopAbs_FACE);
4658 for(; E.More(); E.Next()) LS2.Append(E.Current());
4660 if(LS1.Extent() != LS2.Extent()) return false;
4662 double aMin = RealFirst(), aMax = RealLast();
4663 double xminB1=aMax, yminB1=aMax, zminB1=aMax, xminB2=aMax, yminB2=aMax, zminB2=aMax;
4664 double xmaxB1=aMin, ymaxB1=aMin, zmaxB1=aMin, xmaxB2=aMin, ymaxB2=aMin, zmaxB2=aMin;
4666 for(E.Init(theSolid1, TopAbs_VERTEX); E.More(); E.Next()) {
4667 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4668 if(P.X() < xminB1) xminB1 = P.X();
4669 if(P.Y() < yminB1) yminB1 = P.Y();
4670 if(P.Z() < zminB1) zminB1 = P.Z();
4671 if(P.X() > xmaxB1) xmaxB1 = P.X();
4672 if(P.Y() > ymaxB1) ymaxB1 = P.Y();
4673 if(P.Z() > zmaxB1) zmaxB1 = P.Z();
4676 for(E.Init(theSolid2, TopAbs_VERTEX); E.More(); E.Next()) {
4677 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4678 if(P.X() < xminB2) xminB2 = P.X();
4679 if(P.Y() < yminB2) yminB2 = P.Y();
4680 if(P.Z() < zminB2) zminB2 = P.Z();
4681 if(P.X() > xmaxB2) xmaxB2 = P.X();
4682 if(P.Y() > ymaxB2) ymaxB2 = P.Y();
4683 if(P.Z() > zmaxB2) zmaxB2 = P.Z();
4686 //Compare the bounding boxes of both solids
4687 if(gp_Pnt(xminB1, yminB1, zminB1).Distance(gp_Pnt(xminB2, yminB2, zminB2)) > MAX_TOLERANCE)
4690 if(gp_Pnt(xmaxB1, ymaxB1, zmaxB1).Distance(gp_Pnt(xmaxB2, ymaxB2, zmaxB2)) > MAX_TOLERANCE)
4693 //Check that each face of the Solid1 has a counterpart in the Solid2
4694 TopTools_MapOfOrientedShape aMap;
4695 TopTools_ListIteratorOfListOfShape LSI1(LS1);
4696 for(; LSI1.More(); LSI1.Next()) {
4697 TopoDS_Face F = TopoDS::Face(LSI1.Value());
4698 bool isFound = false;
4699 TopTools_ListIteratorOfListOfShape LSI2(LS2);
4700 for(; LSI2.More(); LSI2.Next()) {
4701 if(aMap.Contains(LSI2.Value())) continue; //To avoid checking already found faces several times
4702 if(isSameFace(F, TopoDS::Face(LSI2.Value()))) {
4703 aMap.Add(LSI2.Value());
4708 if(!isFound) return false;
4714 //=======================================================================
4715 //function : GetSame
4717 //=======================================================================
4718 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetSame(const Handle(GEOM_Object)& theShapeWhere,
4719 const Handle(GEOM_Object)& theShapeWhat)
4722 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
4724 TopoDS_Shape aWhere = theShapeWhere->GetValue();
4725 TopoDS_Shape aWhat = theShapeWhat->GetValue();
4727 if (aWhere.IsNull() || aWhat.IsNull()) return NULL;
4730 bool isFound = false;
4731 TopoDS_Shape aSubShape;
4732 TopTools_MapOfShape aMap;
4734 if (aWhat.ShapeType() == TopAbs_COMPOUND || aWhat.ShapeType() == TopAbs_COMPSOLID) {
4735 TopoDS_Iterator It (aWhat, Standard_True, Standard_True);
4736 if (It.More()) aWhat = It.Value();
4739 SetErrorCode("Compounds of two or more shapes are not allowed for aWhat argument");
4744 switch (aWhat.ShapeType()) {
4745 case TopAbs_VERTEX: {
4746 aSubShape = getSameVertex(aWhere, TopoDS::Vertex(aWhat));
4747 isFound = !aSubShape.IsNull();
4751 TopoDS_Edge anEdge = TopoDS::Edge(aWhat);
4752 TopExp_Explorer E(aWhere, TopAbs_EDGE);
4753 for(; E.More(); E.Next()) {
4754 if(!aMap.Add(E.Current())) continue;
4755 if(isSameEdge(anEdge, TopoDS::Edge(E.Current()))) {
4756 aSubShape = E.Current();
4764 TopoDS_Face aFace = TopoDS::Face(aWhat);
4765 TopExp_Explorer E(aWhere, TopAbs_FACE);
4766 for(; E.More(); E.Next()) {
4767 if(!aMap.Add(E.Current())) continue;
4768 if(isSameFace(aFace, TopoDS::Face(E.Current()))) {
4769 aSubShape = E.Current();
4776 case TopAbs_SOLID: {
4777 TopoDS_Solid aSolid = TopoDS::Solid(aWhat);
4778 TopExp_Explorer E(aWhere, TopAbs_SOLID);
4779 for(; E.More(); E.Next()) {
4780 if(!aMap.Add(E.Current())) continue;
4781 if(isSameSolid(aSolid, TopoDS::Solid(E.Current()))) {
4782 aSubShape = E.Current();
4794 TopTools_IndexedMapOfShape anIndices;
4795 TopExp::MapShapes(aWhere, anIndices);
4796 if (anIndices.Contains(aSubShape))
4797 anIndex = anIndices.FindIndex(aSubShape);
4800 if (anIndex < 0) return NULL;
4802 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
4804 anArray->SetValue(1, anIndex);
4806 Handle(GEOM_Object) aResult = GetEngine()->AddSubShape(theShapeWhere, anArray);
4807 Handle(GEOM_Function) aFunction = aResult->GetLastFunction();
4809 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetSame("
4810 << theShapeWhere << ", " << theShapeWhat << ")";
4818 //=======================================================================
4819 //function : GetSameIDs
4821 //=======================================================================
4822 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetSameIDs
4823 (const Handle(GEOM_Object)& theShapeWhere,
4824 const Handle(GEOM_Object)& theShapeWhat)
4827 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
4829 TopoDS_Shape aWhere = theShapeWhere->GetValue();
4830 TopoDS_Shape aWhat = theShapeWhat->GetValue();
4832 if (aWhere.IsNull() || aWhat.IsNull()) return NULL;
4834 TopTools_ListOfShape listShape;
4835 TopTools_MapOfShape aMap;
4837 if (aWhat.ShapeType() == TopAbs_COMPOUND || aWhat.ShapeType() == TopAbs_COMPSOLID) {
4838 TopoDS_Iterator It (aWhat, Standard_True, Standard_True);
4839 if (It.More()) aWhat = It.Value();
4842 SetErrorCode("Compounds of two or more shapes are not allowed for aWhat argument");
4847 switch (aWhat.ShapeType()) {
4848 case TopAbs_VERTEX: {
4849 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(aWhat));
4850 TopExp_Explorer E(aWhere, TopAbs_VERTEX);
4851 for(; E.More(); E.Next()) {
4852 if(!aMap.Add(E.Current())) continue;
4853 gp_Pnt P2 = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4854 if(P.Distance(P2) <= MAX_TOLERANCE) {
4855 listShape.Append(E.Current());
4861 TopoDS_Edge anEdge = TopoDS::Edge(aWhat);
4862 TopExp_Explorer E(aWhere, TopAbs_EDGE);
4863 for(; E.More(); E.Next()) {
4864 if(!aMap.Add(E.Current())) continue;
4865 if(isSameEdge(anEdge, TopoDS::Edge(E.Current()))) {
4866 listShape.Append(E.Current());
4872 TopoDS_Face aFace = TopoDS::Face(aWhat);
4873 TopExp_Explorer E(aWhere, TopAbs_FACE);
4874 for(; E.More(); E.Next()) {
4875 if(!aMap.Add(E.Current())) continue;
4876 if(isSameFace(aFace, TopoDS::Face(E.Current()))) {
4877 listShape.Append(E.Current());
4882 case TopAbs_SOLID: {
4883 TopoDS_Solid aSolid = TopoDS::Solid(aWhat);
4884 TopExp_Explorer E(aWhere, TopAbs_SOLID);
4885 for(; E.More(); E.Next()) {
4886 if(!aMap.Add(E.Current())) continue;
4887 if(isSameSolid(aSolid, TopoDS::Solid(E.Current()))) {
4888 listShape.Append(E.Current());
4897 if ( !listShape.IsEmpty() ) {
4898 TopTools_IndexedMapOfShape anIndices;
4899 TopExp::MapShapes(aWhere, anIndices);
4900 TopTools_ListIteratorOfListOfShape itSub (listShape);
4901 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
4902 for (; itSub.More(); itSub.Next()) {
4903 if (anIndices.Contains(itSub.Value()))
4904 aSeq->Append(anIndices.FindIndex(itSub.Value()));
4907 // The GetSameIDs() doesn't change object so no new function is required.
4908 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShapeWhere,theShapeWhat)->GetLastFunction();
4910 // Make a Python command
4911 GEOM::TPythonDump(aFunction, /*append=*/true)
4912 << "listSameIDs = geompy.GetSameIDs("
4913 << theShapeWhere << ", "
4914 << theShapeWhat << ")";
4917 SetErrorCode(NOT_FOUND_ANY);
4922 //=======================================================================
4923 //function : ExtendEdge
4925 //=======================================================================
4926 Handle(GEOM_Object) GEOMImpl_IShapesOperations::ExtendEdge
4927 (const Handle(GEOM_Object) &theEdge,
4928 const Standard_Real theMin,
4929 const Standard_Real theMax)
4933 if (theEdge.IsNull()) {
4937 //Add a new Edge object
4938 Handle(GEOM_Object) aResEdge = GetEngine()->AddObject(GetDocID(), GEOM_EDGE);
4940 //Add a new Vector function
4941 Handle(GEOM_Function) aFunction =
4942 aResEdge->AddFunction(GEOMImpl_ShapeDriver::GetID(), EDGE_UV);
4944 //Check if the function is set correctly
4945 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) {
4949 GEOMImpl_IShapeExtend aCI (aFunction);
4951 Handle(GEOM_Function) anEdge = theEdge->GetLastFunction();
4953 if (anEdge.IsNull()) {
4957 aCI.SetShape(anEdge);
4958 aCI.SetUMin(theMin);
4959 aCI.SetUMax(theMax);
4961 //Compute the Edge value
4964 if (!GetSolver()->ComputeFunction(aFunction)) {
4965 SetErrorCode("Shape driver failed");
4970 catch (Standard_Failure) {
4971 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
4972 SetErrorCode(aFail->GetMessageString());
4977 //Make a Python command
4978 GEOM::TPythonDump(aFunction)
4979 << aResEdge << " = geompy.ExtendEdge("
4980 << theEdge << ", " << theMin << ", " << theMax << ")";
4987 //=======================================================================
4988 //function : ExtendFace
4990 //=======================================================================
4991 Handle(GEOM_Object) GEOMImpl_IShapesOperations::ExtendFace
4992 (const Handle(GEOM_Object) &theFace,
4993 const Standard_Real theUMin,
4994 const Standard_Real theUMax,
4995 const Standard_Real theVMin,
4996 const Standard_Real theVMax)
5000 if (theFace.IsNull()) {
5004 //Add a new Face object
5005 Handle(GEOM_Object) aResFace = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
5007 //Add a new Vector function
5008 Handle(GEOM_Function) aFunction =
5009 aResFace->AddFunction(GEOMImpl_ShapeDriver::GetID(), FACE_UV);
5011 //Check if the function is set correctly
5012 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) {
5016 GEOMImpl_IShapeExtend aCI (aFunction);
5018 Handle(GEOM_Function) aFace = theFace->GetLastFunction();
5020 if (aFace.IsNull()) {
5024 aCI.SetShape(aFace);
5025 aCI.SetUMin(theUMin);
5026 aCI.SetUMax(theUMax);
5027 aCI.SetVMin(theVMin);
5028 aCI.SetVMax(theVMax);
5030 //Compute the Face value
5033 if (!GetSolver()->ComputeFunction(aFunction)) {
5034 SetErrorCode("Shape driver failed");
5039 catch (Standard_Failure) {
5040 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
5041 SetErrorCode(aFail->GetMessageString());
5046 //Make a Python command
5047 GEOM::TPythonDump(aFunction)
5048 << aResFace << " = geompy.ExtendFace("
5049 << theFace << ", " << theUMin << ", " << theUMax << ", "
5050 << theVMin << ", " << theVMax << ")";
5057 //=======================================================================
5058 //function : MakeSurfaceFromFace
5060 //=======================================================================
5061 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeSurfaceFromFace
5062 (const Handle(GEOM_Object) &theFace)
5066 if (theFace.IsNull()) {
5070 //Add a new Face object
5071 Handle(GEOM_Object) aResFace = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
5073 //Add a new Vector function
5074 Handle(GEOM_Function) aFunction =
5075 aResFace->AddFunction(GEOMImpl_ShapeDriver::GetID(), SURFACE_FROM_FACE);
5077 //Check if the function is set correctly
5078 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) {
5082 GEOMImpl_IShapeExtend aCI (aFunction);
5084 Handle(GEOM_Function) aFace = theFace->GetLastFunction();
5086 if (aFace.IsNull()) {
5090 aCI.SetShape(aFace);
5092 //Compute the Face value
5095 if (!GetSolver()->ComputeFunction(aFunction)) {
5096 SetErrorCode("Shape driver failed");
5101 catch (Standard_Failure) {
5102 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
5103 SetErrorCode(aFail->GetMessageString());
5108 //Make a Python command
5109 GEOM::TPythonDump(aFunction)
5110 << aResFace << " = geompy.MakeSurfaceFromFace("