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_IExtract.hxx"
40 #include "GEOMImpl_IVector.hxx"
41 #include "GEOMImpl_IShapes.hxx"
42 #include "GEOMImpl_IShapeExtend.hxx"
43 #include "GEOMImpl_IGlue.hxx"
44 #include "GEOMImpl_IFilling.hxx"
46 #include "GEOMImpl_Block6Explorer.hxx"
47 #include "GEOMImpl_IHealingOperations.hxx"
49 #include "GEOMImpl_Gen.hxx"
51 #include "GEOM_Function.hxx"
52 #include "GEOM_ISubShape.hxx"
53 #include "GEOM_PythonDump.hxx"
55 #include "GEOMUtils.hxx"
57 #include "GEOMAlgo_ClsfBox.hxx"
58 #include "GEOMAlgo_ClsfQuad.hxx"
59 #include "GEOMAlgo_ClsfSolid.hxx"
60 #include "GEOMAlgo_ClsfSurf.hxx"
61 #include "GEOMAlgo_FinderShapeOn2.hxx"
62 #include "GEOMAlgo_GetInPlace.hxx"
63 #include "GEOMAlgo_GetInPlaceAPI.hxx"
64 #include "GEOMAlgo_GlueDetector.hxx"
66 #include <utilities.h>
68 #include <BRepAdaptor_Curve.hxx>
69 #include <BRepAdaptor_Surface.hxx>
70 #include <BRepTools.hxx>
71 #include <BRep_Builder.hxx>
72 #include <BRep_Tool.hxx>
73 #include <GeomLib_Tool.hxx>
74 #include <Geom_CylindricalSurface.hxx>
75 #include <Geom_Plane.hxx>
76 #include <Geom_SphericalSurface.hxx>
77 #include <Geom_Surface.hxx>
78 #include <Geom_TrimmedCurve.hxx>
79 #include <Precision.hxx>
80 #include <TColStd_HArray1OfInteger.hxx>
81 #include <TDF_Tool.hxx>
82 #include <TDataStd_Integer.hxx>
83 #include <TDataStd_ListIteratorOfListOfExtendedString.hxx>
85 #include <TopExp_Explorer.hxx>
86 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
87 #include <TopTools_IndexedMapOfShape.hxx>
88 #include <TopTools_ListIteratorOfListOfShape.hxx>
89 #include <TopTools_MapOfOrientedShape.hxx>
90 #include <TopTools_MapOfShape.hxx>
91 #include <TopTools_SequenceOfShape.hxx>
93 #include <TopoDS_Compound.hxx>
94 #include <TopoDS_Edge.hxx>
95 #include <TopoDS_Face.hxx>
96 #include <TopoDS_Iterator.hxx>
97 #include <TopoDS_Shape.hxx>
98 #include <TopoDS_Solid.hxx>
99 #include <TopoDS_Vertex.hxx>
100 #include <gp_Cylinder.hxx>
101 #include <gp_Pnt.hxx>
105 #include <Standard_Failure.hxx>
106 #include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
110 void AddFlatSubShapes(const TopoDS_Shape& S, TopTools_ListOfShape& L, TopTools_MapOfShape& M)
112 if (S.ShapeType() != TopAbs_COMPOUND) {
116 TopoDS_Iterator It(S, Standard_True, Standard_True);
117 for (; It.More(); It.Next()) {
118 TopoDS_Shape SS = It.Value();
120 AddFlatSubShapes(SS, L, M);
128 const double MAX_TOLERANCE = 1.e-7;
131 * \brief Returns the vertex from theWhere shape that is coincident with
134 * \param theWhere the shape where the coinsident vertex is searched.
135 * \param theVertex the vertex to be searched.
136 * \return the coincident vertex if it is found. Otherwise null object.
138 static TopoDS_Vertex getSameVertex(const TopoDS_Shape &theWhere,
139 const TopoDS_Vertex &theVertex)
141 TopoDS_Vertex aResult;
142 gp_Pnt aPoint = BRep_Tool::Pnt(theVertex);
143 TopExp_Explorer anExp(theWhere, TopAbs_VERTEX);
144 TopTools_MapOfShape aMap;
146 for(; anExp.More(); anExp.Next()) {
147 const TopoDS_Shape &aLocalShape = anExp.Current();
149 if(!aMap.Add(aLocalShape)) {
153 TopoDS_Vertex aVertex = TopoDS::Vertex(aLocalShape);
154 gp_Pnt aPoint2 = BRep_Tool::Pnt(aVertex);
156 if(aPoint.Distance(aPoint2) <= MAX_TOLERANCE) {
164 } // end of namespace
166 //=============================================================================
170 //=============================================================================
171 GEOMImpl_IShapesOperations::GEOMImpl_IShapesOperations (GEOM_Engine* theEngine, int theDocID)
172 : GEOM_IOperations(theEngine, theDocID)
174 MESSAGE("GEOMImpl_IShapesOperations::GEOMImpl_IShapesOperations");
177 //=============================================================================
181 //=============================================================================
182 GEOMImpl_IShapesOperations::~GEOMImpl_IShapesOperations()
184 MESSAGE("GEOMImpl_IShapesOperations::~GEOMImpl_IShapesOperations");
187 //=============================================================================
191 //=============================================================================
192 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeEdge
193 (Handle(GEOM_Object) thePnt1, Handle(GEOM_Object) thePnt2)
197 if (thePnt1.IsNull() || thePnt2.IsNull()) return NULL;
199 //Add a new Edge object
200 Handle(GEOM_Object) anEdge = GetEngine()->AddObject(GetDocID(), GEOM_EDGE);
202 //Add a new Vector function
203 Handle(GEOM_Function) aFunction =
204 anEdge->AddFunction(GEOMImpl_VectorDriver::GetID(), VECTOR_TWO_PNT);
206 //Check if the function is set correctly
207 if (aFunction->GetDriverGUID() != GEOMImpl_VectorDriver::GetID()) return NULL;
209 GEOMImpl_IVector aPI (aFunction);
211 Handle(GEOM_Function) aRef1 = thePnt1->GetLastFunction();
212 Handle(GEOM_Function) aRef2 = thePnt2->GetLastFunction();
213 if (aRef1.IsNull() || aRef2.IsNull()) return NULL;
215 aPI.SetPoint1(aRef1);
216 aPI.SetPoint2(aRef2);
218 //Compute the Edge value
221 if (!GetSolver()->ComputeFunction(aFunction)) {
222 SetErrorCode("Vector driver failed");
226 catch (Standard_Failure) {
227 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
228 SetErrorCode(aFail->GetMessageString());
232 //Make a Python command
233 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdge("
234 << thePnt1 << ", " << thePnt2 << ")";
240 //=============================================================================
242 * MakeEdgeOnCurveByLength
244 //=============================================================================
245 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeEdgeOnCurveByLength
246 (Handle(GEOM_Object) theRefCurve,
247 const Standard_Real theLength,
248 Handle(GEOM_Object) theStartPoint)
252 if (theRefCurve.IsNull()) return NULL;
254 //Add a new Edge object
255 Handle(GEOM_Object) anEdge = GetEngine()->AddObject(GetDocID(), GEOM_EDGE);
257 //Add a new Vector function
258 Handle(GEOM_Function) aFunction =
259 anEdge->AddFunction(GEOMImpl_ShapeDriver::GetID(), EDGE_CURVE_LENGTH);
261 //Check if the function is set correctly
262 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
264 GEOMImpl_IVector aPI (aFunction);
266 Handle(GEOM_Function) aRef1 = theRefCurve->GetLastFunction();
267 if (aRef1.IsNull()) return NULL;
268 aPI.SetPoint1(aRef1);
270 if (!theStartPoint.IsNull()) {
271 Handle(GEOM_Function) aRef2 = theStartPoint->GetLastFunction();
272 aPI.SetPoint2(aRef2);
275 aPI.SetParameter(theLength);
277 //Compute the Edge value
280 if (!GetSolver()->ComputeFunction(aFunction)) {
281 SetErrorCode("Vector driver failed");
285 catch (Standard_Failure) {
286 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
287 SetErrorCode(aFail->GetMessageString());
291 //Make a Python command
292 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdgeOnCurveByLength("
293 << theRefCurve << ", " << theLength << ", " << theStartPoint << ")";
299 //=============================================================================
303 //=============================================================================
304 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeEdgeWire
305 (Handle(GEOM_Object) theWire,
306 const Standard_Real theLinearTolerance,
307 const Standard_Real theAngularTolerance)
311 if (theWire.IsNull()) return NULL;
313 //Add a new Edge object
314 Handle(GEOM_Object) anEdge = GetEngine()->AddObject(GetDocID(), GEOM_EDGE);
316 //Add a new Vector function
317 Handle(GEOM_Function) aFunction =
318 anEdge->AddFunction(GEOMImpl_ShapeDriver::GetID(), EDGE_WIRE);
320 //Check if the function is set correctly
321 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
323 GEOMImpl_IShapes aCI (aFunction);
325 Handle(GEOM_Function) aWire = theWire->GetLastFunction();
327 if (aWire.IsNull()) return NULL;
330 aCI.SetTolerance(theLinearTolerance);
331 aCI.SetAngularTolerance(theAngularTolerance);
333 //Compute the Edge value
336 if (!GetSolver()->ComputeFunction(aFunction)) {
337 SetErrorCode("Shape driver failed");
341 catch (Standard_Failure) {
342 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
343 SetErrorCode(aFail->GetMessageString());
347 const double DEF_LIN_TOL = Precision::Confusion();
348 const double DEF_ANG_TOL = Precision::Angular();
349 //Make a Python command
350 if ( theAngularTolerance == DEF_ANG_TOL ) {
351 if ( theLinearTolerance == DEF_LIN_TOL )
352 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdgeWire("
355 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdgeWire("
356 << theWire << ", " << theLinearTolerance << ")";
359 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdgeWire("
360 << theWire << ", " << theLinearTolerance << ", "
361 << theAngularTolerance << ")";
368 //=============================================================================
372 //=============================================================================
373 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeWire
374 (std::list<Handle(GEOM_Object)> theShapes,
375 const Standard_Real theTolerance)
380 Handle(GEOM_Object) aWire = GetEngine()->AddObject(GetDocID(), GEOM_WIRE);
383 Handle(GEOM_Function) aFunction =
384 aWire->AddFunction(GEOMImpl_ShapeDriver::GetID(), WIRE_EDGES);
385 if (aFunction.IsNull()) return NULL;
387 //Check if the function is set correctly
388 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
390 GEOMImpl_IShapes aCI (aFunction);
391 aCI.SetTolerance(theTolerance);
393 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
396 std::list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
397 for (; it != theShapes.end(); it++) {
398 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
399 if (aRefSh.IsNull()) {
400 SetErrorCode("NULL argument shape for the shape construction");
403 aShapesSeq->Append(aRefSh);
405 aCI.SetShapes(aShapesSeq);
410 if (!GetSolver()->ComputeFunction(aFunction)) {
411 SetErrorCode("Shape driver failed");
415 catch (Standard_Failure) {
416 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
417 SetErrorCode(aFail->GetMessageString());
421 //Make a Python command
422 GEOM::TPythonDump pd (aFunction);
423 pd << aWire << " = geompy.MakeWire([";
426 it = theShapes.begin();
427 if (it != theShapes.end()) {
429 while (it != theShapes.end()) {
430 pd << ", " << (*it++);
433 pd << "], " << theTolerance << ")";
439 //=============================================================================
443 //=============================================================================
444 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFace (Handle(GEOM_Object) theWire,
445 const bool isPlanarWanted)
449 if (theWire.IsNull()) return NULL;
451 //Add a new Face object
452 Handle(GEOM_Object) aFace = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
454 //Add a new Shape function for creation of a face from a wire
455 Handle(GEOM_Function) aFunction =
456 aFace->AddFunction(GEOMImpl_ShapeDriver::GetID(), FACE_WIRE);
457 if (aFunction.IsNull()) return NULL;
459 //Check if the function is set correctly
460 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
462 GEOMImpl_IShapes aCI (aFunction);
464 Handle(GEOM_Function) aRefWire = theWire->GetLastFunction();
466 if (aRefWire.IsNull()) return NULL;
468 aCI.SetBase(aRefWire);
469 aCI.SetIsPlanar(isPlanarWanted);
471 //Compute the Face value
472 Standard_Boolean isWarning = Standard_False;
475 if (!GetSolver()->ComputeFunction(aFunction)) {
476 SetErrorCode("Shape driver failed to compute a face");
480 catch (Standard_Failure) {
481 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
482 SetErrorCode(aFail->GetMessageString());
483 // to provide warning
484 if (!aFunction->GetValue().IsNull()) {
485 isWarning = Standard_True;
491 //Make a Python command
492 GEOM::TPythonDump(aFunction) << aFace << " = geompy.MakeFace("
493 << theWire << ", " << (int)isPlanarWanted << ")";
495 // to provide warning
496 if (!isWarning) SetErrorCode(OK);
500 //=============================================================================
504 //=============================================================================
505 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFaceWires
506 (std::list<Handle(GEOM_Object)> theShapes,
507 const bool isPlanarWanted)
512 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
515 Handle(GEOM_Function) aFunction =
516 aShape->AddFunction(GEOMImpl_ShapeDriver::GetID(), FACE_WIRES);
517 if (aFunction.IsNull()) return NULL;
519 //Check if the function is set correctly
520 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
522 GEOMImpl_IShapes aCI (aFunction);
524 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
527 std::list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
528 for (; it != theShapes.end(); it++) {
529 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
530 if (aRefSh.IsNull()) {
531 SetErrorCode("NULL argument shape for the face construction");
534 aShapesSeq->Append(aRefSh);
536 aCI.SetShapes(aShapesSeq);
538 aCI.SetIsPlanar(isPlanarWanted);
541 Standard_Boolean isWarning = Standard_False;
544 if (!GetSolver()->ComputeFunction(aFunction)) {
545 SetErrorCode("Shape driver failed");
549 catch (Standard_Failure) {
550 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
551 SetErrorCode(aFail->GetMessageString());
552 // to provide warning
553 if (!aFunction->GetValue().IsNull()) {
554 isWarning = Standard_True;
560 //Make a Python command
561 GEOM::TPythonDump pd (aFunction);
562 pd << aShape << " = geompy.MakeFaceWires([";
565 it = theShapes.begin();
566 if (it != theShapes.end()) {
568 while (it != theShapes.end()) {
569 pd << ", " << (*it++);
572 pd << "], " << (int)isPlanarWanted << ")";
574 // to provide warning
575 if (!isWarning) SetErrorCode(OK);
579 //=============================================================================
581 * MakeFaceFromSurface
583 //=============================================================================
584 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFaceFromSurface
585 (Handle(GEOM_Object) theFace,
586 Handle(GEOM_Object) theWire)
591 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
594 Handle(GEOM_Function) aFunction =
595 aShape->AddFunction(GEOMImpl_ShapeDriver::GetID(), FACE_FROM_SURFACE);
597 if (aFunction.IsNull()) {
601 //Check if the function is set correctly
602 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) {
606 GEOMImpl_IShapes aCI (aFunction);
607 Handle(TColStd_HSequenceOfTransient) aShapesSeq =
608 new TColStd_HSequenceOfTransient;
609 Handle(GEOM_Function) aRefFace = theFace->GetLastFunction();
610 Handle(GEOM_Function) aRefWire = theWire->GetLastFunction();
612 if (aRefFace.IsNull()) {
613 SetErrorCode("NULL argument face for the face construction");
617 if (aRefWire.IsNull()) {
618 SetErrorCode("NULL argument wire for the face construction");
622 aShapesSeq->Append(aRefFace);
623 aShapesSeq->Append(aRefWire);
625 aCI.SetShapes(aShapesSeq);
630 if (!GetSolver()->ComputeFunction(aFunction)) {
631 SetErrorCode("Shape driver failed");
635 catch (Standard_Failure) {
636 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
637 SetErrorCode(aFail->GetMessageString());
641 //Make a Python command
642 GEOM::TPythonDump (aFunction) << aShape
643 << " = geompy.MakeFaceFromSurface(" << theFace << ", " << theWire << ")";
650 //=============================================================================
652 * MakeFaceWithConstraints
654 //=============================================================================
655 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFaceWithConstraints
656 (std::list<Handle(GEOM_Object)> theConstraints)
661 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_FILLING);
664 Handle(GEOM_Function) aFunction =
665 aShape->AddFunction(GEOMImpl_FillingDriver::GetID(), FILLING_ON_CONSTRAINTS);
666 if (aFunction.IsNull()) return NULL;
668 //Check if the function is set correctly
669 if (aFunction->GetDriverGUID() != GEOMImpl_FillingDriver::GetID()) return NULL;
671 GEOMImpl_IFilling aCI (aFunction);
672 Handle(TColStd_HSequenceOfTransient) aConstraints = new TColStd_HSequenceOfTransient;
675 std::list<Handle(GEOM_Object)>::iterator it = theConstraints.begin();
676 while (it != theConstraints.end()) {
677 Handle(GEOM_Object) anObject = (*it);
678 if ( anObject.IsNull() || anObject->GetValue().ShapeType() != TopAbs_EDGE ) {
679 SetErrorCode("NULL argument edge for the face construction");
682 Handle(GEOM_Function) aRefSh = anObject->GetLastFunction();
683 aConstraints->Append(aRefSh);
685 if ( it != theConstraints.end() ) {
686 Handle(GEOM_Object) aFace = (*it);
687 if ( aFace.IsNull() ) {
688 // null constraint face - it is a valid case
692 if ( aFace->GetValue().ShapeType() != TopAbs_FACE )
693 // constraint face can be omitted - it is a valid case
695 // Keep the old error code as IsSubShapeBelongsTo changes it.
696 TCollection_AsciiString anOldCode = GetErrorCode();
698 if ( IsSubShapeBelongsTo( anObject, 0, aFace, 0 ) ) {
700 SetErrorCode(anOldCode);
701 aRefSh = aFace->GetLastFunction();
702 aConstraints->Append(aRefSh);
707 SetErrorCode("Face is NULL or not connected to the Edge");
712 aCI.SetShapes( aConstraints );
715 Standard_Boolean isWarning = Standard_False;
718 if (!GetSolver()->ComputeFunction(aFunction)) {
719 SetErrorCode("Shape driver failed");
723 catch (Standard_Failure) {
724 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
725 SetErrorCode(aFail->GetMessageString());
726 // to provide warning
727 if (!aFunction->GetValue().IsNull()) {
728 isWarning = Standard_True;
734 //Make a Python command
735 GEOM::TPythonDump pd (aFunction);
736 pd << aShape << " = geompy.MakeFaceWithConstraints([";
739 it = theConstraints.begin();
740 if (it != theConstraints.end() ) {
742 while (it != theConstraints.end()) {
743 Handle(GEOM_Object) anObject = (*it++);
744 if( !anObject.IsNull() )
745 pd << ", " << anObject;
750 // to provide warning
751 if (!isWarning) SetErrorCode(OK);
755 //=============================================================================
759 //=============================================================================
760 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeShell
761 (std::list<Handle(GEOM_Object)> theShapes)
763 return MakeShape(theShapes, GEOM_SHELL, SHELL_FACES, "MakeShell");
766 //=============================================================================
770 //=============================================================================
771 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeSolidShells
772 (std::list<Handle(GEOM_Object)> theShapes)
774 return MakeShape(theShapes, GEOM_SOLID, SOLID_SHELLS, "MakeSolid");
777 //=============================================================================
781 //=============================================================================
782 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeCompound
783 (std::list<Handle(GEOM_Object)> theShapes)
785 return MakeShape(theShapes, GEOM_COMPOUND, COMPOUND_SHAPES, "MakeCompound");
788 //=============================================================================
792 //=============================================================================
793 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeShape
794 (std::list<Handle(GEOM_Object)> theShapes,
795 const Standard_Integer theObjectType,
796 const Standard_Integer theFunctionType,
797 const TCollection_AsciiString& theMethodName)
802 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), theObjectType);
805 Handle(GEOM_Function) aFunction =
806 aShape->AddFunction(GEOMImpl_ShapeDriver::GetID(), theFunctionType);
807 if (aFunction.IsNull()) return NULL;
809 //Check if the function is set correctly
810 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
812 GEOMImpl_IShapes aCI (aFunction);
814 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
817 std::list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
818 for (; it != theShapes.end(); it++) {
819 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
820 if (aRefSh.IsNull()) {
821 SetErrorCode("NULL argument shape for the shape construction");
824 aShapesSeq->Append(aRefSh);
826 aCI.SetShapes(aShapesSeq);
831 if (!GetSolver()->ComputeFunction(aFunction)) {
832 SetErrorCode("Shape driver failed");
836 catch (Standard_Failure) {
837 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
838 SetErrorCode(aFail->GetMessageString());
842 //Make a Python command
843 GEOM::TPythonDump pd (aFunction);
844 pd << aShape << " = geompy." << theMethodName.ToCString() << "([";
847 it = theShapes.begin();
848 if (it != theShapes.end()) {
850 while (it != theShapes.end()) {
851 pd << ", " << (*it++);
860 //=============================================================================
862 * MakeSolidFromConnectedFaces
864 //=============================================================================
865 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeSolidFromConnectedFaces
866 (std::list<Handle(GEOM_Object)> theFacesOrShells,
867 const Standard_Boolean isIntersect)
872 Handle(GEOM_Object) aSolid = GetEngine()->AddObject(GetDocID(), GEOM_SOLID);
875 Handle(GEOM_Function) aFunction =
876 aSolid->AddFunction(GEOMImpl_ShapeDriver::GetID(), SOLID_FACES);
877 if (aFunction.IsNull()) return NULL;
879 //Check if the function is set correctly
880 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
882 GEOMImpl_IShapes aCI (aFunction);
884 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
887 std::list<Handle(GEOM_Object)>::iterator it = theFacesOrShells.begin();
888 for (; it != theFacesOrShells.end(); it++) {
889 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
890 if (aRefSh.IsNull()) {
891 SetErrorCode("NULL argument shape for the shape construction");
894 aShapesSeq->Append(aRefSh);
896 aCI.SetShapes(aShapesSeq);
897 aCI.SetIsIntersect(isIntersect);
902 if (!GetSolver()->ComputeFunction(aFunction)) {
903 SetErrorCode("Shape driver failed");
907 catch (Standard_Failure) {
908 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
909 SetErrorCode(aFail->GetMessageString());
913 //Make a Python command
914 GEOM::TPythonDump pd (aFunction);
915 pd << aSolid << " = geompy.MakeSolidFromConnectedFaces([";
918 it = theFacesOrShells.begin();
919 if (it != theFacesOrShells.end()) {
921 while (it != theFacesOrShells.end()) {
922 pd << ", " << (*it++);
925 pd << "]," << (isIntersect ? "True" : "False") << ")";
931 //=============================================================================
935 //=============================================================================
937 GEOMImpl_IShapesOperations::MakeGlueFaces (std::list< Handle(GEOM_Object) >& theShapes,
938 const Standard_Real theTolerance,
939 const Standard_Boolean doKeepNonSolids)
943 Handle(TColStd_HSequenceOfTransient) objects = GEOM_Object::GetLastFunctions( theShapes );
944 if ( objects.IsNull() || objects->IsEmpty() ) {
945 SetErrorCode("NULL argument shape");
949 //Add a new Glued object
950 Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
952 //Add a new Glue function
953 Handle(GEOM_Function) aFunction;
954 aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_FACES);
955 if (aFunction.IsNull()) return NULL;
957 //Check if the function is set correctly
958 if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
960 GEOMImpl_IGlue aCI (aFunction);
962 aCI.SetBase( objects );
963 aCI.SetTolerance(theTolerance);
964 aCI.SetKeepNonSolids(doKeepNonSolids);
966 //Compute the sub-shape value
967 Standard_Boolean isWarning = Standard_False;
970 if (!GetSolver()->ComputeFunction(aFunction)) {
971 SetErrorCode("Shape driver failed to glue faces");
975 catch (Standard_Failure) {
976 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
977 SetErrorCode(aFail->GetMessageString());
978 // to provide warning
979 if (!aFunction->GetValue().IsNull()) {
980 isWarning = Standard_True;
986 //Make a Python command
987 GEOM::TPythonDump(aFunction) << aGlued << " = geompy.MakeGlueFaces("
988 << theShapes << ", " << theTolerance << ")";
990 // to provide warning
991 if (!isWarning) SetErrorCode(OK);
995 //=============================================================================
999 //=============================================================================
1001 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetGlueFaces
1002 (Handle(GEOM_Object) theShape,
1003 const Standard_Real theTolerance)
1007 if (theShape.IsNull()) return NULL;
1008 TopoDS_Shape aShape = theShape->GetValue();
1009 if (aShape.IsNull()) return NULL;
1011 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1013 Standard_Integer iErr;
1015 GEOMAlgo_Gluer1 aGluer;
1016 GEOMAlgo_ListIteratorOfListOfCoupleOfShapes aItCS;
1017 GEOMAlgo_CoupleOfShapes aCS;
1018 GEOMAlgo_ListOfCoupleOfShapes aLCS;
1020 //aGluer = new GEOMAlgo_Gluer1;
1021 aGluer.SetShape(aShape);
1022 aGluer.SetTolerance(theTolerance);
1024 iErr = aGluer.ErrorStatus();
1025 if (iErr) return NULL;
1027 TopTools_ListOfShape listShape;
1028 const GEOMAlgo_ListOfCoupleOfShapes& aLCSG = aGluer.GluedFaces();
1030 aItCS.Initialize(aLCSG);
1031 for (; aItCS.More(); aItCS.Next()) {
1032 const GEOMAlgo_CoupleOfShapes& aCSG = aItCS.Value();
1033 listShape.Append(aCSG.Shape1());
1036 TopTools_ListIteratorOfListOfShape itSub (listShape);
1037 TCollection_AsciiString anAsciiList, anEntry;
1038 TopTools_IndexedMapOfShape anIndices;
1039 TopExp::MapShapes(aShape, anIndices);
1040 Handle(TColStd_HArray1OfInteger) anArray;
1041 Handle(GEOM_Object) anObj;
1042 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
1043 TopoDS_Shape aValue = itSub.Value();
1044 anArray = new TColStd_HArray1OfInteger(1,1);
1045 anArray->SetValue(1, anIndices.FindIndex(aValue));
1046 anObj = GetEngine()->AddSubShape(theShape, anArray);
1047 if (!anObj.IsNull()) {
1048 aSeq->Append(anObj);
1050 // for python command
1051 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
1052 anAsciiList += anEntry;
1057 //Make a Python command
1058 if( anAsciiList.Length() > 0 ) {
1059 anAsciiList.Trunc(anAsciiList.Length() - 1);
1060 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
1061 GEOM::TPythonDump pd (aFunction, true);
1062 pd << "[" << anAsciiList.ToCString();
1063 pd << "] = geompy.GetGlueFaces(" << theShape << ", " << theTolerance << ")";
1072 //=============================================================================
1074 * MakeGlueFacesByList
1076 //=============================================================================
1078 GEOMImpl_IShapesOperations::MakeGlueFacesByList(std::list< Handle(GEOM_Object) >& theShapes,
1079 const Standard_Real theTolerance,
1080 std::list<Handle(GEOM_Object)> & theFaces,
1081 const Standard_Boolean doKeepNonSolids,
1082 const Standard_Boolean doGlueAllEdges)
1086 Handle(TColStd_HSequenceOfTransient) objects = GEOM_Object::GetLastFunctions( theShapes );
1087 if ( objects.IsNull() || objects->IsEmpty() ) {
1088 SetErrorCode("NULL argument shape");
1091 Handle(TColStd_HSequenceOfTransient) aFaces = GEOM_Object::GetLastFunctions( theFaces );
1092 if ( aFaces.IsNull() ) {
1093 SetErrorCode("NULL argument shape for the shape construction");
1097 //Add a new Glued object
1098 Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
1100 //Add a new Glue function
1101 Handle(GEOM_Function) aFunction;
1102 aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_FACES_BY_LIST);
1103 if (aFunction.IsNull()) return NULL;
1105 //Check if the function is set correctly
1106 if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
1108 GEOMImpl_IGlue aCI (aFunction);
1110 aCI.SetBase( objects );
1111 aCI.SetTolerance(theTolerance);
1112 aCI.SetKeepNonSolids(doKeepNonSolids);
1113 aCI.SetGlueAllEdges(doGlueAllEdges);
1114 aCI.SetFaces(aFaces);
1116 //Compute the sub-shape value
1117 Standard_Boolean isWarning = Standard_False;
1120 if (!GetSolver()->ComputeFunction(aFunction)) {
1121 SetErrorCode("Shape driver failed to glue faces");
1125 catch (Standard_Failure) {
1126 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1127 SetErrorCode(aFail->GetMessageString());
1128 // to provide warning
1129 if (!aFunction->GetValue().IsNull()) {
1130 isWarning = Standard_True;
1136 //Make a Python command
1138 GEOM::TPythonDump pd(aFunction);
1139 pd << aGlued << " = geompy.MakeGlueFacesByList("
1140 << theShapes << ", " << theTolerance << ", " << theFaces << ", "
1141 << (bool)doKeepNonSolids << ", " << (bool)doGlueAllEdges << ")";
1143 // to provide warning
1144 if (!isWarning) SetErrorCode(OK);
1148 //=============================================================================
1152 //=============================================================================
1154 GEOMImpl_IShapesOperations::MakeGlueEdges (std::list< Handle(GEOM_Object) >& theShapes,
1155 const Standard_Real theTolerance)
1159 Handle(TColStd_HSequenceOfTransient) objects = GEOM_Object::GetLastFunctions( theShapes );
1160 if ( objects.IsNull() || objects->IsEmpty() ) {
1161 SetErrorCode("NULL argument shape");
1165 //Add a new Glued object
1166 Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
1168 //Add a new Glue function
1169 Handle(GEOM_Function) aFunction;
1170 aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_EDGES);
1171 if (aFunction.IsNull()) return NULL;
1173 //Check if the function is set correctly
1174 if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
1176 GEOMImpl_IGlue aCI (aFunction);
1178 aCI.SetBase( objects );
1179 aCI.SetTolerance(theTolerance);
1180 aCI.SetKeepNonSolids(true);
1182 //Compute the sub-shape value
1183 Standard_Boolean isWarning = Standard_False;
1186 if (!GetSolver()->ComputeFunction(aFunction)) {
1187 SetErrorCode("Shape driver failed to glue edges");
1191 catch (Standard_Failure) {
1192 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1193 SetErrorCode(aFail->GetMessageString());
1194 // to provide warning
1195 if (!aFunction->GetValue().IsNull()) {
1196 isWarning = Standard_True;
1202 //Make a Python command
1203 GEOM::TPythonDump(aFunction) << aGlued << " = geompy.MakeGlueEdges("
1204 << theShapes << ", " << theTolerance << ")";
1206 // to provide warning
1207 if (!isWarning) SetErrorCode(OK);
1211 //=============================================================================
1215 //=============================================================================
1216 Handle(TColStd_HSequenceOfTransient)
1217 GEOMImpl_IShapesOperations::GetGlueShapes (std::list< Handle(GEOM_Object) >& theShapes,
1218 const Standard_Real theTolerance,
1219 const TopAbs_ShapeEnum theType)
1223 TopoDS_Shape aShape;
1224 TopTools_SequenceOfShape shapes;
1225 std::list< Handle(GEOM_Object) >::iterator s = theShapes.begin();
1226 Handle(GEOM_Object) lastCreatedGO;
1227 for ( ; s != theShapes.end(); ++s )
1229 Handle(GEOM_Object) go = *s;
1230 if ( go.IsNull() ) return NULL;
1231 aShape = go->GetValue();
1232 if ( aShape.IsNull() ) return NULL;
1233 shapes.Append( aShape );
1234 lastCreatedGO = GEOM::GetCreatedLast( lastCreatedGO, go );
1236 if ( shapes.Length() > 1 )
1238 TopoDS_Compound compound;
1239 BRep_Builder builder;
1240 builder.MakeCompound( compound );
1241 for ( int i = 1; i <= shapes.Length(); ++i )
1242 builder.Add( compound, shapes( i ) );
1247 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1249 GEOMAlgo_GlueDetector aGluer;
1250 aGluer.SetArgument(aShape);
1251 aGluer.SetTolerance(theTolerance);
1253 Standard_Integer iErr = aGluer.ErrorStatus();
1254 if (iErr) return NULL;
1256 std::vector< TopTools_IndexedMapOfShape* > anIndices( shapes.Length(), NULL );
1257 Handle(TColStd_HArray1OfInteger) anArray;
1258 Handle(GEOM_Object) anObj;
1260 TopTools_ListOfShape listOnePerSet;
1262 const TopTools_DataMapOfShapeListOfShape& aImages = aGluer.Images();
1263 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape aItDMSLS (aImages);
1264 for (int index = 1; aItDMSLS.More(); aItDMSLS.Next(), ++index) {
1266 //const TopoDS_Shape& aSkey = aItDMSLS.Key();
1268 // list of shapes of the argument that can be glued
1269 const TopTools_ListOfShape& aLSD = aItDMSLS.Value();
1271 //listShape.Append(aLSD.First());
1272 TopoDS_Shape aValue = aLSD.First();
1274 if (aValue.ShapeType() == theType) {
1275 listOnePerSet.Append(aValue);
1279 // for stable order of returned entities
1280 GEOMUtils::SortShapes(listOnePerSet, Standard_False);
1282 TopTools_ListIteratorOfListOfShape aListIt (listOnePerSet);
1283 for (; aListIt.More(); aListIt.Next())
1285 TopoDS_Shape aValue = aListIt.Value();
1286 // find a shape to add aValue as a sub-shape
1288 s = theShapes.begin();
1289 for ( int i = 0; i < shapes.Length(); ++i, ++s )
1291 Handle(GEOM_Object) object = *s;
1292 if ( !anIndices[i] ) {
1293 anIndices[i] = new TopTools_IndexedMapOfShape;
1294 TopExp::MapShapes( object->GetValue(), *anIndices[i]);
1296 if (int index = anIndices[i]->FindIndex( aValue )) {
1297 anArray = new TColStd_HArray1OfInteger(1,1);
1298 anArray->SetValue(1, index);
1299 anObj = GetEngine()->AddSubShape( object, anArray);
1303 if (!anObj.IsNull())
1304 aSeq->Append(anObj);
1306 for ( size_t i = 0 ; i < anIndices.size(); ++i )
1307 delete anIndices[i];
1309 // Make a Python command
1310 if ( aSeq->Length() > 0)
1312 Handle(GEOM_Function) aFunction = lastCreatedGO->GetLastFunction();
1313 GEOM::TPythonDump pd (aFunction, /*append=*/true);
1315 << " = geompy." << (theType == TopAbs_FACE ? "GetGlueFaces" : "GetGlueEdges" )
1316 << "( " << theShapes << ", " << theTolerance << ")";
1324 //=============================================================================
1326 * MakeGlueEdgesByList
1328 //=============================================================================
1330 GEOMImpl_IShapesOperations::MakeGlueEdgesByList (std::list< Handle(GEOM_Object) >& theShapes,
1331 const Standard_Real theTolerance,
1332 std::list<Handle(GEOM_Object)>& theEdges)
1336 Handle(TColStd_HSequenceOfTransient) objects = GEOM_Object::GetLastFunctions( theShapes );
1337 if ( objects.IsNull() || objects->IsEmpty() ) {
1338 SetErrorCode("NULL argument shape");
1341 Handle(TColStd_HSequenceOfTransient) anEdges = GEOM_Object::GetLastFunctions( theEdges );
1342 if ( anEdges.IsNull() ) {
1343 SetErrorCode("NULL argument shape for the shape construction");
1346 //Add a new Glued object
1347 Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
1349 //Add a new Glue function
1350 Handle(GEOM_Function) aFunction;
1351 aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_EDGES_BY_LIST);
1352 if (aFunction.IsNull()) return NULL;
1354 //Check if the function is set correctly
1355 if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
1357 GEOMImpl_IGlue aCI (aFunction);
1359 aCI.SetBase( objects );
1360 aCI.SetTolerance(theTolerance);
1361 aCI.SetKeepNonSolids(true);
1362 aCI.SetFaces(anEdges);
1364 //Compute the sub-shape value
1365 Standard_Boolean isWarning = Standard_False;
1368 if (!GetSolver()->ComputeFunction(aFunction)) {
1369 SetErrorCode("Shape driver failed to glue edges");
1373 catch (Standard_Failure) {
1374 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1375 SetErrorCode(aFail->GetMessageString());
1376 // to provide warning
1377 if (!aFunction->GetValue().IsNull()) {
1378 isWarning = Standard_True;
1384 //Make a Python command
1386 GEOM::TPythonDump pd (aFunction);
1387 pd << aGlued << " = geompy.MakeGlueEdgesByList("
1388 << theShapes << ", " << theTolerance << ", " << theEdges << " )";
1390 // to provide warning
1391 if (!isWarning) SetErrorCode(OK);
1395 //=============================================================================
1397 * GetExistingSubObjects
1399 //=============================================================================
1400 Handle(TColStd_HSequenceOfTransient)
1401 GEOMImpl_IShapesOperations::GetExistingSubObjects(Handle(GEOM_Object) theShape,
1402 const Standard_Boolean theGroupsOnly)
1404 // note: this method does not return fields
1406 Standard_Integer types = theGroupsOnly ? Groups : Groups|SubShapes;
1407 Handle(TColStd_HSequenceOfTransient) results = GetExistingSubObjects(theShape, types);
1409 if (results->Length() > 0) {
1410 //Make a Python command
1411 TCollection_AsciiString anAsciiList;
1412 for (int i = 1; i <= results->Length(); i++)
1414 Handle(GEOM_BaseObject) obj = Handle(GEOM_BaseObject)::DownCast( results->Value(i));
1415 obj->GetEntryString();
1416 if ( i < results->Length() )
1420 GEOM::TPythonDump pd (theShape->GetLastFunction(), /*append=*/true);
1421 pd << "[" << anAsciiList.ToCString();
1422 pd << "] = geompy.GetExistingSubObjects(";
1423 pd << theShape << ", " << (bool)theGroupsOnly << ")";
1429 Handle(TColStd_HSequenceOfTransient)
1430 GEOMImpl_IShapesOperations::GetExistingSubObjects(Handle(GEOM_Object) theShape,
1431 const Standard_Integer theTypes)
1435 if (theShape.IsNull()) return NULL;
1437 Handle(GEOM_Function) aMainShape = theShape->GetLastFunction();
1438 if (aMainShape.IsNull()) return NULL;
1440 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1441 SetErrorCode(NOT_FOUND_ANY);
1443 if (!aMainShape->HasSubShapeReferences()) return aSeq;
1444 const TDataStd_ListOfExtendedString& aListEntries = aMainShape->GetSubShapeReferences();
1445 if (aListEntries.IsEmpty()) return aSeq;
1449 TDataStd_ListIteratorOfListOfExtendedString anIt (aListEntries);
1450 for (; anIt.More(); anIt.Next()) {
1451 TCollection_ExtendedString anEntry = anIt.Value();
1452 Standard_Integer aStrLen = anEntry.LengthOfCString();
1453 char* anEntryStr = new char[aStrLen+1];
1454 anEntry.ToUTF8CString(anEntryStr);
1455 Handle(GEOM_BaseObject) anObj = GetEngine()->GetObject(GetDocID(), anEntryStr, false);
1456 if (!anObj.IsNull() ) {
1457 bool isGroup = anObj->IsKind(STANDARD_TYPE(GEOM_Object)) && anObj->GetType() == GEOM_GROUP;
1458 bool isSubShape = anObj->IsKind(STANDARD_TYPE(GEOM_Object)) && anObj->GetType() != GEOM_GROUP;
1459 bool isField = anObj->IsKind(STANDARD_TYPE(GEOM_Field));
1460 if (theTypes & Groups && isGroup ||
1461 theTypes & SubShapes && isSubShape ||
1462 theTypes & Fields && isField) {
1463 aSeq->Append(anObj);
1466 delete [] anEntryStr;
1469 if (aSeq->Length() == 0) {
1470 SetErrorCode(NOT_FOUND_ANY);
1479 //=============================================================================
1483 //=============================================================================
1484 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::MakeExplode
1485 (Handle(GEOM_Object) theShape,
1486 const Standard_Integer theShapeType,
1487 const Standard_Boolean isSorted,
1488 const ExplodeType theExplodeType)
1492 if (theShape.IsNull()) return NULL;
1493 TopoDS_Shape aShape = theShape->GetValue();
1494 if (aShape.IsNull()) return NULL;
1496 Handle(GEOM_Function) aMainShape = theShape->GetLastFunction();
1498 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1499 Handle(GEOM_Object) anObj;
1500 TopTools_MapOfShape mapShape;
1501 TopTools_ListOfShape listShape;
1503 if (aShape.ShapeType() == TopAbs_COMPOUND &&
1504 (theShapeType == TopAbs_SHAPE || theShapeType == TopAbs_FLAT || theShapeType == TopAbs_COMPOUND))
1506 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
1507 for (; It.More(); It.Next()) {
1508 TopoDS_Shape SS = It.Value();
1509 if (mapShape.Add(SS)) {
1510 if (theShapeType == TopAbs_FLAT) {
1511 AddFlatSubShapes(SS, listShape, mapShape);
1513 else if (theShapeType == TopAbs_SHAPE || theShapeType == SS.ShapeType()) {
1514 listShape.Append(SS);
1516 // VSR: for EXPLODE_NEW_INCLUDE_MAIN and EXPLODE_OLD_INCLUDE_MAIN:
1517 // it seems it is necessary to add top-level shape if theShapeType == TopAbs_COMPOUND
1521 else if (theExplodeType != EXPLODE_NEW_EXCLUDE_MAIN || aShape.ShapeType() != theShapeType) // issue 0021079
1523 TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
1524 for (; exp.More(); exp.Next())
1525 if (mapShape.Add(exp.Current()))
1526 listShape.Append(exp.Current());
1529 if (listShape.IsEmpty()){
1530 //SetErrorCode("The given shape has no sub-shapes of the requested type");
1531 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
1536 bool isOldSorting = false;
1537 if (theExplodeType == EXPLODE_OLD_INCLUDE_MAIN)
1538 isOldSorting = true;
1539 GEOMUtils::SortShapes(listShape, isOldSorting);
1542 TopTools_IndexedMapOfShape anIndices;
1543 TopExp::MapShapes(aShape, anIndices);
1544 Handle(TColStd_HArray1OfInteger) anArray;
1546 TopTools_ListIteratorOfListOfShape itSub (listShape);
1547 TCollection_AsciiString anAsciiList, anEntry;
1548 for (int index = 1; itSub.More(); itSub.Next(), ++index)
1550 TopoDS_Shape aValue = itSub.Value();
1551 anArray = new TColStd_HArray1OfInteger(1,1);
1552 anArray->SetValue(1, anIndices.FindIndex(aValue));
1554 //anObj = GetEngine()->AddSubShape(theShape, anArray);
1556 anObj = GetEngine()->AddObject(GetDocID(), GEOM_SUBSHAPE);
1557 Handle(GEOM_Function) aFunction = anObj->AddFunction(GEOM_Object::GetSubShapeID(), 1);
1558 if (aFunction.IsNull()) return aSeq;
1560 GEOM_ISubShape aSSI (aFunction);
1561 aSSI.SetMainShape(aMainShape);
1562 aSSI.SetIndices(anArray);
1564 // Set function value directly, as we know it.
1565 // Usage of Solver here would lead to significant loss of time,
1566 // because GEOM_SubShapeDriver will build TopTools_IndexedMapOfShape
1567 // on the main shape for each being calculated sub-shape separately.
1568 aFunction->SetValue(aValue);
1570 // Put this subshape in the list of sub-shapes of theMainShape
1571 aMainShape->AddSubShapeReference(aFunction);
1573 if (!anObj.IsNull()) {
1574 aSeq->Append(anObj);
1576 // for python command
1577 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
1578 anAsciiList += anEntry;
1583 //Make a Python command
1584 anAsciiList.Trunc(anAsciiList.Length() - 1);
1586 GEOM::TPythonDump pd (aMainShape, /*append=*/true);
1587 pd << "[" << anAsciiList.ToCString() << "] = geompy.";
1588 switch (theExplodeType) {
1589 case EXPLODE_NEW_EXCLUDE_MAIN:
1590 pd << "ExtractShapes(" << theShape << ", "
1591 << TopAbs_ShapeEnum(theShapeType) << ", " << (isSorted ? "True" : "False") << ")";
1593 case EXPLODE_NEW_INCLUDE_MAIN:
1594 pd << "SubShapeAll" << (isSorted ? "SortedCentres(" : "(")
1595 << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
1597 case EXPLODE_OLD_INCLUDE_MAIN:
1598 pd << "SubShapeAll" << (isSorted ? "Sorted(" : "(")
1599 << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
1608 //=============================================================================
1612 //=============================================================================
1613 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::SubShapeAllIDs
1614 (Handle(GEOM_Object) theShape,
1615 const Standard_Integer theShapeType,
1616 const Standard_Boolean isSorted,
1617 const ExplodeType theExplodeType)
1621 if (theShape.IsNull()) return NULL;
1622 TopoDS_Shape aShape = theShape->GetValue();
1623 if (aShape.IsNull()) return NULL;
1625 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
1626 TopTools_MapOfShape mapShape;
1627 TopTools_ListOfShape listShape;
1629 if (aShape.ShapeType() == TopAbs_COMPOUND &&
1630 (theShapeType == TopAbs_SHAPE || theShapeType == TopAbs_FLAT || theShapeType == TopAbs_COMPOUND))
1632 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
1633 for (; It.More(); It.Next()) {
1634 TopoDS_Shape SS = It.Value();
1635 if (mapShape.Add(SS)) {
1636 if (theShapeType == TopAbs_FLAT) {
1637 AddFlatSubShapes(SS, listShape, mapShape);
1639 else if (theShapeType == TopAbs_SHAPE || theShapeType == SS.ShapeType()) {
1640 listShape.Append(SS);
1645 else if (theExplodeType != EXPLODE_NEW_EXCLUDE_MAIN || aShape.ShapeType() != theShapeType) // issue 0021079
1647 TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
1648 for (; exp.More(); exp.Next())
1649 if (mapShape.Add(exp.Current()))
1650 listShape.Append(exp.Current());
1653 if (listShape.IsEmpty()) {
1654 //SetErrorCode("The given shape has no sub-shapes of the requested type");
1655 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
1660 bool isOldSorting = false;
1661 if (theExplodeType == EXPLODE_OLD_INCLUDE_MAIN)
1662 isOldSorting = true;
1663 GEOMUtils::SortShapes(listShape, isOldSorting);
1666 TopTools_IndexedMapOfShape anIndices;
1667 TopExp::MapShapes(aShape, anIndices);
1668 Handle(TColStd_HArray1OfInteger) anArray;
1670 TopTools_ListIteratorOfListOfShape itSub (listShape);
1671 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
1672 TopoDS_Shape aValue = itSub.Value();
1673 aSeq->Append(anIndices.FindIndex(aValue));
1676 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
1678 //Make a Python command
1679 GEOM::TPythonDump pd (aFunction, /*append=*/true);
1680 pd << "listSubShapeIDs = geompy.SubShapeAll";
1681 switch (theExplodeType) {
1682 case EXPLODE_NEW_EXCLUDE_MAIN:
1684 case EXPLODE_NEW_INCLUDE_MAIN:
1685 pd << (isSorted ? "SortedCentresIDs(" : "IDs(")
1686 << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
1688 case EXPLODE_OLD_INCLUDE_MAIN:
1689 pd << (isSorted ? "SortedIDs(" : "IDs(")
1690 << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
1699 //=============================================================================
1703 //=============================================================================
1704 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetSubShape
1705 (Handle(GEOM_Object) theMainShape,
1706 const Standard_Integer theID)
1710 if (theMainShape.IsNull()) return NULL;
1712 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
1713 anArray->SetValue(1, theID);
1714 Handle(GEOM_Object) anObj = GetEngine()->AddSubShape(theMainShape, anArray,true);
1715 if (anObj.IsNull()) {
1716 SetErrorCode("Can not get a sub-shape with the given ID");
1720 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1722 //Make a Python command
1723 GEOM::TPythonDump(aFunction) << anObj << " = geompy.GetSubShape("
1724 << theMainShape << ", [" << theID << "])";
1730 //=============================================================================
1734 //=============================================================================
1735 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::MakeSubShapes
1736 (Handle(GEOM_Object) theMainShape,
1737 Handle(TColStd_HArray1OfInteger) theIndices)
1741 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1743 if (!theIndices->Length()) {
1744 SetErrorCode(NOT_FOUND_ANY);
1748 if (theMainShape.IsNull()) return NULL;
1749 TopoDS_Shape aShape = theMainShape->GetValue();
1750 if (aShape.IsNull()) return NULL;
1752 Handle(GEOM_Function) aMainShape = theMainShape->GetLastFunction();
1754 TopTools_IndexedMapOfShape anIndices;
1755 TopExp::MapShapes(aShape, anIndices);
1757 Handle(TColStd_HArray1OfInteger) anArray;
1758 Handle(GEOM_Object) anObj;
1760 TCollection_AsciiString anAsciiList, anEntry;
1761 Standard_Integer i, low = theIndices->Lower(), up = theIndices->Upper();
1762 for (i = low; i <= up; i++) {
1763 int id = theIndices->Value(i);
1764 if (1 <= id && id <= anIndices.Extent()) {
1765 TopoDS_Shape aValue = anIndices.FindKey(id);
1766 anArray = new TColStd_HArray1OfInteger(1,1);
1767 anArray->SetValue(1, id);
1769 anObj = GetEngine()->AddObject(GetDocID(), GEOM_SUBSHAPE);
1770 if (!anObj.IsNull()) {
1771 Handle(GEOM_Function) aFunction = anObj->AddFunction(GEOM_Object::GetSubShapeID(), 1);
1772 if (aFunction.IsNull()) return aSeq;
1774 GEOM_ISubShape aSSI (aFunction);
1775 aSSI.SetMainShape(aMainShape);
1776 aSSI.SetIndices(anArray);
1778 // Set function value directly, as we know it.
1779 // Usage of Solver here would lead to significant loss of time,
1780 // because GEOM_SubShapeDriver will build TopTools_IndexedMapOfShape
1781 // on the main shape for each being calculated sub-shape separately.
1782 aFunction->SetValue(aValue);
1784 // Put this sub-shape in the list of sub-shapes of theMainShape
1785 aMainShape->AddSubShapeReference(aFunction);
1787 aSeq->Append(anObj);
1789 // for python command
1790 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
1791 anAsciiList += anEntry;
1797 //Make a Python command
1798 anAsciiList.Trunc(anAsciiList.Length() - 1);
1800 GEOM::TPythonDump pd (aMainShape, /*append=*/true);
1801 pd << "[" << anAsciiList.ToCString() << "] = geompy.SubShapes("
1802 << theMainShape << ", [" ;
1803 for (i = low; i <= up - 1; i++) {
1804 pd << theIndices->Value(i) << ", ";
1806 pd << theIndices->Value(up) << "])";
1813 //=============================================================================
1817 //=============================================================================
1818 Standard_Integer GEOMImpl_IShapesOperations::GetSubShapeIndex (Handle(GEOM_Object) theMainShape,
1819 Handle(GEOM_Object) theSubShape)
1823 TopoDS_Shape aMainShape = theMainShape->GetValue();
1824 TopoDS_Shape aSubShape = theSubShape->GetValue();
1826 if (aMainShape.IsNull() || aSubShape.IsNull()) return -1;
1828 TopTools_IndexedMapOfShape anIndices;
1829 TopExp::MapShapes(aMainShape, anIndices);
1830 // if (anIndices.Contains(aSubShape)) {
1831 // SetErrorCode(OK);
1832 // return anIndices.FindIndex(aSubShape);
1834 int id = anIndices.FindIndex(aSubShape);
1845 //=============================================================================
1847 * GetSubShapeIndices
1849 //=============================================================================
1850 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetSubShapesIndices (Handle(GEOM_Object) theMainShape,
1851 std::list<Handle(GEOM_Object)> theSubShapes)
1853 MESSAGE("GEOMImpl_IShapesOperations::GetSubShapesIndices")
1856 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
1858 TopoDS_Shape aMainShape = theMainShape->GetValue();
1859 if (aMainShape.IsNull())
1861 MESSAGE("NULL main shape")
1865 TopTools_IndexedMapOfShape anIndices;
1866 TopExp::MapShapes(aMainShape, anIndices);
1868 std::list<Handle(GEOM_Object)>::iterator it;
1869 for (it=theSubShapes.begin(); it != theSubShapes.end(); ++it)
1871 TopoDS_Shape aSubShape = (*it)->GetValue();
1872 if (aSubShape.IsNull())
1874 MESSAGE("NULL subshape")
1877 int id = anIndices.FindIndex(aSubShape);
1886 //=============================================================================
1890 //=============================================================================
1891 Standard_Integer GEOMImpl_IShapesOperations::GetTopologyIndex (Handle(GEOM_Object) theMainShape,
1892 Handle(GEOM_Object) theSubShape)
1896 TopoDS_Shape aMainShape = theMainShape->GetValue();
1897 TopoDS_Shape aSubShape = theSubShape->GetValue();
1899 if (aMainShape.IsNull() || aSubShape.IsNull()) {
1900 SetErrorCode("Null argument shape given");
1905 if (aSubShape.ShapeType() == TopAbs_COMPOUND) {
1907 TopTools_ListOfShape CL;
1908 CL.Append(aMainShape);
1909 TopTools_ListIteratorOfListOfShape itC;
1910 for (itC.Initialize(CL); itC.More(); itC.Next()) {
1911 for (it.Initialize(itC.Value()); it.More(); it.Next()) {
1912 if (it.Value().ShapeType() == TopAbs_COMPOUND) {
1913 if (it.Value().IsSame(aSubShape))
1917 CL.Append(it.Value());
1922 TopExp_Explorer anExp (aMainShape, aSubShape.ShapeType());
1923 TopTools_MapOfShape M;
1924 for (; anExp.More(); anExp.Next()) {
1925 if (M.Add(anExp.Current())) {
1926 if (anExp.Current().IsSame(aSubShape))
1933 SetErrorCode("The sub-shape does not belong to the main shape");
1937 //=============================================================================
1939 * GetShapeTypeString
1941 //=============================================================================
1942 TCollection_AsciiString GEOMImpl_IShapesOperations::GetShapeTypeString (Handle(GEOM_Object) theShape)
1946 TCollection_AsciiString aTypeName ("Null Shape");
1948 TopoDS_Shape aShape = theShape->GetValue();
1949 if (aShape.IsNull())
1952 switch (aShape.ShapeType() )
1954 case TopAbs_COMPOUND:
1955 aTypeName = "Compound";
1957 case TopAbs_COMPSOLID:
1958 aTypeName = "Compound Solid";
1961 aTypeName = "Solid";
1964 aTypeName = "Shell";
1968 BRepAdaptor_Surface surf (TopoDS::Face(aShape));
1969 if (surf.GetType() == GeomAbs_Plane)
1970 aTypeName = "Plane";
1971 else if (surf.GetType() == GeomAbs_Cylinder)
1972 aTypeName = "Cylindrical Face";
1973 else if (surf.GetType() == GeomAbs_Sphere)
1974 aTypeName = "Spherical Face";
1975 else if (surf.GetType() == GeomAbs_Torus)
1976 aTypeName = "Toroidal Face";
1977 else if (surf.GetType() == GeomAbs_Cone)
1978 aTypeName = "Conical Face";
1980 aTypeName = "GEOM::FACE";
1988 BRepAdaptor_Curve curv (TopoDS::Edge(aShape));
1989 if (curv.GetType() == GeomAbs_Line) {
1990 if ((Abs(curv.FirstParameter()) >= 1E6) ||
1991 (Abs(curv.LastParameter()) >= 1E6))
1995 } else if (curv.GetType() == GeomAbs_Circle) {
1996 if (curv.IsClosed())
1997 aTypeName = "Circle";
2006 aTypeName = "Vertex";
2009 aTypeName = "Shape";
2012 aTypeName = "Shape of unknown type";
2018 //=============================================================================
2020 * IsSubShapeBelongsTo
2022 //=============================================================================
2023 Standard_Boolean GEOMImpl_IShapesOperations::IsSubShapeBelongsTo( Handle(GEOM_Object) theSubObject,
2024 const Standard_Integer theSubObjectIndex,
2025 Handle(GEOM_Object) theObject,
2026 const Standard_Integer theObjectIndex)
2030 if ( theObject.IsNull() || theSubObject.IsNull() )
2033 TopoDS_Shape shape = theObject->GetValue();
2034 TopoDS_Shape subShape = theSubObject->GetValue();
2036 if ( shape.IsNull() || subShape.IsNull() )
2039 TopTools_IndexedMapOfShape anIndices;
2040 if ( theObjectIndex > 0 ) {
2041 TopExp::MapShapes( shape, anIndices );
2042 shape = anIndices.FindKey(theObjectIndex);
2044 if ( theSubObjectIndex > 0 ) {
2045 TopExp::MapShapes( subShape, anIndices );
2046 subShape = anIndices.FindKey(theSubObjectIndex);
2049 TopExp::MapShapes( shape, anIndices );
2051 const Standard_Boolean isBelongTo = anIndices.Contains(subShape);
2058 //=============================================================================
2062 //=============================================================================
2063 Standard_Integer GEOMImpl_IShapesOperations::NumberOfSubShapes
2064 (Handle(GEOM_Object) theShape,
2065 const Standard_Integer theShapeType)
2068 Standard_Integer nbShapes = 0;
2070 if (theShape.IsNull()) return -1;
2071 TopoDS_Shape aShape = theShape->GetValue();
2072 if (aShape.IsNull()) return -1;
2075 TopTools_MapOfShape mapShape;
2077 if (aShape.ShapeType() == TopAbs_COMPOUND &&
2078 (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
2079 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPSOLID ||
2080 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPOUND)) {
2081 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
2082 for (; It.More(); It.Next()) {
2083 if (mapShape.Add(It.Value())) {
2084 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
2085 TopAbs_ShapeEnum(theShapeType) == It.Value().ShapeType()) {
2091 TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
2092 for (; exp.More(); exp.Next())
2093 if (mapShape.Add(exp.Current()))
2099 if (theShapeType == TopAbs_FLAT) {
2100 TopTools_MapOfShape aMapOfShape;
2101 TopTools_ListOfShape aListOfShape;
2102 AddFlatSubShapes(aShape, aListOfShape, aMapOfShape);
2103 nbShapes = aListOfShape.Extent();
2107 int iType, nbTypes [TopAbs_SHAPE];
2108 for (iType = 0; iType < TopAbs_SHAPE; ++iType)
2110 nbTypes[aShape.ShapeType()]++;
2112 TopTools_MapOfShape aMapOfShape;
2113 aMapOfShape.Add(aShape);
2114 TopTools_ListOfShape aListOfShape;
2115 aListOfShape.Append(aShape);
2117 TopTools_ListIteratorOfListOfShape itL (aListOfShape);
2118 for (; itL.More(); itL.Next()) {
2119 TopoDS_Iterator it (itL.Value());
2120 for (; it.More(); it.Next()) {
2121 TopoDS_Shape s = it.Value();
2122 if (aMapOfShape.Add(s)) {
2123 aListOfShape.Append(s);
2124 nbTypes[s.ShapeType()]++;
2129 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE)
2130 nbShapes = aMapOfShape.Extent();
2132 nbShapes = nbTypes[theShapeType];
2135 catch (Standard_Failure) {
2136 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2137 SetErrorCode(aFail->GetMessageString());
2145 //=============================================================================
2149 //=============================================================================
2150 Handle(GEOM_Object) GEOMImpl_IShapesOperations::ReverseShape(Handle(GEOM_Object) theShape)
2154 if (theShape.IsNull()) return NULL;
2157 //Add a new reversed object
2158 Handle(GEOM_Object) aReversed = GetEngine()->AddObject(GetDocID(), theShape->GetType());
2160 //Add a new Revese function
2161 Handle(GEOM_Function) aFunction;
2162 aFunction = aReversed->AddFunction(GEOMImpl_ShapeDriver::GetID(), REVERSE_ORIENTATION);
2163 if (aFunction.IsNull()) return NULL;
2165 //Check if the function is set correctly
2166 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
2168 GEOMImpl_IShapes aSI (aFunction);
2170 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
2171 if (aRefShape.IsNull()) return NULL;
2173 aSI.SetBase(aRefShape);
2175 //Compute the sub-shape value
2178 if (!GetSolver()->ComputeFunction(aFunction)) {
2179 SetErrorCode("Shape driver failed to reverse shape");
2183 catch (Standard_Failure) {
2184 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2185 SetErrorCode(aFail->GetMessageString());
2189 //Make a Python command
2190 GEOM::TPythonDump(aFunction) << aReversed
2191 << " = geompy.ChangeOrientation(" << theShape << ")";
2196 Handle(GEOM_Object) aReversed;
2198 GEOM_Engine* anEngine = GetEngine();
2199 //GEOMImpl_Gen* aGen = dynamic_cast<GEOMImpl_Gen*>(anEngine);
2200 GEOMImpl_Gen* aGen = (GEOMImpl_Gen*)anEngine;
2203 GEOMImpl_IHealingOperations* anIHealingOperations =
2204 aGen->GetIHealingOperations(GetDocID());
2205 aReversed = anIHealingOperations->ChangeOrientationCopy(theShape);
2206 SetErrorCode(anIHealingOperations->GetErrorCode());
2212 //=============================================================================
2216 //=============================================================================
2217 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetFreeFacesIDs
2218 (Handle(GEOM_Object) theShape)
2222 if (theShape.IsNull()) return NULL;
2223 TopoDS_Shape aShape = theShape->GetValue();
2224 if (aShape.IsNull()) return NULL;
2226 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
2228 TopTools_IndexedDataMapOfShapeListOfShape mapFaceBlocks;
2229 GEOMImpl_Block6Explorer::MapShapesAndAncestors
2230 (aShape, TopAbs_FACE, TopAbs_SOLID, mapFaceBlocks);
2232 Standard_Integer ind = 1, nbFaces = mapFaceBlocks.Extent();
2235 SetErrorCode("The given shape has no faces");
2239 TopTools_IndexedMapOfShape anIndices;
2240 TopExp::MapShapes(aShape, anIndices);
2242 Standard_Integer id;
2243 for (; ind <= nbFaces; ind++) {
2244 if (mapFaceBlocks.FindFromIndex(ind).Extent() != 2) {
2245 id = anIndices.FindIndex(mapFaceBlocks.FindKey(ind));
2250 //The explode doesn't change object so no new function is required.
2251 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
2253 //Make a Python command
2254 GEOM::TPythonDump(aFunction, /*append=*/true)
2255 << "listFreeFacesIDs = geompy.GetFreeFacesIDs(" << theShape << ")";
2261 //=======================================================================
2262 //function : GetSharedShapes
2264 //=======================================================================
2265 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetSharedShapes
2266 (Handle(GEOM_Object) theShape1,
2267 Handle(GEOM_Object) theShape2,
2268 const Standard_Integer theShapeType)
2272 if (theShape1.IsNull() || theShape2.IsNull()) return NULL;
2274 TopoDS_Shape aShape1 = theShape1->GetValue();
2275 TopoDS_Shape aShape2 = theShape2->GetValue();
2277 if (aShape1.IsNull() || aShape2.IsNull()) return NULL;
2279 TopTools_IndexedMapOfShape anIndices;
2280 TopExp::MapShapes(aShape1, anIndices);
2281 Handle(TColStd_HArray1OfInteger) anArray;
2283 TopTools_IndexedMapOfShape mapShape1;
2284 TopExp::MapShapes(aShape1, TopAbs_ShapeEnum(theShapeType), mapShape1);
2286 Handle(GEOM_Object) anObj;
2287 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
2288 TCollection_AsciiString anAsciiList, anEntry;
2290 TopTools_MapOfShape mapShape2;
2291 TopExp_Explorer exp (aShape2, TopAbs_ShapeEnum(theShapeType));
2292 for (; exp.More(); exp.Next()) {
2293 TopoDS_Shape aSS = exp.Current();
2294 if (mapShape2.Add(aSS) && mapShape1.Contains(aSS)) {
2295 anArray = new TColStd_HArray1OfInteger(1,1);
2296 anArray->SetValue(1, anIndices.FindIndex(aSS));
2297 anObj = GetEngine()->AddSubShape(theShape1, anArray);
2298 aSeq->Append(anObj);
2300 // for python command
2301 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
2302 anAsciiList += anEntry;
2307 if (aSeq->IsEmpty()) {
2308 SetErrorCode(NOT_FOUND_ANY);
2312 //Make a Python command
2313 anAsciiList.Trunc(anAsciiList.Length() - 1);
2315 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2317 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
2318 << "] = geompy.GetSharedShapes(" << theShape1 << ", "
2319 << theShape2 << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
2325 //=======================================================================
2326 //function : GetSharedShapes
2329 // NOTE on the implementation
2331 // 1) Resulting sub-shapes are published as a children of the 1st input shape
2332 // from theShapes list. Due to this reason only direct sub-shapes of the 1st
2333 // shape can be contained in the result of the operation (i.e. shares between
2334 // 2nd/3rd, etc couples cannot be retrieved.
2335 // 2) An exception from above case is when a single compound is specified as an
2336 // input. In this case we search shares between its top-level content, so we
2337 // are able to search shares between all possible couples of shapes.
2338 // 3) Parameter theMultiShare controls what types of shares to search:
2339 // - True: get sub-shapes that are shared between ALL input shapes;
2340 // - False: get shares between couples of input sub-shapes (see points 1 and 2).
2342 // Thus, we have the following cases:
2343 // [1] theShapes = N shapes (N>1), theMultiShare = True
2344 // Result: sub-shapes that are shared by all theShapes
2345 // [2] theShapes = N shapes (N>1), theMultiShare = False
2346 // Result: sub-shapes of 1st shape from theShapes that are shared with any shape
2348 // [3] theShapes = 1 shape, theMultiShare = True
2349 // Result: sub-shapes that are shared by all top-level sub-objects of theShapes[0]
2350 // [4] theShapes = 1 shape, theMultiShare = False
2351 // Result: sub-shapes of all possible couples of all top-level sub-objects of
2353 //=======================================================================
2354 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetSharedShapes
2355 (std::list<Handle(GEOM_Object)> & theShapes,
2356 const Standard_Integer theShapeType,
2357 const bool theMultiShare)
2361 int aLen = theShapes.size();
2362 if (aLen < 1) return NULL;
2364 std::list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
2366 // main object is always first in the input list
2367 // it is the object from which sub-shapes indices are taken
2368 // and where results are published
2369 Handle(GEOM_Object) aMainObj = *it;
2370 Handle(GEOM_Function) aMainShape = aMainObj->GetLastFunction();
2372 // collect all shapes from the input list (including first one) for processing
2373 TopTools_SequenceOfShape shapeSeq;
2374 for (; it != theShapes.end(); it++) {
2375 Handle(GEOM_Function) aRefShape = (*it)->GetLastFunction();
2376 if (aRefShape.IsNull()) {
2377 SetErrorCode("NULL shape for GetSharedShapes");
2380 TopoDS_Shape aShape = aRefShape->GetValue();
2381 if (aShape.IsNull()) {
2382 SetErrorCode("NULL shape for GetSharedShapes");
2385 shapeSeq.Append( aShape );
2388 // if only single shape is specified as input
2389 // collect all ites top-level sub-shapes for processing
2390 if ( shapeSeq.Length() == 1 )
2392 TopoDS_Shape aShape = shapeSeq.First();
2394 for ( TopoDS_Iterator it( aShape ); it.More(); it.Next() )
2395 shapeSeq.Append( it.Value() );
2398 // map all sub-shapes in a main shape to their indices
2399 TopTools_IndexedMapOfShape anIndices;
2400 TopExp::MapShapes(aMainShape->GetValue(), anIndices);
2401 TopTools_MapOfShape mapShape;
2403 // find shared shapes
2405 // here we will collect all shares
2406 TopTools_ListOfShape aShared;
2408 // number of iterations
2409 int nbIters = theMultiShare || theShapes.size() > 1 ? 1 : shapeSeq.Length()-1;
2410 // numShares factor to search (i.e. by what nb of shapes each found sub-shape should be shared)
2411 int nbShares = theMultiShare ? shapeSeq.Length()-1 : 1;
2413 for ( int iter = 1; iter <= nbIters; iter++) {
2414 for ( int ind = iter+1; ind <= shapeSeq.Length(); ind++) {
2415 if ( ind-1+nbShares > shapeSeq.Length() ) break;
2416 TopoDS_Compound aCurrSelection;
2417 TopoDS_Shape aShape1 = shapeSeq.Value( iter );
2418 TopTools_IndexedMapOfShape mapSelected;
2419 TopExp::MapShapes(aShape1, TopAbs_ShapeEnum(theShapeType), mapSelected);
2420 for ( int s = 0; s < nbShares; s++ ) {
2422 TopoDS_Compound aCompound;
2423 B.MakeCompound(aCompound);
2424 const TopoDS_Shape& aShape2 = shapeSeq.Value( ind+s );
2425 TopTools_MapOfShape mapShape2;
2426 TopExp_Explorer exp (aShape2, TopAbs_ShapeEnum(theShapeType));
2427 for (; exp.More(); exp.Next()) {
2428 const TopoDS_Shape& aSS = exp.Current();
2429 if (mapShape2.Add(aSS) && mapSelected.Contains(aSS)) {
2430 B.Add(aCompound, aSS);
2433 mapSelected.Clear();
2434 aCurrSelection = aCompound;
2435 TopExp::MapShapes(aCurrSelection, TopAbs_ShapeEnum(theShapeType), mapSelected);
2437 TopoDS_Iterator itSel(aCurrSelection, Standard_True, Standard_True);
2438 for (; itSel.More(); itSel.Next()) {
2439 const TopoDS_Shape& aSS = itSel.Value();
2440 if (mapShape.Add(aSS) )
2441 aShared.Append(aSS);
2446 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
2448 if (aShared.IsEmpty()){
2449 SetErrorCode(NOT_FOUND_ANY);
2453 // create GEOM_Object for each found shared shape (collected in aShared)
2454 TCollection_AsciiString anAsciiList;
2455 Handle(GEOM_Object) anObj;
2456 TopTools_ListIteratorOfListOfShape itSub (aShared);
2457 for (; itSub.More(); itSub.Next()) {
2458 TopoDS_Shape aValue = itSub.Value();
2459 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
2460 anArray->SetValue(1, anIndices.FindIndex(aValue));
2461 anObj = GetEngine()->AddSubShape(aMainObj, anArray);
2462 aSeq->Append(anObj);
2464 // for python command
2465 TCollection_AsciiString anEntry;
2466 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
2467 anAsciiList += anEntry;
2471 // make a Python command
2472 anAsciiList.Trunc(anAsciiList.Length() - 1);
2474 GEOM::TPythonDump pd (anObj->GetLastFunction());
2475 pd << "[" << anAsciiList.ToCString()
2476 << "] = geompy.GetSharedShapesMulti(";
2481 it = theShapes.begin();
2483 while (it != theShapes.end()) {
2484 pd << ", " << (*it++);
2489 pd << ", " << TopAbs_ShapeEnum(theShapeType) << ", " << theMultiShare << ")";
2495 //=============================================================================
2499 //=============================================================================
2500 static GEOM::TPythonDump& operator<< (GEOM::TPythonDump& theDump,
2501 const GEOMAlgo_State theState)
2504 case GEOMAlgo_ST_IN:
2505 theDump << "GEOM.ST_IN";
2507 case GEOMAlgo_ST_OUT:
2508 theDump << "GEOM.ST_OUT";
2510 case GEOMAlgo_ST_ON:
2511 theDump << "GEOM.ST_ON";
2513 case GEOMAlgo_ST_ONIN:
2514 theDump << "GEOM.ST_ONIN";
2516 case GEOMAlgo_ST_ONOUT:
2517 theDump << "GEOM.ST_ONOUT";
2520 theDump << "GEOM.ST_UNKNOWN";
2526 //=======================================================================
2527 //function : checkTypeShapesOn
2529 * \brief Checks if theShapeType parameter of GetShapesOnXXX() is OK
2530 * \param theShapeType - the shape type to check
2531 * \retval bool - result of the check
2533 //=======================================================================
2534 bool GEOMImpl_IShapesOperations::checkTypeShapesOn(const Standard_Integer theShapeType)
2536 if (theShapeType != TopAbs_VERTEX &&
2537 theShapeType != TopAbs_EDGE &&
2538 theShapeType != TopAbs_FACE &&
2539 theShapeType != TopAbs_SOLID) {
2540 SetErrorCode("Only solids, vertices, edges or faces can be found by this method");
2546 //=======================================================================
2547 //function : makePlane
2549 * \brief Creates Geom_Plane
2550 * \param theAx1 - shape object defining plane parameters
2551 * \retval Handle(Geom_Surface) - resulting surface
2553 //=======================================================================
2554 Handle(Geom_Surface) GEOMImpl_IShapesOperations::makePlane(const TopoDS_Shape& anAx1)
2556 if (anAx1.ShapeType() != TopAbs_EDGE) return NULL;
2557 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
2558 TopoDS_Vertex V1, V2;
2559 TopExp::Vertices(anEdge, V1, V2, Standard_True);
2560 if (V1.IsNull() || V2.IsNull()) {
2561 SetErrorCode("Bad edge given for the plane normal vector");
2564 gp_Pnt aLoc = BRep_Tool::Pnt(V1);
2565 gp_Vec aVec (aLoc, BRep_Tool::Pnt(V2));
2566 if (aVec.Magnitude() < Precision::Confusion()) {
2567 SetErrorCode("Vector with null magnitude given");
2570 return new Geom_Plane(aLoc, aVec);
2573 //=======================================================================
2574 //function : makeCylinder
2576 * \brief Creates Geom_CylindricalSurface
2577 * \param theAx1 - edge defining cylinder axis
2578 * \param theRadius - cylinder radius
2579 * \retval Handle(Geom_Surface) - resulting surface
2581 //=======================================================================
2582 Handle(Geom_Surface) GEOMImpl_IShapesOperations::makeCylinder(const TopoDS_Shape& anAxis,
2583 const Standard_Real theRadius)
2585 //Axis of the cylinder
2586 if (anAxis.ShapeType() != TopAbs_EDGE) {
2587 SetErrorCode("Not an edge given for the axis");
2590 TopoDS_Edge anEdge = TopoDS::Edge(anAxis);
2591 TopoDS_Vertex V1, V2;
2592 TopExp::Vertices(anEdge, V1, V2, Standard_True);
2593 if (V1.IsNull() || V2.IsNull()) {
2594 SetErrorCode("Bad edge given for the axis");
2597 gp_Pnt aLoc = BRep_Tool::Pnt(V1);
2598 gp_Vec aVec (aLoc, BRep_Tool::Pnt(V2));
2599 if (aVec.Magnitude() < Precision::Confusion()) {
2600 SetErrorCode("Vector with null magnitude given");
2604 gp_Ax3 anAx3 (aLoc, aVec);
2605 return new Geom_CylindricalSurface(anAx3, theRadius);
2608 //=======================================================================
2609 //function : getShapesOnBoxIDs
2611 * \brief Find IDs of sub-shapes complying with given status about surface
2612 * \param theBox - the box to check state of sub-shapes against
2613 * \param theShape - the shape to explore
2614 * \param theShapeType - type of sub-shape of theShape
2615 * \param theState - required state
2616 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
2618 //=======================================================================
2619 Handle(TColStd_HSequenceOfInteger)
2620 GEOMImpl_IShapesOperations::getShapesOnBoxIDs(const Handle(GEOM_Object)& theBox,
2621 const Handle(GEOM_Object)& theShape,
2622 const Standard_Integer theShapeType,
2623 GEOMAlgo_State theState)
2625 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
2627 TopoDS_Shape aBox = theBox->GetValue();
2628 TopoDS_Shape aShape = theShape->GetValue();
2630 // Check presence of triangulation, build if need
2631 if (theShapeType != TopAbs_VERTEX && !GEOMUtils::CheckTriangulation(aShape)) {
2632 SetErrorCode("Cannot build triangulation on the shape");
2637 GEOMAlgo_FinderShapeOn2 aFinder;
2638 Standard_Real aTol = 0.0001; // default value
2640 Handle(GEOMAlgo_ClsfBox) aClsfBox = new GEOMAlgo_ClsfBox;
2641 aClsfBox->SetBox(aBox);
2643 aFinder.SetShape(aShape);
2644 aFinder.SetTolerance(aTol);
2645 aFinder.SetClsf(aClsfBox);
2646 aFinder.SetShapeType( (TopAbs_ShapeEnum)theShapeType );
2647 aFinder.SetState(theState);
2650 // Interprete results
2651 Standard_Integer iErr = aFinder.ErrorStatus();
2652 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn2.cxx
2654 MESSAGE(" iErr : " << iErr);
2655 TCollection_AsciiString aMsg (" iErr : ");
2656 aMsg += TCollection_AsciiString(iErr);
2660 Standard_Integer iWrn = aFinder.WarningStatus();
2661 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn2.cxx
2663 MESSAGE(" *** iWrn : " << iWrn);
2666 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
2668 if (listSS.Extent() < 1) {
2669 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
2670 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
2674 // Fill sequence of object IDs
2675 aSeqOfIDs = new TColStd_HSequenceOfInteger;
2677 TopTools_IndexedMapOfShape anIndices;
2678 TopExp::MapShapes(aShape, anIndices);
2680 TopTools_ListIteratorOfListOfShape itSub (listSS);
2681 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
2682 int id = anIndices.FindIndex(itSub.Value());
2683 aSeqOfIDs->Append(id);
2689 //=======================================================================
2690 //function : GetShapesOnBoxIDs
2692 * \brief Find sub-shapes complying with given status about surface
2693 * \param theBox - the box to check state of sub-shapes against
2694 * \param theShape - the shape to explore
2695 * \param theShapeType - type of sub-shape of theShape
2696 * \param theState - required state
2697 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
2699 //=======================================================================
2700 Handle(TColStd_HSequenceOfInteger)
2701 GEOMImpl_IShapesOperations::GetShapesOnBoxIDs(const Handle(GEOM_Object)& theBox,
2702 const Handle(GEOM_Object)& theShape,
2703 const Standard_Integer theShapeType,
2704 GEOMAlgo_State theState)
2706 // Find sub-shapes ids
2707 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2708 getShapesOnBoxIDs (theBox, theShape, theShapeType, theState);
2709 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2712 // The GetShapesOnBox() doesn't change object so no new function is required.
2713 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theBox)->GetLastFunction();
2715 // Make a Python command
2716 GEOM::TPythonDump(aFunction, /*append=*/true)
2717 << "listShapesOnBoxIDs = geompy.GetShapesOnBoxIDs("
2720 << TopAbs_ShapeEnum(theShapeType) << ", "
2727 //=======================================================================
2728 //function : GetShapesOnBox
2730 * \brief Find sub-shapes complying with given status about surface
2731 * \param theBox - the box to check state of sub-shapes against
2732 * \param theShape - the shape to explore
2733 * \param theShapeType - type of sub-shape of theShape
2734 * \param theState - required state
2735 * \retval Handle(TColStd_HSequenceOfTransient) - found sub-shapes
2737 //=======================================================================
2738 Handle(TColStd_HSequenceOfTransient)
2739 GEOMImpl_IShapesOperations::GetShapesOnBox(const Handle(GEOM_Object)& theBox,
2740 const Handle(GEOM_Object)& theShape,
2741 const Standard_Integer theShapeType,
2742 GEOMAlgo_State theState)
2744 // Find sub-shapes ids
2745 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2746 getShapesOnBoxIDs (theBox, theShape, theShapeType, theState);
2747 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2750 // Find objects by indices
2751 TCollection_AsciiString anAsciiList;
2752 Handle(TColStd_HSequenceOfTransient) aSeq;
2753 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
2754 if ( aSeq.IsNull() || aSeq->IsEmpty() )
2757 // Make a Python command
2759 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2760 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2762 GEOM::TPythonDump(aFunction)
2763 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnBox("
2766 << TopAbs_ShapeEnum(theShapeType) << ", "
2773 //=======================================================================
2774 //function : getShapesOnShapeIDs
2776 * \brief Find IDs of sub-shapes complying with given status about surface
2777 * \param theCheckShape - the shape to check state of sub-shapes against
2778 * \param theShape - the shape to explore
2779 * \param theShapeType - type of sub-shape of theShape
2780 * \param theState - required state
2781 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
2783 //=======================================================================
2784 Handle(TColStd_HSequenceOfInteger)
2785 GEOMImpl_IShapesOperations::getShapesOnShapeIDs
2786 (const Handle(GEOM_Object)& theCheckShape,
2787 const Handle(GEOM_Object)& theShape,
2788 const Standard_Integer theShapeType,
2789 GEOMAlgo_State theState)
2791 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
2793 TopoDS_Shape aCheckShape = theCheckShape->GetValue();
2794 TopoDS_Shape aShape = theShape->GetValue();
2795 TopTools_ListOfShape res;
2797 // Check presence of triangulation, build if need
2798 if (theShapeType != TopAbs_VERTEX && !GEOMUtils::CheckTriangulation(aShape)) {
2799 SetErrorCode("Cannot build triangulation on the shape");
2803 // Compute classification tolerance.
2804 TopTools_IndexedMapOfShape aMapVtx;
2805 Standard_Real aTol = Precision::Confusion();
2807 TopExp::MapShapes(aShape, TopAbs_VERTEX, aMapVtx);
2810 Standard_Integer aNbVtx = aMapVtx.Extent();
2812 for (i = 1; i <= aNbVtx; ++i) {
2813 const TopoDS_Vertex aVtx = TopoDS::Vertex(aMapVtx.FindKey(i));
2814 const Standard_Real aVtxTol = BRep_Tool::Tolerance(aVtx);
2816 if (aTol < aVtxTol) {
2821 // Bound the tolerance value.
2822 if (aTol > 0.0001) {
2827 GEOMAlgo_FinderShapeOn2 aFinder;
2829 Handle(GEOMAlgo_ClsfSolid) aClsfSolid = new GEOMAlgo_ClsfSolid;
2830 aClsfSolid->SetShape(aCheckShape);
2832 aFinder.SetShape(aShape);
2833 aFinder.SetTolerance(aTol);
2834 aFinder.SetClsf(aClsfSolid);
2835 aFinder.SetShapeType( (TopAbs_ShapeEnum)theShapeType );
2836 aFinder.SetState(theState);
2839 // Interprete results
2840 Standard_Integer iErr = aFinder.ErrorStatus();
2841 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn2.cxx
2844 SetErrorCode("theCheckShape must be a solid");
2847 MESSAGE(" iErr : " << iErr);
2848 TCollection_AsciiString aMsg (" iErr : ");
2849 aMsg += TCollection_AsciiString(iErr);
2854 Standard_Integer iWrn = aFinder.WarningStatus();
2855 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn2.cxx
2857 MESSAGE(" *** iWrn : " << iWrn);
2860 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
2862 if (listSS.Extent() < 1) {
2863 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
2864 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
2867 // Fill sequence of object IDs
2868 aSeqOfIDs = new TColStd_HSequenceOfInteger;
2870 TopTools_IndexedMapOfShape anIndices;
2871 TopExp::MapShapes(aShape, anIndices);
2873 TopTools_ListIteratorOfListOfShape itSub (listSS);
2874 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
2875 int id = anIndices.FindIndex(itSub.Value());
2876 aSeqOfIDs->Append(id);
2882 //=======================================================================
2883 //function : GetShapesOnShapeIDs
2885 * \brief Find sub-shapes complying with given status about surface
2886 * \param theCheckShape - the shape to check state of sub-shapes against
2887 * \param theShape - the shape to explore
2888 * \param theShapeType - type of sub-shape of theShape
2889 * \param theState - required state
2890 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
2892 //=======================================================================
2893 Handle(TColStd_HSequenceOfInteger)
2894 GEOMImpl_IShapesOperations::GetShapesOnShapeIDs
2895 (const Handle(GEOM_Object)& theCheckShape,
2896 const Handle(GEOM_Object)& theShape,
2897 const Standard_Integer theShapeType,
2898 GEOMAlgo_State theState)
2900 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2901 getShapesOnShapeIDs (theCheckShape, theShape, theShapeType, theState);
2903 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2906 // The GetShapesOnShape() doesn't change object so no new function is required.
2907 Handle(GEOM_Function) aFunction =
2908 GEOM::GetCreatedLast(theShape,theCheckShape)->GetLastFunction();
2910 // Make a Python command
2911 GEOM::TPythonDump(aFunction, /*append=*/true)
2912 << "listShapesOnBoxIDs = geompy.GetShapesOnShapeIDs("
2913 << theCheckShape << ", "
2915 << TopAbs_ShapeEnum(theShapeType) << ", "
2922 //=======================================================================
2923 //function : GetShapesOnShape
2925 * \brief Find sub-shapes complying with given status about surface
2926 * \param theCheckShape - the shape to check state of sub-shapes against
2927 * \param theShape - the shape to explore
2928 * \param theShapeType - type of sub-shape of theShape
2929 * \param theState - required state
2930 * \retval Handle(TColStd_HSequenceOfTransient) - found sub-shapes
2932 //=======================================================================
2933 Handle(TColStd_HSequenceOfTransient)
2934 GEOMImpl_IShapesOperations::GetShapesOnShape
2935 (const Handle(GEOM_Object)& theCheckShape,
2936 const Handle(GEOM_Object)& theShape,
2937 const Standard_Integer theShapeType,
2938 GEOMAlgo_State theState)
2940 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2941 getShapesOnShapeIDs (theCheckShape, theShape, theShapeType, theState);
2942 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2945 // Find objects by indices
2946 TCollection_AsciiString anAsciiList;
2947 Handle(TColStd_HSequenceOfTransient) aSeq;
2948 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
2950 if ( aSeq.IsNull() || aSeq->IsEmpty() )
2953 // Make a Python command
2955 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2956 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2958 GEOM::TPythonDump(aFunction)
2959 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnShape("
2960 << theCheckShape << ", "
2962 << TopAbs_ShapeEnum(theShapeType) << ", "
2969 //=======================================================================
2970 //function : GetShapesOnShapeAsCompound
2971 //=======================================================================
2972 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetShapesOnShapeAsCompound
2973 (const Handle(GEOM_Object)& theCheckShape,
2974 const Handle(GEOM_Object)& theShape,
2975 const Standard_Integer theShapeType,
2976 GEOMAlgo_State theState)
2978 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2979 getShapesOnShapeIDs (theCheckShape, theShape, theShapeType, theState);
2981 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2984 // Find objects by indices
2985 TCollection_AsciiString anAsciiList;
2986 Handle(TColStd_HSequenceOfTransient) aSeq;
2987 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
2989 if ( aSeq.IsNull() || aSeq->IsEmpty() )
2992 TopoDS_Compound aCompound;
2994 B.MakeCompound(aCompound);
2996 for(; i<=aSeq->Length(); i++) {
2997 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(aSeq->Value(i));
2998 TopoDS_Shape aShape_i = anObj->GetValue();
2999 B.Add(aCompound,aShape_i);
3002 //Add a new result object
3003 Handle(GEOM_Object) aRes = GetEngine()->AddObject(GetDocID(), GEOM_SHAPES_ON_SHAPE);
3004 Handle(GEOM_Function) aFunction =
3005 aRes->AddFunction(GEOMImpl_ShapeDriver::GetID(), SHAPES_ON_SHAPE);
3006 aFunction->SetValue(aCompound);
3009 aSeq->Append( theCheckShape->GetLastFunction() );
3010 aSeq->Append( theShape->GetLastFunction() );
3012 GEOMImpl_IShapes aCI( aFunction );
3013 aCI.SetShapes( aSeq );
3014 aCI.SetSubShapeType( theShapeType );
3015 aCI.SetTolerance( theState );
3017 GEOM::TPythonDump(aFunction)
3018 << aRes << " = geompy.GetShapesOnShapeAsCompound("
3019 << theCheckShape << ", "
3021 << TopAbs_ShapeEnum(theShapeType) << ", "
3029 //=============================================================================
3031 * GetSubShapeEdgeSorted
3033 //=============================================================================
3034 Handle(TColStd_HSequenceOfTransient)
3035 GEOMImpl_IShapesOperations::GetSubShapeEdgeSorted
3036 (const Handle(GEOM_Object) &theShape,
3037 const Handle(GEOM_Object) &theStartPoint)
3039 // Get the sorted edges indices.
3040 Handle(TColStd_HSequenceOfInteger) aSortedIDs =
3041 getSubShapeEdgeSortedIDs(theShape, theStartPoint);
3043 // Get object by indices.
3044 TCollection_AsciiString anAsciiList;
3045 Handle(TColStd_HSequenceOfTransient) aSeq =
3046 getObjectsShapesOn(theShape, aSortedIDs, anAsciiList);
3048 if (aSeq.IsNull() || aSeq->IsEmpty()) {
3049 SetErrorCode("Empty sequence of edges");
3053 // Make a Python command
3054 Handle(GEOM_Object) anObj =
3055 Handle(GEOM_Object)::DownCast(aSeq->Value(1));
3056 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
3058 GEOM::TPythonDump(aFunction)
3059 << "[" << anAsciiList.ToCString() << "] = geompy.GetSubShapeEdgeSorted("
3060 << theShape << ", " << theStartPoint << ")";
3067 //=============================================================================
3069 * GetSubShapesWithTolerance
3071 //=============================================================================
3072 Handle(TColStd_HSequenceOfTransient)
3073 GEOMImpl_IShapesOperations::GetSubShapesWithTolerance
3074 (const Handle(GEOM_Object) &theShape,
3075 const Standard_Integer theShapeType,
3076 const GEOMUtils::ComparisonCondition theCondition,
3077 const Standard_Real theTolerance)
3079 if (theShape.IsNull()) {
3080 SetErrorCode("NULL GEOM object");
3084 TopoDS_Shape aShape = theShape->GetValue();
3086 if (aShape.IsNull()) {
3087 SetErrorCode("NULL Shape");
3091 if (theShapeType != TopAbs_FACE && theShapeType != TopAbs_EDGE &&
3092 theShapeType != TopAbs_VERTEX && aShape.ShapeType() >= theShapeType) {
3093 SetErrorCode("Invalid shape type");
3097 TopTools_IndexedMapOfShape anIndices;
3098 TopTools_MapOfShape aMapFence;
3099 TopExp_Explorer anExp(aShape,
3100 (TopAbs_ShapeEnum) theShapeType);
3101 Handle(TColStd_HSequenceOfInteger) anIDs = new TColStd_HSequenceOfInteger;
3103 TopExp::MapShapes(aShape, anIndices);
3105 for (; anExp.More(); anExp.Next()) {
3106 const TopoDS_Shape &aSubShape = anExp.Current();
3108 if (aMapFence.Add(aSubShape)) {
3109 // Compute tolerance
3110 Standard_Real aTolerance = -1.;
3112 switch (aSubShape.ShapeType()) {
3114 aTolerance = BRep_Tool::Tolerance(TopoDS::Face(aSubShape));
3117 aTolerance = BRep_Tool::Tolerance(TopoDS::Edge(aSubShape));
3120 aTolerance = BRep_Tool::Tolerance(TopoDS::Vertex(aSubShape));
3126 if (aTolerance < 0.) {
3130 // Compare the tolerance with reference value.
3131 if (GEOMUtils::IsFitCondition (theCondition, aTolerance, theTolerance)) {
3132 anIDs->Append(anIndices.FindIndex(aSubShape));
3137 if (anIDs->IsEmpty()) {
3138 SetErrorCode("Empty sequence of sub-shapes");
3142 // Get objects by indices.
3143 TCollection_AsciiString anAsciiList;
3144 Handle(TColStd_HSequenceOfTransient) aSeq =
3145 getObjectsShapesOn(theShape, anIDs, anAsciiList);
3147 if (aSeq.IsNull() || aSeq->IsEmpty()) {
3148 SetErrorCode("Empty sequence of edges");
3152 // Make a Python command
3153 Handle(GEOM_Object) anObj =
3154 Handle(GEOM_Object)::DownCast(aSeq->Value(1));
3155 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
3157 GEOM::TPythonDump(aFunction)
3158 << "[" << anAsciiList.ToCString() << "] = geompy.GetSubShapesWithTolerance("
3159 << theShape << ", " << theShapeType << ", " << theCondition << ", "
3160 << theTolerance << ")";
3167 //=============================================================================
3171 //=============================================================================
3172 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeExtraction
3173 (const Handle(GEOM_Object) &theShape,
3174 const Handle(TColStd_HArray1OfInteger) &theSubShapeIDs,
3175 std::list<ExtractionStat> &theStats)
3179 if (theShape.IsNull()) {
3183 //Add a new Result object
3184 Handle(GEOM_Object) aResult =
3185 GetEngine()->AddObject(GetDocID(), GEOM_EXTRACTION);
3187 //Add a new Extraction function
3188 Handle(GEOM_Function) aFunction =
3189 aResult->AddFunction(GEOMImpl_ShapeDriver::GetID(), EXTRACTION);
3191 //Check if the function is set correctly
3192 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) {
3196 Handle(GEOM_Function) aShape = theShape->GetLastFunction();
3198 if (aShape.IsNull()) {
3202 GEOMImpl_IExtract aCI (aFunction);
3204 aCI.SetShape(aShape);
3205 aCI.SetSubShapeIDs(theSubShapeIDs);
3207 //Compute the Edge value
3210 if (!GetSolver()->ComputeFunction(aFunction)) {
3211 SetErrorCode("Shape driver failed");
3216 catch (Standard_Failure) {
3217 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
3218 SetErrorCode(aFail->GetMessageString());
3223 // Fill in statistics.
3226 Handle(TColStd_HArray1OfInteger) aStatIDsArray[3] =
3227 { aCI.GetRemovedIDs(), aCI.GetModifiedIDs(), aCI.GetAddedIDs() };
3231 for (j = 0; j < 3; ++j) {
3232 if (!aStatIDsArray[j].IsNull()) {
3233 const int anUpperID = aStatIDsArray[j]->Upper();
3234 ExtractionStat aStat;
3236 for (i = aStatIDsArray[j]->Lower(); i <= anUpperID; ++i) {
3237 aStat.indices.push_back(aStatIDsArray[j]->Value(i));
3240 aStat.type = (ExtractionStatType) j;
3241 theStats.push_back(aStat);
3245 //Make a Python command
3246 GEOM::TPythonDump pd(aFunction);
3248 pd << aResult << " = geompy.MakeExtraction(" << theShape << ", [";
3250 if (!theSubShapeIDs.IsNull()) {
3251 const int aNbIDs = theSubShapeIDs->Upper();
3253 for (i = theSubShapeIDs->Lower(); i < aNbIDs; ++i) {
3254 pd << theSubShapeIDs->Value(i) << ", ";
3257 // Dump the last value without a comma.
3258 pd << theSubShapeIDs->Value(i);
3268 //=======================================================================
3269 //function : getShapesOnSurfaceIDs
3271 * \brief Find IDs of sub-shapes complying with given status about surface
3272 * \param theSurface - the surface to check state of sub-shapes against
3273 * \param theShape - the shape to explore
3274 * \param theShapeType - type of sub-shape of theShape
3275 * \param theState - required state
3276 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
3278 //=======================================================================
3279 Handle(TColStd_HSequenceOfInteger)
3280 GEOMImpl_IShapesOperations::getShapesOnSurfaceIDs(const Handle(Geom_Surface)& theSurface,
3281 const TopoDS_Shape& theShape,
3282 TopAbs_ShapeEnum theShapeType,
3283 GEOMAlgo_State theState)
3285 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
3287 // Check presence of triangulation, build if need
3288 if (theShapeType != TopAbs_VERTEX &&
3289 !GEOMUtils::CheckTriangulation(theShape)) {
3290 SetErrorCode("Cannot build triangulation on the shape");
3294 // BEGIN: Mantis issue 0020961: Error on a pipe T-Shape
3295 // Compute tolerance
3296 Standard_Real T, VertMax = -RealLast();
3299 for (TopExp_Explorer ExV (theShape, TopAbs_VERTEX); ExV.More(); ExV.Next()) {
3300 TopoDS_Vertex Vertex = TopoDS::Vertex(ExV.Current());
3301 T = BRep_Tool::Tolerance(Vertex);
3306 catch (Standard_Failure) {
3307 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
3308 SetErrorCode(aFail->GetMessageString());
3311 // END: Mantis issue 0020961
3314 GEOMAlgo_FinderShapeOn2 aFinder;
3315 Handle(GEOMAlgo_ClsfSurf) aClsfSurf = new GEOMAlgo_ClsfSurf;
3316 Standard_Real aTol = VertMax; // Mantis issue 0020961
3318 aClsfSurf->SetSurface(theSurface);
3319 aFinder.SetShape(theShape);
3320 aFinder.SetTolerance(aTol);
3321 aFinder.SetClsf(aClsfSurf);
3322 aFinder.SetShapeType(theShapeType);
3323 aFinder.SetState(theState);
3325 // Sets the minimal number of inner points for the faces that do not have own
3326 // inner points at all (for e.g. rectangular planar faces have just 2 triangles).
3328 aFinder.SetNbPntsMin(3);
3329 // Sets the maximal number of inner points for edges or faces.
3330 // It is usefull for the cases when this number is very big (e.g =2000) to improve
3331 // the performance. If this value =0, all inner points will be taken into account.
3333 aFinder.SetNbPntsMax(100);
3337 // Interprete results
3338 Standard_Integer iErr = aFinder.ErrorStatus();
3339 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn2.cxx
3341 MESSAGE(" iErr : " << iErr);
3342 TCollection_AsciiString aMsg (" iErr : ");
3343 aMsg += TCollection_AsciiString(iErr);
3347 Standard_Integer iWrn = aFinder.WarningStatus();
3348 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn2.cxx
3350 MESSAGE(" *** iWrn : " << iWrn);
3353 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
3355 if (listSS.Extent() < 1) {
3356 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
3357 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
3361 // Fill sequence of object IDs
3362 aSeqOfIDs = new TColStd_HSequenceOfInteger;
3364 TopTools_IndexedMapOfShape anIndices;
3365 TopExp::MapShapes(theShape, anIndices);
3367 TopTools_ListIteratorOfListOfShape itSub (listSS);
3368 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
3369 int id = anIndices.FindIndex(itSub.Value());
3370 aSeqOfIDs->Append(id);
3376 //=======================================================================
3377 //function : getObjectsShapesOn
3379 * \brief Find shape objects and their entries by their ids
3380 * \param theShapeIDs - incoming shape ids
3381 * \param theShapeEntries - outgoing entries like "entry1, entry2, ..."
3382 * \retval Handle(TColStd_HSequenceOfTransient) - found shape objects
3384 //=======================================================================
3385 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::
3386 getObjectsShapesOn(const Handle(GEOM_Object)& theShape,
3387 const Handle(TColStd_HSequenceOfInteger)& theShapeIDs,
3388 TCollection_AsciiString & theShapeEntries)
3390 Handle(TColStd_HSequenceOfTransient) aSeq;
3392 if ( !theShapeIDs.IsNull() && theShapeIDs->Length() > 0 )
3394 aSeq = new TColStd_HSequenceOfTransient;
3395 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
3396 TCollection_AsciiString anEntry;
3397 for ( int i = 1; i <= theShapeIDs->Length(); ++i )
3399 anArray->SetValue(1, theShapeIDs->Value( i ));
3400 Handle(GEOM_Object) anObj = GetEngine()->AddSubShape(theShape, anArray);
3401 aSeq->Append( anObj );
3403 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
3404 if ( i != 1 ) theShapeEntries += ",";
3405 theShapeEntries += anEntry;
3411 //=============================================================================
3413 * getSubShapeEdgeSortedIDs
3415 //=============================================================================
3416 Handle(TColStd_HSequenceOfInteger)
3417 GEOMImpl_IShapesOperations::getSubShapeEdgeSortedIDs
3418 (const Handle(GEOM_Object) &theShape,
3419 const Handle(GEOM_Object) &theStartPoint)
3421 Handle(TColStd_HSequenceOfInteger) aResult;
3423 if (theShape.IsNull() || theStartPoint.IsNull()) {
3424 SetErrorCode("NULL GEOM object");
3428 const TopoDS_Shape aShape = theShape->GetValue();
3429 const TopoDS_Shape aStartPoint = theStartPoint->GetValue();
3431 if (aShape.IsNull() || aStartPoint.IsNull()) {
3432 SetErrorCode("NULL Shape");
3436 if (aStartPoint.ShapeType() != TopAbs_VERTEX) {
3437 SetErrorCode("Starting point is not a vertex");
3441 TopExp_Explorer anExp(aShape, TopAbs_EDGE);
3442 TopTools_MapOfShape aMapFence;
3443 TopTools_ListOfShape anEdges;
3445 for (; anExp.More(); anExp.Next()) {
3446 const TopoDS_Shape &anEdge = anExp.Current();
3448 if (aMapFence.Add(anEdge)) {
3449 anEdges.Append(anEdge);
3453 if (anEdges.IsEmpty()) {
3454 SetErrorCode("Shape doesn't contain edges");
3458 // Step 1: Sort edges
3459 GEOMUtils::SortShapes(anEdges, Standard_False);
3461 TopTools_ListIteratorOfListOfShape anIter(anEdges);
3462 TopoDS_Vertex aV[2];
3463 TopTools_DataMapOfShapeListOfShape aMapVE;
3465 // Step 2: Fill the map vertex - list of edges.
3466 for (; anIter.More(); anIter.Next()) {
3467 TopoDS_Edge anEdge = TopoDS::Edge(anIter.Value());
3469 TopExp::Vertices(anEdge, aV[0], aV[1]);
3471 const Standard_Integer aNbV = aV[0].IsSame(aV[1]) ? 1 : 2;
3474 for (i = 0; i < aNbV; ++i) {
3475 if (aV[i].IsNull() == Standard_False) {
3476 if (!aMapVE.IsBound(aV[i])) {
3477 // There is no this vertex in the map.
3478 aMapVE.Bind(aV[i], TopTools_ListOfShape());
3481 // Add the edge to the list bound with the vertex aV[i].
3482 TopTools_ListOfShape &aLEdges = aMapVE.ChangeFind(aV[i]);
3484 aLEdges.Append(anEdge);
3489 // Step 3: Find starting point in aMapVE.
3490 TopoDS_Vertex aStartVtx = TopoDS::Vertex(aStartPoint);
3492 if (!aMapVE.IsBound(aStartVtx)) {
3493 aStartVtx = getSameVertex(aShape, aStartVtx);
3495 if (aStartVtx.IsNull()) {
3496 SetErrorCode("Invalid Starting point");
3501 TopTools_IndexedMapOfShape anIndices;
3502 TopTools_MapOfShape aMapVFence;
3503 TopoDS_Shape aCurVtx = aStartVtx;
3504 TopoDS_Edge aCurEdge =
3505 TopoDS::Edge(aMapVE.Find(aCurVtx).First());
3507 aResult = new TColStd_HSequenceOfInteger;
3508 TopExp::MapShapes(aShape, anIndices);
3510 // Step 4: Fill the list of sorted edges.
3511 while (aMapVFence.Add(aCurVtx)) {
3512 // Append the ID of the current edge to the list of sorted.
3513 aResult->Append(anIndices.FindIndex(aCurEdge));
3514 TopExp::Vertices(aCurEdge, aV[0], aV[1]);
3516 // Get the next vertex.
3517 if (aCurVtx.IsSame(aV[0])) {
3518 if (aCurVtx.IsSame(aV[1])) {
3519 // There is no next vertex.
3528 if (aCurVtx.IsNull()) {
3529 // There is no next vertex.
3533 // Get the next edge.
3534 const TopTools_ListOfShape &aLEdges = aMapVE.Find(aCurVtx);
3535 TopTools_ListIteratorOfListOfShape anEIter(aLEdges);
3537 for (; anEIter.More(); anEIter.Next()) {
3538 const TopoDS_Shape &aLocalEdge = anEIter.Value();
3540 if (aLocalEdge.IsNull() == Standard_False) {
3541 if (!aCurEdge.IsSame(aLocalEdge)) {
3542 aCurEdge = TopoDS::Edge(aLocalEdge);
3548 if (!anEIter.More()) {
3549 // There is no next edge.
3557 //=======================================================================
3558 //function : getShapesOnSurface
3560 * \brief Find sub-shapes complying with given status about surface
3561 * \param theSurface - the surface to check state of sub-shapes against
3562 * \param theShape - the shape to explore
3563 * \param theShapeType - type of sub-shape of theShape
3564 * \param theState - required state
3565 * \param theShapeEntries - outgoing entries like "entry1, entry2, ..."
3566 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
3568 //=======================================================================
3569 Handle(TColStd_HSequenceOfTransient)
3570 GEOMImpl_IShapesOperations::getShapesOnSurface(const Handle(Geom_Surface)& theSurface,
3571 const Handle(GEOM_Object)& theShape,
3572 TopAbs_ShapeEnum theShapeType,
3573 GEOMAlgo_State theState,
3574 TCollection_AsciiString & theShapeEntries)
3576 // Find sub-shapes ids
3577 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
3578 getShapesOnSurfaceIDs (theSurface, theShape->GetValue(), theShapeType, theState);
3579 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
3582 return getObjectsShapesOn( theShape, aSeqOfIDs, theShapeEntries );
3585 //=============================================================================
3589 //=============================================================================
3590 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnPlane
3591 (const Handle(GEOM_Object)& theShape,
3592 const Standard_Integer theShapeType,
3593 const Handle(GEOM_Object)& theAx1,
3594 const GEOMAlgo_State theState)
3598 if (theShape.IsNull() || theAx1.IsNull()) return NULL;
3600 TopoDS_Shape aShape = theShape->GetValue();
3601 TopoDS_Shape anAx1 = theAx1->GetValue();
3603 if (aShape.IsNull() || anAx1.IsNull()) return NULL;
3605 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3606 if ( !checkTypeShapesOn( theShapeType ))
3610 Handle(Geom_Surface) aPlane = makePlane( anAx1 );
3611 if ( aPlane.IsNull() )
3615 TCollection_AsciiString anAsciiList;
3616 Handle(TColStd_HSequenceOfTransient) aSeq;
3617 aSeq = getShapesOnSurface( aPlane, theShape, aShapeType, theState, anAsciiList );
3618 if ( aSeq.IsNull() || aSeq->Length() == 0 )
3621 // Make a Python command
3623 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
3624 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
3626 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
3627 << "] = geompy.GetShapesOnPlane(" << theShape << ", "
3628 << aShapeType << ", " << theAx1 << ", " << theState << ")";
3634 //=============================================================================
3636 * GetShapesOnPlaneWithLocation
3638 //=============================================================================
3639 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnPlaneWithLocation
3640 (const Handle(GEOM_Object)& theShape,
3641 const Standard_Integer theShapeType,
3642 const Handle(GEOM_Object)& theAx1,
3643 const Handle(GEOM_Object)& thePnt,
3644 const GEOMAlgo_State theState)
3648 if (theShape.IsNull() || theAx1.IsNull() || thePnt.IsNull()) return NULL;
3650 TopoDS_Shape aShape = theShape->GetValue();
3651 TopoDS_Shape anAx1 = theAx1->GetValue();
3652 TopoDS_Shape anPnt = thePnt->GetValue();
3654 if (aShape.IsNull() || anAx1.IsNull() || anPnt.IsNull()) return NULL;
3656 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3657 if ( !checkTypeShapesOn( theShapeType ))
3661 if ( anAx1.ShapeType() != TopAbs_EDGE || anPnt.ShapeType() != TopAbs_VERTEX ) return NULL;
3662 TopoDS_Vertex V1, V2, V3;
3663 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
3664 TopExp::Vertices(anEdge, V1, V2, Standard_True);
3666 if (V1.IsNull() || V2.IsNull()) {
3667 SetErrorCode("Bad edge given for the plane normal vector");
3670 V3 = TopoDS::Vertex(anPnt);
3673 SetErrorCode("Bad vertex given for the plane location");
3676 gp_Pnt aLoc = BRep_Tool::Pnt(V3);
3677 gp_Vec aVec(BRep_Tool::Pnt(V1),BRep_Tool::Pnt(V2));
3679 if (aVec.Magnitude() < Precision::Confusion()) {
3680 SetErrorCode("Vector with null magnitude given");
3683 Handle(Geom_Surface) aPlane = new Geom_Plane(aLoc, aVec);
3685 if ( aPlane.IsNull() )
3689 TCollection_AsciiString anAsciiList;
3690 Handle(TColStd_HSequenceOfTransient) aSeq;
3691 aSeq = getShapesOnSurface( aPlane, theShape, aShapeType, theState, anAsciiList );
3692 if ( aSeq.IsNull() || aSeq->Length() == 0 )
3695 // Make a Python command
3697 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
3698 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
3700 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
3701 << "] = geompy.GetShapesOnPlaneWithLocation(" << theShape << ", "
3702 << aShapeType << ", " << theAx1 << ", "<< thePnt <<", " << theState << ")";
3708 //=============================================================================
3710 * GetShapesOnCylinder
3712 //=============================================================================
3713 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnCylinder
3714 (const Handle(GEOM_Object)& theShape,
3715 const Standard_Integer theShapeType,
3716 const Handle(GEOM_Object)& theAxis,
3717 const Standard_Real theRadius,
3718 const GEOMAlgo_State theState)
3722 if (theShape.IsNull() || theAxis.IsNull()) return NULL;
3724 TopoDS_Shape aShape = theShape->GetValue();
3725 TopoDS_Shape anAxis = theAxis->GetValue();
3727 if (aShape.IsNull() || anAxis.IsNull()) return NULL;
3729 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3730 if ( !checkTypeShapesOn( aShapeType ))
3733 // Create a cylinder surface
3734 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
3735 if ( aCylinder.IsNull() )
3739 TCollection_AsciiString anAsciiList;
3740 Handle(TColStd_HSequenceOfTransient) aSeq;
3741 aSeq = getShapesOnSurface( aCylinder, theShape, aShapeType, theState, anAsciiList );
3742 if ( aSeq.IsNull() || aSeq->Length() == 0 )
3745 // Make a Python command
3747 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
3748 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
3750 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
3751 << "] = geompy.GetShapesOnCylinder(" << theShape << ", " << aShapeType
3752 << ", " << theAxis << ", " << theRadius << ", " << theState << ")";
3758 //=============================================================================
3760 * GetShapesOnCylinderWithLocation
3762 //=============================================================================
3763 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnCylinderWithLocation
3764 (const Handle(GEOM_Object)& theShape,
3765 const Standard_Integer theShapeType,
3766 const Handle(GEOM_Object)& theAxis,
3767 const Handle(GEOM_Object)& thePnt,
3768 const Standard_Real theRadius,
3769 const GEOMAlgo_State theState)
3773 if (theShape.IsNull() || theAxis.IsNull() || thePnt.IsNull()) return NULL;
3775 TopoDS_Shape aShape = theShape->GetValue();
3776 TopoDS_Shape anAxis = theAxis->GetValue();
3777 TopoDS_Shape aPnt = thePnt->GetValue();
3779 if (aShape.IsNull() || anAxis.IsNull() || aPnt.IsNull()) return NULL;
3781 if (aPnt.ShapeType() != TopAbs_VERTEX )
3783 SetErrorCode("Bottom location point must be vertex");
3787 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3788 if ( !checkTypeShapesOn( aShapeType ))
3791 // Create a cylinder surface
3792 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
3793 if ( aCylinder.IsNull() )
3796 // translate the surface
3797 Handle(Geom_CylindricalSurface) aCylSurface =
3798 Handle(Geom_CylindricalSurface)::DownCast( aCylinder );
3799 if ( aCylSurface.IsNull() )
3801 SetErrorCode("Unexpected surface type instead of Geom_CylindricalSurface");
3804 gp_Pnt fromLoc = aCylSurface->Cylinder().Location();
3805 gp_Pnt toLoc = BRep_Tool::Pnt( TopoDS::Vertex( aPnt ));
3806 aCylinder->Translate( fromLoc, toLoc );
3809 TCollection_AsciiString anAsciiList;
3810 Handle(TColStd_HSequenceOfTransient) aSeq;
3811 aSeq = getShapesOnSurface( aCylinder, theShape, aShapeType, theState, anAsciiList );
3812 if ( aSeq.IsNull() || aSeq->Length() == 0 )
3815 // Make a Python command
3817 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
3818 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
3820 GEOM::TPythonDump(aFunction)
3821 << "[" << anAsciiList.ToCString()
3822 << "] = geompy.GetShapesOnCylinderWithLocation(" << theShape << ", " << aShapeType << ", "
3823 << theAxis << ", " << thePnt << ", " << theRadius << ", " << theState << ")";
3829 //=============================================================================
3833 //=============================================================================
3834 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnSphere
3835 (const Handle(GEOM_Object)& theShape,
3836 const Standard_Integer theShapeType,
3837 const Handle(GEOM_Object)& theCenter,
3838 const Standard_Real theRadius,
3839 const GEOMAlgo_State theState)
3843 if (theShape.IsNull() || theCenter.IsNull()) return NULL;
3845 TopoDS_Shape aShape = theShape->GetValue();
3846 TopoDS_Shape aCenter = theCenter->GetValue();
3848 if (aShape.IsNull() || aCenter.IsNull()) return NULL;
3850 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3851 if ( !checkTypeShapesOn( aShapeType ))
3854 // Center of the sphere
3855 if (aCenter.ShapeType() != TopAbs_VERTEX) return NULL;
3856 gp_Pnt aLoc = BRep_Tool::Pnt(TopoDS::Vertex(aCenter));
3858 gp_Ax3 anAx3 (aLoc, gp::DZ());
3859 Handle(Geom_SphericalSurface) aSphere =
3860 new Geom_SphericalSurface(anAx3, theRadius);
3863 TCollection_AsciiString anAsciiList;
3864 Handle(TColStd_HSequenceOfTransient) aSeq;
3865 aSeq = getShapesOnSurface( aSphere, theShape, aShapeType, theState, anAsciiList );
3866 if ( aSeq.IsNull() || aSeq->Length() == 0 )
3869 // Make a Python command
3871 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
3872 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
3874 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
3875 << "] = geompy.GetShapesOnSphere(" << theShape << ", " << aShapeType
3876 << ", " << theCenter << ", " << theRadius << ", " << theState << ")";
3882 //=============================================================================
3884 * GetShapesOnPlaneIDs
3886 //=============================================================================
3887 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnPlaneIDs
3888 (const Handle(GEOM_Object)& theShape,
3889 const Standard_Integer theShapeType,
3890 const Handle(GEOM_Object)& theAx1,
3891 const GEOMAlgo_State theState)
3895 if (theShape.IsNull() || theAx1.IsNull()) return NULL;
3897 TopoDS_Shape aShape = theShape->GetValue();
3898 TopoDS_Shape anAx1 = theAx1->GetValue();
3900 if (aShape.IsNull() || anAx1.IsNull()) return NULL;
3902 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3903 if ( !checkTypeShapesOn( aShapeType ))
3907 Handle(Geom_Surface) aPlane = makePlane( anAx1 );
3908 if ( aPlane.IsNull() )
3912 Handle(TColStd_HSequenceOfInteger) aSeq;
3913 aSeq = getShapesOnSurfaceIDs( aPlane, aShape, aShapeType, theState );
3915 // The GetShapesOnPlaneIDs() doesn't change object so no new function is required.
3916 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAx1)->GetLastFunction();
3918 // Make a Python command
3919 GEOM::TPythonDump(aFunction, /*append=*/true)
3920 << "listShapesOnPlane = geompy.GetShapesOnPlaneIDs"
3921 << "(" << theShape << "," << aShapeType << "," << theAx1 << "," << theState << ")";
3927 //=============================================================================
3929 * GetShapesOnPlaneWithLocationIDs
3931 //=============================================================================
3932 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnPlaneWithLocationIDs
3933 (const Handle(GEOM_Object)& theShape,
3934 const Standard_Integer theShapeType,
3935 const Handle(GEOM_Object)& theAx1,
3936 const Handle(GEOM_Object)& thePnt,
3937 const GEOMAlgo_State theState)
3941 if (theShape.IsNull() || theAx1.IsNull() || thePnt.IsNull()) return NULL;
3943 TopoDS_Shape aShape = theShape->GetValue();
3944 TopoDS_Shape anAx1 = theAx1->GetValue();
3945 TopoDS_Shape anPnt = thePnt->GetValue();
3947 if (aShape.IsNull() || anAx1.IsNull() || anPnt.IsNull()) return NULL;
3949 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3950 if ( !checkTypeShapesOn( aShapeType ))
3954 if (anAx1.ShapeType() != TopAbs_EDGE || anPnt.ShapeType() != TopAbs_VERTEX) return NULL;
3955 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
3956 TopoDS_Vertex V1, V2, V3;
3957 TopExp::Vertices(anEdge, V1, V2, Standard_True);
3958 if (V1.IsNull() || V2.IsNull()) {
3959 SetErrorCode("Bad edge given for the plane normal vector");
3962 V3 = TopoDS::Vertex(anPnt);
3964 SetErrorCode("Bad vertex given for the plane location");
3967 gp_Pnt aLoc = BRep_Tool::Pnt(V3);
3968 gp_Vec aVec(BRep_Tool::Pnt(V1),BRep_Tool::Pnt(V2));
3969 if (aVec.Magnitude() < Precision::Confusion()) {
3970 SetErrorCode("Vector with null magnitude given");
3974 Handle(Geom_Surface) aPlane = new Geom_Plane(aLoc, aVec);
3975 if ( aPlane.IsNull() )
3979 Handle(TColStd_HSequenceOfInteger) aSeq;
3980 aSeq = getShapesOnSurfaceIDs( aPlane, aShape, aShapeType, theState );
3982 // The GetShapesOnPlaneIDs() doesn't change object so no new function is required.
3983 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAx1)->GetLastFunction();
3985 // Make a Python command
3986 GEOM::TPythonDump(aFunction, /*append=*/true)
3987 << "listShapesOnPlane = geompy.GetShapesOnPlaneWithLocationIDs"
3988 << "(" << theShape << ", " << aShapeType << ", " << theAx1 << ", "<< thePnt << ", " << theState << ")";
3994 //=============================================================================
3996 * GetShapesOnCylinderIDs
3998 //=============================================================================
3999 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnCylinderIDs
4000 (const Handle(GEOM_Object)& theShape,
4001 const Standard_Integer theShapeType,
4002 const Handle(GEOM_Object)& theAxis,
4003 const Standard_Real theRadius,
4004 const GEOMAlgo_State theState)
4008 if (theShape.IsNull() || theAxis.IsNull()) return NULL;
4010 TopoDS_Shape aShape = theShape->GetValue();
4011 TopoDS_Shape anAxis = theAxis->GetValue();
4013 if (aShape.IsNull() || anAxis.IsNull()) return NULL;
4015 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
4016 if ( !checkTypeShapesOn( aShapeType ))
4019 // Create a cylinder surface
4020 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
4021 if ( aCylinder.IsNull() )
4025 Handle(TColStd_HSequenceOfInteger) aSeq;
4026 aSeq = getShapesOnSurfaceIDs( aCylinder, aShape, aShapeType, theState );
4028 // The GetShapesOnCylinder() doesn't change object so no new function is required.
4029 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAxis)->GetLastFunction();
4031 // Make a Python command
4032 GEOM::TPythonDump(aFunction, /*append=*/true)
4033 << "listShapesOnCylinder = geompy.GetShapesOnCylinderIDs"
4034 << "(" << theShape << ", " << aShapeType << ", " << theAxis << ", "
4035 << theRadius << ", " << theState << ")";
4041 //=============================================================================
4043 * GetShapesOnCylinderWithLocationIDs
4045 //=============================================================================
4046 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnCylinderWithLocationIDs
4047 (const Handle(GEOM_Object)& theShape,
4048 const Standard_Integer theShapeType,
4049 const Handle(GEOM_Object)& theAxis,
4050 const Handle(GEOM_Object)& thePnt,
4051 const Standard_Real theRadius,
4052 const GEOMAlgo_State theState)
4056 if (theShape.IsNull() || theAxis.IsNull() || thePnt.IsNull()) return NULL;
4058 TopoDS_Shape aShape = theShape->GetValue();
4059 TopoDS_Shape anAxis = theAxis->GetValue();
4060 TopoDS_Shape aPnt = thePnt->GetValue();
4062 if (aShape.IsNull() || anAxis.IsNull() || aPnt.IsNull()) return NULL;
4064 if (aPnt.ShapeType() != TopAbs_VERTEX )
4066 SetErrorCode("Bottom location point must be vertex");
4070 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
4071 if ( !checkTypeShapesOn( aShapeType ))
4074 // Create a cylinder surface
4075 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
4076 if ( aCylinder.IsNull() )
4079 // translate the surface
4080 Handle(Geom_CylindricalSurface) aCylSurface =
4081 Handle(Geom_CylindricalSurface)::DownCast( aCylinder );
4082 if ( aCylSurface.IsNull() )
4084 SetErrorCode("Unexpected surface type instead of Geom_CylindricalSurface");
4087 gp_Pnt fromLoc = aCylSurface->Cylinder().Location();
4088 gp_Pnt toLoc = BRep_Tool::Pnt( TopoDS::Vertex( aPnt ));
4089 aCylinder->Translate( fromLoc, toLoc );
4092 Handle(TColStd_HSequenceOfInteger) aSeq;
4093 aSeq = getShapesOnSurfaceIDs( aCylinder, aShape, aShapeType, theState );
4095 // The GetShapesOnCylinder() doesn't change object so no new function is required.
4096 Handle(GEOM_Function) aFunction =
4097 GEOM::GetCreatedLast(theShape, GEOM::GetCreatedLast(thePnt,theAxis))->GetLastFunction();
4099 // Make a Python command
4100 GEOM::TPythonDump(aFunction, /*append=*/true)
4101 << "listShapesOnCylinder = geompy.GetShapesOnCylinderWithLocationIDs"
4102 << "(" << theShape << ", " << aShapeType << ", " << theAxis << ", "
4103 << thePnt << ", " << theRadius << ", " << theState << ")";
4109 //=============================================================================
4111 * GetShapesOnSphereIDs
4113 //=============================================================================
4114 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnSphereIDs
4115 (const Handle(GEOM_Object)& theShape,
4116 const Standard_Integer theShapeType,
4117 const Handle(GEOM_Object)& theCenter,
4118 const Standard_Real theRadius,
4119 const GEOMAlgo_State theState)
4123 if (theShape.IsNull() || theCenter.IsNull()) return NULL;
4125 TopoDS_Shape aShape = theShape->GetValue();
4126 TopoDS_Shape aCenter = theCenter->GetValue();
4128 if (aShape.IsNull() || aCenter.IsNull()) return NULL;
4130 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
4131 if ( !checkTypeShapesOn( aShapeType ))
4134 // Center of the sphere
4135 if (aCenter.ShapeType() != TopAbs_VERTEX) return NULL;
4136 gp_Pnt aLoc = BRep_Tool::Pnt(TopoDS::Vertex(aCenter));
4138 gp_Ax3 anAx3 (aLoc, gp::DZ());
4139 Handle(Geom_SphericalSurface) aSphere =
4140 new Geom_SphericalSurface(anAx3, theRadius);
4143 Handle(TColStd_HSequenceOfInteger) aSeq;
4144 aSeq = getShapesOnSurfaceIDs( aSphere, aShape, aShapeType, theState );
4146 // The GetShapesOnSphere() doesn't change object so no new function is required.
4147 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theCenter)->GetLastFunction();
4149 // Make a Python command
4150 GEOM::TPythonDump(aFunction, /*append=*/true)
4151 << "listShapesOnCylinder = geompy.GetShapesOnSphereIDs"
4152 << "(" << theShape << ", " << aShapeType << ", " << theCenter << ", "
4153 << theRadius << ", " << theState << ")";
4159 //=======================================================================
4160 //function : getShapesOnQuadrangleIDs
4162 * \brief Find IDs of sub-shapes complying with given status about quadrangle
4163 * \param theShape - the shape to explore
4164 * \param theShapeType - type of sub-shape of theShape
4165 * \param theTopLeftPoint - top left quadrangle corner
4166 * \param theTopRigthPoint - top right quadrangle corner
4167 * \param theBottomLeftPoint - bottom left quadrangle corner
4168 * \param theBottomRigthPoint - bottom right quadrangle corner
4169 * \param theState - required state
4170 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
4172 //=======================================================================
4173 Handle(TColStd_HSequenceOfInteger)
4174 GEOMImpl_IShapesOperations::getShapesOnQuadrangleIDs (const Handle(GEOM_Object)& theShape,
4175 const Standard_Integer theShapeType,
4176 const Handle(GEOM_Object)& theTopLeftPoint,
4177 const Handle(GEOM_Object)& theTopRigthPoint,
4178 const Handle(GEOM_Object)& theBottomLeftPoint,
4179 const Handle(GEOM_Object)& theBottomRigthPoint,
4180 const GEOMAlgo_State theState)
4184 if ( theShape.IsNull() ||
4185 theTopLeftPoint.IsNull() ||
4186 theTopRigthPoint.IsNull() ||
4187 theBottomLeftPoint.IsNull() ||
4188 theBottomRigthPoint.IsNull() )
4191 TopoDS_Shape aShape = theShape->GetValue();
4192 TopoDS_Shape aTL = theTopLeftPoint->GetValue();
4193 TopoDS_Shape aTR = theTopRigthPoint->GetValue();
4194 TopoDS_Shape aBL = theBottomLeftPoint->GetValue();
4195 TopoDS_Shape aBR = theBottomRigthPoint->GetValue();
4197 if (aShape.IsNull() ||
4202 aTL.ShapeType() != TopAbs_VERTEX ||
4203 aTR.ShapeType() != TopAbs_VERTEX ||
4204 aBL.ShapeType() != TopAbs_VERTEX ||
4205 aBR.ShapeType() != TopAbs_VERTEX )
4208 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
4209 if ( !checkTypeShapesOn( aShapeType ))
4212 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
4214 // Check presence of triangulation, build if need
4215 if (theShapeType != TopAbs_VERTEX && !GEOMUtils::CheckTriangulation(aShape)) {
4216 SetErrorCode("Cannot build triangulation on the shape");
4221 gp_Pnt aPntTL = BRep_Tool::Pnt(TopoDS::Vertex(aTL));
4222 gp_Pnt aPntTR = BRep_Tool::Pnt(TopoDS::Vertex(aTR));
4223 gp_Pnt aPntBL = BRep_Tool::Pnt(TopoDS::Vertex(aBL));
4224 gp_Pnt aPntBR = BRep_Tool::Pnt(TopoDS::Vertex(aBR));
4226 GEOMAlgo_FinderShapeOn2 aFinder;
4227 Handle(GEOMAlgo_ClsfQuad) aClsfQuad = new GEOMAlgo_ClsfQuad;
4229 Standard_Real aTol = 0.0001; // default value
4231 aClsfQuad->SetCorners(aPntTL, aPntTR, aPntBL, aPntBR);
4232 aFinder.SetShape(aShape);
4233 aFinder.SetTolerance(aTol);
4234 aFinder.SetClsf(aClsfQuad);
4235 aFinder.SetShapeType(aShapeType);
4236 aFinder.SetState(theState);
4238 // Sets the minimal number of inner points for the faces that do not have own
4239 // inner points at all (for e.g. rectangular planar faces have just 2 triangles).
4241 aFinder.SetNbPntsMin(3);
4242 // Sets the maximal number of inner points for edges or faces.
4243 // It is usefull for the cases when this number is very big (e.g =2000) to improve
4244 // the performance. If this value =0, all inner points will be taken into account.
4246 aFinder.SetNbPntsMax(100);
4250 // Interprete results
4251 Standard_Integer iErr = aFinder.ErrorStatus();
4252 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn2.cxx
4254 MESSAGE(" iErr : " << iErr);
4255 TCollection_AsciiString aMsg (" iErr : ");
4256 aMsg += TCollection_AsciiString(iErr);
4260 Standard_Integer iWrn = aFinder.WarningStatus();
4261 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn2.cxx
4263 MESSAGE(" *** iWrn : " << iWrn);
4266 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
4268 if (listSS.Extent() < 1) {
4269 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
4270 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
4274 // Fill sequence of object IDs
4275 aSeqOfIDs = new TColStd_HSequenceOfInteger;
4277 TopTools_IndexedMapOfShape anIndices;
4278 TopExp::MapShapes(aShape, anIndices);
4280 TopTools_ListIteratorOfListOfShape itSub (listSS);
4281 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
4282 int id = anIndices.FindIndex(itSub.Value());
4283 aSeqOfIDs->Append(id);
4288 //=======================================================================
4289 //function : GetShapesOnQuadrangle
4291 * \brief Find sub-shapes complying with given status about quadrangle
4292 * \param theShape - the shape to explore
4293 * \param theShapeType - type of sub-shape of theShape
4294 * \param theTopLeftPoint - top left quadrangle corner
4295 * \param theTopRigthPoint - top right quadrangle corner
4296 * \param theBottomLeftPoint - bottom left quadrangle corner
4297 * \param theBottomRigthPoint - bottom right quadrangle corner
4298 * \param theState - required state
4299 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
4301 //=======================================================================
4302 Handle(TColStd_HSequenceOfTransient)
4303 GEOMImpl_IShapesOperations::GetShapesOnQuadrangle (const Handle(GEOM_Object)& theShape,
4304 const Standard_Integer theShapeType,
4305 const Handle(GEOM_Object)& theTopLeftPoint,
4306 const Handle(GEOM_Object)& theTopRigthPoint,
4307 const Handle(GEOM_Object)& theBottomLeftPoint,
4308 const Handle(GEOM_Object)& theBottomRigthPoint,
4309 const GEOMAlgo_State theState)
4312 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
4313 getShapesOnQuadrangleIDs( theShape,
4318 theBottomRigthPoint,
4320 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->IsEmpty() )
4323 // Find objects by indices
4324 TCollection_AsciiString anAsciiList;
4325 Handle(TColStd_HSequenceOfTransient) aSeq;
4326 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
4327 if ( aSeq.IsNull() || aSeq->IsEmpty() )
4330 // Make a Python command
4332 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
4333 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
4335 GEOM::TPythonDump(aFunction)
4336 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnQuadrangle("
4338 << TopAbs_ShapeEnum(theShapeType) << ", "
4339 << theTopLeftPoint << ", "
4340 << theTopRigthPoint << ", "
4341 << theBottomLeftPoint << ", "
4342 << theBottomRigthPoint << ", "
4349 //=======================================================================
4350 //function : GetShapesOnQuadrangleIDs
4352 * \brief Find IDs of sub-shapes complying with given status about quadrangle
4353 * \param theShape - the shape to explore
4354 * \param theShapeType - type of sub-shape of theShape
4355 * \param theTopLeftPoint - top left quadrangle corner
4356 * \param theTopRigthPoint - top right quadrangle corner
4357 * \param theBottomLeftPoint - bottom left quadrangle corner
4358 * \param theBottomRigthPoint - bottom right quadrangle corner
4359 * \param theState - required state
4360 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
4362 //=======================================================================
4363 Handle(TColStd_HSequenceOfInteger)
4364 GEOMImpl_IShapesOperations::GetShapesOnQuadrangleIDs (const Handle(GEOM_Object)& theShape,
4365 const Standard_Integer theShapeType,
4366 const Handle(GEOM_Object)& theTopLeftPoint,
4367 const Handle(GEOM_Object)& theTopRigthPoint,
4368 const Handle(GEOM_Object)& theBottomLeftPoint,
4369 const Handle(GEOM_Object)& theBottomRigthPoint,
4370 const GEOMAlgo_State theState)
4373 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
4374 getShapesOnQuadrangleIDs( theShape,
4379 theBottomRigthPoint,
4381 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->IsEmpty() )
4384 // Make a Python command
4386 // The GetShapesOnCylinder() doesn't change object so no new function is required.
4387 Handle(GEOM_Object) lastObj = GEOM::GetCreatedLast(theShape,theTopLeftPoint);
4388 lastObj = GEOM::GetCreatedLast(lastObj,theTopRigthPoint);
4389 lastObj = GEOM::GetCreatedLast(lastObj,theBottomRigthPoint);
4390 lastObj = GEOM::GetCreatedLast(lastObj,theBottomLeftPoint);
4391 Handle(GEOM_Function) aFunction = lastObj->GetLastFunction();
4393 GEOM::TPythonDump(aFunction, /*append=*/true)
4394 << "listShapesOnQuadrangle = geompy.GetShapesOnQuadrangleIDs("
4396 << TopAbs_ShapeEnum(theShapeType) << ", "
4397 << theTopLeftPoint << ", "
4398 << theTopRigthPoint << ", "
4399 << theBottomLeftPoint << ", "
4400 << theBottomRigthPoint << ", "
4407 //=============================================================================
4412 //=============================================================================
4413 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlace (Handle(GEOM_Object) theShapeWhere,
4414 Handle(GEOM_Object) theShapeWhat)
4418 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
4420 TopoDS_Shape aWhere = theShapeWhere->GetValue();
4421 TopoDS_Shape aWhat = theShapeWhat->GetValue();
4423 if (aWhere.IsNull() || aWhat.IsNull()) {
4424 SetErrorCode("Error: aWhere and aWhat TopoDS_Shape are Null.");
4428 // Searching for the sub-shapes inside the ShapeWhere shape
4429 GEOMAlgo_GetInPlace aGIP;
4431 if (!GEOMAlgo_GetInPlaceAPI::GetInPlace(aWhere, aWhat, aGIP)) {
4432 SetErrorCode("Error in GEOMAlgo_GetInPlace");
4436 // Add direct result.
4437 TopTools_ListOfShape aLSA;
4438 const TopoDS_Shape &aShapeResult = aGIP.Result();
4439 TopTools_MapOfShape aMFence;
4440 TopTools_IndexedMapOfShape aWhereIndices;
4441 Standard_Integer aShapeType = -1;
4443 TopExp::MapShapes(aWhere, aWhereIndices);
4445 if (aShapeResult.IsNull() == Standard_False) {
4446 TopoDS_Iterator anIt(aShapeResult);
4447 Standard_Boolean isFirst = Standard_True;
4449 for (; anIt.More(); anIt.Next()) {
4450 const TopoDS_Shape &aPart = anIt.Value();
4452 if(aWhereIndices.Contains(aPart) && aMFence.Add(aPart)) {
4453 const TopAbs_ShapeEnum aType = aPart.ShapeType();
4455 if (aShapeType == -1) {
4458 } else if (aShapeType != TopAbs_SHAPE && aShapeType != aType) {
4460 aShapeType = TopAbs_SHAPE;
4468 if (aLSA.Extent() == 0) {
4469 SetErrorCode(NOT_FOUND_ANY); // Not found any Results
4473 Handle(TColStd_HArray1OfInteger) aModifiedArray = new TColStd_HArray1OfInteger (1, aLSA.Extent());
4474 TopTools_ListIteratorOfListOfShape anIterModif (aLSA);
4475 for (Standard_Integer imod = 1; anIterModif.More(); anIterModif.Next(), imod++) {
4476 aModifiedArray->SetValue(imod, aWhereIndices.FindIndex(anIterModif.Value()));
4480 Handle(GEOM_Object) aResult = GetEngine()->AddSubShape(theShapeWhere, aModifiedArray);
4481 if (aResult.IsNull()) {
4482 SetErrorCode("Error in algorithm: result found, but cannot be returned.");
4486 const Standard_Boolean isSameType = (aShapeType != TopAbs_SHAPE);
4488 if ((aModifiedArray->Length() > 1 && isSameType) ||
4489 theShapeWhat->GetType() == GEOM_GROUP) {
4491 aResult->SetType(GEOM_GROUP);
4493 //Set a sub-shape type
4494 TopoDS_Shape aFirstFound = aLSA.First();
4495 TopAbs_ShapeEnum aShapeType = aFirstFound.ShapeType();
4497 TDF_Label aFreeLabel = aResult->GetFreeLabel();
4498 TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aShapeType);
4501 //Make a Python command
4502 Handle(GEOM_Function) aFunction = aResult->GetFunction(1);
4504 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetInPlace("
4505 << theShapeWhere << ", " << theShapeWhat << ", True)";
4511 //=============================================================================
4513 * case GetInPlaceOld:
4516 //=============================================================================
4517 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlaceOld
4518 (Handle(GEOM_Object) theShapeWhere,
4519 Handle(GEOM_Object) theShapeWhat)
4523 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
4525 TopoDS_Shape aWhere = theShapeWhere->GetValue();
4526 TopoDS_Shape aWhat = theShapeWhat->GetValue();
4527 TopTools_ListOfShape aModifiedList;
4528 const Standard_Integer iErr =
4529 GEOMAlgo_GetInPlaceAPI::GetInPlaceOld(aWhere, aWhat, aModifiedList);
4534 SetErrorCode("Error: aWhere and aWhat TopoDS_Shape are Null.");
4538 ("Error: An attempt to extract a shape of not supported type.");
4541 SetErrorCode(NOT_FOUND_ANY);
4544 SetErrorCode("Shape driver failed");
4551 TopTools_IndexedMapOfShape aWhereIndices;
4552 TopExp::MapShapes(aWhere, aWhereIndices);
4554 Handle(TColStd_HArray1OfInteger) aModifiedArray =
4555 new TColStd_HArray1OfInteger (1, aModifiedList.Extent());
4556 TopTools_ListIteratorOfListOfShape anIterModif (aModifiedList);
4557 Standard_Integer imod;
4558 Standard_Integer aShapeType = -1;
4560 for (imod = 1; anIterModif.More(); anIterModif.Next(), imod++) {
4561 const Standard_Integer anIndex =
4562 aWhereIndices.FindIndex(anIterModif.Value());
4563 const TopAbs_ShapeEnum aType = anIterModif.Value().ShapeType();
4565 if (aShapeType == -1) {
4568 } else if (aShapeType != TopAbs_SHAPE && aShapeType != aType) {
4570 aShapeType = TopAbs_SHAPE;
4573 aModifiedArray->SetValue(imod, anIndex);
4577 Handle(GEOM_Object) aResult =
4578 GetEngine()->AddSubShape(theShapeWhere, aModifiedArray);
4580 if (aResult.IsNull()) {
4581 SetErrorCode("Error in algorithm: result found, but cannot be returned.");
4585 const Standard_Boolean isSameType = (aShapeType != TopAbs_SHAPE);
4587 if ((aModifiedArray->Length() > 1 && isSameType) ||
4588 theShapeWhat->GetType() == GEOM_GROUP) {
4590 aResult->SetType(GEOM_GROUP);
4592 //Set a sub-shape type
4593 TopoDS_Shape aFirstFound = aWhereIndices.FindKey(aModifiedArray->Value(1));
4594 TopAbs_ShapeEnum aShapeType = aFirstFound.ShapeType();
4596 TDF_Label aFreeLabel = aResult->GetFreeLabel();
4597 TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aShapeType);
4600 //Make a Python command
4601 Handle(GEOM_Function) aFunction = aResult->GetFunction(1);
4603 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetInPlace("
4604 << theShapeWhere << ", " << theShapeWhat << ", False)";
4611 //=======================================================================
4612 //function : GetInPlaceByHistory
4614 //=======================================================================
4615 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlaceByHistory
4616 (Handle(GEOM_Object) theShapeWhere,
4617 Handle(GEOM_Object) theShapeWhat)
4621 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
4623 TopoDS_Shape aWhere = theShapeWhere->GetValue();
4624 TopoDS_Shape aWhat = theShapeWhat->GetValue();
4626 if (aWhere.IsNull() || aWhat.IsNull()) return NULL;
4628 Handle(GEOM_Function) aWhereFunction = theShapeWhere->GetLastFunction();
4629 if (aWhereFunction.IsNull()) return NULL;
4631 //Fill array of indices
4632 TopTools_IndexedMapOfShape aWhereIndices;
4634 TopExp::MapShapes(aWhere, aWhereIndices);
4637 TopTools_ListOfShape aModifiedList;
4638 bool isFound = GEOMAlgo_GetInPlaceAPI::GetInPlaceByHistory
4639 (aWhereFunction, aWhereIndices, aWhat, aModifiedList);
4641 if (!isFound || aModifiedList.Extent() < 1) {
4642 SetErrorCode("Error: No history found for the sought shape or its sub-shapes.");
4646 Handle(TColStd_HArray1OfInteger) aModifiedArray =
4647 new TColStd_HArray1OfInteger (1, aModifiedList.Extent());
4648 TopTools_ListIteratorOfListOfShape anIterModif (aModifiedList);
4649 Standard_Integer imod;
4650 Standard_Integer aShapeType = -1;
4652 for (imod = 1; anIterModif.More(); anIterModif.Next(), imod++) {
4653 const Standard_Integer anIndex =
4654 aWhereIndices.FindIndex(anIterModif.Value());
4655 const TopAbs_ShapeEnum aType = anIterModif.Value().ShapeType();
4657 if (aShapeType == -1) {
4660 } else if (aShapeType != TopAbs_SHAPE && aShapeType != aType) {
4662 aShapeType = TopAbs_SHAPE;
4665 aModifiedArray->SetValue(imod, anIndex);
4669 Handle(GEOM_Object) aResult = GetEngine()->AddSubShape(theShapeWhere, aModifiedArray);
4670 if (aResult.IsNull()) {
4671 SetErrorCode("Error in algorithm: result found, but cannot be returned.");
4675 const Standard_Boolean isSameType = (aShapeType != TopAbs_SHAPE);
4677 if ((aModifiedArray->Length() > 1 && isSameType) ||
4678 theShapeWhat->GetType() == GEOM_GROUP) {
4680 aResult->SetType(GEOM_GROUP);
4682 //Set a sub-shape type
4683 TopoDS_Shape aFirstFound = aWhereIndices.FindKey(aModifiedArray->Value(1));
4684 TopAbs_ShapeEnum aShapeType = aFirstFound.ShapeType();
4686 TDF_Label aFreeLabel = aResult->GetFreeLabel();
4687 TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aShapeType);
4690 //Make a Python command
4691 Handle(GEOM_Function) aFunction = aResult->GetFunction(1);
4693 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetInPlaceByHistory("
4694 << theShapeWhere << ", " << theShapeWhat << ")";
4700 //=======================================================================
4701 //function : isSameEdge
4702 //purpose : Returns True if two edges coincide
4703 //=======================================================================
4704 static bool isSameEdge(const TopoDS_Edge& theEdge1, const TopoDS_Edge& theEdge2)
4706 TopoDS_Vertex V11, V12, V21, V22;
4707 TopExp::Vertices(theEdge1, V11, V12);
4708 TopExp::Vertices(theEdge2, V21, V22);
4709 gp_Pnt P11 = BRep_Tool::Pnt(V11);
4710 gp_Pnt P12 = BRep_Tool::Pnt(V12);
4711 gp_Pnt P21 = BRep_Tool::Pnt(V21);
4712 gp_Pnt P22 = BRep_Tool::Pnt(V22);
4713 bool coincide = false;
4715 //Check that ends of edges coincide
4716 if(P11.Distance(P21) <= MAX_TOLERANCE) {
4717 if(P12.Distance(P22) <= MAX_TOLERANCE) coincide = true;
4719 else if(P11.Distance(P22) <= MAX_TOLERANCE) {
4720 if(P12.Distance(P21) <= MAX_TOLERANCE) coincide = true;
4723 if(!coincide) return false;
4725 if (BRep_Tool::Degenerated(theEdge1))
4726 if (BRep_Tool::Degenerated(theEdge2)) return true;
4729 if (BRep_Tool::Degenerated(theEdge2)) return false;
4731 double U11, U12, U21, U22;
4732 Handle(Geom_Curve) C1 = BRep_Tool::Curve(theEdge1, U11, U12);
4733 Handle(Geom_Curve) C2 = BRep_Tool::Curve(theEdge2, U21, U22);
4735 //Check that both edges has the same geometry
4736 double range = U12-U11;
4737 double U = U11+ range/3.0;
4738 gp_Pnt P1 = C1->Value(U); //Compute a point on one third of the edge's length
4739 U = U11+range*2.0/3.0;
4740 gp_Pnt P2 = C1->Value(U); //Compute a point on two thirds of the edge's length
4742 C2 = new Geom_TrimmedCurve(C2, U21, U22);
4744 if(!GeomLib_Tool::Parameter(C2, P1, MAX_TOLERANCE, U) || U < U21 || U > U22)
4747 if(P1.Distance(C2->Value(U)) > MAX_TOLERANCE) return false;
4749 if(!GeomLib_Tool::Parameter(C2, P2, MAX_TOLERANCE, U) || U < U21 || U > U22)
4752 if(P2.Distance(C2->Value(U)) > MAX_TOLERANCE) return false;
4757 #include <TopoDS_TShape.hxx>
4758 //=======================================================================
4759 //function : isSameFace
4760 //purpose : Returns True if two faces coincide
4761 //=======================================================================
4762 static bool isSameFace(const TopoDS_Face& theFace1, const TopoDS_Face& theFace2)
4764 TopExp_Explorer E(theFace1, TopAbs_EDGE);
4765 TopTools_ListOfShape LS1, LS2;
4766 for(; E.More(); E.Next()) LS1.Append(E.Current());
4768 E.Init(theFace2, TopAbs_EDGE);
4769 for(; E.More(); E.Next()) LS2.Append(E.Current());
4771 //Compare the number of edges in the faces
4772 if(LS1.Extent() != LS2.Extent()) return false;
4774 double aMin = RealFirst(), aMax = RealLast();
4775 double xminB1=aMax, yminB1=aMax, zminB1=aMax, xminB2=aMax, yminB2=aMax, zminB2=aMax;
4776 double xmaxB1=aMin, ymaxB1=aMin, zmaxB1=aMin, xmaxB2=aMin, ymaxB2=aMin, zmaxB2=aMin;
4778 for(E.Init(theFace1, TopAbs_VERTEX); E.More(); E.Next()) {
4779 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4780 if(P.X() < xminB1) xminB1 = P.X();
4781 if(P.Y() < yminB1) yminB1 = P.Y();
4782 if(P.Z() < zminB1) zminB1 = P.Z();
4783 if(P.X() > xmaxB1) xmaxB1 = P.X();
4784 if(P.Y() > ymaxB1) ymaxB1 = P.Y();
4785 if(P.Z() > zmaxB1) zmaxB1 = P.Z();
4788 for(E.Init(theFace2, TopAbs_VERTEX); E.More(); E.Next()) {
4789 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4790 if(P.X() < xminB2) xminB2 = P.X();
4791 if(P.Y() < yminB2) yminB2 = P.Y();
4792 if(P.Z() < zminB2) zminB2 = P.Z();
4793 if(P.X() > xmaxB2) xmaxB2 = P.X();
4794 if(P.Y() > ymaxB2) ymaxB2 = P.Y();
4795 if(P.Z() > zmaxB2) zmaxB2 = P.Z();
4798 //Compare the bounding boxes of both faces
4799 if(gp_Pnt(xminB1, yminB1, zminB1).Distance(gp_Pnt(xminB2, yminB2, zminB2)) > MAX_TOLERANCE)
4802 if(gp_Pnt(xmaxB1, ymaxB1, zmaxB1).Distance(gp_Pnt(xmaxB2, ymaxB2, zmaxB2)) > MAX_TOLERANCE)
4805 Handle(Geom_Surface) S1 = BRep_Tool::Surface(theFace1);
4806 Handle(Geom_Surface) S2 = BRep_Tool::Surface(theFace2);
4808 //Check if there a coincidence of two surfaces at least in two points
4809 double U11, U12, V11, V12, U21, U22, V21, V22;
4810 BRepTools::UVBounds(theFace1, U11, U12, V11, V12);
4811 BRepTools::UVBounds(theFace2, U21, U22, V21, V22);
4813 double rangeU = U12-U11;
4814 double rangeV = V12-V11;
4815 double U = U11 + rangeU/3.0;
4816 double V = V11 + rangeV/3.0;
4817 gp_Pnt P1 = S1->Value(U, V);
4818 U = U11+rangeU*2.0/3.0;
4819 V = V11+rangeV*2.0/3.0;
4820 gp_Pnt P2 = S1->Value(U, V);
4822 if (!GeomLib_Tool::Parameters(S2, P1, MAX_TOLERANCE, U, V) || U < U21 || U > U22 || V < V21 || V > V22)
4825 if (P1.Distance(S2->Value(U,V)) > MAX_TOLERANCE) return false;
4827 if (!GeomLib_Tool::Parameters(S2, P2, MAX_TOLERANCE, U, V) || U < U21 || U > U22 || V < V21 || V > V22)
4830 if (P2.Distance(S2->Value(U, V)) > MAX_TOLERANCE) return false;
4832 //Check that each edge of the Face1 has a counterpart in the Face2
4833 TopTools_MapOfOrientedShape aMap;
4834 TopTools_ListIteratorOfListOfShape LSI1(LS1);
4835 for(; LSI1.More(); LSI1.Next()) {
4836 TopoDS_Edge E = TopoDS::Edge(LSI1.Value());
4837 bool isFound = false;
4838 TopTools_ListIteratorOfListOfShape LSI2(LS2);
4839 for(; LSI2.More(); LSI2.Next()) {
4840 TopoDS_Shape aValue = LSI2.Value();
4841 if(aMap.Contains(aValue)) continue; //To avoid checking already found edge several times
4842 if(isSameEdge(E, TopoDS::Edge(aValue))) {
4848 if(!isFound) return false;
4854 //=======================================================================
4855 //function : isSameSolid
4856 //purpose : Returns True if two solids coincide
4857 //=======================================================================
4858 bool isSameSolid(const TopoDS_Solid& theSolid1, const TopoDS_Solid& theSolid2)
4860 TopExp_Explorer E(theSolid1, TopAbs_FACE);
4861 TopTools_ListOfShape LS1, LS2;
4862 for(; E.More(); E.Next()) LS1.Append(E.Current());
4863 E.Init(theSolid2, TopAbs_FACE);
4864 for(; E.More(); E.Next()) LS2.Append(E.Current());
4866 if(LS1.Extent() != LS2.Extent()) return false;
4868 double aMin = RealFirst(), aMax = RealLast();
4869 double xminB1=aMax, yminB1=aMax, zminB1=aMax, xminB2=aMax, yminB2=aMax, zminB2=aMax;
4870 double xmaxB1=aMin, ymaxB1=aMin, zmaxB1=aMin, xmaxB2=aMin, ymaxB2=aMin, zmaxB2=aMin;
4872 for(E.Init(theSolid1, TopAbs_VERTEX); E.More(); E.Next()) {
4873 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4874 if(P.X() < xminB1) xminB1 = P.X();
4875 if(P.Y() < yminB1) yminB1 = P.Y();
4876 if(P.Z() < zminB1) zminB1 = P.Z();
4877 if(P.X() > xmaxB1) xmaxB1 = P.X();
4878 if(P.Y() > ymaxB1) ymaxB1 = P.Y();
4879 if(P.Z() > zmaxB1) zmaxB1 = P.Z();
4882 for(E.Init(theSolid2, TopAbs_VERTEX); E.More(); E.Next()) {
4883 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4884 if(P.X() < xminB2) xminB2 = P.X();
4885 if(P.Y() < yminB2) yminB2 = P.Y();
4886 if(P.Z() < zminB2) zminB2 = P.Z();
4887 if(P.X() > xmaxB2) xmaxB2 = P.X();
4888 if(P.Y() > ymaxB2) ymaxB2 = P.Y();
4889 if(P.Z() > zmaxB2) zmaxB2 = P.Z();
4892 //Compare the bounding boxes of both solids
4893 if(gp_Pnt(xminB1, yminB1, zminB1).Distance(gp_Pnt(xminB2, yminB2, zminB2)) > MAX_TOLERANCE)
4896 if(gp_Pnt(xmaxB1, ymaxB1, zmaxB1).Distance(gp_Pnt(xmaxB2, ymaxB2, zmaxB2)) > MAX_TOLERANCE)
4899 //Check that each face of the Solid1 has a counterpart in the Solid2
4900 TopTools_MapOfOrientedShape aMap;
4901 TopTools_ListIteratorOfListOfShape LSI1(LS1);
4902 for(; LSI1.More(); LSI1.Next()) {
4903 TopoDS_Face F = TopoDS::Face(LSI1.Value());
4904 bool isFound = false;
4905 TopTools_ListIteratorOfListOfShape LSI2(LS2);
4906 for(; LSI2.More(); LSI2.Next()) {
4907 if(aMap.Contains(LSI2.Value())) continue; //To avoid checking already found faces several times
4908 if(isSameFace(F, TopoDS::Face(LSI2.Value()))) {
4909 aMap.Add(LSI2.Value());
4914 if(!isFound) return false;
4920 //=======================================================================
4921 //function : GetSame
4923 //=======================================================================
4924 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetSame(const Handle(GEOM_Object)& theShapeWhere,
4925 const Handle(GEOM_Object)& theShapeWhat)
4928 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
4930 TopoDS_Shape aWhere = theShapeWhere->GetValue();
4931 TopoDS_Shape aWhat = theShapeWhat->GetValue();
4933 if (aWhere.IsNull() || aWhat.IsNull()) return NULL;
4936 bool isFound = false;
4937 TopoDS_Shape aSubShape;
4938 TopTools_MapOfShape aMap;
4940 if (aWhat.ShapeType() == TopAbs_COMPOUND || aWhat.ShapeType() == TopAbs_COMPSOLID) {
4941 TopoDS_Iterator It (aWhat, Standard_True, Standard_True);
4942 if (It.More()) aWhat = It.Value();
4945 SetErrorCode("Compounds of two or more shapes are not allowed for aWhat argument");
4950 switch (aWhat.ShapeType()) {
4951 case TopAbs_VERTEX: {
4952 aSubShape = getSameVertex(aWhere, TopoDS::Vertex(aWhat));
4953 isFound = !aSubShape.IsNull();
4957 TopoDS_Edge anEdge = TopoDS::Edge(aWhat);
4958 TopExp_Explorer E(aWhere, TopAbs_EDGE);
4959 for(; E.More(); E.Next()) {
4960 if(!aMap.Add(E.Current())) continue;
4961 if(isSameEdge(anEdge, TopoDS::Edge(E.Current()))) {
4962 aSubShape = E.Current();
4970 TopoDS_Face aFace = TopoDS::Face(aWhat);
4971 TopExp_Explorer E(aWhere, TopAbs_FACE);
4972 for(; E.More(); E.Next()) {
4973 if(!aMap.Add(E.Current())) continue;
4974 if(isSameFace(aFace, TopoDS::Face(E.Current()))) {
4975 aSubShape = E.Current();
4982 case TopAbs_SOLID: {
4983 TopoDS_Solid aSolid = TopoDS::Solid(aWhat);
4984 TopExp_Explorer E(aWhere, TopAbs_SOLID);
4985 for(; E.More(); E.Next()) {
4986 if(!aMap.Add(E.Current())) continue;
4987 if(isSameSolid(aSolid, TopoDS::Solid(E.Current()))) {
4988 aSubShape = E.Current();
5000 TopTools_IndexedMapOfShape anIndices;
5001 TopExp::MapShapes(aWhere, anIndices);
5002 if (anIndices.Contains(aSubShape))
5003 anIndex = anIndices.FindIndex(aSubShape);
5006 if (anIndex < 0) return NULL;
5008 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
5010 anArray->SetValue(1, anIndex);
5012 Handle(GEOM_Object) aResult = GetEngine()->AddSubShape(theShapeWhere, anArray);
5013 Handle(GEOM_Function) aFunction = aResult->GetLastFunction();
5015 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetSame("
5016 << theShapeWhere << ", " << theShapeWhat << ")";
5024 //=======================================================================
5025 //function : GetSameIDs
5027 //=======================================================================
5028 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetSameIDs
5029 (const Handle(GEOM_Object)& theShapeWhere,
5030 const Handle(GEOM_Object)& theShapeWhat)
5033 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
5035 TopoDS_Shape aWhere = theShapeWhere->GetValue();
5036 TopoDS_Shape aWhat = theShapeWhat->GetValue();
5038 if (aWhere.IsNull() || aWhat.IsNull()) return NULL;
5040 TopTools_ListOfShape listShape;
5041 TopTools_MapOfShape aMap;
5043 if (aWhat.ShapeType() == TopAbs_COMPOUND || aWhat.ShapeType() == TopAbs_COMPSOLID) {
5044 TopoDS_Iterator It (aWhat, Standard_True, Standard_True);
5045 if (It.More()) aWhat = It.Value();
5048 SetErrorCode("Compounds of two or more shapes are not allowed for aWhat argument");
5053 switch (aWhat.ShapeType()) {
5054 case TopAbs_VERTEX: {
5055 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(aWhat));
5056 TopExp_Explorer E(aWhere, TopAbs_VERTEX);
5057 for(; E.More(); E.Next()) {
5058 if(!aMap.Add(E.Current())) continue;
5059 gp_Pnt P2 = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
5060 if(P.Distance(P2) <= MAX_TOLERANCE) {
5061 listShape.Append(E.Current());
5067 TopoDS_Edge anEdge = TopoDS::Edge(aWhat);
5068 TopExp_Explorer E(aWhere, TopAbs_EDGE);
5069 for(; E.More(); E.Next()) {
5070 if(!aMap.Add(E.Current())) continue;
5071 if(isSameEdge(anEdge, TopoDS::Edge(E.Current()))) {
5072 listShape.Append(E.Current());
5078 TopoDS_Face aFace = TopoDS::Face(aWhat);
5079 TopExp_Explorer E(aWhere, TopAbs_FACE);
5080 for(; E.More(); E.Next()) {
5081 if(!aMap.Add(E.Current())) continue;
5082 if(isSameFace(aFace, TopoDS::Face(E.Current()))) {
5083 listShape.Append(E.Current());
5088 case TopAbs_SOLID: {
5089 TopoDS_Solid aSolid = TopoDS::Solid(aWhat);
5090 TopExp_Explorer E(aWhere, TopAbs_SOLID);
5091 for(; E.More(); E.Next()) {
5092 if(!aMap.Add(E.Current())) continue;
5093 if(isSameSolid(aSolid, TopoDS::Solid(E.Current()))) {
5094 listShape.Append(E.Current());
5103 if ( !listShape.IsEmpty() ) {
5104 TopTools_IndexedMapOfShape anIndices;
5105 TopExp::MapShapes(aWhere, anIndices);
5106 TopTools_ListIteratorOfListOfShape itSub (listShape);
5107 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
5108 for (; itSub.More(); itSub.Next()) {
5109 if (anIndices.Contains(itSub.Value()))
5110 aSeq->Append(anIndices.FindIndex(itSub.Value()));
5113 // The GetSameIDs() doesn't change object so no new function is required.
5114 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShapeWhere,theShapeWhat)->GetLastFunction();
5116 // Make a Python command
5117 GEOM::TPythonDump(aFunction, /*append=*/true)
5118 << "listSameIDs = geompy.GetSameIDs("
5119 << theShapeWhere << ", "
5120 << theShapeWhat << ")";
5123 SetErrorCode(NOT_FOUND_ANY);
5128 //=======================================================================
5129 //function : ExtendEdge
5131 //=======================================================================
5132 Handle(GEOM_Object) GEOMImpl_IShapesOperations::ExtendEdge
5133 (const Handle(GEOM_Object) &theEdge,
5134 const Standard_Real theMin,
5135 const Standard_Real theMax)
5139 if (theEdge.IsNull()) {
5143 //Add a new Edge object
5144 Handle(GEOM_Object) aResEdge = GetEngine()->AddObject(GetDocID(), GEOM_EDGE);
5146 //Add a new Vector function
5147 Handle(GEOM_Function) aFunction =
5148 aResEdge->AddFunction(GEOMImpl_ShapeDriver::GetID(), EDGE_UV);
5150 //Check if the function is set correctly
5151 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) {
5155 GEOMImpl_IShapeExtend aCI (aFunction);
5157 Handle(GEOM_Function) anEdge = theEdge->GetLastFunction();
5159 if (anEdge.IsNull()) {
5163 aCI.SetShape(anEdge);
5164 aCI.SetUMin(theMin);
5165 aCI.SetUMax(theMax);
5167 //Compute the Edge value
5170 if (!GetSolver()->ComputeFunction(aFunction)) {
5171 SetErrorCode("Shape driver failed");
5176 catch (Standard_Failure) {
5177 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
5178 SetErrorCode(aFail->GetMessageString());
5183 //Make a Python command
5184 GEOM::TPythonDump(aFunction)
5185 << aResEdge << " = geompy.ExtendEdge("
5186 << theEdge << ", " << theMin << ", " << theMax << ")";
5193 //=======================================================================
5194 //function : ExtendFace
5196 //=======================================================================
5197 Handle(GEOM_Object) GEOMImpl_IShapesOperations::ExtendFace
5198 (const Handle(GEOM_Object) &theFace,
5199 const Standard_Real theUMin,
5200 const Standard_Real theUMax,
5201 const Standard_Real theVMin,
5202 const Standard_Real theVMax)
5206 if (theFace.IsNull()) {
5210 //Add a new Face object
5211 Handle(GEOM_Object) aResFace = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
5213 //Add a new Vector function
5214 Handle(GEOM_Function) aFunction =
5215 aResFace->AddFunction(GEOMImpl_ShapeDriver::GetID(), FACE_UV);
5217 //Check if the function is set correctly
5218 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) {
5222 GEOMImpl_IShapeExtend aCI (aFunction);
5224 Handle(GEOM_Function) aFace = theFace->GetLastFunction();
5226 if (aFace.IsNull()) {
5230 aCI.SetShape(aFace);
5231 aCI.SetUMin(theUMin);
5232 aCI.SetUMax(theUMax);
5233 aCI.SetVMin(theVMin);
5234 aCI.SetVMax(theVMax);
5236 //Compute the Face value
5239 if (!GetSolver()->ComputeFunction(aFunction)) {
5240 SetErrorCode("Shape driver failed");
5245 catch (Standard_Failure) {
5246 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
5247 SetErrorCode(aFail->GetMessageString());
5252 //Make a Python command
5253 GEOM::TPythonDump(aFunction)
5254 << aResFace << " = geompy.ExtendFace("
5255 << theFace << ", " << theUMin << ", " << theUMax << ", "
5256 << theVMin << ", " << theVMax << ")";
5263 //=======================================================================
5264 //function : MakeSurfaceFromFace
5266 //=======================================================================
5267 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeSurfaceFromFace
5268 (const Handle(GEOM_Object) &theFace)
5272 if (theFace.IsNull()) {
5276 //Add a new Face object
5277 Handle(GEOM_Object) aResFace = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
5279 //Add a new Vector function
5280 Handle(GEOM_Function) aFunction =
5281 aResFace->AddFunction(GEOMImpl_ShapeDriver::GetID(), SURFACE_FROM_FACE);
5283 //Check if the function is set correctly
5284 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) {
5288 GEOMImpl_IShapeExtend aCI (aFunction);
5290 Handle(GEOM_Function) aFace = theFace->GetLastFunction();
5292 if (aFace.IsNull()) {
5296 aCI.SetShape(aFace);
5298 //Compute the Face value
5301 if (!GetSolver()->ComputeFunction(aFunction)) {
5302 SetErrorCode("Shape driver failed");
5307 catch (Standard_Failure) {
5308 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
5309 SetErrorCode(aFail->GetMessageString());
5314 //Make a Python command
5315 GEOM::TPythonDump(aFunction)
5316 << aResFace << " = geompy.MakeSurfaceFromFace("