1 // Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 // File : GEOMImpl_IShapesOperations.cxx
24 // 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>
71 #include <BRepExtrema_DistShapeShape.hxx>
73 #include <BRep_Tool.hxx>
74 #include <BRep_Builder.hxx>
75 #include <BRepTools.hxx>
76 #include <BRepGProp.hxx>
77 #include <BRepAdaptor_Curve.hxx>
78 #include <BRepAdaptor_Surface.hxx>
79 #include <BRepBndLib.hxx>
80 #include <BRepBuilderAPI_MakeFace.hxx>
81 #include <BRepMesh_IncrementalMesh.hxx>
86 #include <TopoDS_Shape.hxx>
87 #include <TopoDS_Solid.hxx>
88 #include <TopoDS_Face.hxx>
89 #include <TopoDS_Edge.hxx>
90 #include <TopoDS_Vertex.hxx>
91 #include <TopoDS_Compound.hxx>
92 #include <TopoDS_Iterator.hxx>
93 #include <TopExp_Explorer.hxx>
94 #include <TopLoc_Location.hxx>
95 #include <TopTools_MapOfShape.hxx>
96 #include <TopTools_MapOfOrientedShape.hxx>
97 #include <TopTools_Array1OfShape.hxx>
98 #include <TopTools_ListIteratorOfListOfShape.hxx>
99 #include <TopTools_IndexedMapOfShape.hxx>
101 #include <Geom_Surface.hxx>
102 #include <Geom_Plane.hxx>
103 #include <Geom_SphericalSurface.hxx>
104 #include <Geom_CylindricalSurface.hxx>
105 #include <GeomAdaptor_Surface.hxx>
107 #include <GeomLib_Tool.hxx>
108 #include <Geom2d_Curve.hxx>
110 #include <Bnd_Box.hxx>
111 #include <GProp_GProps.hxx>
112 #include <gp_Pnt.hxx>
113 #include <gp_Lin.hxx>
114 #include <TColStd_ListOfInteger.hxx>
115 #include <TColStd_ListIteratorOfListOfInteger.hxx>
116 #include <TColStd_Array1OfReal.hxx>
117 #include <TColStd_HArray1OfInteger.hxx>
121 #include <Standard_NullObject.hxx>
122 #include <Standard_Failure.hxx>
123 #include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
125 // Includes added for GetInPlace algorithm improvement
127 #include <GEOMImpl_MeasureDriver.hxx>
128 #include <GEOMImpl_IMeasure.hxx>
129 #include <BRepBuilderAPI_MakeVertex.hxx>
131 #include <BRepClass_FaceClassifier.hxx>
132 #include <BRepClass3d_SolidClassifier.hxx>
133 #include <Precision.hxx>
135 //=============================================================================
139 //=============================================================================
140 GEOMImpl_IShapesOperations::GEOMImpl_IShapesOperations (GEOM_Engine* theEngine, int theDocID)
141 : GEOM_IOperations(theEngine, theDocID)
143 MESSAGE("GEOMImpl_IShapesOperations::GEOMImpl_IShapesOperations");
146 //=============================================================================
150 //=============================================================================
151 GEOMImpl_IShapesOperations::~GEOMImpl_IShapesOperations()
153 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 (std::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 (std::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 std::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 (std::list<Handle(GEOM_Object)> theShapes)
360 return MakeShape(theShapes, GEOM_SHELL, SHELL_FACES, "MakeShell");
363 //=============================================================================
367 //=============================================================================
368 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeSolidShells
369 (std::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 (std::list<Handle(GEOM_Object)> theShapes)
436 return MakeShape(theShapes, GEOM_COMPOUND, COMPOUND_SHAPES, "MakeCompound");
439 //=============================================================================
443 //=============================================================================
444 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeShape
445 (std::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 std::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 << ")";
652 //=============================================================================
654 * MakeGlueFacesByList
656 //=============================================================================
657 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeGlueFacesByList
658 (Handle(GEOM_Object) theShape,
659 const Standard_Real theTolerance,
660 std::list<Handle(GEOM_Object)> theFaces,
661 const Standard_Boolean doKeepNonSolids)
665 if (theShape.IsNull()) return NULL;
667 //Add a new Glued object
668 Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
670 //Add a new Glue function
671 Handle(GEOM_Function) aFunction;
672 aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_FACES_BY_LIST);
673 if (aFunction.IsNull()) return NULL;
675 //Check if the function is set correctly
676 if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
678 GEOMImpl_IGlue aCI (aFunction);
680 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
681 if (aRefShape.IsNull()) return NULL;
683 aCI.SetBase(aRefShape);
684 aCI.SetTolerance(theTolerance);
685 aCI.SetKeepNonSolids(doKeepNonSolids);
687 Handle(TColStd_HSequenceOfTransient) aFaces = new TColStd_HSequenceOfTransient;
688 std::list<Handle(GEOM_Object)>::iterator it = theFaces.begin();
689 for (; it != theFaces.end(); it++) {
690 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
691 if (aRefSh.IsNull()) {
692 SetErrorCode("NULL argument shape for the shape construction");
695 aFaces->Append(aRefSh);
697 aCI.SetFaces(aFaces);
699 //Compute the sub-shape value
700 Standard_Boolean isWarning = Standard_False;
702 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
705 if (!GetSolver()->ComputeFunction(aFunction)) {
706 SetErrorCode("Shape driver failed to glue faces");
710 catch (Standard_Failure) {
711 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
712 SetErrorCode(aFail->GetMessageString());
713 // to provide warning
714 if (!aFunction->GetValue().IsNull()) {
715 isWarning = Standard_True;
721 //Make a Python command
723 GEOM::TPythonDump pd(aFunction);
724 pd << aGlued << " = geompy.MakeGlueFacesByList("
725 << theShape << ", " << theTolerance << ", [";
727 it = theFaces.begin();
728 if (it != theFaces.end()) {
730 while (it != theFaces.end()) {
731 pd << ", " << (*it++);
736 // to provide warning
737 if (!isWarning) SetErrorCode(OK);
741 //=============================================================================
745 //=============================================================================
746 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::MakeExplode
747 (Handle(GEOM_Object) theShape,
748 const Standard_Integer theShapeType,
749 const Standard_Boolean isSorted)
753 if (theShape.IsNull()) return NULL;
754 TopoDS_Shape aShape = theShape->GetValue();
755 if (aShape.IsNull()) return NULL;
757 Handle(GEOM_Function) aMainShape = theShape->GetLastFunction();
759 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
760 Handle(GEOM_Object) anObj;
761 TopTools_MapOfShape mapShape;
762 TopTools_ListOfShape listShape;
764 if (aShape.ShapeType() == TopAbs_COMPOUND &&
765 (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
766 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPSOLID ||
767 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPOUND)) {
768 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
769 for (; It.More(); It.Next()) {
770 if (mapShape.Add(It.Value())) {
771 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
772 TopAbs_ShapeEnum(theShapeType) == It.Value().ShapeType()) {
773 listShape.Append(It.Value());
778 TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
779 for (; exp.More(); exp.Next())
780 if (mapShape.Add(exp.Current()))
781 listShape.Append(exp.Current());
784 if (listShape.IsEmpty()) {
785 //SetErrorCode("The given shape has no sub-shapes of the requested type");
786 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
791 SortShapes(listShape);
793 TopTools_IndexedMapOfShape anIndices;
794 TopExp::MapShapes(aShape, anIndices);
795 Handle(TColStd_HArray1OfInteger) anArray;
797 TopTools_ListIteratorOfListOfShape itSub (listShape);
798 TCollection_AsciiString anAsciiList, anEntry;
799 for (int index = 1; itSub.More(); itSub.Next(), ++index)
801 TopoDS_Shape aValue = itSub.Value();
802 anArray = new TColStd_HArray1OfInteger(1,1);
803 anArray->SetValue(1, anIndices.FindIndex(aValue));
805 //anObj = GetEngine()->AddSubShape(theShape, anArray);
807 anObj = GetEngine()->AddObject(GetDocID(), GEOM_SUBSHAPE);
808 Handle(GEOM_Function) aFunction = anObj->AddFunction(GEOM_Object::GetSubShapeID(), 1);
809 if (aFunction.IsNull()) return aSeq;
811 GEOM_ISubShape aSSI (aFunction);
812 aSSI.SetMainShape(aMainShape);
813 aSSI.SetIndices(anArray);
815 // Set function value directly, as we know it.
816 // Usage of Solver here would lead to significant loss of time,
817 // because GEOM_SubShapeDriver will build TopTools_IndexedMapOfShape
818 // on the main shape for each being calculated sub-shape separately.
819 aFunction->SetValue(aValue);
822 if (!anObj.IsNull()) {
825 // for python command
826 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
827 anAsciiList += anEntry;
832 //Make a Python command
833 anAsciiList.Trunc(anAsciiList.Length() - 1);
835 GEOM::TPythonDump pd (aMainShape, /*append=*/true);
836 pd << "[" << anAsciiList.ToCString();
837 pd << "] = geompy.SubShapeAll" << (isSorted ? "Sorted(" : "(");
838 pd << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
845 //=============================================================================
849 //=============================================================================
850 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::SubShapeAllIDs
851 (Handle(GEOM_Object) theShape,
852 const Standard_Integer theShapeType,
853 const Standard_Boolean isSorted)
857 if (theShape.IsNull()) return NULL;
858 TopoDS_Shape aShape = theShape->GetValue();
859 if (aShape.IsNull()) return NULL;
861 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
862 TopTools_MapOfShape mapShape;
863 TopTools_ListOfShape listShape;
865 if (aShape.ShapeType() == TopAbs_COMPOUND &&
866 (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
867 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPSOLID ||
868 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPOUND)) {
869 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
870 for (; It.More(); It.Next()) {
871 if (mapShape.Add(It.Value())) {
872 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
873 TopAbs_ShapeEnum(theShapeType) == It.Value().ShapeType()) {
874 listShape.Append(It.Value());
879 TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
880 for (; exp.More(); exp.Next())
881 if (mapShape.Add(exp.Current()))
882 listShape.Append(exp.Current());
885 if (listShape.IsEmpty()) {
886 //SetErrorCode("The given shape has no sub-shapes of the requested type");
887 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
892 SortShapes(listShape);
894 TopTools_IndexedMapOfShape anIndices;
895 TopExp::MapShapes(aShape, anIndices);
896 Handle(TColStd_HArray1OfInteger) anArray;
898 TopTools_ListIteratorOfListOfShape itSub (listShape);
899 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
900 TopoDS_Shape aValue = itSub.Value();
901 aSeq->Append(anIndices.FindIndex(aValue));
904 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
906 //Make a Python command
907 GEOM::TPythonDump pd (aFunction, /*append=*/true);
908 pd << "listSubShapeIDs = geompy.SubShapeAll";
909 pd << (isSorted ? "SortedIDs(" : "IDs(");
910 pd << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
916 //=============================================================================
920 //=============================================================================
921 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetSubShape
922 (Handle(GEOM_Object) theMainShape,
923 const Standard_Integer theID)
927 if (theMainShape.IsNull()) return NULL;
929 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
930 anArray->SetValue(1, theID);
931 Handle(GEOM_Object) anObj = GetEngine()->AddSubShape(theMainShape, anArray,true);
932 if (anObj.IsNull()) {
933 SetErrorCode("Can not get a sub-shape with the given ID");
937 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
939 //Make a Python command
940 GEOM::TPythonDump(aFunction) << anObj << " = geompy.GetSubShape("
941 << theMainShape << ", [" << theID << "])";
947 //=============================================================================
951 //=============================================================================
952 Standard_Integer GEOMImpl_IShapesOperations::GetSubShapeIndex (Handle(GEOM_Object) theMainShape,
953 Handle(GEOM_Object) theSubShape)
957 TopoDS_Shape aMainShape = theMainShape->GetValue();
958 TopoDS_Shape aSubShape = theSubShape->GetValue();
960 if (aMainShape.IsNull() || aSubShape.IsNull()) return -1;
962 TopTools_IndexedMapOfShape anIndices;
963 TopExp::MapShapes(aMainShape, anIndices);
964 if (anIndices.Contains(aSubShape)) {
966 return anIndices.FindIndex(aSubShape);
972 //=============================================================================
976 //=============================================================================
977 Standard_Integer GEOMImpl_IShapesOperations::GetTopologyIndex (Handle(GEOM_Object) theMainShape,
978 Handle(GEOM_Object) theSubShape)
982 TopoDS_Shape aMainShape = theMainShape->GetValue();
983 TopoDS_Shape aSubShape = theSubShape->GetValue();
985 if (aMainShape.IsNull() || aSubShape.IsNull()) {
986 SetErrorCode("Null argument shape given");
991 if (aSubShape.ShapeType() == TopAbs_COMPOUND) {
993 TopTools_ListOfShape CL;
994 CL.Append(aMainShape);
995 TopTools_ListIteratorOfListOfShape itC;
996 for (itC.Initialize(CL); itC.More(); itC.Next()) {
997 for (it.Initialize(itC.Value()); it.More(); it.Next()) {
998 if (it.Value().ShapeType() == TopAbs_COMPOUND) {
999 if (it.Value().IsSame(aSubShape))
1003 CL.Append(it.Value());
1008 TopExp_Explorer anExp (aMainShape, aSubShape.ShapeType());
1009 TopTools_MapOfShape M;
1010 for (; anExp.More(); anExp.Next()) {
1011 if (M.Add(anExp.Current())) {
1012 if (anExp.Current().IsSame(aSubShape))
1019 SetErrorCode("The sub-shape does not belong to the main shape");
1023 //=============================================================================
1025 * GetShapeTypeString
1027 //=============================================================================
1028 TCollection_AsciiString GEOMImpl_IShapesOperations::GetShapeTypeString (Handle(GEOM_Object) theShape)
1032 TCollection_AsciiString aTypeName ("Null Shape");
1034 TopoDS_Shape aShape = theShape->GetValue();
1035 if (aShape.IsNull())
1038 switch (aShape.ShapeType() )
1040 case TopAbs_COMPOUND:
1041 aTypeName = "Compound";
1043 case TopAbs_COMPSOLID:
1044 aTypeName = "Compound Solid";
1047 aTypeName = "Solid";
1050 aTypeName = "Shell";
1054 BRepAdaptor_Surface surf (TopoDS::Face(aShape));
1055 if (surf.GetType() == GeomAbs_Plane)
1056 aTypeName = "Plane";
1057 else if (surf.GetType() == GeomAbs_Cylinder)
1058 aTypeName = "Cylindrical Face";
1059 else if (surf.GetType() == GeomAbs_Sphere)
1060 aTypeName = "Spherical Face";
1061 else if (surf.GetType() == GeomAbs_Torus)
1062 aTypeName = "Toroidal Face";
1063 else if (surf.GetType() == GeomAbs_Cone)
1064 aTypeName = "Conical Face";
1066 aTypeName = "GEOM::FACE";
1074 BRepAdaptor_Curve curv (TopoDS::Edge(aShape));
1075 if (curv.GetType() == GeomAbs_Line) {
1076 if ((Abs(curv.FirstParameter()) >= 1E6) ||
1077 (Abs(curv.LastParameter()) >= 1E6))
1081 } else if (curv.GetType() == GeomAbs_Circle) {
1082 if (curv.IsClosed())
1083 aTypeName = "Circle";
1092 aTypeName = "Vertex";
1095 aTypeName = "Shape";
1098 aTypeName = "Shape of unknown type";
1104 //=============================================================================
1108 //=============================================================================
1109 Standard_Integer GEOMImpl_IShapesOperations::NumberOfFaces (Handle(GEOM_Object) theShape)
1113 Standard_Integer nb = 0;
1115 if (theShape.IsNull()) return -1;
1116 TopoDS_Shape aShape = theShape->GetValue();
1117 if (aShape.IsNull()) return -1;
1119 TopTools_MapOfShape mapShape;
1121 TopExp_Explorer exp (aShape, TopAbs_FACE);
1122 for (; exp.More(); exp.Next())
1123 if (mapShape.Add(exp.Current()))
1130 //=============================================================================
1134 //=============================================================================
1135 Standard_Integer GEOMImpl_IShapesOperations::NumberOfEdges (Handle(GEOM_Object) theShape)
1139 Standard_Integer nb = 0;
1141 if (theShape.IsNull()) return -1;
1142 TopoDS_Shape aShape = theShape->GetValue();
1143 if (aShape.IsNull()) return -1;
1145 TopTools_MapOfShape mapShape;
1147 TopExp_Explorer exp (aShape, TopAbs_EDGE);
1148 for (; exp.More(); exp.Next())
1149 if (mapShape.Add(exp.Current()))
1156 //=============================================================================
1160 //=============================================================================
1161 Handle(GEOM_Object) GEOMImpl_IShapesOperations::ReverseShape(Handle(GEOM_Object) theShape)
1165 if (theShape.IsNull()) return NULL;
1167 //Add a new reversed object
1168 Handle(GEOM_Object) aReversed = GetEngine()->AddObject(GetDocID(), theShape->GetType());
1170 //Add a new Revese function
1171 Handle(GEOM_Function) aFunction;
1172 aFunction = aReversed->AddFunction(GEOMImpl_ShapeDriver::GetID(), REVERSE_ORIENTATION);
1173 if (aFunction.IsNull()) return NULL;
1175 //Check if the function is set correctly
1176 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
1178 GEOMImpl_IShapes aSI (aFunction);
1180 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
1181 if (aRefShape.IsNull()) return NULL;
1183 aSI.SetBase(aRefShape);
1185 //Compute the sub-shape value
1187 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
1190 if (!GetSolver()->ComputeFunction(aFunction)) {
1191 SetErrorCode("Shape driver failed to reverse shape");
1195 catch (Standard_Failure) {
1196 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1197 SetErrorCode(aFail->GetMessageString());
1201 //Make a Python command
1202 GEOM::TPythonDump(aFunction) << aReversed
1203 << " = geompy.ChangeOrientation(" << theShape << ")";
1209 //=============================================================================
1213 //=============================================================================
1214 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetFreeFacesIDs
1215 (Handle(GEOM_Object) theShape)
1219 if (theShape.IsNull()) return NULL;
1220 TopoDS_Shape aShape = theShape->GetValue();
1221 if (aShape.IsNull()) return NULL;
1223 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
1225 TopTools_IndexedDataMapOfShapeListOfShape mapFaceBlocks;
1226 GEOMImpl_Block6Explorer::MapShapesAndAncestors
1227 (aShape, TopAbs_FACE, TopAbs_SOLID, mapFaceBlocks);
1229 Standard_Integer ind = 1, nbFaces = mapFaceBlocks.Extent();
1232 SetErrorCode("The given shape has no faces");
1236 TopTools_IndexedMapOfShape anIndices;
1237 TopExp::MapShapes(aShape, anIndices);
1239 Standard_Integer id;
1240 for (; ind <= nbFaces; ind++) {
1241 if (mapFaceBlocks.FindFromIndex(ind).Extent() != 2) {
1242 id = anIndices.FindIndex(mapFaceBlocks.FindKey(ind));
1247 //The explode doesn't change object so no new function is required.
1248 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
1250 //Make a Python command
1251 GEOM::TPythonDump(aFunction, /*append=*/true)
1252 << "listFreeFacesIDs = geompy.GetFreeFacesIDs(" << theShape << ")";
1258 //=======================================================================
1259 //function : GetSharedShapes
1261 //=======================================================================
1262 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetSharedShapes
1263 (Handle(GEOM_Object) theShape1,
1264 Handle(GEOM_Object) theShape2,
1265 const Standard_Integer theShapeType)
1269 if (theShape1.IsNull() || theShape2.IsNull()) return NULL;
1271 TopoDS_Shape aShape1 = theShape1->GetValue();
1272 TopoDS_Shape aShape2 = theShape2->GetValue();
1274 if (aShape1.IsNull() || aShape2.IsNull()) return NULL;
1276 TopTools_IndexedMapOfShape anIndices;
1277 TopExp::MapShapes(aShape1, anIndices);
1278 Handle(TColStd_HArray1OfInteger) anArray;
1280 TopTools_IndexedMapOfShape mapShape1;
1281 TopExp::MapShapes(aShape1, TopAbs_ShapeEnum(theShapeType), mapShape1);
1283 Handle(GEOM_Object) anObj;
1284 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1285 TCollection_AsciiString anAsciiList, anEntry;
1287 TopTools_MapOfShape mapShape2;
1288 TopExp_Explorer exp (aShape2, TopAbs_ShapeEnum(theShapeType));
1289 for (; exp.More(); exp.Next()) {
1290 TopoDS_Shape aSS = exp.Current();
1291 if (mapShape2.Add(aSS) && mapShape1.Contains(aSS)) {
1292 anArray = new TColStd_HArray1OfInteger(1,1);
1293 anArray->SetValue(1, anIndices.FindIndex(aSS));
1294 anObj = GetEngine()->AddSubShape(theShape1, anArray);
1295 aSeq->Append(anObj);
1297 // for python command
1298 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
1299 anAsciiList += anEntry;
1304 if (aSeq->IsEmpty()) {
1305 SetErrorCode("The given shapes have no shared sub-shapes of the requested type");
1309 //Make a Python command
1310 anAsciiList.Trunc(anAsciiList.Length() - 1);
1312 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1314 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
1315 << "] = geompy.GetSharedShapes(" << theShape1 << ", "
1316 << theShape2 << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
1322 //=============================================================================
1326 //=============================================================================
1327 static GEOM::TPythonDump& operator<< (GEOM::TPythonDump& theDump,
1328 const GEOMAlgo_State theState)
1331 case GEOMAlgo_ST_IN:
1332 theDump << "geompy.GEOM.ST_IN";
1334 case GEOMAlgo_ST_OUT:
1335 theDump << "geompy.GEOM.ST_OUT";
1337 case GEOMAlgo_ST_ON:
1338 theDump << "geompy.GEOM.ST_ON";
1340 case GEOMAlgo_ST_ONIN:
1341 theDump << "geompy.GEOM.ST_ONIN";
1343 case GEOMAlgo_ST_ONOUT:
1344 theDump << "geompy.GEOM.ST_ONOUT";
1347 theDump << "geompy.GEOM.ST_UNKNOWN";
1353 //=======================================================================
1354 //function : checkTypeShapesOn
1356 * \brief Checks if theShapeType parameter of GetShapesOnXXX() is OK
1357 * \param theShapeType - the shape type to check
1358 * \retval bool - result of the check
1360 //=======================================================================
1361 bool GEOMImpl_IShapesOperations::checkTypeShapesOn(const Standard_Integer theShapeType)
1363 if (theShapeType != TopAbs_VERTEX &&
1364 theShapeType != TopAbs_EDGE &&
1365 theShapeType != TopAbs_FACE &&
1366 theShapeType != TopAbs_SOLID) {
1367 SetErrorCode("Only solids, vertices, edges or faces can be found by this method");
1373 //=======================================================================
1374 //function : makePlane
1376 * \brief Creates Geom_Plane
1377 * \param theAx1 - shape object defining plane parameters
1378 * \retval Handle(Geom_Surface) - resulting surface
1380 //=======================================================================
1381 Handle(Geom_Surface) GEOMImpl_IShapesOperations::makePlane(const TopoDS_Shape& anAx1)
1383 if (anAx1.ShapeType() != TopAbs_EDGE) return NULL;
1384 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
1385 TopoDS_Vertex V1, V2;
1386 TopExp::Vertices(anEdge, V1, V2, Standard_True);
1387 if (V1.IsNull() || V2.IsNull()) {
1388 SetErrorCode("Bad edge given for the plane normal vector");
1391 gp_Pnt aLoc = BRep_Tool::Pnt(V1);
1392 gp_Vec aVec (aLoc, BRep_Tool::Pnt(V2));
1393 if (aVec.Magnitude() < Precision::Confusion()) {
1394 SetErrorCode("Vector with null magnitude given");
1397 return new Geom_Plane(aLoc, aVec);
1400 //=======================================================================
1401 //function : makeCylinder
1403 * \brief Creates Geom_CylindricalSurface
1404 * \param theAx1 - edge defining cylinder axis
1405 * \param theRadius - cylinder radius
1406 * \retval Handle(Geom_Surface) - resulting surface
1408 //=======================================================================
1409 Handle(Geom_Surface) GEOMImpl_IShapesOperations::makeCylinder(const TopoDS_Shape& anAxis,
1410 const Standard_Real theRadius)
1412 //Axis of the cylinder
1413 if (anAxis.ShapeType() != TopAbs_EDGE) {
1414 SetErrorCode("Not an edge given for the axis");
1417 TopoDS_Edge anEdge = TopoDS::Edge(anAxis);
1418 TopoDS_Vertex V1, V2;
1419 TopExp::Vertices(anEdge, V1, V2, Standard_True);
1420 if (V1.IsNull() || V2.IsNull()) {
1421 SetErrorCode("Bad edge given for the axis");
1424 gp_Pnt aLoc = BRep_Tool::Pnt(V1);
1425 gp_Vec aVec (aLoc, BRep_Tool::Pnt(V2));
1426 if (aVec.Magnitude() < Precision::Confusion()) {
1427 SetErrorCode("Vector with null magnitude given");
1431 gp_Ax3 anAx3 (aLoc, aVec);
1432 return new Geom_CylindricalSurface(anAx3, theRadius);
1435 //=======================================================================
1436 //function : getShapesOnBoxIDs
1438 * \brief Find IDs of subshapes complying with given status about surface
1439 * \param theBox - the box to check state of subshapes against
1440 * \param theShape - the shape to explore
1441 * \param theShapeType - type of subshape of theShape
1442 * \param theState - required state
1443 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1445 //=======================================================================
1446 Handle(TColStd_HSequenceOfInteger)
1447 GEOMImpl_IShapesOperations::getShapesOnBoxIDs(const Handle(GEOM_Object)& theBox,
1448 const Handle(GEOM_Object)& theShape,
1449 const Standard_Integer theShapeType,
1450 GEOMAlgo_State theState)
1452 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
1454 TopoDS_Shape aBox = theBox->GetValue();
1455 TopoDS_Shape aShape = theShape->GetValue();
1457 // Check presence of triangulation, build if need
1458 if (!CheckTriangulation(aShape)) {
1459 SetErrorCode("Cannot build triangulation on the shape");
1464 GEOMAlgo_FinderShapeOn2 aFinder;
1465 Standard_Real aTol = 0.0001; // default value
1467 Handle(GEOMAlgo_ClsfBox) aClsfBox = new GEOMAlgo_ClsfBox;
1468 aClsfBox->SetBox(aBox);
1470 aFinder.SetShape(aShape);
1471 aFinder.SetTolerance(aTol);
1472 aFinder.SetClsf(aClsfBox);
1473 aFinder.SetShapeType( (TopAbs_ShapeEnum)theShapeType );
1474 aFinder.SetState(theState);
1477 // Interprete results
1478 Standard_Integer iErr = aFinder.ErrorStatus();
1479 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
1481 MESSAGE(" iErr : " << iErr);
1482 TCollection_AsciiString aMsg (" iErr : ");
1483 aMsg += TCollection_AsciiString(iErr);
1487 Standard_Integer iWrn = aFinder.WarningStatus();
1488 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
1490 MESSAGE(" *** iWrn : " << iWrn);
1493 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
1495 if (listSS.Extent() < 1) {
1496 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
1497 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
1501 // Fill sequence of object IDs
1502 aSeqOfIDs = new TColStd_HSequenceOfInteger;
1504 TopTools_IndexedMapOfShape anIndices;
1505 TopExp::MapShapes(aShape, anIndices);
1507 TopTools_ListIteratorOfListOfShape itSub (listSS);
1508 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
1509 int id = anIndices.FindIndex(itSub.Value());
1510 aSeqOfIDs->Append(id);
1516 //=======================================================================
1517 //function : GetShapesOnBoxIDs
1519 * \brief Find subshapes complying with given status about surface
1520 * \param theBox - the box to check state of subshapes against
1521 * \param theShape - the shape to explore
1522 * \param theShapeType - type of subshape of theShape
1523 * \param theState - required state
1524 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1526 //=======================================================================
1527 Handle(TColStd_HSequenceOfInteger)
1528 GEOMImpl_IShapesOperations::GetShapesOnBoxIDs(const Handle(GEOM_Object)& theBox,
1529 const Handle(GEOM_Object)& theShape,
1530 const Standard_Integer theShapeType,
1531 GEOMAlgo_State theState)
1533 // Find subshapes ids
1534 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
1535 getShapesOnBoxIDs (theBox, theShape, theShapeType, theState);
1536 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
1539 // The GetShapesOnBox() doesn't change object so no new function is required.
1540 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theBox)->GetLastFunction();
1542 // Make a Python command
1543 GEOM::TPythonDump(aFunction)
1544 << "listShapesOnBoxIDs = geompy.GetShapesOnBoxIDs("
1547 << TopAbs_ShapeEnum(theShapeType) << ", "
1554 //=======================================================================
1555 //function : GetShapesOnBox
1557 * \brief Find subshapes complying with given status about surface
1558 * \param theBox - the box to check state of subshapes against
1559 * \param theShape - the shape to explore
1560 * \param theShapeType - type of subshape of theShape
1561 * \param theState - required state
1562 * \retval Handle(TColStd_HSequenceOfTransient) - found subshapes
1564 //=======================================================================
1565 Handle(TColStd_HSequenceOfTransient)
1566 GEOMImpl_IShapesOperations::GetShapesOnBox(const Handle(GEOM_Object)& theBox,
1567 const Handle(GEOM_Object)& theShape,
1568 const Standard_Integer theShapeType,
1569 GEOMAlgo_State theState)
1571 // Find subshapes ids
1572 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
1573 getShapesOnBoxIDs (theBox, theShape, theShapeType, theState);
1574 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
1577 // Find objects by indices
1578 TCollection_AsciiString anAsciiList;
1579 Handle(TColStd_HSequenceOfTransient) aSeq;
1580 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
1581 if ( aSeq.IsNull() || aSeq->IsEmpty() )
1584 // Make a Python command
1586 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
1587 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1589 GEOM::TPythonDump(aFunction)
1590 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnBox("
1593 << TopAbs_ShapeEnum(theShapeType) << ", "
1600 //=======================================================================
1601 //function : getShapesOnShapeIDs
1603 * \brief Find IDs of subshapes complying with given status about surface
1604 * \param theCheckShape - the shape to check state of subshapes against
1605 * \param theShape - the shape to explore
1606 * \param theShapeType - type of subshape of theShape
1607 * \param theState - required state
1608 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1610 //=======================================================================
1611 Handle(TColStd_HSequenceOfInteger)
1612 GEOMImpl_IShapesOperations::getShapesOnShapeIDs
1613 (const Handle(GEOM_Object)& theCheckShape,
1614 const Handle(GEOM_Object)& theShape,
1615 const Standard_Integer theShapeType,
1616 GEOMAlgo_State theState)
1618 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
1620 TopoDS_Shape aCheckShape = theCheckShape->GetValue();
1621 TopoDS_Shape aShape = theShape->GetValue();
1622 TopTools_ListOfShape res;
1624 // Check presence of triangulation, build if need
1625 if (!CheckTriangulation(aShape)) {
1626 SetErrorCode("Cannot build triangulation on the shape");
1631 GEOMAlgo_FinderShapeOn2 aFinder;
1632 Standard_Real aTol = 0.0001; // default value
1634 Handle(GEOMAlgo_ClsfSolid) aClsfSolid = new GEOMAlgo_ClsfSolid;
1635 aClsfSolid->SetShape(aCheckShape);
1637 aFinder.SetShape(aShape);
1638 aFinder.SetTolerance(aTol);
1639 aFinder.SetClsf(aClsfSolid);
1640 aFinder.SetShapeType( (TopAbs_ShapeEnum)theShapeType );
1641 aFinder.SetState(theState);
1644 // Interprete results
1645 Standard_Integer iErr = aFinder.ErrorStatus();
1646 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
1648 MESSAGE(" iErr : " << iErr);
1649 TCollection_AsciiString aMsg (" iErr : ");
1650 aMsg += TCollection_AsciiString(iErr);
1654 Standard_Integer iWrn = aFinder.WarningStatus();
1655 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
1657 MESSAGE(" *** iWrn : " << iWrn);
1660 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
1662 if (listSS.Extent() < 1) {
1663 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
1664 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
1667 // Fill sequence of object IDs
1668 aSeqOfIDs = new TColStd_HSequenceOfInteger;
1670 TopTools_IndexedMapOfShape anIndices;
1671 TopExp::MapShapes(aShape, anIndices);
1673 TopTools_ListIteratorOfListOfShape itSub (listSS);
1674 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
1675 int id = anIndices.FindIndex(itSub.Value());
1676 aSeqOfIDs->Append(id);
1682 //=======================================================================
1683 //function : GetShapesOnShapeIDs
1685 * \brief Find subshapes complying with given status about surface
1686 * \param theCheckShape - the shape to check state of subshapes against
1687 * \param theShape - the shape to explore
1688 * \param theShapeType - type of subshape of theShape
1689 * \param theState - required state
1690 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1692 //=======================================================================
1693 Handle(TColStd_HSequenceOfInteger)
1694 GEOMImpl_IShapesOperations::GetShapesOnShapeIDs
1695 (const Handle(GEOM_Object)& theCheckShape,
1696 const Handle(GEOM_Object)& theShape,
1697 const Standard_Integer theShapeType,
1698 GEOMAlgo_State theState)
1700 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
1701 getShapesOnShapeIDs (theCheckShape, theShape, theShapeType, theState);
1703 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
1706 // The GetShapesOnShape() doesn't change object so no new function is required.
1707 Handle(GEOM_Function) aFunction =
1708 GEOM::GetCreatedLast(theShape,theCheckShape)->GetLastFunction();
1710 // Make a Python command
1711 GEOM::TPythonDump(aFunction)
1712 << "listShapesOnBoxIDs = geompy.GetShapesOnShapeIDs("
1713 << theCheckShape << ", "
1715 << TopAbs_ShapeEnum(theShapeType) << ", "
1722 //=======================================================================
1723 //function : GetShapesOnShape
1725 * \brief Find subshapes complying with given status about surface
1726 * \param theCheckShape - the shape to check state of subshapes against
1727 * \param theShape - the shape to explore
1728 * \param theShapeType - type of subshape of theShape
1729 * \param theState - required state
1730 * \retval Handle(TColStd_HSequenceOfTransient) - found subshapes
1732 //=======================================================================
1733 Handle(TColStd_HSequenceOfTransient)
1734 GEOMImpl_IShapesOperations::GetShapesOnShape
1735 (const Handle(GEOM_Object)& theCheckShape,
1736 const Handle(GEOM_Object)& theShape,
1737 const Standard_Integer theShapeType,
1738 GEOMAlgo_State theState)
1740 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
1741 getShapesOnShapeIDs (theCheckShape, theShape, theShapeType, theState);
1742 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
1745 // Find objects by indices
1746 TCollection_AsciiString anAsciiList;
1747 Handle(TColStd_HSequenceOfTransient) aSeq;
1748 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
1750 if ( aSeq.IsNull() || aSeq->IsEmpty() )
1753 // Make a Python command
1755 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
1756 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1758 GEOM::TPythonDump(aFunction)
1759 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnShape("
1760 << theCheckShape << ", "
1762 << TopAbs_ShapeEnum(theShapeType) << ", "
1769 //=======================================================================
1770 //function : GetShapesOnShapeAsCompound
1771 //=======================================================================
1772 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetShapesOnShapeAsCompound
1773 (const Handle(GEOM_Object)& theCheckShape,
1774 const Handle(GEOM_Object)& theShape,
1775 const Standard_Integer theShapeType,
1776 GEOMAlgo_State theState)
1778 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
1779 getShapesOnShapeIDs (theCheckShape, theShape, theShapeType, theState);
1781 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
1784 // Find objects by indices
1785 TCollection_AsciiString anAsciiList;
1786 Handle(TColStd_HSequenceOfTransient) aSeq;
1787 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
1789 if ( aSeq.IsNull() || aSeq->IsEmpty() )
1792 TopoDS_Compound aCompound;
1794 B.MakeCompound(aCompound);
1796 for(; i<=aSeq->Length(); i++) {
1797 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(aSeq->Value(i));
1798 TopoDS_Shape aShape_i = anObj->GetValue();
1799 B.Add(aCompound,aShape_i);
1802 //Add a new result object
1803 Handle(GEOM_Object) aRes = GetEngine()->AddObject(GetDocID(), GEOM_SHAPES_ON_SHAPE);
1804 Handle(GEOM_Function) aFunction =
1805 aRes->AddFunction(GEOMImpl_ShapeDriver::GetID(), SHAPES_ON_SHAPE);
1806 aFunction->SetValue(aCompound);
1808 GEOM::TPythonDump(aFunction)
1809 << aRes << " = geompy.GetShapesOnShapeAsCompound("
1810 << theCheckShape << ", "
1812 << TopAbs_ShapeEnum(theShapeType) << ", "
1820 //=======================================================================
1821 //function : getShapesOnSurfaceIDs
1823 * \brief Find IDs of subshapes complying with given status about surface
1824 * \param theSurface - the surface to check state of subshapes against
1825 * \param theShape - the shape to explore
1826 * \param theShapeType - type of subshape of theShape
1827 * \param theState - required state
1828 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1830 //=======================================================================
1831 Handle(TColStd_HSequenceOfInteger)
1832 GEOMImpl_IShapesOperations::getShapesOnSurfaceIDs(const Handle(Geom_Surface)& theSurface,
1833 const TopoDS_Shape& theShape,
1834 TopAbs_ShapeEnum theShapeType,
1835 GEOMAlgo_State theState)
1837 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
1839 // Check presence of triangulation, build if need
1840 if (!CheckTriangulation(theShape)) {
1841 SetErrorCode("Cannot build triangulation on the shape");
1846 GEOMAlgo_FinderShapeOn1 aFinder;
1847 Standard_Real aTol = 0.0001; // default value
1849 aFinder.SetShape(theShape);
1850 aFinder.SetTolerance(aTol);
1851 aFinder.SetSurface(theSurface);
1852 aFinder.SetShapeType(theShapeType);
1853 aFinder.SetState(theState);
1855 // Sets the minimal number of inner points for the faces that do not have own
1856 // inner points at all (for e.g. rectangular planar faces have just 2 triangles).
1858 aFinder.SetNbPntsMin(3);
1859 // Sets the maximal number of inner points for edges or faces.
1860 // It is usefull for the cases when this number is very big (e.g =2000) to improve
1861 // the performance. If this value =0, all inner points will be taken into account.
1863 aFinder.SetNbPntsMax(100);
1867 // Interprete results
1868 Standard_Integer iErr = aFinder.ErrorStatus();
1869 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
1871 MESSAGE(" iErr : " << iErr);
1872 TCollection_AsciiString aMsg (" iErr : ");
1873 aMsg += TCollection_AsciiString(iErr);
1877 Standard_Integer iWrn = aFinder.WarningStatus();
1878 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
1880 MESSAGE(" *** iWrn : " << iWrn);
1883 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
1885 if (listSS.Extent() < 1) {
1886 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
1887 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
1891 // Fill sequence of object IDs
1892 aSeqOfIDs = new TColStd_HSequenceOfInteger;
1894 TopTools_IndexedMapOfShape anIndices;
1895 TopExp::MapShapes(theShape, anIndices);
1897 TopTools_ListIteratorOfListOfShape itSub (listSS);
1898 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
1899 int id = anIndices.FindIndex(itSub.Value());
1900 aSeqOfIDs->Append(id);
1906 //=======================================================================
1907 //function : getObjectsShapesOn
1909 * \brief Find shape objects and their entries by their ids
1910 * \param theShapeIDs - incoming shape ids
1911 * \param theShapeEntries - outgoing entries like "entry1, entry2, ..."
1912 * \retval Handle(TColStd_HSequenceOfTransient) - found shape objects
1914 //=======================================================================
1915 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::
1916 getObjectsShapesOn(const Handle(GEOM_Object)& theShape,
1917 const Handle(TColStd_HSequenceOfInteger)& theShapeIDs,
1918 TCollection_AsciiString & theShapeEntries)
1920 Handle(TColStd_HSequenceOfTransient) aSeq;
1922 if ( !theShapeIDs.IsNull() && theShapeIDs->Length() > 0 )
1924 aSeq = new TColStd_HSequenceOfTransient;
1925 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
1926 TCollection_AsciiString anEntry;
1927 for ( int i = 1; i <= theShapeIDs->Length(); ++i )
1929 anArray->SetValue(1, theShapeIDs->Value( i ));
1930 Handle(GEOM_Object) anObj = GetEngine()->AddSubShape(theShape, anArray);
1931 aSeq->Append( anObj );
1933 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
1934 if ( i != 1 ) theShapeEntries += ",";
1935 theShapeEntries += anEntry;
1941 //=======================================================================
1942 //function : getShapesOnSurface
1944 * \brief Find subshapes complying with given status about surface
1945 * \param theSurface - the surface to check state of subshapes against
1946 * \param theShape - the shape to explore
1947 * \param theShapeType - type of subshape of theShape
1948 * \param theState - required state
1949 * \param theShapeEntries - outgoing entries like "entry1, entry2, ..."
1950 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1952 //=======================================================================
1953 Handle(TColStd_HSequenceOfTransient)
1954 GEOMImpl_IShapesOperations::getShapesOnSurface(const Handle(Geom_Surface)& theSurface,
1955 const Handle(GEOM_Object)& theShape,
1956 TopAbs_ShapeEnum theShapeType,
1957 GEOMAlgo_State theState,
1958 TCollection_AsciiString & theShapeEntries)
1960 // Find subshapes ids
1961 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
1962 getShapesOnSurfaceIDs (theSurface, theShape->GetValue(), theShapeType, theState);
1963 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
1966 return getObjectsShapesOn( theShape, aSeqOfIDs, theShapeEntries );
1969 //=============================================================================
1973 //=============================================================================
1974 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnPlane
1975 (const Handle(GEOM_Object)& theShape,
1976 const Standard_Integer theShapeType,
1977 const Handle(GEOM_Object)& theAx1,
1978 const GEOMAlgo_State theState)
1982 if (theShape.IsNull() || theAx1.IsNull()) return NULL;
1984 TopoDS_Shape aShape = theShape->GetValue();
1985 TopoDS_Shape anAx1 = theAx1->GetValue();
1987 if (aShape.IsNull() || anAx1.IsNull()) return NULL;
1989 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
1990 if ( !checkTypeShapesOn( theShapeType ))
1994 Handle(Geom_Surface) aPlane = makePlane( anAx1 );
1995 if ( aPlane.IsNull() )
1999 TCollection_AsciiString anAsciiList;
2000 Handle(TColStd_HSequenceOfTransient) aSeq;
2001 aSeq = getShapesOnSurface( aPlane, theShape, aShapeType, theState, anAsciiList );
2002 if ( aSeq.IsNull() || aSeq->Length() == 0 )
2005 // Make a Python command
2007 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2008 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2010 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
2011 << "] = geompy.GetShapesOnPlane(" << theShape << ", "
2012 << aShapeType << ", " << theAx1 << ", " << theState << ")";
2018 //=============================================================================
2020 * GetShapesOnPlaneWithLocation
2022 //=============================================================================
2023 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnPlaneWithLocation
2024 (const Handle(GEOM_Object)& theShape,
2025 const Standard_Integer theShapeType,
2026 const Handle(GEOM_Object)& theAx1,
2027 const Handle(GEOM_Object)& thePnt,
2028 const GEOMAlgo_State theState)
2032 if (theShape.IsNull() || theAx1.IsNull() || thePnt.IsNull()) return NULL;
2034 TopoDS_Shape aShape = theShape->GetValue();
2035 TopoDS_Shape anAx1 = theAx1->GetValue();
2036 TopoDS_Shape anPnt = thePnt->GetValue();
2038 if (aShape.IsNull() || anAx1.IsNull() || anPnt.IsNull()) return NULL;
2040 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2041 if ( !checkTypeShapesOn( theShapeType ))
2045 if ( anAx1.ShapeType() != TopAbs_EDGE || anPnt.ShapeType() != TopAbs_VERTEX ) return NULL;
2046 TopoDS_Vertex V1, V2, V3;
2047 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
2048 TopExp::Vertices(anEdge, V1, V2, Standard_True);
2050 if (V1.IsNull() || V2.IsNull()) {
2051 SetErrorCode("Bad edge given for the plane normal vector");
2054 V3 = TopoDS::Vertex(anPnt);
2057 SetErrorCode("Bad vertex given for the plane location");
2060 gp_Pnt aLoc = BRep_Tool::Pnt(V3);
2061 gp_Vec aVec(BRep_Tool::Pnt(V1),BRep_Tool::Pnt(V2));
2063 if (aVec.Magnitude() < Precision::Confusion()) {
2064 SetErrorCode("Vector with null magnitude given");
2067 Handle(Geom_Surface) aPlane = new Geom_Plane(aLoc, aVec);
2069 if ( aPlane.IsNull() )
2073 TCollection_AsciiString anAsciiList;
2074 Handle(TColStd_HSequenceOfTransient) aSeq;
2075 aSeq = getShapesOnSurface( aPlane, theShape, aShapeType, theState, anAsciiList );
2076 if ( aSeq.IsNull() || aSeq->Length() == 0 )
2079 // Make a Python command
2081 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2082 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2084 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
2085 << "] = geompy.GetShapesOnPlaneWithLocation(" << theShape << ", "
2086 << aShapeType << ", " << theAx1 << ", "<< thePnt <<", " << theState << ")";
2092 //=============================================================================
2094 * GetShapesOnCylinder
2096 //=============================================================================
2097 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnCylinder
2098 (const Handle(GEOM_Object)& theShape,
2099 const Standard_Integer theShapeType,
2100 const Handle(GEOM_Object)& theAxis,
2101 const Standard_Real theRadius,
2102 const GEOMAlgo_State theState)
2106 if (theShape.IsNull() || theAxis.IsNull()) return NULL;
2108 TopoDS_Shape aShape = theShape->GetValue();
2109 TopoDS_Shape anAxis = theAxis->GetValue();
2111 if (aShape.IsNull() || anAxis.IsNull()) return NULL;
2113 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2114 if ( !checkTypeShapesOn( aShapeType ))
2117 // Create a cylinder surface
2118 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
2119 if ( aCylinder.IsNull() )
2123 TCollection_AsciiString anAsciiList;
2124 Handle(TColStd_HSequenceOfTransient) aSeq;
2125 aSeq = getShapesOnSurface( aCylinder, theShape, aShapeType, theState, anAsciiList );
2126 if ( aSeq.IsNull() || aSeq->Length() == 0 )
2129 // Make a Python command
2131 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2132 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2134 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
2135 << "] = geompy.GetShapesOnCylinder(" << theShape << ", " << aShapeType
2136 << ", " << theAxis << ", " << theRadius << ", " << theState << ")";
2142 //=============================================================================
2146 //=============================================================================
2147 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnSphere
2148 (const Handle(GEOM_Object)& theShape,
2149 const Standard_Integer theShapeType,
2150 const Handle(GEOM_Object)& theCenter,
2151 const Standard_Real theRadius,
2152 const GEOMAlgo_State theState)
2156 if (theShape.IsNull() || theCenter.IsNull()) return NULL;
2158 TopoDS_Shape aShape = theShape->GetValue();
2159 TopoDS_Shape aCenter = theCenter->GetValue();
2161 if (aShape.IsNull() || aCenter.IsNull()) return NULL;
2163 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2164 if ( !checkTypeShapesOn( aShapeType ))
2167 // Center of the sphere
2168 if (aCenter.ShapeType() != TopAbs_VERTEX) return NULL;
2169 gp_Pnt aLoc = BRep_Tool::Pnt(TopoDS::Vertex(aCenter));
2171 gp_Ax3 anAx3 (aLoc, gp::DZ());
2172 Handle(Geom_SphericalSurface) aSphere =
2173 new Geom_SphericalSurface(anAx3, theRadius);
2176 TCollection_AsciiString anAsciiList;
2177 Handle(TColStd_HSequenceOfTransient) aSeq;
2178 aSeq = getShapesOnSurface( aSphere, theShape, aShapeType, theState, anAsciiList );
2179 if ( aSeq.IsNull() || aSeq->Length() == 0 )
2182 // Make a Python command
2184 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2185 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2187 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
2188 << "] = geompy.GetShapesOnSphere(" << theShape << ", " << aShapeType
2189 << ", " << theCenter << ", " << theRadius << ", " << theState << ")";
2195 //=============================================================================
2197 * GetShapesOnPlaneIDs
2199 //=============================================================================
2200 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnPlaneIDs
2201 (const Handle(GEOM_Object)& theShape,
2202 const Standard_Integer theShapeType,
2203 const Handle(GEOM_Object)& theAx1,
2204 const GEOMAlgo_State theState)
2208 if (theShape.IsNull() || theAx1.IsNull()) return NULL;
2210 TopoDS_Shape aShape = theShape->GetValue();
2211 TopoDS_Shape anAx1 = theAx1->GetValue();
2213 if (aShape.IsNull() || anAx1.IsNull()) return NULL;
2215 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2216 if ( !checkTypeShapesOn( aShapeType ))
2220 Handle(Geom_Surface) aPlane = makePlane( anAx1 );
2221 if ( aPlane.IsNull() )
2225 Handle(TColStd_HSequenceOfInteger) aSeq;
2226 aSeq = getShapesOnSurfaceIDs( aPlane, aShape, aShapeType, theState );
2228 // The GetShapesOnPlaneIDs() doesn't change object so no new function is required.
2229 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAx1)->GetLastFunction();
2231 // Make a Python command
2232 GEOM::TPythonDump(aFunction, /*append=*/true)
2233 << "listShapesOnPlane = geompy.GetShapesOnPlaneIDs"
2234 << "(" << theShape << "," << aShapeType << "," << theAx1 << "," << theState << ")";
2240 //=============================================================================
2242 * GetShapesOnPlaneWithLocationIDs
2244 //=============================================================================
2245 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnPlaneWithLocationIDs
2246 (const Handle(GEOM_Object)& theShape,
2247 const Standard_Integer theShapeType,
2248 const Handle(GEOM_Object)& theAx1,
2249 const Handle(GEOM_Object)& thePnt,
2250 const GEOMAlgo_State theState)
2254 if (theShape.IsNull() || theAx1.IsNull() || thePnt.IsNull()) return NULL;
2256 TopoDS_Shape aShape = theShape->GetValue();
2257 TopoDS_Shape anAx1 = theAx1->GetValue();
2258 TopoDS_Shape anPnt = thePnt->GetValue();
2260 if (aShape.IsNull() || anAx1.IsNull() || anPnt.IsNull()) return NULL;
2262 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2263 if ( !checkTypeShapesOn( aShapeType ))
2267 if (anAx1.ShapeType() != TopAbs_EDGE || anPnt.ShapeType() != TopAbs_VERTEX) return NULL;
2268 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
2269 TopoDS_Vertex V1, V2, V3;
2270 TopExp::Vertices(anEdge, V1, V2, Standard_True);
2271 if (V1.IsNull() || V2.IsNull()) {
2272 SetErrorCode("Bad edge given for the plane normal vector");
2275 V3 = TopoDS::Vertex(anPnt);
2277 SetErrorCode("Bad vertex given for the plane location");
2280 gp_Pnt aLoc = BRep_Tool::Pnt(V3);
2281 gp_Vec aVec(BRep_Tool::Pnt(V1),BRep_Tool::Pnt(V2));
2282 if (aVec.Magnitude() < Precision::Confusion()) {
2283 SetErrorCode("Vector with null magnitude given");
2287 Handle(Geom_Surface) aPlane = new Geom_Plane(aLoc, aVec);
2288 if ( aPlane.IsNull() )
2292 Handle(TColStd_HSequenceOfInteger) aSeq;
2293 aSeq = getShapesOnSurfaceIDs( aPlane, aShape, aShapeType, theState );
2295 // The GetShapesOnPlaneIDs() doesn't change object so no new function is required.
2296 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAx1)->GetLastFunction();
2298 // Make a Python command
2299 GEOM::TPythonDump(aFunction, /*append=*/true)
2300 << "listShapesOnPlane = geompy.GetShapesOnPlaneWithLocationIDs"
2301 << "(" << theShape << ", " << aShapeType << ", " << theAx1 << ", "<< thePnt << ", " << theState << ")";
2307 //=============================================================================
2309 * GetShapesOnCylinderIDs
2311 //=============================================================================
2312 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnCylinderIDs
2313 (const Handle(GEOM_Object)& theShape,
2314 const Standard_Integer theShapeType,
2315 const Handle(GEOM_Object)& theAxis,
2316 const Standard_Real theRadius,
2317 const GEOMAlgo_State theState)
2321 if (theShape.IsNull() || theAxis.IsNull()) return NULL;
2323 TopoDS_Shape aShape = theShape->GetValue();
2324 TopoDS_Shape anAxis = theAxis->GetValue();
2326 if (aShape.IsNull() || anAxis.IsNull()) return NULL;
2328 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2329 if ( !checkTypeShapesOn( aShapeType ))
2332 // Create a cylinder surface
2333 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
2334 if ( aCylinder.IsNull() )
2338 Handle(TColStd_HSequenceOfInteger) aSeq;
2339 aSeq = getShapesOnSurfaceIDs( aCylinder, aShape, aShapeType, theState );
2341 // The GetShapesOnCylinder() doesn't change object so no new function is required.
2342 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAxis)->GetLastFunction();
2344 // Make a Python command
2345 GEOM::TPythonDump(aFunction, /*append=*/true)
2346 << "listShapesOnCylinder = geompy.GetShapesOnCylinderIDs"
2347 << "(" << theShape << ", " << aShapeType << ", " << theAxis << ", "
2348 << theRadius << ", " << theState << ")";
2354 //=============================================================================
2356 * GetShapesOnSphereIDs
2358 //=============================================================================
2359 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnSphereIDs
2360 (const Handle(GEOM_Object)& theShape,
2361 const Standard_Integer theShapeType,
2362 const Handle(GEOM_Object)& theCenter,
2363 const Standard_Real theRadius,
2364 const GEOMAlgo_State theState)
2368 if (theShape.IsNull() || theCenter.IsNull()) return NULL;
2370 TopoDS_Shape aShape = theShape->GetValue();
2371 TopoDS_Shape aCenter = theCenter->GetValue();
2373 if (aShape.IsNull() || aCenter.IsNull()) return NULL;
2375 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2376 if ( !checkTypeShapesOn( aShapeType ))
2379 // Center of the sphere
2380 if (aCenter.ShapeType() != TopAbs_VERTEX) return NULL;
2381 gp_Pnt aLoc = BRep_Tool::Pnt(TopoDS::Vertex(aCenter));
2383 gp_Ax3 anAx3 (aLoc, gp::DZ());
2384 Handle(Geom_SphericalSurface) aSphere =
2385 new Geom_SphericalSurface(anAx3, theRadius);
2388 Handle(TColStd_HSequenceOfInteger) aSeq;
2389 aSeq = getShapesOnSurfaceIDs( aSphere, aShape, aShapeType, theState );
2391 // The GetShapesOnSphere() doesn't change object so no new function is required.
2392 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theCenter)->GetLastFunction();
2394 // Make a Python command
2395 GEOM::TPythonDump(aFunction, /*append=*/true)
2396 << "listShapesOnCylinder = geompy.GetShapesOnCylinderIDs"
2397 << "(" << theShape << ", " << aShapeType << ", " << theCenter << ", "
2398 << theRadius << ", " << theState << ")";
2404 //=======================================================================
2405 //function : getShapesOnQuadrangleIDs
2407 * \brief Find IDs of subshapes complying with given status about quadrangle
2408 * \param theShape - the shape to explore
2409 * \param theShapeType - type of subshape of theShape
2410 * \param theTopLeftPoint - top left quadrangle corner
2411 * \param theTopRigthPoint - top right quadrangle corner
2412 * \param theBottomLeftPoint - bottom left quadrangle corner
2413 * \param theBottomRigthPoint - bottom right quadrangle corner
2414 * \param theState - required state
2415 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
2417 //=======================================================================
2418 Handle(TColStd_HSequenceOfInteger)
2419 GEOMImpl_IShapesOperations::getShapesOnQuadrangleIDs (const Handle(GEOM_Object)& theShape,
2420 const Standard_Integer theShapeType,
2421 const Handle(GEOM_Object)& theTopLeftPoint,
2422 const Handle(GEOM_Object)& theTopRigthPoint,
2423 const Handle(GEOM_Object)& theBottomLeftPoint,
2424 const Handle(GEOM_Object)& theBottomRigthPoint,
2425 const GEOMAlgo_State theState)
2429 if ( theShape.IsNull() ||
2430 theTopLeftPoint.IsNull() ||
2431 theTopRigthPoint.IsNull() ||
2432 theBottomLeftPoint.IsNull() ||
2433 theBottomRigthPoint.IsNull() )
2436 TopoDS_Shape aShape = theShape->GetValue();
2437 TopoDS_Shape aTL = theTopLeftPoint->GetValue();
2438 TopoDS_Shape aTR = theTopRigthPoint->GetValue();
2439 TopoDS_Shape aBL = theBottomLeftPoint->GetValue();
2440 TopoDS_Shape aBR = theBottomRigthPoint->GetValue();
2442 if (aShape.IsNull() ||
2447 aTL.ShapeType() != TopAbs_VERTEX ||
2448 aTR.ShapeType() != TopAbs_VERTEX ||
2449 aBL.ShapeType() != TopAbs_VERTEX ||
2450 aBR.ShapeType() != TopAbs_VERTEX )
2453 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2454 if ( !checkTypeShapesOn( aShapeType ))
2457 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
2459 // Check presence of triangulation, build if need
2460 if (!CheckTriangulation(aShape)) {
2461 SetErrorCode("Cannot build triangulation on the shape");
2466 gp_Pnt aPntTL = BRep_Tool::Pnt(TopoDS::Vertex(aTL));
2467 gp_Pnt aPntTR = BRep_Tool::Pnt(TopoDS::Vertex(aTR));
2468 gp_Pnt aPntBL = BRep_Tool::Pnt(TopoDS::Vertex(aBL));
2469 gp_Pnt aPntBR = BRep_Tool::Pnt(TopoDS::Vertex(aBR));
2471 GEOMAlgo_FinderShapeOnQuad aFinder( aPntTL, aPntTR, aPntBL, aPntBR );
2472 Standard_Real aTol = 0.0001; // default value
2474 aFinder.SetShape(aShape);
2475 aFinder.SetTolerance(aTol);
2476 //aFinder.SetSurface(theSurface);
2477 aFinder.SetShapeType(aShapeType);
2478 aFinder.SetState(theState);
2480 // Sets the minimal number of inner points for the faces that do not have own
2481 // inner points at all (for e.g. rectangular planar faces have just 2 triangles).
2483 aFinder.SetNbPntsMin(3);
2484 // Sets the maximal number of inner points for edges or faces.
2485 // It is usefull for the cases when this number is very big (e.g =2000) to improve
2486 // the performance. If this value =0, all inner points will be taken into account.
2488 aFinder.SetNbPntsMax(100);
2492 // Interprete results
2493 Standard_Integer iErr = aFinder.ErrorStatus();
2494 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
2496 MESSAGE(" iErr : " << iErr);
2497 TCollection_AsciiString aMsg (" iErr : ");
2498 aMsg += TCollection_AsciiString(iErr);
2502 Standard_Integer iWrn = aFinder.WarningStatus();
2503 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
2505 MESSAGE(" *** iWrn : " << iWrn);
2508 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
2510 if (listSS.Extent() < 1) {
2511 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
2512 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
2516 // Fill sequence of object IDs
2517 aSeqOfIDs = new TColStd_HSequenceOfInteger;
2519 TopTools_IndexedMapOfShape anIndices;
2520 TopExp::MapShapes(aShape, anIndices);
2522 TopTools_ListIteratorOfListOfShape itSub (listSS);
2523 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
2524 int id = anIndices.FindIndex(itSub.Value());
2525 aSeqOfIDs->Append(id);
2530 //=======================================================================
2531 //function : GetShapesOnQuadrangle
2533 * \brief Find subshapes complying with given status about quadrangle
2534 * \param theShape - the shape to explore
2535 * \param theShapeType - type of subshape of theShape
2536 * \param theTopLeftPoint - top left quadrangle corner
2537 * \param theTopRigthPoint - top right quadrangle corner
2538 * \param theBottomLeftPoint - bottom left quadrangle corner
2539 * \param theBottomRigthPoint - bottom right quadrangle corner
2540 * \param theState - required state
2541 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
2543 //=======================================================================
2544 Handle(TColStd_HSequenceOfTransient)
2545 GEOMImpl_IShapesOperations::GetShapesOnQuadrangle (const Handle(GEOM_Object)& theShape,
2546 const Standard_Integer theShapeType,
2547 const Handle(GEOM_Object)& theTopLeftPoint,
2548 const Handle(GEOM_Object)& theTopRigthPoint,
2549 const Handle(GEOM_Object)& theBottomLeftPoint,
2550 const Handle(GEOM_Object)& theBottomRigthPoint,
2551 const GEOMAlgo_State theState)
2554 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2555 getShapesOnQuadrangleIDs( theShape,
2560 theBottomRigthPoint,
2562 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->IsEmpty() )
2565 // Find objects by indices
2566 TCollection_AsciiString anAsciiList;
2567 Handle(TColStd_HSequenceOfTransient) aSeq;
2568 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
2569 if ( aSeq.IsNull() || aSeq->IsEmpty() )
2572 // Make a Python command
2574 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2575 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2577 GEOM::TPythonDump(aFunction)
2578 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnQuadrangle("
2580 << TopAbs_ShapeEnum(theShapeType) << ", "
2581 << theTopLeftPoint << ", "
2582 << theTopRigthPoint << ", "
2583 << theBottomLeftPoint << ", "
2584 << theBottomRigthPoint << ", "
2591 //=======================================================================
2592 //function : GetShapesOnQuadrangleIDs
2594 * \brief Find IDs of subshapes complying with given status about quadrangle
2595 * \param theShape - the shape to explore
2596 * \param theShapeType - type of subshape of theShape
2597 * \param theTopLeftPoint - top left quadrangle corner
2598 * \param theTopRigthPoint - top right quadrangle corner
2599 * \param theBottomLeftPoint - bottom left quadrangle corner
2600 * \param theBottomRigthPoint - bottom right quadrangle corner
2601 * \param theState - required state
2602 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
2604 //=======================================================================
2605 Handle(TColStd_HSequenceOfInteger)
2606 GEOMImpl_IShapesOperations::GetShapesOnQuadrangleIDs (const Handle(GEOM_Object)& theShape,
2607 const Standard_Integer theShapeType,
2608 const Handle(GEOM_Object)& theTopLeftPoint,
2609 const Handle(GEOM_Object)& theTopRigthPoint,
2610 const Handle(GEOM_Object)& theBottomLeftPoint,
2611 const Handle(GEOM_Object)& theBottomRigthPoint,
2612 const GEOMAlgo_State theState)
2615 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2616 getShapesOnQuadrangleIDs( theShape,
2621 theBottomRigthPoint,
2623 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->IsEmpty() )
2626 // Make a Python command
2628 // The GetShapesOnCylinder() doesn't change object so no new function is required.
2629 Handle(GEOM_Object) lastObj = GEOM::GetCreatedLast(theShape,theTopLeftPoint);
2630 lastObj = GEOM::GetCreatedLast(lastObj,theTopRigthPoint);
2631 lastObj = GEOM::GetCreatedLast(lastObj,theBottomRigthPoint);
2632 lastObj = GEOM::GetCreatedLast(lastObj,theBottomLeftPoint);
2633 Handle(GEOM_Function) aFunction = lastObj->GetLastFunction();
2635 GEOM::TPythonDump(aFunction, /*append=*/true)
2636 << "listShapesOnQuadrangle = geompy.GetShapesOnQuadrangleIDs("
2638 << TopAbs_ShapeEnum(theShapeType) << ", "
2639 << theTopLeftPoint << ", "
2640 << theTopRigthPoint << ", "
2641 << theBottomLeftPoint << ", "
2642 << theBottomRigthPoint << ", "
2649 //=============================================================================
2653 //=============================================================================
2654 static bool GetInPlaceOfShape (const Handle(GEOM_Function)& theWhereFunction,
2655 const TopTools_IndexedMapOfShape& theWhereIndices,
2656 const TopoDS_Shape& theWhat,
2657 TColStd_ListOfInteger& theModifiedList)
2659 if (theWhereFunction.IsNull() || theWhat.IsNull()) return false;
2661 if (theWhereIndices.Contains(theWhat)) {
2662 // entity was not changed by the operation
2663 Standard_Integer aWhatIndex = theWhereIndices.FindIndex(theWhat);
2664 theModifiedList.Append(aWhatIndex);
2668 // try to find in history
2669 TDF_Label aHistoryLabel = theWhereFunction->GetHistoryEntry(Standard_False);
2671 // search in history for all argument shapes
2672 Standard_Boolean isFound = Standard_False;
2673 Standard_Boolean isGood = Standard_False;
2675 TDF_LabelSequence aLabelSeq;
2676 theWhereFunction->GetDependency(aLabelSeq);
2677 Standard_Integer nbArg = aLabelSeq.Length();
2679 for (Standard_Integer iarg = 1; iarg <= nbArg && !isFound; iarg++) {
2681 TDF_Label anArgumentRefLabel = aLabelSeq.Value(iarg);
2683 Handle(GEOM_Object) anArgumentObject = GEOM_Object::GetReferencedObject(anArgumentRefLabel);
2684 TopoDS_Shape anArgumentShape = anArgumentObject->GetValue();
2686 TopTools_IndexedMapOfShape anArgumentIndices;
2687 TopExp::MapShapes(anArgumentShape, anArgumentIndices);
2689 if (anArgumentIndices.Contains(theWhat)) {
2690 isFound = Standard_True;
2691 Standard_Integer aWhatIndex = anArgumentIndices.FindIndex(theWhat);
2693 // Find corresponding label in history
2694 TDF_Label anArgumentHistoryLabel =
2695 theWhereFunction->GetArgumentHistoryEntry(anArgumentRefLabel, Standard_False);
2696 if (anArgumentHistoryLabel.IsNull()) {
2697 // Lost History of operation argument. Possibly, all its entities was removed.
2698 isGood = Standard_True;
2701 TDF_Label aWhatHistoryLabel = anArgumentHistoryLabel.FindChild(aWhatIndex, Standard_False);
2703 if (aWhatHistoryLabel.IsNull()) {
2704 // Removed entity ? Compound ? Compsolid ? Shell ? Wire
2705 isGood = Standard_False;
2707 Handle(TDataStd_IntegerArray) anIntegerArray;
2708 if (!aWhatHistoryLabel.FindAttribute(TDataStd_IntegerArray::GetID(), anIntegerArray)) {
2709 //Error: Empty modifications history for the sought shape.
2710 isGood = Standard_False;
2713 isGood = Standard_True;
2714 Standard_Integer imod, aModifLen = anIntegerArray->Array()->Length();
2715 for (imod = 1; imod <= aModifLen; imod++) {
2716 theModifiedList.Append(anIntegerArray->Array()->Value(imod));
2727 // try compound/compsolid/shell/wire element by element
2728 bool isFoundAny = false;
2729 TopTools_MapOfShape mapShape;
2731 if (theWhat.ShapeType() == TopAbs_COMPOUND ||
2732 theWhat.ShapeType() == TopAbs_COMPSOLID) {
2733 // recursive processing of compound/compsolid
2734 TopoDS_Iterator anIt (theWhat, Standard_True, Standard_True);
2735 for (; anIt.More(); anIt.Next()) {
2736 if (mapShape.Add(anIt.Value())) {
2737 TopoDS_Shape curWhat = anIt.Value();
2738 isFoundAny = GetInPlaceOfShape(theWhereFunction, theWhereIndices, curWhat, theModifiedList);
2739 if (isFoundAny) isFound = Standard_True;
2743 else if (theWhat.ShapeType() == TopAbs_SHELL) {
2744 // try to replace a shell by its faces images
2745 TopExp_Explorer anExp (theWhat, TopAbs_FACE);
2746 for (; anExp.More(); anExp.Next()) {
2747 if (mapShape.Add(anExp.Current())) {
2748 TopoDS_Shape curWhat = anExp.Current();
2749 isFoundAny = GetInPlaceOfShape(theWhereFunction, theWhereIndices, curWhat, theModifiedList);
2750 if (isFoundAny) isFound = Standard_True;
2754 else if (theWhat.ShapeType() == TopAbs_WIRE) {
2755 // try to replace a wire by its edges images
2756 TopExp_Explorer anExp (theWhat, TopAbs_EDGE);
2757 for (; anExp.More(); anExp.Next()) {
2758 if (mapShape.Add(anExp.Current())) {
2759 TopoDS_Shape curWhat = anExp.Current();
2760 isFoundAny = GetInPlaceOfShape(theWhereFunction, theWhereIndices, curWhat, theModifiedList);
2761 if (isFoundAny) isFound = Standard_True;
2773 //=============================================================================
2775 * GetShapeProperties
2777 //=============================================================================
2778 void GEOMImpl_IShapesOperations::GetShapeProperties( const TopoDS_Shape aShape, Standard_Real tab[],
2781 GProp_GProps theProps;
2783 TopoDS_Shape aPntShape;
2784 Standard_Real aShapeSize;
2786 if (aShape.ShapeType() == TopAbs_EDGE) BRepGProp::LinearProperties(aShape, theProps);
2787 else if (aShape.ShapeType() == TopAbs_FACE) BRepGProp::SurfaceProperties(aShape, theProps);
2788 else BRepGProp::VolumeProperties(aShape, theProps);
2790 aCenterMass = theProps.CentreOfMass();
2791 aShapeSize = theProps.Mass();
2793 aPntShape = BRepBuilderAPI_MakeVertex(aCenterMass).Shape();
2794 aVertex = BRep_Tool::Pnt( TopoDS::Vertex( aPntShape ) );
2795 tab[0] = aVertex.X();
2796 tab[1] = aVertex.Y();
2797 tab[2] = aVertex.Z();
2798 tab[3] = aShapeSize;
2802 //=============================================================================
2806 //=============================================================================
2807 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlace (Handle(GEOM_Object) theShapeWhere,
2808 Handle(GEOM_Object) theShapeWhat)
2812 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
2814 TopoDS_Shape aWhere = theShapeWhere->GetValue();
2815 TopoDS_Shape aWhat = theShapeWhat->GetValue();
2816 TopoDS_Shape aPntShape;
2817 TopoDS_Vertex aVertex;
2819 if (aWhere.IsNull() || aWhat.IsNull()) {
2820 SetErrorCode("Error: aWhere and aWhat TopoDS_Shape are Null.");
2824 Handle(GEOM_Function) aWhereFunction = theShapeWhere->GetLastFunction();
2825 if (aWhereFunction.IsNull()) {
2826 SetErrorCode("Error: aWhereFunction is Null.");
2830 TopTools_IndexedMapOfShape aWhereIndices;
2831 TopExp::MapShapes(aWhere, aWhereIndices);
2833 TColStd_ListOfInteger aModifiedList;
2834 Standard_Integer aWhereIndex;
2835 Handle(TColStd_HArray1OfInteger) aModifiedArray;
2836 Handle(GEOM_Object) aResult;
2838 bool isFound = false;
2839 Standard_Integer iType = TopAbs_SOLID;
2840 Standard_Integer compType = TopAbs_SOLID;
2841 Standard_Real aWhat_Mass = 0., aWhere_Mass = 0.;
2842 Standard_Real tab_aWhat[4], tab_aWhere[4];
2843 Standard_Real dl_l = 1e-3;
2844 Standard_Real min_l, Tol_1D, Tol_2D, Tol_3D, Tol_Mass;
2845 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
2846 Bnd_Box BoundingBox;
2847 gp_Pnt aPnt, aPnt_aWhat, tab_Pnt[2];
2848 GProp_GProps aProps;
2850 // Find the iType of the aWhat shape
2851 if ( aWhat.ShapeType() == TopAbs_EDGE || aWhat.ShapeType() == TopAbs_WIRE ) iType = TopAbs_EDGE;
2852 else if ( aWhat.ShapeType() == TopAbs_FACE || aWhat.ShapeType() == TopAbs_SHELL ) iType = TopAbs_FACE;
2853 else if ( aWhat.ShapeType() == TopAbs_SOLID || aWhat.ShapeType() == TopAbs_COMPSOLID ) iType = TopAbs_SOLID;
2854 else if ( aWhat.ShapeType() == TopAbs_COMPOUND ) {
2855 // Only the iType of the first shape in the compound is taken into account
2856 TopoDS_Iterator It (aWhat, Standard_True, Standard_True);
2857 compType = It.Value().ShapeType();
2858 if ( compType == TopAbs_EDGE || compType == TopAbs_WIRE ) iType = TopAbs_EDGE;
2859 else if ( compType == TopAbs_FACE || compType == TopAbs_SHELL) iType = TopAbs_FACE;
2860 else if ( compType == TopAbs_SOLID || compType == TopAbs_COMPSOLID) iType = TopAbs_SOLID;
2863 SetErrorCode("Error: An attempt to extract a shape of not supported type.");
2867 TopExp_Explorer Exp_aWhat( aWhat, TopAbs_ShapeEnum( iType ) );
2868 TopExp_Explorer Exp_aWhere( aWhere, TopAbs_ShapeEnum( iType ) );
2869 TopExp_Explorer Exp_Edge( aWhere, TopAbs_EDGE );
2871 // Find the shortest edge in theShapeWhere shape
2872 BRepBndLib::Add(aWhere, BoundingBox);
2873 BoundingBox.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
2874 min_l = fabs(aXmax - aXmin);
2875 if( min_l < fabs(aYmax - aYmin) ) min_l = fabs(aYmax - aYmin);
2876 if( min_l < fabs(aZmax - aZmin) ) min_l = fabs(aZmax - aZmin);
2878 for ( Standard_Integer nbEdge = 0; Exp_Edge.More(); Exp_Edge.Next(), nbEdge++ ) {
2879 TopExp_Explorer Exp_Vertex( Exp_Edge.Current(), TopAbs_VERTEX);
2880 for ( Standard_Integer nbVertex = 0; Exp_Vertex.More(); Exp_Vertex.Next(), nbVertex++ ) {
2881 aPnt = BRep_Tool::Pnt( TopoDS::Vertex( Exp_Vertex.Current() ) );
2882 tab_Pnt[nbVertex] = aPnt;
2884 if ( ! tab_Pnt[0].IsEqual(tab_Pnt[1], dl_l) ) {
2885 BRepGProp::LinearProperties(Exp_Edge.Current(), aProps);
2886 if ( aProps.Mass() < min_l ) min_l = aProps.Mass();
2890 // Compute tolerances
2891 Tol_1D = dl_l * min_l;
2892 Tol_2D = dl_l * ( min_l * min_l) * ( 2. + dl_l);
2893 Tol_3D = dl_l * ( min_l * min_l * min_l ) * ( 3. + (3 * dl_l) + (dl_l * dl_l) );
2895 if (Tol_1D < Precision::Confusion()) Tol_1D = Precision::Confusion();
2896 if (Tol_2D < Precision::Confusion()) Tol_2D = Precision::Confusion();
2897 if (Tol_3D < Precision::Confusion()) Tol_3D = Precision::Confusion();
2900 if ( iType == TopAbs_EDGE ) Tol_Mass = Tol_1D;
2901 else if ( iType == TopAbs_FACE ) Tol_Mass = Tol_2D;
2903 // Compute the ShapeWhat Mass
2904 for ( ; Exp_aWhat.More(); Exp_aWhat.Next() ) {
2905 if ( iType == TopAbs_EDGE ) BRepGProp::LinearProperties(Exp_aWhat.Current(), aProps);
2906 else if ( iType == TopAbs_FACE ) BRepGProp::SurfaceProperties(Exp_aWhat.Current(), aProps);
2907 else BRepGProp::VolumeProperties(Exp_aWhat.Current(), aProps);
2908 aWhat_Mass += aProps.Mass();
2911 // Searching for the sub-shapes inside the ShapeWhere shape
2912 TopTools_MapOfShape map_aWhere;
2913 for ( Exp_aWhere.ReInit(); Exp_aWhere.More(); Exp_aWhere.Next() ) {
2914 if (!map_aWhere.Add(Exp_aWhere.Current()))
2915 continue; // skip repeated shape to avoid mass addition
2916 GetShapeProperties( Exp_aWhere.Current(), tab_aWhere, aPnt );
2917 for ( Exp_aWhat.ReInit(); Exp_aWhat.More(); Exp_aWhat.Next() ) {
2918 GetShapeProperties( Exp_aWhat.Current(), tab_aWhat, aPnt_aWhat );
2919 if ( fabs(tab_aWhat[3] - tab_aWhere[3]) <= Tol_Mass && aPnt_aWhat.Distance(aPnt) <= Tol_1D )
2922 if ( (tab_aWhat[3] - tab_aWhere[3]) > Tol_Mass ) {
2923 aPntShape = BRepBuilderAPI_MakeVertex( aPnt ).Shape();
2924 aVertex = TopoDS::Vertex( aPntShape );
2925 BRepExtrema_DistShapeShape aWhereDistance ( aVertex, Exp_aWhere.Current() );
2926 BRepExtrema_DistShapeShape aWhatDistance ( aVertex, Exp_aWhat.Current() );
2927 if ( fabs(aWhereDistance.Value() - aWhatDistance.Value()) <= Tol_1D )
2932 aWhereIndex = aWhereIndices.FindIndex(Exp_aWhere.Current());
2933 aModifiedList.Append(aWhereIndex);
2934 aWhere_Mass += tab_aWhere[3];
2939 if ( fabs( aWhat_Mass - aWhere_Mass ) <= Tol_Mass ) break;
2942 if (aModifiedList.Extent() == 0) { // Not found any Results
2943 SetErrorCode(NOT_FOUND_ANY);
2947 aModifiedArray = new TColStd_HArray1OfInteger (1, aModifiedList.Extent());
2948 TColStd_ListIteratorOfListOfInteger anIterModif (aModifiedList);
2949 for (Standard_Integer imod = 1; anIterModif.More(); anIterModif.Next(), imod++)
2950 aModifiedArray->SetValue(imod, anIterModif.Value());
2953 aResult = GetEngine()->AddSubShape(theShapeWhere, aModifiedArray);
2954 if (aResult.IsNull()) {
2955 SetErrorCode("Error in algorithm: result found, but cannot be returned.");
2959 if (aModifiedArray->Length() > 1) {
2961 aResult->SetType(GEOM_GROUP);
2963 //Set a sub shape type
2964 TopoDS_Shape aFirstFound = aWhereIndices.FindKey(aModifiedArray->Value(1));
2965 TopAbs_ShapeEnum aShapeType = aFirstFound.ShapeType();
2967 TDF_Label aFreeLabel = aResult->GetFreeLabel();
2968 TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aShapeType);
2971 //Make a Python command
2972 Handle(GEOM_Function) aFunction = aResult->GetFunction(1);
2974 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetInPlace("
2975 << theShapeWhere << ", " << theShapeWhat << ")";
2981 //=======================================================================
2982 //function : GetInPlaceByHistory
2984 //=======================================================================
2985 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlaceByHistory
2986 (Handle(GEOM_Object) theShapeWhere,
2987 Handle(GEOM_Object) theShapeWhat)
2991 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
2993 TopoDS_Shape aWhere = theShapeWhere->GetValue();
2994 TopoDS_Shape aWhat = theShapeWhat->GetValue();
2996 if (aWhere.IsNull() || aWhat.IsNull()) return NULL;
2998 Handle(GEOM_Function) aWhereFunction = theShapeWhere->GetLastFunction();
2999 if (aWhereFunction.IsNull()) return NULL;
3001 //Fill array of indices
3002 TopTools_IndexedMapOfShape aWhereIndices;
3003 TopExp::MapShapes(aWhere, aWhereIndices);
3006 TColStd_ListOfInteger aModifiedList;
3007 bool isFound = GetInPlaceOfShape(aWhereFunction, aWhereIndices, aWhat, aModifiedList);
3009 if (!isFound || aModifiedList.Extent() < 1) {
3010 SetErrorCode("Error: No history found for the sought shape or its sub-shapes.");
3014 Handle(TColStd_HArray1OfInteger) aModifiedArray =
3015 new TColStd_HArray1OfInteger (1, aModifiedList.Extent());
3016 TColStd_ListIteratorOfListOfInteger anIterModif (aModifiedList);
3017 for (Standard_Integer imod = 1; anIterModif.More(); anIterModif.Next(), imod++) {
3018 aModifiedArray->SetValue(imod, anIterModif.Value());
3022 Handle(GEOM_Object) aResult = GetEngine()->AddSubShape(theShapeWhere, aModifiedArray);
3023 if (aResult.IsNull()) {
3024 SetErrorCode("Error in algorithm: result found, but cannot be returned.");
3028 if (aModifiedArray->Length() > 1) {
3030 aResult->SetType(GEOM_GROUP);
3032 //Set a sub shape type
3033 TopoDS_Shape aFirstFound = aWhereIndices.FindKey(aModifiedArray->Value(1));
3034 TopAbs_ShapeEnum aShapeType = aFirstFound.ShapeType();
3036 TDF_Label aFreeLabel = aResult->GetFreeLabel();
3037 TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aShapeType);
3040 //Make a Python command
3041 Handle(GEOM_Function) aFunction = aResult->GetFunction(1);
3043 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetInPlaceByHistory("
3044 << theShapeWhere << ", " << theShapeWhat << ")";
3050 //=======================================================================
3051 //function : SortShapes
3053 //=======================================================================
3054 void GEOMImpl_IShapesOperations::SortShapes(TopTools_ListOfShape& SL)
3056 Standard_Integer MaxShapes = SL.Extent();
3057 TopTools_Array1OfShape aShapes (1,MaxShapes);
3058 TColStd_Array1OfInteger OrderInd(1,MaxShapes);
3059 TColStd_Array1OfReal MidXYZ (1,MaxShapes); //X,Y,Z;
3060 TColStd_Array1OfReal Length (1,MaxShapes); //X,Y,Z;
3062 // Computing of CentreOfMass
3063 Standard_Integer Index;
3066 TopTools_ListIteratorOfListOfShape it(SL);
3067 for (Index=1; it.More(); Index++)
3069 TopoDS_Shape S = it.Value();
3070 SL.Remove( it ); // == it.Next()
3072 OrderInd.SetValue (Index, Index);
3073 if (S.ShapeType() == TopAbs_VERTEX)
3075 GPoint = BRep_Tool::Pnt( TopoDS::Vertex( S ));
3076 Length.SetValue( Index, (Standard_Real) S.Orientation());
3080 BRepGProp::LinearProperties (S, GPr);
3081 GPoint = GPr.CentreOfMass();
3082 Length.SetValue( Index, GPr.Mass() );
3084 MidXYZ.SetValue(Index,
3085 GPoint.X()*999 + GPoint.Y()*99 + GPoint.Z()*0.9);
3086 //cout << Index << " L: " << Length(Index) << "CG: " << MidXYZ(Index) << endl;
3090 Standard_Integer aTemp;
3091 Standard_Boolean exchange, Sort = Standard_True;
3092 Standard_Real tol = Precision::Confusion();
3095 Sort = Standard_False;
3096 for (Index=1; Index < MaxShapes; Index++)
3098 exchange = Standard_False;
3099 Standard_Real dMidXYZ = MidXYZ(OrderInd(Index)) - MidXYZ(OrderInd(Index+1));
3100 Standard_Real dLength = Length(OrderInd(Index)) - Length(OrderInd(Index+1));
3101 if ( dMidXYZ >= tol ) {
3102 // cout << "MidXYZ: " << MidXYZ(OrderInd(Index))<< " > " <<MidXYZ(OrderInd(Index+1))
3103 // << " d: " << dMidXYZ << endl;
3104 exchange = Standard_True;
3106 else if ( Abs(dMidXYZ) < tol && dLength >= tol ) {
3107 // cout << "Length: " << Length(OrderInd(Index))<< " > " <<Length(OrderInd(Index+1))
3108 // << " d: " << dLength << endl;
3109 exchange = Standard_True;
3111 else if ( Abs(dMidXYZ) < tol && Abs(dLength) < tol &&
3112 aShapes(OrderInd(Index)).ShapeType() <= TopAbs_FACE) {
3114 // equal values possible on shapes such as two halves of a sphere and
3115 // a membrane inside the sphere
3117 BRepBndLib::Add( aShapes( OrderInd(Index) ), box1 );
3118 if ( box1.IsVoid() ) continue;
3119 BRepBndLib::Add( aShapes( OrderInd(Index+1) ), box2 );
3120 Standard_Real dSquareExtent = box1.SquareExtent() - box2.SquareExtent();
3121 if ( dSquareExtent >= tol ) {
3122 // cout << "SquareExtent: " << box1.SquareExtent()<<" > "<<box2.SquareExtent() << endl;
3123 exchange = Standard_True;
3125 else if ( Abs(dSquareExtent) < tol ) {
3126 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax, val1, val2;
3127 box1.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
3128 val1 = (aXmin+aXmax)*999 + (aYmin+aYmax)*99 + (aZmin+aZmax)*0.9;
3129 box2.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
3130 val2 = (aXmin+aXmax)*999 + (aYmin+aYmax)*99 + (aZmin+aZmax)*0.9;
3131 //exchange = val1 > val2;
3132 if ((val1 - val2) >= tol) {
3133 exchange = Standard_True;
3135 //cout << "box: " << val1<<" > "<<val2 << endl;
3141 // cout << "exchange " << Index << " & " << Index+1 << endl;
3142 aTemp = OrderInd(Index);
3143 OrderInd(Index) = OrderInd(Index+1);
3144 OrderInd(Index+1) = aTemp;
3145 Sort = Standard_True;
3150 for (Index=1; Index <= MaxShapes; Index++)
3151 SL.Append( aShapes( OrderInd(Index) ));
3154 //=======================================================================
3155 //function : CompsolidToCompound
3157 //=======================================================================
3158 TopoDS_Shape GEOMImpl_IShapesOperations::CompsolidToCompound (const TopoDS_Shape& theCompsolid)
3160 if (theCompsolid.ShapeType() != TopAbs_COMPSOLID) {
3161 return theCompsolid;
3164 TopoDS_Compound aCompound;
3166 B.MakeCompound(aCompound);
3168 TopTools_MapOfShape mapShape;
3169 TopoDS_Iterator It (theCompsolid, Standard_True, Standard_True);
3171 for (; It.More(); It.Next()) {
3172 TopoDS_Shape aShape_i = It.Value();
3173 if (mapShape.Add(aShape_i)) {
3174 B.Add(aCompound, aShape_i);
3181 //=======================================================================
3182 //function : CheckTriangulation
3184 //=======================================================================
3185 bool GEOMImpl_IShapesOperations::CheckTriangulation (const TopoDS_Shape& aShape)
3187 bool isTriangulation = true;
3189 TopExp_Explorer exp (aShape, TopAbs_FACE);
3192 TopLoc_Location aTopLoc;
3193 Handle(Poly_Triangulation) aTRF;
3194 aTRF = BRep_Tool::Triangulation(TopoDS::Face(exp.Current()), aTopLoc);
3195 if (aTRF.IsNull()) {
3196 isTriangulation = false;
3199 else // no faces, try edges
3201 TopExp_Explorer expe (aShape, TopAbs_EDGE);
3205 TopLoc_Location aLoc;
3206 Handle(Poly_Polygon3D) aPE = BRep_Tool::Polygon3D(TopoDS::Edge(expe.Current()), aLoc);
3208 isTriangulation = false;
3212 if (!isTriangulation) {
3213 // calculate deflection
3214 Standard_Real aDeviationCoefficient = 0.001;
3217 BRepBndLib::Add(aShape, B);
3218 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
3219 B.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
3221 Standard_Real dx = aXmax - aXmin, dy = aYmax - aYmin, dz = aZmax - aZmin;
3222 Standard_Real aDeflection = Max(Max(dx, dy), dz) * aDeviationCoefficient * 4;
3223 Standard_Real aHLRAngle = 0.349066;
3225 BRepMesh_IncrementalMesh Inc (aShape, aDeflection, Standard_False, aHLRAngle);
3231 #define MAX_TOLERANCE 1.e-7
3233 //=======================================================================
3234 //function : isSameEdge
3235 //purpose : Returns True if two edges coincide
3236 //=======================================================================
3237 static bool isSameEdge(const TopoDS_Edge& theEdge1, const TopoDS_Edge& theEdge2)
3239 TopoDS_Vertex V11, V12, V21, V22;
3240 TopExp::Vertices(theEdge1, V11, V12);
3241 TopExp::Vertices(theEdge2, V21, V22);
3242 gp_Pnt P11 = BRep_Tool::Pnt(V11);
3243 gp_Pnt P12 = BRep_Tool::Pnt(V12);
3244 gp_Pnt P21 = BRep_Tool::Pnt(V21);
3245 gp_Pnt P22 = BRep_Tool::Pnt(V22);
3246 bool coincide = false;
3248 //Check that ends of edges coincide
3249 if(P11.Distance(P21) <= MAX_TOLERANCE) {
3250 if(P12.Distance(P22) <= MAX_TOLERANCE) coincide = true;
3252 else if(P11.Distance(P22) <= MAX_TOLERANCE) {
3253 if(P12.Distance(P21) <= MAX_TOLERANCE) coincide = true;
3256 if(!coincide) return false;
3258 if (BRep_Tool::Degenerated(theEdge1))
3259 if (BRep_Tool::Degenerated(theEdge2)) return true;
3262 if (BRep_Tool::Degenerated(theEdge2)) return false;
3264 double U11, U12, U21, U22;
3265 Handle(Geom_Curve) C1 = BRep_Tool::Curve(theEdge1, U11, U12);
3266 Handle(Geom_Curve) C2 = BRep_Tool::Curve(theEdge2, U21, U22);
3267 if(C1->DynamicType() == C2->DynamicType()) return true;
3269 //Check that both edges has the same geometry
3270 double range = U12-U11;
3271 double U = U11+ range/3.0;
3272 gp_Pnt P1 = C1->Value(U); //Compute a point on one third of the edge's length
3273 U = U11+range*2.0/3.0;
3274 gp_Pnt P2 = C1->Value(U); //Compute a point on two thirds of the edge's length
3276 if(!GeomLib_Tool::Parameter(C2, P1, MAX_TOLERANCE, U) || U < U21 || U > U22)
3279 if(P1.Distance(C2->Value(U)) > MAX_TOLERANCE) return false;
3281 if(!GeomLib_Tool::Parameter(C2, P2, MAX_TOLERANCE, U) || U < U21 || U > U22)
3284 if(P2.Distance(C2->Value(U)) > MAX_TOLERANCE) return false;
3289 #include <TopoDS_TShape.hxx>
3290 //=======================================================================
3291 //function : isSameFace
3292 //purpose : Returns True if two faces coincide
3293 //=======================================================================
3294 static bool isSameFace(const TopoDS_Face& theFace1, const TopoDS_Face& theFace2)
3296 TopExp_Explorer E(theFace1, TopAbs_EDGE);
3297 TopTools_ListOfShape LS1, LS2;
3298 for(; E.More(); E.Next()) LS1.Append(E.Current());
3300 E.Init(theFace2, TopAbs_EDGE);
3301 for(; E.More(); E.Next()) LS2.Append(E.Current());
3303 //Compare the number of edges in the faces
3304 if(LS1.Extent() != LS2.Extent()) return false;
3306 double aMin = RealFirst(), aMax = RealLast();
3307 double xminB1=aMax, yminB1=aMax, zminB1=aMax, xminB2=aMax, yminB2=aMax, zminB2=aMax;
3308 double xmaxB1=aMin, ymaxB1=aMin, zmaxB1=aMin, xmaxB2=aMin, ymaxB2=aMin, zmaxB2=aMin;
3310 for(E.Init(theFace1, TopAbs_VERTEX); E.More(); E.Next()) {
3311 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
3312 if(P.X() < xminB1) xminB1 = P.X();
3313 if(P.Y() < yminB1) yminB1 = P.Y();
3314 if(P.Z() < zminB1) zminB1 = P.Z();
3315 if(P.X() > xmaxB1) xmaxB1 = P.X();
3316 if(P.Y() > ymaxB1) ymaxB1 = P.Y();
3317 if(P.Z() > zmaxB1) zmaxB1 = P.Z();
3320 for(E.Init(theFace2, TopAbs_VERTEX); E.More(); E.Next()) {
3321 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
3322 if(P.X() < xminB2) xminB2 = P.X();
3323 if(P.Y() < yminB2) yminB2 = P.Y();
3324 if(P.Z() < zminB2) zminB2 = P.Z();
3325 if(P.X() > xmaxB2) xmaxB2 = P.X();
3326 if(P.Y() > ymaxB2) ymaxB2 = P.Y();
3327 if(P.Z() > zmaxB2) zmaxB2 = P.Z();
3330 //Compare the bounding boxes of both faces
3331 if(gp_Pnt(xminB1, yminB1, zminB1).Distance(gp_Pnt(xminB2, yminB2, zminB2)) > MAX_TOLERANCE)
3334 if(gp_Pnt(xmaxB1, ymaxB1, zmaxB1).Distance(gp_Pnt(xmaxB2, ymaxB2, zmaxB2)) > MAX_TOLERANCE)
3337 Handle(Geom_Surface) S1 = BRep_Tool::Surface(theFace1);
3338 Handle(Geom_Surface) S2 = BRep_Tool::Surface(theFace2);
3340 //Check if there a coincidence of two surfaces at least in two points
3341 double U11, U12, V11, V12, U21, U22, V21, V22;
3342 BRepTools::UVBounds(theFace1, U11, U12, V11, V12);
3343 BRepTools::UVBounds(theFace2, U21, U22, V21, V22);
3345 double rangeU = U12-U11;
3346 double rangeV = V12-V11;
3347 double U = U11 + rangeU/3.0;
3348 double V = V11 + rangeV/3.0;
3349 gp_Pnt P1 = S1->Value(U, V);
3350 U = U11+rangeU*2.0/3.0;
3351 V = V11+rangeV*2.0/3.0;
3352 gp_Pnt P2 = S1->Value(U, V);
3354 if (!GeomLib_Tool::Parameters(S2, P1, MAX_TOLERANCE, U, V) || U < U21 || U > U22 || V < V21 || V > V22)
3357 if (P1.Distance(S2->Value(U,V)) > MAX_TOLERANCE) return false;
3359 if (!GeomLib_Tool::Parameters(S2, P2, MAX_TOLERANCE, U, V) || U < U21 || U > U22 || V < V21 || V > V22)
3362 if (P2.Distance(S2->Value(U, V)) > MAX_TOLERANCE) return false;
3364 //Check that each edge of the Face1 has a counterpart in the Face2
3365 TopTools_MapOfOrientedShape aMap;
3366 TopTools_ListIteratorOfListOfShape LSI1(LS1);
3367 for(; LSI1.More(); LSI1.Next()) {
3368 TopoDS_Edge E = TopoDS::Edge(LSI1.Value());
3369 bool isFound = false;
3370 TopTools_ListIteratorOfListOfShape LSI2(LS2);
3371 for(; LSI2.More(); LSI2.Next()) {
3372 TopoDS_Shape aValue = LSI2.Value();
3373 if(aMap.Contains(aValue)) continue; //To avoid checking already found edge several times
3374 if(isSameEdge(E, TopoDS::Edge(aValue))) {
3380 if(!isFound) return false;
3386 //=======================================================================
3387 //function : isSameSolid
3388 //purpose : Returns True if two solids coincide
3389 //=======================================================================
3390 bool isSameSolid(const TopoDS_Solid& theSolid1, const TopoDS_Solid& theSolid2)
3392 TopExp_Explorer E(theSolid1, TopAbs_FACE);
3393 TopTools_ListOfShape LS1, LS2;
3394 for(; E.More(); E.Next()) LS1.Append(E.Current());
3395 E.Init(theSolid2, TopAbs_FACE);
3396 for(; E.More(); E.Next()) LS2.Append(E.Current());
3398 if(LS1.Extent() != LS2.Extent()) return false;
3400 double aMin = RealFirst(), aMax = RealLast();
3401 double xminB1=aMax, yminB1=aMax, zminB1=aMax, xminB2=aMax, yminB2=aMax, zminB2=aMax;
3402 double xmaxB1=aMin, ymaxB1=aMin, zmaxB1=aMin, xmaxB2=aMin, ymaxB2=aMin, zmaxB2=aMin;
3404 for(E.Init(theSolid1, TopAbs_VERTEX); E.More(); E.Next()) {
3405 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
3406 if(P.X() < xminB1) xminB1 = P.X();
3407 if(P.Y() < yminB1) yminB1 = P.Y();
3408 if(P.Z() < zminB1) zminB1 = P.Z();
3409 if(P.X() > xmaxB1) xmaxB1 = P.X();
3410 if(P.Y() > ymaxB1) ymaxB1 = P.Y();
3411 if(P.Z() > zmaxB1) zmaxB1 = P.Z();
3414 for(E.Init(theSolid2, TopAbs_VERTEX); E.More(); E.Next()) {
3415 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
3416 if(P.X() < xminB2) xminB2 = P.X();
3417 if(P.Y() < yminB2) yminB2 = P.Y();
3418 if(P.Z() < zminB2) zminB2 = P.Z();
3419 if(P.X() > xmaxB2) xmaxB2 = P.X();
3420 if(P.Y() > ymaxB2) ymaxB2 = P.Y();
3421 if(P.Z() > zmaxB2) zmaxB2 = P.Z();
3424 //Compare the bounding boxes of both solids
3425 if(gp_Pnt(xminB1, yminB1, zminB1).Distance(gp_Pnt(xminB2, yminB2, zminB2)) > MAX_TOLERANCE)
3428 if(gp_Pnt(xmaxB1, ymaxB1, zmaxB1).Distance(gp_Pnt(xmaxB2, ymaxB2, zmaxB2)) > MAX_TOLERANCE)
3431 //Check that each face of the Solid1 has a counterpart in the Solid2
3432 TopTools_MapOfOrientedShape aMap;
3433 TopTools_ListIteratorOfListOfShape LSI1(LS1);
3434 for(; LSI1.More(); LSI1.Next()) {
3435 TopoDS_Face F = TopoDS::Face(LSI1.Value());
3436 bool isFound = false;
3437 TopTools_ListIteratorOfListOfShape LSI2(LS2);
3438 for(; LSI2.More(); LSI2.Next()) {
3439 if(aMap.Contains(LSI2.Value())) continue; //To avoid checking already found faces several times
3440 if(isSameFace(F, TopoDS::Face(LSI2.Value()))) {
3441 aMap.Add(LSI2.Value());
3446 if(!isFound) return false;
3452 //=======================================================================
3453 //function : GetSame
3455 //=======================================================================
3456 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetSame(const Handle(GEOM_Object)& theShapeWhere,
3457 const Handle(GEOM_Object)& theShapeWhat)
3460 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
3462 TopoDS_Shape aWhere = theShapeWhere->GetValue();
3463 TopoDS_Shape aWhat = theShapeWhat->GetValue();
3465 if (aWhere.IsNull() || aWhat.IsNull()) return NULL;
3468 bool isFound = false;
3469 TopoDS_Shape aSubShape;
3470 TopTools_MapOfShape aMap;
3472 switch(aWhat.ShapeType()) {
3473 case TopAbs_VERTEX: {
3474 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(aWhat));
3475 TopExp_Explorer E(aWhere, TopAbs_VERTEX);
3476 for(; E.More(); E.Next()) {
3477 if(!aMap.Add(E.Current())) continue;
3478 gp_Pnt P2 = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
3479 if(P.Distance(P2) <= MAX_TOLERANCE) {
3481 aSubShape = E.Current();
3488 TopoDS_Face aFace = TopoDS::Face(aWhat);
3489 TopExp_Explorer E(aWhere, TopAbs_FACE);
3490 for(; E.More(); E.Next()) {
3491 if(!aMap.Add(E.Current())) continue;
3492 if(isSameFace(aFace, TopoDS::Face(E.Current()))) {
3493 aSubShape = E.Current();
3501 TopoDS_Edge anEdge = TopoDS::Edge(aWhat);
3502 TopExp_Explorer E(aWhere, TopAbs_EDGE);
3503 for(; E.More(); E.Next()) {
3504 if(!aMap.Add(E.Current())) continue;
3505 if(isSameEdge(anEdge, TopoDS::Edge(E.Current()))) {
3506 aSubShape = E.Current();
3513 case TopAbs_SOLID: {
3514 TopoDS_Solid aSolid = TopoDS::Solid(aWhat);
3515 TopExp_Explorer E(aWhere, TopAbs_SOLID);
3516 for(; E.More(); E.Next()) {
3517 if(!aMap.Add(E.Current())) continue;
3518 if(isSameSolid(aSolid, TopoDS::Solid(E.Current()))) {
3519 aSubShape = E.Current();
3531 TopTools_IndexedMapOfShape anIndices;
3532 TopExp::MapShapes(aWhere, anIndices);
3533 if (anIndices.Contains(aSubShape))
3534 anIndex = anIndices.FindIndex(aSubShape);
3537 if(anIndex < 0) return NULL;
3539 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
3541 anArray->SetValue(1, anIndex);
3543 Handle(GEOM_Object) aResult = GetEngine()->AddSubShape(theShapeWhere, anArray);
3544 Handle(GEOM_Function) aFunction = aResult->GetLastFunction();
3546 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetSame("
3547 << theShapeWhere << ", " << theShapeWhat << ")";