1 // Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
2 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License.
9 // This library is distributed in the hope that it will be useful
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // Lesser General Public License for more details.
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 #include <Standard_Stream.hxx>
23 #include "GEOMImpl_IShapesOperations.hxx"
25 #include "GEOMImpl_Types.hxx"
27 #include "GEOMImpl_VectorDriver.hxx"
28 #include "GEOMImpl_ShapeDriver.hxx"
29 #include "GEOMImpl_CopyDriver.hxx"
30 #include "GEOMImpl_GlueDriver.hxx"
32 #include "GEOMImpl_IVector.hxx"
33 #include "GEOMImpl_IShapes.hxx"
34 #include "GEOMImpl_IGlue.hxx"
36 #include "GEOMImpl_Block6Explorer.hxx"
38 #include "GEOM_Function.hxx"
39 #include "GEOM_PythonDump.hxx"
41 #include "GEOMAlgo_FinderShapeOn1.hxx"
42 #include "GEOMAlgo_FinderShapeOnQuad.hxx"
43 #include "GEOMAlgo_FinderShapeOn2.hxx"
44 #include "GEOMAlgo_ClsfBox.hxx"
45 #include "GEOMAlgo_Gluer1.hxx"
46 #include "GEOMAlgo_ListIteratorOfListOfCoupleOfShapes.hxx"
47 #include "GEOMAlgo_CoupleOfShapes.hxx"
48 #include "GEOMAlgo_ListOfCoupleOfShapes.hxx"
50 #include "utilities.h"
52 #include "Utils_ExceptHandlers.hxx"
54 #include <TFunction_DriverTable.hxx>
55 #include <TFunction_Driver.hxx>
56 #include <TFunction_Logbook.hxx>
57 #include <TDataStd_Integer.hxx>
58 #include <TDataStd_IntegerArray.hxx>
59 #include <TDF_Tool.hxx>
61 #include <BRepExtrema_ExtCF.hxx>
63 #include <BRep_Tool.hxx>
64 #include <BRep_Builder.hxx>
65 #include <BRepTools.hxx>
66 #include <BRepGProp.hxx>
67 #include <BRepAdaptor_Curve.hxx>
68 #include <BRepAdaptor_Surface.hxx>
69 #include <BRepBndLib.hxx>
70 #include <BRepBuilderAPI_MakeFace.hxx>
71 #include <BRepMesh_IncrementalMesh.hxx>
76 #include <TopoDS_Shape.hxx>
77 #include <TopoDS_Solid.hxx>
78 #include <TopoDS_Face.hxx>
79 #include <TopoDS_Edge.hxx>
80 #include <TopoDS_Vertex.hxx>
81 #include <TopoDS_Compound.hxx>
82 #include <TopoDS_Iterator.hxx>
83 #include <TopExp_Explorer.hxx>
84 #include <TopLoc_Location.hxx>
85 #include <TopTools_MapOfShape.hxx>
86 #include <TopTools_MapOfOrientedShape.hxx>
87 #include <TopTools_Array1OfShape.hxx>
88 #include <TopTools_ListIteratorOfListOfShape.hxx>
89 #include <TopTools_IndexedMapOfShape.hxx>
91 #include <Geom_Surface.hxx>
92 #include <Geom_Plane.hxx>
93 #include <Geom_SphericalSurface.hxx>
94 #include <Geom_CylindricalSurface.hxx>
95 #include <GeomAdaptor_Surface.hxx>
97 #include <GeomLib_Tool.hxx>
98 #include <Geom2d_Curve.hxx>
100 #include <Bnd_Box.hxx>
101 #include <GProp_GProps.hxx>
102 #include <gp_Pnt.hxx>
103 #include <gp_Lin.hxx>
104 #include <TColStd_ListOfInteger.hxx>
105 #include <TColStd_ListIteratorOfListOfInteger.hxx>
106 #include <TColStd_Array1OfReal.hxx>
107 #include <TColStd_HArray1OfInteger.hxx>
111 #include <Standard_Failure.hxx>
112 #include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
114 //=============================================================================
118 //=============================================================================
119 GEOMImpl_IShapesOperations::GEOMImpl_IShapesOperations (GEOM_Engine* theEngine, int theDocID)
120 : GEOM_IOperations(theEngine, theDocID)
122 MESSAGE("GEOMImpl_IShapesOperations::GEOMImpl_IShapesOperations");
125 //=============================================================================
129 //=============================================================================
130 GEOMImpl_IShapesOperations::~GEOMImpl_IShapesOperations()
132 MESSAGE("GEOMImpl_IShapesOperations::~GEOMImpl_IShapesOperations");
136 //=============================================================================
140 //=============================================================================
141 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeEdge
142 (Handle(GEOM_Object) thePnt1, Handle(GEOM_Object) thePnt2)
146 if (thePnt1.IsNull() || thePnt2.IsNull()) return NULL;
148 //Add a new Edge object
149 Handle(GEOM_Object) anEdge = GetEngine()->AddObject(GetDocID(), GEOM_EDGE);
151 //Add a new Vector function
152 Handle(GEOM_Function) aFunction =
153 anEdge->AddFunction(GEOMImpl_VectorDriver::GetID(), VECTOR_TWO_PNT);
155 //Check if the function is set correctly
156 if (aFunction->GetDriverGUID() != GEOMImpl_VectorDriver::GetID()) return NULL;
158 GEOMImpl_IVector aPI (aFunction);
160 Handle(GEOM_Function) aRef1 = thePnt1->GetLastFunction();
161 Handle(GEOM_Function) aRef2 = thePnt2->GetLastFunction();
162 if (aRef1.IsNull() || aRef2.IsNull()) return NULL;
164 aPI.SetPoint1(aRef1);
165 aPI.SetPoint2(aRef2);
167 //Compute the Edge value
169 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
172 if (!GetSolver()->ComputeFunction(aFunction)) {
173 SetErrorCode("Vector driver failed");
177 catch (Standard_Failure) {
178 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
179 SetErrorCode(aFail->GetMessageString());
183 //Make a Python command
184 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdge("
185 << thePnt1 << ", " << thePnt2 << ")";
191 //=============================================================================
195 //=============================================================================
196 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeWire
197 (list<Handle(GEOM_Object)> theShapes)
199 return MakeShape(theShapes, GEOM_WIRE, WIRE_EDGES, "MakeWire");
202 //=============================================================================
206 //=============================================================================
207 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFace (Handle(GEOM_Object) theWire,
208 const bool isPlanarWanted)
212 if (theWire.IsNull()) return NULL;
214 //Add a new Face object
215 Handle(GEOM_Object) aFace = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
217 //Add a new Shape function for creation of a face from a wire
218 Handle(GEOM_Function) aFunction =
219 aFace->AddFunction(GEOMImpl_ShapeDriver::GetID(), FACE_WIRE);
220 if (aFunction.IsNull()) return NULL;
222 //Check if the function is set correctly
223 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
225 GEOMImpl_IShapes aCI (aFunction);
227 Handle(GEOM_Function) aRefWire = theWire->GetLastFunction();
229 if (aRefWire.IsNull()) return NULL;
231 aCI.SetBase(aRefWire);
232 aCI.SetIsPlanar(isPlanarWanted);
234 //Compute the Face value
236 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
239 if (!GetSolver()->ComputeFunction(aFunction)) {
240 SetErrorCode("Shape driver failed to compute a face");
244 catch (Standard_Failure) {
245 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
246 SetErrorCode(aFail->GetMessageString());
250 //Make a Python command
251 GEOM::TPythonDump(aFunction) << aFace << " = geompy.MakeFace("
252 << theWire << ", " << (int)isPlanarWanted << ")";
258 //=============================================================================
262 //=============================================================================
263 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFaceWires
264 (list<Handle(GEOM_Object)> theShapes,
265 const bool isPlanarWanted)
270 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
273 Handle(GEOM_Function) aFunction =
274 aShape->AddFunction(GEOMImpl_ShapeDriver::GetID(), FACE_WIRES);
275 if (aFunction.IsNull()) return NULL;
277 //Check if the function is set correctly
278 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
280 GEOMImpl_IShapes aCI (aFunction);
282 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
285 list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
286 for (; it != theShapes.end(); it++) {
287 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
288 if (aRefSh.IsNull()) {
289 SetErrorCode("NULL argument shape for the face construction");
292 aShapesSeq->Append(aRefSh);
294 aCI.SetShapes(aShapesSeq);
296 aCI.SetIsPlanar(isPlanarWanted);
300 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
303 if (!GetSolver()->ComputeFunction(aFunction)) {
304 SetErrorCode("Shape driver failed");
308 catch (Standard_Failure) {
309 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
310 SetErrorCode(aFail->GetMessageString());
314 //Make a Python command
315 GEOM::TPythonDump pd (aFunction);
316 pd << aShape << " = geompy.MakeFaceWires([";
319 it = theShapes.begin();
320 if (it != theShapes.end()) {
322 while (it != theShapes.end()) {
323 pd << ", " << (*it++);
326 pd << "], " << (int)isPlanarWanted << ")";
332 //=============================================================================
336 //=============================================================================
337 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeShell
338 (list<Handle(GEOM_Object)> theShapes)
340 return MakeShape(theShapes, GEOM_SHELL, SHELL_FACES, "MakeShell");
343 //=============================================================================
347 //=============================================================================
348 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeSolidShells
349 (list<Handle(GEOM_Object)> theShapes)
351 return MakeShape(theShapes, GEOM_SOLID, SOLID_SHELLS, "MakeSolid");
354 //=============================================================================
358 //=============================================================================
359 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeSolidShell (Handle(GEOM_Object) theShell)
363 if (theShell.IsNull()) return NULL;
365 //Add a new Solid object
366 Handle(GEOM_Object) aSolid = GetEngine()->AddObject(GetDocID(), GEOM_SOLID);
368 //Add a new Solid function for creation of a solid from a shell
369 Handle(GEOM_Function) aFunction =
370 aSolid->AddFunction(GEOMImpl_ShapeDriver::GetID(), SOLID_SHELL);
371 if (aFunction.IsNull()) return NULL;
373 //Check if the function is set correctly
374 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
376 GEOMImpl_IShapes aCI (aFunction);
378 Handle(GEOM_Function) aRefShell = theShell->GetLastFunction();
380 if (aRefShell.IsNull()) return NULL;
382 aCI.SetBase(aRefShell);
384 //Compute the Solid value
386 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
389 if (!GetSolver()->ComputeFunction(aFunction)) {
390 SetErrorCode("Solid driver failed");
394 catch (Standard_Failure) {
395 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
396 SetErrorCode(aFail->GetMessageString());
400 //Make a Python command
401 GEOM::TPythonDump(aFunction) << aSolid
402 << " = geompy.MakeSolid(" << theShell << ")";
408 //=============================================================================
412 //=============================================================================
413 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeCompound
414 (list<Handle(GEOM_Object)> theShapes)
416 return MakeShape(theShapes, GEOM_COMPOUND, COMPOUND_SHAPES, "MakeCompound");
419 //=============================================================================
423 //=============================================================================
424 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeShape
425 (list<Handle(GEOM_Object)> theShapes,
426 const Standard_Integer theObjectType,
427 const Standard_Integer theFunctionType,
428 const TCollection_AsciiString& theMethodName)
433 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), theObjectType);
436 Handle(GEOM_Function) aFunction =
437 aShape->AddFunction(GEOMImpl_ShapeDriver::GetID(), theFunctionType);
438 if (aFunction.IsNull()) return NULL;
440 //Check if the function is set correctly
441 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
443 GEOMImpl_IShapes aCI (aFunction);
445 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
448 list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
449 for (; it != theShapes.end(); it++) {
450 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
451 if (aRefSh.IsNull()) {
452 SetErrorCode("NULL argument shape for the shape construction");
455 aShapesSeq->Append(aRefSh);
457 aCI.SetShapes(aShapesSeq);
461 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
464 if (!GetSolver()->ComputeFunction(aFunction)) {
465 SetErrorCode("Shape driver failed");
469 catch (Standard_Failure) {
470 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
471 SetErrorCode(aFail->GetMessageString());
475 //Make a Python command
476 GEOM::TPythonDump pd (aFunction);
477 pd << aShape << " = geompy." << theMethodName.ToCString() << "([";
480 it = theShapes.begin();
481 if (it != theShapes.end()) {
483 while (it != theShapes.end()) {
484 pd << ", " << (*it++);
493 //=============================================================================
497 //=============================================================================
498 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeGlueFaces
499 (Handle(GEOM_Object) theShape,
500 const Standard_Real theTolerance,
501 const Standard_Boolean doKeepNonSolids)
505 if (theShape.IsNull()) return NULL;
507 //Add a new Glued object
508 Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
510 //Add a new Glue function
511 Handle(GEOM_Function) aFunction;
512 aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_FACES);
513 if (aFunction.IsNull()) return NULL;
515 //Check if the function is set correctly
516 if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
518 GEOMImpl_IGlue aCI (aFunction);
520 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
521 if (aRefShape.IsNull()) return NULL;
523 aCI.SetBase(aRefShape);
524 aCI.SetTolerance(theTolerance);
525 aCI.SetKeepNonSolids(doKeepNonSolids);
527 //Compute the sub-shape value
528 Standard_Boolean isWarning = Standard_False;
530 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
533 if (!GetSolver()->ComputeFunction(aFunction)) {
534 SetErrorCode("Shape driver failed to glue faces");
538 catch (Standard_Failure) {
539 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
540 SetErrorCode(aFail->GetMessageString());
541 // to provide warning
542 if (!aFunction->GetValue().IsNull()) {
543 isWarning = Standard_True;
549 //Make a Python command
550 GEOM::TPythonDump(aFunction) << aGlued << " = geompy.MakeGlueFaces("
551 << theShape << ", " << theTolerance << ")";
553 // to provide warning
554 if (!isWarning) SetErrorCode(OK);
558 //=============================================================================
562 //=============================================================================
563 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetGlueFaces
564 (Handle(GEOM_Object) theShape,
565 const Standard_Real theTolerance)
569 if (theShape.IsNull()) return NULL;
570 TopoDS_Shape aShape = theShape->GetValue();
571 if (aShape.IsNull()) return NULL;
573 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
575 Standard_Integer iErr;
577 GEOMAlgo_Gluer1 aGluer;
578 GEOMAlgo_ListIteratorOfListOfCoupleOfShapes aItCS;
579 GEOMAlgo_CoupleOfShapes aCS;
580 GEOMAlgo_ListOfCoupleOfShapes aLCS;
582 //aGluer = new GEOMAlgo_Gluer1;
583 aGluer.SetShape(aShape);
584 aGluer.SetTolerance(theTolerance);
586 iErr = aGluer.ErrorStatus();
587 if (iErr) return NULL;
589 TopTools_ListOfShape listShape;
590 const GEOMAlgo_ListOfCoupleOfShapes& aLCSG = aGluer.GluedFaces();
592 aItCS.Initialize(aLCSG);
593 for (; aItCS.More(); aItCS.Next()) {
594 const GEOMAlgo_CoupleOfShapes& aCSG = aItCS.Value();
595 listShape.Append(aCSG.Shape1());
598 TopTools_ListIteratorOfListOfShape itSub (listShape);
599 TCollection_AsciiString anAsciiList, anEntry;
600 TopTools_IndexedMapOfShape anIndices;
601 TopExp::MapShapes(aShape, anIndices);
602 Handle(TColStd_HArray1OfInteger) anArray;
603 Handle(GEOM_Object) anObj;
604 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
605 TopoDS_Shape aValue = itSub.Value();
606 anArray = new TColStd_HArray1OfInteger(1,1);
607 anArray->SetValue(1, anIndices.FindIndex(aValue));
608 anObj = GetEngine()->AddSubShape(theShape, anArray);
609 if (!anObj.IsNull()) {
612 // for python command
613 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
614 anAsciiList += anEntry;
619 //Make a Python command
620 if(anAsciiList.Length()>0)
621 anAsciiList.Trunc(anAsciiList.Length() - 1);
622 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
623 GEOM::TPythonDump pd (aFunction, /*append=*/true);
624 pd << "[" << anAsciiList.ToCString();
625 pd << "] = geompy.GetGlueFaces" << theShape << ", " << theTolerance << ")";
633 //=============================================================================
635 * MakeGlueFacesByList
637 //=============================================================================
638 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeGlueFacesByList
639 (Handle(GEOM_Object) theShape,
640 const Standard_Real theTolerance,
641 list<Handle(GEOM_Object)> theFaces,
642 const Standard_Boolean doKeepNonSolids)
646 if (theShape.IsNull()) return NULL;
648 //Add a new Glued object
649 Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
651 //Add a new Glue function
652 Handle(GEOM_Function) aFunction;
653 aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_FACES_BY_LIST);
654 if (aFunction.IsNull()) return NULL;
656 //Check if the function is set correctly
657 if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
659 GEOMImpl_IGlue aCI (aFunction);
661 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
662 if (aRefShape.IsNull()) return NULL;
664 aCI.SetBase(aRefShape);
665 aCI.SetTolerance(theTolerance);
666 aCI.SetKeepNonSolids(doKeepNonSolids);
668 Handle(TColStd_HSequenceOfTransient) aFaces = new TColStd_HSequenceOfTransient;
669 list<Handle(GEOM_Object)>::iterator it = theFaces.begin();
670 for (; it != theFaces.end(); it++) {
671 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
672 if (aRefSh.IsNull()) {
673 SetErrorCode("NULL argument shape for the shape construction");
676 aFaces->Append(aRefSh);
678 aCI.SetFaces(aFaces);
680 //Compute the sub-shape value
681 Standard_Boolean isWarning = Standard_False;
683 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
686 if (!GetSolver()->ComputeFunction(aFunction)) {
687 SetErrorCode("Shape driver failed to glue faces");
691 catch (Standard_Failure) {
692 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
693 SetErrorCode(aFail->GetMessageString());
694 // to provide warning
695 if (!aFunction->GetValue().IsNull()) {
696 isWarning = Standard_True;
702 //Make a Python command
704 GEOM::TPythonDump pd(aFunction);
705 pd << aGlued << " = geompy.MakeGlueFacesByList("
706 << theShape << ", " << theTolerance << ", [";
708 it = theFaces.begin();
709 if (it != theFaces.end()) {
711 while (it != theFaces.end()) {
712 pd << ", " << (*it++);
718 // to provide warning
719 if (!isWarning) SetErrorCode(OK);
725 //=============================================================================
729 //=============================================================================
730 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::MakeExplode
731 (Handle(GEOM_Object) theShape,
732 const Standard_Integer theShapeType,
733 const Standard_Boolean isSorted)
737 if (theShape.IsNull()) return NULL;
738 TopoDS_Shape aShape = theShape->GetValue();
739 if (aShape.IsNull()) return NULL;
741 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
742 Handle(GEOM_Object) anObj;
743 Handle(GEOM_Function) aFunction;
744 TopTools_MapOfShape mapShape;
745 TopTools_ListOfShape listShape;
747 if (aShape.ShapeType() == TopAbs_COMPOUND &&
748 (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
749 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPSOLID ||
750 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPOUND)) {
751 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
752 for (; It.More(); It.Next()) {
753 if (mapShape.Add(It.Value())) {
754 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
755 TopAbs_ShapeEnum(theShapeType) == It.Value().ShapeType()) {
756 listShape.Append(It.Value());
761 TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
762 for (; exp.More(); exp.Next())
763 if (mapShape.Add(exp.Current()))
764 listShape.Append(exp.Current());
767 if (listShape.IsEmpty()) {
768 SetErrorCode("The given shape has no sub-shapes of the requested type");
773 SortShapes(listShape);
775 TopTools_IndexedMapOfShape anIndices;
776 TopExp::MapShapes(aShape, anIndices);
777 Handle(TColStd_HArray1OfInteger) anArray;
779 TopTools_ListIteratorOfListOfShape itSub (listShape);
780 TCollection_AsciiString anAsciiList, anEntry;
781 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
782 TopoDS_Shape aValue = itSub.Value();
783 anArray = new TColStd_HArray1OfInteger(1,1);
784 anArray->SetValue(1, anIndices.FindIndex(aValue));
785 anObj = GetEngine()->AddSubShape(theShape, anArray);
786 if (!anObj.IsNull()) {
789 // for python command
790 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
791 anAsciiList += anEntry;
796 //Make a Python command
797 anAsciiList.Trunc(anAsciiList.Length() - 1);
799 aFunction = theShape->GetLastFunction();
801 GEOM::TPythonDump pd (aFunction, /*append=*/true);
802 pd << "[" << anAsciiList.ToCString();
803 pd << "] = geompy.SubShapeAll" << (isSorted ? "Sorted(" : "(");
804 pd << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
811 //=============================================================================
815 //=============================================================================
816 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::SubShapeAllIDs
817 (Handle(GEOM_Object) theShape,
818 const Standard_Integer theShapeType,
819 const Standard_Boolean isSorted)
823 if (theShape.IsNull()) return NULL;
824 TopoDS_Shape aShape = theShape->GetValue();
825 if (aShape.IsNull()) return NULL;
827 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
828 TopTools_MapOfShape mapShape;
829 TopTools_ListOfShape listShape;
831 if (aShape.ShapeType() == TopAbs_COMPOUND &&
832 (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
833 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPSOLID ||
834 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPOUND)) {
835 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
836 for (; It.More(); It.Next()) {
837 if (mapShape.Add(It.Value())) {
838 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
839 TopAbs_ShapeEnum(theShapeType) == It.Value().ShapeType()) {
840 listShape.Append(It.Value());
845 TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
846 for (; exp.More(); exp.Next())
847 if (mapShape.Add(exp.Current()))
848 listShape.Append(exp.Current());
851 if (listShape.IsEmpty()) {
852 SetErrorCode("The given shape has no sub-shapes of the requested type");
857 SortShapes(listShape);
859 TopTools_IndexedMapOfShape anIndices;
860 TopExp::MapShapes(aShape, anIndices);
861 Handle(TColStd_HArray1OfInteger) anArray;
863 TopTools_ListIteratorOfListOfShape itSub (listShape);
864 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
865 TopoDS_Shape aValue = itSub.Value();
866 aSeq->Append(anIndices.FindIndex(aValue));
869 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
871 //Make a Python command
872 GEOM::TPythonDump pd (aFunction, /*append=*/true);
873 pd << "listSubShapeIDs = geompy.SubShapeAll";
874 pd << (isSorted ? "SortedIDs(" : "IDs(");
875 pd << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
881 //=============================================================================
885 //=============================================================================
886 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetSubShape
887 (Handle(GEOM_Object) theMainShape,
888 const Standard_Integer theID)
892 if (theMainShape.IsNull()) return NULL;
894 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
895 anArray->SetValue(1, theID);
896 Handle(GEOM_Object) anObj = GetEngine()->AddSubShape(theMainShape, anArray,true);
897 if (anObj.IsNull()) {
898 SetErrorCode("Can not get a sub-shape with the given ID");
902 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
904 //Make a Python command
905 GEOM::TPythonDump(aFunction) << anObj << " = geompy.GetSubShape("
906 << theMainShape << ", [" << theID << "])";
912 //=============================================================================
916 //=============================================================================
917 Standard_Integer GEOMImpl_IShapesOperations::GetSubShapeIndex (Handle(GEOM_Object) theMainShape,
918 Handle(GEOM_Object) theSubShape)
922 TopoDS_Shape aMainShape = theMainShape->GetValue();
923 TopoDS_Shape aSubShape = theSubShape->GetValue();
925 if (aMainShape.IsNull() || aSubShape.IsNull()) return -1;
927 TopTools_IndexedMapOfShape anIndices;
928 TopExp::MapShapes(aMainShape, anIndices);
929 if (anIndices.Contains(aSubShape)) {
931 return anIndices.FindIndex(aSubShape);
937 //=============================================================================
941 //=============================================================================
942 Standard_Integer GEOMImpl_IShapesOperations::GetTopologyIndex (Handle(GEOM_Object) theMainShape,
943 Handle(GEOM_Object) theSubShape)
947 TopoDS_Shape aMainShape = theMainShape->GetValue();
948 TopoDS_Shape aSubShape = theSubShape->GetValue();
950 if (aMainShape.IsNull() || aSubShape.IsNull()) {
951 SetErrorCode("Null argument shape given");
956 if (aSubShape.ShapeType() == TopAbs_COMPOUND) {
958 TopTools_ListOfShape CL;
959 CL.Append(aMainShape);
960 TopTools_ListIteratorOfListOfShape itC;
961 for (itC.Initialize(CL); itC.More(); itC.Next()) {
962 for (it.Initialize(itC.Value()); it.More(); it.Next()) {
963 if (it.Value().ShapeType() == TopAbs_COMPOUND) {
964 if (it.Value().IsSame(aSubShape))
968 CL.Append(it.Value());
973 TopExp_Explorer anExp (aMainShape, aSubShape.ShapeType());
974 TopTools_MapOfShape M;
975 for (; anExp.More(); anExp.Next()) {
976 if (M.Add(anExp.Current())) {
977 if (anExp.Current().IsSame(aSubShape))
984 SetErrorCode("The sub-shape does not belong to the main shape");
988 //=============================================================================
992 //=============================================================================
993 TCollection_AsciiString GEOMImpl_IShapesOperations::GetShapeTypeString (Handle(GEOM_Object) theShape)
997 TCollection_AsciiString aTypeName ("Null Shape");
999 TopoDS_Shape aShape = theShape->GetValue();
1000 if (aShape.IsNull())
1003 switch (aShape.ShapeType() )
1005 case TopAbs_COMPOUND:
1006 aTypeName = "Compound";
1008 case TopAbs_COMPSOLID:
1009 aTypeName = "Compound Solid";
1012 aTypeName = "Solid";
1015 aTypeName = "Shell";
1019 BRepAdaptor_Surface surf (TopoDS::Face(aShape));
1020 if (surf.GetType() == GeomAbs_Plane)
1021 aTypeName = "Plane";
1022 else if (surf.GetType() == GeomAbs_Cylinder)
1023 aTypeName = "Cylindrical Face";
1024 else if (surf.GetType() == GeomAbs_Sphere)
1025 aTypeName = "Spherical Face";
1026 else if (surf.GetType() == GeomAbs_Torus)
1027 aTypeName = "Toroidal Face";
1028 else if (surf.GetType() == GeomAbs_Cone)
1029 aTypeName = "Conical Face";
1031 aTypeName = "GEOM::FACE";
1039 BRepAdaptor_Curve curv (TopoDS::Edge(aShape));
1040 if (curv.GetType() == GeomAbs_Line) {
1041 if ((Abs(curv.FirstParameter()) >= 1E6) ||
1042 (Abs(curv.LastParameter()) >= 1E6))
1045 aTypeName = "Edge" ;
1046 } else if (curv.GetType() == GeomAbs_Circle) {
1047 if (curv.IsClosed())
1048 aTypeName = "Circle";
1057 aTypeName = "Vertex";
1060 aTypeName = "Shape";
1063 aTypeName = "Shape of unknown type";
1070 //=============================================================================
1074 //=============================================================================
1075 Standard_Integer GEOMImpl_IShapesOperations::NumberOfFaces (Handle(GEOM_Object) theShape)
1079 Standard_Integer nb = 0;
1081 if (theShape.IsNull()) return -1;
1082 TopoDS_Shape aShape = theShape->GetValue();
1083 if (aShape.IsNull()) return -1;
1085 TopTools_MapOfShape mapShape;
1087 TopExp_Explorer exp (aShape, TopAbs_FACE);
1088 for (; exp.More(); exp.Next())
1089 if (mapShape.Add(exp.Current()))
1096 //=============================================================================
1100 //=============================================================================
1101 Standard_Integer GEOMImpl_IShapesOperations::NumberOfEdges (Handle(GEOM_Object) theShape)
1105 Standard_Integer nb = 0;
1107 if (theShape.IsNull()) return -1;
1108 TopoDS_Shape aShape = theShape->GetValue();
1109 if (aShape.IsNull()) return -1;
1111 TopTools_MapOfShape mapShape;
1113 TopExp_Explorer exp (aShape, TopAbs_EDGE);
1114 for (; exp.More(); exp.Next())
1115 if (mapShape.Add(exp.Current()))
1122 //=============================================================================
1126 //=============================================================================
1127 Handle(GEOM_Object) GEOMImpl_IShapesOperations::ReverseShape(Handle(GEOM_Object) theShape)
1131 if (theShape.IsNull()) return NULL;
1133 //Add a new reversed object
1134 Handle(GEOM_Object) aReversed = GetEngine()->AddObject(GetDocID(), theShape->GetType());
1136 //Add a new Revese function
1137 Handle(GEOM_Function) aFunction;
1138 aFunction = aReversed->AddFunction(GEOMImpl_ShapeDriver::GetID(), REVERSE_ORIENTATION);
1139 if (aFunction.IsNull()) return NULL;
1141 //Check if the function is set correctly
1142 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
1144 GEOMImpl_IShapes aSI (aFunction);
1146 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
1147 if (aRefShape.IsNull()) return NULL;
1149 aSI.SetBase(aRefShape);
1151 //Compute the sub-shape value
1153 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
1156 if (!GetSolver()->ComputeFunction(aFunction)) {
1157 SetErrorCode("Shape driver failed to reverse shape");
1161 catch (Standard_Failure) {
1162 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1163 SetErrorCode(aFail->GetMessageString());
1167 //Make a Python command
1168 GEOM::TPythonDump(aFunction) << aReversed
1169 << " = geompy.ChangeOrientation(" << theShape << ")";
1175 //=============================================================================
1179 //=============================================================================
1180 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetFreeFacesIDs
1181 (Handle(GEOM_Object) theShape)
1185 if (theShape.IsNull()) return NULL;
1186 TopoDS_Shape aShape = theShape->GetValue();
1187 if (aShape.IsNull()) return NULL;
1189 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
1191 TopTools_IndexedDataMapOfShapeListOfShape mapFaceBlocks;
1192 GEOMImpl_Block6Explorer::MapShapesAndAncestors
1193 (aShape, TopAbs_FACE, TopAbs_SOLID, mapFaceBlocks);
1195 Standard_Integer ind = 1, nbFaces = mapFaceBlocks.Extent();
1198 SetErrorCode("The given shape has no faces");
1202 TopTools_IndexedMapOfShape anIndices;
1203 TopExp::MapShapes(aShape, anIndices);
1205 Standard_Integer id;
1206 for (; ind <= nbFaces; ind++) {
1207 if (mapFaceBlocks.FindFromIndex(ind).Extent() != 2) {
1208 id = anIndices.FindIndex(mapFaceBlocks.FindKey(ind));
1213 //The explode doesn't change object so no new function is required.
1214 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
1216 //Make a Python command
1217 GEOM::TPythonDump(aFunction, /*append=*/true)
1218 << "listFreeFacesIDs = geompy.GetFreeFacesIDs(" << theShape << ")";
1224 //=======================================================================
1225 //function : GetSharedShapes
1227 //=======================================================================
1229 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetSharedShapes
1230 (Handle(GEOM_Object) theShape1,
1231 Handle(GEOM_Object) theShape2,
1232 const Standard_Integer theShapeType)
1236 if (theShape1.IsNull() || theShape2.IsNull()) return NULL;
1238 TopoDS_Shape aShape1 = theShape1->GetValue();
1239 TopoDS_Shape aShape2 = theShape2->GetValue();
1241 if (aShape1.IsNull() || aShape2.IsNull()) return NULL;
1243 TopTools_IndexedMapOfShape anIndices;
1244 TopExp::MapShapes(aShape1, anIndices);
1245 Handle(TColStd_HArray1OfInteger) anArray;
1247 TopTools_IndexedMapOfShape mapShape1;
1248 TopExp::MapShapes(aShape1, TopAbs_ShapeEnum(theShapeType), mapShape1);
1250 Handle(GEOM_Object) anObj;
1251 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1252 TCollection_AsciiString anAsciiList, anEntry;
1254 TopTools_MapOfShape mapShape2;
1255 TopExp_Explorer exp (aShape2, TopAbs_ShapeEnum(theShapeType));
1256 for (; exp.More(); exp.Next()) {
1257 TopoDS_Shape aSS = exp.Current();
1258 if (mapShape2.Add(aSS) && mapShape1.Contains(aSS)) {
1259 anArray = new TColStd_HArray1OfInteger(1,1);
1260 anArray->SetValue(1, anIndices.FindIndex(aSS));
1261 anObj = GetEngine()->AddSubShape(theShape1, anArray);
1262 aSeq->Append(anObj);
1264 // for python command
1265 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
1266 anAsciiList += anEntry;
1271 if (aSeq->IsEmpty()) {
1272 SetErrorCode("The given shapes have no shared sub-shapes of the requested type");
1276 //Make a Python command
1277 anAsciiList.Trunc(anAsciiList.Length() - 1);
1279 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1281 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
1282 << "] = geompy.GetSharedShapes(" << theShape1 << ", "
1283 << theShape2 << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
1289 //=============================================================================
1293 //=============================================================================
1294 static GEOM::TPythonDump& operator<< (GEOM::TPythonDump& theDump,
1295 const GEOMAlgo_State theState)
1298 case GEOMAlgo_ST_IN:
1299 theDump << "geompy.GEOM.ST_IN";
1301 case GEOMAlgo_ST_OUT:
1302 theDump << "geompy.GEOM.ST_OUT";
1304 case GEOMAlgo_ST_ON:
1305 theDump << "geompy.GEOM.ST_ON";
1307 case GEOMAlgo_ST_ONIN:
1308 theDump << "geompy.GEOM.ST_ONIN";
1310 case GEOMAlgo_ST_ONOUT:
1311 theDump << "geompy.GEOM.ST_ONOUT";
1314 theDump << "geompy.GEOM.ST_UNKNOWN";
1320 //=======================================================================
1321 //function : checkTypeShapesOn
1323 * \brief Checks if theShapeType parameter of GetShapesOnXXX() is OK
1324 * \param theShapeType - the shape type to check
1325 * \retval bool - result of the check
1327 //=======================================================================
1329 bool GEOMImpl_IShapesOperations::checkTypeShapesOn(const Standard_Integer theShapeType)
1331 if (theShapeType != TopAbs_VERTEX &&
1332 theShapeType != TopAbs_EDGE &&
1333 theShapeType != TopAbs_FACE &&
1334 theShapeType != TopAbs_SOLID) {
1335 SetErrorCode("Only solids, vertices, edges or faces can be found by this method");
1341 //=======================================================================
1342 //function : makePlane
1344 * \brief Creates Geom_Plane
1345 * \param theAx1 - shape object defining plane parameters
1346 * \retval Handle(Geom_Surface) - resulting surface
1348 //=======================================================================
1350 Handle(Geom_Surface) GEOMImpl_IShapesOperations::makePlane(const TopoDS_Shape& anAx1)
1352 if (anAx1.ShapeType() != TopAbs_EDGE) return NULL;
1353 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
1354 TopoDS_Vertex V1, V2;
1355 TopExp::Vertices(anEdge, V1, V2, Standard_True);
1356 if (V1.IsNull() || V2.IsNull()) {
1357 SetErrorCode("Bad edge given for the plane normal vector");
1360 gp_Pnt aLoc = BRep_Tool::Pnt(V1);
1361 gp_Vec aVec (aLoc, BRep_Tool::Pnt(V2));
1362 if (aVec.Magnitude() < Precision::Confusion()) {
1363 SetErrorCode("Vector with null magnitude given");
1366 return new Geom_Plane(aLoc, aVec);
1369 //=======================================================================
1370 //function : makeCylinder
1372 * \brief Creates Geom_CylindricalSurface
1373 * \param theAx1 - edge defining cylinder axis
1374 * \param theRadius - cylinder radius
1375 * \retval Handle(Geom_Surface) - resulting surface
1377 //=======================================================================
1379 Handle(Geom_Surface) GEOMImpl_IShapesOperations::makeCylinder(const TopoDS_Shape& anAxis,
1380 const Standard_Real theRadius)
1382 //Axis of the cylinder
1383 if (anAxis.ShapeType() != TopAbs_EDGE) {
1384 SetErrorCode("Not an edge given for the axis");
1387 TopoDS_Edge anEdge = TopoDS::Edge(anAxis);
1388 TopoDS_Vertex V1, V2;
1389 TopExp::Vertices(anEdge, V1, V2, Standard_True);
1390 if (V1.IsNull() || V2.IsNull()) {
1391 SetErrorCode("Bad edge given for the axis");
1394 gp_Pnt aLoc = BRep_Tool::Pnt(V1);
1395 gp_Vec aVec (aLoc, BRep_Tool::Pnt(V2));
1396 if (aVec.Magnitude() < Precision::Confusion()) {
1397 SetErrorCode("Vector with null magnitude given");
1401 gp_Ax3 anAx3 (aLoc, aVec);
1402 return new Geom_CylindricalSurface(anAx3, theRadius);
1406 //=======================================================================
1407 //function : getShapesOnBoxIDs
1409 * \brief Find IDs of subshapes complying with given status about surface
1410 * \param theBox - the box to check state of subshapes against
1411 * \param theShape - the shape to explore
1412 * \param theShapeType - type of subshape of theShape
1413 * \param theState - required state
1414 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1416 //=======================================================================
1418 Handle(TColStd_HSequenceOfInteger)
1419 GEOMImpl_IShapesOperations::getShapesOnBoxIDs(const Handle(GEOM_Object)& theBox,
1420 const Handle(GEOM_Object)& theShape,
1421 const Standard_Integer theShapeType,
1422 GEOMAlgo_State theState)
1424 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
1426 TopoDS_Shape aBox = theBox->GetValue();
1427 TopoDS_Shape aShape = theShape->GetValue();
1429 // Check presence of triangulation, build if need
1430 if (!CheckTriangulation(aShape)) {
1431 SetErrorCode("Cannot build triangulation on the shape");
1436 GEOMAlgo_FinderShapeOn2 aFinder;
1437 Standard_Real aTol = 0.0001; // default value
1439 Handle(GEOMAlgo_ClsfBox) aClsfBox = new GEOMAlgo_ClsfBox;
1440 aClsfBox->SetBox(aBox);
1442 aFinder.SetShape(aShape);
1443 aFinder.SetTolerance(aTol);
1444 aFinder.SetClsf(aClsfBox);
1445 aFinder.SetShapeType( (TopAbs_ShapeEnum)theShapeType );
1446 aFinder.SetState(theState);
1449 // Interprete results
1450 Standard_Integer iErr = aFinder.ErrorStatus();
1451 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
1453 MESSAGE(" iErr : " << iErr);
1454 TCollection_AsciiString aMsg (" iErr : ");
1455 aMsg += TCollection_AsciiString(iErr);
1459 Standard_Integer iWrn = aFinder.WarningStatus();
1460 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
1462 MESSAGE(" *** iWrn : " << iWrn);
1465 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
1467 if (listSS.Extent() < 1) {
1468 SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
1472 // Fill sequence of object IDs
1473 aSeqOfIDs = new TColStd_HSequenceOfInteger;
1475 TopTools_IndexedMapOfShape anIndices;
1476 TopExp::MapShapes(aShape, anIndices);
1478 TopTools_ListIteratorOfListOfShape itSub (listSS);
1479 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
1480 int id = anIndices.FindIndex(itSub.Value());
1481 aSeqOfIDs->Append(id);
1488 //=======================================================================
1489 //function : GetShapesOnBoxIDs
1491 * \brief Find subshapes complying with given status about surface
1492 * \param theBox - the box to check state of subshapes against
1493 * \param theShape - the shape to explore
1494 * \param theShapeType - type of subshape of theShape
1495 * \param theState - required state
1496 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1498 //=======================================================================
1500 Handle(TColStd_HSequenceOfInteger)
1501 GEOMImpl_IShapesOperations::GetShapesOnBoxIDs(const Handle(GEOM_Object)& theBox,
1502 const Handle(GEOM_Object)& theShape,
1503 const Standard_Integer theShapeType,
1504 GEOMAlgo_State theState)
1506 // Find subshapes ids
1507 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
1508 getShapesOnBoxIDs (theBox, theShape, theShapeType, theState);
1509 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
1512 // The GetShapesOnBox() doesn't change object so no new function is required.
1513 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theBox)->GetLastFunction();
1515 // Make a Python command
1516 GEOM::TPythonDump(aFunction)
1517 << "listShapesOnBoxIDs = geompy.GetShapesOnQuadrangleIDs("
1520 << TopAbs_ShapeEnum(theShapeType) << ", "
1527 //=======================================================================
1528 //function : GetShapesOnBox
1530 * \brief Find subshapes complying with given status about surface
1531 * \param theBox - the box to check state of subshapes against
1532 * \param theShape - the shape to explore
1533 * \param theShapeType - type of subshape of theShape
1534 * \param theState - required state
1535 * \retval Handle(TColStd_HSequenceOfTransient) - found subshapes
1537 //=======================================================================
1539 Handle(TColStd_HSequenceOfTransient)
1540 GEOMImpl_IShapesOperations::GetShapesOnBox(const Handle(GEOM_Object)& theBox,
1541 const Handle(GEOM_Object)& theShape,
1542 const Standard_Integer theShapeType,
1543 GEOMAlgo_State theState)
1545 // Find subshapes ids
1546 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
1547 getShapesOnBoxIDs (theBox, theShape, theShapeType, theState);
1548 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
1551 // Find objects by indices
1552 TCollection_AsciiString anAsciiList;
1553 Handle(TColStd_HSequenceOfTransient) aSeq;
1554 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
1555 if ( aSeq.IsNull() || aSeq->IsEmpty() )
1558 // Make a Python command
1560 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
1561 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1563 GEOM::TPythonDump(aFunction)
1564 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnBox("
1567 << TopAbs_ShapeEnum(theShapeType) << ", "
1575 //=======================================================================
1576 //function : getShapesOnSurfaceIDs
1578 * \brief Find IDs of subshapes complying with given status about surface
1579 * \param theSurface - the surface to check state of subshapes against
1580 * \param theShape - the shape to explore
1581 * \param theShapeType - type of subshape of theShape
1582 * \param theState - required state
1583 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1585 //=======================================================================
1587 Handle(TColStd_HSequenceOfInteger)
1588 GEOMImpl_IShapesOperations::getShapesOnSurfaceIDs(const Handle(Geom_Surface)& theSurface,
1589 const TopoDS_Shape& theShape,
1590 TopAbs_ShapeEnum theShapeType,
1591 GEOMAlgo_State theState)
1593 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
1595 // Check presence of triangulation, build if need
1596 if (!CheckTriangulation(theShape)) {
1597 SetErrorCode("Cannot build triangulation on the shape");
1602 GEOMAlgo_FinderShapeOn1 aFinder;
1603 Standard_Real aTol = 0.0001; // default value
1605 aFinder.SetShape(theShape);
1606 aFinder.SetTolerance(aTol);
1607 aFinder.SetSurface(theSurface);
1608 aFinder.SetShapeType(theShapeType);
1609 aFinder.SetState(theState);
1611 // Sets the minimal number of inner points for the faces that do not have own
1612 // inner points at all (for e.g. rectangular planar faces have just 2 triangles).
1614 aFinder.SetNbPntsMin(3);
1615 // Sets the maximal number of inner points for edges or faces.
1616 // It is usefull for the cases when this number is very big (e.g =2000) to improve
1617 // the performance. If this value =0, all inner points will be taken into account.
1619 aFinder.SetNbPntsMax(100);
1623 // Interprete results
1624 Standard_Integer iErr = aFinder.ErrorStatus();
1625 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
1627 MESSAGE(" iErr : " << iErr);
1628 TCollection_AsciiString aMsg (" iErr : ");
1629 aMsg += TCollection_AsciiString(iErr);
1633 Standard_Integer iWrn = aFinder.WarningStatus();
1634 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
1636 MESSAGE(" *** iWrn : " << iWrn);
1639 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
1641 if (listSS.Extent() < 1) {
1642 SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
1646 // Fill sequence of object IDs
1647 aSeqOfIDs = new TColStd_HSequenceOfInteger;
1649 TopTools_IndexedMapOfShape anIndices;
1650 TopExp::MapShapes(theShape, anIndices);
1652 TopTools_ListIteratorOfListOfShape itSub (listSS);
1653 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
1654 int id = anIndices.FindIndex(itSub.Value());
1655 aSeqOfIDs->Append(id);
1661 //=======================================================================
1662 //function : getObjectsShapesOn
1664 * \brief Find shape objects and their entries by their ids
1665 * \param theShapeIDs - incoming shape ids
1666 * \param theShapeEntries - outgoing entries like "entry1, entry2, ..."
1667 * \retval Handle(TColStd_HSequenceOfTransient) - found shape objects
1669 //=======================================================================
1671 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::
1672 getObjectsShapesOn(const Handle(GEOM_Object)& theShape,
1673 const Handle(TColStd_HSequenceOfInteger)& theShapeIDs,
1674 TCollection_AsciiString & theShapeEntries)
1676 Handle(TColStd_HSequenceOfTransient) aSeq;
1678 if ( !theShapeIDs.IsNull() && theShapeIDs->Length() > 0 )
1680 aSeq = new TColStd_HSequenceOfTransient;
1681 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
1682 TCollection_AsciiString anEntry;
1683 for ( int i = 1; i <= theShapeIDs->Length(); ++i )
1685 anArray->SetValue(1, theShapeIDs->Value( i ));
1686 Handle(GEOM_Object) anObj = GetEngine()->AddSubShape(theShape, anArray);
1687 aSeq->Append( anObj );
1689 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
1690 if ( i != 1 ) theShapeEntries += ",";
1691 theShapeEntries += anEntry;
1697 //=======================================================================
1698 //function : getShapesOnSurface
1700 * \brief Find subshapes complying with given status about surface
1701 * \param theSurface - the surface to check state of subshapes against
1702 * \param theShape - the shape to explore
1703 * \param theShapeType - type of subshape of theShape
1704 * \param theState - required state
1705 * \param theShapeEntries - outgoing entries like "entry1, entry2, ..."
1706 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1708 //=======================================================================
1710 Handle(TColStd_HSequenceOfTransient)
1711 GEOMImpl_IShapesOperations::getShapesOnSurface(const Handle(Geom_Surface)& theSurface,
1712 const Handle(GEOM_Object)& theShape,
1713 TopAbs_ShapeEnum theShapeType,
1714 GEOMAlgo_State theState,
1715 TCollection_AsciiString & theShapeEntries)
1717 // Find subshapes ids
1718 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
1719 getShapesOnSurfaceIDs (theSurface, theShape->GetValue(), theShapeType, theState);
1720 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
1723 return getObjectsShapesOn( theShape, aSeqOfIDs, theShapeEntries );
1726 //=============================================================================
1730 //=============================================================================
1731 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnPlane
1732 (const Handle(GEOM_Object)& theShape,
1733 const Standard_Integer theShapeType,
1734 const Handle(GEOM_Object)& theAx1,
1735 const GEOMAlgo_State theState)
1739 if (theShape.IsNull() || theAx1.IsNull()) return NULL;
1741 TopoDS_Shape aShape = theShape->GetValue();
1742 TopoDS_Shape anAx1 = theAx1->GetValue();
1744 if (aShape.IsNull() || anAx1.IsNull()) return NULL;
1746 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
1747 if ( !checkTypeShapesOn( theShapeType ))
1751 Handle(Geom_Surface) aPlane = makePlane( anAx1 );
1752 if ( aPlane.IsNull() )
1756 TCollection_AsciiString anAsciiList;
1757 Handle(TColStd_HSequenceOfTransient) aSeq;
1758 aSeq = getShapesOnSurface( aPlane, theShape, aShapeType, theState, anAsciiList );
1759 if ( aSeq.IsNull() || aSeq->Length() == 0 )
1762 // Make a Python command
1764 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
1765 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1767 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
1768 << "] = geompy.GetShapesOnPlane(" << theShape << ", "
1769 << aShapeType << ", " << theAx1 << ", " << theState << ")";
1775 //=============================================================================
1777 * GetShapesOnPlaneWithLocation
1779 //=============================================================================
1780 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnPlaneWithLocation
1781 (const Handle(GEOM_Object)& theShape,
1782 const Standard_Integer theShapeType,
1783 const Handle(GEOM_Object)& theAx1,
1784 const Handle(GEOM_Object)& thePnt,
1785 const GEOMAlgo_State theState)
1789 if (theShape.IsNull() || theAx1.IsNull() || thePnt.IsNull()) return NULL;
1791 TopoDS_Shape aShape = theShape->GetValue();
1792 TopoDS_Shape anAx1 = theAx1->GetValue();
1793 TopoDS_Shape anPnt = thePnt->GetValue();
1795 if (aShape.IsNull() || anAx1.IsNull() || anPnt.IsNull()) return NULL;
1797 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
1798 if ( !checkTypeShapesOn( theShapeType ))
1802 if ( anAx1.ShapeType() != TopAbs_EDGE || anPnt.ShapeType() != TopAbs_VERTEX ) return NULL;
1803 TopoDS_Vertex V1, V2, V3;
1804 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
1805 TopExp::Vertices(anEdge, V1, V2, Standard_True);
1807 if (V1.IsNull() || V2.IsNull()) {
1808 SetErrorCode("Bad edge given for the plane normal vector");
1811 V3 = TopoDS::Vertex(anPnt);
1814 SetErrorCode("Bad vertex given for the plane location");
1817 gp_Pnt aLoc = BRep_Tool::Pnt(V3);
1818 gp_Vec aVec(BRep_Tool::Pnt(V1),BRep_Tool::Pnt(V2));
1820 if (aVec.Magnitude() < Precision::Confusion()) {
1821 SetErrorCode("Vector with null magnitude given");
1824 Handle(Geom_Surface) aPlane = new Geom_Plane(aLoc, aVec);
1826 if ( aPlane.IsNull() )
1830 TCollection_AsciiString anAsciiList;
1831 Handle(TColStd_HSequenceOfTransient) aSeq;
1832 aSeq = getShapesOnSurface( aPlane, theShape, aShapeType, theState, anAsciiList );
1833 if ( aSeq.IsNull() || aSeq->Length() == 0 )
1836 // Make a Python command
1838 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
1839 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1841 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
1842 << "] = geompy.GetShapesOnPlaneWithLocation(" << theShape << ", "
1843 << aShapeType << ", " << theAx1 << ", "<< thePnt <<", " << theState << ")";
1849 //=============================================================================
1851 * GetShapesOnCylinder
1853 //=============================================================================
1854 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnCylinder
1855 (const Handle(GEOM_Object)& theShape,
1856 const Standard_Integer theShapeType,
1857 const Handle(GEOM_Object)& theAxis,
1858 const Standard_Real theRadius,
1859 const GEOMAlgo_State theState)
1863 if (theShape.IsNull() || theAxis.IsNull()) return NULL;
1865 TopoDS_Shape aShape = theShape->GetValue();
1866 TopoDS_Shape anAxis = theAxis->GetValue();
1868 if (aShape.IsNull() || anAxis.IsNull()) return NULL;
1870 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
1871 if ( !checkTypeShapesOn( aShapeType ))
1874 // Create a cylinder surface
1875 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
1876 if ( aCylinder.IsNull() )
1880 TCollection_AsciiString anAsciiList;
1881 Handle(TColStd_HSequenceOfTransient) aSeq;
1882 aSeq = getShapesOnSurface( aCylinder, theShape, aShapeType, theState, anAsciiList );
1883 if ( aSeq.IsNull() || aSeq->Length() == 0 )
1886 // Make a Python command
1888 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
1889 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1891 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
1892 << "] = geompy.GetShapesOnCylinder(" << theShape << ", " << aShapeType
1893 << ", " << theAxis << ", " << theRadius << ", " << theState << ")";
1899 //=============================================================================
1903 //=============================================================================
1904 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnSphere
1905 (const Handle(GEOM_Object)& theShape,
1906 const Standard_Integer theShapeType,
1907 const Handle(GEOM_Object)& theCenter,
1908 const Standard_Real theRadius,
1909 const GEOMAlgo_State theState)
1913 if (theShape.IsNull() || theCenter.IsNull()) return NULL;
1915 TopoDS_Shape aShape = theShape->GetValue();
1916 TopoDS_Shape aCenter = theCenter->GetValue();
1918 if (aShape.IsNull() || aCenter.IsNull()) return NULL;
1920 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
1921 if ( !checkTypeShapesOn( aShapeType ))
1924 // Center of the sphere
1925 if (aCenter.ShapeType() != TopAbs_VERTEX) return NULL;
1926 gp_Pnt aLoc = BRep_Tool::Pnt(TopoDS::Vertex(aCenter));
1928 gp_Ax3 anAx3 (aLoc, gp::DZ());
1929 Handle(Geom_SphericalSurface) aSphere =
1930 new Geom_SphericalSurface(anAx3, theRadius);
1933 TCollection_AsciiString anAsciiList;
1934 Handle(TColStd_HSequenceOfTransient) aSeq;
1935 aSeq = getShapesOnSurface( aSphere, theShape, aShapeType, theState, anAsciiList );
1936 if ( aSeq.IsNull() || aSeq->Length() == 0 )
1939 // Make a Python command
1941 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
1942 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1944 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
1945 << "] = geompy.GetShapesOnSphere(" << theShape << ", " << aShapeType
1946 << ", " << theCenter << ", " << theRadius << ", " << theState << ")";
1952 //=============================================================================
1954 * GetShapesOnPlaneIDs
1956 //=============================================================================
1957 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnPlaneIDs
1958 (const Handle(GEOM_Object)& theShape,
1959 const Standard_Integer theShapeType,
1960 const Handle(GEOM_Object)& theAx1,
1961 const GEOMAlgo_State theState)
1965 if (theShape.IsNull() || theAx1.IsNull()) return NULL;
1967 TopoDS_Shape aShape = theShape->GetValue();
1968 TopoDS_Shape anAx1 = theAx1->GetValue();
1970 if (aShape.IsNull() || anAx1.IsNull()) return NULL;
1972 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
1973 if ( !checkTypeShapesOn( aShapeType ))
1977 Handle(Geom_Surface) aPlane = makePlane( anAx1 );
1978 if ( aPlane.IsNull() )
1982 Handle(TColStd_HSequenceOfInteger) aSeq;
1983 aSeq = getShapesOnSurfaceIDs( aPlane, aShape, aShapeType, theState );
1985 // The GetShapesOnPlaneIDs() doesn't change object so no new function is required.
1986 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAx1)->GetLastFunction();
1988 // Make a Python command
1989 GEOM::TPythonDump(aFunction, /*append=*/true)
1990 << "listShapesOnPlane = geompy.GetShapesOnPlaneIDs"
1991 << "(" << theShape << "," << aShapeType << "," << theAx1 << "," << theState << ")";
1997 //=============================================================================
1999 * GetShapesOnPlaneWithLocationIDs
2001 //=============================================================================
2002 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnPlaneWithLocationIDs
2003 (const Handle(GEOM_Object)& theShape,
2004 const Standard_Integer theShapeType,
2005 const Handle(GEOM_Object)& theAx1,
2006 const Handle(GEOM_Object)& thePnt,
2007 const GEOMAlgo_State theState)
2011 if (theShape.IsNull() || theAx1.IsNull() || thePnt.IsNull()) return NULL;
2013 TopoDS_Shape aShape = theShape->GetValue();
2014 TopoDS_Shape anAx1 = theAx1->GetValue();
2015 TopoDS_Shape anPnt = thePnt->GetValue();
2017 if (aShape.IsNull() || anAx1.IsNull() || anPnt.IsNull()) return NULL;
2019 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2020 if ( !checkTypeShapesOn( aShapeType ))
2024 if (anAx1.ShapeType() != TopAbs_EDGE || anPnt.ShapeType() != TopAbs_VERTEX) return NULL;
2025 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
2026 TopoDS_Vertex V1, V2, V3;
2027 TopExp::Vertices(anEdge, V1, V2, Standard_True);
2028 if (V1.IsNull() || V2.IsNull()) {
2029 SetErrorCode("Bad edge given for the plane normal vector");
2032 V3 = TopoDS::Vertex(anPnt);
2034 SetErrorCode("Bad vertex given for the plane location");
2037 gp_Pnt aLoc = BRep_Tool::Pnt(V3);
2038 gp_Vec aVec(BRep_Tool::Pnt(V1),BRep_Tool::Pnt(V2));
2039 if (aVec.Magnitude() < Precision::Confusion()) {
2040 SetErrorCode("Vector with null magnitude given");
2044 Handle(Geom_Surface) aPlane = new Geom_Plane(aLoc, aVec);
2045 if ( aPlane.IsNull() )
2049 Handle(TColStd_HSequenceOfInteger) aSeq;
2050 aSeq = getShapesOnSurfaceIDs( aPlane, aShape, aShapeType, theState );
2052 // The GetShapesOnPlaneIDs() doesn't change object so no new function is required.
2053 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAx1)->GetLastFunction();
2055 // Make a Python command
2056 GEOM::TPythonDump(aFunction, /*append=*/true)
2057 << "listShapesOnPlane = geompy.GetShapesOnPlaneWithLocationIDs"
2058 << "(" << theShape << ", " << aShapeType << ", " << theAx1 << ", "<< thePnt << ", " << theState << ")";
2064 //=============================================================================
2066 * GetShapesOnCylinderIDs
2068 //=============================================================================
2069 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnCylinderIDs
2070 (const Handle(GEOM_Object)& theShape,
2071 const Standard_Integer theShapeType,
2072 const Handle(GEOM_Object)& theAxis,
2073 const Standard_Real theRadius,
2074 const GEOMAlgo_State theState)
2078 if (theShape.IsNull() || theAxis.IsNull()) return NULL;
2080 TopoDS_Shape aShape = theShape->GetValue();
2081 TopoDS_Shape anAxis = theAxis->GetValue();
2083 if (aShape.IsNull() || anAxis.IsNull()) return NULL;
2085 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2086 if ( !checkTypeShapesOn( aShapeType ))
2089 // Create a cylinder surface
2090 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
2091 if ( aCylinder.IsNull() )
2095 Handle(TColStd_HSequenceOfInteger) aSeq;
2096 aSeq = getShapesOnSurfaceIDs( aCylinder, aShape, aShapeType, theState );
2098 // The GetShapesOnCylinder() doesn't change object so no new function is required.
2099 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAxis)->GetLastFunction();
2101 // Make a Python command
2102 GEOM::TPythonDump(aFunction, /*append=*/true)
2103 << "listShapesOnCylinder = geompy.GetShapesOnCylinderIDs"
2104 << "(" << theShape << ", " << aShapeType << ", " << theAxis << ", "
2105 << theRadius << ", " << theState << ")";
2111 //=============================================================================
2113 * GetShapesOnSphereIDs
2115 //=============================================================================
2116 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnSphereIDs
2117 (const Handle(GEOM_Object)& theShape,
2118 const Standard_Integer theShapeType,
2119 const Handle(GEOM_Object)& theCenter,
2120 const Standard_Real theRadius,
2121 const GEOMAlgo_State theState)
2125 if (theShape.IsNull() || theCenter.IsNull()) return NULL;
2127 TopoDS_Shape aShape = theShape->GetValue();
2128 TopoDS_Shape aCenter = theCenter->GetValue();
2130 if (aShape.IsNull() || aCenter.IsNull()) return NULL;
2132 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2133 if ( !checkTypeShapesOn( aShapeType ))
2136 // Center of the sphere
2137 if (aCenter.ShapeType() != TopAbs_VERTEX) return NULL;
2138 gp_Pnt aLoc = BRep_Tool::Pnt(TopoDS::Vertex(aCenter));
2140 gp_Ax3 anAx3 (aLoc, gp::DZ());
2141 Handle(Geom_SphericalSurface) aSphere =
2142 new Geom_SphericalSurface(anAx3, theRadius);
2145 Handle(TColStd_HSequenceOfInteger) aSeq;
2146 aSeq = getShapesOnSurfaceIDs( aSphere, aShape, aShapeType, theState );
2148 // The GetShapesOnSphere() doesn't change object so no new function is required.
2149 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theCenter)->GetLastFunction();
2151 // Make a Python command
2152 GEOM::TPythonDump(aFunction, /*append=*/true)
2153 << "listShapesOnCylinder = geompy.GetShapesOnCylinderIDs"
2154 << "(" << theShape << ", " << aShapeType << ", " << theCenter << ", "
2155 << theRadius << ", " << theState << ")";
2161 //=======================================================================
2162 //function : getShapesOnQuadrangleIDs
2164 * \brief Find IDs of subshapes complying with given status about quadrangle
2165 * \param theShape - the shape to explore
2166 * \param theShapeType - type of subshape of theShape
2167 * \param theTopLeftPoint - top left quadrangle corner
2168 * \param theTopRigthPoint - top right quadrangle corner
2169 * \param theBottomLeftPoint - bottom left quadrangle corner
2170 * \param theBottomRigthPoint - bottom right quadrangle corner
2171 * \param theState - required state
2172 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
2174 //=======================================================================
2176 Handle(TColStd_HSequenceOfInteger)
2177 GEOMImpl_IShapesOperations::getShapesOnQuadrangleIDs (const Handle(GEOM_Object)& theShape,
2178 const Standard_Integer theShapeType,
2179 const Handle(GEOM_Object)& theTopLeftPoint,
2180 const Handle(GEOM_Object)& theTopRigthPoint,
2181 const Handle(GEOM_Object)& theBottomLeftPoint,
2182 const Handle(GEOM_Object)& theBottomRigthPoint,
2183 const GEOMAlgo_State theState)
2187 if ( theShape.IsNull() ||
2188 theTopLeftPoint.IsNull() ||
2189 theTopRigthPoint.IsNull() ||
2190 theBottomLeftPoint.IsNull() ||
2191 theBottomRigthPoint.IsNull() )
2194 TopoDS_Shape aShape = theShape->GetValue();
2195 TopoDS_Shape aTL = theTopLeftPoint->GetValue();
2196 TopoDS_Shape aTR = theTopRigthPoint->GetValue();
2197 TopoDS_Shape aBL = theBottomLeftPoint->GetValue();
2198 TopoDS_Shape aBR = theBottomRigthPoint->GetValue();
2200 if (aShape.IsNull() ||
2205 aTL.ShapeType() != TopAbs_VERTEX ||
2206 aTR.ShapeType() != TopAbs_VERTEX ||
2207 aBL.ShapeType() != TopAbs_VERTEX ||
2208 aBR.ShapeType() != TopAbs_VERTEX )
2211 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2212 if ( !checkTypeShapesOn( aShapeType ))
2215 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
2217 // Check presence of triangulation, build if need
2218 if (!CheckTriangulation(aShape)) {
2219 SetErrorCode("Cannot build triangulation on the shape");
2224 gp_Pnt aPntTL = BRep_Tool::Pnt(TopoDS::Vertex(aTL));
2225 gp_Pnt aPntTR = BRep_Tool::Pnt(TopoDS::Vertex(aTR));
2226 gp_Pnt aPntBL = BRep_Tool::Pnt(TopoDS::Vertex(aBL));
2227 gp_Pnt aPntBR = BRep_Tool::Pnt(TopoDS::Vertex(aBR));
2229 GEOMAlgo_FinderShapeOnQuad aFinder( aPntTL, aPntTR, aPntBL, aPntBR );
2230 Standard_Real aTol = 0.0001; // default value
2232 aFinder.SetShape(aShape);
2233 aFinder.SetTolerance(aTol);
2234 //aFinder.SetSurface(theSurface);
2235 aFinder.SetShapeType(aShapeType);
2236 aFinder.SetState(theState);
2238 // Sets the minimal number of inner points for the faces that do not have own
2239 // inner points at all (for e.g. rectangular planar faces have just 2 triangles).
2241 aFinder.SetNbPntsMin(3);
2242 // Sets the maximal number of inner points for edges or faces.
2243 // It is usefull for the cases when this number is very big (e.g =2000) to improve
2244 // the performance. If this value =0, all inner points will be taken into account.
2246 aFinder.SetNbPntsMax(100);
2250 // Interprete results
2251 Standard_Integer iErr = aFinder.ErrorStatus();
2252 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
2254 MESSAGE(" iErr : " << iErr);
2255 TCollection_AsciiString aMsg (" iErr : ");
2256 aMsg += TCollection_AsciiString(iErr);
2260 Standard_Integer iWrn = aFinder.WarningStatus();
2261 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
2263 MESSAGE(" *** iWrn : " << iWrn);
2266 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
2268 if (listSS.Extent() < 1) {
2269 SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
2273 // Fill sequence of object IDs
2274 aSeqOfIDs = new TColStd_HSequenceOfInteger;
2276 TopTools_IndexedMapOfShape anIndices;
2277 TopExp::MapShapes(aShape, anIndices);
2279 TopTools_ListIteratorOfListOfShape itSub (listSS);
2280 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
2281 int id = anIndices.FindIndex(itSub.Value());
2282 aSeqOfIDs->Append(id);
2287 //=======================================================================
2288 //function : GetShapesOnQuadrangle
2290 * \brief Find subshapes complying with given status about quadrangle
2291 * \param theShape - the shape to explore
2292 * \param theShapeType - type of subshape of theShape
2293 * \param theTopLeftPoint - top left quadrangle corner
2294 * \param theTopRigthPoint - top right quadrangle corner
2295 * \param theBottomLeftPoint - bottom left quadrangle corner
2296 * \param theBottomRigthPoint - bottom right quadrangle corner
2297 * \param theState - required state
2298 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
2300 //=======================================================================
2302 Handle(TColStd_HSequenceOfTransient)
2303 GEOMImpl_IShapesOperations::GetShapesOnQuadrangle (const Handle(GEOM_Object)& theShape,
2304 const Standard_Integer theShapeType,
2305 const Handle(GEOM_Object)& theTopLeftPoint,
2306 const Handle(GEOM_Object)& theTopRigthPoint,
2307 const Handle(GEOM_Object)& theBottomLeftPoint,
2308 const Handle(GEOM_Object)& theBottomRigthPoint,
2309 const GEOMAlgo_State theState)
2312 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2313 getShapesOnQuadrangleIDs( theShape,
2318 theBottomRigthPoint,
2320 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->IsEmpty() )
2323 // Find objects by indices
2324 TCollection_AsciiString anAsciiList;
2325 Handle(TColStd_HSequenceOfTransient) aSeq;
2326 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
2327 if ( aSeq.IsNull() || aSeq->IsEmpty() )
2330 // Make a Python command
2332 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2333 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2335 GEOM::TPythonDump(aFunction)
2336 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnQuadrangle("
2338 << TopAbs_ShapeEnum(theShapeType) << ", "
2339 << theTopLeftPoint << ", "
2340 << theTopRigthPoint << ", "
2341 << theBottomLeftPoint << ", "
2342 << theBottomRigthPoint << ", "
2349 //=======================================================================
2350 //function : GetShapesOnQuadrangleIDs
2352 * \brief Find IDs of subshapes complying with given status about quadrangle
2353 * \param theShape - the shape to explore
2354 * \param theShapeType - type of subshape of theShape
2355 * \param theTopLeftPoint - top left quadrangle corner
2356 * \param theTopRigthPoint - top right quadrangle corner
2357 * \param theBottomLeftPoint - bottom left quadrangle corner
2358 * \param theBottomRigthPoint - bottom right quadrangle corner
2359 * \param theState - required state
2360 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
2362 //=======================================================================
2364 Handle(TColStd_HSequenceOfInteger)
2365 GEOMImpl_IShapesOperations::GetShapesOnQuadrangleIDs (const Handle(GEOM_Object)& theShape,
2366 const Standard_Integer theShapeType,
2367 const Handle(GEOM_Object)& theTopLeftPoint,
2368 const Handle(GEOM_Object)& theTopRigthPoint,
2369 const Handle(GEOM_Object)& theBottomLeftPoint,
2370 const Handle(GEOM_Object)& theBottomRigthPoint,
2371 const GEOMAlgo_State theState)
2374 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2375 getShapesOnQuadrangleIDs( theShape,
2380 theBottomRigthPoint,
2382 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->IsEmpty() )
2385 // Make a Python command
2387 // The GetShapesOnCylinder() doesn't change object so no new function is required.
2388 Handle(GEOM_Object) lastObj = GEOM::GetCreatedLast(theShape,theTopLeftPoint);
2389 lastObj = GEOM::GetCreatedLast(lastObj,theTopRigthPoint);
2390 lastObj = GEOM::GetCreatedLast(lastObj,theBottomRigthPoint);
2391 lastObj = GEOM::GetCreatedLast(lastObj,theBottomLeftPoint);
2392 Handle(GEOM_Function) aFunction = lastObj->GetLastFunction();
2394 GEOM::TPythonDump(aFunction, /*append=*/true)
2395 << "listShapesOnQuadrangle = geompy.GetShapesOnQuadrangleIDs("
2397 << TopAbs_ShapeEnum(theShapeType) << ", "
2398 << theTopLeftPoint << ", "
2399 << theTopRigthPoint << ", "
2400 << theBottomLeftPoint << ", "
2401 << theBottomRigthPoint << ", "
2409 //=============================================================================
2413 //=============================================================================
2414 static bool GetInPlaceOfShape (const Handle(GEOM_Function)& theWhereFunction,
2415 const TopTools_IndexedMapOfShape& theWhereIndices,
2416 const TopoDS_Shape& theWhat,
2417 TColStd_ListOfInteger& theModifiedList)
2419 if (theWhereFunction.IsNull() || theWhat.IsNull()) return false;
2421 if (theWhereIndices.Contains(theWhat)) {
2422 // entity was not changed by the operation
2423 Standard_Integer aWhatIndex = theWhereIndices.FindIndex(theWhat);
2424 theModifiedList.Append(aWhatIndex);
2428 // try to find in history
2429 TDF_Label aHistoryLabel = theWhereFunction->GetHistoryEntry(Standard_False);
2431 // search in history for all argument shapes
2432 Standard_Boolean isFound = Standard_False;
2433 Standard_Boolean isGood = Standard_False;
2435 TDF_LabelSequence aLabelSeq;
2436 theWhereFunction->GetDependency(aLabelSeq);
2437 Standard_Integer nbArg = aLabelSeq.Length();
2439 for (Standard_Integer iarg = 1; iarg <= nbArg && !isFound; iarg++) {
2441 TDF_Label anArgumentRefLabel = aLabelSeq.Value(iarg);
2443 Handle(GEOM_Object) anArgumentObject = GEOM_Object::GetReferencedObject(anArgumentRefLabel);
2444 TopoDS_Shape anArgumentShape = anArgumentObject->GetValue();
2446 TopTools_IndexedMapOfShape anArgumentIndices;
2447 TopExp::MapShapes(anArgumentShape, anArgumentIndices);
2449 if (anArgumentIndices.Contains(theWhat)) {
2450 isFound = Standard_True;
2451 Standard_Integer aWhatIndex = anArgumentIndices.FindIndex(theWhat);
2453 // Find corresponding label in history
2454 TDF_Label anArgumentHistoryLabel =
2455 theWhereFunction->GetArgumentHistoryEntry(anArgumentRefLabel, Standard_False);
2456 if (anArgumentHistoryLabel.IsNull()) {
2457 // Lost History of operation argument. Possibly, all its entities was removed.
2458 isGood = Standard_True;
2461 TDF_Label aWhatHistoryLabel = anArgumentHistoryLabel.FindChild(aWhatIndex, Standard_False);
2463 if (aWhatHistoryLabel.IsNull()) {
2464 // Removed entity ? Compound ? Compsolid ? Shell ? Wire
2465 isGood = Standard_False;
2467 Handle(TDataStd_IntegerArray) anIntegerArray;
2468 if (!aWhatHistoryLabel.FindAttribute(TDataStd_IntegerArray::GetID(), anIntegerArray)) {
2469 //Error: Empty modifications history for the sought shape.
2470 isGood = Standard_False;
2473 isGood = Standard_True;
2474 Standard_Integer imod, aModifLen = anIntegerArray->Array()->Length();
2475 for (imod = 1; imod <= aModifLen; imod++) {
2476 theModifiedList.Append(anIntegerArray->Array()->Value(imod));
2487 // try compound/compsolid/shell/wire element by element
2488 bool isFoundAny = false;
2489 TopTools_MapOfShape mapShape;
2491 if (theWhat.ShapeType() == TopAbs_COMPOUND ||
2492 theWhat.ShapeType() == TopAbs_COMPSOLID) {
2493 // recursive processing of compound/compsolid
2494 TopoDS_Iterator anIt (theWhat, Standard_True, Standard_True);
2495 for (; anIt.More(); anIt.Next()) {
2496 if (mapShape.Add(anIt.Value())) {
2497 TopoDS_Shape curWhat = anIt.Value();
2498 isFoundAny = GetInPlaceOfShape(theWhereFunction, theWhereIndices, curWhat, theModifiedList);
2499 if (isFoundAny) isFound = Standard_True;
2503 else if (theWhat.ShapeType() == TopAbs_SHELL) {
2504 // try to replace a shell by its faces images
2505 TopExp_Explorer anExp (theWhat, TopAbs_FACE);
2506 for (; anExp.More(); anExp.Next()) {
2507 if (mapShape.Add(anExp.Current())) {
2508 TopoDS_Shape curWhat = anExp.Current();
2509 isFoundAny = GetInPlaceOfShape(theWhereFunction, theWhereIndices, curWhat, theModifiedList);
2510 if (isFoundAny) isFound = Standard_True;
2514 else if (theWhat.ShapeType() == TopAbs_WIRE) {
2515 // try to replace a wire by its edges images
2516 TopExp_Explorer anExp (theWhat, TopAbs_EDGE);
2517 for (; anExp.More(); anExp.Next()) {
2518 if (mapShape.Add(anExp.Current())) {
2519 TopoDS_Shape curWhat = anExp.Current();
2520 isFoundAny = GetInPlaceOfShape(theWhereFunction, theWhereIndices, curWhat, theModifiedList);
2521 if (isFoundAny) isFound = Standard_True;
2533 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlace
2534 (Handle(GEOM_Object) theShapeWhere,
2535 Handle(GEOM_Object) theShapeWhat)
2539 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
2541 TopoDS_Shape aWhere = theShapeWhere->GetValue();
2542 TopoDS_Shape aWhat = theShapeWhat->GetValue();
2544 if (aWhere.IsNull() || aWhat.IsNull()) return NULL;
2546 Handle(GEOM_Function) aWhereFunction = theShapeWhere->GetLastFunction();
2547 if (aWhereFunction.IsNull()) return NULL;
2549 //Fill array of indices
2550 TopTools_IndexedMapOfShape aWhereIndices;
2551 TopExp::MapShapes(aWhere, aWhereIndices);
2554 TColStd_ListOfInteger aModifiedList;
2555 bool isFound = GetInPlaceOfShape(aWhereFunction, aWhereIndices, aWhat, aModifiedList);
2557 if (!isFound || aModifiedList.Extent() < 1) {
2558 SetErrorCode("Error: No history found for the sought shape or its sub-shapes.");
2562 Handle(TColStd_HArray1OfInteger) aModifiedArray =
2563 new TColStd_HArray1OfInteger (1, aModifiedList.Extent());
2564 TColStd_ListIteratorOfListOfInteger anIterModif (aModifiedList);
2565 for (Standard_Integer imod = 1; anIterModif.More(); anIterModif.Next(), imod++) {
2566 aModifiedArray->SetValue(imod, anIterModif.Value());
2570 Handle(GEOM_Object) aResult = GetEngine()->AddSubShape(theShapeWhere, aModifiedArray);
2571 if (aResult.IsNull()) {
2572 SetErrorCode("Error in algorithm: result found, but cannot be returned.");
2576 if (aModifiedArray->Length() > 1) {
2578 aResult->SetType(GEOM_GROUP);
2580 //Set a sub shape type
2581 TopoDS_Shape aFirstFound = aWhereIndices.FindKey(aModifiedArray->Value(1));
2582 TopAbs_ShapeEnum aShapeType = aFirstFound.ShapeType();
2584 TDF_Label aFreeLabel = aResult->GetFreeLabel();
2585 TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aShapeType);
2588 //Make a Python command
2589 Handle(GEOM_Function) aFunction = aResult->GetFunction(1);
2591 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetInPlace("
2592 << theShapeWhere << ", " << theShapeWhat << ")";
2598 //=======================================================================
2599 //function : SortShapes
2601 //=======================================================================
2602 void GEOMImpl_IShapesOperations::SortShapes(TopTools_ListOfShape& SL)
2604 Standard_Integer MaxShapes = SL.Extent();
2605 TopTools_Array1OfShape aShapes (1,MaxShapes);
2606 TColStd_Array1OfInteger OrderInd(1,MaxShapes);
2607 TColStd_Array1OfReal MidXYZ (1,MaxShapes); //X,Y,Z;
2608 TColStd_Array1OfReal Length (1,MaxShapes); //X,Y,Z;
2610 // Computing of CentreOfMass
2611 Standard_Integer Index;
2614 TopTools_ListIteratorOfListOfShape it(SL);
2615 for (Index=1; it.More(); Index++)
2617 TopoDS_Shape S = it.Value();
2618 SL.Remove( it ); // == it.Next()
2620 OrderInd.SetValue (Index, Index);
2621 if (S.ShapeType() == TopAbs_VERTEX)
2623 GPoint = BRep_Tool::Pnt( TopoDS::Vertex( S ));
2624 Length.SetValue( Index, (Standard_Real) S.Orientation());
2628 BRepGProp::LinearProperties (S, GPr);
2629 GPoint = GPr.CentreOfMass();
2630 Length.SetValue( Index, GPr.Mass() );
2632 MidXYZ.SetValue(Index,
2633 GPoint.X()*999 + GPoint.Y()*99 + GPoint.Z()*0.9);
2637 Standard_Integer aTemp;
2638 Standard_Boolean exchange, Sort = Standard_True;
2641 Sort = Standard_False;
2642 for (Index=1; Index < MaxShapes; Index++)
2644 if (MidXYZ(OrderInd(Index)) > MidXYZ(OrderInd(Index+1)))
2645 exchange = Standard_True;
2646 else if (MidXYZ(OrderInd(Index)) == MidXYZ(OrderInd(Index+1)) &&
2647 Length(OrderInd(Index)) > Length(OrderInd(Index+1)) )
2648 exchange = Standard_True;
2650 exchange = Standard_False;
2653 aTemp = OrderInd(Index);
2654 OrderInd(Index) = OrderInd(Index+1);
2655 OrderInd(Index+1) = aTemp;
2656 Sort = Standard_True;
2660 for (Index=1; Index <= MaxShapes; Index++)
2661 SL.Append( aShapes( OrderInd(Index) ));
2664 //=======================================================================
2665 //function : CompsolidToCompound
2667 //=======================================================================
2668 TopoDS_Shape GEOMImpl_IShapesOperations::CompsolidToCompound (const TopoDS_Shape& theCompsolid)
2670 if (theCompsolid.ShapeType() != TopAbs_COMPSOLID) {
2671 return theCompsolid;
2674 TopoDS_Compound aCompound;
2676 B.MakeCompound(aCompound);
2678 TopTools_MapOfShape mapShape;
2679 TopoDS_Iterator It (theCompsolid, Standard_True, Standard_True);
2681 for (; It.More(); It.Next()) {
2682 TopoDS_Shape aShape_i = It.Value();
2683 if (mapShape.Add(aShape_i)) {
2684 B.Add(aCompound, aShape_i);
2691 //=======================================================================
2692 //function : CheckTriangulation
2694 //=======================================================================
2695 bool GEOMImpl_IShapesOperations::CheckTriangulation (const TopoDS_Shape& aShape)
2697 bool isTriangulation = true;
2699 TopExp_Explorer exp (aShape, TopAbs_FACE);
2702 TopLoc_Location aTopLoc;
2703 Handle(Poly_Triangulation) aTRF;
2704 aTRF = BRep_Tool::Triangulation(TopoDS::Face(exp.Current()), aTopLoc);
2705 if (aTRF.IsNull()) {
2706 isTriangulation = false;
2709 else // no faces, try edges
2711 TopExp_Explorer expe (aShape, TopAbs_EDGE);
2715 TopLoc_Location aLoc;
2716 Handle(Poly_Polygon3D) aPE = BRep_Tool::Polygon3D(TopoDS::Edge(expe.Current()), aLoc);
2718 isTriangulation = false;
2722 if (!isTriangulation) {
2723 // calculate deflection
2724 Standard_Real aDeviationCoefficient = 0.001;
2727 BRepBndLib::Add(aShape, B);
2728 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
2729 B.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
2731 Standard_Real dx = aXmax - aXmin, dy = aYmax - aYmin, dz = aZmax - aZmin;
2732 Standard_Real aDeflection = Max(Max(dx, dy), dz) * aDeviationCoefficient * 4;
2733 Standard_Real aHLRAngle = 0.349066;
2735 BRepMesh_IncrementalMesh Inc (aShape, aDeflection, Standard_False, aHLRAngle);
2741 #define MAX_TOLERANCE 1.e-7
2744 //=======================================================================
2745 //function : isSameEdge
2746 //purpose : Returns True if two edges coincide
2747 //=======================================================================
2748 static bool isSameEdge(const TopoDS_Edge& theEdge1, const TopoDS_Edge& theEdge2)
2750 TopoDS_Vertex V11, V12, V21, V22;
2751 TopExp::Vertices(theEdge1, V11, V12);
2752 TopExp::Vertices(theEdge2, V21, V22);
2753 gp_Pnt P11 = BRep_Tool::Pnt(V11);
2754 gp_Pnt P12 = BRep_Tool::Pnt(V12);
2755 gp_Pnt P21 = BRep_Tool::Pnt(V21);
2756 gp_Pnt P22 = BRep_Tool::Pnt(V22);
2757 bool coincide = false;
2759 //Check that ends of edges coincide
2760 if(P11.Distance(P21) <= MAX_TOLERANCE) {
2761 if(P12.Distance(P22) <= MAX_TOLERANCE) coincide = true;
2763 else if(P11.Distance(P22) <= MAX_TOLERANCE) {
2764 if(P12.Distance(P21) <= MAX_TOLERANCE) coincide = true;
2767 if(!coincide) return false;
2769 double U11, U12, U21, U22;
2770 Handle(Geom_Curve) C1 = BRep_Tool::Curve(theEdge1, U11, U12);
2771 Handle(Geom_Curve) C2 = BRep_Tool::Curve(theEdge2, U21, U22);
2772 if(C1->DynamicType() == C2->DynamicType()) return true;
2774 //Check that both edges has the same geometry
2775 double range = U12-U11;
2776 double U = U11+ range/3.0;
2777 gp_Pnt P1 = C1->Value(U); //Compute a point on one third of the edge's length
2778 U = U11+range*2.0/3.0;
2779 gp_Pnt P2 = C1->Value(U); //Compute a point on two thirds of the edge's length
2781 if(!GeomLib_Tool::Parameter(C2, P1, MAX_TOLERANCE, U) || U < U21 || U > U22)
2784 if(P1.Distance(C2->Value(U)) > MAX_TOLERANCE) return false;
2786 if(!GeomLib_Tool::Parameter(C2, P2, MAX_TOLERANCE, U) || U < U21 || U > U22)
2789 if(P2.Distance(C2->Value(U)) > MAX_TOLERANCE) return false;
2794 #include <TopoDS_TShape.hxx>
2795 //=======================================================================
2796 //function : isSameFace
2797 //purpose : Returns True if two faces coincide
2798 //=======================================================================
2799 static bool isSameFace(const TopoDS_Face& theFace1, const TopoDS_Face& theFace2)
2801 TopExp_Explorer E(theFace1, TopAbs_EDGE);
2802 TopTools_ListOfShape LS1, LS2;
2803 for(; E.More(); E.Next()) LS1.Append(E.Current());
2805 E.Init(theFace2, TopAbs_EDGE);
2806 for(; E.More(); E.Next()) LS2.Append(E.Current());
2808 //Compare the number of edges in the faces
2809 if(LS1.Extent() != LS2.Extent()) return false;
2811 double aMin = RealFirst(), aMax = RealLast();
2812 double xminB1=aMax, yminB1=aMax, zminB1=aMax, xminB2=aMax, yminB2=aMax, zminB2=aMax;
2813 double xmaxB1=aMin, ymaxB1=aMin, zmaxB1=aMin, xmaxB2=aMin, ymaxB2=aMin, zmaxB2=aMin;
2815 for(E.Init(theFace1, TopAbs_VERTEX); E.More(); E.Next()) {
2816 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
2817 if(P.X() < xminB1) xminB1 = P.X();
2818 if(P.Y() < yminB1) yminB1 = P.Y();
2819 if(P.Z() < zminB1) zminB1 = P.Z();
2820 if(P.X() > xmaxB1) xmaxB1 = P.X();
2821 if(P.Y() > ymaxB1) ymaxB1 = P.Y();
2822 if(P.Z() > zmaxB1) zmaxB1 = P.Z();
2825 for(E.Init(theFace2, TopAbs_VERTEX); E.More(); E.Next()) {
2826 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
2827 if(P.X() < xminB2) xminB2 = P.X();
2828 if(P.Y() < yminB2) yminB2 = P.Y();
2829 if(P.Z() < zminB2) zminB2 = P.Z();
2830 if(P.X() > xmaxB2) xmaxB2 = P.X();
2831 if(P.Y() > ymaxB2) ymaxB2 = P.Y();
2832 if(P.Z() > zmaxB2) zmaxB2 = P.Z();
2836 //Compare the bounding boxes of both faces
2837 if(gp_Pnt(xminB1, yminB1, zminB1).Distance(gp_Pnt(xminB2, yminB2, zminB2)) > MAX_TOLERANCE)
2840 if(gp_Pnt(xmaxB1, ymaxB1, zmaxB1).Distance(gp_Pnt(xmaxB2, ymaxB2, zmaxB2)) > MAX_TOLERANCE)
2843 Handle(Geom_Surface) S1 = BRep_Tool::Surface(theFace1);
2844 Handle(Geom_Surface) S2 = BRep_Tool::Surface(theFace2);
2846 //Check if there a coincidence of two surfaces at least in two points
2847 double U11, U12, V11, V12, U21, U22, V21, V22;
2848 BRepTools::UVBounds(theFace1, U11, U12, V11, V12);
2849 BRepTools::UVBounds(theFace2, U21, U22, V21, V22);
2851 double rangeU = U12-U11;
2852 double rangeV = V12-V11;
2853 double U = U11 + rangeU/3.0;
2854 double V = V11 + rangeV/3.0;
2855 gp_Pnt P1 = S1->Value(U, V);
2856 U = U11+rangeU*2.0/3.0;
2857 V = V11+rangeV*2.0/3.0;
2858 gp_Pnt P2 = S1->Value(U, V);
2860 if(!GeomLib_Tool::Parameters(S2, P1, MAX_TOLERANCE, U, V) || U < U21 || U > U22 || V < V21 || V > V22)
2863 if(P1.Distance(S2->Value(U,V)) > MAX_TOLERANCE) return false;
2865 if(!GeomLib_Tool::Parameters(S2, P2, MAX_TOLERANCE, U, V) || U < U21 || U > U22 || V < V21 || V > V22)
2868 if(P2.Distance(S2->Value(U, V)) > MAX_TOLERANCE) return false;
2870 //Check that each edge of the Face1 has a counterpart in the Face2
2871 TopTools_MapOfOrientedShape aMap;
2872 TopTools_ListIteratorOfListOfShape LSI1(LS1);
2873 for(; LSI1.More(); LSI1.Next()) {
2874 TopoDS_Edge E = TopoDS::Edge(LSI1.Value());
2875 bool isFound = false;
2876 TopTools_ListIteratorOfListOfShape LSI2(LS2);
2877 for(; LSI2.More(); LSI2.Next()) {
2878 TopoDS_Shape aValue = LSI2.Value();
2879 if(aMap.Contains(aValue)) continue; //To avoid checking already found edge several times
2880 if(isSameEdge(E, TopoDS::Edge(aValue))) {
2886 if(!isFound) return false;
2892 //=======================================================================
2893 //function : isSameSolid
2894 //purpose : Returns True if two solids coincide
2895 //=======================================================================
2896 bool isSameSolid(const TopoDS_Solid& theSolid1, const TopoDS_Solid& theSolid2)
2898 TopExp_Explorer E(theSolid1, TopAbs_FACE);
2899 TopTools_ListOfShape LS1, LS2;
2900 for(; E.More(); E.Next()) LS1.Append(E.Current());
2901 E.Init(theSolid2, TopAbs_FACE);
2902 for(; E.More(); E.Next()) LS2.Append(E.Current());
2904 if(LS1.Extent() != LS2.Extent()) return false;
2906 double aMin = RealFirst(), aMax = RealLast();
2907 double xminB1=aMax, yminB1=aMax, zminB1=aMax, xminB2=aMax, yminB2=aMax, zminB2=aMax;
2908 double xmaxB1=aMin, ymaxB1=aMin, zmaxB1=aMin, xmaxB2=aMin, ymaxB2=aMin, zmaxB2=aMin;
2910 for(E.Init(theSolid1, TopAbs_VERTEX); E.More(); E.Next()) {
2911 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
2912 if(P.X() < xminB1) xminB1 = P.X();
2913 if(P.Y() < yminB1) yminB1 = P.Y();
2914 if(P.Z() < zminB1) zminB1 = P.Z();
2915 if(P.X() > xmaxB1) xmaxB1 = P.X();
2916 if(P.Y() > ymaxB1) ymaxB1 = P.Y();
2917 if(P.Z() > zmaxB1) zmaxB1 = P.Z();
2920 for(E.Init(theSolid2, TopAbs_VERTEX); E.More(); E.Next()) {
2921 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
2922 if(P.X() < xminB2) xminB2 = P.X();
2923 if(P.Y() < yminB2) yminB2 = P.Y();
2924 if(P.Z() < zminB2) zminB2 = P.Z();
2925 if(P.X() > xmaxB2) xmaxB2 = P.X();
2926 if(P.Y() > ymaxB2) ymaxB2 = P.Y();
2927 if(P.Z() > zmaxB2) zmaxB2 = P.Z();
2930 //Compare the bounding boxes of both solids
2931 if(gp_Pnt(xminB1, yminB1, zminB1).Distance(gp_Pnt(xminB2, yminB2, zminB2)) > MAX_TOLERANCE)
2934 if(gp_Pnt(xmaxB1, ymaxB1, zmaxB1).Distance(gp_Pnt(xmaxB2, ymaxB2, zmaxB2)) > MAX_TOLERANCE)
2937 //Check that each face of the Solid1 has a counterpart in the Solid2
2938 TopTools_MapOfOrientedShape aMap;
2939 TopTools_ListIteratorOfListOfShape LSI1(LS1);
2940 for(; LSI1.More(); LSI1.Next()) {
2941 TopoDS_Face F = TopoDS::Face(LSI1.Value());
2942 bool isFound = false;
2943 TopTools_ListIteratorOfListOfShape LSI2(LS2);
2944 for(; LSI2.More(); LSI2.Next()) {
2945 if(aMap.Contains(LSI2.Value())) continue; //To avoid checking already found faces several times
2946 if(isSameFace(F, TopoDS::Face(LSI2.Value()))) {
2947 aMap.Add(LSI2.Value());
2952 if(!isFound) return false;
2958 //=======================================================================
2959 //function : GetSame
2961 //=======================================================================
2962 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetSame(const Handle(GEOM_Object)& theShapeWhere,
2963 const Handle(GEOM_Object)& theShapeWhat)
2966 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
2968 TopoDS_Shape aWhere = theShapeWhere->GetValue();
2969 TopoDS_Shape aWhat = theShapeWhat->GetValue();
2971 if (aWhere.IsNull() || aWhat.IsNull()) return NULL;
2974 bool isFound = false;
2975 TopoDS_Shape aSubShape;
2976 TopTools_MapOfShape aMap;
2978 switch(aWhat.ShapeType()) {
2979 case TopAbs_VERTEX: {
2980 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(aWhat));
2981 TopExp_Explorer E(aWhere, TopAbs_VERTEX);
2982 for(; E.More(); E.Next()) {
2983 if(!aMap.Add(E.Current())) continue;
2984 gp_Pnt P2 = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
2985 if(P.Distance(P2) <= MAX_TOLERANCE) {
2987 aSubShape = E.Current();
2994 TopoDS_Face aFace = TopoDS::Face(aWhat);
2995 TopExp_Explorer E(aWhere, TopAbs_FACE);
2996 for(; E.More(); E.Next()) {
2997 if(!aMap.Add(E.Current())) continue;
2998 if(isSameFace(aFace, TopoDS::Face(E.Current()))) {
2999 aSubShape = E.Current();
3007 TopoDS_Edge anEdge = TopoDS::Edge(aWhat);
3008 TopExp_Explorer E(aWhere, TopAbs_EDGE);
3009 for(; E.More(); E.Next()) {
3010 if(!aMap.Add(E.Current())) continue;
3011 if(isSameEdge(anEdge, TopoDS::Edge(E.Current()))) {
3012 aSubShape = E.Current();
3019 case TopAbs_SOLID: {
3020 TopoDS_Solid aSolid = TopoDS::Solid(aWhat);
3021 TopExp_Explorer E(aWhere, TopAbs_SOLID);
3022 for(; E.More(); E.Next()) {
3023 if(!aMap.Add(E.Current())) continue;
3024 if(isSameSolid(aSolid, TopoDS::Solid(E.Current()))) {
3025 aSubShape = E.Current();
3037 TopTools_IndexedMapOfShape anIndices;
3038 TopExp::MapShapes(aWhere, anIndices);
3039 if (anIndices.Contains(aSubShape))
3040 anIndex = anIndices.FindIndex(aSubShape);
3043 if(anIndex < 0) return NULL;
3045 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
3047 anArray->SetValue(1, anIndex);
3049 Handle(GEOM_Object) aResult = GetEngine()->AddSubShape(theShapeWhere, anArray);
3050 Handle(GEOM_Function) aFunction = aResult->GetLastFunction();
3052 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetSame("
3053 << theShapeWhere << ", " << theShapeWhat << ")";