1 // Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
2 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License.
9 // This library is distributed in the hope that it will be useful
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // Lesser General Public License for more details.
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 // File : GEOMImpl_IShapesOperations.cxx
22 // Author : modified by Lioka RAZAFINDRAZAKA (CEA) 22/06/2007
28 #include <Standard_Stream.hxx>
30 #include "GEOMImpl_IShapesOperations.hxx"
32 #include "GEOMImpl_Types.hxx"
34 #include "GEOMImpl_VectorDriver.hxx"
35 #include "GEOMImpl_ShapeDriver.hxx"
36 #include "GEOMImpl_CopyDriver.hxx"
37 #include "GEOMImpl_GlueDriver.hxx"
39 #include "GEOMImpl_IVector.hxx"
40 #include "GEOMImpl_IShapes.hxx"
41 #include "GEOMImpl_IGlue.hxx"
43 #include "GEOMImpl_Block6Explorer.hxx"
45 #include "GEOM_Function.hxx"
46 #include "GEOM_ISubShape.hxx"
47 #include "GEOM_PythonDump.hxx"
49 #include "GEOMAlgo_FinderShapeOn1.hxx"
50 #include "GEOMAlgo_FinderShapeOnQuad.hxx"
51 #include "GEOMAlgo_FinderShapeOn2.hxx"
52 #include "GEOMAlgo_ClsfBox.hxx"
53 #include "GEOMAlgo_ClsfSolid.hxx"
54 #include "GEOMAlgo_Gluer1.hxx"
55 #include "GEOMAlgo_ListIteratorOfListOfCoupleOfShapes.hxx"
56 #include "GEOMAlgo_CoupleOfShapes.hxx"
57 #include "GEOMAlgo_ListOfCoupleOfShapes.hxx"
59 #include "utilities.h"
61 #include "Utils_ExceptHandlers.hxx"
63 #include <TFunction_DriverTable.hxx>
64 #include <TFunction_Driver.hxx>
65 #include <TFunction_Logbook.hxx>
66 #include <TDataStd_Integer.hxx>
67 #include <TDataStd_IntegerArray.hxx>
68 #include <TDF_Tool.hxx>
70 #include <BRepExtrema_ExtCF.hxx>
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");
157 //=============================================================================
161 //=============================================================================
162 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeEdge
163 (Handle(GEOM_Object) thePnt1, Handle(GEOM_Object) thePnt2)
167 if (thePnt1.IsNull() || thePnt2.IsNull()) return NULL;
169 //Add a new Edge object
170 Handle(GEOM_Object) anEdge = GetEngine()->AddObject(GetDocID(), GEOM_EDGE);
172 //Add a new Vector function
173 Handle(GEOM_Function) aFunction =
174 anEdge->AddFunction(GEOMImpl_VectorDriver::GetID(), VECTOR_TWO_PNT);
176 //Check if the function is set correctly
177 if (aFunction->GetDriverGUID() != GEOMImpl_VectorDriver::GetID()) return NULL;
179 GEOMImpl_IVector aPI (aFunction);
181 Handle(GEOM_Function) aRef1 = thePnt1->GetLastFunction();
182 Handle(GEOM_Function) aRef2 = thePnt2->GetLastFunction();
183 if (aRef1.IsNull() || aRef2.IsNull()) return NULL;
185 aPI.SetPoint1(aRef1);
186 aPI.SetPoint2(aRef2);
188 //Compute the Edge value
190 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
193 if (!GetSolver()->ComputeFunction(aFunction)) {
194 SetErrorCode("Vector driver failed");
198 catch (Standard_Failure) {
199 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
200 SetErrorCode(aFail->GetMessageString());
204 //Make a Python command
205 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdge("
206 << thePnt1 << ", " << thePnt2 << ")";
212 //=============================================================================
216 //=============================================================================
217 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeWire
218 (list<Handle(GEOM_Object)> theShapes)
220 return MakeShape(theShapes, GEOM_WIRE, WIRE_EDGES, "MakeWire");
223 //=============================================================================
227 //=============================================================================
228 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFace (Handle(GEOM_Object) theWire,
229 const bool isPlanarWanted)
233 if (theWire.IsNull()) return NULL;
235 //Add a new Face object
236 Handle(GEOM_Object) aFace = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
238 //Add a new Shape function for creation of a face from a wire
239 Handle(GEOM_Function) aFunction =
240 aFace->AddFunction(GEOMImpl_ShapeDriver::GetID(), FACE_WIRE);
241 if (aFunction.IsNull()) return NULL;
243 //Check if the function is set correctly
244 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
246 GEOMImpl_IShapes aCI (aFunction);
248 Handle(GEOM_Function) aRefWire = theWire->GetLastFunction();
250 if (aRefWire.IsNull()) return NULL;
252 aCI.SetBase(aRefWire);
253 aCI.SetIsPlanar(isPlanarWanted);
255 //Compute the Face value
257 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
260 if (!GetSolver()->ComputeFunction(aFunction)) {
261 SetErrorCode("Shape driver failed to compute a face");
265 catch (Standard_Failure) {
266 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
267 SetErrorCode(aFail->GetMessageString());
271 //Make a Python command
272 GEOM::TPythonDump(aFunction) << aFace << " = geompy.MakeFace("
273 << theWire << ", " << (int)isPlanarWanted << ")";
279 //=============================================================================
283 //=============================================================================
284 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFaceWires
285 (list<Handle(GEOM_Object)> theShapes,
286 const bool isPlanarWanted)
291 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
294 Handle(GEOM_Function) aFunction =
295 aShape->AddFunction(GEOMImpl_ShapeDriver::GetID(), FACE_WIRES);
296 if (aFunction.IsNull()) return NULL;
298 //Check if the function is set correctly
299 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
301 GEOMImpl_IShapes aCI (aFunction);
303 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
306 list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
307 for (; it != theShapes.end(); it++) {
308 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
309 if (aRefSh.IsNull()) {
310 SetErrorCode("NULL argument shape for the face construction");
313 aShapesSeq->Append(aRefSh);
315 aCI.SetShapes(aShapesSeq);
317 aCI.SetIsPlanar(isPlanarWanted);
321 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
324 if (!GetSolver()->ComputeFunction(aFunction)) {
325 SetErrorCode("Shape driver failed");
329 catch (Standard_Failure) {
330 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
331 SetErrorCode(aFail->GetMessageString());
335 //Make a Python command
336 GEOM::TPythonDump pd (aFunction);
337 pd << aShape << " = geompy.MakeFaceWires([";
340 it = theShapes.begin();
341 if (it != theShapes.end()) {
343 while (it != theShapes.end()) {
344 pd << ", " << (*it++);
347 pd << "], " << (int)isPlanarWanted << ")";
353 //=============================================================================
357 //=============================================================================
358 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeShell
359 (list<Handle(GEOM_Object)> theShapes)
361 return MakeShape(theShapes, GEOM_SHELL, SHELL_FACES, "MakeShell");
364 //=============================================================================
368 //=============================================================================
369 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeSolidShells
370 (list<Handle(GEOM_Object)> theShapes)
372 return MakeShape(theShapes, GEOM_SOLID, SOLID_SHELLS, "MakeSolid");
375 //=============================================================================
379 //=============================================================================
380 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeSolidShell (Handle(GEOM_Object) theShell)
384 if (theShell.IsNull()) return NULL;
386 //Add a new Solid object
387 Handle(GEOM_Object) aSolid = GetEngine()->AddObject(GetDocID(), GEOM_SOLID);
389 //Add a new Solid function for creation of a solid from a shell
390 Handle(GEOM_Function) aFunction =
391 aSolid->AddFunction(GEOMImpl_ShapeDriver::GetID(), SOLID_SHELL);
392 if (aFunction.IsNull()) return NULL;
394 //Check if the function is set correctly
395 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
397 GEOMImpl_IShapes aCI (aFunction);
399 Handle(GEOM_Function) aRefShell = theShell->GetLastFunction();
401 if (aRefShell.IsNull()) return NULL;
403 aCI.SetBase(aRefShell);
405 //Compute the Solid value
407 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
410 if (!GetSolver()->ComputeFunction(aFunction)) {
411 SetErrorCode("Solid driver failed");
415 catch (Standard_Failure) {
416 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
417 SetErrorCode(aFail->GetMessageString());
421 //Make a Python command
422 GEOM::TPythonDump(aFunction) << aSolid
423 << " = geompy.MakeSolid(" << theShell << ")";
429 //=============================================================================
433 //=============================================================================
434 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeCompound
435 (list<Handle(GEOM_Object)> theShapes)
437 return MakeShape(theShapes, GEOM_COMPOUND, COMPOUND_SHAPES, "MakeCompound");
440 //=============================================================================
444 //=============================================================================
445 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeShape
446 (list<Handle(GEOM_Object)> theShapes,
447 const Standard_Integer theObjectType,
448 const Standard_Integer theFunctionType,
449 const TCollection_AsciiString& theMethodName)
454 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), theObjectType);
457 Handle(GEOM_Function) aFunction =
458 aShape->AddFunction(GEOMImpl_ShapeDriver::GetID(), theFunctionType);
459 if (aFunction.IsNull()) return NULL;
461 //Check if the function is set correctly
462 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
464 GEOMImpl_IShapes aCI (aFunction);
466 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
469 list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
470 for (; it != theShapes.end(); it++) {
471 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
472 if (aRefSh.IsNull()) {
473 SetErrorCode("NULL argument shape for the shape construction");
476 aShapesSeq->Append(aRefSh);
478 aCI.SetShapes(aShapesSeq);
482 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
485 if (!GetSolver()->ComputeFunction(aFunction)) {
486 SetErrorCode("Shape driver failed");
490 catch (Standard_Failure) {
491 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
492 SetErrorCode(aFail->GetMessageString());
496 //Make a Python command
497 GEOM::TPythonDump pd (aFunction);
498 pd << aShape << " = geompy." << theMethodName.ToCString() << "([";
501 it = theShapes.begin();
502 if (it != theShapes.end()) {
504 while (it != theShapes.end()) {
505 pd << ", " << (*it++);
514 //=============================================================================
518 //=============================================================================
519 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeGlueFaces
520 (Handle(GEOM_Object) theShape,
521 const Standard_Real theTolerance,
522 const Standard_Boolean doKeepNonSolids)
526 if (theShape.IsNull()) return NULL;
528 //Add a new Glued object
529 Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
531 //Add a new Glue function
532 Handle(GEOM_Function) aFunction;
533 aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_FACES);
534 if (aFunction.IsNull()) return NULL;
536 //Check if the function is set correctly
537 if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
539 GEOMImpl_IGlue aCI (aFunction);
541 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
542 if (aRefShape.IsNull()) return NULL;
544 aCI.SetBase(aRefShape);
545 aCI.SetTolerance(theTolerance);
546 aCI.SetKeepNonSolids(doKeepNonSolids);
548 //Compute the sub-shape value
549 Standard_Boolean isWarning = Standard_False;
551 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
554 if (!GetSolver()->ComputeFunction(aFunction)) {
555 SetErrorCode("Shape driver failed to glue faces");
559 catch (Standard_Failure) {
560 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
561 SetErrorCode(aFail->GetMessageString());
562 // to provide warning
563 if (!aFunction->GetValue().IsNull()) {
564 isWarning = Standard_True;
570 //Make a Python command
571 GEOM::TPythonDump(aFunction) << aGlued << " = geompy.MakeGlueFaces("
572 << theShape << ", " << theTolerance << ")";
574 // to provide warning
575 if (!isWarning) SetErrorCode(OK);
579 //=============================================================================
583 //=============================================================================
584 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetGlueFaces
585 (Handle(GEOM_Object) theShape,
586 const Standard_Real theTolerance)
590 if (theShape.IsNull()) return NULL;
591 TopoDS_Shape aShape = theShape->GetValue();
592 if (aShape.IsNull()) return NULL;
594 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
596 Standard_Integer iErr;
598 GEOMAlgo_Gluer1 aGluer;
599 GEOMAlgo_ListIteratorOfListOfCoupleOfShapes aItCS;
600 GEOMAlgo_CoupleOfShapes aCS;
601 GEOMAlgo_ListOfCoupleOfShapes aLCS;
603 //aGluer = new GEOMAlgo_Gluer1;
604 aGluer.SetShape(aShape);
605 aGluer.SetTolerance(theTolerance);
607 iErr = aGluer.ErrorStatus();
608 if (iErr) return NULL;
610 TopTools_ListOfShape listShape;
611 const GEOMAlgo_ListOfCoupleOfShapes& aLCSG = aGluer.GluedFaces();
613 aItCS.Initialize(aLCSG);
614 for (; aItCS.More(); aItCS.Next()) {
615 const GEOMAlgo_CoupleOfShapes& aCSG = aItCS.Value();
616 listShape.Append(aCSG.Shape1());
619 TopTools_ListIteratorOfListOfShape itSub (listShape);
620 TCollection_AsciiString anAsciiList, anEntry;
621 TopTools_IndexedMapOfShape anIndices;
622 TopExp::MapShapes(aShape, anIndices);
623 Handle(TColStd_HArray1OfInteger) anArray;
624 Handle(GEOM_Object) anObj;
625 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
626 TopoDS_Shape aValue = itSub.Value();
627 anArray = new TColStd_HArray1OfInteger(1,1);
628 anArray->SetValue(1, anIndices.FindIndex(aValue));
629 anObj = GetEngine()->AddSubShape(theShape, anArray);
630 if (!anObj.IsNull()) {
633 // for python command
634 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
635 anAsciiList += anEntry;
640 //Make a Python command
641 if(anAsciiList.Length()>0)
642 anAsciiList.Trunc(anAsciiList.Length() - 1);
643 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
644 GEOM::TPythonDump pd (aFunction, /*append=*/true);
645 pd << "[" << anAsciiList.ToCString();
646 pd << "] = geompy.GetGlueFaces(" << theShape << ", " << theTolerance << ")";
654 //=============================================================================
656 * MakeGlueFacesByList
658 //=============================================================================
659 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeGlueFacesByList
660 (Handle(GEOM_Object) theShape,
661 const Standard_Real theTolerance,
662 list<Handle(GEOM_Object)> theFaces,
663 const Standard_Boolean doKeepNonSolids)
667 if (theShape.IsNull()) return NULL;
669 //Add a new Glued object
670 Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
672 //Add a new Glue function
673 Handle(GEOM_Function) aFunction;
674 aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_FACES_BY_LIST);
675 if (aFunction.IsNull()) return NULL;
677 //Check if the function is set correctly
678 if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
680 GEOMImpl_IGlue aCI (aFunction);
682 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
683 if (aRefShape.IsNull()) return NULL;
685 aCI.SetBase(aRefShape);
686 aCI.SetTolerance(theTolerance);
687 aCI.SetKeepNonSolids(doKeepNonSolids);
689 Handle(TColStd_HSequenceOfTransient) aFaces = new TColStd_HSequenceOfTransient;
690 list<Handle(GEOM_Object)>::iterator it = theFaces.begin();
691 for (; it != theFaces.end(); it++) {
692 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
693 if (aRefSh.IsNull()) {
694 SetErrorCode("NULL argument shape for the shape construction");
697 aFaces->Append(aRefSh);
699 aCI.SetFaces(aFaces);
701 //Compute the sub-shape value
702 Standard_Boolean isWarning = Standard_False;
704 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
707 if (!GetSolver()->ComputeFunction(aFunction)) {
708 SetErrorCode("Shape driver failed to glue faces");
712 catch (Standard_Failure) {
713 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
714 SetErrorCode(aFail->GetMessageString());
715 // to provide warning
716 if (!aFunction->GetValue().IsNull()) {
717 isWarning = Standard_True;
723 //Make a Python command
725 GEOM::TPythonDump pd(aFunction);
726 pd << aGlued << " = geompy.MakeGlueFacesByList("
727 << theShape << ", " << theTolerance << ", [";
729 it = theFaces.begin();
730 if (it != theFaces.end()) {
732 while (it != theFaces.end()) {
733 pd << ", " << (*it++);
739 // to provide warning
740 if (!isWarning) SetErrorCode(OK);
746 //=============================================================================
750 //=============================================================================
751 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::MakeExplode
752 (Handle(GEOM_Object) theShape,
753 const Standard_Integer theShapeType,
754 const Standard_Boolean isSorted)
758 if (theShape.IsNull()) return NULL;
759 TopoDS_Shape aShape = theShape->GetValue();
760 if (aShape.IsNull()) return NULL;
762 Handle(GEOM_Function) aMainShape = theShape->GetLastFunction();
764 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
765 Handle(GEOM_Object) anObj;
766 TopTools_MapOfShape mapShape;
767 TopTools_ListOfShape listShape;
769 if (aShape.ShapeType() == TopAbs_COMPOUND &&
770 (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
771 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPSOLID ||
772 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPOUND)) {
773 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
774 for (; It.More(); It.Next()) {
775 if (mapShape.Add(It.Value())) {
776 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
777 TopAbs_ShapeEnum(theShapeType) == It.Value().ShapeType()) {
778 listShape.Append(It.Value());
783 TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
784 for (; exp.More(); exp.Next())
785 if (mapShape.Add(exp.Current()))
786 listShape.Append(exp.Current());
789 if (listShape.IsEmpty()) {
790 //SetErrorCode("The given shape has no sub-shapes of the requested type");
791 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
796 SortShapes(listShape);
798 TopTools_IndexedMapOfShape anIndices;
799 TopExp::MapShapes(aShape, anIndices);
800 Handle(TColStd_HArray1OfInteger) anArray;
802 TopTools_ListIteratorOfListOfShape itSub (listShape);
803 TCollection_AsciiString anAsciiList, anEntry;
804 for (int index = 1; itSub.More(); itSub.Next(), ++index)
806 TopoDS_Shape aValue = itSub.Value();
807 anArray = new TColStd_HArray1OfInteger(1,1);
808 anArray->SetValue(1, anIndices.FindIndex(aValue));
810 //anObj = GetEngine()->AddSubShape(theShape, anArray);
812 anObj = GetEngine()->AddObject(GetDocID(), GEOM_SUBSHAPE);
813 Handle(GEOM_Function) aFunction = anObj->AddFunction(GEOM_Object::GetSubShapeID(), 1);
814 if (aFunction.IsNull()) return aSeq;
816 GEOM_ISubShape aSSI (aFunction);
817 aSSI.SetMainShape(aMainShape);
818 aSSI.SetIndices(anArray);
820 // Set function value directly, as we know it.
821 // Usage of Solver here would lead to significant loss of time,
822 // because GEOM_SubShapeDriver will build TopTools_IndexedMapOfShape
823 // on the main shape for each being calculated sub-shape separately.
824 aFunction->SetValue(aValue);
827 if (!anObj.IsNull()) {
830 // for python command
831 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
832 anAsciiList += anEntry;
837 //Make a Python command
838 anAsciiList.Trunc(anAsciiList.Length() - 1);
840 GEOM::TPythonDump pd (aMainShape, /*append=*/true);
841 pd << "[" << anAsciiList.ToCString();
842 pd << "] = geompy.SubShapeAll" << (isSorted ? "Sorted(" : "(");
843 pd << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
850 //=============================================================================
854 //=============================================================================
855 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::SubShapeAllIDs
856 (Handle(GEOM_Object) theShape,
857 const Standard_Integer theShapeType,
858 const Standard_Boolean isSorted)
862 if (theShape.IsNull()) return NULL;
863 TopoDS_Shape aShape = theShape->GetValue();
864 if (aShape.IsNull()) return NULL;
866 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
867 TopTools_MapOfShape mapShape;
868 TopTools_ListOfShape listShape;
870 if (aShape.ShapeType() == TopAbs_COMPOUND &&
871 (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
872 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPSOLID ||
873 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPOUND)) {
874 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
875 for (; It.More(); It.Next()) {
876 if (mapShape.Add(It.Value())) {
877 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
878 TopAbs_ShapeEnum(theShapeType) == It.Value().ShapeType()) {
879 listShape.Append(It.Value());
884 TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
885 for (; exp.More(); exp.Next())
886 if (mapShape.Add(exp.Current()))
887 listShape.Append(exp.Current());
890 if (listShape.IsEmpty()) {
891 //SetErrorCode("The given shape has no sub-shapes of the requested type");
892 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
897 SortShapes(listShape);
899 TopTools_IndexedMapOfShape anIndices;
900 TopExp::MapShapes(aShape, anIndices);
901 Handle(TColStd_HArray1OfInteger) anArray;
903 TopTools_ListIteratorOfListOfShape itSub (listShape);
904 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
905 TopoDS_Shape aValue = itSub.Value();
906 aSeq->Append(anIndices.FindIndex(aValue));
909 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
911 //Make a Python command
912 GEOM::TPythonDump pd (aFunction, /*append=*/true);
913 pd << "listSubShapeIDs = geompy.SubShapeAll";
914 pd << (isSorted ? "SortedIDs(" : "IDs(");
915 pd << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
921 //=============================================================================
925 //=============================================================================
926 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetSubShape
927 (Handle(GEOM_Object) theMainShape,
928 const Standard_Integer theID)
932 if (theMainShape.IsNull()) return NULL;
934 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
935 anArray->SetValue(1, theID);
936 Handle(GEOM_Object) anObj = GetEngine()->AddSubShape(theMainShape, anArray,true);
937 if (anObj.IsNull()) {
938 SetErrorCode("Can not get a sub-shape with the given ID");
942 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
944 //Make a Python command
945 GEOM::TPythonDump(aFunction) << anObj << " = geompy.GetSubShape("
946 << theMainShape << ", [" << theID << "])";
952 //=============================================================================
956 //=============================================================================
957 Standard_Integer GEOMImpl_IShapesOperations::GetSubShapeIndex (Handle(GEOM_Object) theMainShape,
958 Handle(GEOM_Object) theSubShape)
962 TopoDS_Shape aMainShape = theMainShape->GetValue();
963 TopoDS_Shape aSubShape = theSubShape->GetValue();
965 if (aMainShape.IsNull() || aSubShape.IsNull()) return -1;
967 TopTools_IndexedMapOfShape anIndices;
968 TopExp::MapShapes(aMainShape, anIndices);
969 if (anIndices.Contains(aSubShape)) {
971 return anIndices.FindIndex(aSubShape);
977 //=============================================================================
981 //=============================================================================
982 Standard_Integer GEOMImpl_IShapesOperations::GetTopologyIndex (Handle(GEOM_Object) theMainShape,
983 Handle(GEOM_Object) theSubShape)
987 TopoDS_Shape aMainShape = theMainShape->GetValue();
988 TopoDS_Shape aSubShape = theSubShape->GetValue();
990 if (aMainShape.IsNull() || aSubShape.IsNull()) {
991 SetErrorCode("Null argument shape given");
996 if (aSubShape.ShapeType() == TopAbs_COMPOUND) {
998 TopTools_ListOfShape CL;
999 CL.Append(aMainShape);
1000 TopTools_ListIteratorOfListOfShape itC;
1001 for (itC.Initialize(CL); itC.More(); itC.Next()) {
1002 for (it.Initialize(itC.Value()); it.More(); it.Next()) {
1003 if (it.Value().ShapeType() == TopAbs_COMPOUND) {
1004 if (it.Value().IsSame(aSubShape))
1008 CL.Append(it.Value());
1013 TopExp_Explorer anExp (aMainShape, aSubShape.ShapeType());
1014 TopTools_MapOfShape M;
1015 for (; anExp.More(); anExp.Next()) {
1016 if (M.Add(anExp.Current())) {
1017 if (anExp.Current().IsSame(aSubShape))
1024 SetErrorCode("The sub-shape does not belong to the main shape");
1028 //=============================================================================
1030 * GetShapeTypeString
1032 //=============================================================================
1033 TCollection_AsciiString GEOMImpl_IShapesOperations::GetShapeTypeString (Handle(GEOM_Object) theShape)
1037 TCollection_AsciiString aTypeName ("Null Shape");
1039 TopoDS_Shape aShape = theShape->GetValue();
1040 if (aShape.IsNull())
1043 switch (aShape.ShapeType() )
1045 case TopAbs_COMPOUND:
1046 aTypeName = "Compound";
1048 case TopAbs_COMPSOLID:
1049 aTypeName = "Compound Solid";
1052 aTypeName = "Solid";
1055 aTypeName = "Shell";
1059 BRepAdaptor_Surface surf (TopoDS::Face(aShape));
1060 if (surf.GetType() == GeomAbs_Plane)
1061 aTypeName = "Plane";
1062 else if (surf.GetType() == GeomAbs_Cylinder)
1063 aTypeName = "Cylindrical Face";
1064 else if (surf.GetType() == GeomAbs_Sphere)
1065 aTypeName = "Spherical Face";
1066 else if (surf.GetType() == GeomAbs_Torus)
1067 aTypeName = "Toroidal Face";
1068 else if (surf.GetType() == GeomAbs_Cone)
1069 aTypeName = "Conical Face";
1071 aTypeName = "GEOM::FACE";
1079 BRepAdaptor_Curve curv (TopoDS::Edge(aShape));
1080 if (curv.GetType() == GeomAbs_Line) {
1081 if ((Abs(curv.FirstParameter()) >= 1E6) ||
1082 (Abs(curv.LastParameter()) >= 1E6))
1085 aTypeName = "Edge" ;
1086 } else if (curv.GetType() == GeomAbs_Circle) {
1087 if (curv.IsClosed())
1088 aTypeName = "Circle";
1097 aTypeName = "Vertex";
1100 aTypeName = "Shape";
1103 aTypeName = "Shape of unknown type";
1110 //=============================================================================
1114 //=============================================================================
1115 Standard_Integer GEOMImpl_IShapesOperations::NumberOfFaces (Handle(GEOM_Object) theShape)
1119 Standard_Integer nb = 0;
1121 if (theShape.IsNull()) return -1;
1122 TopoDS_Shape aShape = theShape->GetValue();
1123 if (aShape.IsNull()) return -1;
1125 TopTools_MapOfShape mapShape;
1127 TopExp_Explorer exp (aShape, TopAbs_FACE);
1128 for (; exp.More(); exp.Next())
1129 if (mapShape.Add(exp.Current()))
1136 //=============================================================================
1140 //=============================================================================
1141 Standard_Integer GEOMImpl_IShapesOperations::NumberOfEdges (Handle(GEOM_Object) theShape)
1145 Standard_Integer nb = 0;
1147 if (theShape.IsNull()) return -1;
1148 TopoDS_Shape aShape = theShape->GetValue();
1149 if (aShape.IsNull()) return -1;
1151 TopTools_MapOfShape mapShape;
1153 TopExp_Explorer exp (aShape, TopAbs_EDGE);
1154 for (; exp.More(); exp.Next())
1155 if (mapShape.Add(exp.Current()))
1162 //=============================================================================
1166 //=============================================================================
1167 Handle(GEOM_Object) GEOMImpl_IShapesOperations::ReverseShape(Handle(GEOM_Object) theShape)
1171 if (theShape.IsNull()) return NULL;
1173 //Add a new reversed object
1174 Handle(GEOM_Object) aReversed = GetEngine()->AddObject(GetDocID(), theShape->GetType());
1176 //Add a new Revese function
1177 Handle(GEOM_Function) aFunction;
1178 aFunction = aReversed->AddFunction(GEOMImpl_ShapeDriver::GetID(), REVERSE_ORIENTATION);
1179 if (aFunction.IsNull()) return NULL;
1181 //Check if the function is set correctly
1182 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
1184 GEOMImpl_IShapes aSI (aFunction);
1186 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
1187 if (aRefShape.IsNull()) return NULL;
1189 aSI.SetBase(aRefShape);
1191 //Compute the sub-shape value
1193 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
1196 if (!GetSolver()->ComputeFunction(aFunction)) {
1197 SetErrorCode("Shape driver failed to reverse shape");
1201 catch (Standard_Failure) {
1202 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1203 SetErrorCode(aFail->GetMessageString());
1207 //Make a Python command
1208 GEOM::TPythonDump(aFunction) << aReversed
1209 << " = geompy.ChangeOrientation(" << theShape << ")";
1215 //=============================================================================
1219 //=============================================================================
1220 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetFreeFacesIDs
1221 (Handle(GEOM_Object) theShape)
1225 if (theShape.IsNull()) return NULL;
1226 TopoDS_Shape aShape = theShape->GetValue();
1227 if (aShape.IsNull()) return NULL;
1229 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
1231 TopTools_IndexedDataMapOfShapeListOfShape mapFaceBlocks;
1232 GEOMImpl_Block6Explorer::MapShapesAndAncestors
1233 (aShape, TopAbs_FACE, TopAbs_SOLID, mapFaceBlocks);
1235 Standard_Integer ind = 1, nbFaces = mapFaceBlocks.Extent();
1238 SetErrorCode("The given shape has no faces");
1242 TopTools_IndexedMapOfShape anIndices;
1243 TopExp::MapShapes(aShape, anIndices);
1245 Standard_Integer id;
1246 for (; ind <= nbFaces; ind++) {
1247 if (mapFaceBlocks.FindFromIndex(ind).Extent() != 2) {
1248 id = anIndices.FindIndex(mapFaceBlocks.FindKey(ind));
1253 //The explode doesn't change object so no new function is required.
1254 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
1256 //Make a Python command
1257 GEOM::TPythonDump(aFunction, /*append=*/true)
1258 << "listFreeFacesIDs = geompy.GetFreeFacesIDs(" << theShape << ")";
1264 //=======================================================================
1265 //function : GetSharedShapes
1267 //=======================================================================
1269 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetSharedShapes
1270 (Handle(GEOM_Object) theShape1,
1271 Handle(GEOM_Object) theShape2,
1272 const Standard_Integer theShapeType)
1276 if (theShape1.IsNull() || theShape2.IsNull()) return NULL;
1278 TopoDS_Shape aShape1 = theShape1->GetValue();
1279 TopoDS_Shape aShape2 = theShape2->GetValue();
1281 if (aShape1.IsNull() || aShape2.IsNull()) return NULL;
1283 TopTools_IndexedMapOfShape anIndices;
1284 TopExp::MapShapes(aShape1, anIndices);
1285 Handle(TColStd_HArray1OfInteger) anArray;
1287 TopTools_IndexedMapOfShape mapShape1;
1288 TopExp::MapShapes(aShape1, TopAbs_ShapeEnum(theShapeType), mapShape1);
1290 Handle(GEOM_Object) anObj;
1291 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1292 TCollection_AsciiString anAsciiList, anEntry;
1294 TopTools_MapOfShape mapShape2;
1295 TopExp_Explorer exp (aShape2, TopAbs_ShapeEnum(theShapeType));
1296 for (; exp.More(); exp.Next()) {
1297 TopoDS_Shape aSS = exp.Current();
1298 if (mapShape2.Add(aSS) && mapShape1.Contains(aSS)) {
1299 anArray = new TColStd_HArray1OfInteger(1,1);
1300 anArray->SetValue(1, anIndices.FindIndex(aSS));
1301 anObj = GetEngine()->AddSubShape(theShape1, anArray);
1302 aSeq->Append(anObj);
1304 // for python command
1305 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
1306 anAsciiList += anEntry;
1311 if (aSeq->IsEmpty()) {
1312 SetErrorCode("The given shapes have no shared sub-shapes of the requested type");
1316 //Make a Python command
1317 anAsciiList.Trunc(anAsciiList.Length() - 1);
1319 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1321 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
1322 << "] = geompy.GetSharedShapes(" << theShape1 << ", "
1323 << theShape2 << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
1329 //=============================================================================
1333 //=============================================================================
1334 static GEOM::TPythonDump& operator<< (GEOM::TPythonDump& theDump,
1335 const GEOMAlgo_State theState)
1338 case GEOMAlgo_ST_IN:
1339 theDump << "geompy.GEOM.ST_IN";
1341 case GEOMAlgo_ST_OUT:
1342 theDump << "geompy.GEOM.ST_OUT";
1344 case GEOMAlgo_ST_ON:
1345 theDump << "geompy.GEOM.ST_ON";
1347 case GEOMAlgo_ST_ONIN:
1348 theDump << "geompy.GEOM.ST_ONIN";
1350 case GEOMAlgo_ST_ONOUT:
1351 theDump << "geompy.GEOM.ST_ONOUT";
1354 theDump << "geompy.GEOM.ST_UNKNOWN";
1360 //=======================================================================
1361 //function : checkTypeShapesOn
1363 * \brief Checks if theShapeType parameter of GetShapesOnXXX() is OK
1364 * \param theShapeType - the shape type to check
1365 * \retval bool - result of the check
1367 //=======================================================================
1369 bool GEOMImpl_IShapesOperations::checkTypeShapesOn(const Standard_Integer theShapeType)
1371 if (theShapeType != TopAbs_VERTEX &&
1372 theShapeType != TopAbs_EDGE &&
1373 theShapeType != TopAbs_FACE &&
1374 theShapeType != TopAbs_SOLID) {
1375 SetErrorCode("Only solids, vertices, edges or faces can be found by this method");
1381 //=======================================================================
1382 //function : makePlane
1384 * \brief Creates Geom_Plane
1385 * \param theAx1 - shape object defining plane parameters
1386 * \retval Handle(Geom_Surface) - resulting surface
1388 //=======================================================================
1390 Handle(Geom_Surface) GEOMImpl_IShapesOperations::makePlane(const TopoDS_Shape& anAx1)
1392 if (anAx1.ShapeType() != TopAbs_EDGE) return NULL;
1393 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
1394 TopoDS_Vertex V1, V2;
1395 TopExp::Vertices(anEdge, V1, V2, Standard_True);
1396 if (V1.IsNull() || V2.IsNull()) {
1397 SetErrorCode("Bad edge given for the plane normal vector");
1400 gp_Pnt aLoc = BRep_Tool::Pnt(V1);
1401 gp_Vec aVec (aLoc, BRep_Tool::Pnt(V2));
1402 if (aVec.Magnitude() < Precision::Confusion()) {
1403 SetErrorCode("Vector with null magnitude given");
1406 return new Geom_Plane(aLoc, aVec);
1409 //=======================================================================
1410 //function : makeCylinder
1412 * \brief Creates Geom_CylindricalSurface
1413 * \param theAx1 - edge defining cylinder axis
1414 * \param theRadius - cylinder radius
1415 * \retval Handle(Geom_Surface) - resulting surface
1417 //=======================================================================
1419 Handle(Geom_Surface) GEOMImpl_IShapesOperations::makeCylinder(const TopoDS_Shape& anAxis,
1420 const Standard_Real theRadius)
1422 //Axis of the cylinder
1423 if (anAxis.ShapeType() != TopAbs_EDGE) {
1424 SetErrorCode("Not an edge given for the axis");
1427 TopoDS_Edge anEdge = TopoDS::Edge(anAxis);
1428 TopoDS_Vertex V1, V2;
1429 TopExp::Vertices(anEdge, V1, V2, Standard_True);
1430 if (V1.IsNull() || V2.IsNull()) {
1431 SetErrorCode("Bad edge given for the axis");
1434 gp_Pnt aLoc = BRep_Tool::Pnt(V1);
1435 gp_Vec aVec (aLoc, BRep_Tool::Pnt(V2));
1436 if (aVec.Magnitude() < Precision::Confusion()) {
1437 SetErrorCode("Vector with null magnitude given");
1441 gp_Ax3 anAx3 (aLoc, aVec);
1442 return new Geom_CylindricalSurface(anAx3, theRadius);
1446 //=======================================================================
1447 //function : getShapesOnBoxIDs
1449 * \brief Find IDs of subshapes complying with given status about surface
1450 * \param theBox - the box to check state of subshapes against
1451 * \param theShape - the shape to explore
1452 * \param theShapeType - type of subshape of theShape
1453 * \param theState - required state
1454 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1456 //=======================================================================
1458 Handle(TColStd_HSequenceOfInteger)
1459 GEOMImpl_IShapesOperations::getShapesOnBoxIDs(const Handle(GEOM_Object)& theBox,
1460 const Handle(GEOM_Object)& theShape,
1461 const Standard_Integer theShapeType,
1462 GEOMAlgo_State theState)
1464 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
1466 TopoDS_Shape aBox = theBox->GetValue();
1467 TopoDS_Shape aShape = theShape->GetValue();
1469 // Check presence of triangulation, build if need
1470 if (!CheckTriangulation(aShape)) {
1471 SetErrorCode("Cannot build triangulation on the shape");
1476 GEOMAlgo_FinderShapeOn2 aFinder;
1477 Standard_Real aTol = 0.0001; // default value
1479 Handle(GEOMAlgo_ClsfBox) aClsfBox = new GEOMAlgo_ClsfBox;
1480 aClsfBox->SetBox(aBox);
1482 aFinder.SetShape(aShape);
1483 aFinder.SetTolerance(aTol);
1484 aFinder.SetClsf(aClsfBox);
1485 aFinder.SetShapeType( (TopAbs_ShapeEnum)theShapeType );
1486 aFinder.SetState(theState);
1489 // Interprete results
1490 Standard_Integer iErr = aFinder.ErrorStatus();
1491 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
1493 MESSAGE(" iErr : " << iErr);
1494 TCollection_AsciiString aMsg (" iErr : ");
1495 aMsg += TCollection_AsciiString(iErr);
1499 Standard_Integer iWrn = aFinder.WarningStatus();
1500 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
1502 MESSAGE(" *** iWrn : " << iWrn);
1505 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
1507 if (listSS.Extent() < 1) {
1508 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
1509 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
1513 // Fill sequence of object IDs
1514 aSeqOfIDs = new TColStd_HSequenceOfInteger;
1516 TopTools_IndexedMapOfShape anIndices;
1517 TopExp::MapShapes(aShape, anIndices);
1519 TopTools_ListIteratorOfListOfShape itSub (listSS);
1520 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
1521 int id = anIndices.FindIndex(itSub.Value());
1522 aSeqOfIDs->Append(id);
1529 //=======================================================================
1530 //function : GetShapesOnBoxIDs
1532 * \brief Find subshapes complying with given status about surface
1533 * \param theBox - the box to check state of subshapes against
1534 * \param theShape - the shape to explore
1535 * \param theShapeType - type of subshape of theShape
1536 * \param theState - required state
1537 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1539 //=======================================================================
1541 Handle(TColStd_HSequenceOfInteger)
1542 GEOMImpl_IShapesOperations::GetShapesOnBoxIDs(const Handle(GEOM_Object)& theBox,
1543 const Handle(GEOM_Object)& theShape,
1544 const Standard_Integer theShapeType,
1545 GEOMAlgo_State theState)
1547 // Find subshapes ids
1548 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
1549 getShapesOnBoxIDs (theBox, theShape, theShapeType, theState);
1550 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
1553 // The GetShapesOnBox() doesn't change object so no new function is required.
1554 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theBox)->GetLastFunction();
1556 // Make a Python command
1557 GEOM::TPythonDump(aFunction)
1558 << "listShapesOnBoxIDs = geompy.GetShapesOnBoxIDs("
1561 << TopAbs_ShapeEnum(theShapeType) << ", "
1568 //=======================================================================
1569 //function : GetShapesOnBox
1571 * \brief Find subshapes complying with given status about surface
1572 * \param theBox - the box to check state of subshapes against
1573 * \param theShape - the shape to explore
1574 * \param theShapeType - type of subshape of theShape
1575 * \param theState - required state
1576 * \retval Handle(TColStd_HSequenceOfTransient) - found subshapes
1578 //=======================================================================
1580 Handle(TColStd_HSequenceOfTransient)
1581 GEOMImpl_IShapesOperations::GetShapesOnBox(const Handle(GEOM_Object)& theBox,
1582 const Handle(GEOM_Object)& theShape,
1583 const Standard_Integer theShapeType,
1584 GEOMAlgo_State theState)
1586 // Find subshapes ids
1587 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
1588 getShapesOnBoxIDs (theBox, theShape, theShapeType, theState);
1589 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
1592 // Find objects by indices
1593 TCollection_AsciiString anAsciiList;
1594 Handle(TColStd_HSequenceOfTransient) aSeq;
1595 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
1596 if ( aSeq.IsNull() || aSeq->IsEmpty() )
1599 // Make a Python command
1601 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
1602 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1604 GEOM::TPythonDump(aFunction)
1605 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnBox("
1608 << TopAbs_ShapeEnum(theShapeType) << ", "
1616 //=======================================================================
1617 //function : getShapesOnShapeIDs
1619 * \brief Find IDs of subshapes complying with given status about surface
1620 * \param theCheckShape - the shape to check state of subshapes against
1621 * \param theShape - the shape to explore
1622 * \param theShapeType - type of subshape of theShape
1623 * \param theState - required state
1624 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1626 //=======================================================================
1628 Handle(TColStd_HSequenceOfInteger)
1629 GEOMImpl_IShapesOperations::getShapesOnShapeIDs
1630 (const Handle(GEOM_Object)& theCheckShape,
1631 const Handle(GEOM_Object)& theShape,
1632 const Standard_Integer theShapeType,
1633 GEOMAlgo_State theState)
1635 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
1637 TopoDS_Shape aCheckShape = theCheckShape->GetValue();
1638 TopoDS_Shape aShape = theShape->GetValue();
1639 TopTools_ListOfShape res;
1641 // Check presence of triangulation, build if need
1642 if (!CheckTriangulation(aShape)) {
1643 SetErrorCode("Cannot build triangulation on the shape");
1648 GEOMAlgo_FinderShapeOn2 aFinder;
1649 Standard_Real aTol = 0.0001; // default value
1651 Handle(GEOMAlgo_ClsfSolid) aClsfSolid = new GEOMAlgo_ClsfSolid;
1652 aClsfSolid->SetShape(aCheckShape);
1654 aFinder.SetShape(aShape);
1655 aFinder.SetTolerance(aTol);
1656 aFinder.SetClsf(aClsfSolid);
1657 aFinder.SetShapeType( (TopAbs_ShapeEnum)theShapeType );
1658 aFinder.SetState(theState);
1661 // Interprete results
1662 Standard_Integer iErr = aFinder.ErrorStatus();
1663 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
1665 MESSAGE(" iErr : " << iErr);
1666 TCollection_AsciiString aMsg (" iErr : ");
1667 aMsg += TCollection_AsciiString(iErr);
1671 Standard_Integer iWrn = aFinder.WarningStatus();
1672 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
1674 MESSAGE(" *** iWrn : " << iWrn);
1677 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
1679 if (listSS.Extent() < 1) {
1680 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
1681 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
1684 // Fill sequence of object IDs
1685 aSeqOfIDs = new TColStd_HSequenceOfInteger;
1687 TopTools_IndexedMapOfShape anIndices;
1688 TopExp::MapShapes(aShape, anIndices);
1690 TopTools_ListIteratorOfListOfShape itSub (listSS);
1691 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
1692 int id = anIndices.FindIndex(itSub.Value());
1693 aSeqOfIDs->Append(id);
1700 //=======================================================================
1701 //function : GetShapesOnShapeIDs
1703 * \brief Find subshapes complying with given status about surface
1704 * \param theCheckShape - the shape to check state of subshapes against
1705 * \param theShape - the shape to explore
1706 * \param theShapeType - type of subshape of theShape
1707 * \param theState - required state
1708 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1710 //=======================================================================
1712 Handle(TColStd_HSequenceOfInteger)
1713 GEOMImpl_IShapesOperations::GetShapesOnShapeIDs
1714 (const Handle(GEOM_Object)& theCheckShape,
1715 const Handle(GEOM_Object)& theShape,
1716 const Standard_Integer theShapeType,
1717 GEOMAlgo_State theState)
1719 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
1720 getShapesOnShapeIDs (theCheckShape, theShape, theShapeType, theState);
1722 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
1725 // The GetShapesOnShape() doesn't change object so no new function is required.
1726 Handle(GEOM_Function) aFunction =
1727 GEOM::GetCreatedLast(theShape,theCheckShape)->GetLastFunction();
1729 // Make a Python command
1730 GEOM::TPythonDump(aFunction)
1731 << "listShapesOnBoxIDs = geompy.GetShapesOnShapeIDs("
1732 << theCheckShape << ", "
1734 << TopAbs_ShapeEnum(theShapeType) << ", "
1742 //=======================================================================
1743 //function : GetShapesOnShape
1745 * \brief Find subshapes complying with given status about surface
1746 * \param theCheckShape - the shape to check state of subshapes against
1747 * \param theShape - the shape to explore
1748 * \param theShapeType - type of subshape of theShape
1749 * \param theState - required state
1750 * \retval Handle(TColStd_HSequenceOfTransient) - found subshapes
1752 //=======================================================================
1754 Handle(TColStd_HSequenceOfTransient)
1755 GEOMImpl_IShapesOperations::GetShapesOnShape
1756 (const Handle(GEOM_Object)& theCheckShape,
1757 const Handle(GEOM_Object)& theShape,
1758 const Standard_Integer theShapeType,
1759 GEOMAlgo_State theState)
1761 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
1762 getShapesOnShapeIDs (theCheckShape, theShape, theShapeType, theState);
1763 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
1766 // Find objects by indices
1767 TCollection_AsciiString anAsciiList;
1768 Handle(TColStd_HSequenceOfTransient) aSeq;
1769 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
1771 if ( aSeq.IsNull() || aSeq->IsEmpty() )
1774 // Make a Python command
1776 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
1777 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1779 GEOM::TPythonDump(aFunction)
1780 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnShape("
1781 << theCheckShape << ", "
1783 << TopAbs_ShapeEnum(theShapeType) << ", "
1792 //=======================================================================
1793 //function : GetShapesOnShapeAsCompound
1794 //=======================================================================
1796 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetShapesOnShapeAsCompound
1797 (const Handle(GEOM_Object)& theCheckShape,
1798 const Handle(GEOM_Object)& theShape,
1799 const Standard_Integer theShapeType,
1800 GEOMAlgo_State theState)
1802 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
1803 getShapesOnShapeIDs (theCheckShape, theShape, theShapeType, theState);
1805 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
1808 // Find objects by indices
1809 TCollection_AsciiString anAsciiList;
1810 Handle(TColStd_HSequenceOfTransient) aSeq;
1811 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
1813 if ( aSeq.IsNull() || aSeq->IsEmpty() )
1816 TopoDS_Compound aCompound;
1818 B.MakeCompound(aCompound);
1820 for(; i<=aSeq->Length(); i++) {
1821 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(aSeq->Value(i));
1822 TopoDS_Shape aShape_i = anObj->GetValue();
1823 B.Add(aCompound,aShape_i);
1826 //Add a new result object
1827 Handle(GEOM_Object) aRes = GetEngine()->AddObject(GetDocID(), GEOM_SHAPES_ON_SHAPE);
1828 Handle(GEOM_Function) aFunction =
1829 aRes->AddFunction(GEOMImpl_ShapeDriver::GetID(), SHAPES_ON_SHAPE);
1830 aFunction->SetValue(aCompound);
1832 GEOM::TPythonDump(aFunction)
1833 << aRes << " = geompy.GetShapesOnShapeAsCompound("
1834 << theCheckShape << ", "
1836 << TopAbs_ShapeEnum(theShapeType) << ", "
1845 //=======================================================================
1846 //function : getShapesOnSurfaceIDs
1848 * \brief Find IDs of subshapes complying with given status about surface
1849 * \param theSurface - the surface to check state of subshapes against
1850 * \param theShape - the shape to explore
1851 * \param theShapeType - type of subshape of theShape
1852 * \param theState - required state
1853 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1855 //=======================================================================
1857 Handle(TColStd_HSequenceOfInteger)
1858 GEOMImpl_IShapesOperations::getShapesOnSurfaceIDs(const Handle(Geom_Surface)& theSurface,
1859 const TopoDS_Shape& theShape,
1860 TopAbs_ShapeEnum theShapeType,
1861 GEOMAlgo_State theState)
1863 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
1865 // Check presence of triangulation, build if need
1866 if (!CheckTriangulation(theShape)) {
1867 SetErrorCode("Cannot build triangulation on the shape");
1872 GEOMAlgo_FinderShapeOn1 aFinder;
1873 Standard_Real aTol = 0.0001; // default value
1875 aFinder.SetShape(theShape);
1876 aFinder.SetTolerance(aTol);
1877 aFinder.SetSurface(theSurface);
1878 aFinder.SetShapeType(theShapeType);
1879 aFinder.SetState(theState);
1881 // Sets the minimal number of inner points for the faces that do not have own
1882 // inner points at all (for e.g. rectangular planar faces have just 2 triangles).
1884 aFinder.SetNbPntsMin(3);
1885 // Sets the maximal number of inner points for edges or faces.
1886 // It is usefull for the cases when this number is very big (e.g =2000) to improve
1887 // the performance. If this value =0, all inner points will be taken into account.
1889 aFinder.SetNbPntsMax(100);
1893 // Interprete results
1894 Standard_Integer iErr = aFinder.ErrorStatus();
1895 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
1897 MESSAGE(" iErr : " << iErr);
1898 TCollection_AsciiString aMsg (" iErr : ");
1899 aMsg += TCollection_AsciiString(iErr);
1903 Standard_Integer iWrn = aFinder.WarningStatus();
1904 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
1906 MESSAGE(" *** iWrn : " << iWrn);
1909 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
1911 if (listSS.Extent() < 1) {
1912 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
1913 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
1917 // Fill sequence of object IDs
1918 aSeqOfIDs = new TColStd_HSequenceOfInteger;
1920 TopTools_IndexedMapOfShape anIndices;
1921 TopExp::MapShapes(theShape, anIndices);
1923 TopTools_ListIteratorOfListOfShape itSub (listSS);
1924 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
1925 int id = anIndices.FindIndex(itSub.Value());
1926 aSeqOfIDs->Append(id);
1932 //=======================================================================
1933 //function : getObjectsShapesOn
1935 * \brief Find shape objects and their entries by their ids
1936 * \param theShapeIDs - incoming shape ids
1937 * \param theShapeEntries - outgoing entries like "entry1, entry2, ..."
1938 * \retval Handle(TColStd_HSequenceOfTransient) - found shape objects
1940 //=======================================================================
1942 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::
1943 getObjectsShapesOn(const Handle(GEOM_Object)& theShape,
1944 const Handle(TColStd_HSequenceOfInteger)& theShapeIDs,
1945 TCollection_AsciiString & theShapeEntries)
1947 Handle(TColStd_HSequenceOfTransient) aSeq;
1949 if ( !theShapeIDs.IsNull() && theShapeIDs->Length() > 0 )
1951 aSeq = new TColStd_HSequenceOfTransient;
1952 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
1953 TCollection_AsciiString anEntry;
1954 for ( int i = 1; i <= theShapeIDs->Length(); ++i )
1956 anArray->SetValue(1, theShapeIDs->Value( i ));
1957 Handle(GEOM_Object) anObj = GetEngine()->AddSubShape(theShape, anArray);
1958 aSeq->Append( anObj );
1960 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
1961 if ( i != 1 ) theShapeEntries += ",";
1962 theShapeEntries += anEntry;
1968 //=======================================================================
1969 //function : getShapesOnSurface
1971 * \brief Find subshapes complying with given status about surface
1972 * \param theSurface - the surface to check state of subshapes against
1973 * \param theShape - the shape to explore
1974 * \param theShapeType - type of subshape of theShape
1975 * \param theState - required state
1976 * \param theShapeEntries - outgoing entries like "entry1, entry2, ..."
1977 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1979 //=======================================================================
1981 Handle(TColStd_HSequenceOfTransient)
1982 GEOMImpl_IShapesOperations::getShapesOnSurface(const Handle(Geom_Surface)& theSurface,
1983 const Handle(GEOM_Object)& theShape,
1984 TopAbs_ShapeEnum theShapeType,
1985 GEOMAlgo_State theState,
1986 TCollection_AsciiString & theShapeEntries)
1988 // Find subshapes ids
1989 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
1990 getShapesOnSurfaceIDs (theSurface, theShape->GetValue(), theShapeType, theState);
1991 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
1994 return getObjectsShapesOn( theShape, aSeqOfIDs, theShapeEntries );
1997 //=============================================================================
2001 //=============================================================================
2002 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnPlane
2003 (const Handle(GEOM_Object)& theShape,
2004 const Standard_Integer theShapeType,
2005 const Handle(GEOM_Object)& theAx1,
2006 const GEOMAlgo_State theState)
2010 if (theShape.IsNull() || theAx1.IsNull()) return NULL;
2012 TopoDS_Shape aShape = theShape->GetValue();
2013 TopoDS_Shape anAx1 = theAx1->GetValue();
2015 if (aShape.IsNull() || anAx1.IsNull()) return NULL;
2017 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2018 if ( !checkTypeShapesOn( theShapeType ))
2022 Handle(Geom_Surface) aPlane = makePlane( anAx1 );
2023 if ( aPlane.IsNull() )
2027 TCollection_AsciiString anAsciiList;
2028 Handle(TColStd_HSequenceOfTransient) aSeq;
2029 aSeq = getShapesOnSurface( aPlane, theShape, aShapeType, theState, anAsciiList );
2030 if ( aSeq.IsNull() || aSeq->Length() == 0 )
2033 // Make a Python command
2035 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2036 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2038 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
2039 << "] = geompy.GetShapesOnPlane(" << theShape << ", "
2040 << aShapeType << ", " << theAx1 << ", " << theState << ")";
2046 //=============================================================================
2048 * GetShapesOnPlaneWithLocation
2050 //=============================================================================
2051 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnPlaneWithLocation
2052 (const Handle(GEOM_Object)& theShape,
2053 const Standard_Integer theShapeType,
2054 const Handle(GEOM_Object)& theAx1,
2055 const Handle(GEOM_Object)& thePnt,
2056 const GEOMAlgo_State theState)
2060 if (theShape.IsNull() || theAx1.IsNull() || thePnt.IsNull()) return NULL;
2062 TopoDS_Shape aShape = theShape->GetValue();
2063 TopoDS_Shape anAx1 = theAx1->GetValue();
2064 TopoDS_Shape anPnt = thePnt->GetValue();
2066 if (aShape.IsNull() || anAx1.IsNull() || anPnt.IsNull()) return NULL;
2068 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2069 if ( !checkTypeShapesOn( theShapeType ))
2073 if ( anAx1.ShapeType() != TopAbs_EDGE || anPnt.ShapeType() != TopAbs_VERTEX ) return NULL;
2074 TopoDS_Vertex V1, V2, V3;
2075 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
2076 TopExp::Vertices(anEdge, V1, V2, Standard_True);
2078 if (V1.IsNull() || V2.IsNull()) {
2079 SetErrorCode("Bad edge given for the plane normal vector");
2082 V3 = TopoDS::Vertex(anPnt);
2085 SetErrorCode("Bad vertex given for the plane location");
2088 gp_Pnt aLoc = BRep_Tool::Pnt(V3);
2089 gp_Vec aVec(BRep_Tool::Pnt(V1),BRep_Tool::Pnt(V2));
2091 if (aVec.Magnitude() < Precision::Confusion()) {
2092 SetErrorCode("Vector with null magnitude given");
2095 Handle(Geom_Surface) aPlane = new Geom_Plane(aLoc, aVec);
2097 if ( aPlane.IsNull() )
2101 TCollection_AsciiString anAsciiList;
2102 Handle(TColStd_HSequenceOfTransient) aSeq;
2103 aSeq = getShapesOnSurface( aPlane, theShape, aShapeType, theState, anAsciiList );
2104 if ( aSeq.IsNull() || aSeq->Length() == 0 )
2107 // Make a Python command
2109 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2110 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2112 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
2113 << "] = geompy.GetShapesOnPlaneWithLocation(" << theShape << ", "
2114 << aShapeType << ", " << theAx1 << ", "<< thePnt <<", " << theState << ")";
2120 //=============================================================================
2122 * GetShapesOnCylinder
2124 //=============================================================================
2125 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnCylinder
2126 (const Handle(GEOM_Object)& theShape,
2127 const Standard_Integer theShapeType,
2128 const Handle(GEOM_Object)& theAxis,
2129 const Standard_Real theRadius,
2130 const GEOMAlgo_State theState)
2134 if (theShape.IsNull() || theAxis.IsNull()) return NULL;
2136 TopoDS_Shape aShape = theShape->GetValue();
2137 TopoDS_Shape anAxis = theAxis->GetValue();
2139 if (aShape.IsNull() || anAxis.IsNull()) return NULL;
2141 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2142 if ( !checkTypeShapesOn( aShapeType ))
2145 // Create a cylinder surface
2146 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
2147 if ( aCylinder.IsNull() )
2151 TCollection_AsciiString anAsciiList;
2152 Handle(TColStd_HSequenceOfTransient) aSeq;
2153 aSeq = getShapesOnSurface( aCylinder, theShape, aShapeType, theState, anAsciiList );
2154 if ( aSeq.IsNull() || aSeq->Length() == 0 )
2157 // Make a Python command
2159 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2160 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2162 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
2163 << "] = geompy.GetShapesOnCylinder(" << theShape << ", " << aShapeType
2164 << ", " << theAxis << ", " << theRadius << ", " << theState << ")";
2170 //=============================================================================
2174 //=============================================================================
2175 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnSphere
2176 (const Handle(GEOM_Object)& theShape,
2177 const Standard_Integer theShapeType,
2178 const Handle(GEOM_Object)& theCenter,
2179 const Standard_Real theRadius,
2180 const GEOMAlgo_State theState)
2184 if (theShape.IsNull() || theCenter.IsNull()) return NULL;
2186 TopoDS_Shape aShape = theShape->GetValue();
2187 TopoDS_Shape aCenter = theCenter->GetValue();
2189 if (aShape.IsNull() || aCenter.IsNull()) return NULL;
2191 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2192 if ( !checkTypeShapesOn( aShapeType ))
2195 // Center of the sphere
2196 if (aCenter.ShapeType() != TopAbs_VERTEX) return NULL;
2197 gp_Pnt aLoc = BRep_Tool::Pnt(TopoDS::Vertex(aCenter));
2199 gp_Ax3 anAx3 (aLoc, gp::DZ());
2200 Handle(Geom_SphericalSurface) aSphere =
2201 new Geom_SphericalSurface(anAx3, theRadius);
2204 TCollection_AsciiString anAsciiList;
2205 Handle(TColStd_HSequenceOfTransient) aSeq;
2206 aSeq = getShapesOnSurface( aSphere, theShape, aShapeType, theState, anAsciiList );
2207 if ( aSeq.IsNull() || aSeq->Length() == 0 )
2210 // Make a Python command
2212 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2213 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2215 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
2216 << "] = geompy.GetShapesOnSphere(" << theShape << ", " << aShapeType
2217 << ", " << theCenter << ", " << theRadius << ", " << theState << ")";
2223 //=============================================================================
2225 * GetShapesOnPlaneIDs
2227 //=============================================================================
2228 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnPlaneIDs
2229 (const Handle(GEOM_Object)& theShape,
2230 const Standard_Integer theShapeType,
2231 const Handle(GEOM_Object)& theAx1,
2232 const GEOMAlgo_State theState)
2236 if (theShape.IsNull() || theAx1.IsNull()) return NULL;
2238 TopoDS_Shape aShape = theShape->GetValue();
2239 TopoDS_Shape anAx1 = theAx1->GetValue();
2241 if (aShape.IsNull() || anAx1.IsNull()) return NULL;
2243 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2244 if ( !checkTypeShapesOn( aShapeType ))
2248 Handle(Geom_Surface) aPlane = makePlane( anAx1 );
2249 if ( aPlane.IsNull() )
2253 Handle(TColStd_HSequenceOfInteger) aSeq;
2254 aSeq = getShapesOnSurfaceIDs( aPlane, aShape, aShapeType, theState );
2256 // The GetShapesOnPlaneIDs() doesn't change object so no new function is required.
2257 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAx1)->GetLastFunction();
2259 // Make a Python command
2260 GEOM::TPythonDump(aFunction, /*append=*/true)
2261 << "listShapesOnPlane = geompy.GetShapesOnPlaneIDs"
2262 << "(" << theShape << "," << aShapeType << "," << theAx1 << "," << theState << ")";
2268 //=============================================================================
2270 * GetShapesOnPlaneWithLocationIDs
2272 //=============================================================================
2273 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnPlaneWithLocationIDs
2274 (const Handle(GEOM_Object)& theShape,
2275 const Standard_Integer theShapeType,
2276 const Handle(GEOM_Object)& theAx1,
2277 const Handle(GEOM_Object)& thePnt,
2278 const GEOMAlgo_State theState)
2282 if (theShape.IsNull() || theAx1.IsNull() || thePnt.IsNull()) return NULL;
2284 TopoDS_Shape aShape = theShape->GetValue();
2285 TopoDS_Shape anAx1 = theAx1->GetValue();
2286 TopoDS_Shape anPnt = thePnt->GetValue();
2288 if (aShape.IsNull() || anAx1.IsNull() || anPnt.IsNull()) return NULL;
2290 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2291 if ( !checkTypeShapesOn( aShapeType ))
2295 if (anAx1.ShapeType() != TopAbs_EDGE || anPnt.ShapeType() != TopAbs_VERTEX) return NULL;
2296 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
2297 TopoDS_Vertex V1, V2, V3;
2298 TopExp::Vertices(anEdge, V1, V2, Standard_True);
2299 if (V1.IsNull() || V2.IsNull()) {
2300 SetErrorCode("Bad edge given for the plane normal vector");
2303 V3 = TopoDS::Vertex(anPnt);
2305 SetErrorCode("Bad vertex given for the plane location");
2308 gp_Pnt aLoc = BRep_Tool::Pnt(V3);
2309 gp_Vec aVec(BRep_Tool::Pnt(V1),BRep_Tool::Pnt(V2));
2310 if (aVec.Magnitude() < Precision::Confusion()) {
2311 SetErrorCode("Vector with null magnitude given");
2315 Handle(Geom_Surface) aPlane = new Geom_Plane(aLoc, aVec);
2316 if ( aPlane.IsNull() )
2320 Handle(TColStd_HSequenceOfInteger) aSeq;
2321 aSeq = getShapesOnSurfaceIDs( aPlane, aShape, aShapeType, theState );
2323 // The GetShapesOnPlaneIDs() doesn't change object so no new function is required.
2324 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAx1)->GetLastFunction();
2326 // Make a Python command
2327 GEOM::TPythonDump(aFunction, /*append=*/true)
2328 << "listShapesOnPlane = geompy.GetShapesOnPlaneWithLocationIDs"
2329 << "(" << theShape << ", " << aShapeType << ", " << theAx1 << ", "<< thePnt << ", " << theState << ")";
2335 //=============================================================================
2337 * GetShapesOnCylinderIDs
2339 //=============================================================================
2340 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnCylinderIDs
2341 (const Handle(GEOM_Object)& theShape,
2342 const Standard_Integer theShapeType,
2343 const Handle(GEOM_Object)& theAxis,
2344 const Standard_Real theRadius,
2345 const GEOMAlgo_State theState)
2349 if (theShape.IsNull() || theAxis.IsNull()) return NULL;
2351 TopoDS_Shape aShape = theShape->GetValue();
2352 TopoDS_Shape anAxis = theAxis->GetValue();
2354 if (aShape.IsNull() || anAxis.IsNull()) return NULL;
2356 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2357 if ( !checkTypeShapesOn( aShapeType ))
2360 // Create a cylinder surface
2361 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
2362 if ( aCylinder.IsNull() )
2366 Handle(TColStd_HSequenceOfInteger) aSeq;
2367 aSeq = getShapesOnSurfaceIDs( aCylinder, aShape, aShapeType, theState );
2369 // The GetShapesOnCylinder() doesn't change object so no new function is required.
2370 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAxis)->GetLastFunction();
2372 // Make a Python command
2373 GEOM::TPythonDump(aFunction, /*append=*/true)
2374 << "listShapesOnCylinder = geompy.GetShapesOnCylinderIDs"
2375 << "(" << theShape << ", " << aShapeType << ", " << theAxis << ", "
2376 << theRadius << ", " << theState << ")";
2382 //=============================================================================
2384 * GetShapesOnSphereIDs
2386 //=============================================================================
2387 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnSphereIDs
2388 (const Handle(GEOM_Object)& theShape,
2389 const Standard_Integer theShapeType,
2390 const Handle(GEOM_Object)& theCenter,
2391 const Standard_Real theRadius,
2392 const GEOMAlgo_State theState)
2396 if (theShape.IsNull() || theCenter.IsNull()) return NULL;
2398 TopoDS_Shape aShape = theShape->GetValue();
2399 TopoDS_Shape aCenter = theCenter->GetValue();
2401 if (aShape.IsNull() || aCenter.IsNull()) return NULL;
2403 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2404 if ( !checkTypeShapesOn( aShapeType ))
2407 // Center of the sphere
2408 if (aCenter.ShapeType() != TopAbs_VERTEX) return NULL;
2409 gp_Pnt aLoc = BRep_Tool::Pnt(TopoDS::Vertex(aCenter));
2411 gp_Ax3 anAx3 (aLoc, gp::DZ());
2412 Handle(Geom_SphericalSurface) aSphere =
2413 new Geom_SphericalSurface(anAx3, theRadius);
2416 Handle(TColStd_HSequenceOfInteger) aSeq;
2417 aSeq = getShapesOnSurfaceIDs( aSphere, aShape, aShapeType, theState );
2419 // The GetShapesOnSphere() doesn't change object so no new function is required.
2420 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theCenter)->GetLastFunction();
2422 // Make a Python command
2423 GEOM::TPythonDump(aFunction, /*append=*/true)
2424 << "listShapesOnCylinder = geompy.GetShapesOnCylinderIDs"
2425 << "(" << theShape << ", " << aShapeType << ", " << theCenter << ", "
2426 << theRadius << ", " << theState << ")";
2432 //=======================================================================
2433 //function : getShapesOnQuadrangleIDs
2435 * \brief Find IDs of subshapes complying with given status about quadrangle
2436 * \param theShape - the shape to explore
2437 * \param theShapeType - type of subshape of theShape
2438 * \param theTopLeftPoint - top left quadrangle corner
2439 * \param theTopRigthPoint - top right quadrangle corner
2440 * \param theBottomLeftPoint - bottom left quadrangle corner
2441 * \param theBottomRigthPoint - bottom right quadrangle corner
2442 * \param theState - required state
2443 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
2445 //=======================================================================
2447 Handle(TColStd_HSequenceOfInteger)
2448 GEOMImpl_IShapesOperations::getShapesOnQuadrangleIDs (const Handle(GEOM_Object)& theShape,
2449 const Standard_Integer theShapeType,
2450 const Handle(GEOM_Object)& theTopLeftPoint,
2451 const Handle(GEOM_Object)& theTopRigthPoint,
2452 const Handle(GEOM_Object)& theBottomLeftPoint,
2453 const Handle(GEOM_Object)& theBottomRigthPoint,
2454 const GEOMAlgo_State theState)
2458 if ( theShape.IsNull() ||
2459 theTopLeftPoint.IsNull() ||
2460 theTopRigthPoint.IsNull() ||
2461 theBottomLeftPoint.IsNull() ||
2462 theBottomRigthPoint.IsNull() )
2465 TopoDS_Shape aShape = theShape->GetValue();
2466 TopoDS_Shape aTL = theTopLeftPoint->GetValue();
2467 TopoDS_Shape aTR = theTopRigthPoint->GetValue();
2468 TopoDS_Shape aBL = theBottomLeftPoint->GetValue();
2469 TopoDS_Shape aBR = theBottomRigthPoint->GetValue();
2471 if (aShape.IsNull() ||
2476 aTL.ShapeType() != TopAbs_VERTEX ||
2477 aTR.ShapeType() != TopAbs_VERTEX ||
2478 aBL.ShapeType() != TopAbs_VERTEX ||
2479 aBR.ShapeType() != TopAbs_VERTEX )
2482 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2483 if ( !checkTypeShapesOn( aShapeType ))
2486 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
2488 // Check presence of triangulation, build if need
2489 if (!CheckTriangulation(aShape)) {
2490 SetErrorCode("Cannot build triangulation on the shape");
2495 gp_Pnt aPntTL = BRep_Tool::Pnt(TopoDS::Vertex(aTL));
2496 gp_Pnt aPntTR = BRep_Tool::Pnt(TopoDS::Vertex(aTR));
2497 gp_Pnt aPntBL = BRep_Tool::Pnt(TopoDS::Vertex(aBL));
2498 gp_Pnt aPntBR = BRep_Tool::Pnt(TopoDS::Vertex(aBR));
2500 GEOMAlgo_FinderShapeOnQuad aFinder( aPntTL, aPntTR, aPntBL, aPntBR );
2501 Standard_Real aTol = 0.0001; // default value
2503 aFinder.SetShape(aShape);
2504 aFinder.SetTolerance(aTol);
2505 //aFinder.SetSurface(theSurface);
2506 aFinder.SetShapeType(aShapeType);
2507 aFinder.SetState(theState);
2509 // Sets the minimal number of inner points for the faces that do not have own
2510 // inner points at all (for e.g. rectangular planar faces have just 2 triangles).
2512 aFinder.SetNbPntsMin(3);
2513 // Sets the maximal number of inner points for edges or faces.
2514 // It is usefull for the cases when this number is very big (e.g =2000) to improve
2515 // the performance. If this value =0, all inner points will be taken into account.
2517 aFinder.SetNbPntsMax(100);
2521 // Interprete results
2522 Standard_Integer iErr = aFinder.ErrorStatus();
2523 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
2525 MESSAGE(" iErr : " << iErr);
2526 TCollection_AsciiString aMsg (" iErr : ");
2527 aMsg += TCollection_AsciiString(iErr);
2531 Standard_Integer iWrn = aFinder.WarningStatus();
2532 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
2534 MESSAGE(" *** iWrn : " << iWrn);
2537 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
2539 if (listSS.Extent() < 1) {
2540 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
2541 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
2545 // Fill sequence of object IDs
2546 aSeqOfIDs = new TColStd_HSequenceOfInteger;
2548 TopTools_IndexedMapOfShape anIndices;
2549 TopExp::MapShapes(aShape, anIndices);
2551 TopTools_ListIteratorOfListOfShape itSub (listSS);
2552 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
2553 int id = anIndices.FindIndex(itSub.Value());
2554 aSeqOfIDs->Append(id);
2559 //=======================================================================
2560 //function : GetShapesOnQuadrangle
2562 * \brief Find subshapes complying with given status about quadrangle
2563 * \param theShape - the shape to explore
2564 * \param theShapeType - type of subshape of theShape
2565 * \param theTopLeftPoint - top left quadrangle corner
2566 * \param theTopRigthPoint - top right quadrangle corner
2567 * \param theBottomLeftPoint - bottom left quadrangle corner
2568 * \param theBottomRigthPoint - bottom right quadrangle corner
2569 * \param theState - required state
2570 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
2572 //=======================================================================
2574 Handle(TColStd_HSequenceOfTransient)
2575 GEOMImpl_IShapesOperations::GetShapesOnQuadrangle (const Handle(GEOM_Object)& theShape,
2576 const Standard_Integer theShapeType,
2577 const Handle(GEOM_Object)& theTopLeftPoint,
2578 const Handle(GEOM_Object)& theTopRigthPoint,
2579 const Handle(GEOM_Object)& theBottomLeftPoint,
2580 const Handle(GEOM_Object)& theBottomRigthPoint,
2581 const GEOMAlgo_State theState)
2584 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2585 getShapesOnQuadrangleIDs( theShape,
2590 theBottomRigthPoint,
2592 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->IsEmpty() )
2595 // Find objects by indices
2596 TCollection_AsciiString anAsciiList;
2597 Handle(TColStd_HSequenceOfTransient) aSeq;
2598 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
2599 if ( aSeq.IsNull() || aSeq->IsEmpty() )
2602 // Make a Python command
2604 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2605 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2607 GEOM::TPythonDump(aFunction)
2608 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnQuadrangle("
2610 << TopAbs_ShapeEnum(theShapeType) << ", "
2611 << theTopLeftPoint << ", "
2612 << theTopRigthPoint << ", "
2613 << theBottomLeftPoint << ", "
2614 << theBottomRigthPoint << ", "
2621 //=======================================================================
2622 //function : GetShapesOnQuadrangleIDs
2624 * \brief Find IDs of subshapes complying with given status about quadrangle
2625 * \param theShape - the shape to explore
2626 * \param theShapeType - type of subshape of theShape
2627 * \param theTopLeftPoint - top left quadrangle corner
2628 * \param theTopRigthPoint - top right quadrangle corner
2629 * \param theBottomLeftPoint - bottom left quadrangle corner
2630 * \param theBottomRigthPoint - bottom right quadrangle corner
2631 * \param theState - required state
2632 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
2634 //=======================================================================
2636 Handle(TColStd_HSequenceOfInteger)
2637 GEOMImpl_IShapesOperations::GetShapesOnQuadrangleIDs (const Handle(GEOM_Object)& theShape,
2638 const Standard_Integer theShapeType,
2639 const Handle(GEOM_Object)& theTopLeftPoint,
2640 const Handle(GEOM_Object)& theTopRigthPoint,
2641 const Handle(GEOM_Object)& theBottomLeftPoint,
2642 const Handle(GEOM_Object)& theBottomRigthPoint,
2643 const GEOMAlgo_State theState)
2646 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2647 getShapesOnQuadrangleIDs( theShape,
2652 theBottomRigthPoint,
2654 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->IsEmpty() )
2657 // Make a Python command
2659 // The GetShapesOnCylinder() doesn't change object so no new function is required.
2660 Handle(GEOM_Object) lastObj = GEOM::GetCreatedLast(theShape,theTopLeftPoint);
2661 lastObj = GEOM::GetCreatedLast(lastObj,theTopRigthPoint);
2662 lastObj = GEOM::GetCreatedLast(lastObj,theBottomRigthPoint);
2663 lastObj = GEOM::GetCreatedLast(lastObj,theBottomLeftPoint);
2664 Handle(GEOM_Function) aFunction = lastObj->GetLastFunction();
2666 GEOM::TPythonDump(aFunction, /*append=*/true)
2667 << "listShapesOnQuadrangle = geompy.GetShapesOnQuadrangleIDs("
2669 << TopAbs_ShapeEnum(theShapeType) << ", "
2670 << theTopLeftPoint << ", "
2671 << theTopRigthPoint << ", "
2672 << theBottomLeftPoint << ", "
2673 << theBottomRigthPoint << ", "
2681 //=============================================================================
2685 //=============================================================================
2686 static bool GetInPlaceOfShape (const Handle(GEOM_Function)& theWhereFunction,
2687 const TopTools_IndexedMapOfShape& theWhereIndices,
2688 const TopoDS_Shape& theWhat,
2689 TColStd_ListOfInteger& theModifiedList)
2691 if (theWhereFunction.IsNull() || theWhat.IsNull()) return false;
2693 if (theWhereIndices.Contains(theWhat)) {
2694 // entity was not changed by the operation
2695 Standard_Integer aWhatIndex = theWhereIndices.FindIndex(theWhat);
2696 theModifiedList.Append(aWhatIndex);
2700 // try to find in history
2701 TDF_Label aHistoryLabel = theWhereFunction->GetHistoryEntry(Standard_False);
2703 // search in history for all argument shapes
2704 Standard_Boolean isFound = Standard_False;
2705 Standard_Boolean isGood = Standard_False;
2707 TDF_LabelSequence aLabelSeq;
2708 theWhereFunction->GetDependency(aLabelSeq);
2709 Standard_Integer nbArg = aLabelSeq.Length();
2711 for (Standard_Integer iarg = 1; iarg <= nbArg && !isFound; iarg++) {
2713 TDF_Label anArgumentRefLabel = aLabelSeq.Value(iarg);
2715 Handle(GEOM_Object) anArgumentObject = GEOM_Object::GetReferencedObject(anArgumentRefLabel);
2716 TopoDS_Shape anArgumentShape = anArgumentObject->GetValue();
2718 TopTools_IndexedMapOfShape anArgumentIndices;
2719 TopExp::MapShapes(anArgumentShape, anArgumentIndices);
2721 if (anArgumentIndices.Contains(theWhat)) {
2722 isFound = Standard_True;
2723 Standard_Integer aWhatIndex = anArgumentIndices.FindIndex(theWhat);
2725 // Find corresponding label in history
2726 TDF_Label anArgumentHistoryLabel =
2727 theWhereFunction->GetArgumentHistoryEntry(anArgumentRefLabel, Standard_False);
2728 if (anArgumentHistoryLabel.IsNull()) {
2729 // Lost History of operation argument. Possibly, all its entities was removed.
2730 isGood = Standard_True;
2733 TDF_Label aWhatHistoryLabel = anArgumentHistoryLabel.FindChild(aWhatIndex, Standard_False);
2735 if (aWhatHistoryLabel.IsNull()) {
2736 // Removed entity ? Compound ? Compsolid ? Shell ? Wire
2737 isGood = Standard_False;
2739 Handle(TDataStd_IntegerArray) anIntegerArray;
2740 if (!aWhatHistoryLabel.FindAttribute(TDataStd_IntegerArray::GetID(), anIntegerArray)) {
2741 //Error: Empty modifications history for the sought shape.
2742 isGood = Standard_False;
2745 isGood = Standard_True;
2746 Standard_Integer imod, aModifLen = anIntegerArray->Array()->Length();
2747 for (imod = 1; imod <= aModifLen; imod++) {
2748 theModifiedList.Append(anIntegerArray->Array()->Value(imod));
2759 // try compound/compsolid/shell/wire element by element
2760 bool isFoundAny = false;
2761 TopTools_MapOfShape mapShape;
2763 if (theWhat.ShapeType() == TopAbs_COMPOUND ||
2764 theWhat.ShapeType() == TopAbs_COMPSOLID) {
2765 // recursive processing of compound/compsolid
2766 TopoDS_Iterator anIt (theWhat, Standard_True, Standard_True);
2767 for (; anIt.More(); anIt.Next()) {
2768 if (mapShape.Add(anIt.Value())) {
2769 TopoDS_Shape curWhat = anIt.Value();
2770 isFoundAny = GetInPlaceOfShape(theWhereFunction, theWhereIndices, curWhat, theModifiedList);
2771 if (isFoundAny) isFound = Standard_True;
2775 else if (theWhat.ShapeType() == TopAbs_SHELL) {
2776 // try to replace a shell by its faces images
2777 TopExp_Explorer anExp (theWhat, TopAbs_FACE);
2778 for (; anExp.More(); anExp.Next()) {
2779 if (mapShape.Add(anExp.Current())) {
2780 TopoDS_Shape curWhat = anExp.Current();
2781 isFoundAny = GetInPlaceOfShape(theWhereFunction, theWhereIndices, curWhat, theModifiedList);
2782 if (isFoundAny) isFound = Standard_True;
2786 else if (theWhat.ShapeType() == TopAbs_WIRE) {
2787 // try to replace a wire by its edges images
2788 TopExp_Explorer anExp (theWhat, TopAbs_EDGE);
2789 for (; anExp.More(); anExp.Next()) {
2790 if (mapShape.Add(anExp.Current())) {
2791 TopoDS_Shape curWhat = anExp.Current();
2792 isFoundAny = GetInPlaceOfShape(theWhereFunction, theWhereIndices, curWhat, theModifiedList);
2793 if (isFoundAny) isFound = Standard_True;
2805 //=============================================================================
2807 * GetShapeProperties
2809 //=============================================================================
2811 void GEOMImpl_IShapesOperations::GetShapeProperties( const TopoDS_Shape aShape, Standard_Real tab[],
2814 GProp_GProps theProps;
2816 TopoDS_Shape aPntShape;
2817 Standard_Real aShapeSize;
2819 if (aShape.ShapeType() == TopAbs_EDGE) BRepGProp::LinearProperties(aShape, theProps);
2820 else if (aShape.ShapeType() == TopAbs_FACE) BRepGProp::SurfaceProperties(aShape, theProps);
2821 else BRepGProp::VolumeProperties(aShape, theProps);
2823 aCenterMass = theProps.CentreOfMass();
2824 aShapeSize = theProps.Mass();
2826 aPntShape = BRepBuilderAPI_MakeVertex(aCenterMass).Shape();
2827 aVertex = BRep_Tool::Pnt( TopoDS::Vertex( aPntShape ) );
2828 tab[0] = aVertex.X();
2829 tab[1] = aVertex.Y();
2830 tab[2] = aVertex.Z();
2831 tab[3] = aShapeSize;
2835 //=============================================================================
2839 //=============================================================================
2840 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlace (Handle(GEOM_Object) theShapeWhere,
2841 Handle(GEOM_Object) theShapeWhat)
2845 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
2847 TopoDS_Shape aWhere = theShapeWhere->GetValue();
2848 TopoDS_Shape aWhat = theShapeWhat->GetValue();
2849 TopoDS_Shape aPntShape;
2850 TopoDS_Vertex aVertex;
2852 if (aWhere.IsNull() || aWhat.IsNull()) {
2853 SetErrorCode("Error: aWhere and aWhat TopoDS_Shape are Null.");
2857 Handle(GEOM_Function) aWhereFunction = theShapeWhere->GetLastFunction();
2858 if (aWhereFunction.IsNull()) {
2859 SetErrorCode("Error: aWhereFunction is Null.");
2863 TopTools_IndexedMapOfShape aWhereIndices;
2864 TopExp::MapShapes(aWhere, aWhereIndices);
2866 TColStd_ListOfInteger aModifiedList;
2867 Standard_Integer aWhereIndex;
2868 Handle(TColStd_HArray1OfInteger) aModifiedArray;
2869 Handle(GEOM_Object) aResult;
2871 bool isFound = false;
2872 Standard_Integer iType = TopAbs_SOLID;
2873 Standard_Integer compType = TopAbs_SOLID;
2874 Standard_Real aWhat_Mass = 0., aWhere_Mass = 0.;
2875 Standard_Real tab_aWhat[4], tab_aWhere[4];
2876 Standard_Real dl_l = 1e-3;
2877 Standard_Real min_l, Tol_1D, Tol_2D, Tol_3D, Tol_Mass;
2878 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
2879 Bnd_Box BoundingBox;
2880 gp_Pnt aPnt, aPnt_aWhat, tab_Pnt[2];
2881 GProp_GProps aProps;
2883 // Find the iType of the aWhat shape
2884 if ( aWhat.ShapeType() == TopAbs_EDGE || aWhat.ShapeType() == TopAbs_WIRE ) iType = TopAbs_EDGE;
2885 else if ( aWhat.ShapeType() == TopAbs_FACE || aWhat.ShapeType() == TopAbs_SHELL ) iType = TopAbs_FACE;
2886 else if ( aWhat.ShapeType() == TopAbs_SOLID || aWhat.ShapeType() == TopAbs_COMPSOLID ) iType = TopAbs_SOLID;
2887 else if ( aWhat.ShapeType() == TopAbs_COMPOUND ) {
2888 // Only the iType of the first shape in the compound is taken into account
2889 TopoDS_Iterator It (aWhat, Standard_True, Standard_True);
2890 compType = It.Value().ShapeType();
2891 if ( compType == TopAbs_EDGE || compType == TopAbs_WIRE ) iType = TopAbs_EDGE;
2892 else if ( compType == TopAbs_FACE || compType == TopAbs_SHELL) iType = TopAbs_FACE;
2893 else if ( compType == TopAbs_SOLID || compType == TopAbs_COMPSOLID) iType = TopAbs_SOLID;
2896 SetErrorCode("Error: An attempt to extract a shape of not supported type.");
2900 TopExp_Explorer Exp_aWhat( aWhat, TopAbs_ShapeEnum( iType ) );
2901 TopExp_Explorer Exp_aWhere( aWhere, TopAbs_ShapeEnum( iType ) );
2902 TopExp_Explorer Exp_Edge( aWhere, TopAbs_EDGE );
2904 // Find the shortest edge in theShapeWhere shape
2905 BRepBndLib::Add(aWhere, BoundingBox);
2906 BoundingBox.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
2907 min_l = fabs(aXmax - aXmin);
2908 if( min_l < fabs(aYmax - aYmin) ) min_l = fabs(aYmax - aYmin);
2909 if( min_l < fabs(aZmax - aZmin) ) min_l = fabs(aZmax - aZmin);
2911 for ( Standard_Integer nbEdge = 0; Exp_Edge.More(); Exp_Edge.Next(), nbEdge++ ) {
2912 TopExp_Explorer Exp_Vertex( Exp_Edge.Current(), TopAbs_VERTEX);
2913 for ( Standard_Integer nbVertex = 0; Exp_Vertex.More(); Exp_Vertex.Next(), nbVertex++ ) {
2914 aPnt = BRep_Tool::Pnt( TopoDS::Vertex( Exp_Vertex.Current() ) );
2915 tab_Pnt[nbVertex] = aPnt;
2917 if ( not tab_Pnt[0].IsEqual(tab_Pnt[1], dl_l) ) {
2918 BRepGProp::LinearProperties(Exp_Edge.Current(), aProps);
2919 if ( aProps.Mass() < min_l ) min_l = aProps.Mass();
2923 // Compute tolerances
2924 Tol_1D = dl_l * min_l;
2925 Tol_2D = dl_l * ( min_l * min_l) * ( 2. + dl_l);
2926 Tol_3D = dl_l * ( min_l * min_l * min_l ) * ( 3. + (3 * dl_l) + (dl_l * dl_l) );
2929 if ( iType == TopAbs_EDGE ) Tol_Mass = Tol_1D;
2930 else if ( iType == TopAbs_FACE ) Tol_Mass = Tol_2D;
2932 // Compute the ShapeWhat Mass
2933 for ( ; Exp_aWhat.More(); Exp_aWhat.Next() ) {
2934 if ( iType == TopAbs_EDGE ) BRepGProp::LinearProperties(Exp_aWhat.Current(), aProps);
2935 else if ( iType == TopAbs_FACE ) BRepGProp::SurfaceProperties(Exp_aWhat.Current(), aProps);
2936 else BRepGProp::VolumeProperties(Exp_aWhat.Current(), aProps);
2937 aWhat_Mass += aProps.Mass();
2940 // Searching for the sub-shapes inside the ShapeWhere shape
2941 for ( Exp_aWhere.ReInit(); Exp_aWhere.More(); Exp_aWhere.Next() ) {
2942 GetShapeProperties( Exp_aWhere.Current(), tab_aWhere, aPnt );
2943 for ( Exp_aWhat.ReInit(); Exp_aWhat.More(); Exp_aWhat.Next() ) {
2944 GetShapeProperties( Exp_aWhat.Current(), tab_aWhat, aPnt_aWhat );
2945 if ( fabs(tab_aWhat[3] - tab_aWhere[3]) <= Tol_Mass && aPnt_aWhat.Distance(aPnt) <= Tol_1D ) isFound = true;
2947 if ( (tab_aWhat[3] - tab_aWhere[3]) > Tol_Mass ) {
2948 aPntShape = BRepBuilderAPI_MakeVertex( aPnt ).Shape();
2949 aVertex = TopoDS::Vertex( aPntShape );
2950 BRepExtrema_DistShapeShape aWhereDistance ( aVertex, Exp_aWhere.Current() );
2951 BRepExtrema_DistShapeShape aWhatDistance ( aVertex, Exp_aWhat.Current() );
2952 if ( fabs(aWhereDistance.Value() - aWhatDistance.Value()) <= Tol_1D ) isFound = true;
2956 aWhereIndex = aWhereIndices.FindIndex(Exp_aWhere.Current());
2957 aModifiedList.Append(aWhereIndex);
2958 aWhere_Mass += tab_aWhere[3];
2963 if ( fabs( aWhat_Mass - aWhere_Mass ) <= Tol_Mass ) break;
2966 if (aModifiedList.Extent() == 0) { // Not found any Results
2967 SetErrorCode(NOT_FOUND_ANY);
2971 aModifiedArray = new TColStd_HArray1OfInteger (1, aModifiedList.Extent());
2972 TColStd_ListIteratorOfListOfInteger anIterModif (aModifiedList);
2973 for (Standard_Integer imod = 1; anIterModif.More(); anIterModif.Next(), imod++)
2974 aModifiedArray->SetValue(imod, anIterModif.Value());
2977 aResult = GetEngine()->AddSubShape(theShapeWhere, aModifiedArray);
2978 if (aResult.IsNull()) {
2979 SetErrorCode("Error in algorithm: result found, but cannot be returned.");
2983 if (aModifiedArray->Length() > 1) {
2985 aResult->SetType(GEOM_GROUP);
2987 //Set a sub shape type
2988 TopoDS_Shape aFirstFound = aWhereIndices.FindKey(aModifiedArray->Value(1));
2989 TopAbs_ShapeEnum aShapeType = aFirstFound.ShapeType();
2991 TDF_Label aFreeLabel = aResult->GetFreeLabel();
2992 TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aShapeType);
2995 //Make a Python command
2996 Handle(GEOM_Function) aFunction = aResult->GetFunction(1);
2998 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetInPlace("
2999 << theShapeWhere << ", " << theShapeWhat << ")";
3005 //=======================================================================
3006 //function : GetInPlaceByHistory
3008 //=======================================================================
3009 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlaceByHistory
3010 (Handle(GEOM_Object) theShapeWhere,
3011 Handle(GEOM_Object) theShapeWhat)
3015 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
3017 TopoDS_Shape aWhere = theShapeWhere->GetValue();
3018 TopoDS_Shape aWhat = theShapeWhat->GetValue();
3020 if (aWhere.IsNull() || aWhat.IsNull()) return NULL;
3022 Handle(GEOM_Function) aWhereFunction = theShapeWhere->GetLastFunction();
3023 if (aWhereFunction.IsNull()) return NULL;
3025 //Fill array of indices
3026 TopTools_IndexedMapOfShape aWhereIndices;
3027 TopExp::MapShapes(aWhere, aWhereIndices);
3030 TColStd_ListOfInteger aModifiedList;
3031 bool isFound = GetInPlaceOfShape(aWhereFunction, aWhereIndices, aWhat, aModifiedList);
3033 if (!isFound || aModifiedList.Extent() < 1) {
3034 SetErrorCode("Error: No history found for the sought shape or its sub-shapes.");
3038 Handle(TColStd_HArray1OfInteger) aModifiedArray =
3039 new TColStd_HArray1OfInteger (1, aModifiedList.Extent());
3040 TColStd_ListIteratorOfListOfInteger anIterModif (aModifiedList);
3041 for (Standard_Integer imod = 1; anIterModif.More(); anIterModif.Next(), imod++) {
3042 aModifiedArray->SetValue(imod, anIterModif.Value());
3046 Handle(GEOM_Object) aResult = GetEngine()->AddSubShape(theShapeWhere, aModifiedArray);
3047 if (aResult.IsNull()) {
3048 SetErrorCode("Error in algorithm: result found, but cannot be returned.");
3052 if (aModifiedArray->Length() > 1) {
3054 aResult->SetType(GEOM_GROUP);
3056 //Set a sub shape type
3057 TopoDS_Shape aFirstFound = aWhereIndices.FindKey(aModifiedArray->Value(1));
3058 TopAbs_ShapeEnum aShapeType = aFirstFound.ShapeType();
3060 TDF_Label aFreeLabel = aResult->GetFreeLabel();
3061 TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aShapeType);
3064 //Make a Python command
3065 Handle(GEOM_Function) aFunction = aResult->GetFunction(1);
3067 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetInPlace("
3068 << theShapeWhere << ", " << theShapeWhat << ")";
3074 //=======================================================================
3075 //function : SortShapes
3077 //=======================================================================
3078 void GEOMImpl_IShapesOperations::SortShapes(TopTools_ListOfShape& SL)
3080 Standard_Integer MaxShapes = SL.Extent();
3081 TopTools_Array1OfShape aShapes (1,MaxShapes);
3082 TColStd_Array1OfInteger OrderInd(1,MaxShapes);
3083 TColStd_Array1OfReal MidXYZ (1,MaxShapes); //X,Y,Z;
3084 TColStd_Array1OfReal Length (1,MaxShapes); //X,Y,Z;
3086 // Computing of CentreOfMass
3087 Standard_Integer Index;
3090 TopTools_ListIteratorOfListOfShape it(SL);
3091 for (Index=1; it.More(); Index++)
3093 TopoDS_Shape S = it.Value();
3094 SL.Remove( it ); // == it.Next()
3096 OrderInd.SetValue (Index, Index);
3097 if (S.ShapeType() == TopAbs_VERTEX)
3099 GPoint = BRep_Tool::Pnt( TopoDS::Vertex( S ));
3100 Length.SetValue( Index, (Standard_Real) S.Orientation());
3104 BRepGProp::LinearProperties (S, GPr);
3105 GPoint = GPr.CentreOfMass();
3106 Length.SetValue( Index, GPr.Mass() );
3108 MidXYZ.SetValue(Index,
3109 GPoint.X()*999 + GPoint.Y()*99 + GPoint.Z()*0.9);
3110 //cout << Index << " L: " << Length(Index) << "CG: " << MidXYZ(Index) << endl;
3114 Standard_Integer aTemp;
3115 Standard_Boolean exchange, Sort = Standard_True;
3116 Standard_Real tol = Precision::Confusion();
3119 Sort = Standard_False;
3120 for (Index=1; Index < MaxShapes; Index++)
3122 Standard_Real dMidXYZ = MidXYZ(OrderInd(Index)) - MidXYZ(OrderInd(Index+1));
3123 Standard_Real dLength = Length(OrderInd(Index)) - Length(OrderInd(Index+1));
3124 if ( dMidXYZ >= tol ) {
3125 // cout << "MidXYZ: " << MidXYZ(OrderInd(Index))<< " > " <<MidXYZ(OrderInd(Index+1))
3126 // << " d: " << dMidXYZ << endl;
3127 exchange = Standard_True;
3129 else if ( Abs(dMidXYZ) < tol && dLength >= tol ) {
3130 // cout << "Length: " << Length(OrderInd(Index))<< " > " <<Length(OrderInd(Index+1))
3131 // << " d: " << dLength << endl;
3132 exchange = Standard_True;
3134 else if ( Abs(dMidXYZ) < tol && Abs(dLength) < tol &&
3135 aShapes(OrderInd(Index)).ShapeType() <= TopAbs_FACE) {
3137 // equal values possible on shapes such as two halves of a sphere and
3138 // a membrane inside the sphere
3140 BRepBndLib::Add( aShapes( OrderInd(Index) ), box1 );
3141 if ( box1.IsVoid() ) continue;
3142 BRepBndLib::Add( aShapes( OrderInd(Index+1) ), box2 );
3143 Standard_Real dSquareExtent = box1.SquareExtent() - box2.SquareExtent();
3144 if ( dSquareExtent >= tol ) {
3145 // cout << "SquareExtent: " << box1.SquareExtent()<<" > "<<box2.SquareExtent() << endl;
3146 exchange = Standard_True;
3148 else if ( Abs(dSquareExtent) < tol ) {
3149 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax, val1, val2;
3150 box1.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
3151 val1 = (aXmin+aXmax)*999 + (aYmin+aYmax)*99 + (aZmin+aZmax)*0.9;
3152 box2.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
3153 val2 = (aXmin+aXmax)*999 + (aYmin+aYmax)*99 + (aZmin+aZmax)*0.9;
3154 exchange = val1 > val2;
3155 // cout << "box: " << val1<<" > "<<val2 << endl;
3159 exchange = Standard_False;
3163 // cout << "exchange " << Index << " & " << Index+1 << endl;
3164 aTemp = OrderInd(Index);
3165 OrderInd(Index) = OrderInd(Index+1);
3166 OrderInd(Index+1) = aTemp;
3167 Sort = Standard_True;
3172 for (Index=1; Index <= MaxShapes; Index++)
3173 SL.Append( aShapes( OrderInd(Index) ));
3176 //=======================================================================
3177 //function : CompsolidToCompound
3179 //=======================================================================
3180 TopoDS_Shape GEOMImpl_IShapesOperations::CompsolidToCompound (const TopoDS_Shape& theCompsolid)
3182 if (theCompsolid.ShapeType() != TopAbs_COMPSOLID) {
3183 return theCompsolid;
3186 TopoDS_Compound aCompound;
3188 B.MakeCompound(aCompound);
3190 TopTools_MapOfShape mapShape;
3191 TopoDS_Iterator It (theCompsolid, Standard_True, Standard_True);
3193 for (; It.More(); It.Next()) {
3194 TopoDS_Shape aShape_i = It.Value();
3195 if (mapShape.Add(aShape_i)) {
3196 B.Add(aCompound, aShape_i);
3203 //=======================================================================
3204 //function : CheckTriangulation
3206 //=======================================================================
3207 bool GEOMImpl_IShapesOperations::CheckTriangulation (const TopoDS_Shape& aShape)
3209 bool isTriangulation = true;
3211 TopExp_Explorer exp (aShape, TopAbs_FACE);
3214 TopLoc_Location aTopLoc;
3215 Handle(Poly_Triangulation) aTRF;
3216 aTRF = BRep_Tool::Triangulation(TopoDS::Face(exp.Current()), aTopLoc);
3217 if (aTRF.IsNull()) {
3218 isTriangulation = false;
3221 else // no faces, try edges
3223 TopExp_Explorer expe (aShape, TopAbs_EDGE);
3227 TopLoc_Location aLoc;
3228 Handle(Poly_Polygon3D) aPE = BRep_Tool::Polygon3D(TopoDS::Edge(expe.Current()), aLoc);
3230 isTriangulation = false;
3234 if (!isTriangulation) {
3235 // calculate deflection
3236 Standard_Real aDeviationCoefficient = 0.001;
3239 BRepBndLib::Add(aShape, B);
3240 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
3241 B.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
3243 Standard_Real dx = aXmax - aXmin, dy = aYmax - aYmin, dz = aZmax - aZmin;
3244 Standard_Real aDeflection = Max(Max(dx, dy), dz) * aDeviationCoefficient * 4;
3245 Standard_Real aHLRAngle = 0.349066;
3247 BRepMesh_IncrementalMesh Inc (aShape, aDeflection, Standard_False, aHLRAngle);
3253 #define MAX_TOLERANCE 1.e-7
3256 //=======================================================================
3257 //function : isSameEdge
3258 //purpose : Returns True if two edges coincide
3259 //=======================================================================
3260 static bool isSameEdge(const TopoDS_Edge& theEdge1, const TopoDS_Edge& theEdge2)
3262 TopoDS_Vertex V11, V12, V21, V22;
3263 TopExp::Vertices(theEdge1, V11, V12);
3264 TopExp::Vertices(theEdge2, V21, V22);
3265 gp_Pnt P11 = BRep_Tool::Pnt(V11);
3266 gp_Pnt P12 = BRep_Tool::Pnt(V12);
3267 gp_Pnt P21 = BRep_Tool::Pnt(V21);
3268 gp_Pnt P22 = BRep_Tool::Pnt(V22);
3269 bool coincide = false;
3271 //Check that ends of edges coincide
3272 if(P11.Distance(P21) <= MAX_TOLERANCE) {
3273 if(P12.Distance(P22) <= MAX_TOLERANCE) coincide = true;
3275 else if(P11.Distance(P22) <= MAX_TOLERANCE) {
3276 if(P12.Distance(P21) <= MAX_TOLERANCE) coincide = true;
3279 if(!coincide) return false;
3281 if (BRep_Tool::Degenerated(theEdge1))
3282 if (BRep_Tool::Degenerated(theEdge2)) return true;
3285 if (BRep_Tool::Degenerated(theEdge2)) return false;
3287 double U11, U12, U21, U22;
3288 Handle(Geom_Curve) C1 = BRep_Tool::Curve(theEdge1, U11, U12);
3289 Handle(Geom_Curve) C2 = BRep_Tool::Curve(theEdge2, U21, U22);
3290 if(C1->DynamicType() == C2->DynamicType()) return true;
3292 //Check that both edges has the same geometry
3293 double range = U12-U11;
3294 double U = U11+ range/3.0;
3295 gp_Pnt P1 = C1->Value(U); //Compute a point on one third of the edge's length
3296 U = U11+range*2.0/3.0;
3297 gp_Pnt P2 = C1->Value(U); //Compute a point on two thirds of the edge's length
3299 if(!GeomLib_Tool::Parameter(C2, P1, MAX_TOLERANCE, U) || U < U21 || U > U22)
3302 if(P1.Distance(C2->Value(U)) > MAX_TOLERANCE) return false;
3304 if(!GeomLib_Tool::Parameter(C2, P2, MAX_TOLERANCE, U) || U < U21 || U > U22)
3307 if(P2.Distance(C2->Value(U)) > MAX_TOLERANCE) return false;
3312 #include <TopoDS_TShape.hxx>
3313 //=======================================================================
3314 //function : isSameFace
3315 //purpose : Returns True if two faces coincide
3316 //=======================================================================
3317 static bool isSameFace(const TopoDS_Face& theFace1, const TopoDS_Face& theFace2)
3319 TopExp_Explorer E(theFace1, TopAbs_EDGE);
3320 TopTools_ListOfShape LS1, LS2;
3321 for(; E.More(); E.Next()) LS1.Append(E.Current());
3323 E.Init(theFace2, TopAbs_EDGE);
3324 for(; E.More(); E.Next()) LS2.Append(E.Current());
3326 //Compare the number of edges in the faces
3327 if(LS1.Extent() != LS2.Extent()) return false;
3329 double aMin = RealFirst(), aMax = RealLast();
3330 double xminB1=aMax, yminB1=aMax, zminB1=aMax, xminB2=aMax, yminB2=aMax, zminB2=aMax;
3331 double xmaxB1=aMin, ymaxB1=aMin, zmaxB1=aMin, xmaxB2=aMin, ymaxB2=aMin, zmaxB2=aMin;
3333 for(E.Init(theFace1, TopAbs_VERTEX); E.More(); E.Next()) {
3334 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
3335 if(P.X() < xminB1) xminB1 = P.X();
3336 if(P.Y() < yminB1) yminB1 = P.Y();
3337 if(P.Z() < zminB1) zminB1 = P.Z();
3338 if(P.X() > xmaxB1) xmaxB1 = P.X();
3339 if(P.Y() > ymaxB1) ymaxB1 = P.Y();
3340 if(P.Z() > zmaxB1) zmaxB1 = P.Z();
3343 for(E.Init(theFace2, TopAbs_VERTEX); E.More(); E.Next()) {
3344 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
3345 if(P.X() < xminB2) xminB2 = P.X();
3346 if(P.Y() < yminB2) yminB2 = P.Y();
3347 if(P.Z() < zminB2) zminB2 = P.Z();
3348 if(P.X() > xmaxB2) xmaxB2 = P.X();
3349 if(P.Y() > ymaxB2) ymaxB2 = P.Y();
3350 if(P.Z() > zmaxB2) zmaxB2 = P.Z();
3354 //Compare the bounding boxes of both faces
3355 if(gp_Pnt(xminB1, yminB1, zminB1).Distance(gp_Pnt(xminB2, yminB2, zminB2)) > MAX_TOLERANCE)
3358 if(gp_Pnt(xmaxB1, ymaxB1, zmaxB1).Distance(gp_Pnt(xmaxB2, ymaxB2, zmaxB2)) > MAX_TOLERANCE)
3361 Handle(Geom_Surface) S1 = BRep_Tool::Surface(theFace1);
3362 Handle(Geom_Surface) S2 = BRep_Tool::Surface(theFace2);
3364 //Check if there a coincidence of two surfaces at least in two points
3365 double U11, U12, V11, V12, U21, U22, V21, V22;
3366 BRepTools::UVBounds(theFace1, U11, U12, V11, V12);
3367 BRepTools::UVBounds(theFace2, U21, U22, V21, V22);
3369 double rangeU = U12-U11;
3370 double rangeV = V12-V11;
3371 double U = U11 + rangeU/3.0;
3372 double V = V11 + rangeV/3.0;
3373 gp_Pnt P1 = S1->Value(U, V);
3374 U = U11+rangeU*2.0/3.0;
3375 V = V11+rangeV*2.0/3.0;
3376 gp_Pnt P2 = S1->Value(U, V);
3378 if(!GeomLib_Tool::Parameters(S2, P1, MAX_TOLERANCE, U, V) || U < U21 || U > U22 || V < V21 || V > V22)
3381 if(P1.Distance(S2->Value(U,V)) > MAX_TOLERANCE) return false;
3383 if(!GeomLib_Tool::Parameters(S2, P2, MAX_TOLERANCE, U, V) || U < U21 || U > U22 || V < V21 || V > V22)
3386 if(P2.Distance(S2->Value(U, V)) > MAX_TOLERANCE) return false;
3388 //Check that each edge of the Face1 has a counterpart in the Face2
3389 TopTools_MapOfOrientedShape aMap;
3390 TopTools_ListIteratorOfListOfShape LSI1(LS1);
3391 for(; LSI1.More(); LSI1.Next()) {
3392 TopoDS_Edge E = TopoDS::Edge(LSI1.Value());
3393 bool isFound = false;
3394 TopTools_ListIteratorOfListOfShape LSI2(LS2);
3395 for(; LSI2.More(); LSI2.Next()) {
3396 TopoDS_Shape aValue = LSI2.Value();
3397 if(aMap.Contains(aValue)) continue; //To avoid checking already found edge several times
3398 if(isSameEdge(E, TopoDS::Edge(aValue))) {
3404 if(!isFound) return false;
3410 //=======================================================================
3411 //function : isSameSolid
3412 //purpose : Returns True if two solids coincide
3413 //=======================================================================
3414 bool isSameSolid(const TopoDS_Solid& theSolid1, const TopoDS_Solid& theSolid2)
3416 TopExp_Explorer E(theSolid1, TopAbs_FACE);
3417 TopTools_ListOfShape LS1, LS2;
3418 for(; E.More(); E.Next()) LS1.Append(E.Current());
3419 E.Init(theSolid2, TopAbs_FACE);
3420 for(; E.More(); E.Next()) LS2.Append(E.Current());
3422 if(LS1.Extent() != LS2.Extent()) return false;
3424 double aMin = RealFirst(), aMax = RealLast();
3425 double xminB1=aMax, yminB1=aMax, zminB1=aMax, xminB2=aMax, yminB2=aMax, zminB2=aMax;
3426 double xmaxB1=aMin, ymaxB1=aMin, zmaxB1=aMin, xmaxB2=aMin, ymaxB2=aMin, zmaxB2=aMin;
3428 for(E.Init(theSolid1, TopAbs_VERTEX); E.More(); E.Next()) {
3429 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
3430 if(P.X() < xminB1) xminB1 = P.X();
3431 if(P.Y() < yminB1) yminB1 = P.Y();
3432 if(P.Z() < zminB1) zminB1 = P.Z();
3433 if(P.X() > xmaxB1) xmaxB1 = P.X();
3434 if(P.Y() > ymaxB1) ymaxB1 = P.Y();
3435 if(P.Z() > zmaxB1) zmaxB1 = P.Z();
3438 for(E.Init(theSolid2, TopAbs_VERTEX); E.More(); E.Next()) {
3439 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
3440 if(P.X() < xminB2) xminB2 = P.X();
3441 if(P.Y() < yminB2) yminB2 = P.Y();
3442 if(P.Z() < zminB2) zminB2 = P.Z();
3443 if(P.X() > xmaxB2) xmaxB2 = P.X();
3444 if(P.Y() > ymaxB2) ymaxB2 = P.Y();
3445 if(P.Z() > zmaxB2) zmaxB2 = P.Z();
3448 //Compare the bounding boxes of both solids
3449 if(gp_Pnt(xminB1, yminB1, zminB1).Distance(gp_Pnt(xminB2, yminB2, zminB2)) > MAX_TOLERANCE)
3452 if(gp_Pnt(xmaxB1, ymaxB1, zmaxB1).Distance(gp_Pnt(xmaxB2, ymaxB2, zmaxB2)) > MAX_TOLERANCE)
3455 //Check that each face of the Solid1 has a counterpart in the Solid2
3456 TopTools_MapOfOrientedShape aMap;
3457 TopTools_ListIteratorOfListOfShape LSI1(LS1);
3458 for(; LSI1.More(); LSI1.Next()) {
3459 TopoDS_Face F = TopoDS::Face(LSI1.Value());
3460 bool isFound = false;
3461 TopTools_ListIteratorOfListOfShape LSI2(LS2);
3462 for(; LSI2.More(); LSI2.Next()) {
3463 if(aMap.Contains(LSI2.Value())) continue; //To avoid checking already found faces several times
3464 if(isSameFace(F, TopoDS::Face(LSI2.Value()))) {
3465 aMap.Add(LSI2.Value());
3470 if(!isFound) return false;
3476 //=======================================================================
3477 //function : GetSame
3479 //=======================================================================
3480 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetSame(const Handle(GEOM_Object)& theShapeWhere,
3481 const Handle(GEOM_Object)& theShapeWhat)
3484 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
3486 TopoDS_Shape aWhere = theShapeWhere->GetValue();
3487 TopoDS_Shape aWhat = theShapeWhat->GetValue();
3489 if (aWhere.IsNull() || aWhat.IsNull()) return NULL;
3492 bool isFound = false;
3493 TopoDS_Shape aSubShape;
3494 TopTools_MapOfShape aMap;
3496 switch(aWhat.ShapeType()) {
3497 case TopAbs_VERTEX: {
3498 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(aWhat));
3499 TopExp_Explorer E(aWhere, TopAbs_VERTEX);
3500 for(; E.More(); E.Next()) {
3501 if(!aMap.Add(E.Current())) continue;
3502 gp_Pnt P2 = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
3503 if(P.Distance(P2) <= MAX_TOLERANCE) {
3505 aSubShape = E.Current();
3512 TopoDS_Face aFace = TopoDS::Face(aWhat);
3513 TopExp_Explorer E(aWhere, TopAbs_FACE);
3514 for(; E.More(); E.Next()) {
3515 if(!aMap.Add(E.Current())) continue;
3516 if(isSameFace(aFace, TopoDS::Face(E.Current()))) {
3517 aSubShape = E.Current();
3525 TopoDS_Edge anEdge = TopoDS::Edge(aWhat);
3526 TopExp_Explorer E(aWhere, TopAbs_EDGE);
3527 for(; E.More(); E.Next()) {
3528 if(!aMap.Add(E.Current())) continue;
3529 if(isSameEdge(anEdge, TopoDS::Edge(E.Current()))) {
3530 aSubShape = E.Current();
3537 case TopAbs_SOLID: {
3538 TopoDS_Solid aSolid = TopoDS::Solid(aWhat);
3539 TopExp_Explorer E(aWhere, TopAbs_SOLID);
3540 for(; E.More(); E.Next()) {
3541 if(!aMap.Add(E.Current())) continue;
3542 if(isSameSolid(aSolid, TopoDS::Solid(E.Current()))) {
3543 aSubShape = E.Current();
3555 TopTools_IndexedMapOfShape anIndices;
3556 TopExp::MapShapes(aWhere, anIndices);
3557 if (anIndices.Contains(aSubShape))
3558 anIndex = anIndices.FindIndex(aSubShape);
3561 if(anIndex < 0) return NULL;
3563 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
3565 anArray->SetValue(1, anIndex);
3567 Handle(GEOM_Object) aResult = GetEngine()->AddSubShape(theShapeWhere, anArray);
3568 Handle(GEOM_Function) aFunction = aResult->GetLastFunction();
3570 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetSame("
3571 << theShapeWhere << ", " << theShapeWhat << ")";