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
28 #include <Standard_Stream.hxx>
30 #include "GEOMImpl_IShapesOperations.hxx"
32 #include "GEOMImpl_Types.hxx"
34 #include "GEOMImpl_VectorDriver.hxx"
35 #include "GEOMImpl_ShapeDriver.hxx"
36 #include "GEOMImpl_CopyDriver.hxx"
37 #include "GEOMImpl_GlueDriver.hxx"
39 #include "GEOMImpl_IVector.hxx"
40 #include "GEOMImpl_IShapes.hxx"
41 #include "GEOMImpl_IGlue.hxx"
43 #include "GEOMImpl_Block6Explorer.hxx"
45 #include "GEOM_Function.hxx"
46 #include "GEOM_ISubShape.hxx"
47 #include "GEOM_PythonDump.hxx"
49 #include "GEOMAlgo_FinderShapeOn1.hxx"
50 #include "GEOMAlgo_FinderShapeOnQuad.hxx"
51 #include "GEOMAlgo_FinderShapeOn2.hxx"
52 #include "GEOMAlgo_ClsfBox.hxx"
53 #include "GEOMAlgo_ClsfSolid.hxx"
54 #include "GEOMAlgo_Gluer1.hxx"
55 #include "GEOMAlgo_ListIteratorOfListOfCoupleOfShapes.hxx"
56 #include "GEOMAlgo_CoupleOfShapes.hxx"
57 #include "GEOMAlgo_ListOfCoupleOfShapes.hxx"
59 #include "utilities.h"
61 #include "Utils_ExceptHandlers.hxx"
63 #include <TFunction_DriverTable.hxx>
64 #include <TFunction_Driver.hxx>
65 #include <TFunction_Logbook.hxx>
66 #include <TDataStd_Integer.hxx>
67 #include <TDataStd_IntegerArray.hxx>
68 #include <TDF_Tool.hxx>
70 #include <BRepExtrema_ExtCF.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>
134 //=============================================================================
138 //=============================================================================
139 GEOMImpl_IShapesOperations::GEOMImpl_IShapesOperations (GEOM_Engine* theEngine, int theDocID)
140 : GEOM_IOperations(theEngine, theDocID)
142 MESSAGE("GEOMImpl_IShapesOperations::GEOMImpl_IShapesOperations");
145 //=============================================================================
149 //=============================================================================
150 GEOMImpl_IShapesOperations::~GEOMImpl_IShapesOperations()
152 MESSAGE("GEOMImpl_IShapesOperations::~GEOMImpl_IShapesOperations");
156 //=============================================================================
160 //=============================================================================
161 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeEdge
162 (Handle(GEOM_Object) thePnt1, Handle(GEOM_Object) thePnt2)
166 if (thePnt1.IsNull() || thePnt2.IsNull()) return NULL;
168 //Add a new Edge object
169 Handle(GEOM_Object) anEdge = GetEngine()->AddObject(GetDocID(), GEOM_EDGE);
171 //Add a new Vector function
172 Handle(GEOM_Function) aFunction =
173 anEdge->AddFunction(GEOMImpl_VectorDriver::GetID(), VECTOR_TWO_PNT);
175 //Check if the function is set correctly
176 if (aFunction->GetDriverGUID() != GEOMImpl_VectorDriver::GetID()) return NULL;
178 GEOMImpl_IVector aPI (aFunction);
180 Handle(GEOM_Function) aRef1 = thePnt1->GetLastFunction();
181 Handle(GEOM_Function) aRef2 = thePnt2->GetLastFunction();
182 if (aRef1.IsNull() || aRef2.IsNull()) return NULL;
184 aPI.SetPoint1(aRef1);
185 aPI.SetPoint2(aRef2);
187 //Compute the Edge value
189 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
192 if (!GetSolver()->ComputeFunction(aFunction)) {
193 SetErrorCode("Vector driver failed");
197 catch (Standard_Failure) {
198 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
199 SetErrorCode(aFail->GetMessageString());
203 //Make a Python command
204 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdge("
205 << thePnt1 << ", " << thePnt2 << ")";
211 //=============================================================================
215 //=============================================================================
216 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeWire
217 (list<Handle(GEOM_Object)> theShapes)
219 return MakeShape(theShapes, GEOM_WIRE, WIRE_EDGES, "MakeWire");
222 //=============================================================================
226 //=============================================================================
227 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFace (Handle(GEOM_Object) theWire,
228 const bool isPlanarWanted)
232 if (theWire.IsNull()) return NULL;
234 //Add a new Face object
235 Handle(GEOM_Object) aFace = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
237 //Add a new Shape function for creation of a face from a wire
238 Handle(GEOM_Function) aFunction =
239 aFace->AddFunction(GEOMImpl_ShapeDriver::GetID(), FACE_WIRE);
240 if (aFunction.IsNull()) return NULL;
242 //Check if the function is set correctly
243 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
245 GEOMImpl_IShapes aCI (aFunction);
247 Handle(GEOM_Function) aRefWire = theWire->GetLastFunction();
249 if (aRefWire.IsNull()) return NULL;
251 aCI.SetBase(aRefWire);
252 aCI.SetIsPlanar(isPlanarWanted);
254 //Compute the Face value
256 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
259 if (!GetSolver()->ComputeFunction(aFunction)) {
260 SetErrorCode("Shape driver failed to compute a face");
264 catch (Standard_Failure) {
265 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
266 SetErrorCode(aFail->GetMessageString());
270 //Make a Python command
271 GEOM::TPythonDump(aFunction) << aFace << " = geompy.MakeFace("
272 << theWire << ", " << (int)isPlanarWanted << ")";
278 //=============================================================================
282 //=============================================================================
283 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFaceWires
284 (list<Handle(GEOM_Object)> theShapes,
285 const bool isPlanarWanted)
290 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
293 Handle(GEOM_Function) aFunction =
294 aShape->AddFunction(GEOMImpl_ShapeDriver::GetID(), FACE_WIRES);
295 if (aFunction.IsNull()) return NULL;
297 //Check if the function is set correctly
298 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
300 GEOMImpl_IShapes aCI (aFunction);
302 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
305 list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
306 for (; it != theShapes.end(); it++) {
307 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
308 if (aRefSh.IsNull()) {
309 SetErrorCode("NULL argument shape for the face construction");
312 aShapesSeq->Append(aRefSh);
314 aCI.SetShapes(aShapesSeq);
316 aCI.SetIsPlanar(isPlanarWanted);
320 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
323 if (!GetSolver()->ComputeFunction(aFunction)) {
324 SetErrorCode("Shape driver failed");
328 catch (Standard_Failure) {
329 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
330 SetErrorCode(aFail->GetMessageString());
334 //Make a Python command
335 GEOM::TPythonDump pd (aFunction);
336 pd << aShape << " = geompy.MakeFaceWires([";
339 it = theShapes.begin();
340 if (it != theShapes.end()) {
342 while (it != theShapes.end()) {
343 pd << ", " << (*it++);
346 pd << "], " << (int)isPlanarWanted << ")";
352 //=============================================================================
356 //=============================================================================
357 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeShell
358 (list<Handle(GEOM_Object)> theShapes)
360 return MakeShape(theShapes, GEOM_SHELL, SHELL_FACES, "MakeShell");
363 //=============================================================================
367 //=============================================================================
368 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeSolidShells
369 (list<Handle(GEOM_Object)> theShapes)
371 return MakeShape(theShapes, GEOM_SOLID, SOLID_SHELLS, "MakeSolid");
374 //=============================================================================
378 //=============================================================================
379 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeSolidShell (Handle(GEOM_Object) theShell)
383 if (theShell.IsNull()) return NULL;
385 //Add a new Solid object
386 Handle(GEOM_Object) aSolid = GetEngine()->AddObject(GetDocID(), GEOM_SOLID);
388 //Add a new Solid function for creation of a solid from a shell
389 Handle(GEOM_Function) aFunction =
390 aSolid->AddFunction(GEOMImpl_ShapeDriver::GetID(), SOLID_SHELL);
391 if (aFunction.IsNull()) return NULL;
393 //Check if the function is set correctly
394 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
396 GEOMImpl_IShapes aCI (aFunction);
398 Handle(GEOM_Function) aRefShell = theShell->GetLastFunction();
400 if (aRefShell.IsNull()) return NULL;
402 aCI.SetBase(aRefShell);
404 //Compute the Solid value
406 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
409 if (!GetSolver()->ComputeFunction(aFunction)) {
410 SetErrorCode("Solid driver failed");
414 catch (Standard_Failure) {
415 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
416 SetErrorCode(aFail->GetMessageString());
420 //Make a Python command
421 GEOM::TPythonDump(aFunction) << aSolid
422 << " = geompy.MakeSolid(" << theShell << ")";
428 //=============================================================================
432 //=============================================================================
433 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeCompound
434 (list<Handle(GEOM_Object)> theShapes)
436 return MakeShape(theShapes, GEOM_COMPOUND, COMPOUND_SHAPES, "MakeCompound");
439 //=============================================================================
443 //=============================================================================
444 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeShape
445 (list<Handle(GEOM_Object)> theShapes,
446 const Standard_Integer theObjectType,
447 const Standard_Integer theFunctionType,
448 const TCollection_AsciiString& theMethodName)
453 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), theObjectType);
456 Handle(GEOM_Function) aFunction =
457 aShape->AddFunction(GEOMImpl_ShapeDriver::GetID(), theFunctionType);
458 if (aFunction.IsNull()) return NULL;
460 //Check if the function is set correctly
461 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
463 GEOMImpl_IShapes aCI (aFunction);
465 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
468 list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
469 for (; it != theShapes.end(); it++) {
470 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
471 if (aRefSh.IsNull()) {
472 SetErrorCode("NULL argument shape for the shape construction");
475 aShapesSeq->Append(aRefSh);
477 aCI.SetShapes(aShapesSeq);
481 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
484 if (!GetSolver()->ComputeFunction(aFunction)) {
485 SetErrorCode("Shape driver failed");
489 catch (Standard_Failure) {
490 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
491 SetErrorCode(aFail->GetMessageString());
495 //Make a Python command
496 GEOM::TPythonDump pd (aFunction);
497 pd << aShape << " = geompy." << theMethodName.ToCString() << "([";
500 it = theShapes.begin();
501 if (it != theShapes.end()) {
503 while (it != theShapes.end()) {
504 pd << ", " << (*it++);
513 //=============================================================================
517 //=============================================================================
518 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeGlueFaces
519 (Handle(GEOM_Object) theShape,
520 const Standard_Real theTolerance,
521 const Standard_Boolean doKeepNonSolids)
525 if (theShape.IsNull()) return NULL;
527 //Add a new Glued object
528 Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
530 //Add a new Glue function
531 Handle(GEOM_Function) aFunction;
532 aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_FACES);
533 if (aFunction.IsNull()) return NULL;
535 //Check if the function is set correctly
536 if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
538 GEOMImpl_IGlue aCI (aFunction);
540 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
541 if (aRefShape.IsNull()) return NULL;
543 aCI.SetBase(aRefShape);
544 aCI.SetTolerance(theTolerance);
545 aCI.SetKeepNonSolids(doKeepNonSolids);
547 //Compute the sub-shape value
548 Standard_Boolean isWarning = Standard_False;
550 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
553 if (!GetSolver()->ComputeFunction(aFunction)) {
554 SetErrorCode("Shape driver failed to glue faces");
558 catch (Standard_Failure) {
559 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
560 SetErrorCode(aFail->GetMessageString());
561 // to provide warning
562 if (!aFunction->GetValue().IsNull()) {
563 isWarning = Standard_True;
569 //Make a Python command
570 GEOM::TPythonDump(aFunction) << aGlued << " = geompy.MakeGlueFaces("
571 << theShape << ", " << theTolerance << ")";
573 // to provide warning
574 if (!isWarning) SetErrorCode(OK);
578 //=============================================================================
582 //=============================================================================
583 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetGlueFaces
584 (Handle(GEOM_Object) theShape,
585 const Standard_Real theTolerance)
589 if (theShape.IsNull()) return NULL;
590 TopoDS_Shape aShape = theShape->GetValue();
591 if (aShape.IsNull()) return NULL;
593 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
595 Standard_Integer iErr;
597 GEOMAlgo_Gluer1 aGluer;
598 GEOMAlgo_ListIteratorOfListOfCoupleOfShapes aItCS;
599 GEOMAlgo_CoupleOfShapes aCS;
600 GEOMAlgo_ListOfCoupleOfShapes aLCS;
602 //aGluer = new GEOMAlgo_Gluer1;
603 aGluer.SetShape(aShape);
604 aGluer.SetTolerance(theTolerance);
606 iErr = aGluer.ErrorStatus();
607 if (iErr) return NULL;
609 TopTools_ListOfShape listShape;
610 const GEOMAlgo_ListOfCoupleOfShapes& aLCSG = aGluer.GluedFaces();
612 aItCS.Initialize(aLCSG);
613 for (; aItCS.More(); aItCS.Next()) {
614 const GEOMAlgo_CoupleOfShapes& aCSG = aItCS.Value();
615 listShape.Append(aCSG.Shape1());
618 TopTools_ListIteratorOfListOfShape itSub (listShape);
619 TCollection_AsciiString anAsciiList, anEntry;
620 TopTools_IndexedMapOfShape anIndices;
621 TopExp::MapShapes(aShape, anIndices);
622 Handle(TColStd_HArray1OfInteger) anArray;
623 Handle(GEOM_Object) anObj;
624 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
625 TopoDS_Shape aValue = itSub.Value();
626 anArray = new TColStd_HArray1OfInteger(1,1);
627 anArray->SetValue(1, anIndices.FindIndex(aValue));
628 anObj = GetEngine()->AddSubShape(theShape, anArray);
629 if (!anObj.IsNull()) {
632 // for python command
633 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
634 anAsciiList += anEntry;
639 //Make a Python command
640 if(anAsciiList.Length()>0)
641 anAsciiList.Trunc(anAsciiList.Length() - 1);
642 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
643 GEOM::TPythonDump pd (aFunction, /*append=*/true);
644 pd << "[" << anAsciiList.ToCString();
645 pd << "] = geompy.GetGlueFaces(" << theShape << ", " << theTolerance << ")";
653 //=============================================================================
655 * MakeGlueFacesByList
657 //=============================================================================
658 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeGlueFacesByList
659 (Handle(GEOM_Object) theShape,
660 const Standard_Real theTolerance,
661 list<Handle(GEOM_Object)> theFaces,
662 const Standard_Boolean doKeepNonSolids)
666 if (theShape.IsNull()) return NULL;
668 //Add a new Glued object
669 Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
671 //Add a new Glue function
672 Handle(GEOM_Function) aFunction;
673 aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_FACES_BY_LIST);
674 if (aFunction.IsNull()) return NULL;
676 //Check if the function is set correctly
677 if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
679 GEOMImpl_IGlue aCI (aFunction);
681 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
682 if (aRefShape.IsNull()) return NULL;
684 aCI.SetBase(aRefShape);
685 aCI.SetTolerance(theTolerance);
686 aCI.SetKeepNonSolids(doKeepNonSolids);
688 Handle(TColStd_HSequenceOfTransient) aFaces = new TColStd_HSequenceOfTransient;
689 list<Handle(GEOM_Object)>::iterator it = theFaces.begin();
690 for (; it != theFaces.end(); it++) {
691 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
692 if (aRefSh.IsNull()) {
693 SetErrorCode("NULL argument shape for the shape construction");
696 aFaces->Append(aRefSh);
698 aCI.SetFaces(aFaces);
700 //Compute the sub-shape value
701 Standard_Boolean isWarning = Standard_False;
703 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
706 if (!GetSolver()->ComputeFunction(aFunction)) {
707 SetErrorCode("Shape driver failed to glue faces");
711 catch (Standard_Failure) {
712 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
713 SetErrorCode(aFail->GetMessageString());
714 // to provide warning
715 if (!aFunction->GetValue().IsNull()) {
716 isWarning = Standard_True;
722 //Make a Python command
724 GEOM::TPythonDump pd(aFunction);
725 pd << aGlued << " = geompy.MakeGlueFacesByList("
726 << theShape << ", " << theTolerance << ", [";
728 it = theFaces.begin();
729 if (it != theFaces.end()) {
731 while (it != theFaces.end()) {
732 pd << ", " << (*it++);
738 // to provide warning
739 if (!isWarning) SetErrorCode(OK);
745 //=============================================================================
749 //=============================================================================
750 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::MakeExplode
751 (Handle(GEOM_Object) theShape,
752 const Standard_Integer theShapeType,
753 const Standard_Boolean isSorted)
757 if (theShape.IsNull()) return NULL;
758 TopoDS_Shape aShape = theShape->GetValue();
759 if (aShape.IsNull()) return NULL;
761 Handle(GEOM_Function) aMainShape = theShape->GetLastFunction();
763 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
764 Handle(GEOM_Object) anObj;
765 TopTools_MapOfShape mapShape;
766 TopTools_ListOfShape listShape;
768 if (aShape.ShapeType() == TopAbs_COMPOUND &&
769 (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
770 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPSOLID ||
771 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPOUND)) {
772 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
773 for (; It.More(); It.Next()) {
774 if (mapShape.Add(It.Value())) {
775 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
776 TopAbs_ShapeEnum(theShapeType) == It.Value().ShapeType()) {
777 listShape.Append(It.Value());
782 TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
783 for (; exp.More(); exp.Next())
784 if (mapShape.Add(exp.Current()))
785 listShape.Append(exp.Current());
788 if (listShape.IsEmpty()) {
789 //SetErrorCode("The given shape has no sub-shapes of the requested type");
790 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
795 SortShapes(listShape);
797 TopTools_IndexedMapOfShape anIndices;
798 TopExp::MapShapes(aShape, anIndices);
799 Handle(TColStd_HArray1OfInteger) anArray;
801 Standard_Integer nbAllSubShape = anIndices.Extent();
803 TopTools_ListIteratorOfListOfShape itSub (listShape);
804 TCollection_AsciiString anAsciiList, anEntry;
805 for (int index = 1; itSub.More(); itSub.Next(), ++index)
807 TopoDS_Shape aValue = itSub.Value();
808 anArray = new TColStd_HArray1OfInteger(1,1);
809 anArray->SetValue(1, anIndices.FindIndex(aValue));
811 //anObj = GetEngine()->AddSubShape(theShape, anArray);
813 anObj = GetEngine()->AddObject(GetDocID(), GEOM_SUBSHAPE);
814 Handle(GEOM_Function) aFunction = anObj->AddFunction(GEOM_Object::GetSubShapeID(), 1);
815 if (aFunction.IsNull()) return aSeq;
817 GEOM_ISubShape aSSI (aFunction);
818 aSSI.SetMainShape(aMainShape);
819 aSSI.SetIndices(anArray);
821 // Set function value directly, as we know it.
822 // Usage of Solver here would lead to significant loss of time,
823 // because GEOM_SubShapeDriver will build TopTools_IndexedMapOfShape
824 // on the main shape for each being calculated sub-shape separately.
825 aFunction->SetValue(aValue);
828 if (!anObj.IsNull()) {
831 // for python command
832 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
833 anAsciiList += anEntry;
838 //Make a Python command
839 anAsciiList.Trunc(anAsciiList.Length() - 1);
841 GEOM::TPythonDump pd (aMainShape, /*append=*/true);
842 pd << "[" << anAsciiList.ToCString();
843 pd << "] = geompy.SubShapeAll" << (isSorted ? "Sorted(" : "(");
844 pd << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
851 //=============================================================================
855 //=============================================================================
856 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::SubShapeAllIDs
857 (Handle(GEOM_Object) theShape,
858 const Standard_Integer theShapeType,
859 const Standard_Boolean isSorted)
863 if (theShape.IsNull()) return NULL;
864 TopoDS_Shape aShape = theShape->GetValue();
865 if (aShape.IsNull()) return NULL;
867 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
868 TopTools_MapOfShape mapShape;
869 TopTools_ListOfShape listShape;
871 if (aShape.ShapeType() == TopAbs_COMPOUND &&
872 (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
873 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPSOLID ||
874 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPOUND)) {
875 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
876 for (; It.More(); It.Next()) {
877 if (mapShape.Add(It.Value())) {
878 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
879 TopAbs_ShapeEnum(theShapeType) == It.Value().ShapeType()) {
880 listShape.Append(It.Value());
885 TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
886 for (; exp.More(); exp.Next())
887 if (mapShape.Add(exp.Current()))
888 listShape.Append(exp.Current());
891 if (listShape.IsEmpty()) {
892 //SetErrorCode("The given shape has no sub-shapes of the requested type");
893 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
898 SortShapes(listShape);
900 TopTools_IndexedMapOfShape anIndices;
901 TopExp::MapShapes(aShape, anIndices);
902 Handle(TColStd_HArray1OfInteger) anArray;
904 TopTools_ListIteratorOfListOfShape itSub (listShape);
905 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
906 TopoDS_Shape aValue = itSub.Value();
907 aSeq->Append(anIndices.FindIndex(aValue));
910 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
912 //Make a Python command
913 GEOM::TPythonDump pd (aFunction, /*append=*/true);
914 pd << "listSubShapeIDs = geompy.SubShapeAll";
915 pd << (isSorted ? "SortedIDs(" : "IDs(");
916 pd << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
922 //=============================================================================
926 //=============================================================================
927 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetSubShape
928 (Handle(GEOM_Object) theMainShape,
929 const Standard_Integer theID)
933 if (theMainShape.IsNull()) return NULL;
935 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
936 anArray->SetValue(1, theID);
937 Handle(GEOM_Object) anObj = GetEngine()->AddSubShape(theMainShape, anArray,true);
938 if (anObj.IsNull()) {
939 SetErrorCode("Can not get a sub-shape with the given ID");
943 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
945 //Make a Python command
946 GEOM::TPythonDump(aFunction) << anObj << " = geompy.GetSubShape("
947 << theMainShape << ", [" << theID << "])";
953 //=============================================================================
957 //=============================================================================
958 Standard_Integer GEOMImpl_IShapesOperations::GetSubShapeIndex (Handle(GEOM_Object) theMainShape,
959 Handle(GEOM_Object) theSubShape)
963 TopoDS_Shape aMainShape = theMainShape->GetValue();
964 TopoDS_Shape aSubShape = theSubShape->GetValue();
966 if (aMainShape.IsNull() || aSubShape.IsNull()) return -1;
968 TopTools_IndexedMapOfShape anIndices;
969 TopExp::MapShapes(aMainShape, anIndices);
970 if (anIndices.Contains(aSubShape)) {
972 return anIndices.FindIndex(aSubShape);
978 //=============================================================================
982 //=============================================================================
983 Standard_Integer GEOMImpl_IShapesOperations::GetTopologyIndex (Handle(GEOM_Object) theMainShape,
984 Handle(GEOM_Object) theSubShape)
988 TopoDS_Shape aMainShape = theMainShape->GetValue();
989 TopoDS_Shape aSubShape = theSubShape->GetValue();
991 if (aMainShape.IsNull() || aSubShape.IsNull()) {
992 SetErrorCode("Null argument shape given");
997 if (aSubShape.ShapeType() == TopAbs_COMPOUND) {
999 TopTools_ListOfShape CL;
1000 CL.Append(aMainShape);
1001 TopTools_ListIteratorOfListOfShape itC;
1002 for (itC.Initialize(CL); itC.More(); itC.Next()) {
1003 for (it.Initialize(itC.Value()); it.More(); it.Next()) {
1004 if (it.Value().ShapeType() == TopAbs_COMPOUND) {
1005 if (it.Value().IsSame(aSubShape))
1009 CL.Append(it.Value());
1014 TopExp_Explorer anExp (aMainShape, aSubShape.ShapeType());
1015 TopTools_MapOfShape M;
1016 for (; anExp.More(); anExp.Next()) {
1017 if (M.Add(anExp.Current())) {
1018 if (anExp.Current().IsSame(aSubShape))
1025 SetErrorCode("The sub-shape does not belong to the main shape");
1029 //=============================================================================
1031 * GetShapeTypeString
1033 //=============================================================================
1034 TCollection_AsciiString GEOMImpl_IShapesOperations::GetShapeTypeString (Handle(GEOM_Object) theShape)
1038 TCollection_AsciiString aTypeName ("Null Shape");
1040 TopoDS_Shape aShape = theShape->GetValue();
1041 if (aShape.IsNull())
1044 switch (aShape.ShapeType() )
1046 case TopAbs_COMPOUND:
1047 aTypeName = "Compound";
1049 case TopAbs_COMPSOLID:
1050 aTypeName = "Compound Solid";
1053 aTypeName = "Solid";
1056 aTypeName = "Shell";
1060 BRepAdaptor_Surface surf (TopoDS::Face(aShape));
1061 if (surf.GetType() == GeomAbs_Plane)
1062 aTypeName = "Plane";
1063 else if (surf.GetType() == GeomAbs_Cylinder)
1064 aTypeName = "Cylindrical Face";
1065 else if (surf.GetType() == GeomAbs_Sphere)
1066 aTypeName = "Spherical Face";
1067 else if (surf.GetType() == GeomAbs_Torus)
1068 aTypeName = "Toroidal Face";
1069 else if (surf.GetType() == GeomAbs_Cone)
1070 aTypeName = "Conical Face";
1072 aTypeName = "GEOM::FACE";
1080 BRepAdaptor_Curve curv (TopoDS::Edge(aShape));
1081 if (curv.GetType() == GeomAbs_Line) {
1082 if ((Abs(curv.FirstParameter()) >= 1E6) ||
1083 (Abs(curv.LastParameter()) >= 1E6))
1086 aTypeName = "Edge" ;
1087 } else if (curv.GetType() == GeomAbs_Circle) {
1088 if (curv.IsClosed())
1089 aTypeName = "Circle";
1098 aTypeName = "Vertex";
1101 aTypeName = "Shape";
1104 aTypeName = "Shape of unknown type";
1111 //=============================================================================
1115 //=============================================================================
1116 Standard_Integer GEOMImpl_IShapesOperations::NumberOfFaces (Handle(GEOM_Object) theShape)
1120 Standard_Integer nb = 0;
1122 if (theShape.IsNull()) return -1;
1123 TopoDS_Shape aShape = theShape->GetValue();
1124 if (aShape.IsNull()) return -1;
1126 TopTools_MapOfShape mapShape;
1128 TopExp_Explorer exp (aShape, TopAbs_FACE);
1129 for (; exp.More(); exp.Next())
1130 if (mapShape.Add(exp.Current()))
1137 //=============================================================================
1141 //=============================================================================
1142 Standard_Integer GEOMImpl_IShapesOperations::NumberOfEdges (Handle(GEOM_Object) theShape)
1146 Standard_Integer nb = 0;
1148 if (theShape.IsNull()) return -1;
1149 TopoDS_Shape aShape = theShape->GetValue();
1150 if (aShape.IsNull()) return -1;
1152 TopTools_MapOfShape mapShape;
1154 TopExp_Explorer exp (aShape, TopAbs_EDGE);
1155 for (; exp.More(); exp.Next())
1156 if (mapShape.Add(exp.Current()))
1163 //=============================================================================
1167 //=============================================================================
1168 Handle(GEOM_Object) GEOMImpl_IShapesOperations::ReverseShape(Handle(GEOM_Object) theShape)
1172 if (theShape.IsNull()) return NULL;
1174 //Add a new reversed object
1175 Handle(GEOM_Object) aReversed = GetEngine()->AddObject(GetDocID(), theShape->GetType());
1177 //Add a new Revese function
1178 Handle(GEOM_Function) aFunction;
1179 aFunction = aReversed->AddFunction(GEOMImpl_ShapeDriver::GetID(), REVERSE_ORIENTATION);
1180 if (aFunction.IsNull()) return NULL;
1182 //Check if the function is set correctly
1183 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
1185 GEOMImpl_IShapes aSI (aFunction);
1187 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
1188 if (aRefShape.IsNull()) return NULL;
1190 aSI.SetBase(aRefShape);
1192 //Compute the sub-shape value
1194 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
1197 if (!GetSolver()->ComputeFunction(aFunction)) {
1198 SetErrorCode("Shape driver failed to reverse shape");
1202 catch (Standard_Failure) {
1203 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1204 SetErrorCode(aFail->GetMessageString());
1208 //Make a Python command
1209 GEOM::TPythonDump(aFunction) << aReversed
1210 << " = geompy.ChangeOrientation(" << theShape << ")";
1216 //=============================================================================
1220 //=============================================================================
1221 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetFreeFacesIDs
1222 (Handle(GEOM_Object) theShape)
1226 if (theShape.IsNull()) return NULL;
1227 TopoDS_Shape aShape = theShape->GetValue();
1228 if (aShape.IsNull()) return NULL;
1230 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
1232 TopTools_IndexedDataMapOfShapeListOfShape mapFaceBlocks;
1233 GEOMImpl_Block6Explorer::MapShapesAndAncestors
1234 (aShape, TopAbs_FACE, TopAbs_SOLID, mapFaceBlocks);
1236 Standard_Integer ind = 1, nbFaces = mapFaceBlocks.Extent();
1239 SetErrorCode("The given shape has no faces");
1243 TopTools_IndexedMapOfShape anIndices;
1244 TopExp::MapShapes(aShape, anIndices);
1246 Standard_Integer id;
1247 for (; ind <= nbFaces; ind++) {
1248 if (mapFaceBlocks.FindFromIndex(ind).Extent() != 2) {
1249 id = anIndices.FindIndex(mapFaceBlocks.FindKey(ind));
1254 //The explode doesn't change object so no new function is required.
1255 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
1257 //Make a Python command
1258 GEOM::TPythonDump(aFunction, /*append=*/true)
1259 << "listFreeFacesIDs = geompy.GetFreeFacesIDs(" << theShape << ")";
1265 //=======================================================================
1266 //function : GetSharedShapes
1268 //=======================================================================
1270 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetSharedShapes
1271 (Handle(GEOM_Object) theShape1,
1272 Handle(GEOM_Object) theShape2,
1273 const Standard_Integer theShapeType)
1277 if (theShape1.IsNull() || theShape2.IsNull()) return NULL;
1279 TopoDS_Shape aShape1 = theShape1->GetValue();
1280 TopoDS_Shape aShape2 = theShape2->GetValue();
1282 if (aShape1.IsNull() || aShape2.IsNull()) return NULL;
1284 TopTools_IndexedMapOfShape anIndices;
1285 TopExp::MapShapes(aShape1, anIndices);
1286 Handle(TColStd_HArray1OfInteger) anArray;
1288 TopTools_IndexedMapOfShape mapShape1;
1289 TopExp::MapShapes(aShape1, TopAbs_ShapeEnum(theShapeType), mapShape1);
1291 Handle(GEOM_Object) anObj;
1292 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1293 TCollection_AsciiString anAsciiList, anEntry;
1295 TopTools_MapOfShape mapShape2;
1296 TopExp_Explorer exp (aShape2, TopAbs_ShapeEnum(theShapeType));
1297 for (; exp.More(); exp.Next()) {
1298 TopoDS_Shape aSS = exp.Current();
1299 if (mapShape2.Add(aSS) && mapShape1.Contains(aSS)) {
1300 anArray = new TColStd_HArray1OfInteger(1,1);
1301 anArray->SetValue(1, anIndices.FindIndex(aSS));
1302 anObj = GetEngine()->AddSubShape(theShape1, anArray);
1303 aSeq->Append(anObj);
1305 // for python command
1306 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
1307 anAsciiList += anEntry;
1312 if (aSeq->IsEmpty()) {
1313 SetErrorCode("The given shapes have no shared sub-shapes of the requested type");
1317 //Make a Python command
1318 anAsciiList.Trunc(anAsciiList.Length() - 1);
1320 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1322 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
1323 << "] = geompy.GetSharedShapes(" << theShape1 << ", "
1324 << theShape2 << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
1330 //=============================================================================
1334 //=============================================================================
1335 static GEOM::TPythonDump& operator<< (GEOM::TPythonDump& theDump,
1336 const GEOMAlgo_State theState)
1339 case GEOMAlgo_ST_IN:
1340 theDump << "geompy.GEOM.ST_IN";
1342 case GEOMAlgo_ST_OUT:
1343 theDump << "geompy.GEOM.ST_OUT";
1345 case GEOMAlgo_ST_ON:
1346 theDump << "geompy.GEOM.ST_ON";
1348 case GEOMAlgo_ST_ONIN:
1349 theDump << "geompy.GEOM.ST_ONIN";
1351 case GEOMAlgo_ST_ONOUT:
1352 theDump << "geompy.GEOM.ST_ONOUT";
1355 theDump << "geompy.GEOM.ST_UNKNOWN";
1361 //=======================================================================
1362 //function : checkTypeShapesOn
1364 * \brief Checks if theShapeType parameter of GetShapesOnXXX() is OK
1365 * \param theShapeType - the shape type to check
1366 * \retval bool - result of the check
1368 //=======================================================================
1370 bool GEOMImpl_IShapesOperations::checkTypeShapesOn(const Standard_Integer theShapeType)
1372 if (theShapeType != TopAbs_VERTEX &&
1373 theShapeType != TopAbs_EDGE &&
1374 theShapeType != TopAbs_FACE &&
1375 theShapeType != TopAbs_SOLID) {
1376 SetErrorCode("Only solids, vertices, edges or faces can be found by this method");
1382 //=======================================================================
1383 //function : makePlane
1385 * \brief Creates Geom_Plane
1386 * \param theAx1 - shape object defining plane parameters
1387 * \retval Handle(Geom_Surface) - resulting surface
1389 //=======================================================================
1391 Handle(Geom_Surface) GEOMImpl_IShapesOperations::makePlane(const TopoDS_Shape& anAx1)
1393 if (anAx1.ShapeType() != TopAbs_EDGE) return NULL;
1394 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
1395 TopoDS_Vertex V1, V2;
1396 TopExp::Vertices(anEdge, V1, V2, Standard_True);
1397 if (V1.IsNull() || V2.IsNull()) {
1398 SetErrorCode("Bad edge given for the plane normal vector");
1401 gp_Pnt aLoc = BRep_Tool::Pnt(V1);
1402 gp_Vec aVec (aLoc, BRep_Tool::Pnt(V2));
1403 if (aVec.Magnitude() < Precision::Confusion()) {
1404 SetErrorCode("Vector with null magnitude given");
1407 return new Geom_Plane(aLoc, aVec);
1410 //=======================================================================
1411 //function : makeCylinder
1413 * \brief Creates Geom_CylindricalSurface
1414 * \param theAx1 - edge defining cylinder axis
1415 * \param theRadius - cylinder radius
1416 * \retval Handle(Geom_Surface) - resulting surface
1418 //=======================================================================
1420 Handle(Geom_Surface) GEOMImpl_IShapesOperations::makeCylinder(const TopoDS_Shape& anAxis,
1421 const Standard_Real theRadius)
1423 //Axis of the cylinder
1424 if (anAxis.ShapeType() != TopAbs_EDGE) {
1425 SetErrorCode("Not an edge given for the axis");
1428 TopoDS_Edge anEdge = TopoDS::Edge(anAxis);
1429 TopoDS_Vertex V1, V2;
1430 TopExp::Vertices(anEdge, V1, V2, Standard_True);
1431 if (V1.IsNull() || V2.IsNull()) {
1432 SetErrorCode("Bad edge given for the axis");
1435 gp_Pnt aLoc = BRep_Tool::Pnt(V1);
1436 gp_Vec aVec (aLoc, BRep_Tool::Pnt(V2));
1437 if (aVec.Magnitude() < Precision::Confusion()) {
1438 SetErrorCode("Vector with null magnitude given");
1442 gp_Ax3 anAx3 (aLoc, aVec);
1443 return new Geom_CylindricalSurface(anAx3, theRadius);
1447 //=======================================================================
1448 //function : getShapesOnBoxIDs
1450 * \brief Find IDs of subshapes complying with given status about surface
1451 * \param theBox - the box to check state of subshapes against
1452 * \param theShape - the shape to explore
1453 * \param theShapeType - type of subshape of theShape
1454 * \param theState - required state
1455 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1457 //=======================================================================
1459 Handle(TColStd_HSequenceOfInteger)
1460 GEOMImpl_IShapesOperations::getShapesOnBoxIDs(const Handle(GEOM_Object)& theBox,
1461 const Handle(GEOM_Object)& theShape,
1462 const Standard_Integer theShapeType,
1463 GEOMAlgo_State theState)
1465 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
1467 TopoDS_Shape aBox = theBox->GetValue();
1468 TopoDS_Shape aShape = theShape->GetValue();
1470 // Check presence of triangulation, build if need
1471 if (!CheckTriangulation(aShape)) {
1472 SetErrorCode("Cannot build triangulation on the shape");
1477 GEOMAlgo_FinderShapeOn2 aFinder;
1478 Standard_Real aTol = 0.0001; // default value
1480 Handle(GEOMAlgo_ClsfBox) aClsfBox = new GEOMAlgo_ClsfBox;
1481 aClsfBox->SetBox(aBox);
1483 aFinder.SetShape(aShape);
1484 aFinder.SetTolerance(aTol);
1485 aFinder.SetClsf(aClsfBox);
1486 aFinder.SetShapeType( (TopAbs_ShapeEnum)theShapeType );
1487 aFinder.SetState(theState);
1490 // Interprete results
1491 Standard_Integer iErr = aFinder.ErrorStatus();
1492 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
1494 MESSAGE(" iErr : " << iErr);
1495 TCollection_AsciiString aMsg (" iErr : ");
1496 aMsg += TCollection_AsciiString(iErr);
1500 Standard_Integer iWrn = aFinder.WarningStatus();
1501 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
1503 MESSAGE(" *** iWrn : " << iWrn);
1506 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
1508 if (listSS.Extent() < 1) {
1509 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
1510 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
1514 // Fill sequence of object IDs
1515 aSeqOfIDs = new TColStd_HSequenceOfInteger;
1517 TopTools_IndexedMapOfShape anIndices;
1518 TopExp::MapShapes(aShape, anIndices);
1520 TopTools_ListIteratorOfListOfShape itSub (listSS);
1521 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
1522 int id = anIndices.FindIndex(itSub.Value());
1523 aSeqOfIDs->Append(id);
1530 //=======================================================================
1531 //function : GetShapesOnBoxIDs
1533 * \brief Find subshapes complying with given status about surface
1534 * \param theBox - the box to check state of subshapes against
1535 * \param theShape - the shape to explore
1536 * \param theShapeType - type of subshape of theShape
1537 * \param theState - required state
1538 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1540 //=======================================================================
1542 Handle(TColStd_HSequenceOfInteger)
1543 GEOMImpl_IShapesOperations::GetShapesOnBoxIDs(const Handle(GEOM_Object)& theBox,
1544 const Handle(GEOM_Object)& theShape,
1545 const Standard_Integer theShapeType,
1546 GEOMAlgo_State theState)
1548 // Find subshapes ids
1549 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
1550 getShapesOnBoxIDs (theBox, theShape, theShapeType, theState);
1551 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
1554 // The GetShapesOnBox() doesn't change object so no new function is required.
1555 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theBox)->GetLastFunction();
1557 // Make a Python command
1558 GEOM::TPythonDump(aFunction)
1559 << "listShapesOnBoxIDs = geompy.GetShapesOnBoxIDs("
1562 << TopAbs_ShapeEnum(theShapeType) << ", "
1569 //=======================================================================
1570 //function : GetShapesOnBox
1572 * \brief Find subshapes complying with given status about surface
1573 * \param theBox - the box to check state of subshapes against
1574 * \param theShape - the shape to explore
1575 * \param theShapeType - type of subshape of theShape
1576 * \param theState - required state
1577 * \retval Handle(TColStd_HSequenceOfTransient) - found subshapes
1579 //=======================================================================
1581 Handle(TColStd_HSequenceOfTransient)
1582 GEOMImpl_IShapesOperations::GetShapesOnBox(const Handle(GEOM_Object)& theBox,
1583 const Handle(GEOM_Object)& theShape,
1584 const Standard_Integer theShapeType,
1585 GEOMAlgo_State theState)
1587 // Find subshapes ids
1588 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
1589 getShapesOnBoxIDs (theBox, theShape, theShapeType, theState);
1590 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
1593 // Find objects by indices
1594 TCollection_AsciiString anAsciiList;
1595 Handle(TColStd_HSequenceOfTransient) aSeq;
1596 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
1597 if ( aSeq.IsNull() || aSeq->IsEmpty() )
1600 // Make a Python command
1602 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
1603 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1605 GEOM::TPythonDump(aFunction)
1606 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnBox("
1609 << TopAbs_ShapeEnum(theShapeType) << ", "
1617 //=======================================================================
1618 //function : getShapesOnShapeIDs
1620 * \brief Find IDs of subshapes complying with given status about surface
1621 * \param theCheckShape - the shape to check state of subshapes against
1622 * \param theShape - the shape to explore
1623 * \param theShapeType - type of subshape of theShape
1624 * \param theState - required state
1625 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1627 //=======================================================================
1629 Handle(TColStd_HSequenceOfInteger)
1630 GEOMImpl_IShapesOperations::getShapesOnShapeIDs
1631 (const Handle(GEOM_Object)& theCheckShape,
1632 const Handle(GEOM_Object)& theShape,
1633 const Standard_Integer theShapeType,
1634 GEOMAlgo_State theState)
1636 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
1638 TopoDS_Shape aCheckShape = theCheckShape->GetValue();
1639 TopoDS_Shape aShape = theShape->GetValue();
1640 TopTools_ListOfShape res;
1642 // Check presence of triangulation, build if need
1643 if (!CheckTriangulation(aShape)) {
1644 SetErrorCode("Cannot build triangulation on the shape");
1649 GEOMAlgo_FinderShapeOn2 aFinder;
1650 Standard_Real aTol = 0.0001; // default value
1652 Handle(GEOMAlgo_ClsfSolid) aClsfSolid = new GEOMAlgo_ClsfSolid;
1653 aClsfSolid->SetShape(aCheckShape);
1655 aFinder.SetShape(aShape);
1656 aFinder.SetTolerance(aTol);
1657 aFinder.SetClsf(aClsfSolid);
1658 aFinder.SetShapeType( (TopAbs_ShapeEnum)theShapeType );
1659 aFinder.SetState(theState);
1662 // Interprete results
1663 Standard_Integer iErr = aFinder.ErrorStatus();
1664 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
1666 MESSAGE(" iErr : " << iErr);
1667 TCollection_AsciiString aMsg (" iErr : ");
1668 aMsg += TCollection_AsciiString(iErr);
1672 Standard_Integer iWrn = aFinder.WarningStatus();
1673 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
1675 MESSAGE(" *** iWrn : " << iWrn);
1678 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
1680 if (listSS.Extent() < 1) {
1681 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
1682 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
1685 // Fill sequence of object IDs
1686 aSeqOfIDs = new TColStd_HSequenceOfInteger;
1688 TopTools_IndexedMapOfShape anIndices;
1689 TopExp::MapShapes(aShape, anIndices);
1691 TopTools_ListIteratorOfListOfShape itSub (listSS);
1692 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
1693 int id = anIndices.FindIndex(itSub.Value());
1694 aSeqOfIDs->Append(id);
1701 //=======================================================================
1702 //function : GetShapesOnShapeIDs
1704 * \brief Find subshapes complying with given status about surface
1705 * \param theCheckShape - the shape to check state of subshapes against
1706 * \param theShape - the shape to explore
1707 * \param theShapeType - type of subshape of theShape
1708 * \param theState - required state
1709 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1711 //=======================================================================
1713 Handle(TColStd_HSequenceOfInteger)
1714 GEOMImpl_IShapesOperations::GetShapesOnShapeIDs
1715 (const Handle(GEOM_Object)& theCheckShape,
1716 const Handle(GEOM_Object)& theShape,
1717 const Standard_Integer theShapeType,
1718 GEOMAlgo_State theState)
1720 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
1721 getShapesOnShapeIDs (theCheckShape, theShape, theShapeType, theState);
1723 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
1726 // The GetShapesOnShape() doesn't change object so no new function is required.
1727 Handle(GEOM_Function) aFunction =
1728 GEOM::GetCreatedLast(theShape,theCheckShape)->GetLastFunction();
1730 // Make a Python command
1731 GEOM::TPythonDump(aFunction)
1732 << "listShapesOnBoxIDs = geompy.GetShapesOnShapeIDs("
1733 << theCheckShape << ", "
1735 << TopAbs_ShapeEnum(theShapeType) << ", "
1743 //=======================================================================
1744 //function : GetShapesOnShape
1746 * \brief Find subshapes complying with given status about surface
1747 * \param theCheckShape - the shape to check state of subshapes against
1748 * \param theShape - the shape to explore
1749 * \param theShapeType - type of subshape of theShape
1750 * \param theState - required state
1751 * \retval Handle(TColStd_HSequenceOfTransient) - found subshapes
1753 //=======================================================================
1755 Handle(TColStd_HSequenceOfTransient)
1756 GEOMImpl_IShapesOperations::GetShapesOnShape
1757 (const Handle(GEOM_Object)& theCheckShape,
1758 const Handle(GEOM_Object)& theShape,
1759 const Standard_Integer theShapeType,
1760 GEOMAlgo_State theState)
1762 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
1763 getShapesOnShapeIDs (theCheckShape, theShape, theShapeType, theState);
1764 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
1767 // Find objects by indices
1768 TCollection_AsciiString anAsciiList;
1769 Handle(TColStd_HSequenceOfTransient) aSeq;
1770 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
1772 if ( aSeq.IsNull() || aSeq->IsEmpty() )
1775 // Make a Python command
1777 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
1778 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1780 GEOM::TPythonDump(aFunction)
1781 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnShape("
1782 << theCheckShape << ", "
1784 << TopAbs_ShapeEnum(theShapeType) << ", "
1793 //=======================================================================
1794 //function : GetShapesOnShapeAsCompound
1795 //=======================================================================
1797 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetShapesOnShapeAsCompound
1798 (const Handle(GEOM_Object)& theCheckShape,
1799 const Handle(GEOM_Object)& theShape,
1800 const Standard_Integer theShapeType,
1801 GEOMAlgo_State theState)
1803 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
1804 getShapesOnShapeIDs (theCheckShape, theShape, theShapeType, theState);
1806 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
1809 // Find objects by indices
1810 TCollection_AsciiString anAsciiList;
1811 Handle(TColStd_HSequenceOfTransient) aSeq;
1812 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
1814 if ( aSeq.IsNull() || aSeq->IsEmpty() )
1817 TopoDS_Compound aCompound;
1819 B.MakeCompound(aCompound);
1821 for(; i<=aSeq->Length(); i++) {
1822 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(aSeq->Value(i));
1823 TopoDS_Shape aShape_i = anObj->GetValue();
1824 B.Add(aCompound,aShape_i);
1827 //Add a new result object
1828 Handle(GEOM_Object) aRes = GetEngine()->AddObject(GetDocID(), GEOM_SHAPES_ON_SHAPE);
1829 Handle(GEOM_Function) aFunction =
1830 aRes->AddFunction(GEOMImpl_ShapeDriver::GetID(), SHAPES_ON_SHAPE);
1831 aFunction->SetValue(aCompound);
1833 GEOM::TPythonDump(aFunction)
1834 << aRes << " = geompy.GetShapesOnShapeAsCompound("
1835 << theCheckShape << ", "
1837 << TopAbs_ShapeEnum(theShapeType) << ", "
1846 //=======================================================================
1847 //function : getShapesOnSurfaceIDs
1849 * \brief Find IDs of subshapes complying with given status about surface
1850 * \param theSurface - the surface to check state of subshapes against
1851 * \param theShape - the shape to explore
1852 * \param theShapeType - type of subshape of theShape
1853 * \param theState - required state
1854 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1856 //=======================================================================
1858 Handle(TColStd_HSequenceOfInteger)
1859 GEOMImpl_IShapesOperations::getShapesOnSurfaceIDs(const Handle(Geom_Surface)& theSurface,
1860 const TopoDS_Shape& theShape,
1861 TopAbs_ShapeEnum theShapeType,
1862 GEOMAlgo_State theState)
1864 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
1866 // Check presence of triangulation, build if need
1867 if (!CheckTriangulation(theShape)) {
1868 SetErrorCode("Cannot build triangulation on the shape");
1873 GEOMAlgo_FinderShapeOn1 aFinder;
1874 Standard_Real aTol = 0.0001; // default value
1876 aFinder.SetShape(theShape);
1877 aFinder.SetTolerance(aTol);
1878 aFinder.SetSurface(theSurface);
1879 aFinder.SetShapeType(theShapeType);
1880 aFinder.SetState(theState);
1882 // Sets the minimal number of inner points for the faces that do not have own
1883 // inner points at all (for e.g. rectangular planar faces have just 2 triangles).
1885 aFinder.SetNbPntsMin(3);
1886 // Sets the maximal number of inner points for edges or faces.
1887 // It is usefull for the cases when this number is very big (e.g =2000) to improve
1888 // the performance. If this value =0, all inner points will be taken into account.
1890 aFinder.SetNbPntsMax(100);
1894 // Interprete results
1895 Standard_Integer iErr = aFinder.ErrorStatus();
1896 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
1898 MESSAGE(" iErr : " << iErr);
1899 TCollection_AsciiString aMsg (" iErr : ");
1900 aMsg += TCollection_AsciiString(iErr);
1904 Standard_Integer iWrn = aFinder.WarningStatus();
1905 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
1907 MESSAGE(" *** iWrn : " << iWrn);
1910 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
1912 if (listSS.Extent() < 1) {
1913 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
1914 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
1918 // Fill sequence of object IDs
1919 aSeqOfIDs = new TColStd_HSequenceOfInteger;
1921 TopTools_IndexedMapOfShape anIndices;
1922 TopExp::MapShapes(theShape, anIndices);
1924 TopTools_ListIteratorOfListOfShape itSub (listSS);
1925 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
1926 int id = anIndices.FindIndex(itSub.Value());
1927 aSeqOfIDs->Append(id);
1933 //=======================================================================
1934 //function : getObjectsShapesOn
1936 * \brief Find shape objects and their entries by their ids
1937 * \param theShapeIDs - incoming shape ids
1938 * \param theShapeEntries - outgoing entries like "entry1, entry2, ..."
1939 * \retval Handle(TColStd_HSequenceOfTransient) - found shape objects
1941 //=======================================================================
1943 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::
1944 getObjectsShapesOn(const Handle(GEOM_Object)& theShape,
1945 const Handle(TColStd_HSequenceOfInteger)& theShapeIDs,
1946 TCollection_AsciiString & theShapeEntries)
1948 Handle(TColStd_HSequenceOfTransient) aSeq;
1950 if ( !theShapeIDs.IsNull() && theShapeIDs->Length() > 0 )
1952 aSeq = new TColStd_HSequenceOfTransient;
1953 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
1954 TCollection_AsciiString anEntry;
1955 for ( int i = 1; i <= theShapeIDs->Length(); ++i )
1957 anArray->SetValue(1, theShapeIDs->Value( i ));
1958 Handle(GEOM_Object) anObj = GetEngine()->AddSubShape(theShape, anArray);
1959 aSeq->Append( anObj );
1961 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
1962 if ( i != 1 ) theShapeEntries += ",";
1963 theShapeEntries += anEntry;
1969 //=======================================================================
1970 //function : getShapesOnSurface
1972 * \brief Find subshapes complying with given status about surface
1973 * \param theSurface - the surface to check state of subshapes against
1974 * \param theShape - the shape to explore
1975 * \param theShapeType - type of subshape of theShape
1976 * \param theState - required state
1977 * \param theShapeEntries - outgoing entries like "entry1, entry2, ..."
1978 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1980 //=======================================================================
1982 Handle(TColStd_HSequenceOfTransient)
1983 GEOMImpl_IShapesOperations::getShapesOnSurface(const Handle(Geom_Surface)& theSurface,
1984 const Handle(GEOM_Object)& theShape,
1985 TopAbs_ShapeEnum theShapeType,
1986 GEOMAlgo_State theState,
1987 TCollection_AsciiString & theShapeEntries)
1989 // Find subshapes ids
1990 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
1991 getShapesOnSurfaceIDs (theSurface, theShape->GetValue(), theShapeType, theState);
1992 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
1995 return getObjectsShapesOn( theShape, aSeqOfIDs, theShapeEntries );
1998 //=============================================================================
2002 //=============================================================================
2003 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnPlane
2004 (const Handle(GEOM_Object)& theShape,
2005 const Standard_Integer theShapeType,
2006 const Handle(GEOM_Object)& theAx1,
2007 const GEOMAlgo_State theState)
2011 if (theShape.IsNull() || theAx1.IsNull()) return NULL;
2013 TopoDS_Shape aShape = theShape->GetValue();
2014 TopoDS_Shape anAx1 = theAx1->GetValue();
2016 if (aShape.IsNull() || anAx1.IsNull()) return NULL;
2018 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2019 if ( !checkTypeShapesOn( theShapeType ))
2023 Handle(Geom_Surface) aPlane = makePlane( anAx1 );
2024 if ( aPlane.IsNull() )
2028 TCollection_AsciiString anAsciiList;
2029 Handle(TColStd_HSequenceOfTransient) aSeq;
2030 aSeq = getShapesOnSurface( aPlane, theShape, aShapeType, theState, anAsciiList );
2031 if ( aSeq.IsNull() || aSeq->Length() == 0 )
2034 // Make a Python command
2036 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2037 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2039 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
2040 << "] = geompy.GetShapesOnPlane(" << theShape << ", "
2041 << aShapeType << ", " << theAx1 << ", " << theState << ")";
2047 //=============================================================================
2049 * GetShapesOnPlaneWithLocation
2051 //=============================================================================
2052 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnPlaneWithLocation
2053 (const Handle(GEOM_Object)& theShape,
2054 const Standard_Integer theShapeType,
2055 const Handle(GEOM_Object)& theAx1,
2056 const Handle(GEOM_Object)& thePnt,
2057 const GEOMAlgo_State theState)
2061 if (theShape.IsNull() || theAx1.IsNull() || thePnt.IsNull()) return NULL;
2063 TopoDS_Shape aShape = theShape->GetValue();
2064 TopoDS_Shape anAx1 = theAx1->GetValue();
2065 TopoDS_Shape anPnt = thePnt->GetValue();
2067 if (aShape.IsNull() || anAx1.IsNull() || anPnt.IsNull()) return NULL;
2069 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2070 if ( !checkTypeShapesOn( theShapeType ))
2074 if ( anAx1.ShapeType() != TopAbs_EDGE || anPnt.ShapeType() != TopAbs_VERTEX ) return NULL;
2075 TopoDS_Vertex V1, V2, V3;
2076 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
2077 TopExp::Vertices(anEdge, V1, V2, Standard_True);
2079 if (V1.IsNull() || V2.IsNull()) {
2080 SetErrorCode("Bad edge given for the plane normal vector");
2083 V3 = TopoDS::Vertex(anPnt);
2086 SetErrorCode("Bad vertex given for the plane location");
2089 gp_Pnt aLoc = BRep_Tool::Pnt(V3);
2090 gp_Vec aVec(BRep_Tool::Pnt(V1),BRep_Tool::Pnt(V2));
2092 if (aVec.Magnitude() < Precision::Confusion()) {
2093 SetErrorCode("Vector with null magnitude given");
2096 Handle(Geom_Surface) aPlane = new Geom_Plane(aLoc, aVec);
2098 if ( aPlane.IsNull() )
2102 TCollection_AsciiString anAsciiList;
2103 Handle(TColStd_HSequenceOfTransient) aSeq;
2104 aSeq = getShapesOnSurface( aPlane, theShape, aShapeType, theState, anAsciiList );
2105 if ( aSeq.IsNull() || aSeq->Length() == 0 )
2108 // Make a Python command
2110 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2111 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2113 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
2114 << "] = geompy.GetShapesOnPlaneWithLocation(" << theShape << ", "
2115 << aShapeType << ", " << theAx1 << ", "<< thePnt <<", " << theState << ")";
2121 //=============================================================================
2123 * GetShapesOnCylinder
2125 //=============================================================================
2126 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnCylinder
2127 (const Handle(GEOM_Object)& theShape,
2128 const Standard_Integer theShapeType,
2129 const Handle(GEOM_Object)& theAxis,
2130 const Standard_Real theRadius,
2131 const GEOMAlgo_State theState)
2135 if (theShape.IsNull() || theAxis.IsNull()) return NULL;
2137 TopoDS_Shape aShape = theShape->GetValue();
2138 TopoDS_Shape anAxis = theAxis->GetValue();
2140 if (aShape.IsNull() || anAxis.IsNull()) return NULL;
2142 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2143 if ( !checkTypeShapesOn( aShapeType ))
2146 // Create a cylinder surface
2147 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
2148 if ( aCylinder.IsNull() )
2152 TCollection_AsciiString anAsciiList;
2153 Handle(TColStd_HSequenceOfTransient) aSeq;
2154 aSeq = getShapesOnSurface( aCylinder, theShape, aShapeType, theState, anAsciiList );
2155 if ( aSeq.IsNull() || aSeq->Length() == 0 )
2158 // Make a Python command
2160 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2161 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2163 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
2164 << "] = geompy.GetShapesOnCylinder(" << theShape << ", " << aShapeType
2165 << ", " << theAxis << ", " << theRadius << ", " << theState << ")";
2171 //=============================================================================
2175 //=============================================================================
2176 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnSphere
2177 (const Handle(GEOM_Object)& theShape,
2178 const Standard_Integer theShapeType,
2179 const Handle(GEOM_Object)& theCenter,
2180 const Standard_Real theRadius,
2181 const GEOMAlgo_State theState)
2185 if (theShape.IsNull() || theCenter.IsNull()) return NULL;
2187 TopoDS_Shape aShape = theShape->GetValue();
2188 TopoDS_Shape aCenter = theCenter->GetValue();
2190 if (aShape.IsNull() || aCenter.IsNull()) return NULL;
2192 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2193 if ( !checkTypeShapesOn( aShapeType ))
2196 // Center of the sphere
2197 if (aCenter.ShapeType() != TopAbs_VERTEX) return NULL;
2198 gp_Pnt aLoc = BRep_Tool::Pnt(TopoDS::Vertex(aCenter));
2200 gp_Ax3 anAx3 (aLoc, gp::DZ());
2201 Handle(Geom_SphericalSurface) aSphere =
2202 new Geom_SphericalSurface(anAx3, theRadius);
2205 TCollection_AsciiString anAsciiList;
2206 Handle(TColStd_HSequenceOfTransient) aSeq;
2207 aSeq = getShapesOnSurface( aSphere, theShape, aShapeType, theState, anAsciiList );
2208 if ( aSeq.IsNull() || aSeq->Length() == 0 )
2211 // Make a Python command
2213 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2214 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2216 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
2217 << "] = geompy.GetShapesOnSphere(" << theShape << ", " << aShapeType
2218 << ", " << theCenter << ", " << theRadius << ", " << theState << ")";
2224 //=============================================================================
2226 * GetShapesOnPlaneIDs
2228 //=============================================================================
2229 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnPlaneIDs
2230 (const Handle(GEOM_Object)& theShape,
2231 const Standard_Integer theShapeType,
2232 const Handle(GEOM_Object)& theAx1,
2233 const GEOMAlgo_State theState)
2237 if (theShape.IsNull() || theAx1.IsNull()) return NULL;
2239 TopoDS_Shape aShape = theShape->GetValue();
2240 TopoDS_Shape anAx1 = theAx1->GetValue();
2242 if (aShape.IsNull() || anAx1.IsNull()) return NULL;
2244 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2245 if ( !checkTypeShapesOn( aShapeType ))
2249 Handle(Geom_Surface) aPlane = makePlane( anAx1 );
2250 if ( aPlane.IsNull() )
2254 Handle(TColStd_HSequenceOfInteger) aSeq;
2255 aSeq = getShapesOnSurfaceIDs( aPlane, aShape, aShapeType, theState );
2257 // The GetShapesOnPlaneIDs() doesn't change object so no new function is required.
2258 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAx1)->GetLastFunction();
2260 // Make a Python command
2261 GEOM::TPythonDump(aFunction, /*append=*/true)
2262 << "listShapesOnPlane = geompy.GetShapesOnPlaneIDs"
2263 << "(" << theShape << "," << aShapeType << "," << theAx1 << "," << theState << ")";
2269 //=============================================================================
2271 * GetShapesOnPlaneWithLocationIDs
2273 //=============================================================================
2274 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnPlaneWithLocationIDs
2275 (const Handle(GEOM_Object)& theShape,
2276 const Standard_Integer theShapeType,
2277 const Handle(GEOM_Object)& theAx1,
2278 const Handle(GEOM_Object)& thePnt,
2279 const GEOMAlgo_State theState)
2283 if (theShape.IsNull() || theAx1.IsNull() || thePnt.IsNull()) return NULL;
2285 TopoDS_Shape aShape = theShape->GetValue();
2286 TopoDS_Shape anAx1 = theAx1->GetValue();
2287 TopoDS_Shape anPnt = thePnt->GetValue();
2289 if (aShape.IsNull() || anAx1.IsNull() || anPnt.IsNull()) return NULL;
2291 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2292 if ( !checkTypeShapesOn( aShapeType ))
2296 if (anAx1.ShapeType() != TopAbs_EDGE || anPnt.ShapeType() != TopAbs_VERTEX) return NULL;
2297 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
2298 TopoDS_Vertex V1, V2, V3;
2299 TopExp::Vertices(anEdge, V1, V2, Standard_True);
2300 if (V1.IsNull() || V2.IsNull()) {
2301 SetErrorCode("Bad edge given for the plane normal vector");
2304 V3 = TopoDS::Vertex(anPnt);
2306 SetErrorCode("Bad vertex given for the plane location");
2309 gp_Pnt aLoc = BRep_Tool::Pnt(V3);
2310 gp_Vec aVec(BRep_Tool::Pnt(V1),BRep_Tool::Pnt(V2));
2311 if (aVec.Magnitude() < Precision::Confusion()) {
2312 SetErrorCode("Vector with null magnitude given");
2316 Handle(Geom_Surface) aPlane = new Geom_Plane(aLoc, aVec);
2317 if ( aPlane.IsNull() )
2321 Handle(TColStd_HSequenceOfInteger) aSeq;
2322 aSeq = getShapesOnSurfaceIDs( aPlane, aShape, aShapeType, theState );
2324 // The GetShapesOnPlaneIDs() doesn't change object so no new function is required.
2325 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAx1)->GetLastFunction();
2327 // Make a Python command
2328 GEOM::TPythonDump(aFunction, /*append=*/true)
2329 << "listShapesOnPlane = geompy.GetShapesOnPlaneWithLocationIDs"
2330 << "(" << theShape << ", " << aShapeType << ", " << theAx1 << ", "<< thePnt << ", " << theState << ")";
2336 //=============================================================================
2338 * GetShapesOnCylinderIDs
2340 //=============================================================================
2341 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnCylinderIDs
2342 (const Handle(GEOM_Object)& theShape,
2343 const Standard_Integer theShapeType,
2344 const Handle(GEOM_Object)& theAxis,
2345 const Standard_Real theRadius,
2346 const GEOMAlgo_State theState)
2350 if (theShape.IsNull() || theAxis.IsNull()) return NULL;
2352 TopoDS_Shape aShape = theShape->GetValue();
2353 TopoDS_Shape anAxis = theAxis->GetValue();
2355 if (aShape.IsNull() || anAxis.IsNull()) return NULL;
2357 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2358 if ( !checkTypeShapesOn( aShapeType ))
2361 // Create a cylinder surface
2362 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
2363 if ( aCylinder.IsNull() )
2367 Handle(TColStd_HSequenceOfInteger) aSeq;
2368 aSeq = getShapesOnSurfaceIDs( aCylinder, aShape, aShapeType, theState );
2370 // The GetShapesOnCylinder() doesn't change object so no new function is required.
2371 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAxis)->GetLastFunction();
2373 // Make a Python command
2374 GEOM::TPythonDump(aFunction, /*append=*/true)
2375 << "listShapesOnCylinder = geompy.GetShapesOnCylinderIDs"
2376 << "(" << theShape << ", " << aShapeType << ", " << theAxis << ", "
2377 << theRadius << ", " << theState << ")";
2383 //=============================================================================
2385 * GetShapesOnSphereIDs
2387 //=============================================================================
2388 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnSphereIDs
2389 (const Handle(GEOM_Object)& theShape,
2390 const Standard_Integer theShapeType,
2391 const Handle(GEOM_Object)& theCenter,
2392 const Standard_Real theRadius,
2393 const GEOMAlgo_State theState)
2397 if (theShape.IsNull() || theCenter.IsNull()) return NULL;
2399 TopoDS_Shape aShape = theShape->GetValue();
2400 TopoDS_Shape aCenter = theCenter->GetValue();
2402 if (aShape.IsNull() || aCenter.IsNull()) return NULL;
2404 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2405 if ( !checkTypeShapesOn( aShapeType ))
2408 // Center of the sphere
2409 if (aCenter.ShapeType() != TopAbs_VERTEX) return NULL;
2410 gp_Pnt aLoc = BRep_Tool::Pnt(TopoDS::Vertex(aCenter));
2412 gp_Ax3 anAx3 (aLoc, gp::DZ());
2413 Handle(Geom_SphericalSurface) aSphere =
2414 new Geom_SphericalSurface(anAx3, theRadius);
2417 Handle(TColStd_HSequenceOfInteger) aSeq;
2418 aSeq = getShapesOnSurfaceIDs( aSphere, aShape, aShapeType, theState );
2420 // The GetShapesOnSphere() doesn't change object so no new function is required.
2421 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theCenter)->GetLastFunction();
2423 // Make a Python command
2424 GEOM::TPythonDump(aFunction, /*append=*/true)
2425 << "listShapesOnCylinder = geompy.GetShapesOnCylinderIDs"
2426 << "(" << theShape << ", " << aShapeType << ", " << theCenter << ", "
2427 << theRadius << ", " << theState << ")";
2433 //=======================================================================
2434 //function : getShapesOnQuadrangleIDs
2436 * \brief Find IDs of subshapes complying with given status about quadrangle
2437 * \param theShape - the shape to explore
2438 * \param theShapeType - type of subshape of theShape
2439 * \param theTopLeftPoint - top left quadrangle corner
2440 * \param theTopRigthPoint - top right quadrangle corner
2441 * \param theBottomLeftPoint - bottom left quadrangle corner
2442 * \param theBottomRigthPoint - bottom right quadrangle corner
2443 * \param theState - required state
2444 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
2446 //=======================================================================
2448 Handle(TColStd_HSequenceOfInteger)
2449 GEOMImpl_IShapesOperations::getShapesOnQuadrangleIDs (const Handle(GEOM_Object)& theShape,
2450 const Standard_Integer theShapeType,
2451 const Handle(GEOM_Object)& theTopLeftPoint,
2452 const Handle(GEOM_Object)& theTopRigthPoint,
2453 const Handle(GEOM_Object)& theBottomLeftPoint,
2454 const Handle(GEOM_Object)& theBottomRigthPoint,
2455 const GEOMAlgo_State theState)
2459 if ( theShape.IsNull() ||
2460 theTopLeftPoint.IsNull() ||
2461 theTopRigthPoint.IsNull() ||
2462 theBottomLeftPoint.IsNull() ||
2463 theBottomRigthPoint.IsNull() )
2466 TopoDS_Shape aShape = theShape->GetValue();
2467 TopoDS_Shape aTL = theTopLeftPoint->GetValue();
2468 TopoDS_Shape aTR = theTopRigthPoint->GetValue();
2469 TopoDS_Shape aBL = theBottomLeftPoint->GetValue();
2470 TopoDS_Shape aBR = theBottomRigthPoint->GetValue();
2472 if (aShape.IsNull() ||
2477 aTL.ShapeType() != TopAbs_VERTEX ||
2478 aTR.ShapeType() != TopAbs_VERTEX ||
2479 aBL.ShapeType() != TopAbs_VERTEX ||
2480 aBR.ShapeType() != TopAbs_VERTEX )
2483 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2484 if ( !checkTypeShapesOn( aShapeType ))
2487 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
2489 // Check presence of triangulation, build if need
2490 if (!CheckTriangulation(aShape)) {
2491 SetErrorCode("Cannot build triangulation on the shape");
2496 gp_Pnt aPntTL = BRep_Tool::Pnt(TopoDS::Vertex(aTL));
2497 gp_Pnt aPntTR = BRep_Tool::Pnt(TopoDS::Vertex(aTR));
2498 gp_Pnt aPntBL = BRep_Tool::Pnt(TopoDS::Vertex(aBL));
2499 gp_Pnt aPntBR = BRep_Tool::Pnt(TopoDS::Vertex(aBR));
2501 GEOMAlgo_FinderShapeOnQuad aFinder( aPntTL, aPntTR, aPntBL, aPntBR );
2502 Standard_Real aTol = 0.0001; // default value
2504 aFinder.SetShape(aShape);
2505 aFinder.SetTolerance(aTol);
2506 //aFinder.SetSurface(theSurface);
2507 aFinder.SetShapeType(aShapeType);
2508 aFinder.SetState(theState);
2510 // Sets the minimal number of inner points for the faces that do not have own
2511 // inner points at all (for e.g. rectangular planar faces have just 2 triangles).
2513 aFinder.SetNbPntsMin(3);
2514 // Sets the maximal number of inner points for edges or faces.
2515 // It is usefull for the cases when this number is very big (e.g =2000) to improve
2516 // the performance. If this value =0, all inner points will be taken into account.
2518 aFinder.SetNbPntsMax(100);
2522 // Interprete results
2523 Standard_Integer iErr = aFinder.ErrorStatus();
2524 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
2526 MESSAGE(" iErr : " << iErr);
2527 TCollection_AsciiString aMsg (" iErr : ");
2528 aMsg += TCollection_AsciiString(iErr);
2532 Standard_Integer iWrn = aFinder.WarningStatus();
2533 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
2535 MESSAGE(" *** iWrn : " << iWrn);
2538 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
2540 if (listSS.Extent() < 1) {
2541 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
2542 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
2546 // Fill sequence of object IDs
2547 aSeqOfIDs = new TColStd_HSequenceOfInteger;
2549 TopTools_IndexedMapOfShape anIndices;
2550 TopExp::MapShapes(aShape, anIndices);
2552 TopTools_ListIteratorOfListOfShape itSub (listSS);
2553 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
2554 int id = anIndices.FindIndex(itSub.Value());
2555 aSeqOfIDs->Append(id);
2560 //=======================================================================
2561 //function : GetShapesOnQuadrangle
2563 * \brief Find subshapes complying with given status about quadrangle
2564 * \param theShape - the shape to explore
2565 * \param theShapeType - type of subshape of theShape
2566 * \param theTopLeftPoint - top left quadrangle corner
2567 * \param theTopRigthPoint - top right quadrangle corner
2568 * \param theBottomLeftPoint - bottom left quadrangle corner
2569 * \param theBottomRigthPoint - bottom right quadrangle corner
2570 * \param theState - required state
2571 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
2573 //=======================================================================
2575 Handle(TColStd_HSequenceOfTransient)
2576 GEOMImpl_IShapesOperations::GetShapesOnQuadrangle (const Handle(GEOM_Object)& theShape,
2577 const Standard_Integer theShapeType,
2578 const Handle(GEOM_Object)& theTopLeftPoint,
2579 const Handle(GEOM_Object)& theTopRigthPoint,
2580 const Handle(GEOM_Object)& theBottomLeftPoint,
2581 const Handle(GEOM_Object)& theBottomRigthPoint,
2582 const GEOMAlgo_State theState)
2585 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2586 getShapesOnQuadrangleIDs( theShape,
2591 theBottomRigthPoint,
2593 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->IsEmpty() )
2596 // Find objects by indices
2597 TCollection_AsciiString anAsciiList;
2598 Handle(TColStd_HSequenceOfTransient) aSeq;
2599 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
2600 if ( aSeq.IsNull() || aSeq->IsEmpty() )
2603 // Make a Python command
2605 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2606 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2608 GEOM::TPythonDump(aFunction)
2609 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnQuadrangle("
2611 << TopAbs_ShapeEnum(theShapeType) << ", "
2612 << theTopLeftPoint << ", "
2613 << theTopRigthPoint << ", "
2614 << theBottomLeftPoint << ", "
2615 << theBottomRigthPoint << ", "
2622 //=======================================================================
2623 //function : GetShapesOnQuadrangleIDs
2625 * \brief Find IDs of subshapes complying with given status about quadrangle
2626 * \param theShape - the shape to explore
2627 * \param theShapeType - type of subshape of theShape
2628 * \param theTopLeftPoint - top left quadrangle corner
2629 * \param theTopRigthPoint - top right quadrangle corner
2630 * \param theBottomLeftPoint - bottom left quadrangle corner
2631 * \param theBottomRigthPoint - bottom right quadrangle corner
2632 * \param theState - required state
2633 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
2635 //=======================================================================
2637 Handle(TColStd_HSequenceOfInteger)
2638 GEOMImpl_IShapesOperations::GetShapesOnQuadrangleIDs (const Handle(GEOM_Object)& theShape,
2639 const Standard_Integer theShapeType,
2640 const Handle(GEOM_Object)& theTopLeftPoint,
2641 const Handle(GEOM_Object)& theTopRigthPoint,
2642 const Handle(GEOM_Object)& theBottomLeftPoint,
2643 const Handle(GEOM_Object)& theBottomRigthPoint,
2644 const GEOMAlgo_State theState)
2647 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2648 getShapesOnQuadrangleIDs( theShape,
2653 theBottomRigthPoint,
2655 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->IsEmpty() )
2658 // Make a Python command
2660 // The GetShapesOnCylinder() doesn't change object so no new function is required.
2661 Handle(GEOM_Object) lastObj = GEOM::GetCreatedLast(theShape,theTopLeftPoint);
2662 lastObj = GEOM::GetCreatedLast(lastObj,theTopRigthPoint);
2663 lastObj = GEOM::GetCreatedLast(lastObj,theBottomRigthPoint);
2664 lastObj = GEOM::GetCreatedLast(lastObj,theBottomLeftPoint);
2665 Handle(GEOM_Function) aFunction = lastObj->GetLastFunction();
2667 GEOM::TPythonDump(aFunction, /*append=*/true)
2668 << "listShapesOnQuadrangle = geompy.GetShapesOnQuadrangleIDs("
2670 << TopAbs_ShapeEnum(theShapeType) << ", "
2671 << theTopLeftPoint << ", "
2672 << theTopRigthPoint << ", "
2673 << theBottomLeftPoint << ", "
2674 << theBottomRigthPoint << ", "
2682 //=============================================================================
2686 //=============================================================================
2687 static bool GetInPlaceOfShape (const Handle(GEOM_Function)& theWhereFunction,
2688 const TopTools_IndexedMapOfShape& theWhereIndices,
2689 const TopoDS_Shape& theWhat,
2690 TColStd_ListOfInteger& theModifiedList)
2692 if (theWhereFunction.IsNull() || theWhat.IsNull()) return false;
2694 if (theWhereIndices.Contains(theWhat)) {
2695 // entity was not changed by the operation
2696 Standard_Integer aWhatIndex = theWhereIndices.FindIndex(theWhat);
2697 theModifiedList.Append(aWhatIndex);
2701 // try to find in history
2702 TDF_Label aHistoryLabel = theWhereFunction->GetHistoryEntry(Standard_False);
2704 // search in history for all argument shapes
2705 Standard_Boolean isFound = Standard_False;
2706 Standard_Boolean isGood = Standard_False;
2708 TDF_LabelSequence aLabelSeq;
2709 theWhereFunction->GetDependency(aLabelSeq);
2710 Standard_Integer nbArg = aLabelSeq.Length();
2712 for (Standard_Integer iarg = 1; iarg <= nbArg && !isFound; iarg++) {
2714 TDF_Label anArgumentRefLabel = aLabelSeq.Value(iarg);
2716 Handle(GEOM_Object) anArgumentObject = GEOM_Object::GetReferencedObject(anArgumentRefLabel);
2717 TopoDS_Shape anArgumentShape = anArgumentObject->GetValue();
2719 TopTools_IndexedMapOfShape anArgumentIndices;
2720 TopExp::MapShapes(anArgumentShape, anArgumentIndices);
2722 if (anArgumentIndices.Contains(theWhat)) {
2723 isFound = Standard_True;
2724 Standard_Integer aWhatIndex = anArgumentIndices.FindIndex(theWhat);
2726 // Find corresponding label in history
2727 TDF_Label anArgumentHistoryLabel =
2728 theWhereFunction->GetArgumentHistoryEntry(anArgumentRefLabel, Standard_False);
2729 if (anArgumentHistoryLabel.IsNull()) {
2730 // Lost History of operation argument. Possibly, all its entities was removed.
2731 isGood = Standard_True;
2734 TDF_Label aWhatHistoryLabel = anArgumentHistoryLabel.FindChild(aWhatIndex, Standard_False);
2736 if (aWhatHistoryLabel.IsNull()) {
2737 // Removed entity ? Compound ? Compsolid ? Shell ? Wire
2738 isGood = Standard_False;
2740 Handle(TDataStd_IntegerArray) anIntegerArray;
2741 if (!aWhatHistoryLabel.FindAttribute(TDataStd_IntegerArray::GetID(), anIntegerArray)) {
2742 //Error: Empty modifications history for the sought shape.
2743 isGood = Standard_False;
2746 isGood = Standard_True;
2747 Standard_Integer imod, aModifLen = anIntegerArray->Array()->Length();
2748 for (imod = 1; imod <= aModifLen; imod++) {
2749 theModifiedList.Append(anIntegerArray->Array()->Value(imod));
2760 // try compound/compsolid/shell/wire element by element
2761 bool isFoundAny = false;
2762 TopTools_MapOfShape mapShape;
2764 if (theWhat.ShapeType() == TopAbs_COMPOUND ||
2765 theWhat.ShapeType() == TopAbs_COMPSOLID) {
2766 // recursive processing of compound/compsolid
2767 TopoDS_Iterator anIt (theWhat, Standard_True, Standard_True);
2768 for (; anIt.More(); anIt.Next()) {
2769 if (mapShape.Add(anIt.Value())) {
2770 TopoDS_Shape curWhat = anIt.Value();
2771 isFoundAny = GetInPlaceOfShape(theWhereFunction, theWhereIndices, curWhat, theModifiedList);
2772 if (isFoundAny) isFound = Standard_True;
2776 else if (theWhat.ShapeType() == TopAbs_SHELL) {
2777 // try to replace a shell by its faces images
2778 TopExp_Explorer anExp (theWhat, TopAbs_FACE);
2779 for (; anExp.More(); anExp.Next()) {
2780 if (mapShape.Add(anExp.Current())) {
2781 TopoDS_Shape curWhat = anExp.Current();
2782 isFoundAny = GetInPlaceOfShape(theWhereFunction, theWhereIndices, curWhat, theModifiedList);
2783 if (isFoundAny) isFound = Standard_True;
2787 else if (theWhat.ShapeType() == TopAbs_WIRE) {
2788 // try to replace a wire by its edges images
2789 TopExp_Explorer anExp (theWhat, TopAbs_EDGE);
2790 for (; anExp.More(); anExp.Next()) {
2791 if (mapShape.Add(anExp.Current())) {
2792 TopoDS_Shape curWhat = anExp.Current();
2793 isFoundAny = GetInPlaceOfShape(theWhereFunction, theWhereIndices, curWhat, theModifiedList);
2794 if (isFoundAny) isFound = Standard_True;
2806 //=============================================================================
2808 * GetShapeProperties
2810 //=============================================================================
2812 void GEOMImpl_IShapesOperations::GetShapeProperties( const TopoDS_Shape aShape, Standard_Real tab[],
2815 GProp_GProps SProps, VProps;
2817 TopoDS_Shape aPntShape;
2818 Standard_Real aShapeSize;
2820 BRepGProp::VolumeProperties(aShape, VProps);
2821 aCenterMass = VProps.CentreOfMass();
2822 aShapeSize = VProps.Mass();
2823 if (aShape.ShapeType() == TopAbs_FACE) {
2824 BRepGProp::SurfaceProperties(aShape, SProps);
2825 aCenterMass = SProps.CentreOfMass();
2826 aShapeSize = SProps.Mass();
2829 aPntShape = BRepBuilderAPI_MakeVertex(aCenterMass).Shape();
2830 aVertex = BRep_Tool::Pnt( TopoDS::Vertex( aPntShape ) );
2831 tab[0] = aVertex.X();
2832 tab[1] = aVertex.Y();
2833 tab[2] = aVertex.Z();
2834 tab[3] = aShapeSize;
2838 //=============================================================================
2842 //=============================================================================
2843 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlace (Handle(GEOM_Object) theShapeWhere,
2844 Handle(GEOM_Object) theShapeWhat)
2848 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
2850 TopoDS_Shape aWhere = theShapeWhere->GetValue();
2851 TopoDS_Shape aWhat = theShapeWhat->GetValue();
2853 if (aWhere.IsNull() || aWhat.IsNull()) {
2854 SetErrorCode("Error: aWhere and aWhat TopoDS_Shape are Null.");
2858 Handle(GEOM_Function) aWhereFunction = theShapeWhere->GetLastFunction();
2859 if (aWhereFunction.IsNull()) {
2860 SetErrorCode("Error: aWhereFunction is Null.");
2864 TopTools_IndexedMapOfShape aWhereIndices;
2865 TopExp::MapShapes(aWhere, aWhereIndices);
2867 TColStd_ListOfInteger aModifiedList;
2868 Standard_Integer aWhereIndex;
2869 Handle(TColStd_HArray1OfInteger) aModifiedArray;
2870 Handle(GEOM_Object) aResult;
2872 bool isFound = false;
2873 Standard_Integer iType = TopAbs_SOLID;
2874 Standard_Real aWhat_Mass = 0., aWhere_Mass = 0.;
2875 Standard_Real tab_aWhat[4], tab_aWhere[4];
2876 Standard_Real dl_l = 1e-3;
2877 Standard_Real min_l, Tol_1D, Tol_2D, Tol_3D, Tol_Mass;
2878 gp_Pnt aPnt, aPnt_aWhat;
2879 GProp_GProps aProps;
2882 if ( aWhat.ShapeType() == TopAbs_COMPOUND ||
2883 aWhat.ShapeType() == TopAbs_SHELL ||
2884 aWhat.ShapeType() == TopAbs_COMPSOLID ) {
2885 TopExp_Explorer Exp( aWhat, TopAbs_ShapeEnum( iType ) );
2886 if ( ! Exp.More() ) iType = TopAbs_FACE;
2888 else if ( aWhat.ShapeType() == TopAbs_FACE )
2889 iType = TopAbs_FACE;
2891 TopExp_Explorer Exp_aWhat( aWhat, TopAbs_ShapeEnum( iType ) );
2892 TopExp_Explorer Exp_aWhere( aWhere, TopAbs_ShapeEnum( iType ) );
2893 TopExp_Explorer Exp_Edge( aWhere, TopAbs_EDGE );
2895 // Find the shortest edge in theShapeWhere shape
2896 for ( Standard_Integer nbEdge = 0; Exp_Edge.More(); Exp_Edge.Next(), nbEdge++ ) {
2897 BRepGProp::LinearProperties(Exp_Edge.Current(), aProps);
2898 if ( ! nbEdge ) min_l = aProps.Mass();
2899 if ( aProps.Mass() < min_l ) min_l = aProps.Mass();
2902 // Compute tolerances
2903 Tol_1D = dl_l * min_l;
2904 Tol_2D = dl_l * ( min_l * min_l) * ( 2. + dl_l);
2905 Tol_3D = dl_l * ( min_l * min_l * min_l ) * ( 3. + (3 * dl_l) + (dl_l * dl_l) );
2908 if ( iType == TopAbs_FACE ) Tol_Mass = Tol_2D;
2910 // Compute the ShapeWhat Mass
2911 for ( ; Exp_aWhat.More(); Exp_aWhat.Next() ) {
2912 if ( iType == TopAbs_SOLID ) BRepGProp::VolumeProperties(Exp_aWhat.Current(), aProps);
2913 else if ( iType == TopAbs_FACE ) BRepGProp::SurfaceProperties(Exp_aWhat.Current(), aProps);
2914 aWhat_Mass += aProps.Mass();
2917 // Finding the Sub-ShapeWhere
2918 for ( Exp_aWhere.ReInit(); Exp_aWhere.More(); Exp_aWhere.Next() ) {
2919 GetShapeProperties( Exp_aWhere.Current(), tab_aWhere, aPnt );
2920 for ( Exp_aWhat.ReInit(); Exp_aWhat.More(); Exp_aWhat.Next() ) {
2921 GetShapeProperties( Exp_aWhat.Current(), tab_aWhat, aPnt_aWhat );
2922 if ( fabs(tab_aWhat[3] - tab_aWhere[3]) <= Tol_Mass && aPnt_aWhat.Distance(aPnt) <= Tol_1D )
2924 else if ( tab_aWhat[3] - ( tab_aWhere[3] > Tol_Mass) ) {
2925 BRepClass3d_SolidClassifier SC_aWhere (Exp_aWhere.Current(), aPnt, Precision::Confusion());
2926 BRepClass3d_SolidClassifier SC_aWhat (Exp_aWhat.Current(), aPnt, Precision::Confusion());
2927 // Block construction 3D
2928 if ( SC_aWhere.State() == TopAbs_IN && SC_aWhat.State() == TopAbs_IN ) isFound = true;
2929 // Block construction 2D
2930 else if ( SC_aWhere.State() == TopAbs_ON && SC_aWhat.State() == TopAbs_ON ) isFound = true;
2933 aWhereIndex = aWhereIndices.FindIndex(Exp_aWhere.Current());
2934 aModifiedList.Append(aWhereIndex);
2935 aWhere_Mass += tab_aWhere[3];
2940 if ( fabs( aWhat_Mass - aWhere_Mass ) <= Tol_Mass ) break;
2943 aModifiedArray = new TColStd_HArray1OfInteger (1, aModifiedList.Extent());
2944 TColStd_ListIteratorOfListOfInteger anIterModif (aModifiedList);
2945 for (Standard_Integer imod = 1; anIterModif.More(); anIterModif.Next(), imod++)
2946 aModifiedArray->SetValue(imod, anIterModif.Value());
2949 aResult = GetEngine()->AddSubShape(theShapeWhere, aModifiedArray);
2950 if (aResult.IsNull()) {
2951 SetErrorCode("Error in algorithm: result found, but cannot be returned.");
2955 if (aModifiedArray->Length() > 1) {
2957 aResult->SetType(GEOM_GROUP);
2959 //Set a sub shape type
2960 TopoDS_Shape aFirstFound = aWhereIndices.FindKey(aModifiedArray->Value(1));
2961 TopAbs_ShapeEnum aShapeType = aFirstFound.ShapeType();
2963 TDF_Label aFreeLabel = aResult->GetFreeLabel();
2964 TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aShapeType);
2967 //Make a Python command
2968 Handle(GEOM_Function) aFunction = aResult->GetFunction(1);
2970 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetInPlace("
2971 << theShapeWhere << ", " << theShapeWhat << ")";
2977 //=======================================================================
2978 //function : GetInPlaceByHistory
2980 //=======================================================================
2981 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlaceByHistory
2982 (Handle(GEOM_Object) theShapeWhere,
2983 Handle(GEOM_Object) theShapeWhat)
2987 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
2989 TopoDS_Shape aWhere = theShapeWhere->GetValue();
2990 TopoDS_Shape aWhat = theShapeWhat->GetValue();
2992 if (aWhere.IsNull() || aWhat.IsNull()) return NULL;
2994 Handle(GEOM_Function) aWhereFunction = theShapeWhere->GetLastFunction();
2995 if (aWhereFunction.IsNull()) return NULL;
2997 //Fill array of indices
2998 TopTools_IndexedMapOfShape aWhereIndices;
2999 TopExp::MapShapes(aWhere, aWhereIndices);
3002 TColStd_ListOfInteger aModifiedList;
3003 bool isFound = GetInPlaceOfShape(aWhereFunction, aWhereIndices, aWhat, aModifiedList);
3005 if (!isFound || aModifiedList.Extent() < 1) {
3006 SetErrorCode("Error: No history found for the sought shape or its sub-shapes.");
3010 Handle(TColStd_HArray1OfInteger) aModifiedArray =
3011 new TColStd_HArray1OfInteger (1, aModifiedList.Extent());
3012 TColStd_ListIteratorOfListOfInteger anIterModif (aModifiedList);
3013 for (Standard_Integer imod = 1; anIterModif.More(); anIterModif.Next(), imod++) {
3014 aModifiedArray->SetValue(imod, anIterModif.Value());
3018 Handle(GEOM_Object) aResult = GetEngine()->AddSubShape(theShapeWhere, aModifiedArray);
3019 if (aResult.IsNull()) {
3020 SetErrorCode("Error in algorithm: result found, but cannot be returned.");
3024 if (aModifiedArray->Length() > 1) {
3026 aResult->SetType(GEOM_GROUP);
3028 //Set a sub shape type
3029 TopoDS_Shape aFirstFound = aWhereIndices.FindKey(aModifiedArray->Value(1));
3030 TopAbs_ShapeEnum aShapeType = aFirstFound.ShapeType();
3032 TDF_Label aFreeLabel = aResult->GetFreeLabel();
3033 TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aShapeType);
3036 //Make a Python command
3037 Handle(GEOM_Function) aFunction = aResult->GetFunction(1);
3039 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetInPlace("
3040 << theShapeWhere << ", " << theShapeWhat << ")";
3046 //=======================================================================
3047 //function : SortShapes
3049 //=======================================================================
3050 void GEOMImpl_IShapesOperations::SortShapes(TopTools_ListOfShape& SL)
3052 Standard_Integer MaxShapes = SL.Extent();
3053 TopTools_Array1OfShape aShapes (1,MaxShapes);
3054 TColStd_Array1OfInteger OrderInd(1,MaxShapes);
3055 TColStd_Array1OfReal MidXYZ (1,MaxShapes); //X,Y,Z;
3056 TColStd_Array1OfReal Length (1,MaxShapes); //X,Y,Z;
3058 // Computing of CentreOfMass
3059 Standard_Integer Index;
3062 TopTools_ListIteratorOfListOfShape it(SL);
3063 for (Index=1; it.More(); Index++)
3065 TopoDS_Shape S = it.Value();
3066 SL.Remove( it ); // == it.Next()
3068 OrderInd.SetValue (Index, Index);
3069 if (S.ShapeType() == TopAbs_VERTEX)
3071 GPoint = BRep_Tool::Pnt( TopoDS::Vertex( S ));
3072 Length.SetValue( Index, (Standard_Real) S.Orientation());
3076 BRepGProp::LinearProperties (S, GPr);
3077 GPoint = GPr.CentreOfMass();
3078 Length.SetValue( Index, GPr.Mass() );
3080 MidXYZ.SetValue(Index,
3081 GPoint.X()*999 + GPoint.Y()*99 + GPoint.Z()*0.9);
3082 //cout << Index << " L: " << Length(Index) << "CG: " << MidXYZ(Index) << endl;
3086 Standard_Integer aTemp;
3087 Standard_Boolean exchange, Sort = Standard_True;
3088 Standard_Real tol = Precision::Confusion();
3091 Sort = Standard_False;
3092 for (Index=1; Index < MaxShapes; Index++)
3094 Standard_Real dMidXYZ = MidXYZ(OrderInd(Index)) - MidXYZ(OrderInd(Index+1));
3095 Standard_Real dLength = Length(OrderInd(Index)) - Length(OrderInd(Index+1));
3096 if ( dMidXYZ >= tol ) {
3097 // cout << "MidXYZ: " << MidXYZ(OrderInd(Index))<< " > " <<MidXYZ(OrderInd(Index+1))
3098 // << " d: " << dMidXYZ << endl;
3099 exchange = Standard_True;
3101 else if ( Abs(dMidXYZ) < tol && dLength >= tol ) {
3102 // cout << "Length: " << Length(OrderInd(Index))<< " > " <<Length(OrderInd(Index+1))
3103 // << " d: " << dLength << endl;
3104 exchange = Standard_True;
3106 else if ( Abs(dMidXYZ) < tol && Abs(dLength) < tol &&
3107 aShapes(OrderInd(Index)).ShapeType() <= TopAbs_FACE) {
3109 // equal values possible on shapes such as two halves of a sphere and
3110 // a membrane inside the sphere
3112 BRepBndLib::Add( aShapes( OrderInd(Index) ), box1 );
3113 if ( box1.IsVoid() ) continue;
3114 BRepBndLib::Add( aShapes( OrderInd(Index+1) ), box2 );
3115 Standard_Real dSquareExtent = box1.SquareExtent() - box2.SquareExtent();
3116 if ( dSquareExtent >= tol ) {
3117 // cout << "SquareExtent: " << box1.SquareExtent()<<" > "<<box2.SquareExtent() << endl;
3118 exchange = Standard_True;
3120 else if ( Abs(dSquareExtent) < tol ) {
3121 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax, val1, val2;
3122 box1.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
3123 val1 = (aXmin+aXmax)*999 + (aYmin+aYmax)*99 + (aZmin+aZmax)*0.9;
3124 box2.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
3125 val2 = (aXmin+aXmax)*999 + (aYmin+aYmax)*99 + (aZmin+aZmax)*0.9;
3126 exchange = val1 > val2;
3127 // cout << "box: " << val1<<" > "<<val2 << endl;
3131 exchange = Standard_False;
3135 // cout << "exchange " << Index << " & " << Index+1 << endl;
3136 aTemp = OrderInd(Index);
3137 OrderInd(Index) = OrderInd(Index+1);
3138 OrderInd(Index+1) = aTemp;
3139 Sort = Standard_True;
3144 for (Index=1; Index <= MaxShapes; Index++)
3145 SL.Append( aShapes( OrderInd(Index) ));
3148 //=======================================================================
3149 //function : CompsolidToCompound
3151 //=======================================================================
3152 TopoDS_Shape GEOMImpl_IShapesOperations::CompsolidToCompound (const TopoDS_Shape& theCompsolid)
3154 if (theCompsolid.ShapeType() != TopAbs_COMPSOLID) {
3155 return theCompsolid;
3158 TopoDS_Compound aCompound;
3160 B.MakeCompound(aCompound);
3162 TopTools_MapOfShape mapShape;
3163 TopoDS_Iterator It (theCompsolid, Standard_True, Standard_True);
3165 for (; It.More(); It.Next()) {
3166 TopoDS_Shape aShape_i = It.Value();
3167 if (mapShape.Add(aShape_i)) {
3168 B.Add(aCompound, aShape_i);
3175 //=======================================================================
3176 //function : CheckTriangulation
3178 //=======================================================================
3179 bool GEOMImpl_IShapesOperations::CheckTriangulation (const TopoDS_Shape& aShape)
3181 bool isTriangulation = true;
3183 TopExp_Explorer exp (aShape, TopAbs_FACE);
3186 TopLoc_Location aTopLoc;
3187 Handle(Poly_Triangulation) aTRF;
3188 aTRF = BRep_Tool::Triangulation(TopoDS::Face(exp.Current()), aTopLoc);
3189 if (aTRF.IsNull()) {
3190 isTriangulation = false;
3193 else // no faces, try edges
3195 TopExp_Explorer expe (aShape, TopAbs_EDGE);
3199 TopLoc_Location aLoc;
3200 Handle(Poly_Polygon3D) aPE = BRep_Tool::Polygon3D(TopoDS::Edge(expe.Current()), aLoc);
3202 isTriangulation = false;
3206 if (!isTriangulation) {
3207 // calculate deflection
3208 Standard_Real aDeviationCoefficient = 0.001;
3211 BRepBndLib::Add(aShape, B);
3212 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
3213 B.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
3215 Standard_Real dx = aXmax - aXmin, dy = aYmax - aYmin, dz = aZmax - aZmin;
3216 Standard_Real aDeflection = Max(Max(dx, dy), dz) * aDeviationCoefficient * 4;
3217 Standard_Real aHLRAngle = 0.349066;
3219 BRepMesh_IncrementalMesh Inc (aShape, aDeflection, Standard_False, aHLRAngle);
3225 #define MAX_TOLERANCE 1.e-7
3228 //=======================================================================
3229 //function : isSameEdge
3230 //purpose : Returns True if two edges coincide
3231 //=======================================================================
3232 static bool isSameEdge(const TopoDS_Edge& theEdge1, const TopoDS_Edge& theEdge2)
3234 TopoDS_Vertex V11, V12, V21, V22;
3235 TopExp::Vertices(theEdge1, V11, V12);
3236 TopExp::Vertices(theEdge2, V21, V22);
3237 gp_Pnt P11 = BRep_Tool::Pnt(V11);
3238 gp_Pnt P12 = BRep_Tool::Pnt(V12);
3239 gp_Pnt P21 = BRep_Tool::Pnt(V21);
3240 gp_Pnt P22 = BRep_Tool::Pnt(V22);
3241 bool coincide = false;
3243 //Check that ends of edges coincide
3244 if(P11.Distance(P21) <= MAX_TOLERANCE) {
3245 if(P12.Distance(P22) <= MAX_TOLERANCE) coincide = true;
3247 else if(P11.Distance(P22) <= MAX_TOLERANCE) {
3248 if(P12.Distance(P21) <= MAX_TOLERANCE) coincide = true;
3251 if(!coincide) return false;
3253 double U11, U12, U21, U22;
3254 Handle(Geom_Curve) C1 = BRep_Tool::Curve(theEdge1, U11, U12);
3255 Handle(Geom_Curve) C2 = BRep_Tool::Curve(theEdge2, U21, U22);
3256 if(C1->DynamicType() == C2->DynamicType()) return true;
3258 //Check that both edges has the same geometry
3259 double range = U12-U11;
3260 double U = U11+ range/3.0;
3261 gp_Pnt P1 = C1->Value(U); //Compute a point on one third of the edge's length
3262 U = U11+range*2.0/3.0;
3263 gp_Pnt P2 = C1->Value(U); //Compute a point on two thirds of the edge's length
3265 if(!GeomLib_Tool::Parameter(C2, P1, MAX_TOLERANCE, U) || U < U21 || U > U22)
3268 if(P1.Distance(C2->Value(U)) > MAX_TOLERANCE) return false;
3270 if(!GeomLib_Tool::Parameter(C2, P2, MAX_TOLERANCE, U) || U < U21 || U > U22)
3273 if(P2.Distance(C2->Value(U)) > MAX_TOLERANCE) return false;
3278 #include <TopoDS_TShape.hxx>
3279 //=======================================================================
3280 //function : isSameFace
3281 //purpose : Returns True if two faces coincide
3282 //=======================================================================
3283 static bool isSameFace(const TopoDS_Face& theFace1, const TopoDS_Face& theFace2)
3285 TopExp_Explorer E(theFace1, TopAbs_EDGE);
3286 TopTools_ListOfShape LS1, LS2;
3287 for(; E.More(); E.Next()) LS1.Append(E.Current());
3289 E.Init(theFace2, TopAbs_EDGE);
3290 for(; E.More(); E.Next()) LS2.Append(E.Current());
3292 //Compare the number of edges in the faces
3293 if(LS1.Extent() != LS2.Extent()) return false;
3295 double aMin = RealFirst(), aMax = RealLast();
3296 double xminB1=aMax, yminB1=aMax, zminB1=aMax, xminB2=aMax, yminB2=aMax, zminB2=aMax;
3297 double xmaxB1=aMin, ymaxB1=aMin, zmaxB1=aMin, xmaxB2=aMin, ymaxB2=aMin, zmaxB2=aMin;
3299 for(E.Init(theFace1, TopAbs_VERTEX); E.More(); E.Next()) {
3300 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
3301 if(P.X() < xminB1) xminB1 = P.X();
3302 if(P.Y() < yminB1) yminB1 = P.Y();
3303 if(P.Z() < zminB1) zminB1 = P.Z();
3304 if(P.X() > xmaxB1) xmaxB1 = P.X();
3305 if(P.Y() > ymaxB1) ymaxB1 = P.Y();
3306 if(P.Z() > zmaxB1) zmaxB1 = P.Z();
3309 for(E.Init(theFace2, TopAbs_VERTEX); E.More(); E.Next()) {
3310 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
3311 if(P.X() < xminB2) xminB2 = P.X();
3312 if(P.Y() < yminB2) yminB2 = P.Y();
3313 if(P.Z() < zminB2) zminB2 = P.Z();
3314 if(P.X() > xmaxB2) xmaxB2 = P.X();
3315 if(P.Y() > ymaxB2) ymaxB2 = P.Y();
3316 if(P.Z() > zmaxB2) zmaxB2 = P.Z();
3320 //Compare the bounding boxes of both faces
3321 if(gp_Pnt(xminB1, yminB1, zminB1).Distance(gp_Pnt(xminB2, yminB2, zminB2)) > MAX_TOLERANCE)
3324 if(gp_Pnt(xmaxB1, ymaxB1, zmaxB1).Distance(gp_Pnt(xmaxB2, ymaxB2, zmaxB2)) > MAX_TOLERANCE)
3327 Handle(Geom_Surface) S1 = BRep_Tool::Surface(theFace1);
3328 Handle(Geom_Surface) S2 = BRep_Tool::Surface(theFace2);
3330 //Check if there a coincidence of two surfaces at least in two points
3331 double U11, U12, V11, V12, U21, U22, V21, V22;
3332 BRepTools::UVBounds(theFace1, U11, U12, V11, V12);
3333 BRepTools::UVBounds(theFace2, U21, U22, V21, V22);
3335 double rangeU = U12-U11;
3336 double rangeV = V12-V11;
3337 double U = U11 + rangeU/3.0;
3338 double V = V11 + rangeV/3.0;
3339 gp_Pnt P1 = S1->Value(U, V);
3340 U = U11+rangeU*2.0/3.0;
3341 V = V11+rangeV*2.0/3.0;
3342 gp_Pnt P2 = S1->Value(U, V);
3344 if(!GeomLib_Tool::Parameters(S2, P1, MAX_TOLERANCE, U, V) || U < U21 || U > U22 || V < V21 || V > V22)
3347 if(P1.Distance(S2->Value(U,V)) > MAX_TOLERANCE) return false;
3349 if(!GeomLib_Tool::Parameters(S2, P2, MAX_TOLERANCE, U, V) || U < U21 || U > U22 || V < V21 || V > V22)
3352 if(P2.Distance(S2->Value(U, V)) > MAX_TOLERANCE) return false;
3354 //Check that each edge of the Face1 has a counterpart in the Face2
3355 TopTools_MapOfOrientedShape aMap;
3356 TopTools_ListIteratorOfListOfShape LSI1(LS1);
3357 for(; LSI1.More(); LSI1.Next()) {
3358 TopoDS_Edge E = TopoDS::Edge(LSI1.Value());
3359 bool isFound = false;
3360 TopTools_ListIteratorOfListOfShape LSI2(LS2);
3361 for(; LSI2.More(); LSI2.Next()) {
3362 TopoDS_Shape aValue = LSI2.Value();
3363 if(aMap.Contains(aValue)) continue; //To avoid checking already found edge several times
3364 if(isSameEdge(E, TopoDS::Edge(aValue))) {
3370 if(!isFound) return false;
3376 //=======================================================================
3377 //function : isSameSolid
3378 //purpose : Returns True if two solids coincide
3379 //=======================================================================
3380 bool isSameSolid(const TopoDS_Solid& theSolid1, const TopoDS_Solid& theSolid2)
3382 TopExp_Explorer E(theSolid1, TopAbs_FACE);
3383 TopTools_ListOfShape LS1, LS2;
3384 for(; E.More(); E.Next()) LS1.Append(E.Current());
3385 E.Init(theSolid2, TopAbs_FACE);
3386 for(; E.More(); E.Next()) LS2.Append(E.Current());
3388 if(LS1.Extent() != LS2.Extent()) return false;
3390 double aMin = RealFirst(), aMax = RealLast();
3391 double xminB1=aMax, yminB1=aMax, zminB1=aMax, xminB2=aMax, yminB2=aMax, zminB2=aMax;
3392 double xmaxB1=aMin, ymaxB1=aMin, zmaxB1=aMin, xmaxB2=aMin, ymaxB2=aMin, zmaxB2=aMin;
3394 for(E.Init(theSolid1, TopAbs_VERTEX); E.More(); E.Next()) {
3395 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
3396 if(P.X() < xminB1) xminB1 = P.X();
3397 if(P.Y() < yminB1) yminB1 = P.Y();
3398 if(P.Z() < zminB1) zminB1 = P.Z();
3399 if(P.X() > xmaxB1) xmaxB1 = P.X();
3400 if(P.Y() > ymaxB1) ymaxB1 = P.Y();
3401 if(P.Z() > zmaxB1) zmaxB1 = P.Z();
3404 for(E.Init(theSolid2, TopAbs_VERTEX); E.More(); E.Next()) {
3405 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
3406 if(P.X() < xminB2) xminB2 = P.X();
3407 if(P.Y() < yminB2) yminB2 = P.Y();
3408 if(P.Z() < zminB2) zminB2 = P.Z();
3409 if(P.X() > xmaxB2) xmaxB2 = P.X();
3410 if(P.Y() > ymaxB2) ymaxB2 = P.Y();
3411 if(P.Z() > zmaxB2) zmaxB2 = P.Z();
3414 //Compare the bounding boxes of both solids
3415 if(gp_Pnt(xminB1, yminB1, zminB1).Distance(gp_Pnt(xminB2, yminB2, zminB2)) > MAX_TOLERANCE)
3418 if(gp_Pnt(xmaxB1, ymaxB1, zmaxB1).Distance(gp_Pnt(xmaxB2, ymaxB2, zmaxB2)) > MAX_TOLERANCE)
3421 //Check that each face of the Solid1 has a counterpart in the Solid2
3422 TopTools_MapOfOrientedShape aMap;
3423 TopTools_ListIteratorOfListOfShape LSI1(LS1);
3424 for(; LSI1.More(); LSI1.Next()) {
3425 TopoDS_Face F = TopoDS::Face(LSI1.Value());
3426 bool isFound = false;
3427 TopTools_ListIteratorOfListOfShape LSI2(LS2);
3428 for(; LSI2.More(); LSI2.Next()) {
3429 if(aMap.Contains(LSI2.Value())) continue; //To avoid checking already found faces several times
3430 if(isSameFace(F, TopoDS::Face(LSI2.Value()))) {
3431 aMap.Add(LSI2.Value());
3436 if(!isFound) return false;
3442 //=======================================================================
3443 //function : GetSame
3445 //=======================================================================
3446 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetSame(const Handle(GEOM_Object)& theShapeWhere,
3447 const Handle(GEOM_Object)& theShapeWhat)
3450 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
3452 TopoDS_Shape aWhere = theShapeWhere->GetValue();
3453 TopoDS_Shape aWhat = theShapeWhat->GetValue();
3455 if (aWhere.IsNull() || aWhat.IsNull()) return NULL;
3458 bool isFound = false;
3459 TopoDS_Shape aSubShape;
3460 TopTools_MapOfShape aMap;
3462 switch(aWhat.ShapeType()) {
3463 case TopAbs_VERTEX: {
3464 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(aWhat));
3465 TopExp_Explorer E(aWhere, TopAbs_VERTEX);
3466 for(; E.More(); E.Next()) {
3467 if(!aMap.Add(E.Current())) continue;
3468 gp_Pnt P2 = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
3469 if(P.Distance(P2) <= MAX_TOLERANCE) {
3471 aSubShape = E.Current();
3478 TopoDS_Face aFace = TopoDS::Face(aWhat);
3479 TopExp_Explorer E(aWhere, TopAbs_FACE);
3480 for(; E.More(); E.Next()) {
3481 if(!aMap.Add(E.Current())) continue;
3482 if(isSameFace(aFace, TopoDS::Face(E.Current()))) {
3483 aSubShape = E.Current();
3491 TopoDS_Edge anEdge = TopoDS::Edge(aWhat);
3492 TopExp_Explorer E(aWhere, TopAbs_EDGE);
3493 for(; E.More(); E.Next()) {
3494 if(!aMap.Add(E.Current())) continue;
3495 if(isSameEdge(anEdge, TopoDS::Edge(E.Current()))) {
3496 aSubShape = E.Current();
3503 case TopAbs_SOLID: {
3504 TopoDS_Solid aSolid = TopoDS::Solid(aWhat);
3505 TopExp_Explorer E(aWhere, TopAbs_SOLID);
3506 for(; E.More(); E.Next()) {
3507 if(!aMap.Add(E.Current())) continue;
3508 if(isSameSolid(aSolid, TopoDS::Solid(E.Current()))) {
3509 aSubShape = E.Current();
3521 TopTools_IndexedMapOfShape anIndices;
3522 TopExp::MapShapes(aWhere, anIndices);
3523 if (anIndices.Contains(aSubShape))
3524 anIndex = anIndices.FindIndex(aSubShape);
3527 if(anIndex < 0) return NULL;
3529 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
3531 anArray->SetValue(1, anIndex);
3533 Handle(GEOM_Object) aResult = GetEngine()->AddSubShape(theShapeWhere, anArray);
3534 Handle(GEOM_Function) aFunction = aResult->GetLastFunction();
3536 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetSame("
3537 << theShapeWhere << ", " << theShapeWhat << ")";