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
20 // File : GEOMImpl_IShapesOperations.cxx
22 // Author : modified by Lioka RAZAFINDRAZAKA (CEA) 22/06/2007
27 #include <Standard_Stream.hxx>
29 #include "GEOMImpl_IShapesOperations.hxx"
31 #include "GEOMImpl_Types.hxx"
33 #include "GEOMImpl_VectorDriver.hxx"
34 #include "GEOMImpl_ShapeDriver.hxx"
35 #include "GEOMImpl_CopyDriver.hxx"
36 #include "GEOMImpl_GlueDriver.hxx"
38 #include "GEOMImpl_IVector.hxx"
39 #include "GEOMImpl_IShapes.hxx"
40 #include "GEOMImpl_IGlue.hxx"
42 #include "GEOMImpl_Block6Explorer.hxx"
44 #include "GEOM_Function.hxx"
45 #include "GEOM_ISubShape.hxx"
46 #include "GEOM_PythonDump.hxx"
48 #include "GEOMAlgo_FinderShapeOn1.hxx"
49 #include "GEOMAlgo_FinderShapeOnQuad.hxx"
50 #include "GEOMAlgo_FinderShapeOn2.hxx"
51 #include "GEOMAlgo_ClsfBox.hxx"
52 #include "GEOMAlgo_ClsfSolid.hxx"
53 #include "GEOMAlgo_Gluer1.hxx"
54 #include "GEOMAlgo_ListIteratorOfListOfCoupleOfShapes.hxx"
55 #include "GEOMAlgo_CoupleOfShapes.hxx"
56 #include "GEOMAlgo_ListOfCoupleOfShapes.hxx"
58 #include "utilities.h"
60 #include "Utils_ExceptHandlers.hxx"
62 #include <TFunction_DriverTable.hxx>
63 #include <TFunction_Driver.hxx>
64 #include <TFunction_Logbook.hxx>
65 #include <TDataStd_Integer.hxx>
66 #include <TDataStd_IntegerArray.hxx>
67 #include <TDF_Tool.hxx>
69 #include <BRepExtrema_ExtCF.hxx>
70 #include <BRepExtrema_DistShapeShape.hxx>
72 #include <BRep_Tool.hxx>
73 #include <BRep_Builder.hxx>
74 #include <BRepTools.hxx>
75 #include <BRepGProp.hxx>
76 #include <BRepAdaptor_Curve.hxx>
77 #include <BRepAdaptor_Surface.hxx>
78 #include <BRepBndLib.hxx>
79 #include <BRepBuilderAPI_MakeFace.hxx>
80 #include <BRepMesh_IncrementalMesh.hxx>
85 #include <TopoDS_Shape.hxx>
86 #include <TopoDS_Solid.hxx>
87 #include <TopoDS_Face.hxx>
88 #include <TopoDS_Edge.hxx>
89 #include <TopoDS_Vertex.hxx>
90 #include <TopoDS_Compound.hxx>
91 #include <TopoDS_Iterator.hxx>
92 #include <TopExp_Explorer.hxx>
93 #include <TopLoc_Location.hxx>
94 #include <TopTools_MapOfShape.hxx>
95 #include <TopTools_MapOfOrientedShape.hxx>
96 #include <TopTools_Array1OfShape.hxx>
97 #include <TopTools_ListIteratorOfListOfShape.hxx>
98 #include <TopTools_IndexedMapOfShape.hxx>
100 #include <Geom_Surface.hxx>
101 #include <Geom_Plane.hxx>
102 #include <Geom_SphericalSurface.hxx>
103 #include <Geom_CylindricalSurface.hxx>
104 #include <GeomAdaptor_Surface.hxx>
106 #include <GeomLib_Tool.hxx>
107 #include <Geom2d_Curve.hxx>
109 #include <Bnd_Box.hxx>
110 #include <GProp_GProps.hxx>
111 #include <gp_Pnt.hxx>
112 #include <gp_Lin.hxx>
113 #include <TColStd_ListOfInteger.hxx>
114 #include <TColStd_ListIteratorOfListOfInteger.hxx>
115 #include <TColStd_Array1OfReal.hxx>
116 #include <TColStd_HArray1OfInteger.hxx>
120 #include <Standard_NullObject.hxx>
121 #include <Standard_Failure.hxx>
122 #include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
124 // Includes added for GetInPlace algorithm improvement
126 #include <GEOMImpl_MeasureDriver.hxx>
127 #include <GEOMImpl_IMeasure.hxx>
128 #include <BRepBuilderAPI_MakeVertex.hxx>
130 #include <BRepClass_FaceClassifier.hxx>
131 #include <BRepClass3d_SolidClassifier.hxx>
132 #include <Precision.hxx>
137 //=============================================================================
141 //=============================================================================
142 GEOMImpl_IShapesOperations::GEOMImpl_IShapesOperations (GEOM_Engine* theEngine, int theDocID)
143 : GEOM_IOperations(theEngine, theDocID)
145 MESSAGE("GEOMImpl_IShapesOperations::GEOMImpl_IShapesOperations");
148 //=============================================================================
152 //=============================================================================
153 GEOMImpl_IShapesOperations::~GEOMImpl_IShapesOperations()
155 MESSAGE("GEOMImpl_IShapesOperations::~GEOMImpl_IShapesOperations");
159 //=============================================================================
163 //=============================================================================
164 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeEdge
165 (Handle(GEOM_Object) thePnt1, Handle(GEOM_Object) thePnt2)
169 if (thePnt1.IsNull() || thePnt2.IsNull()) return NULL;
171 //Add a new Edge object
172 Handle(GEOM_Object) anEdge = GetEngine()->AddObject(GetDocID(), GEOM_EDGE);
174 //Add a new Vector function
175 Handle(GEOM_Function) aFunction =
176 anEdge->AddFunction(GEOMImpl_VectorDriver::GetID(), VECTOR_TWO_PNT);
178 //Check if the function is set correctly
179 if (aFunction->GetDriverGUID() != GEOMImpl_VectorDriver::GetID()) return NULL;
181 GEOMImpl_IVector aPI (aFunction);
183 Handle(GEOM_Function) aRef1 = thePnt1->GetLastFunction();
184 Handle(GEOM_Function) aRef2 = thePnt2->GetLastFunction();
185 if (aRef1.IsNull() || aRef2.IsNull()) return NULL;
187 aPI.SetPoint1(aRef1);
188 aPI.SetPoint2(aRef2);
190 //Compute the Edge value
192 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
195 if (!GetSolver()->ComputeFunction(aFunction)) {
196 SetErrorCode("Vector driver failed");
200 catch (Standard_Failure) {
201 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
202 SetErrorCode(aFail->GetMessageString());
206 //Make a Python command
207 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdge("
208 << thePnt1 << ", " << thePnt2 << ")";
214 //=============================================================================
218 //=============================================================================
219 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeWire
220 (list<Handle(GEOM_Object)> theShapes)
222 return MakeShape(theShapes, GEOM_WIRE, WIRE_EDGES, "MakeWire");
225 //=============================================================================
229 //=============================================================================
230 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFace (Handle(GEOM_Object) theWire,
231 const bool isPlanarWanted)
235 if (theWire.IsNull()) return NULL;
237 //Add a new Face object
238 Handle(GEOM_Object) aFace = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
240 //Add a new Shape function for creation of a face from a wire
241 Handle(GEOM_Function) aFunction =
242 aFace->AddFunction(GEOMImpl_ShapeDriver::GetID(), FACE_WIRE);
243 if (aFunction.IsNull()) return NULL;
245 //Check if the function is set correctly
246 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
248 GEOMImpl_IShapes aCI (aFunction);
250 Handle(GEOM_Function) aRefWire = theWire->GetLastFunction();
252 if (aRefWire.IsNull()) return NULL;
254 aCI.SetBase(aRefWire);
255 aCI.SetIsPlanar(isPlanarWanted);
257 //Compute the Face value
259 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
262 if (!GetSolver()->ComputeFunction(aFunction)) {
263 SetErrorCode("Shape driver failed to compute a face");
267 catch (Standard_Failure) {
268 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
269 SetErrorCode(aFail->GetMessageString());
273 //Make a Python command
274 GEOM::TPythonDump(aFunction) << aFace << " = geompy.MakeFace("
275 << theWire << ", " << (int)isPlanarWanted << ")";
281 //=============================================================================
285 //=============================================================================
286 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFaceWires
287 (list<Handle(GEOM_Object)> theShapes,
288 const bool isPlanarWanted)
293 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
296 Handle(GEOM_Function) aFunction =
297 aShape->AddFunction(GEOMImpl_ShapeDriver::GetID(), FACE_WIRES);
298 if (aFunction.IsNull()) return NULL;
300 //Check if the function is set correctly
301 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
303 GEOMImpl_IShapes aCI (aFunction);
305 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
308 list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
309 for (; it != theShapes.end(); it++) {
310 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
311 if (aRefSh.IsNull()) {
312 SetErrorCode("NULL argument shape for the face construction");
315 aShapesSeq->Append(aRefSh);
317 aCI.SetShapes(aShapesSeq);
319 aCI.SetIsPlanar(isPlanarWanted);
323 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
326 if (!GetSolver()->ComputeFunction(aFunction)) {
327 SetErrorCode("Shape driver failed");
331 catch (Standard_Failure) {
332 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
333 SetErrorCode(aFail->GetMessageString());
337 //Make a Python command
338 GEOM::TPythonDump pd (aFunction);
339 pd << aShape << " = geompy.MakeFaceWires([";
342 it = theShapes.begin();
343 if (it != theShapes.end()) {
345 while (it != theShapes.end()) {
346 pd << ", " << (*it++);
349 pd << "], " << (int)isPlanarWanted << ")";
355 //=============================================================================
359 //=============================================================================
360 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeShell
361 (list<Handle(GEOM_Object)> theShapes)
363 return MakeShape(theShapes, GEOM_SHELL, SHELL_FACES, "MakeShell");
366 //=============================================================================
370 //=============================================================================
371 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeSolidShells
372 (list<Handle(GEOM_Object)> theShapes)
374 return MakeShape(theShapes, GEOM_SOLID, SOLID_SHELLS, "MakeSolid");
377 //=============================================================================
381 //=============================================================================
382 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeSolidShell (Handle(GEOM_Object) theShell)
386 if (theShell.IsNull()) return NULL;
388 //Add a new Solid object
389 Handle(GEOM_Object) aSolid = GetEngine()->AddObject(GetDocID(), GEOM_SOLID);
391 //Add a new Solid function for creation of a solid from a shell
392 Handle(GEOM_Function) aFunction =
393 aSolid->AddFunction(GEOMImpl_ShapeDriver::GetID(), SOLID_SHELL);
394 if (aFunction.IsNull()) return NULL;
396 //Check if the function is set correctly
397 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
399 GEOMImpl_IShapes aCI (aFunction);
401 Handle(GEOM_Function) aRefShell = theShell->GetLastFunction();
403 if (aRefShell.IsNull()) return NULL;
405 aCI.SetBase(aRefShell);
407 //Compute the Solid value
409 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
412 if (!GetSolver()->ComputeFunction(aFunction)) {
413 SetErrorCode("Solid driver failed");
417 catch (Standard_Failure) {
418 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
419 SetErrorCode(aFail->GetMessageString());
423 //Make a Python command
424 GEOM::TPythonDump(aFunction) << aSolid
425 << " = geompy.MakeSolid(" << theShell << ")";
431 //=============================================================================
435 //=============================================================================
436 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeCompound
437 (list<Handle(GEOM_Object)> theShapes)
439 return MakeShape(theShapes, GEOM_COMPOUND, COMPOUND_SHAPES, "MakeCompound");
442 //=============================================================================
446 //=============================================================================
447 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeShape
448 (list<Handle(GEOM_Object)> theShapes,
449 const Standard_Integer theObjectType,
450 const Standard_Integer theFunctionType,
451 const TCollection_AsciiString& theMethodName)
456 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), theObjectType);
459 Handle(GEOM_Function) aFunction =
460 aShape->AddFunction(GEOMImpl_ShapeDriver::GetID(), theFunctionType);
461 if (aFunction.IsNull()) return NULL;
463 //Check if the function is set correctly
464 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
466 GEOMImpl_IShapes aCI (aFunction);
468 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
471 list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
472 for (; it != theShapes.end(); it++) {
473 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
474 if (aRefSh.IsNull()) {
475 SetErrorCode("NULL argument shape for the shape construction");
478 aShapesSeq->Append(aRefSh);
480 aCI.SetShapes(aShapesSeq);
484 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
487 if (!GetSolver()->ComputeFunction(aFunction)) {
488 SetErrorCode("Shape driver failed");
492 catch (Standard_Failure) {
493 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
494 SetErrorCode(aFail->GetMessageString());
498 //Make a Python command
499 GEOM::TPythonDump pd (aFunction);
500 pd << aShape << " = geompy." << theMethodName.ToCString() << "([";
503 it = theShapes.begin();
504 if (it != theShapes.end()) {
506 while (it != theShapes.end()) {
507 pd << ", " << (*it++);
516 //=============================================================================
520 //=============================================================================
521 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeGlueFaces
522 (Handle(GEOM_Object) theShape,
523 const Standard_Real theTolerance,
524 const Standard_Boolean doKeepNonSolids)
528 if (theShape.IsNull()) return NULL;
530 //Add a new Glued object
531 Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
533 //Add a new Glue function
534 Handle(GEOM_Function) aFunction;
535 aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_FACES);
536 if (aFunction.IsNull()) return NULL;
538 //Check if the function is set correctly
539 if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
541 GEOMImpl_IGlue aCI (aFunction);
543 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
544 if (aRefShape.IsNull()) return NULL;
546 aCI.SetBase(aRefShape);
547 aCI.SetTolerance(theTolerance);
548 aCI.SetKeepNonSolids(doKeepNonSolids);
550 //Compute the sub-shape value
551 Standard_Boolean isWarning = Standard_False;
553 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
556 if (!GetSolver()->ComputeFunction(aFunction)) {
557 SetErrorCode("Shape driver failed to glue faces");
561 catch (Standard_Failure) {
562 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
563 SetErrorCode(aFail->GetMessageString());
564 // to provide warning
565 if (!aFunction->GetValue().IsNull()) {
566 isWarning = Standard_True;
572 //Make a Python command
573 GEOM::TPythonDump(aFunction) << aGlued << " = geompy.MakeGlueFaces("
574 << theShape << ", " << theTolerance << ")";
576 // to provide warning
577 if (!isWarning) SetErrorCode(OK);
581 //=============================================================================
585 //=============================================================================
586 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetGlueFaces
587 (Handle(GEOM_Object) theShape,
588 const Standard_Real theTolerance)
592 if (theShape.IsNull()) return NULL;
593 TopoDS_Shape aShape = theShape->GetValue();
594 if (aShape.IsNull()) return NULL;
596 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
598 Standard_Integer iErr;
600 GEOMAlgo_Gluer1 aGluer;
601 GEOMAlgo_ListIteratorOfListOfCoupleOfShapes aItCS;
602 GEOMAlgo_CoupleOfShapes aCS;
603 GEOMAlgo_ListOfCoupleOfShapes aLCS;
605 //aGluer = new GEOMAlgo_Gluer1;
606 aGluer.SetShape(aShape);
607 aGluer.SetTolerance(theTolerance);
609 iErr = aGluer.ErrorStatus();
610 if (iErr) return NULL;
612 TopTools_ListOfShape listShape;
613 const GEOMAlgo_ListOfCoupleOfShapes& aLCSG = aGluer.GluedFaces();
615 aItCS.Initialize(aLCSG);
616 for (; aItCS.More(); aItCS.Next()) {
617 const GEOMAlgo_CoupleOfShapes& aCSG = aItCS.Value();
618 listShape.Append(aCSG.Shape1());
621 TopTools_ListIteratorOfListOfShape itSub (listShape);
622 TCollection_AsciiString anAsciiList, anEntry;
623 TopTools_IndexedMapOfShape anIndices;
624 TopExp::MapShapes(aShape, anIndices);
625 Handle(TColStd_HArray1OfInteger) anArray;
626 Handle(GEOM_Object) anObj;
627 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
628 TopoDS_Shape aValue = itSub.Value();
629 anArray = new TColStd_HArray1OfInteger(1,1);
630 anArray->SetValue(1, anIndices.FindIndex(aValue));
631 anObj = GetEngine()->AddSubShape(theShape, anArray);
632 if (!anObj.IsNull()) {
635 // for python command
636 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
637 anAsciiList += anEntry;
642 //Make a Python command
643 if(anAsciiList.Length()>0)
644 anAsciiList.Trunc(anAsciiList.Length() - 1);
645 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
646 GEOM::TPythonDump pd (aFunction, /*append=*/true);
647 pd << "[" << anAsciiList.ToCString();
648 pd << "] = geompy.GetGlueFaces(" << theShape << ", " << theTolerance << ")";
656 //=============================================================================
658 * MakeGlueFacesByList
660 //=============================================================================
661 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeGlueFacesByList
662 (Handle(GEOM_Object) theShape,
663 const Standard_Real theTolerance,
664 list<Handle(GEOM_Object)> theFaces,
665 const Standard_Boolean doKeepNonSolids)
669 if (theShape.IsNull()) return NULL;
671 //Add a new Glued object
672 Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
674 //Add a new Glue function
675 Handle(GEOM_Function) aFunction;
676 aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_FACES_BY_LIST);
677 if (aFunction.IsNull()) return NULL;
679 //Check if the function is set correctly
680 if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
682 GEOMImpl_IGlue aCI (aFunction);
684 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
685 if (aRefShape.IsNull()) return NULL;
687 aCI.SetBase(aRefShape);
688 aCI.SetTolerance(theTolerance);
689 aCI.SetKeepNonSolids(doKeepNonSolids);
691 Handle(TColStd_HSequenceOfTransient) aFaces = new TColStd_HSequenceOfTransient;
692 list<Handle(GEOM_Object)>::iterator it = theFaces.begin();
693 for (; it != theFaces.end(); it++) {
694 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
695 if (aRefSh.IsNull()) {
696 SetErrorCode("NULL argument shape for the shape construction");
699 aFaces->Append(aRefSh);
701 aCI.SetFaces(aFaces);
703 //Compute the sub-shape value
704 Standard_Boolean isWarning = Standard_False;
706 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
709 if (!GetSolver()->ComputeFunction(aFunction)) {
710 SetErrorCode("Shape driver failed to glue faces");
714 catch (Standard_Failure) {
715 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
716 SetErrorCode(aFail->GetMessageString());
717 // to provide warning
718 if (!aFunction->GetValue().IsNull()) {
719 isWarning = Standard_True;
725 //Make a Python command
727 GEOM::TPythonDump pd(aFunction);
728 pd << aGlued << " = geompy.MakeGlueFacesByList("
729 << theShape << ", " << theTolerance << ", [";
731 it = theFaces.begin();
732 if (it != theFaces.end()) {
734 while (it != theFaces.end()) {
735 pd << ", " << (*it++);
741 // to provide warning
742 if (!isWarning) SetErrorCode(OK);
748 //=============================================================================
752 //=============================================================================
753 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::MakeExplode
754 (Handle(GEOM_Object) theShape,
755 const Standard_Integer theShapeType,
756 const Standard_Boolean isSorted)
760 if (theShape.IsNull()) return NULL;
761 TopoDS_Shape aShape = theShape->GetValue();
762 if (aShape.IsNull()) return NULL;
764 Handle(GEOM_Function) aMainShape = theShape->GetLastFunction();
766 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
767 Handle(GEOM_Object) anObj;
768 TopTools_MapOfShape mapShape;
769 TopTools_ListOfShape listShape;
771 if (aShape.ShapeType() == TopAbs_COMPOUND &&
772 (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
773 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPSOLID ||
774 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPOUND)) {
775 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
776 for (; It.More(); It.Next()) {
777 if (mapShape.Add(It.Value())) {
778 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
779 TopAbs_ShapeEnum(theShapeType) == It.Value().ShapeType()) {
780 listShape.Append(It.Value());
785 TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
786 for (; exp.More(); exp.Next())
787 if (mapShape.Add(exp.Current()))
788 listShape.Append(exp.Current());
791 if (listShape.IsEmpty()) {
792 //SetErrorCode("The given shape has no sub-shapes of the requested type");
793 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
798 SortShapes(listShape);
800 TopTools_IndexedMapOfShape anIndices;
801 TopExp::MapShapes(aShape, anIndices);
802 Handle(TColStd_HArray1OfInteger) anArray;
804 TopTools_ListIteratorOfListOfShape itSub (listShape);
805 TCollection_AsciiString anAsciiList, anEntry;
806 for (int index = 1; itSub.More(); itSub.Next(), ++index)
808 TopoDS_Shape aValue = itSub.Value();
809 anArray = new TColStd_HArray1OfInteger(1,1);
810 anArray->SetValue(1, anIndices.FindIndex(aValue));
812 //anObj = GetEngine()->AddSubShape(theShape, anArray);
814 anObj = GetEngine()->AddObject(GetDocID(), GEOM_SUBSHAPE);
815 Handle(GEOM_Function) aFunction = anObj->AddFunction(GEOM_Object::GetSubShapeID(), 1);
816 if (aFunction.IsNull()) return aSeq;
818 GEOM_ISubShape aSSI (aFunction);
819 aSSI.SetMainShape(aMainShape);
820 aSSI.SetIndices(anArray);
822 // Set function value directly, as we know it.
823 // Usage of Solver here would lead to significant loss of time,
824 // because GEOM_SubShapeDriver will build TopTools_IndexedMapOfShape
825 // on the main shape for each being calculated sub-shape separately.
826 aFunction->SetValue(aValue);
829 if (!anObj.IsNull()) {
832 // for python command
833 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
834 anAsciiList += anEntry;
839 //Make a Python command
840 anAsciiList.Trunc(anAsciiList.Length() - 1);
842 GEOM::TPythonDump pd (aMainShape, /*append=*/true);
843 pd << "[" << anAsciiList.ToCString();
844 pd << "] = geompy.SubShapeAll" << (isSorted ? "Sorted(" : "(");
845 pd << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
852 //=============================================================================
856 //=============================================================================
857 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::SubShapeAllIDs
858 (Handle(GEOM_Object) theShape,
859 const Standard_Integer theShapeType,
860 const Standard_Boolean isSorted)
864 if (theShape.IsNull()) return NULL;
865 TopoDS_Shape aShape = theShape->GetValue();
866 if (aShape.IsNull()) return NULL;
868 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
869 TopTools_MapOfShape mapShape;
870 TopTools_ListOfShape listShape;
872 if (aShape.ShapeType() == TopAbs_COMPOUND &&
873 (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
874 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPSOLID ||
875 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPOUND)) {
876 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
877 for (; It.More(); It.Next()) {
878 if (mapShape.Add(It.Value())) {
879 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
880 TopAbs_ShapeEnum(theShapeType) == It.Value().ShapeType()) {
881 listShape.Append(It.Value());
886 TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
887 for (; exp.More(); exp.Next())
888 if (mapShape.Add(exp.Current()))
889 listShape.Append(exp.Current());
892 if (listShape.IsEmpty()) {
893 //SetErrorCode("The given shape has no sub-shapes of the requested type");
894 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
899 SortShapes(listShape);
901 TopTools_IndexedMapOfShape anIndices;
902 TopExp::MapShapes(aShape, anIndices);
903 Handle(TColStd_HArray1OfInteger) anArray;
905 TopTools_ListIteratorOfListOfShape itSub (listShape);
906 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
907 TopoDS_Shape aValue = itSub.Value();
908 aSeq->Append(anIndices.FindIndex(aValue));
911 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
913 //Make a Python command
914 GEOM::TPythonDump pd (aFunction, /*append=*/true);
915 pd << "listSubShapeIDs = geompy.SubShapeAll";
916 pd << (isSorted ? "SortedIDs(" : "IDs(");
917 pd << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
923 //=============================================================================
927 //=============================================================================
928 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetSubShape
929 (Handle(GEOM_Object) theMainShape,
930 const Standard_Integer theID)
934 if (theMainShape.IsNull()) return NULL;
936 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
937 anArray->SetValue(1, theID);
938 Handle(GEOM_Object) anObj = GetEngine()->AddSubShape(theMainShape, anArray,true);
939 if (anObj.IsNull()) {
940 SetErrorCode("Can not get a sub-shape with the given ID");
944 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
946 //Make a Python command
947 GEOM::TPythonDump(aFunction) << anObj << " = geompy.GetSubShape("
948 << theMainShape << ", [" << theID << "])";
954 //=============================================================================
958 //=============================================================================
959 Standard_Integer GEOMImpl_IShapesOperations::GetSubShapeIndex (Handle(GEOM_Object) theMainShape,
960 Handle(GEOM_Object) theSubShape)
964 TopoDS_Shape aMainShape = theMainShape->GetValue();
965 TopoDS_Shape aSubShape = theSubShape->GetValue();
967 if (aMainShape.IsNull() || aSubShape.IsNull()) return -1;
969 TopTools_IndexedMapOfShape anIndices;
970 TopExp::MapShapes(aMainShape, anIndices);
971 if (anIndices.Contains(aSubShape)) {
973 return anIndices.FindIndex(aSubShape);
979 //=============================================================================
983 //=============================================================================
984 Standard_Integer GEOMImpl_IShapesOperations::GetTopologyIndex (Handle(GEOM_Object) theMainShape,
985 Handle(GEOM_Object) theSubShape)
989 TopoDS_Shape aMainShape = theMainShape->GetValue();
990 TopoDS_Shape aSubShape = theSubShape->GetValue();
992 if (aMainShape.IsNull() || aSubShape.IsNull()) {
993 SetErrorCode("Null argument shape given");
998 if (aSubShape.ShapeType() == TopAbs_COMPOUND) {
1000 TopTools_ListOfShape CL;
1001 CL.Append(aMainShape);
1002 TopTools_ListIteratorOfListOfShape itC;
1003 for (itC.Initialize(CL); itC.More(); itC.Next()) {
1004 for (it.Initialize(itC.Value()); it.More(); it.Next()) {
1005 if (it.Value().ShapeType() == TopAbs_COMPOUND) {
1006 if (it.Value().IsSame(aSubShape))
1010 CL.Append(it.Value());
1015 TopExp_Explorer anExp (aMainShape, aSubShape.ShapeType());
1016 TopTools_MapOfShape M;
1017 for (; anExp.More(); anExp.Next()) {
1018 if (M.Add(anExp.Current())) {
1019 if (anExp.Current().IsSame(aSubShape))
1026 SetErrorCode("The sub-shape does not belong to the main shape");
1030 //=============================================================================
1032 * GetShapeTypeString
1034 //=============================================================================
1035 TCollection_AsciiString GEOMImpl_IShapesOperations::GetShapeTypeString (Handle(GEOM_Object) theShape)
1039 TCollection_AsciiString aTypeName ("Null Shape");
1041 TopoDS_Shape aShape = theShape->GetValue();
1042 if (aShape.IsNull())
1045 switch (aShape.ShapeType() )
1047 case TopAbs_COMPOUND:
1048 aTypeName = "Compound";
1050 case TopAbs_COMPSOLID:
1051 aTypeName = "Compound Solid";
1054 aTypeName = "Solid";
1057 aTypeName = "Shell";
1061 BRepAdaptor_Surface surf (TopoDS::Face(aShape));
1062 if (surf.GetType() == GeomAbs_Plane)
1063 aTypeName = "Plane";
1064 else if (surf.GetType() == GeomAbs_Cylinder)
1065 aTypeName = "Cylindrical Face";
1066 else if (surf.GetType() == GeomAbs_Sphere)
1067 aTypeName = "Spherical Face";
1068 else if (surf.GetType() == GeomAbs_Torus)
1069 aTypeName = "Toroidal Face";
1070 else if (surf.GetType() == GeomAbs_Cone)
1071 aTypeName = "Conical Face";
1073 aTypeName = "GEOM::FACE";
1081 BRepAdaptor_Curve curv (TopoDS::Edge(aShape));
1082 if (curv.GetType() == GeomAbs_Line) {
1083 if ((Abs(curv.FirstParameter()) >= 1E6) ||
1084 (Abs(curv.LastParameter()) >= 1E6))
1087 aTypeName = "Edge" ;
1088 } else if (curv.GetType() == GeomAbs_Circle) {
1089 if (curv.IsClosed())
1090 aTypeName = "Circle";
1099 aTypeName = "Vertex";
1102 aTypeName = "Shape";
1105 aTypeName = "Shape of unknown type";
1112 //=============================================================================
1116 //=============================================================================
1117 Standard_Integer GEOMImpl_IShapesOperations::NumberOfFaces (Handle(GEOM_Object) theShape)
1121 Standard_Integer nb = 0;
1123 if (theShape.IsNull()) return -1;
1124 TopoDS_Shape aShape = theShape->GetValue();
1125 if (aShape.IsNull()) return -1;
1127 TopTools_MapOfShape mapShape;
1129 TopExp_Explorer exp (aShape, TopAbs_FACE);
1130 for (; exp.More(); exp.Next())
1131 if (mapShape.Add(exp.Current()))
1138 //=============================================================================
1142 //=============================================================================
1143 Standard_Integer GEOMImpl_IShapesOperations::NumberOfEdges (Handle(GEOM_Object) theShape)
1147 Standard_Integer nb = 0;
1149 if (theShape.IsNull()) return -1;
1150 TopoDS_Shape aShape = theShape->GetValue();
1151 if (aShape.IsNull()) return -1;
1153 TopTools_MapOfShape mapShape;
1155 TopExp_Explorer exp (aShape, TopAbs_EDGE);
1156 for (; exp.More(); exp.Next())
1157 if (mapShape.Add(exp.Current()))
1164 //=============================================================================
1168 //=============================================================================
1169 Handle(GEOM_Object) GEOMImpl_IShapesOperations::ReverseShape(Handle(GEOM_Object) theShape)
1173 if (theShape.IsNull()) return NULL;
1175 //Add a new reversed object
1176 Handle(GEOM_Object) aReversed = GetEngine()->AddObject(GetDocID(), theShape->GetType());
1178 //Add a new Revese function
1179 Handle(GEOM_Function) aFunction;
1180 aFunction = aReversed->AddFunction(GEOMImpl_ShapeDriver::GetID(), REVERSE_ORIENTATION);
1181 if (aFunction.IsNull()) return NULL;
1183 //Check if the function is set correctly
1184 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
1186 GEOMImpl_IShapes aSI (aFunction);
1188 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
1189 if (aRefShape.IsNull()) return NULL;
1191 aSI.SetBase(aRefShape);
1193 //Compute the sub-shape value
1195 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
1198 if (!GetSolver()->ComputeFunction(aFunction)) {
1199 SetErrorCode("Shape driver failed to reverse shape");
1203 catch (Standard_Failure) {
1204 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1205 SetErrorCode(aFail->GetMessageString());
1209 //Make a Python command
1210 GEOM::TPythonDump(aFunction) << aReversed
1211 << " = geompy.ChangeOrientation(" << theShape << ")";
1217 //=============================================================================
1221 //=============================================================================
1222 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetFreeFacesIDs
1223 (Handle(GEOM_Object) theShape)
1227 if (theShape.IsNull()) return NULL;
1228 TopoDS_Shape aShape = theShape->GetValue();
1229 if (aShape.IsNull()) return NULL;
1231 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
1233 TopTools_IndexedDataMapOfShapeListOfShape mapFaceBlocks;
1234 GEOMImpl_Block6Explorer::MapShapesAndAncestors
1235 (aShape, TopAbs_FACE, TopAbs_SOLID, mapFaceBlocks);
1237 Standard_Integer ind = 1, nbFaces = mapFaceBlocks.Extent();
1240 SetErrorCode("The given shape has no faces");
1244 TopTools_IndexedMapOfShape anIndices;
1245 TopExp::MapShapes(aShape, anIndices);
1247 Standard_Integer id;
1248 for (; ind <= nbFaces; ind++) {
1249 if (mapFaceBlocks.FindFromIndex(ind).Extent() != 2) {
1250 id = anIndices.FindIndex(mapFaceBlocks.FindKey(ind));
1255 //The explode doesn't change object so no new function is required.
1256 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
1258 //Make a Python command
1259 GEOM::TPythonDump(aFunction, /*append=*/true)
1260 << "listFreeFacesIDs = geompy.GetFreeFacesIDs(" << theShape << ")";
1266 //=======================================================================
1267 //function : GetSharedShapes
1269 //=======================================================================
1271 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetSharedShapes
1272 (Handle(GEOM_Object) theShape1,
1273 Handle(GEOM_Object) theShape2,
1274 const Standard_Integer theShapeType)
1278 if (theShape1.IsNull() || theShape2.IsNull()) return NULL;
1280 TopoDS_Shape aShape1 = theShape1->GetValue();
1281 TopoDS_Shape aShape2 = theShape2->GetValue();
1283 if (aShape1.IsNull() || aShape2.IsNull()) return NULL;
1285 TopTools_IndexedMapOfShape anIndices;
1286 TopExp::MapShapes(aShape1, anIndices);
1287 Handle(TColStd_HArray1OfInteger) anArray;
1289 TopTools_IndexedMapOfShape mapShape1;
1290 TopExp::MapShapes(aShape1, TopAbs_ShapeEnum(theShapeType), mapShape1);
1292 Handle(GEOM_Object) anObj;
1293 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1294 TCollection_AsciiString anAsciiList, anEntry;
1296 TopTools_MapOfShape mapShape2;
1297 TopExp_Explorer exp (aShape2, TopAbs_ShapeEnum(theShapeType));
1298 for (; exp.More(); exp.Next()) {
1299 TopoDS_Shape aSS = exp.Current();
1300 if (mapShape2.Add(aSS) && mapShape1.Contains(aSS)) {
1301 anArray = new TColStd_HArray1OfInteger(1,1);
1302 anArray->SetValue(1, anIndices.FindIndex(aSS));
1303 anObj = GetEngine()->AddSubShape(theShape1, anArray);
1304 aSeq->Append(anObj);
1306 // for python command
1307 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
1308 anAsciiList += anEntry;
1313 if (aSeq->IsEmpty()) {
1314 SetErrorCode("The given shapes have no shared sub-shapes of the requested type");
1318 //Make a Python command
1319 anAsciiList.Trunc(anAsciiList.Length() - 1);
1321 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1323 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
1324 << "] = geompy.GetSharedShapes(" << theShape1 << ", "
1325 << theShape2 << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
1331 //=============================================================================
1335 //=============================================================================
1336 static GEOM::TPythonDump& operator<< (GEOM::TPythonDump& theDump,
1337 const GEOMAlgo_State theState)
1340 case GEOMAlgo_ST_IN:
1341 theDump << "geompy.GEOM.ST_IN";
1343 case GEOMAlgo_ST_OUT:
1344 theDump << "geompy.GEOM.ST_OUT";
1346 case GEOMAlgo_ST_ON:
1347 theDump << "geompy.GEOM.ST_ON";
1349 case GEOMAlgo_ST_ONIN:
1350 theDump << "geompy.GEOM.ST_ONIN";
1352 case GEOMAlgo_ST_ONOUT:
1353 theDump << "geompy.GEOM.ST_ONOUT";
1356 theDump << "geompy.GEOM.ST_UNKNOWN";
1362 //=======================================================================
1363 //function : checkTypeShapesOn
1365 * \brief Checks if theShapeType parameter of GetShapesOnXXX() is OK
1366 * \param theShapeType - the shape type to check
1367 * \retval bool - result of the check
1369 //=======================================================================
1371 bool GEOMImpl_IShapesOperations::checkTypeShapesOn(const Standard_Integer theShapeType)
1373 if (theShapeType != TopAbs_VERTEX &&
1374 theShapeType != TopAbs_EDGE &&
1375 theShapeType != TopAbs_FACE &&
1376 theShapeType != TopAbs_SOLID) {
1377 SetErrorCode("Only solids, vertices, edges or faces can be found by this method");
1383 //=======================================================================
1384 //function : makePlane
1386 * \brief Creates Geom_Plane
1387 * \param theAx1 - shape object defining plane parameters
1388 * \retval Handle(Geom_Surface) - resulting surface
1390 //=======================================================================
1392 Handle(Geom_Surface) GEOMImpl_IShapesOperations::makePlane(const TopoDS_Shape& anAx1)
1394 if (anAx1.ShapeType() != TopAbs_EDGE) return NULL;
1395 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
1396 TopoDS_Vertex V1, V2;
1397 TopExp::Vertices(anEdge, V1, V2, Standard_True);
1398 if (V1.IsNull() || V2.IsNull()) {
1399 SetErrorCode("Bad edge given for the plane normal vector");
1402 gp_Pnt aLoc = BRep_Tool::Pnt(V1);
1403 gp_Vec aVec (aLoc, BRep_Tool::Pnt(V2));
1404 if (aVec.Magnitude() < Precision::Confusion()) {
1405 SetErrorCode("Vector with null magnitude given");
1408 return new Geom_Plane(aLoc, aVec);
1411 //=======================================================================
1412 //function : makeCylinder
1414 * \brief Creates Geom_CylindricalSurface
1415 * \param theAx1 - edge defining cylinder axis
1416 * \param theRadius - cylinder radius
1417 * \retval Handle(Geom_Surface) - resulting surface
1419 //=======================================================================
1421 Handle(Geom_Surface) GEOMImpl_IShapesOperations::makeCylinder(const TopoDS_Shape& anAxis,
1422 const Standard_Real theRadius)
1424 //Axis of the cylinder
1425 if (anAxis.ShapeType() != TopAbs_EDGE) {
1426 SetErrorCode("Not an edge given for the axis");
1429 TopoDS_Edge anEdge = TopoDS::Edge(anAxis);
1430 TopoDS_Vertex V1, V2;
1431 TopExp::Vertices(anEdge, V1, V2, Standard_True);
1432 if (V1.IsNull() || V2.IsNull()) {
1433 SetErrorCode("Bad edge given for the axis");
1436 gp_Pnt aLoc = BRep_Tool::Pnt(V1);
1437 gp_Vec aVec (aLoc, BRep_Tool::Pnt(V2));
1438 if (aVec.Magnitude() < Precision::Confusion()) {
1439 SetErrorCode("Vector with null magnitude given");
1443 gp_Ax3 anAx3 (aLoc, aVec);
1444 return new Geom_CylindricalSurface(anAx3, theRadius);
1448 //=======================================================================
1449 //function : getShapesOnBoxIDs
1451 * \brief Find IDs of subshapes complying with given status about surface
1452 * \param theBox - the box to check state of subshapes against
1453 * \param theShape - the shape to explore
1454 * \param theShapeType - type of subshape of theShape
1455 * \param theState - required state
1456 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1458 //=======================================================================
1460 Handle(TColStd_HSequenceOfInteger)
1461 GEOMImpl_IShapesOperations::getShapesOnBoxIDs(const Handle(GEOM_Object)& theBox,
1462 const Handle(GEOM_Object)& theShape,
1463 const Standard_Integer theShapeType,
1464 GEOMAlgo_State theState)
1466 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
1468 TopoDS_Shape aBox = theBox->GetValue();
1469 TopoDS_Shape aShape = theShape->GetValue();
1471 // Check presence of triangulation, build if need
1472 if (!CheckTriangulation(aShape)) {
1473 SetErrorCode("Cannot build triangulation on the shape");
1478 GEOMAlgo_FinderShapeOn2 aFinder;
1479 Standard_Real aTol = 0.0001; // default value
1481 Handle(GEOMAlgo_ClsfBox) aClsfBox = new GEOMAlgo_ClsfBox;
1482 aClsfBox->SetBox(aBox);
1484 aFinder.SetShape(aShape);
1485 aFinder.SetTolerance(aTol);
1486 aFinder.SetClsf(aClsfBox);
1487 aFinder.SetShapeType( (TopAbs_ShapeEnum)theShapeType );
1488 aFinder.SetState(theState);
1491 // Interprete results
1492 Standard_Integer iErr = aFinder.ErrorStatus();
1493 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
1495 MESSAGE(" iErr : " << iErr);
1496 TCollection_AsciiString aMsg (" iErr : ");
1497 aMsg += TCollection_AsciiString(iErr);
1501 Standard_Integer iWrn = aFinder.WarningStatus();
1502 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
1504 MESSAGE(" *** iWrn : " << iWrn);
1507 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
1509 if (listSS.Extent() < 1) {
1510 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
1511 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
1515 // Fill sequence of object IDs
1516 aSeqOfIDs = new TColStd_HSequenceOfInteger;
1518 TopTools_IndexedMapOfShape anIndices;
1519 TopExp::MapShapes(aShape, anIndices);
1521 TopTools_ListIteratorOfListOfShape itSub (listSS);
1522 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
1523 int id = anIndices.FindIndex(itSub.Value());
1524 aSeqOfIDs->Append(id);
1531 //=======================================================================
1532 //function : GetShapesOnBoxIDs
1534 * \brief Find subshapes complying with given status about surface
1535 * \param theBox - the box to check state of subshapes against
1536 * \param theShape - the shape to explore
1537 * \param theShapeType - type of subshape of theShape
1538 * \param theState - required state
1539 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1541 //=======================================================================
1543 Handle(TColStd_HSequenceOfInteger)
1544 GEOMImpl_IShapesOperations::GetShapesOnBoxIDs(const Handle(GEOM_Object)& theBox,
1545 const Handle(GEOM_Object)& theShape,
1546 const Standard_Integer theShapeType,
1547 GEOMAlgo_State theState)
1549 // Find subshapes ids
1550 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
1551 getShapesOnBoxIDs (theBox, theShape, theShapeType, theState);
1552 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
1555 // The GetShapesOnBox() doesn't change object so no new function is required.
1556 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theBox)->GetLastFunction();
1558 // Make a Python command
1559 GEOM::TPythonDump(aFunction)
1560 << "listShapesOnBoxIDs = geompy.GetShapesOnBoxIDs("
1563 << TopAbs_ShapeEnum(theShapeType) << ", "
1570 //=======================================================================
1571 //function : GetShapesOnBox
1573 * \brief Find subshapes complying with given status about surface
1574 * \param theBox - the box to check state of subshapes against
1575 * \param theShape - the shape to explore
1576 * \param theShapeType - type of subshape of theShape
1577 * \param theState - required state
1578 * \retval Handle(TColStd_HSequenceOfTransient) - found subshapes
1580 //=======================================================================
1582 Handle(TColStd_HSequenceOfTransient)
1583 GEOMImpl_IShapesOperations::GetShapesOnBox(const Handle(GEOM_Object)& theBox,
1584 const Handle(GEOM_Object)& theShape,
1585 const Standard_Integer theShapeType,
1586 GEOMAlgo_State theState)
1588 // Find subshapes ids
1589 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
1590 getShapesOnBoxIDs (theBox, theShape, theShapeType, theState);
1591 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
1594 // Find objects by indices
1595 TCollection_AsciiString anAsciiList;
1596 Handle(TColStd_HSequenceOfTransient) aSeq;
1597 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
1598 if ( aSeq.IsNull() || aSeq->IsEmpty() )
1601 // Make a Python command
1603 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
1604 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1606 GEOM::TPythonDump(aFunction)
1607 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnBox("
1610 << TopAbs_ShapeEnum(theShapeType) << ", "
1618 //=======================================================================
1619 //function : getShapesOnShapeIDs
1621 * \brief Find IDs of subshapes complying with given status about surface
1622 * \param theCheckShape - the shape to check state of subshapes against
1623 * \param theShape - the shape to explore
1624 * \param theShapeType - type of subshape of theShape
1625 * \param theState - required state
1626 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1628 //=======================================================================
1630 Handle(TColStd_HSequenceOfInteger)
1631 GEOMImpl_IShapesOperations::getShapesOnShapeIDs
1632 (const Handle(GEOM_Object)& theCheckShape,
1633 const Handle(GEOM_Object)& theShape,
1634 const Standard_Integer theShapeType,
1635 GEOMAlgo_State theState)
1637 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
1639 TopoDS_Shape aCheckShape = theCheckShape->GetValue();
1640 TopoDS_Shape aShape = theShape->GetValue();
1641 TopTools_ListOfShape res;
1643 // Check presence of triangulation, build if need
1644 if (!CheckTriangulation(aShape)) {
1645 SetErrorCode("Cannot build triangulation on the shape");
1650 GEOMAlgo_FinderShapeOn2 aFinder;
1651 Standard_Real aTol = 0.0001; // default value
1653 Handle(GEOMAlgo_ClsfSolid) aClsfSolid = new GEOMAlgo_ClsfSolid;
1654 aClsfSolid->SetShape(aCheckShape);
1656 aFinder.SetShape(aShape);
1657 aFinder.SetTolerance(aTol);
1658 aFinder.SetClsf(aClsfSolid);
1659 aFinder.SetShapeType( (TopAbs_ShapeEnum)theShapeType );
1660 aFinder.SetState(theState);
1663 // Interprete results
1664 Standard_Integer iErr = aFinder.ErrorStatus();
1665 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
1667 MESSAGE(" iErr : " << iErr);
1668 TCollection_AsciiString aMsg (" iErr : ");
1669 aMsg += TCollection_AsciiString(iErr);
1673 Standard_Integer iWrn = aFinder.WarningStatus();
1674 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
1676 MESSAGE(" *** iWrn : " << iWrn);
1679 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
1681 if (listSS.Extent() < 1) {
1682 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
1683 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
1686 // Fill sequence of object IDs
1687 aSeqOfIDs = new TColStd_HSequenceOfInteger;
1689 TopTools_IndexedMapOfShape anIndices;
1690 TopExp::MapShapes(aShape, anIndices);
1692 TopTools_ListIteratorOfListOfShape itSub (listSS);
1693 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
1694 int id = anIndices.FindIndex(itSub.Value());
1695 aSeqOfIDs->Append(id);
1702 //=======================================================================
1703 //function : GetShapesOnShapeIDs
1705 * \brief Find subshapes complying with given status about surface
1706 * \param theCheckShape - the shape to check state of subshapes against
1707 * \param theShape - the shape to explore
1708 * \param theShapeType - type of subshape of theShape
1709 * \param theState - required state
1710 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1712 //=======================================================================
1714 Handle(TColStd_HSequenceOfInteger)
1715 GEOMImpl_IShapesOperations::GetShapesOnShapeIDs
1716 (const Handle(GEOM_Object)& theCheckShape,
1717 const Handle(GEOM_Object)& theShape,
1718 const Standard_Integer theShapeType,
1719 GEOMAlgo_State theState)
1721 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
1722 getShapesOnShapeIDs (theCheckShape, theShape, theShapeType, theState);
1724 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
1727 // The GetShapesOnShape() doesn't change object so no new function is required.
1728 Handle(GEOM_Function) aFunction =
1729 GEOM::GetCreatedLast(theShape,theCheckShape)->GetLastFunction();
1731 // Make a Python command
1732 GEOM::TPythonDump(aFunction)
1733 << "listShapesOnBoxIDs = geompy.GetShapesOnShapeIDs("
1734 << theCheckShape << ", "
1736 << TopAbs_ShapeEnum(theShapeType) << ", "
1744 //=======================================================================
1745 //function : GetShapesOnShape
1747 * \brief Find subshapes complying with given status about surface
1748 * \param theCheckShape - the shape to check state of subshapes against
1749 * \param theShape - the shape to explore
1750 * \param theShapeType - type of subshape of theShape
1751 * \param theState - required state
1752 * \retval Handle(TColStd_HSequenceOfTransient) - found subshapes
1754 //=======================================================================
1756 Handle(TColStd_HSequenceOfTransient)
1757 GEOMImpl_IShapesOperations::GetShapesOnShape
1758 (const Handle(GEOM_Object)& theCheckShape,
1759 const Handle(GEOM_Object)& theShape,
1760 const Standard_Integer theShapeType,
1761 GEOMAlgo_State theState)
1763 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
1764 getShapesOnShapeIDs (theCheckShape, theShape, theShapeType, theState);
1765 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
1768 // Find objects by indices
1769 TCollection_AsciiString anAsciiList;
1770 Handle(TColStd_HSequenceOfTransient) aSeq;
1771 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
1773 if ( aSeq.IsNull() || aSeq->IsEmpty() )
1776 // Make a Python command
1778 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
1779 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1781 GEOM::TPythonDump(aFunction)
1782 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnShape("
1783 << theCheckShape << ", "
1785 << TopAbs_ShapeEnum(theShapeType) << ", "
1794 //=======================================================================
1795 //function : GetShapesOnShapeAsCompound
1796 //=======================================================================
1798 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetShapesOnShapeAsCompound
1799 (const Handle(GEOM_Object)& theCheckShape,
1800 const Handle(GEOM_Object)& theShape,
1801 const Standard_Integer theShapeType,
1802 GEOMAlgo_State theState)
1804 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
1805 getShapesOnShapeIDs (theCheckShape, theShape, theShapeType, theState);
1807 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
1810 // Find objects by indices
1811 TCollection_AsciiString anAsciiList;
1812 Handle(TColStd_HSequenceOfTransient) aSeq;
1813 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
1815 if ( aSeq.IsNull() || aSeq->IsEmpty() )
1818 TopoDS_Compound aCompound;
1820 B.MakeCompound(aCompound);
1822 for(; i<=aSeq->Length(); i++) {
1823 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(aSeq->Value(i));
1824 TopoDS_Shape aShape_i = anObj->GetValue();
1825 B.Add(aCompound,aShape_i);
1828 //Add a new result object
1829 Handle(GEOM_Object) aRes = GetEngine()->AddObject(GetDocID(), GEOM_SHAPES_ON_SHAPE);
1830 Handle(GEOM_Function) aFunction =
1831 aRes->AddFunction(GEOMImpl_ShapeDriver::GetID(), SHAPES_ON_SHAPE);
1832 aFunction->SetValue(aCompound);
1834 GEOM::TPythonDump(aFunction)
1835 << aRes << " = geompy.GetShapesOnShapeAsCompound("
1836 << theCheckShape << ", "
1838 << TopAbs_ShapeEnum(theShapeType) << ", "
1847 //=======================================================================
1848 //function : getShapesOnSurfaceIDs
1850 * \brief Find IDs of subshapes complying with given status about surface
1851 * \param theSurface - the surface to check state of subshapes against
1852 * \param theShape - the shape to explore
1853 * \param theShapeType - type of subshape of theShape
1854 * \param theState - required state
1855 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1857 //=======================================================================
1859 Handle(TColStd_HSequenceOfInteger)
1860 GEOMImpl_IShapesOperations::getShapesOnSurfaceIDs(const Handle(Geom_Surface)& theSurface,
1861 const TopoDS_Shape& theShape,
1862 TopAbs_ShapeEnum theShapeType,
1863 GEOMAlgo_State theState)
1865 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
1867 // Check presence of triangulation, build if need
1868 if (!CheckTriangulation(theShape)) {
1869 SetErrorCode("Cannot build triangulation on the shape");
1874 GEOMAlgo_FinderShapeOn1 aFinder;
1875 Standard_Real aTol = 0.0001; // default value
1877 aFinder.SetShape(theShape);
1878 aFinder.SetTolerance(aTol);
1879 aFinder.SetSurface(theSurface);
1880 aFinder.SetShapeType(theShapeType);
1881 aFinder.SetState(theState);
1883 // Sets the minimal number of inner points for the faces that do not have own
1884 // inner points at all (for e.g. rectangular planar faces have just 2 triangles).
1886 aFinder.SetNbPntsMin(3);
1887 // Sets the maximal number of inner points for edges or faces.
1888 // It is usefull for the cases when this number is very big (e.g =2000) to improve
1889 // the performance. If this value =0, all inner points will be taken into account.
1891 aFinder.SetNbPntsMax(100);
1895 // Interprete results
1896 Standard_Integer iErr = aFinder.ErrorStatus();
1897 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
1899 MESSAGE(" iErr : " << iErr);
1900 TCollection_AsciiString aMsg (" iErr : ");
1901 aMsg += TCollection_AsciiString(iErr);
1905 Standard_Integer iWrn = aFinder.WarningStatus();
1906 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
1908 MESSAGE(" *** iWrn : " << iWrn);
1911 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
1913 if (listSS.Extent() < 1) {
1914 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
1915 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
1919 // Fill sequence of object IDs
1920 aSeqOfIDs = new TColStd_HSequenceOfInteger;
1922 TopTools_IndexedMapOfShape anIndices;
1923 TopExp::MapShapes(theShape, anIndices);
1925 TopTools_ListIteratorOfListOfShape itSub (listSS);
1926 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
1927 int id = anIndices.FindIndex(itSub.Value());
1928 aSeqOfIDs->Append(id);
1934 //=======================================================================
1935 //function : getObjectsShapesOn
1937 * \brief Find shape objects and their entries by their ids
1938 * \param theShapeIDs - incoming shape ids
1939 * \param theShapeEntries - outgoing entries like "entry1, entry2, ..."
1940 * \retval Handle(TColStd_HSequenceOfTransient) - found shape objects
1942 //=======================================================================
1944 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::
1945 getObjectsShapesOn(const Handle(GEOM_Object)& theShape,
1946 const Handle(TColStd_HSequenceOfInteger)& theShapeIDs,
1947 TCollection_AsciiString & theShapeEntries)
1949 Handle(TColStd_HSequenceOfTransient) aSeq;
1951 if ( !theShapeIDs.IsNull() && theShapeIDs->Length() > 0 )
1953 aSeq = new TColStd_HSequenceOfTransient;
1954 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
1955 TCollection_AsciiString anEntry;
1956 for ( int i = 1; i <= theShapeIDs->Length(); ++i )
1958 anArray->SetValue(1, theShapeIDs->Value( i ));
1959 Handle(GEOM_Object) anObj = GetEngine()->AddSubShape(theShape, anArray);
1960 aSeq->Append( anObj );
1962 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
1963 if ( i != 1 ) theShapeEntries += ",";
1964 theShapeEntries += anEntry;
1970 //=======================================================================
1971 //function : getShapesOnSurface
1973 * \brief Find subshapes complying with given status about surface
1974 * \param theSurface - the surface to check state of subshapes against
1975 * \param theShape - the shape to explore
1976 * \param theShapeType - type of subshape of theShape
1977 * \param theState - required state
1978 * \param theShapeEntries - outgoing entries like "entry1, entry2, ..."
1979 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1981 //=======================================================================
1983 Handle(TColStd_HSequenceOfTransient)
1984 GEOMImpl_IShapesOperations::getShapesOnSurface(const Handle(Geom_Surface)& theSurface,
1985 const Handle(GEOM_Object)& theShape,
1986 TopAbs_ShapeEnum theShapeType,
1987 GEOMAlgo_State theState,
1988 TCollection_AsciiString & theShapeEntries)
1990 // Find subshapes ids
1991 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
1992 getShapesOnSurfaceIDs (theSurface, theShape->GetValue(), theShapeType, theState);
1993 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
1996 return getObjectsShapesOn( theShape, aSeqOfIDs, theShapeEntries );
1999 //=============================================================================
2003 //=============================================================================
2004 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnPlane
2005 (const Handle(GEOM_Object)& theShape,
2006 const Standard_Integer theShapeType,
2007 const Handle(GEOM_Object)& theAx1,
2008 const GEOMAlgo_State theState)
2012 if (theShape.IsNull() || theAx1.IsNull()) return NULL;
2014 TopoDS_Shape aShape = theShape->GetValue();
2015 TopoDS_Shape anAx1 = theAx1->GetValue();
2017 if (aShape.IsNull() || anAx1.IsNull()) return NULL;
2019 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2020 if ( !checkTypeShapesOn( theShapeType ))
2024 Handle(Geom_Surface) aPlane = makePlane( anAx1 );
2025 if ( aPlane.IsNull() )
2029 TCollection_AsciiString anAsciiList;
2030 Handle(TColStd_HSequenceOfTransient) aSeq;
2031 aSeq = getShapesOnSurface( aPlane, theShape, aShapeType, theState, anAsciiList );
2032 if ( aSeq.IsNull() || aSeq->Length() == 0 )
2035 // Make a Python command
2037 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2038 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2040 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
2041 << "] = geompy.GetShapesOnPlane(" << theShape << ", "
2042 << aShapeType << ", " << theAx1 << ", " << theState << ")";
2048 //=============================================================================
2050 * GetShapesOnPlaneWithLocation
2052 //=============================================================================
2053 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnPlaneWithLocation
2054 (const Handle(GEOM_Object)& theShape,
2055 const Standard_Integer theShapeType,
2056 const Handle(GEOM_Object)& theAx1,
2057 const Handle(GEOM_Object)& thePnt,
2058 const GEOMAlgo_State theState)
2062 if (theShape.IsNull() || theAx1.IsNull() || thePnt.IsNull()) return NULL;
2064 TopoDS_Shape aShape = theShape->GetValue();
2065 TopoDS_Shape anAx1 = theAx1->GetValue();
2066 TopoDS_Shape anPnt = thePnt->GetValue();
2068 if (aShape.IsNull() || anAx1.IsNull() || anPnt.IsNull()) return NULL;
2070 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2071 if ( !checkTypeShapesOn( theShapeType ))
2075 if ( anAx1.ShapeType() != TopAbs_EDGE || anPnt.ShapeType() != TopAbs_VERTEX ) return NULL;
2076 TopoDS_Vertex V1, V2, V3;
2077 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
2078 TopExp::Vertices(anEdge, V1, V2, Standard_True);
2080 if (V1.IsNull() || V2.IsNull()) {
2081 SetErrorCode("Bad edge given for the plane normal vector");
2084 V3 = TopoDS::Vertex(anPnt);
2087 SetErrorCode("Bad vertex given for the plane location");
2090 gp_Pnt aLoc = BRep_Tool::Pnt(V3);
2091 gp_Vec aVec(BRep_Tool::Pnt(V1),BRep_Tool::Pnt(V2));
2093 if (aVec.Magnitude() < Precision::Confusion()) {
2094 SetErrorCode("Vector with null magnitude given");
2097 Handle(Geom_Surface) aPlane = new Geom_Plane(aLoc, aVec);
2099 if ( aPlane.IsNull() )
2103 TCollection_AsciiString anAsciiList;
2104 Handle(TColStd_HSequenceOfTransient) aSeq;
2105 aSeq = getShapesOnSurface( aPlane, theShape, aShapeType, theState, anAsciiList );
2106 if ( aSeq.IsNull() || aSeq->Length() == 0 )
2109 // Make a Python command
2111 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2112 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2114 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
2115 << "] = geompy.GetShapesOnPlaneWithLocation(" << theShape << ", "
2116 << aShapeType << ", " << theAx1 << ", "<< thePnt <<", " << theState << ")";
2122 //=============================================================================
2124 * GetShapesOnCylinder
2126 //=============================================================================
2127 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnCylinder
2128 (const Handle(GEOM_Object)& theShape,
2129 const Standard_Integer theShapeType,
2130 const Handle(GEOM_Object)& theAxis,
2131 const Standard_Real theRadius,
2132 const GEOMAlgo_State theState)
2136 if (theShape.IsNull() || theAxis.IsNull()) return NULL;
2138 TopoDS_Shape aShape = theShape->GetValue();
2139 TopoDS_Shape anAxis = theAxis->GetValue();
2141 if (aShape.IsNull() || anAxis.IsNull()) return NULL;
2143 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2144 if ( !checkTypeShapesOn( aShapeType ))
2147 // Create a cylinder surface
2148 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
2149 if ( aCylinder.IsNull() )
2153 TCollection_AsciiString anAsciiList;
2154 Handle(TColStd_HSequenceOfTransient) aSeq;
2155 aSeq = getShapesOnSurface( aCylinder, theShape, aShapeType, theState, anAsciiList );
2156 if ( aSeq.IsNull() || aSeq->Length() == 0 )
2159 // Make a Python command
2161 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2162 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2164 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
2165 << "] = geompy.GetShapesOnCylinder(" << theShape << ", " << aShapeType
2166 << ", " << theAxis << ", " << theRadius << ", " << theState << ")";
2172 //=============================================================================
2176 //=============================================================================
2177 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnSphere
2178 (const Handle(GEOM_Object)& theShape,
2179 const Standard_Integer theShapeType,
2180 const Handle(GEOM_Object)& theCenter,
2181 const Standard_Real theRadius,
2182 const GEOMAlgo_State theState)
2186 if (theShape.IsNull() || theCenter.IsNull()) return NULL;
2188 TopoDS_Shape aShape = theShape->GetValue();
2189 TopoDS_Shape aCenter = theCenter->GetValue();
2191 if (aShape.IsNull() || aCenter.IsNull()) return NULL;
2193 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2194 if ( !checkTypeShapesOn( aShapeType ))
2197 // Center of the sphere
2198 if (aCenter.ShapeType() != TopAbs_VERTEX) return NULL;
2199 gp_Pnt aLoc = BRep_Tool::Pnt(TopoDS::Vertex(aCenter));
2201 gp_Ax3 anAx3 (aLoc, gp::DZ());
2202 Handle(Geom_SphericalSurface) aSphere =
2203 new Geom_SphericalSurface(anAx3, theRadius);
2206 TCollection_AsciiString anAsciiList;
2207 Handle(TColStd_HSequenceOfTransient) aSeq;
2208 aSeq = getShapesOnSurface( aSphere, theShape, aShapeType, theState, anAsciiList );
2209 if ( aSeq.IsNull() || aSeq->Length() == 0 )
2212 // Make a Python command
2214 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2215 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2217 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
2218 << "] = geompy.GetShapesOnSphere(" << theShape << ", " << aShapeType
2219 << ", " << theCenter << ", " << theRadius << ", " << theState << ")";
2225 //=============================================================================
2227 * GetShapesOnPlaneIDs
2229 //=============================================================================
2230 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnPlaneIDs
2231 (const Handle(GEOM_Object)& theShape,
2232 const Standard_Integer theShapeType,
2233 const Handle(GEOM_Object)& theAx1,
2234 const GEOMAlgo_State theState)
2238 if (theShape.IsNull() || theAx1.IsNull()) return NULL;
2240 TopoDS_Shape aShape = theShape->GetValue();
2241 TopoDS_Shape anAx1 = theAx1->GetValue();
2243 if (aShape.IsNull() || anAx1.IsNull()) return NULL;
2245 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2246 if ( !checkTypeShapesOn( aShapeType ))
2250 Handle(Geom_Surface) aPlane = makePlane( anAx1 );
2251 if ( aPlane.IsNull() )
2255 Handle(TColStd_HSequenceOfInteger) aSeq;
2256 aSeq = getShapesOnSurfaceIDs( aPlane, aShape, aShapeType, theState );
2258 // The GetShapesOnPlaneIDs() doesn't change object so no new function is required.
2259 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAx1)->GetLastFunction();
2261 // Make a Python command
2262 GEOM::TPythonDump(aFunction, /*append=*/true)
2263 << "listShapesOnPlane = geompy.GetShapesOnPlaneIDs"
2264 << "(" << theShape << "," << aShapeType << "," << theAx1 << "," << theState << ")";
2270 //=============================================================================
2272 * GetShapesOnPlaneWithLocationIDs
2274 //=============================================================================
2275 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnPlaneWithLocationIDs
2276 (const Handle(GEOM_Object)& theShape,
2277 const Standard_Integer theShapeType,
2278 const Handle(GEOM_Object)& theAx1,
2279 const Handle(GEOM_Object)& thePnt,
2280 const GEOMAlgo_State theState)
2284 if (theShape.IsNull() || theAx1.IsNull() || thePnt.IsNull()) return NULL;
2286 TopoDS_Shape aShape = theShape->GetValue();
2287 TopoDS_Shape anAx1 = theAx1->GetValue();
2288 TopoDS_Shape anPnt = thePnt->GetValue();
2290 if (aShape.IsNull() || anAx1.IsNull() || anPnt.IsNull()) return NULL;
2292 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2293 if ( !checkTypeShapesOn( aShapeType ))
2297 if (anAx1.ShapeType() != TopAbs_EDGE || anPnt.ShapeType() != TopAbs_VERTEX) return NULL;
2298 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
2299 TopoDS_Vertex V1, V2, V3;
2300 TopExp::Vertices(anEdge, V1, V2, Standard_True);
2301 if (V1.IsNull() || V2.IsNull()) {
2302 SetErrorCode("Bad edge given for the plane normal vector");
2305 V3 = TopoDS::Vertex(anPnt);
2307 SetErrorCode("Bad vertex given for the plane location");
2310 gp_Pnt aLoc = BRep_Tool::Pnt(V3);
2311 gp_Vec aVec(BRep_Tool::Pnt(V1),BRep_Tool::Pnt(V2));
2312 if (aVec.Magnitude() < Precision::Confusion()) {
2313 SetErrorCode("Vector with null magnitude given");
2317 Handle(Geom_Surface) aPlane = new Geom_Plane(aLoc, aVec);
2318 if ( aPlane.IsNull() )
2322 Handle(TColStd_HSequenceOfInteger) aSeq;
2323 aSeq = getShapesOnSurfaceIDs( aPlane, aShape, aShapeType, theState );
2325 // The GetShapesOnPlaneIDs() doesn't change object so no new function is required.
2326 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAx1)->GetLastFunction();
2328 // Make a Python command
2329 GEOM::TPythonDump(aFunction, /*append=*/true)
2330 << "listShapesOnPlane = geompy.GetShapesOnPlaneWithLocationIDs"
2331 << "(" << theShape << ", " << aShapeType << ", " << theAx1 << ", "<< thePnt << ", " << theState << ")";
2337 //=============================================================================
2339 * GetShapesOnCylinderIDs
2341 //=============================================================================
2342 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnCylinderIDs
2343 (const Handle(GEOM_Object)& theShape,
2344 const Standard_Integer theShapeType,
2345 const Handle(GEOM_Object)& theAxis,
2346 const Standard_Real theRadius,
2347 const GEOMAlgo_State theState)
2351 if (theShape.IsNull() || theAxis.IsNull()) return NULL;
2353 TopoDS_Shape aShape = theShape->GetValue();
2354 TopoDS_Shape anAxis = theAxis->GetValue();
2356 if (aShape.IsNull() || anAxis.IsNull()) return NULL;
2358 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2359 if ( !checkTypeShapesOn( aShapeType ))
2362 // Create a cylinder surface
2363 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
2364 if ( aCylinder.IsNull() )
2368 Handle(TColStd_HSequenceOfInteger) aSeq;
2369 aSeq = getShapesOnSurfaceIDs( aCylinder, aShape, aShapeType, theState );
2371 // The GetShapesOnCylinder() doesn't change object so no new function is required.
2372 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAxis)->GetLastFunction();
2374 // Make a Python command
2375 GEOM::TPythonDump(aFunction, /*append=*/true)
2376 << "listShapesOnCylinder = geompy.GetShapesOnCylinderIDs"
2377 << "(" << theShape << ", " << aShapeType << ", " << theAxis << ", "
2378 << theRadius << ", " << theState << ")";
2384 //=============================================================================
2386 * GetShapesOnSphereIDs
2388 //=============================================================================
2389 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnSphereIDs
2390 (const Handle(GEOM_Object)& theShape,
2391 const Standard_Integer theShapeType,
2392 const Handle(GEOM_Object)& theCenter,
2393 const Standard_Real theRadius,
2394 const GEOMAlgo_State theState)
2398 if (theShape.IsNull() || theCenter.IsNull()) return NULL;
2400 TopoDS_Shape aShape = theShape->GetValue();
2401 TopoDS_Shape aCenter = theCenter->GetValue();
2403 if (aShape.IsNull() || aCenter.IsNull()) return NULL;
2405 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2406 if ( !checkTypeShapesOn( aShapeType ))
2409 // Center of the sphere
2410 if (aCenter.ShapeType() != TopAbs_VERTEX) return NULL;
2411 gp_Pnt aLoc = BRep_Tool::Pnt(TopoDS::Vertex(aCenter));
2413 gp_Ax3 anAx3 (aLoc, gp::DZ());
2414 Handle(Geom_SphericalSurface) aSphere =
2415 new Geom_SphericalSurface(anAx3, theRadius);
2418 Handle(TColStd_HSequenceOfInteger) aSeq;
2419 aSeq = getShapesOnSurfaceIDs( aSphere, aShape, aShapeType, theState );
2421 // The GetShapesOnSphere() doesn't change object so no new function is required.
2422 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theCenter)->GetLastFunction();
2424 // Make a Python command
2425 GEOM::TPythonDump(aFunction, /*append=*/true)
2426 << "listShapesOnCylinder = geompy.GetShapesOnCylinderIDs"
2427 << "(" << theShape << ", " << aShapeType << ", " << theCenter << ", "
2428 << theRadius << ", " << theState << ")";
2434 //=======================================================================
2435 //function : getShapesOnQuadrangleIDs
2437 * \brief Find IDs of subshapes complying with given status about quadrangle
2438 * \param theShape - the shape to explore
2439 * \param theShapeType - type of subshape of theShape
2440 * \param theTopLeftPoint - top left quadrangle corner
2441 * \param theTopRigthPoint - top right quadrangle corner
2442 * \param theBottomLeftPoint - bottom left quadrangle corner
2443 * \param theBottomRigthPoint - bottom right quadrangle corner
2444 * \param theState - required state
2445 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
2447 //=======================================================================
2449 Handle(TColStd_HSequenceOfInteger)
2450 GEOMImpl_IShapesOperations::getShapesOnQuadrangleIDs (const Handle(GEOM_Object)& theShape,
2451 const Standard_Integer theShapeType,
2452 const Handle(GEOM_Object)& theTopLeftPoint,
2453 const Handle(GEOM_Object)& theTopRigthPoint,
2454 const Handle(GEOM_Object)& theBottomLeftPoint,
2455 const Handle(GEOM_Object)& theBottomRigthPoint,
2456 const GEOMAlgo_State theState)
2460 if ( theShape.IsNull() ||
2461 theTopLeftPoint.IsNull() ||
2462 theTopRigthPoint.IsNull() ||
2463 theBottomLeftPoint.IsNull() ||
2464 theBottomRigthPoint.IsNull() )
2467 TopoDS_Shape aShape = theShape->GetValue();
2468 TopoDS_Shape aTL = theTopLeftPoint->GetValue();
2469 TopoDS_Shape aTR = theTopRigthPoint->GetValue();
2470 TopoDS_Shape aBL = theBottomLeftPoint->GetValue();
2471 TopoDS_Shape aBR = theBottomRigthPoint->GetValue();
2473 if (aShape.IsNull() ||
2478 aTL.ShapeType() != TopAbs_VERTEX ||
2479 aTR.ShapeType() != TopAbs_VERTEX ||
2480 aBL.ShapeType() != TopAbs_VERTEX ||
2481 aBR.ShapeType() != TopAbs_VERTEX )
2484 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2485 if ( !checkTypeShapesOn( aShapeType ))
2488 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
2490 // Check presence of triangulation, build if need
2491 if (!CheckTriangulation(aShape)) {
2492 SetErrorCode("Cannot build triangulation on the shape");
2497 gp_Pnt aPntTL = BRep_Tool::Pnt(TopoDS::Vertex(aTL));
2498 gp_Pnt aPntTR = BRep_Tool::Pnt(TopoDS::Vertex(aTR));
2499 gp_Pnt aPntBL = BRep_Tool::Pnt(TopoDS::Vertex(aBL));
2500 gp_Pnt aPntBR = BRep_Tool::Pnt(TopoDS::Vertex(aBR));
2502 GEOMAlgo_FinderShapeOnQuad aFinder( aPntTL, aPntTR, aPntBL, aPntBR );
2503 Standard_Real aTol = 0.0001; // default value
2505 aFinder.SetShape(aShape);
2506 aFinder.SetTolerance(aTol);
2507 //aFinder.SetSurface(theSurface);
2508 aFinder.SetShapeType(aShapeType);
2509 aFinder.SetState(theState);
2511 // Sets the minimal number of inner points for the faces that do not have own
2512 // inner points at all (for e.g. rectangular planar faces have just 2 triangles).
2514 aFinder.SetNbPntsMin(3);
2515 // Sets the maximal number of inner points for edges or faces.
2516 // It is usefull for the cases when this number is very big (e.g =2000) to improve
2517 // the performance. If this value =0, all inner points will be taken into account.
2519 aFinder.SetNbPntsMax(100);
2523 // Interprete results
2524 Standard_Integer iErr = aFinder.ErrorStatus();
2525 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
2527 MESSAGE(" iErr : " << iErr);
2528 TCollection_AsciiString aMsg (" iErr : ");
2529 aMsg += TCollection_AsciiString(iErr);
2533 Standard_Integer iWrn = aFinder.WarningStatus();
2534 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
2536 MESSAGE(" *** iWrn : " << iWrn);
2539 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
2541 if (listSS.Extent() < 1) {
2542 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
2543 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
2547 // Fill sequence of object IDs
2548 aSeqOfIDs = new TColStd_HSequenceOfInteger;
2550 TopTools_IndexedMapOfShape anIndices;
2551 TopExp::MapShapes(aShape, anIndices);
2553 TopTools_ListIteratorOfListOfShape itSub (listSS);
2554 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
2555 int id = anIndices.FindIndex(itSub.Value());
2556 aSeqOfIDs->Append(id);
2561 //=======================================================================
2562 //function : GetShapesOnQuadrangle
2564 * \brief Find subshapes complying with given status about quadrangle
2565 * \param theShape - the shape to explore
2566 * \param theShapeType - type of subshape of theShape
2567 * \param theTopLeftPoint - top left quadrangle corner
2568 * \param theTopRigthPoint - top right quadrangle corner
2569 * \param theBottomLeftPoint - bottom left quadrangle corner
2570 * \param theBottomRigthPoint - bottom right quadrangle corner
2571 * \param theState - required state
2572 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
2574 //=======================================================================
2576 Handle(TColStd_HSequenceOfTransient)
2577 GEOMImpl_IShapesOperations::GetShapesOnQuadrangle (const Handle(GEOM_Object)& theShape,
2578 const Standard_Integer theShapeType,
2579 const Handle(GEOM_Object)& theTopLeftPoint,
2580 const Handle(GEOM_Object)& theTopRigthPoint,
2581 const Handle(GEOM_Object)& theBottomLeftPoint,
2582 const Handle(GEOM_Object)& theBottomRigthPoint,
2583 const GEOMAlgo_State theState)
2586 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2587 getShapesOnQuadrangleIDs( theShape,
2592 theBottomRigthPoint,
2594 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->IsEmpty() )
2597 // Find objects by indices
2598 TCollection_AsciiString anAsciiList;
2599 Handle(TColStd_HSequenceOfTransient) aSeq;
2600 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
2601 if ( aSeq.IsNull() || aSeq->IsEmpty() )
2604 // Make a Python command
2606 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2607 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2609 GEOM::TPythonDump(aFunction)
2610 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnQuadrangle("
2612 << TopAbs_ShapeEnum(theShapeType) << ", "
2613 << theTopLeftPoint << ", "
2614 << theTopRigthPoint << ", "
2615 << theBottomLeftPoint << ", "
2616 << theBottomRigthPoint << ", "
2623 //=======================================================================
2624 //function : GetShapesOnQuadrangleIDs
2626 * \brief Find IDs of subshapes complying with given status about quadrangle
2627 * \param theShape - the shape to explore
2628 * \param theShapeType - type of subshape of theShape
2629 * \param theTopLeftPoint - top left quadrangle corner
2630 * \param theTopRigthPoint - top right quadrangle corner
2631 * \param theBottomLeftPoint - bottom left quadrangle corner
2632 * \param theBottomRigthPoint - bottom right quadrangle corner
2633 * \param theState - required state
2634 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
2636 //=======================================================================
2638 Handle(TColStd_HSequenceOfInteger)
2639 GEOMImpl_IShapesOperations::GetShapesOnQuadrangleIDs (const Handle(GEOM_Object)& theShape,
2640 const Standard_Integer theShapeType,
2641 const Handle(GEOM_Object)& theTopLeftPoint,
2642 const Handle(GEOM_Object)& theTopRigthPoint,
2643 const Handle(GEOM_Object)& theBottomLeftPoint,
2644 const Handle(GEOM_Object)& theBottomRigthPoint,
2645 const GEOMAlgo_State theState)
2648 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2649 getShapesOnQuadrangleIDs( theShape,
2654 theBottomRigthPoint,
2656 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->IsEmpty() )
2659 // Make a Python command
2661 // The GetShapesOnCylinder() doesn't change object so no new function is required.
2662 Handle(GEOM_Object) lastObj = GEOM::GetCreatedLast(theShape,theTopLeftPoint);
2663 lastObj = GEOM::GetCreatedLast(lastObj,theTopRigthPoint);
2664 lastObj = GEOM::GetCreatedLast(lastObj,theBottomRigthPoint);
2665 lastObj = GEOM::GetCreatedLast(lastObj,theBottomLeftPoint);
2666 Handle(GEOM_Function) aFunction = lastObj->GetLastFunction();
2668 GEOM::TPythonDump(aFunction, /*append=*/true)
2669 << "listShapesOnQuadrangle = geompy.GetShapesOnQuadrangleIDs("
2671 << TopAbs_ShapeEnum(theShapeType) << ", "
2672 << theTopLeftPoint << ", "
2673 << theTopRigthPoint << ", "
2674 << theBottomLeftPoint << ", "
2675 << theBottomRigthPoint << ", "
2683 //=============================================================================
2687 //=============================================================================
2688 static bool GetInPlaceOfShape (const Handle(GEOM_Function)& theWhereFunction,
2689 const TopTools_IndexedMapOfShape& theWhereIndices,
2690 const TopoDS_Shape& theWhat,
2691 TColStd_ListOfInteger& theModifiedList)
2693 if (theWhereFunction.IsNull() || theWhat.IsNull()) return false;
2695 if (theWhereIndices.Contains(theWhat)) {
2696 // entity was not changed by the operation
2697 Standard_Integer aWhatIndex = theWhereIndices.FindIndex(theWhat);
2698 theModifiedList.Append(aWhatIndex);
2702 // try to find in history
2703 TDF_Label aHistoryLabel = theWhereFunction->GetHistoryEntry(Standard_False);
2705 // search in history for all argument shapes
2706 Standard_Boolean isFound = Standard_False;
2707 Standard_Boolean isGood = Standard_False;
2709 TDF_LabelSequence aLabelSeq;
2710 theWhereFunction->GetDependency(aLabelSeq);
2711 Standard_Integer nbArg = aLabelSeq.Length();
2713 for (Standard_Integer iarg = 1; iarg <= nbArg && !isFound; iarg++) {
2715 TDF_Label anArgumentRefLabel = aLabelSeq.Value(iarg);
2717 Handle(GEOM_Object) anArgumentObject = GEOM_Object::GetReferencedObject(anArgumentRefLabel);
2718 TopoDS_Shape anArgumentShape = anArgumentObject->GetValue();
2720 TopTools_IndexedMapOfShape anArgumentIndices;
2721 TopExp::MapShapes(anArgumentShape, anArgumentIndices);
2723 if (anArgumentIndices.Contains(theWhat)) {
2724 isFound = Standard_True;
2725 Standard_Integer aWhatIndex = anArgumentIndices.FindIndex(theWhat);
2727 // Find corresponding label in history
2728 TDF_Label anArgumentHistoryLabel =
2729 theWhereFunction->GetArgumentHistoryEntry(anArgumentRefLabel, Standard_False);
2730 if (anArgumentHistoryLabel.IsNull()) {
2731 // Lost History of operation argument. Possibly, all its entities was removed.
2732 isGood = Standard_True;
2735 TDF_Label aWhatHistoryLabel = anArgumentHistoryLabel.FindChild(aWhatIndex, Standard_False);
2737 if (aWhatHistoryLabel.IsNull()) {
2738 // Removed entity ? Compound ? Compsolid ? Shell ? Wire
2739 isGood = Standard_False;
2741 Handle(TDataStd_IntegerArray) anIntegerArray;
2742 if (!aWhatHistoryLabel.FindAttribute(TDataStd_IntegerArray::GetID(), anIntegerArray)) {
2743 //Error: Empty modifications history for the sought shape.
2744 isGood = Standard_False;
2747 isGood = Standard_True;
2748 Standard_Integer imod, aModifLen = anIntegerArray->Array()->Length();
2749 for (imod = 1; imod <= aModifLen; imod++) {
2750 theModifiedList.Append(anIntegerArray->Array()->Value(imod));
2761 // try compound/compsolid/shell/wire element by element
2762 bool isFoundAny = false;
2763 TopTools_MapOfShape mapShape;
2765 if (theWhat.ShapeType() == TopAbs_COMPOUND ||
2766 theWhat.ShapeType() == TopAbs_COMPSOLID) {
2767 // recursive processing of compound/compsolid
2768 TopoDS_Iterator anIt (theWhat, Standard_True, Standard_True);
2769 for (; anIt.More(); anIt.Next()) {
2770 if (mapShape.Add(anIt.Value())) {
2771 TopoDS_Shape curWhat = anIt.Value();
2772 isFoundAny = GetInPlaceOfShape(theWhereFunction, theWhereIndices, curWhat, theModifiedList);
2773 if (isFoundAny) isFound = Standard_True;
2777 else if (theWhat.ShapeType() == TopAbs_SHELL) {
2778 // try to replace a shell by its faces images
2779 TopExp_Explorer anExp (theWhat, TopAbs_FACE);
2780 for (; anExp.More(); anExp.Next()) {
2781 if (mapShape.Add(anExp.Current())) {
2782 TopoDS_Shape curWhat = anExp.Current();
2783 isFoundAny = GetInPlaceOfShape(theWhereFunction, theWhereIndices, curWhat, theModifiedList);
2784 if (isFoundAny) isFound = Standard_True;
2788 else if (theWhat.ShapeType() == TopAbs_WIRE) {
2789 // try to replace a wire by its edges images
2790 TopExp_Explorer anExp (theWhat, TopAbs_EDGE);
2791 for (; anExp.More(); anExp.Next()) {
2792 if (mapShape.Add(anExp.Current())) {
2793 TopoDS_Shape curWhat = anExp.Current();
2794 isFoundAny = GetInPlaceOfShape(theWhereFunction, theWhereIndices, curWhat, theModifiedList);
2795 if (isFoundAny) isFound = Standard_True;
2807 //=============================================================================
2809 * GetShapeProperties
2811 //=============================================================================
2813 void GEOMImpl_IShapesOperations::GetShapeProperties( const TopoDS_Shape aShape, Standard_Real tab[],
2816 GProp_GProps theProps;
2818 TopoDS_Shape aPntShape;
2819 Standard_Real aShapeSize;
2821 if (aShape.ShapeType() == TopAbs_EDGE) BRepGProp::LinearProperties(aShape, theProps);
2822 else if (aShape.ShapeType() == TopAbs_FACE) BRepGProp::SurfaceProperties(aShape, theProps);
2823 else BRepGProp::VolumeProperties(aShape, theProps);
2825 aCenterMass = theProps.CentreOfMass();
2826 aShapeSize = theProps.Mass();
2828 aPntShape = BRepBuilderAPI_MakeVertex(aCenterMass).Shape();
2829 aVertex = BRep_Tool::Pnt( TopoDS::Vertex( aPntShape ) );
2830 tab[0] = aVertex.X();
2831 tab[1] = aVertex.Y();
2832 tab[2] = aVertex.Z();
2833 tab[3] = aShapeSize;
2837 //=============================================================================
2841 //=============================================================================
2842 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlace (Handle(GEOM_Object) theShapeWhere,
2843 Handle(GEOM_Object) theShapeWhat)
2847 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
2849 TopoDS_Shape aWhere = theShapeWhere->GetValue();
2850 TopoDS_Shape aWhat = theShapeWhat->GetValue();
2851 TopoDS_Shape aPntShape;
2852 TopoDS_Vertex aVertex;
2854 if (aWhere.IsNull() || aWhat.IsNull()) {
2855 SetErrorCode("Error: aWhere and aWhat TopoDS_Shape are Null.");
2859 Handle(GEOM_Function) aWhereFunction = theShapeWhere->GetLastFunction();
2860 if (aWhereFunction.IsNull()) {
2861 SetErrorCode("Error: aWhereFunction is Null.");
2865 TopTools_IndexedMapOfShape aWhereIndices;
2866 TopExp::MapShapes(aWhere, aWhereIndices);
2868 TColStd_ListOfInteger aModifiedList;
2869 Standard_Integer aWhereIndex;
2870 Handle(TColStd_HArray1OfInteger) aModifiedArray;
2871 Handle(GEOM_Object) aResult;
2873 bool isFound = false;
2874 Standard_Integer iType = TopAbs_SOLID;
2875 Standard_Integer compType = TopAbs_SOLID;
2876 Standard_Real aWhat_Mass = 0., aWhere_Mass = 0.;
2877 Standard_Real tab_aWhat[4], tab_aWhere[4];
2878 Standard_Real dl_l = 1e-3;
2879 Standard_Real min_l, Tol_1D, Tol_2D, Tol_3D, Tol_Mass;
2880 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
2881 Bnd_Box BoundingBox;
2882 gp_Pnt aPnt, aPnt_aWhat, tab_Pnt[2];
2883 GProp_GProps aProps;
2885 // Find the iType of the aWhat shape
2886 if ( aWhat.ShapeType() == TopAbs_EDGE || aWhat.ShapeType() == TopAbs_WIRE ) iType = TopAbs_EDGE;
2887 else if ( aWhat.ShapeType() == TopAbs_FACE || aWhat.ShapeType() == TopAbs_SHELL ) iType = TopAbs_FACE;
2888 else if ( aWhat.ShapeType() == TopAbs_SOLID || aWhat.ShapeType() == TopAbs_COMPSOLID ) iType = TopAbs_SOLID;
2889 else if ( aWhat.ShapeType() == TopAbs_COMPOUND ) {
2890 // Only the iType of the first shape in the compound is taken into account
2891 TopoDS_Iterator It (aWhat, Standard_True, Standard_True);
2892 compType = It.Value().ShapeType();
2893 if ( compType == TopAbs_EDGE || compType == TopAbs_WIRE ) iType = TopAbs_EDGE;
2894 else if ( compType == TopAbs_FACE || compType == TopAbs_SHELL) iType = TopAbs_FACE;
2895 else if ( compType == TopAbs_SOLID || compType == TopAbs_COMPSOLID) iType = TopAbs_SOLID;
2898 SetErrorCode("Error: An attempt to extract a shape of not supported type.");
2902 TopExp_Explorer Exp_aWhat( aWhat, TopAbs_ShapeEnum( iType ) );
2903 TopExp_Explorer Exp_aWhere( aWhere, TopAbs_ShapeEnum( iType ) );
2904 TopExp_Explorer Exp_Edge( aWhere, TopAbs_EDGE );
2906 // Find the shortest edge in theShapeWhere shape
2907 BRepBndLib::Add(aWhere, BoundingBox);
2908 BoundingBox.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
2909 min_l = fabs(aXmax - aXmin);
2910 if( min_l < fabs(aYmax - aYmin) ) min_l = fabs(aYmax - aYmin);
2911 if( min_l < fabs(aZmax - aZmin) ) min_l = fabs(aZmax - aZmin);
2913 for ( Standard_Integer nbEdge = 0; Exp_Edge.More(); Exp_Edge.Next(), nbEdge++ ) {
2914 TopExp_Explorer Exp_Vertex( Exp_Edge.Current(), TopAbs_VERTEX);
2915 for ( Standard_Integer nbVertex = 0; Exp_Vertex.More(); Exp_Vertex.Next(), nbVertex++ ) {
2916 aPnt = BRep_Tool::Pnt( TopoDS::Vertex( Exp_Vertex.Current() ) );
2917 tab_Pnt[nbVertex] = aPnt;
2919 if ( ! tab_Pnt[0].IsEqual(tab_Pnt[1], dl_l) ) {
2920 BRepGProp::LinearProperties(Exp_Edge.Current(), aProps);
2921 if ( aProps.Mass() < min_l ) min_l = aProps.Mass();
2925 // Compute tolerances
2926 Tol_1D = dl_l * min_l;
2927 Tol_2D = dl_l * ( min_l * min_l) * ( 2. + dl_l);
2928 Tol_3D = dl_l * ( min_l * min_l * min_l ) * ( 3. + (3 * dl_l) + (dl_l * dl_l) );
2931 if ( iType == TopAbs_EDGE ) Tol_Mass = Tol_1D;
2932 else if ( iType == TopAbs_FACE ) Tol_Mass = Tol_2D;
2934 // Compute the ShapeWhat Mass
2935 for ( ; Exp_aWhat.More(); Exp_aWhat.Next() ) {
2936 if ( iType == TopAbs_EDGE ) BRepGProp::LinearProperties(Exp_aWhat.Current(), aProps);
2937 else if ( iType == TopAbs_FACE ) BRepGProp::SurfaceProperties(Exp_aWhat.Current(), aProps);
2938 else BRepGProp::VolumeProperties(Exp_aWhat.Current(), aProps);
2939 aWhat_Mass += aProps.Mass();
2942 // Searching for the sub-shapes inside the ShapeWhere shape
2943 TopTools_MapOfShape map_aWhere;
2944 for ( Exp_aWhere.ReInit(); Exp_aWhere.More(); Exp_aWhere.Next() ) {
2945 if (!map_aWhere.Add(Exp_aWhere.Current()))
2946 continue; // skip repeated shape to avoid mass addition
2947 GetShapeProperties( Exp_aWhere.Current(), tab_aWhere, aPnt );
2948 for ( Exp_aWhat.ReInit(); Exp_aWhat.More(); Exp_aWhat.Next() ) {
2949 GetShapeProperties( Exp_aWhat.Current(), tab_aWhat, aPnt_aWhat );
2950 if ( fabs(tab_aWhat[3] - tab_aWhere[3]) <= Tol_Mass && aPnt_aWhat.Distance(aPnt) <= Tol_1D )
2953 if ( (tab_aWhat[3] - tab_aWhere[3]) > Tol_Mass ) {
2954 aPntShape = BRepBuilderAPI_MakeVertex( aPnt ).Shape();
2955 aVertex = TopoDS::Vertex( aPntShape );
2956 BRepExtrema_DistShapeShape aWhereDistance ( aVertex, Exp_aWhere.Current() );
2957 BRepExtrema_DistShapeShape aWhatDistance ( aVertex, Exp_aWhat.Current() );
2958 if ( fabs(aWhereDistance.Value() - aWhatDistance.Value()) <= Tol_1D )
2963 aWhereIndex = aWhereIndices.FindIndex(Exp_aWhere.Current());
2964 aModifiedList.Append(aWhereIndex);
2965 aWhere_Mass += tab_aWhere[3];
2970 if ( fabs( aWhat_Mass - aWhere_Mass ) <= Tol_Mass ) break;
2973 if (aModifiedList.Extent() == 0) { // Not found any Results
2974 SetErrorCode(NOT_FOUND_ANY);
2978 aModifiedArray = new TColStd_HArray1OfInteger (1, aModifiedList.Extent());
2979 TColStd_ListIteratorOfListOfInteger anIterModif (aModifiedList);
2980 for (Standard_Integer imod = 1; anIterModif.More(); anIterModif.Next(), imod++)
2981 aModifiedArray->SetValue(imod, anIterModif.Value());
2984 aResult = GetEngine()->AddSubShape(theShapeWhere, aModifiedArray);
2985 if (aResult.IsNull()) {
2986 SetErrorCode("Error in algorithm: result found, but cannot be returned.");
2990 if (aModifiedArray->Length() > 1) {
2992 aResult->SetType(GEOM_GROUP);
2994 //Set a sub shape type
2995 TopoDS_Shape aFirstFound = aWhereIndices.FindKey(aModifiedArray->Value(1));
2996 TopAbs_ShapeEnum aShapeType = aFirstFound.ShapeType();
2998 TDF_Label aFreeLabel = aResult->GetFreeLabel();
2999 TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aShapeType);
3002 //Make a Python command
3003 Handle(GEOM_Function) aFunction = aResult->GetFunction(1);
3005 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetInPlace("
3006 << theShapeWhere << ", " << theShapeWhat << ")";
3012 //=======================================================================
3013 //function : GetInPlaceByHistory
3015 //=======================================================================
3016 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlaceByHistory
3017 (Handle(GEOM_Object) theShapeWhere,
3018 Handle(GEOM_Object) theShapeWhat)
3022 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
3024 TopoDS_Shape aWhere = theShapeWhere->GetValue();
3025 TopoDS_Shape aWhat = theShapeWhat->GetValue();
3027 if (aWhere.IsNull() || aWhat.IsNull()) return NULL;
3029 Handle(GEOM_Function) aWhereFunction = theShapeWhere->GetLastFunction();
3030 if (aWhereFunction.IsNull()) return NULL;
3032 //Fill array of indices
3033 TopTools_IndexedMapOfShape aWhereIndices;
3034 TopExp::MapShapes(aWhere, aWhereIndices);
3037 TColStd_ListOfInteger aModifiedList;
3038 bool isFound = GetInPlaceOfShape(aWhereFunction, aWhereIndices, aWhat, aModifiedList);
3040 if (!isFound || aModifiedList.Extent() < 1) {
3041 SetErrorCode("Error: No history found for the sought shape or its sub-shapes.");
3045 Handle(TColStd_HArray1OfInteger) aModifiedArray =
3046 new TColStd_HArray1OfInteger (1, aModifiedList.Extent());
3047 TColStd_ListIteratorOfListOfInteger anIterModif (aModifiedList);
3048 for (Standard_Integer imod = 1; anIterModif.More(); anIterModif.Next(), imod++) {
3049 aModifiedArray->SetValue(imod, anIterModif.Value());
3053 Handle(GEOM_Object) aResult = GetEngine()->AddSubShape(theShapeWhere, aModifiedArray);
3054 if (aResult.IsNull()) {
3055 SetErrorCode("Error in algorithm: result found, but cannot be returned.");
3059 if (aModifiedArray->Length() > 1) {
3061 aResult->SetType(GEOM_GROUP);
3063 //Set a sub shape type
3064 TopoDS_Shape aFirstFound = aWhereIndices.FindKey(aModifiedArray->Value(1));
3065 TopAbs_ShapeEnum aShapeType = aFirstFound.ShapeType();
3067 TDF_Label aFreeLabel = aResult->GetFreeLabel();
3068 TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aShapeType);
3071 //Make a Python command
3072 Handle(GEOM_Function) aFunction = aResult->GetFunction(1);
3074 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetInPlaceByHistory("
3075 << theShapeWhere << ", " << theShapeWhat << ")";
3081 //=======================================================================
3082 //function : SortShapes
3084 //=======================================================================
3085 void GEOMImpl_IShapesOperations::SortShapes(TopTools_ListOfShape& SL)
3087 Standard_Integer MaxShapes = SL.Extent();
3088 TopTools_Array1OfShape aShapes (1,MaxShapes);
3089 TColStd_Array1OfInteger OrderInd(1,MaxShapes);
3090 TColStd_Array1OfReal MidXYZ (1,MaxShapes); //X,Y,Z;
3091 TColStd_Array1OfReal Length (1,MaxShapes); //X,Y,Z;
3093 // Computing of CentreOfMass
3094 Standard_Integer Index;
3097 TopTools_ListIteratorOfListOfShape it(SL);
3098 for (Index=1; it.More(); Index++)
3100 TopoDS_Shape S = it.Value();
3101 SL.Remove( it ); // == it.Next()
3103 OrderInd.SetValue (Index, Index);
3104 if (S.ShapeType() == TopAbs_VERTEX)
3106 GPoint = BRep_Tool::Pnt( TopoDS::Vertex( S ));
3107 Length.SetValue( Index, (Standard_Real) S.Orientation());
3111 BRepGProp::LinearProperties (S, GPr);
3112 GPoint = GPr.CentreOfMass();
3113 Length.SetValue( Index, GPr.Mass() );
3115 MidXYZ.SetValue(Index,
3116 GPoint.X()*999 + GPoint.Y()*99 + GPoint.Z()*0.9);
3117 //cout << Index << " L: " << Length(Index) << "CG: " << MidXYZ(Index) << endl;
3121 Standard_Integer aTemp;
3122 Standard_Boolean exchange, Sort = Standard_True;
3123 Standard_Real tol = Precision::Confusion();
3126 Sort = Standard_False;
3127 for (Index=1; Index < MaxShapes; Index++)
3129 Standard_Real dMidXYZ = MidXYZ(OrderInd(Index)) - MidXYZ(OrderInd(Index+1));
3130 Standard_Real dLength = Length(OrderInd(Index)) - Length(OrderInd(Index+1));
3131 if ( dMidXYZ >= tol ) {
3132 // cout << "MidXYZ: " << MidXYZ(OrderInd(Index))<< " > " <<MidXYZ(OrderInd(Index+1))
3133 // << " d: " << dMidXYZ << endl;
3134 exchange = Standard_True;
3136 else if ( Abs(dMidXYZ) < tol && dLength >= tol ) {
3137 // cout << "Length: " << Length(OrderInd(Index))<< " > " <<Length(OrderInd(Index+1))
3138 // << " d: " << dLength << endl;
3139 exchange = Standard_True;
3141 else if ( Abs(dMidXYZ) < tol && Abs(dLength) < tol &&
3142 aShapes(OrderInd(Index)).ShapeType() <= TopAbs_FACE) {
3144 // equal values possible on shapes such as two halves of a sphere and
3145 // a membrane inside the sphere
3147 BRepBndLib::Add( aShapes( OrderInd(Index) ), box1 );
3148 if ( box1.IsVoid() ) continue;
3149 BRepBndLib::Add( aShapes( OrderInd(Index+1) ), box2 );
3150 Standard_Real dSquareExtent = box1.SquareExtent() - box2.SquareExtent();
3151 if ( dSquareExtent >= tol ) {
3152 // cout << "SquareExtent: " << box1.SquareExtent()<<" > "<<box2.SquareExtent() << endl;
3153 exchange = Standard_True;
3155 else if ( Abs(dSquareExtent) < tol ) {
3156 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax, val1, val2;
3157 box1.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
3158 val1 = (aXmin+aXmax)*999 + (aYmin+aYmax)*99 + (aZmin+aZmax)*0.9;
3159 box2.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
3160 val2 = (aXmin+aXmax)*999 + (aYmin+aYmax)*99 + (aZmin+aZmax)*0.9;
3161 exchange = val1 > val2;
3162 // cout << "box: " << val1<<" > "<<val2 << endl;
3166 exchange = Standard_False;
3170 // cout << "exchange " << Index << " & " << Index+1 << endl;
3171 aTemp = OrderInd(Index);
3172 OrderInd(Index) = OrderInd(Index+1);
3173 OrderInd(Index+1) = aTemp;
3174 Sort = Standard_True;
3179 for (Index=1; Index <= MaxShapes; Index++)
3180 SL.Append( aShapes( OrderInd(Index) ));
3183 //=======================================================================
3184 //function : CompsolidToCompound
3186 //=======================================================================
3187 TopoDS_Shape GEOMImpl_IShapesOperations::CompsolidToCompound (const TopoDS_Shape& theCompsolid)
3189 if (theCompsolid.ShapeType() != TopAbs_COMPSOLID) {
3190 return theCompsolid;
3193 TopoDS_Compound aCompound;
3195 B.MakeCompound(aCompound);
3197 TopTools_MapOfShape mapShape;
3198 TopoDS_Iterator It (theCompsolid, Standard_True, Standard_True);
3200 for (; It.More(); It.Next()) {
3201 TopoDS_Shape aShape_i = It.Value();
3202 if (mapShape.Add(aShape_i)) {
3203 B.Add(aCompound, aShape_i);
3210 //=======================================================================
3211 //function : CheckTriangulation
3213 //=======================================================================
3214 bool GEOMImpl_IShapesOperations::CheckTriangulation (const TopoDS_Shape& aShape)
3216 bool isTriangulation = true;
3218 TopExp_Explorer exp (aShape, TopAbs_FACE);
3221 TopLoc_Location aTopLoc;
3222 Handle(Poly_Triangulation) aTRF;
3223 aTRF = BRep_Tool::Triangulation(TopoDS::Face(exp.Current()), aTopLoc);
3224 if (aTRF.IsNull()) {
3225 isTriangulation = false;
3228 else // no faces, try edges
3230 TopExp_Explorer expe (aShape, TopAbs_EDGE);
3234 TopLoc_Location aLoc;
3235 Handle(Poly_Polygon3D) aPE = BRep_Tool::Polygon3D(TopoDS::Edge(expe.Current()), aLoc);
3237 isTriangulation = false;
3241 if (!isTriangulation) {
3242 // calculate deflection
3243 Standard_Real aDeviationCoefficient = 0.001;
3246 BRepBndLib::Add(aShape, B);
3247 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
3248 B.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
3250 Standard_Real dx = aXmax - aXmin, dy = aYmax - aYmin, dz = aZmax - aZmin;
3251 Standard_Real aDeflection = Max(Max(dx, dy), dz) * aDeviationCoefficient * 4;
3252 Standard_Real aHLRAngle = 0.349066;
3254 BRepMesh_IncrementalMesh Inc (aShape, aDeflection, Standard_False, aHLRAngle);
3260 #define MAX_TOLERANCE 1.e-7
3263 //=======================================================================
3264 //function : isSameEdge
3265 //purpose : Returns True if two edges coincide
3266 //=======================================================================
3267 static bool isSameEdge(const TopoDS_Edge& theEdge1, const TopoDS_Edge& theEdge2)
3269 TopoDS_Vertex V11, V12, V21, V22;
3270 TopExp::Vertices(theEdge1, V11, V12);
3271 TopExp::Vertices(theEdge2, V21, V22);
3272 gp_Pnt P11 = BRep_Tool::Pnt(V11);
3273 gp_Pnt P12 = BRep_Tool::Pnt(V12);
3274 gp_Pnt P21 = BRep_Tool::Pnt(V21);
3275 gp_Pnt P22 = BRep_Tool::Pnt(V22);
3276 bool coincide = false;
3278 //Check that ends of edges coincide
3279 if(P11.Distance(P21) <= MAX_TOLERANCE) {
3280 if(P12.Distance(P22) <= MAX_TOLERANCE) coincide = true;
3282 else if(P11.Distance(P22) <= MAX_TOLERANCE) {
3283 if(P12.Distance(P21) <= MAX_TOLERANCE) coincide = true;
3286 if(!coincide) return false;
3288 if (BRep_Tool::Degenerated(theEdge1))
3289 if (BRep_Tool::Degenerated(theEdge2)) return true;
3292 if (BRep_Tool::Degenerated(theEdge2)) return false;
3294 double U11, U12, U21, U22;
3295 Handle(Geom_Curve) C1 = BRep_Tool::Curve(theEdge1, U11, U12);
3296 Handle(Geom_Curve) C2 = BRep_Tool::Curve(theEdge2, U21, U22);
3297 if(C1->DynamicType() == C2->DynamicType()) return true;
3299 //Check that both edges has the same geometry
3300 double range = U12-U11;
3301 double U = U11+ range/3.0;
3302 gp_Pnt P1 = C1->Value(U); //Compute a point on one third of the edge's length
3303 U = U11+range*2.0/3.0;
3304 gp_Pnt P2 = C1->Value(U); //Compute a point on two thirds of the edge's length
3306 if(!GeomLib_Tool::Parameter(C2, P1, MAX_TOLERANCE, U) || U < U21 || U > U22)
3309 if(P1.Distance(C2->Value(U)) > MAX_TOLERANCE) return false;
3311 if(!GeomLib_Tool::Parameter(C2, P2, MAX_TOLERANCE, U) || U < U21 || U > U22)
3314 if(P2.Distance(C2->Value(U)) > MAX_TOLERANCE) return false;
3319 #include <TopoDS_TShape.hxx>
3320 //=======================================================================
3321 //function : isSameFace
3322 //purpose : Returns True if two faces coincide
3323 //=======================================================================
3324 static bool isSameFace(const TopoDS_Face& theFace1, const TopoDS_Face& theFace2)
3326 TopExp_Explorer E(theFace1, TopAbs_EDGE);
3327 TopTools_ListOfShape LS1, LS2;
3328 for(; E.More(); E.Next()) LS1.Append(E.Current());
3330 E.Init(theFace2, TopAbs_EDGE);
3331 for(; E.More(); E.Next()) LS2.Append(E.Current());
3333 //Compare the number of edges in the faces
3334 if(LS1.Extent() != LS2.Extent()) return false;
3336 double aMin = RealFirst(), aMax = RealLast();
3337 double xminB1=aMax, yminB1=aMax, zminB1=aMax, xminB2=aMax, yminB2=aMax, zminB2=aMax;
3338 double xmaxB1=aMin, ymaxB1=aMin, zmaxB1=aMin, xmaxB2=aMin, ymaxB2=aMin, zmaxB2=aMin;
3340 for(E.Init(theFace1, TopAbs_VERTEX); E.More(); E.Next()) {
3341 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
3342 if(P.X() < xminB1) xminB1 = P.X();
3343 if(P.Y() < yminB1) yminB1 = P.Y();
3344 if(P.Z() < zminB1) zminB1 = P.Z();
3345 if(P.X() > xmaxB1) xmaxB1 = P.X();
3346 if(P.Y() > ymaxB1) ymaxB1 = P.Y();
3347 if(P.Z() > zmaxB1) zmaxB1 = P.Z();
3350 for(E.Init(theFace2, TopAbs_VERTEX); E.More(); E.Next()) {
3351 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
3352 if(P.X() < xminB2) xminB2 = P.X();
3353 if(P.Y() < yminB2) yminB2 = P.Y();
3354 if(P.Z() < zminB2) zminB2 = P.Z();
3355 if(P.X() > xmaxB2) xmaxB2 = P.X();
3356 if(P.Y() > ymaxB2) ymaxB2 = P.Y();
3357 if(P.Z() > zmaxB2) zmaxB2 = P.Z();
3361 //Compare the bounding boxes of both faces
3362 if(gp_Pnt(xminB1, yminB1, zminB1).Distance(gp_Pnt(xminB2, yminB2, zminB2)) > MAX_TOLERANCE)
3365 if(gp_Pnt(xmaxB1, ymaxB1, zmaxB1).Distance(gp_Pnt(xmaxB2, ymaxB2, zmaxB2)) > MAX_TOLERANCE)
3368 Handle(Geom_Surface) S1 = BRep_Tool::Surface(theFace1);
3369 Handle(Geom_Surface) S2 = BRep_Tool::Surface(theFace2);
3371 //Check if there a coincidence of two surfaces at least in two points
3372 double U11, U12, V11, V12, U21, U22, V21, V22;
3373 BRepTools::UVBounds(theFace1, U11, U12, V11, V12);
3374 BRepTools::UVBounds(theFace2, U21, U22, V21, V22);
3376 double rangeU = U12-U11;
3377 double rangeV = V12-V11;
3378 double U = U11 + rangeU/3.0;
3379 double V = V11 + rangeV/3.0;
3380 gp_Pnt P1 = S1->Value(U, V);
3381 U = U11+rangeU*2.0/3.0;
3382 V = V11+rangeV*2.0/3.0;
3383 gp_Pnt P2 = S1->Value(U, V);
3385 if(!GeomLib_Tool::Parameters(S2, P1, MAX_TOLERANCE, U, V) || U < U21 || U > U22 || V < V21 || V > V22)
3388 if(P1.Distance(S2->Value(U,V)) > MAX_TOLERANCE) return false;
3390 if(!GeomLib_Tool::Parameters(S2, P2, MAX_TOLERANCE, U, V) || U < U21 || U > U22 || V < V21 || V > V22)
3393 if(P2.Distance(S2->Value(U, V)) > MAX_TOLERANCE) return false;
3395 //Check that each edge of the Face1 has a counterpart in the Face2
3396 TopTools_MapOfOrientedShape aMap;
3397 TopTools_ListIteratorOfListOfShape LSI1(LS1);
3398 for(; LSI1.More(); LSI1.Next()) {
3399 TopoDS_Edge E = TopoDS::Edge(LSI1.Value());
3400 bool isFound = false;
3401 TopTools_ListIteratorOfListOfShape LSI2(LS2);
3402 for(; LSI2.More(); LSI2.Next()) {
3403 TopoDS_Shape aValue = LSI2.Value();
3404 if(aMap.Contains(aValue)) continue; //To avoid checking already found edge several times
3405 if(isSameEdge(E, TopoDS::Edge(aValue))) {
3411 if(!isFound) return false;
3417 //=======================================================================
3418 //function : isSameSolid
3419 //purpose : Returns True if two solids coincide
3420 //=======================================================================
3421 bool isSameSolid(const TopoDS_Solid& theSolid1, const TopoDS_Solid& theSolid2)
3423 TopExp_Explorer E(theSolid1, TopAbs_FACE);
3424 TopTools_ListOfShape LS1, LS2;
3425 for(; E.More(); E.Next()) LS1.Append(E.Current());
3426 E.Init(theSolid2, TopAbs_FACE);
3427 for(; E.More(); E.Next()) LS2.Append(E.Current());
3429 if(LS1.Extent() != LS2.Extent()) return false;
3431 double aMin = RealFirst(), aMax = RealLast();
3432 double xminB1=aMax, yminB1=aMax, zminB1=aMax, xminB2=aMax, yminB2=aMax, zminB2=aMax;
3433 double xmaxB1=aMin, ymaxB1=aMin, zmaxB1=aMin, xmaxB2=aMin, ymaxB2=aMin, zmaxB2=aMin;
3435 for(E.Init(theSolid1, TopAbs_VERTEX); E.More(); E.Next()) {
3436 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
3437 if(P.X() < xminB1) xminB1 = P.X();
3438 if(P.Y() < yminB1) yminB1 = P.Y();
3439 if(P.Z() < zminB1) zminB1 = P.Z();
3440 if(P.X() > xmaxB1) xmaxB1 = P.X();
3441 if(P.Y() > ymaxB1) ymaxB1 = P.Y();
3442 if(P.Z() > zmaxB1) zmaxB1 = P.Z();
3445 for(E.Init(theSolid2, TopAbs_VERTEX); E.More(); E.Next()) {
3446 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
3447 if(P.X() < xminB2) xminB2 = P.X();
3448 if(P.Y() < yminB2) yminB2 = P.Y();
3449 if(P.Z() < zminB2) zminB2 = P.Z();
3450 if(P.X() > xmaxB2) xmaxB2 = P.X();
3451 if(P.Y() > ymaxB2) ymaxB2 = P.Y();
3452 if(P.Z() > zmaxB2) zmaxB2 = P.Z();
3455 //Compare the bounding boxes of both solids
3456 if(gp_Pnt(xminB1, yminB1, zminB1).Distance(gp_Pnt(xminB2, yminB2, zminB2)) > MAX_TOLERANCE)
3459 if(gp_Pnt(xmaxB1, ymaxB1, zmaxB1).Distance(gp_Pnt(xmaxB2, ymaxB2, zmaxB2)) > MAX_TOLERANCE)
3462 //Check that each face of the Solid1 has a counterpart in the Solid2
3463 TopTools_MapOfOrientedShape aMap;
3464 TopTools_ListIteratorOfListOfShape LSI1(LS1);
3465 for(; LSI1.More(); LSI1.Next()) {
3466 TopoDS_Face F = TopoDS::Face(LSI1.Value());
3467 bool isFound = false;
3468 TopTools_ListIteratorOfListOfShape LSI2(LS2);
3469 for(; LSI2.More(); LSI2.Next()) {
3470 if(aMap.Contains(LSI2.Value())) continue; //To avoid checking already found faces several times
3471 if(isSameFace(F, TopoDS::Face(LSI2.Value()))) {
3472 aMap.Add(LSI2.Value());
3477 if(!isFound) return false;
3483 //=======================================================================
3484 //function : GetSame
3486 //=======================================================================
3487 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetSame(const Handle(GEOM_Object)& theShapeWhere,
3488 const Handle(GEOM_Object)& theShapeWhat)
3491 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
3493 TopoDS_Shape aWhere = theShapeWhere->GetValue();
3494 TopoDS_Shape aWhat = theShapeWhat->GetValue();
3496 if (aWhere.IsNull() || aWhat.IsNull()) return NULL;
3499 bool isFound = false;
3500 TopoDS_Shape aSubShape;
3501 TopTools_MapOfShape aMap;
3503 switch(aWhat.ShapeType()) {
3504 case TopAbs_VERTEX: {
3505 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(aWhat));
3506 TopExp_Explorer E(aWhere, TopAbs_VERTEX);
3507 for(; E.More(); E.Next()) {
3508 if(!aMap.Add(E.Current())) continue;
3509 gp_Pnt P2 = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
3510 if(P.Distance(P2) <= MAX_TOLERANCE) {
3512 aSubShape = E.Current();
3519 TopoDS_Face aFace = TopoDS::Face(aWhat);
3520 TopExp_Explorer E(aWhere, TopAbs_FACE);
3521 for(; E.More(); E.Next()) {
3522 if(!aMap.Add(E.Current())) continue;
3523 if(isSameFace(aFace, TopoDS::Face(E.Current()))) {
3524 aSubShape = E.Current();
3532 TopoDS_Edge anEdge = TopoDS::Edge(aWhat);
3533 TopExp_Explorer E(aWhere, TopAbs_EDGE);
3534 for(; E.More(); E.Next()) {
3535 if(!aMap.Add(E.Current())) continue;
3536 if(isSameEdge(anEdge, TopoDS::Edge(E.Current()))) {
3537 aSubShape = E.Current();
3544 case TopAbs_SOLID: {
3545 TopoDS_Solid aSolid = TopoDS::Solid(aWhat);
3546 TopExp_Explorer E(aWhere, TopAbs_SOLID);
3547 for(; E.More(); E.Next()) {
3548 if(!aMap.Add(E.Current())) continue;
3549 if(isSameSolid(aSolid, TopoDS::Solid(E.Current()))) {
3550 aSubShape = E.Current();
3562 TopTools_IndexedMapOfShape anIndices;
3563 TopExp::MapShapes(aWhere, anIndices);
3564 if (anIndices.Contains(aSubShape))
3565 anIndex = anIndices.FindIndex(aSubShape);
3568 if(anIndex < 0) return NULL;
3570 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
3572 anArray->SetValue(1, anIndex);
3574 Handle(GEOM_Object) aResult = GetEngine()->AddSubShape(theShapeWhere, anArray);
3575 Handle(GEOM_Function) aFunction = aResult->GetLastFunction();
3577 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetSame("
3578 << theShapeWhere << ", " << theShapeWhat << ")";