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 Standard_Integer nbAllSubShape = anIndices.Extent();
804 TopTools_ListIteratorOfListOfShape itSub (listShape);
805 TCollection_AsciiString anAsciiList, anEntry;
806 for (int index = 1; itSub.More(); itSub.Next(), ++index)
808 TopoDS_Shape aValue = itSub.Value();
809 anArray = new TColStd_HArray1OfInteger(1,1);
810 anArray->SetValue(1, anIndices.FindIndex(aValue));
812 //anObj = GetEngine()->AddSubShape(theShape, anArray);
814 anObj = GetEngine()->AddObject(GetDocID(), GEOM_SUBSHAPE);
815 Handle(GEOM_Function) aFunction = anObj->AddFunction(GEOM_Object::GetSubShapeID(), 1);
816 if (aFunction.IsNull()) return aSeq;
818 GEOM_ISubShape aSSI (aFunction);
819 aSSI.SetMainShape(aMainShape);
820 aSSI.SetIndices(anArray);
822 // Set function value directly, as we know it.
823 // Usage of Solver here would lead to significant loss of time,
824 // because GEOM_SubShapeDriver will build TopTools_IndexedMapOfShape
825 // on the main shape for each being calculated sub-shape separately.
826 aFunction->SetValue(aValue);
829 if (!anObj.IsNull()) {
832 // for python command
833 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
834 anAsciiList += anEntry;
839 //Make a Python command
840 anAsciiList.Trunc(anAsciiList.Length() - 1);
842 GEOM::TPythonDump pd (aMainShape, /*append=*/true);
843 pd << "[" << anAsciiList.ToCString();
844 pd << "] = geompy.SubShapeAll" << (isSorted ? "Sorted(" : "(");
845 pd << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
852 //=============================================================================
856 //=============================================================================
857 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::SubShapeAllIDs
858 (Handle(GEOM_Object) theShape,
859 const Standard_Integer theShapeType,
860 const Standard_Boolean isSorted)
864 if (theShape.IsNull()) return NULL;
865 TopoDS_Shape aShape = theShape->GetValue();
866 if (aShape.IsNull()) return NULL;
868 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
869 TopTools_MapOfShape mapShape;
870 TopTools_ListOfShape listShape;
872 if (aShape.ShapeType() == TopAbs_COMPOUND &&
873 (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
874 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPSOLID ||
875 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPOUND)) {
876 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
877 for (; It.More(); It.Next()) {
878 if (mapShape.Add(It.Value())) {
879 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
880 TopAbs_ShapeEnum(theShapeType) == It.Value().ShapeType()) {
881 listShape.Append(It.Value());
886 TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
887 for (; exp.More(); exp.Next())
888 if (mapShape.Add(exp.Current()))
889 listShape.Append(exp.Current());
892 if (listShape.IsEmpty()) {
893 //SetErrorCode("The given shape has no sub-shapes of the requested type");
894 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
899 SortShapes(listShape);
901 TopTools_IndexedMapOfShape anIndices;
902 TopExp::MapShapes(aShape, anIndices);
903 Handle(TColStd_HArray1OfInteger) anArray;
905 TopTools_ListIteratorOfListOfShape itSub (listShape);
906 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
907 TopoDS_Shape aValue = itSub.Value();
908 aSeq->Append(anIndices.FindIndex(aValue));
911 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
913 //Make a Python command
914 GEOM::TPythonDump pd (aFunction, /*append=*/true);
915 pd << "listSubShapeIDs = geompy.SubShapeAll";
916 pd << (isSorted ? "SortedIDs(" : "IDs(");
917 pd << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
923 //=============================================================================
927 //=============================================================================
928 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetSubShape
929 (Handle(GEOM_Object) theMainShape,
930 const Standard_Integer theID)
934 if (theMainShape.IsNull()) return NULL;
936 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
937 anArray->SetValue(1, theID);
938 Handle(GEOM_Object) anObj = GetEngine()->AddSubShape(theMainShape, anArray,true);
939 if (anObj.IsNull()) {
940 SetErrorCode("Can not get a sub-shape with the given ID");
944 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
946 //Make a Python command
947 GEOM::TPythonDump(aFunction) << anObj << " = geompy.GetSubShape("
948 << theMainShape << ", [" << theID << "])";
954 //=============================================================================
958 //=============================================================================
959 Standard_Integer GEOMImpl_IShapesOperations::GetSubShapeIndex (Handle(GEOM_Object) theMainShape,
960 Handle(GEOM_Object) theSubShape)
964 TopoDS_Shape aMainShape = theMainShape->GetValue();
965 TopoDS_Shape aSubShape = theSubShape->GetValue();
967 if (aMainShape.IsNull() || aSubShape.IsNull()) return -1;
969 TopTools_IndexedMapOfShape anIndices;
970 TopExp::MapShapes(aMainShape, anIndices);
971 if (anIndices.Contains(aSubShape)) {
973 return anIndices.FindIndex(aSubShape);
979 //=============================================================================
983 //=============================================================================
984 Standard_Integer GEOMImpl_IShapesOperations::GetTopologyIndex (Handle(GEOM_Object) theMainShape,
985 Handle(GEOM_Object) theSubShape)
989 TopoDS_Shape aMainShape = theMainShape->GetValue();
990 TopoDS_Shape aSubShape = theSubShape->GetValue();
992 if (aMainShape.IsNull() || aSubShape.IsNull()) {
993 SetErrorCode("Null argument shape given");
998 if (aSubShape.ShapeType() == TopAbs_COMPOUND) {
1000 TopTools_ListOfShape CL;
1001 CL.Append(aMainShape);
1002 TopTools_ListIteratorOfListOfShape itC;
1003 for (itC.Initialize(CL); itC.More(); itC.Next()) {
1004 for (it.Initialize(itC.Value()); it.More(); it.Next()) {
1005 if (it.Value().ShapeType() == TopAbs_COMPOUND) {
1006 if (it.Value().IsSame(aSubShape))
1010 CL.Append(it.Value());
1015 TopExp_Explorer anExp (aMainShape, aSubShape.ShapeType());
1016 TopTools_MapOfShape M;
1017 for (; anExp.More(); anExp.Next()) {
1018 if (M.Add(anExp.Current())) {
1019 if (anExp.Current().IsSame(aSubShape))
1026 SetErrorCode("The sub-shape does not belong to the main shape");
1030 //=============================================================================
1032 * GetShapeTypeString
1034 //=============================================================================
1035 TCollection_AsciiString GEOMImpl_IShapesOperations::GetShapeTypeString (Handle(GEOM_Object) theShape)
1039 TCollection_AsciiString aTypeName ("Null Shape");
1041 TopoDS_Shape aShape = theShape->GetValue();
1042 if (aShape.IsNull())
1045 switch (aShape.ShapeType() )
1047 case TopAbs_COMPOUND:
1048 aTypeName = "Compound";
1050 case TopAbs_COMPSOLID:
1051 aTypeName = "Compound Solid";
1054 aTypeName = "Solid";
1057 aTypeName = "Shell";
1061 BRepAdaptor_Surface surf (TopoDS::Face(aShape));
1062 if (surf.GetType() == GeomAbs_Plane)
1063 aTypeName = "Plane";
1064 else if (surf.GetType() == GeomAbs_Cylinder)
1065 aTypeName = "Cylindrical Face";
1066 else if (surf.GetType() == GeomAbs_Sphere)
1067 aTypeName = "Spherical Face";
1068 else if (surf.GetType() == GeomAbs_Torus)
1069 aTypeName = "Toroidal Face";
1070 else if (surf.GetType() == GeomAbs_Cone)
1071 aTypeName = "Conical Face";
1073 aTypeName = "GEOM::FACE";
1081 BRepAdaptor_Curve curv (TopoDS::Edge(aShape));
1082 if (curv.GetType() == GeomAbs_Line) {
1083 if ((Abs(curv.FirstParameter()) >= 1E6) ||
1084 (Abs(curv.LastParameter()) >= 1E6))
1087 aTypeName = "Edge" ;
1088 } else if (curv.GetType() == GeomAbs_Circle) {
1089 if (curv.IsClosed())
1090 aTypeName = "Circle";
1099 aTypeName = "Vertex";
1102 aTypeName = "Shape";
1105 aTypeName = "Shape of unknown type";
1112 //=============================================================================
1116 //=============================================================================
1117 Standard_Integer GEOMImpl_IShapesOperations::NumberOfFaces (Handle(GEOM_Object) theShape)
1121 Standard_Integer nb = 0;
1123 if (theShape.IsNull()) return -1;
1124 TopoDS_Shape aShape = theShape->GetValue();
1125 if (aShape.IsNull()) return -1;
1127 TopTools_MapOfShape mapShape;
1129 TopExp_Explorer exp (aShape, TopAbs_FACE);
1130 for (; exp.More(); exp.Next())
1131 if (mapShape.Add(exp.Current()))
1138 //=============================================================================
1142 //=============================================================================
1143 Standard_Integer GEOMImpl_IShapesOperations::NumberOfEdges (Handle(GEOM_Object) theShape)
1147 Standard_Integer nb = 0;
1149 if (theShape.IsNull()) return -1;
1150 TopoDS_Shape aShape = theShape->GetValue();
1151 if (aShape.IsNull()) return -1;
1153 TopTools_MapOfShape mapShape;
1155 TopExp_Explorer exp (aShape, TopAbs_EDGE);
1156 for (; exp.More(); exp.Next())
1157 if (mapShape.Add(exp.Current()))
1164 //=============================================================================
1168 //=============================================================================
1169 Handle(GEOM_Object) GEOMImpl_IShapesOperations::ReverseShape(Handle(GEOM_Object) theShape)
1173 if (theShape.IsNull()) return NULL;
1175 //Add a new reversed object
1176 Handle(GEOM_Object) aReversed = GetEngine()->AddObject(GetDocID(), theShape->GetType());
1178 //Add a new Revese function
1179 Handle(GEOM_Function) aFunction;
1180 aFunction = aReversed->AddFunction(GEOMImpl_ShapeDriver::GetID(), REVERSE_ORIENTATION);
1181 if (aFunction.IsNull()) return NULL;
1183 //Check if the function is set correctly
1184 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
1186 GEOMImpl_IShapes aSI (aFunction);
1188 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
1189 if (aRefShape.IsNull()) return NULL;
1191 aSI.SetBase(aRefShape);
1193 //Compute the sub-shape value
1195 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
1198 if (!GetSolver()->ComputeFunction(aFunction)) {
1199 SetErrorCode("Shape driver failed to reverse shape");
1203 catch (Standard_Failure) {
1204 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1205 SetErrorCode(aFail->GetMessageString());
1209 //Make a Python command
1210 GEOM::TPythonDump(aFunction) << aReversed
1211 << " = geompy.ChangeOrientation(" << theShape << ")";
1217 //=============================================================================
1221 //=============================================================================
1222 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetFreeFacesIDs
1223 (Handle(GEOM_Object) theShape)
1227 if (theShape.IsNull()) return NULL;
1228 TopoDS_Shape aShape = theShape->GetValue();
1229 if (aShape.IsNull()) return NULL;
1231 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
1233 TopTools_IndexedDataMapOfShapeListOfShape mapFaceBlocks;
1234 GEOMImpl_Block6Explorer::MapShapesAndAncestors
1235 (aShape, TopAbs_FACE, TopAbs_SOLID, mapFaceBlocks);
1237 Standard_Integer ind = 1, nbFaces = mapFaceBlocks.Extent();
1240 SetErrorCode("The given shape has no faces");
1244 TopTools_IndexedMapOfShape anIndices;
1245 TopExp::MapShapes(aShape, anIndices);
1247 Standard_Integer id;
1248 for (; ind <= nbFaces; ind++) {
1249 if (mapFaceBlocks.FindFromIndex(ind).Extent() != 2) {
1250 id = anIndices.FindIndex(mapFaceBlocks.FindKey(ind));
1255 //The explode doesn't change object so no new function is required.
1256 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
1258 //Make a Python command
1259 GEOM::TPythonDump(aFunction, /*append=*/true)
1260 << "listFreeFacesIDs = geompy.GetFreeFacesIDs(" << theShape << ")";
1266 //=======================================================================
1267 //function : GetSharedShapes
1269 //=======================================================================
1271 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetSharedShapes
1272 (Handle(GEOM_Object) theShape1,
1273 Handle(GEOM_Object) theShape2,
1274 const Standard_Integer theShapeType)
1278 if (theShape1.IsNull() || theShape2.IsNull()) return NULL;
1280 TopoDS_Shape aShape1 = theShape1->GetValue();
1281 TopoDS_Shape aShape2 = theShape2->GetValue();
1283 if (aShape1.IsNull() || aShape2.IsNull()) return NULL;
1285 TopTools_IndexedMapOfShape anIndices;
1286 TopExp::MapShapes(aShape1, anIndices);
1287 Handle(TColStd_HArray1OfInteger) anArray;
1289 TopTools_IndexedMapOfShape mapShape1;
1290 TopExp::MapShapes(aShape1, TopAbs_ShapeEnum(theShapeType), mapShape1);
1292 Handle(GEOM_Object) anObj;
1293 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1294 TCollection_AsciiString anAsciiList, anEntry;
1296 TopTools_MapOfShape mapShape2;
1297 TopExp_Explorer exp (aShape2, TopAbs_ShapeEnum(theShapeType));
1298 for (; exp.More(); exp.Next()) {
1299 TopoDS_Shape aSS = exp.Current();
1300 if (mapShape2.Add(aSS) && mapShape1.Contains(aSS)) {
1301 anArray = new TColStd_HArray1OfInteger(1,1);
1302 anArray->SetValue(1, anIndices.FindIndex(aSS));
1303 anObj = GetEngine()->AddSubShape(theShape1, anArray);
1304 aSeq->Append(anObj);
1306 // for python command
1307 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
1308 anAsciiList += anEntry;
1313 if (aSeq->IsEmpty()) {
1314 SetErrorCode("The given shapes have no shared sub-shapes of the requested type");
1318 //Make a Python command
1319 anAsciiList.Trunc(anAsciiList.Length() - 1);
1321 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1323 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
1324 << "] = geompy.GetSharedShapes(" << theShape1 << ", "
1325 << theShape2 << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
1331 //=============================================================================
1335 //=============================================================================
1336 static GEOM::TPythonDump& operator<< (GEOM::TPythonDump& theDump,
1337 const GEOMAlgo_State theState)
1340 case GEOMAlgo_ST_IN:
1341 theDump << "geompy.GEOM.ST_IN";
1343 case GEOMAlgo_ST_OUT:
1344 theDump << "geompy.GEOM.ST_OUT";
1346 case GEOMAlgo_ST_ON:
1347 theDump << "geompy.GEOM.ST_ON";
1349 case GEOMAlgo_ST_ONIN:
1350 theDump << "geompy.GEOM.ST_ONIN";
1352 case GEOMAlgo_ST_ONOUT:
1353 theDump << "geompy.GEOM.ST_ONOUT";
1356 theDump << "geompy.GEOM.ST_UNKNOWN";
1362 //=======================================================================
1363 //function : checkTypeShapesOn
1365 * \brief Checks if theShapeType parameter of GetShapesOnXXX() is OK
1366 * \param theShapeType - the shape type to check
1367 * \retval bool - result of the check
1369 //=======================================================================
1371 bool GEOMImpl_IShapesOperations::checkTypeShapesOn(const Standard_Integer theShapeType)
1373 if (theShapeType != TopAbs_VERTEX &&
1374 theShapeType != TopAbs_EDGE &&
1375 theShapeType != TopAbs_FACE &&
1376 theShapeType != TopAbs_SOLID) {
1377 SetErrorCode("Only solids, vertices, edges or faces can be found by this method");
1383 //=======================================================================
1384 //function : makePlane
1386 * \brief Creates Geom_Plane
1387 * \param theAx1 - shape object defining plane parameters
1388 * \retval Handle(Geom_Surface) - resulting surface
1390 //=======================================================================
1392 Handle(Geom_Surface) GEOMImpl_IShapesOperations::makePlane(const TopoDS_Shape& anAx1)
1394 if (anAx1.ShapeType() != TopAbs_EDGE) return NULL;
1395 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
1396 TopoDS_Vertex V1, V2;
1397 TopExp::Vertices(anEdge, V1, V2, Standard_True);
1398 if (V1.IsNull() || V2.IsNull()) {
1399 SetErrorCode("Bad edge given for the plane normal vector");
1402 gp_Pnt aLoc = BRep_Tool::Pnt(V1);
1403 gp_Vec aVec (aLoc, BRep_Tool::Pnt(V2));
1404 if (aVec.Magnitude() < Precision::Confusion()) {
1405 SetErrorCode("Vector with null magnitude given");
1408 return new Geom_Plane(aLoc, aVec);
1411 //=======================================================================
1412 //function : makeCylinder
1414 * \brief Creates Geom_CylindricalSurface
1415 * \param theAx1 - edge defining cylinder axis
1416 * \param theRadius - cylinder radius
1417 * \retval Handle(Geom_Surface) - resulting surface
1419 //=======================================================================
1421 Handle(Geom_Surface) GEOMImpl_IShapesOperations::makeCylinder(const TopoDS_Shape& anAxis,
1422 const Standard_Real theRadius)
1424 //Axis of the cylinder
1425 if (anAxis.ShapeType() != TopAbs_EDGE) {
1426 SetErrorCode("Not an edge given for the axis");
1429 TopoDS_Edge anEdge = TopoDS::Edge(anAxis);
1430 TopoDS_Vertex V1, V2;
1431 TopExp::Vertices(anEdge, V1, V2, Standard_True);
1432 if (V1.IsNull() || V2.IsNull()) {
1433 SetErrorCode("Bad edge given for the axis");
1436 gp_Pnt aLoc = BRep_Tool::Pnt(V1);
1437 gp_Vec aVec (aLoc, BRep_Tool::Pnt(V2));
1438 if (aVec.Magnitude() < Precision::Confusion()) {
1439 SetErrorCode("Vector with null magnitude given");
1443 gp_Ax3 anAx3 (aLoc, aVec);
1444 return new Geom_CylindricalSurface(anAx3, theRadius);
1448 //=======================================================================
1449 //function : getShapesOnBoxIDs
1451 * \brief Find IDs of subshapes complying with given status about surface
1452 * \param theBox - the box to check state of subshapes against
1453 * \param theShape - the shape to explore
1454 * \param theShapeType - type of subshape of theShape
1455 * \param theState - required state
1456 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1458 //=======================================================================
1460 Handle(TColStd_HSequenceOfInteger)
1461 GEOMImpl_IShapesOperations::getShapesOnBoxIDs(const Handle(GEOM_Object)& theBox,
1462 const Handle(GEOM_Object)& theShape,
1463 const Standard_Integer theShapeType,
1464 GEOMAlgo_State theState)
1466 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
1468 TopoDS_Shape aBox = theBox->GetValue();
1469 TopoDS_Shape aShape = theShape->GetValue();
1471 // Check presence of triangulation, build if need
1472 if (!CheckTriangulation(aShape)) {
1473 SetErrorCode("Cannot build triangulation on the shape");
1478 GEOMAlgo_FinderShapeOn2 aFinder;
1479 Standard_Real aTol = 0.0001; // default value
1481 Handle(GEOMAlgo_ClsfBox) aClsfBox = new GEOMAlgo_ClsfBox;
1482 aClsfBox->SetBox(aBox);
1484 aFinder.SetShape(aShape);
1485 aFinder.SetTolerance(aTol);
1486 aFinder.SetClsf(aClsfBox);
1487 aFinder.SetShapeType( (TopAbs_ShapeEnum)theShapeType );
1488 aFinder.SetState(theState);
1491 // Interprete results
1492 Standard_Integer iErr = aFinder.ErrorStatus();
1493 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
1495 MESSAGE(" iErr : " << iErr);
1496 TCollection_AsciiString aMsg (" iErr : ");
1497 aMsg += TCollection_AsciiString(iErr);
1501 Standard_Integer iWrn = aFinder.WarningStatus();
1502 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
1504 MESSAGE(" *** iWrn : " << iWrn);
1507 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
1509 if (listSS.Extent() < 1) {
1510 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
1511 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
1515 // Fill sequence of object IDs
1516 aSeqOfIDs = new TColStd_HSequenceOfInteger;
1518 TopTools_IndexedMapOfShape anIndices;
1519 TopExp::MapShapes(aShape, anIndices);
1521 TopTools_ListIteratorOfListOfShape itSub (listSS);
1522 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
1523 int id = anIndices.FindIndex(itSub.Value());
1524 aSeqOfIDs->Append(id);
1531 //=======================================================================
1532 //function : GetShapesOnBoxIDs
1534 * \brief Find subshapes complying with given status about surface
1535 * \param theBox - the box to check state of subshapes against
1536 * \param theShape - the shape to explore
1537 * \param theShapeType - type of subshape of theShape
1538 * \param theState - required state
1539 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1541 //=======================================================================
1543 Handle(TColStd_HSequenceOfInteger)
1544 GEOMImpl_IShapesOperations::GetShapesOnBoxIDs(const Handle(GEOM_Object)& theBox,
1545 const Handle(GEOM_Object)& theShape,
1546 const Standard_Integer theShapeType,
1547 GEOMAlgo_State theState)
1549 // Find subshapes ids
1550 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
1551 getShapesOnBoxIDs (theBox, theShape, theShapeType, theState);
1552 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
1555 // The GetShapesOnBox() doesn't change object so no new function is required.
1556 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theBox)->GetLastFunction();
1558 // Make a Python command
1559 GEOM::TPythonDump(aFunction)
1560 << "listShapesOnBoxIDs = geompy.GetShapesOnBoxIDs("
1563 << TopAbs_ShapeEnum(theShapeType) << ", "
1570 //=======================================================================
1571 //function : GetShapesOnBox
1573 * \brief Find subshapes complying with given status about surface
1574 * \param theBox - the box to check state of subshapes against
1575 * \param theShape - the shape to explore
1576 * \param theShapeType - type of subshape of theShape
1577 * \param theState - required state
1578 * \retval Handle(TColStd_HSequenceOfTransient) - found subshapes
1580 //=======================================================================
1582 Handle(TColStd_HSequenceOfTransient)
1583 GEOMImpl_IShapesOperations::GetShapesOnBox(const Handle(GEOM_Object)& theBox,
1584 const Handle(GEOM_Object)& theShape,
1585 const Standard_Integer theShapeType,
1586 GEOMAlgo_State theState)
1588 // Find subshapes ids
1589 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
1590 getShapesOnBoxIDs (theBox, theShape, theShapeType, theState);
1591 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
1594 // Find objects by indices
1595 TCollection_AsciiString anAsciiList;
1596 Handle(TColStd_HSequenceOfTransient) aSeq;
1597 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
1598 if ( aSeq.IsNull() || aSeq->IsEmpty() )
1601 // Make a Python command
1603 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
1604 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1606 GEOM::TPythonDump(aFunction)
1607 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnBox("
1610 << TopAbs_ShapeEnum(theShapeType) << ", "
1618 //=======================================================================
1619 //function : getShapesOnShapeIDs
1621 * \brief Find IDs of subshapes complying with given status about surface
1622 * \param theCheckShape - the shape to check state of subshapes against
1623 * \param theShape - the shape to explore
1624 * \param theShapeType - type of subshape of theShape
1625 * \param theState - required state
1626 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1628 //=======================================================================
1630 Handle(TColStd_HSequenceOfInteger)
1631 GEOMImpl_IShapesOperations::getShapesOnShapeIDs
1632 (const Handle(GEOM_Object)& theCheckShape,
1633 const Handle(GEOM_Object)& theShape,
1634 const Standard_Integer theShapeType,
1635 GEOMAlgo_State theState)
1637 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
1639 TopoDS_Shape aCheckShape = theCheckShape->GetValue();
1640 TopoDS_Shape aShape = theShape->GetValue();
1641 TopTools_ListOfShape res;
1643 // Check presence of triangulation, build if need
1644 if (!CheckTriangulation(aShape)) {
1645 SetErrorCode("Cannot build triangulation on the shape");
1650 GEOMAlgo_FinderShapeOn2 aFinder;
1651 Standard_Real aTol = 0.0001; // default value
1653 Handle(GEOMAlgo_ClsfSolid) aClsfSolid = new GEOMAlgo_ClsfSolid;
1654 aClsfSolid->SetShape(aCheckShape);
1656 aFinder.SetShape(aShape);
1657 aFinder.SetTolerance(aTol);
1658 aFinder.SetClsf(aClsfSolid);
1659 aFinder.SetShapeType( (TopAbs_ShapeEnum)theShapeType );
1660 aFinder.SetState(theState);
1663 // Interprete results
1664 Standard_Integer iErr = aFinder.ErrorStatus();
1665 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
1667 MESSAGE(" iErr : " << iErr);
1668 TCollection_AsciiString aMsg (" iErr : ");
1669 aMsg += TCollection_AsciiString(iErr);
1673 Standard_Integer iWrn = aFinder.WarningStatus();
1674 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
1676 MESSAGE(" *** iWrn : " << iWrn);
1679 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
1681 if (listSS.Extent() < 1) {
1682 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
1683 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
1686 // Fill sequence of object IDs
1687 aSeqOfIDs = new TColStd_HSequenceOfInteger;
1689 TopTools_IndexedMapOfShape anIndices;
1690 TopExp::MapShapes(aShape, anIndices);
1692 TopTools_ListIteratorOfListOfShape itSub (listSS);
1693 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
1694 int id = anIndices.FindIndex(itSub.Value());
1695 aSeqOfIDs->Append(id);
1702 //=======================================================================
1703 //function : GetShapesOnShapeIDs
1705 * \brief Find subshapes complying with given status about surface
1706 * \param theCheckShape - the shape to check state of subshapes against
1707 * \param theShape - the shape to explore
1708 * \param theShapeType - type of subshape of theShape
1709 * \param theState - required state
1710 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1712 //=======================================================================
1714 Handle(TColStd_HSequenceOfInteger)
1715 GEOMImpl_IShapesOperations::GetShapesOnShapeIDs
1716 (const Handle(GEOM_Object)& theCheckShape,
1717 const Handle(GEOM_Object)& theShape,
1718 const Standard_Integer theShapeType,
1719 GEOMAlgo_State theState)
1721 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
1722 getShapesOnShapeIDs (theCheckShape, theShape, theShapeType, theState);
1724 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
1727 // The GetShapesOnShape() doesn't change object so no new function is required.
1728 Handle(GEOM_Function) aFunction =
1729 GEOM::GetCreatedLast(theShape,theCheckShape)->GetLastFunction();
1731 // Make a Python command
1732 GEOM::TPythonDump(aFunction)
1733 << "listShapesOnBoxIDs = geompy.GetShapesOnShapeIDs("
1734 << theCheckShape << ", "
1736 << TopAbs_ShapeEnum(theShapeType) << ", "
1744 //=======================================================================
1745 //function : GetShapesOnShape
1747 * \brief Find subshapes complying with given status about surface
1748 * \param theCheckShape - the shape to check state of subshapes against
1749 * \param theShape - the shape to explore
1750 * \param theShapeType - type of subshape of theShape
1751 * \param theState - required state
1752 * \retval Handle(TColStd_HSequenceOfTransient) - found subshapes
1754 //=======================================================================
1756 Handle(TColStd_HSequenceOfTransient)
1757 GEOMImpl_IShapesOperations::GetShapesOnShape
1758 (const Handle(GEOM_Object)& theCheckShape,
1759 const Handle(GEOM_Object)& theShape,
1760 const Standard_Integer theShapeType,
1761 GEOMAlgo_State theState)
1763 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
1764 getShapesOnShapeIDs (theCheckShape, theShape, theShapeType, theState);
1765 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
1768 // Find objects by indices
1769 TCollection_AsciiString anAsciiList;
1770 Handle(TColStd_HSequenceOfTransient) aSeq;
1771 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
1773 if ( aSeq.IsNull() || aSeq->IsEmpty() )
1776 // Make a Python command
1778 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
1779 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1781 GEOM::TPythonDump(aFunction)
1782 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnShape("
1783 << theCheckShape << ", "
1785 << TopAbs_ShapeEnum(theShapeType) << ", "
1794 //=======================================================================
1795 //function : GetShapesOnShapeAsCompound
1796 //=======================================================================
1798 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetShapesOnShapeAsCompound
1799 (const Handle(GEOM_Object)& theCheckShape,
1800 const Handle(GEOM_Object)& theShape,
1801 const Standard_Integer theShapeType,
1802 GEOMAlgo_State theState)
1804 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
1805 getShapesOnShapeIDs (theCheckShape, theShape, theShapeType, theState);
1807 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
1810 // Find objects by indices
1811 TCollection_AsciiString anAsciiList;
1812 Handle(TColStd_HSequenceOfTransient) aSeq;
1813 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
1815 if ( aSeq.IsNull() || aSeq->IsEmpty() )
1818 TopoDS_Compound aCompound;
1820 B.MakeCompound(aCompound);
1822 for(; i<=aSeq->Length(); i++) {
1823 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(aSeq->Value(i));
1824 TopoDS_Shape aShape_i = anObj->GetValue();
1825 B.Add(aCompound,aShape_i);
1828 //Add a new result object
1829 Handle(GEOM_Object) aRes = GetEngine()->AddObject(GetDocID(), GEOM_SHAPES_ON_SHAPE);
1830 Handle(GEOM_Function) aFunction =
1831 aRes->AddFunction(GEOMImpl_ShapeDriver::GetID(), SHAPES_ON_SHAPE);
1832 aFunction->SetValue(aCompound);
1834 GEOM::TPythonDump(aFunction)
1835 << aRes << " = geompy.GetShapesOnShapeAsCompound("
1836 << theCheckShape << ", "
1838 << TopAbs_ShapeEnum(theShapeType) << ", "
1847 //=======================================================================
1848 //function : getShapesOnSurfaceIDs
1850 * \brief Find IDs of subshapes complying with given status about surface
1851 * \param theSurface - the surface to check state of subshapes against
1852 * \param theShape - the shape to explore
1853 * \param theShapeType - type of subshape of theShape
1854 * \param theState - required state
1855 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1857 //=======================================================================
1859 Handle(TColStd_HSequenceOfInteger)
1860 GEOMImpl_IShapesOperations::getShapesOnSurfaceIDs(const Handle(Geom_Surface)& theSurface,
1861 const TopoDS_Shape& theShape,
1862 TopAbs_ShapeEnum theShapeType,
1863 GEOMAlgo_State theState)
1865 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
1867 // Check presence of triangulation, build if need
1868 if (!CheckTriangulation(theShape)) {
1869 SetErrorCode("Cannot build triangulation on the shape");
1874 GEOMAlgo_FinderShapeOn1 aFinder;
1875 Standard_Real aTol = 0.0001; // default value
1877 aFinder.SetShape(theShape);
1878 aFinder.SetTolerance(aTol);
1879 aFinder.SetSurface(theSurface);
1880 aFinder.SetShapeType(theShapeType);
1881 aFinder.SetState(theState);
1883 // Sets the minimal number of inner points for the faces that do not have own
1884 // inner points at all (for e.g. rectangular planar faces have just 2 triangles).
1886 aFinder.SetNbPntsMin(3);
1887 // Sets the maximal number of inner points for edges or faces.
1888 // It is usefull for the cases when this number is very big (e.g =2000) to improve
1889 // the performance. If this value =0, all inner points will be taken into account.
1891 aFinder.SetNbPntsMax(100);
1895 // Interprete results
1896 Standard_Integer iErr = aFinder.ErrorStatus();
1897 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
1899 MESSAGE(" iErr : " << iErr);
1900 TCollection_AsciiString aMsg (" iErr : ");
1901 aMsg += TCollection_AsciiString(iErr);
1905 Standard_Integer iWrn = aFinder.WarningStatus();
1906 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
1908 MESSAGE(" *** iWrn : " << iWrn);
1911 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
1913 if (listSS.Extent() < 1) {
1914 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
1915 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
1919 // Fill sequence of object IDs
1920 aSeqOfIDs = new TColStd_HSequenceOfInteger;
1922 TopTools_IndexedMapOfShape anIndices;
1923 TopExp::MapShapes(theShape, anIndices);
1925 TopTools_ListIteratorOfListOfShape itSub (listSS);
1926 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
1927 int id = anIndices.FindIndex(itSub.Value());
1928 aSeqOfIDs->Append(id);
1934 //=======================================================================
1935 //function : getObjectsShapesOn
1937 * \brief Find shape objects and their entries by their ids
1938 * \param theShapeIDs - incoming shape ids
1939 * \param theShapeEntries - outgoing entries like "entry1, entry2, ..."
1940 * \retval Handle(TColStd_HSequenceOfTransient) - found shape objects
1942 //=======================================================================
1944 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::
1945 getObjectsShapesOn(const Handle(GEOM_Object)& theShape,
1946 const Handle(TColStd_HSequenceOfInteger)& theShapeIDs,
1947 TCollection_AsciiString & theShapeEntries)
1949 Handle(TColStd_HSequenceOfTransient) aSeq;
1951 if ( !theShapeIDs.IsNull() && theShapeIDs->Length() > 0 )
1953 aSeq = new TColStd_HSequenceOfTransient;
1954 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
1955 TCollection_AsciiString anEntry;
1956 for ( int i = 1; i <= theShapeIDs->Length(); ++i )
1958 anArray->SetValue(1, theShapeIDs->Value( i ));
1959 Handle(GEOM_Object) anObj = GetEngine()->AddSubShape(theShape, anArray);
1960 aSeq->Append( anObj );
1962 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
1963 if ( i != 1 ) theShapeEntries += ",";
1964 theShapeEntries += anEntry;
1970 //=======================================================================
1971 //function : getShapesOnSurface
1973 * \brief Find subshapes complying with given status about surface
1974 * \param theSurface - the surface to check state of subshapes against
1975 * \param theShape - the shape to explore
1976 * \param theShapeType - type of subshape of theShape
1977 * \param theState - required state
1978 * \param theShapeEntries - outgoing entries like "entry1, entry2, ..."
1979 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1981 //=======================================================================
1983 Handle(TColStd_HSequenceOfTransient)
1984 GEOMImpl_IShapesOperations::getShapesOnSurface(const Handle(Geom_Surface)& theSurface,
1985 const Handle(GEOM_Object)& theShape,
1986 TopAbs_ShapeEnum theShapeType,
1987 GEOMAlgo_State theState,
1988 TCollection_AsciiString & theShapeEntries)
1990 // Find subshapes ids
1991 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
1992 getShapesOnSurfaceIDs (theSurface, theShape->GetValue(), theShapeType, theState);
1993 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
1996 return getObjectsShapesOn( theShape, aSeqOfIDs, theShapeEntries );
1999 //=============================================================================
2003 //=============================================================================
2004 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnPlane
2005 (const Handle(GEOM_Object)& theShape,
2006 const Standard_Integer theShapeType,
2007 const Handle(GEOM_Object)& theAx1,
2008 const GEOMAlgo_State theState)
2012 if (theShape.IsNull() || theAx1.IsNull()) return NULL;
2014 TopoDS_Shape aShape = theShape->GetValue();
2015 TopoDS_Shape anAx1 = theAx1->GetValue();
2017 if (aShape.IsNull() || anAx1.IsNull()) return NULL;
2019 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2020 if ( !checkTypeShapesOn( theShapeType ))
2024 Handle(Geom_Surface) aPlane = makePlane( anAx1 );
2025 if ( aPlane.IsNull() )
2029 TCollection_AsciiString anAsciiList;
2030 Handle(TColStd_HSequenceOfTransient) aSeq;
2031 aSeq = getShapesOnSurface( aPlane, theShape, aShapeType, theState, anAsciiList );
2032 if ( aSeq.IsNull() || aSeq->Length() == 0 )
2035 // Make a Python command
2037 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2038 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2040 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
2041 << "] = geompy.GetShapesOnPlane(" << theShape << ", "
2042 << aShapeType << ", " << theAx1 << ", " << theState << ")";
2048 //=============================================================================
2050 * GetShapesOnPlaneWithLocation
2052 //=============================================================================
2053 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnPlaneWithLocation
2054 (const Handle(GEOM_Object)& theShape,
2055 const Standard_Integer theShapeType,
2056 const Handle(GEOM_Object)& theAx1,
2057 const Handle(GEOM_Object)& thePnt,
2058 const GEOMAlgo_State theState)
2062 if (theShape.IsNull() || theAx1.IsNull() || thePnt.IsNull()) return NULL;
2064 TopoDS_Shape aShape = theShape->GetValue();
2065 TopoDS_Shape anAx1 = theAx1->GetValue();
2066 TopoDS_Shape anPnt = thePnt->GetValue();
2068 if (aShape.IsNull() || anAx1.IsNull() || anPnt.IsNull()) return NULL;
2070 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2071 if ( !checkTypeShapesOn( theShapeType ))
2075 if ( anAx1.ShapeType() != TopAbs_EDGE || anPnt.ShapeType() != TopAbs_VERTEX ) return NULL;
2076 TopoDS_Vertex V1, V2, V3;
2077 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
2078 TopExp::Vertices(anEdge, V1, V2, Standard_True);
2080 if (V1.IsNull() || V2.IsNull()) {
2081 SetErrorCode("Bad edge given for the plane normal vector");
2084 V3 = TopoDS::Vertex(anPnt);
2087 SetErrorCode("Bad vertex given for the plane location");
2090 gp_Pnt aLoc = BRep_Tool::Pnt(V3);
2091 gp_Vec aVec(BRep_Tool::Pnt(V1),BRep_Tool::Pnt(V2));
2093 if (aVec.Magnitude() < Precision::Confusion()) {
2094 SetErrorCode("Vector with null magnitude given");
2097 Handle(Geom_Surface) aPlane = new Geom_Plane(aLoc, aVec);
2099 if ( aPlane.IsNull() )
2103 TCollection_AsciiString anAsciiList;
2104 Handle(TColStd_HSequenceOfTransient) aSeq;
2105 aSeq = getShapesOnSurface( aPlane, theShape, aShapeType, theState, anAsciiList );
2106 if ( aSeq.IsNull() || aSeq->Length() == 0 )
2109 // Make a Python command
2111 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2112 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2114 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
2115 << "] = geompy.GetShapesOnPlaneWithLocation(" << theShape << ", "
2116 << aShapeType << ", " << theAx1 << ", "<< thePnt <<", " << theState << ")";
2122 //=============================================================================
2124 * GetShapesOnCylinder
2126 //=============================================================================
2127 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnCylinder
2128 (const Handle(GEOM_Object)& theShape,
2129 const Standard_Integer theShapeType,
2130 const Handle(GEOM_Object)& theAxis,
2131 const Standard_Real theRadius,
2132 const GEOMAlgo_State theState)
2136 if (theShape.IsNull() || theAxis.IsNull()) return NULL;
2138 TopoDS_Shape aShape = theShape->GetValue();
2139 TopoDS_Shape anAxis = theAxis->GetValue();
2141 if (aShape.IsNull() || anAxis.IsNull()) return NULL;
2143 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2144 if ( !checkTypeShapesOn( aShapeType ))
2147 // Create a cylinder surface
2148 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
2149 if ( aCylinder.IsNull() )
2153 TCollection_AsciiString anAsciiList;
2154 Handle(TColStd_HSequenceOfTransient) aSeq;
2155 aSeq = getShapesOnSurface( aCylinder, theShape, aShapeType, theState, anAsciiList );
2156 if ( aSeq.IsNull() || aSeq->Length() == 0 )
2159 // Make a Python command
2161 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2162 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2164 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
2165 << "] = geompy.GetShapesOnCylinder(" << theShape << ", " << aShapeType
2166 << ", " << theAxis << ", " << theRadius << ", " << theState << ")";
2172 //=============================================================================
2176 //=============================================================================
2177 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnSphere
2178 (const Handle(GEOM_Object)& theShape,
2179 const Standard_Integer theShapeType,
2180 const Handle(GEOM_Object)& theCenter,
2181 const Standard_Real theRadius,
2182 const GEOMAlgo_State theState)
2186 if (theShape.IsNull() || theCenter.IsNull()) return NULL;
2188 TopoDS_Shape aShape = theShape->GetValue();
2189 TopoDS_Shape aCenter = theCenter->GetValue();
2191 if (aShape.IsNull() || aCenter.IsNull()) return NULL;
2193 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2194 if ( !checkTypeShapesOn( aShapeType ))
2197 // Center of the sphere
2198 if (aCenter.ShapeType() != TopAbs_VERTEX) return NULL;
2199 gp_Pnt aLoc = BRep_Tool::Pnt(TopoDS::Vertex(aCenter));
2201 gp_Ax3 anAx3 (aLoc, gp::DZ());
2202 Handle(Geom_SphericalSurface) aSphere =
2203 new Geom_SphericalSurface(anAx3, theRadius);
2206 TCollection_AsciiString anAsciiList;
2207 Handle(TColStd_HSequenceOfTransient) aSeq;
2208 aSeq = getShapesOnSurface( aSphere, theShape, aShapeType, theState, anAsciiList );
2209 if ( aSeq.IsNull() || aSeq->Length() == 0 )
2212 // Make a Python command
2214 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2215 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2217 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
2218 << "] = geompy.GetShapesOnSphere(" << theShape << ", " << aShapeType
2219 << ", " << theCenter << ", " << theRadius << ", " << theState << ")";
2225 //=============================================================================
2227 * GetShapesOnPlaneIDs
2229 //=============================================================================
2230 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnPlaneIDs
2231 (const Handle(GEOM_Object)& theShape,
2232 const Standard_Integer theShapeType,
2233 const Handle(GEOM_Object)& theAx1,
2234 const GEOMAlgo_State theState)
2238 if (theShape.IsNull() || theAx1.IsNull()) return NULL;
2240 TopoDS_Shape aShape = theShape->GetValue();
2241 TopoDS_Shape anAx1 = theAx1->GetValue();
2243 if (aShape.IsNull() || anAx1.IsNull()) return NULL;
2245 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2246 if ( !checkTypeShapesOn( aShapeType ))
2250 Handle(Geom_Surface) aPlane = makePlane( anAx1 );
2251 if ( aPlane.IsNull() )
2255 Handle(TColStd_HSequenceOfInteger) aSeq;
2256 aSeq = getShapesOnSurfaceIDs( aPlane, aShape, aShapeType, theState );
2258 // The GetShapesOnPlaneIDs() doesn't change object so no new function is required.
2259 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAx1)->GetLastFunction();
2261 // Make a Python command
2262 GEOM::TPythonDump(aFunction, /*append=*/true)
2263 << "listShapesOnPlane = geompy.GetShapesOnPlaneIDs"
2264 << "(" << theShape << "," << aShapeType << "," << theAx1 << "," << theState << ")";
2270 //=============================================================================
2272 * GetShapesOnPlaneWithLocationIDs
2274 //=============================================================================
2275 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnPlaneWithLocationIDs
2276 (const Handle(GEOM_Object)& theShape,
2277 const Standard_Integer theShapeType,
2278 const Handle(GEOM_Object)& theAx1,
2279 const Handle(GEOM_Object)& thePnt,
2280 const GEOMAlgo_State theState)
2284 if (theShape.IsNull() || theAx1.IsNull() || thePnt.IsNull()) return NULL;
2286 TopoDS_Shape aShape = theShape->GetValue();
2287 TopoDS_Shape anAx1 = theAx1->GetValue();
2288 TopoDS_Shape anPnt = thePnt->GetValue();
2290 if (aShape.IsNull() || anAx1.IsNull() || anPnt.IsNull()) return NULL;
2292 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2293 if ( !checkTypeShapesOn( aShapeType ))
2297 if (anAx1.ShapeType() != TopAbs_EDGE || anPnt.ShapeType() != TopAbs_VERTEX) return NULL;
2298 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
2299 TopoDS_Vertex V1, V2, V3;
2300 TopExp::Vertices(anEdge, V1, V2, Standard_True);
2301 if (V1.IsNull() || V2.IsNull()) {
2302 SetErrorCode("Bad edge given for the plane normal vector");
2305 V3 = TopoDS::Vertex(anPnt);
2307 SetErrorCode("Bad vertex given for the plane location");
2310 gp_Pnt aLoc = BRep_Tool::Pnt(V3);
2311 gp_Vec aVec(BRep_Tool::Pnt(V1),BRep_Tool::Pnt(V2));
2312 if (aVec.Magnitude() < Precision::Confusion()) {
2313 SetErrorCode("Vector with null magnitude given");
2317 Handle(Geom_Surface) aPlane = new Geom_Plane(aLoc, aVec);
2318 if ( aPlane.IsNull() )
2322 Handle(TColStd_HSequenceOfInteger) aSeq;
2323 aSeq = getShapesOnSurfaceIDs( aPlane, aShape, aShapeType, theState );
2325 // The GetShapesOnPlaneIDs() doesn't change object so no new function is required.
2326 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAx1)->GetLastFunction();
2328 // Make a Python command
2329 GEOM::TPythonDump(aFunction, /*append=*/true)
2330 << "listShapesOnPlane = geompy.GetShapesOnPlaneWithLocationIDs"
2331 << "(" << theShape << ", " << aShapeType << ", " << theAx1 << ", "<< thePnt << ", " << theState << ")";
2337 //=============================================================================
2339 * GetShapesOnCylinderIDs
2341 //=============================================================================
2342 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnCylinderIDs
2343 (const Handle(GEOM_Object)& theShape,
2344 const Standard_Integer theShapeType,
2345 const Handle(GEOM_Object)& theAxis,
2346 const Standard_Real theRadius,
2347 const GEOMAlgo_State theState)
2351 if (theShape.IsNull() || theAxis.IsNull()) return NULL;
2353 TopoDS_Shape aShape = theShape->GetValue();
2354 TopoDS_Shape anAxis = theAxis->GetValue();
2356 if (aShape.IsNull() || anAxis.IsNull()) return NULL;
2358 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2359 if ( !checkTypeShapesOn( aShapeType ))
2362 // Create a cylinder surface
2363 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
2364 if ( aCylinder.IsNull() )
2368 Handle(TColStd_HSequenceOfInteger) aSeq;
2369 aSeq = getShapesOnSurfaceIDs( aCylinder, aShape, aShapeType, theState );
2371 // The GetShapesOnCylinder() doesn't change object so no new function is required.
2372 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAxis)->GetLastFunction();
2374 // Make a Python command
2375 GEOM::TPythonDump(aFunction, /*append=*/true)
2376 << "listShapesOnCylinder = geompy.GetShapesOnCylinderIDs"
2377 << "(" << theShape << ", " << aShapeType << ", " << theAxis << ", "
2378 << theRadius << ", " << theState << ")";
2384 //=============================================================================
2386 * GetShapesOnSphereIDs
2388 //=============================================================================
2389 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnSphereIDs
2390 (const Handle(GEOM_Object)& theShape,
2391 const Standard_Integer theShapeType,
2392 const Handle(GEOM_Object)& theCenter,
2393 const Standard_Real theRadius,
2394 const GEOMAlgo_State theState)
2398 if (theShape.IsNull() || theCenter.IsNull()) return NULL;
2400 TopoDS_Shape aShape = theShape->GetValue();
2401 TopoDS_Shape aCenter = theCenter->GetValue();
2403 if (aShape.IsNull() || aCenter.IsNull()) return NULL;
2405 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2406 if ( !checkTypeShapesOn( aShapeType ))
2409 // Center of the sphere
2410 if (aCenter.ShapeType() != TopAbs_VERTEX) return NULL;
2411 gp_Pnt aLoc = BRep_Tool::Pnt(TopoDS::Vertex(aCenter));
2413 gp_Ax3 anAx3 (aLoc, gp::DZ());
2414 Handle(Geom_SphericalSurface) aSphere =
2415 new Geom_SphericalSurface(anAx3, theRadius);
2418 Handle(TColStd_HSequenceOfInteger) aSeq;
2419 aSeq = getShapesOnSurfaceIDs( aSphere, aShape, aShapeType, theState );
2421 // The GetShapesOnSphere() doesn't change object so no new function is required.
2422 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theCenter)->GetLastFunction();
2424 // Make a Python command
2425 GEOM::TPythonDump(aFunction, /*append=*/true)
2426 << "listShapesOnCylinder = geompy.GetShapesOnCylinderIDs"
2427 << "(" << theShape << ", " << aShapeType << ", " << theCenter << ", "
2428 << theRadius << ", " << theState << ")";
2434 //=======================================================================
2435 //function : getShapesOnQuadrangleIDs
2437 * \brief Find IDs of subshapes complying with given status about quadrangle
2438 * \param theShape - the shape to explore
2439 * \param theShapeType - type of subshape of theShape
2440 * \param theTopLeftPoint - top left quadrangle corner
2441 * \param theTopRigthPoint - top right quadrangle corner
2442 * \param theBottomLeftPoint - bottom left quadrangle corner
2443 * \param theBottomRigthPoint - bottom right quadrangle corner
2444 * \param theState - required state
2445 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
2447 //=======================================================================
2449 Handle(TColStd_HSequenceOfInteger)
2450 GEOMImpl_IShapesOperations::getShapesOnQuadrangleIDs (const Handle(GEOM_Object)& theShape,
2451 const Standard_Integer theShapeType,
2452 const Handle(GEOM_Object)& theTopLeftPoint,
2453 const Handle(GEOM_Object)& theTopRigthPoint,
2454 const Handle(GEOM_Object)& theBottomLeftPoint,
2455 const Handle(GEOM_Object)& theBottomRigthPoint,
2456 const GEOMAlgo_State theState)
2460 if ( theShape.IsNull() ||
2461 theTopLeftPoint.IsNull() ||
2462 theTopRigthPoint.IsNull() ||
2463 theBottomLeftPoint.IsNull() ||
2464 theBottomRigthPoint.IsNull() )
2467 TopoDS_Shape aShape = theShape->GetValue();
2468 TopoDS_Shape aTL = theTopLeftPoint->GetValue();
2469 TopoDS_Shape aTR = theTopRigthPoint->GetValue();
2470 TopoDS_Shape aBL = theBottomLeftPoint->GetValue();
2471 TopoDS_Shape aBR = theBottomRigthPoint->GetValue();
2473 if (aShape.IsNull() ||
2478 aTL.ShapeType() != TopAbs_VERTEX ||
2479 aTR.ShapeType() != TopAbs_VERTEX ||
2480 aBL.ShapeType() != TopAbs_VERTEX ||
2481 aBR.ShapeType() != TopAbs_VERTEX )
2484 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2485 if ( !checkTypeShapesOn( aShapeType ))
2488 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
2490 // Check presence of triangulation, build if need
2491 if (!CheckTriangulation(aShape)) {
2492 SetErrorCode("Cannot build triangulation on the shape");
2497 gp_Pnt aPntTL = BRep_Tool::Pnt(TopoDS::Vertex(aTL));
2498 gp_Pnt aPntTR = BRep_Tool::Pnt(TopoDS::Vertex(aTR));
2499 gp_Pnt aPntBL = BRep_Tool::Pnt(TopoDS::Vertex(aBL));
2500 gp_Pnt aPntBR = BRep_Tool::Pnt(TopoDS::Vertex(aBR));
2502 GEOMAlgo_FinderShapeOnQuad aFinder( aPntTL, aPntTR, aPntBL, aPntBR );
2503 Standard_Real aTol = 0.0001; // default value
2505 aFinder.SetShape(aShape);
2506 aFinder.SetTolerance(aTol);
2507 //aFinder.SetSurface(theSurface);
2508 aFinder.SetShapeType(aShapeType);
2509 aFinder.SetState(theState);
2511 // Sets the minimal number of inner points for the faces that do not have own
2512 // inner points at all (for e.g. rectangular planar faces have just 2 triangles).
2514 aFinder.SetNbPntsMin(3);
2515 // Sets the maximal number of inner points for edges or faces.
2516 // It is usefull for the cases when this number is very big (e.g =2000) to improve
2517 // the performance. If this value =0, all inner points will be taken into account.
2519 aFinder.SetNbPntsMax(100);
2523 // Interprete results
2524 Standard_Integer iErr = aFinder.ErrorStatus();
2525 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
2527 MESSAGE(" iErr : " << iErr);
2528 TCollection_AsciiString aMsg (" iErr : ");
2529 aMsg += TCollection_AsciiString(iErr);
2533 Standard_Integer iWrn = aFinder.WarningStatus();
2534 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
2536 MESSAGE(" *** iWrn : " << iWrn);
2539 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
2541 if (listSS.Extent() < 1) {
2542 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
2543 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
2547 // Fill sequence of object IDs
2548 aSeqOfIDs = new TColStd_HSequenceOfInteger;
2550 TopTools_IndexedMapOfShape anIndices;
2551 TopExp::MapShapes(aShape, anIndices);
2553 TopTools_ListIteratorOfListOfShape itSub (listSS);
2554 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
2555 int id = anIndices.FindIndex(itSub.Value());
2556 aSeqOfIDs->Append(id);
2561 //=======================================================================
2562 //function : GetShapesOnQuadrangle
2564 * \brief Find subshapes complying with given status about quadrangle
2565 * \param theShape - the shape to explore
2566 * \param theShapeType - type of subshape of theShape
2567 * \param theTopLeftPoint - top left quadrangle corner
2568 * \param theTopRigthPoint - top right quadrangle corner
2569 * \param theBottomLeftPoint - bottom left quadrangle corner
2570 * \param theBottomRigthPoint - bottom right quadrangle corner
2571 * \param theState - required state
2572 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
2574 //=======================================================================
2576 Handle(TColStd_HSequenceOfTransient)
2577 GEOMImpl_IShapesOperations::GetShapesOnQuadrangle (const Handle(GEOM_Object)& theShape,
2578 const Standard_Integer theShapeType,
2579 const Handle(GEOM_Object)& theTopLeftPoint,
2580 const Handle(GEOM_Object)& theTopRigthPoint,
2581 const Handle(GEOM_Object)& theBottomLeftPoint,
2582 const Handle(GEOM_Object)& theBottomRigthPoint,
2583 const GEOMAlgo_State theState)
2586 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2587 getShapesOnQuadrangleIDs( theShape,
2592 theBottomRigthPoint,
2594 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->IsEmpty() )
2597 // Find objects by indices
2598 TCollection_AsciiString anAsciiList;
2599 Handle(TColStd_HSequenceOfTransient) aSeq;
2600 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
2601 if ( aSeq.IsNull() || aSeq->IsEmpty() )
2604 // Make a Python command
2606 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2607 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2609 GEOM::TPythonDump(aFunction)
2610 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnQuadrangle("
2612 << TopAbs_ShapeEnum(theShapeType) << ", "
2613 << theTopLeftPoint << ", "
2614 << theTopRigthPoint << ", "
2615 << theBottomLeftPoint << ", "
2616 << theBottomRigthPoint << ", "
2623 //=======================================================================
2624 //function : GetShapesOnQuadrangleIDs
2626 * \brief Find IDs of subshapes complying with given status about quadrangle
2627 * \param theShape - the shape to explore
2628 * \param theShapeType - type of subshape of theShape
2629 * \param theTopLeftPoint - top left quadrangle corner
2630 * \param theTopRigthPoint - top right quadrangle corner
2631 * \param theBottomLeftPoint - bottom left quadrangle corner
2632 * \param theBottomRigthPoint - bottom right quadrangle corner
2633 * \param theState - required state
2634 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
2636 //=======================================================================
2638 Handle(TColStd_HSequenceOfInteger)
2639 GEOMImpl_IShapesOperations::GetShapesOnQuadrangleIDs (const Handle(GEOM_Object)& theShape,
2640 const Standard_Integer theShapeType,
2641 const Handle(GEOM_Object)& theTopLeftPoint,
2642 const Handle(GEOM_Object)& theTopRigthPoint,
2643 const Handle(GEOM_Object)& theBottomLeftPoint,
2644 const Handle(GEOM_Object)& theBottomRigthPoint,
2645 const GEOMAlgo_State theState)
2648 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2649 getShapesOnQuadrangleIDs( theShape,
2654 theBottomRigthPoint,
2656 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->IsEmpty() )
2659 // Make a Python command
2661 // The GetShapesOnCylinder() doesn't change object so no new function is required.
2662 Handle(GEOM_Object) lastObj = GEOM::GetCreatedLast(theShape,theTopLeftPoint);
2663 lastObj = GEOM::GetCreatedLast(lastObj,theTopRigthPoint);
2664 lastObj = GEOM::GetCreatedLast(lastObj,theBottomRigthPoint);
2665 lastObj = GEOM::GetCreatedLast(lastObj,theBottomLeftPoint);
2666 Handle(GEOM_Function) aFunction = lastObj->GetLastFunction();
2668 GEOM::TPythonDump(aFunction, /*append=*/true)
2669 << "listShapesOnQuadrangle = geompy.GetShapesOnQuadrangleIDs("
2671 << TopAbs_ShapeEnum(theShapeType) << ", "
2672 << theTopLeftPoint << ", "
2673 << theTopRigthPoint << ", "
2674 << theBottomLeftPoint << ", "
2675 << theBottomRigthPoint << ", "
2683 //=============================================================================
2687 //=============================================================================
2688 static bool GetInPlaceOfShape (const Handle(GEOM_Function)& theWhereFunction,
2689 const TopTools_IndexedMapOfShape& theWhereIndices,
2690 const TopoDS_Shape& theWhat,
2691 TColStd_ListOfInteger& theModifiedList)
2693 if (theWhereFunction.IsNull() || theWhat.IsNull()) return false;
2695 if (theWhereIndices.Contains(theWhat)) {
2696 // entity was not changed by the operation
2697 Standard_Integer aWhatIndex = theWhereIndices.FindIndex(theWhat);
2698 theModifiedList.Append(aWhatIndex);
2702 // try to find in history
2703 TDF_Label aHistoryLabel = theWhereFunction->GetHistoryEntry(Standard_False);
2705 // search in history for all argument shapes
2706 Standard_Boolean isFound = Standard_False;
2707 Standard_Boolean isGood = Standard_False;
2709 TDF_LabelSequence aLabelSeq;
2710 theWhereFunction->GetDependency(aLabelSeq);
2711 Standard_Integer nbArg = aLabelSeq.Length();
2713 for (Standard_Integer iarg = 1; iarg <= nbArg && !isFound; iarg++) {
2715 TDF_Label anArgumentRefLabel = aLabelSeq.Value(iarg);
2717 Handle(GEOM_Object) anArgumentObject = GEOM_Object::GetReferencedObject(anArgumentRefLabel);
2718 TopoDS_Shape anArgumentShape = anArgumentObject->GetValue();
2720 TopTools_IndexedMapOfShape anArgumentIndices;
2721 TopExp::MapShapes(anArgumentShape, anArgumentIndices);
2723 if (anArgumentIndices.Contains(theWhat)) {
2724 isFound = Standard_True;
2725 Standard_Integer aWhatIndex = anArgumentIndices.FindIndex(theWhat);
2727 // Find corresponding label in history
2728 TDF_Label anArgumentHistoryLabel =
2729 theWhereFunction->GetArgumentHistoryEntry(anArgumentRefLabel, Standard_False);
2730 if (anArgumentHistoryLabel.IsNull()) {
2731 // Lost History of operation argument. Possibly, all its entities was removed.
2732 isGood = Standard_True;
2735 TDF_Label aWhatHistoryLabel = anArgumentHistoryLabel.FindChild(aWhatIndex, Standard_False);
2737 if (aWhatHistoryLabel.IsNull()) {
2738 // Removed entity ? Compound ? Compsolid ? Shell ? Wire
2739 isGood = Standard_False;
2741 Handle(TDataStd_IntegerArray) anIntegerArray;
2742 if (!aWhatHistoryLabel.FindAttribute(TDataStd_IntegerArray::GetID(), anIntegerArray)) {
2743 //Error: Empty modifications history for the sought shape.
2744 isGood = Standard_False;
2747 isGood = Standard_True;
2748 Standard_Integer imod, aModifLen = anIntegerArray->Array()->Length();
2749 for (imod = 1; imod <= aModifLen; imod++) {
2750 theModifiedList.Append(anIntegerArray->Array()->Value(imod));
2761 // try compound/compsolid/shell/wire element by element
2762 bool isFoundAny = false;
2763 TopTools_MapOfShape mapShape;
2765 if (theWhat.ShapeType() == TopAbs_COMPOUND ||
2766 theWhat.ShapeType() == TopAbs_COMPSOLID) {
2767 // recursive processing of compound/compsolid
2768 TopoDS_Iterator anIt (theWhat, Standard_True, Standard_True);
2769 for (; anIt.More(); anIt.Next()) {
2770 if (mapShape.Add(anIt.Value())) {
2771 TopoDS_Shape curWhat = anIt.Value();
2772 isFoundAny = GetInPlaceOfShape(theWhereFunction, theWhereIndices, curWhat, theModifiedList);
2773 if (isFoundAny) isFound = Standard_True;
2777 else if (theWhat.ShapeType() == TopAbs_SHELL) {
2778 // try to replace a shell by its faces images
2779 TopExp_Explorer anExp (theWhat, TopAbs_FACE);
2780 for (; anExp.More(); anExp.Next()) {
2781 if (mapShape.Add(anExp.Current())) {
2782 TopoDS_Shape curWhat = anExp.Current();
2783 isFoundAny = GetInPlaceOfShape(theWhereFunction, theWhereIndices, curWhat, theModifiedList);
2784 if (isFoundAny) isFound = Standard_True;
2788 else if (theWhat.ShapeType() == TopAbs_WIRE) {
2789 // try to replace a wire by its edges images
2790 TopExp_Explorer anExp (theWhat, TopAbs_EDGE);
2791 for (; anExp.More(); anExp.Next()) {
2792 if (mapShape.Add(anExp.Current())) {
2793 TopoDS_Shape curWhat = anExp.Current();
2794 isFoundAny = GetInPlaceOfShape(theWhereFunction, theWhereIndices, curWhat, theModifiedList);
2795 if (isFoundAny) isFound = Standard_True;
2807 //=============================================================================
2809 * GetShapeProperties
2811 //=============================================================================
2813 void GEOMImpl_IShapesOperations::GetShapeProperties( const TopoDS_Shape aShape, Standard_Real tab[],
2816 GProp_GProps theProps;
2818 TopoDS_Shape aPntShape;
2819 Standard_Real aShapeSize;
2821 if (aShape.ShapeType() == TopAbs_EDGE) BRepGProp::LinearProperties(aShape, theProps);
2822 else if (aShape.ShapeType() == TopAbs_FACE) BRepGProp::SurfaceProperties(aShape, theProps);
2823 else BRepGProp::VolumeProperties(aShape, theProps);
2825 aCenterMass = theProps.CentreOfMass();
2826 aShapeSize = theProps.Mass();
2828 aPntShape = BRepBuilderAPI_MakeVertex(aCenterMass).Shape();
2829 aVertex = BRep_Tool::Pnt( TopoDS::Vertex( aPntShape ) );
2830 tab[0] = aVertex.X();
2831 tab[1] = aVertex.Y();
2832 tab[2] = aVertex.Z();
2833 tab[3] = aShapeSize;
2837 //=============================================================================
2841 //=============================================================================
2842 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlace (Handle(GEOM_Object) theShapeWhere,
2843 Handle(GEOM_Object) theShapeWhat)
2847 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
2849 TopoDS_Shape aWhere = theShapeWhere->GetValue();
2850 TopoDS_Shape aWhat = theShapeWhat->GetValue();
2851 TopoDS_Shape aPntShape;
2852 TopoDS_Vertex aVertex;
2854 if (aWhere.IsNull() || aWhat.IsNull()) {
2855 SetErrorCode("Error: aWhere and aWhat TopoDS_Shape are Null.");
2859 Handle(GEOM_Function) aWhereFunction = theShapeWhere->GetLastFunction();
2860 if (aWhereFunction.IsNull()) {
2861 SetErrorCode("Error: aWhereFunction is Null.");
2865 TopTools_IndexedMapOfShape aWhereIndices;
2866 TopExp::MapShapes(aWhere, aWhereIndices);
2868 TColStd_ListOfInteger aModifiedList;
2869 Standard_Integer aWhereIndex;
2870 Handle(TColStd_HArray1OfInteger) aModifiedArray;
2871 Handle(GEOM_Object) aResult;
2873 bool isFound = false;
2874 Standard_Integer iType = TopAbs_SOLID;
2875 Standard_Integer compType = TopAbs_SOLID;
2876 Standard_Real aWhat_Mass = 0., aWhere_Mass = 0.;
2877 Standard_Real tab_aWhat[4], tab_aWhere[4];
2878 Standard_Real dl_l = 1e-3;
2879 Standard_Real min_l, Tol_1D, Tol_2D, Tol_3D, Tol_Mass;
2880 gp_Pnt aPnt, aPnt_aWhat;
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;
2897 cout << "WARNING : shape to be extracted is of unknown type !" << endl;
2901 TopExp_Explorer Exp_aWhat( aWhat, TopAbs_ShapeEnum( iType ) );
2902 TopExp_Explorer Exp_aWhere( aWhere, TopAbs_ShapeEnum( iType ) );
2903 TopExp_Explorer Exp_Edge( aWhere, TopAbs_EDGE );
2905 // Find the shortest edge in theShapeWhere shape
2906 for ( Standard_Integer nbEdge = 0; Exp_Edge.More(); Exp_Edge.Next(), nbEdge++ ) {
2907 BRepGProp::LinearProperties(Exp_Edge.Current(), aProps);
2908 if ( ! nbEdge ) min_l = aProps.Mass();
2909 if ( aProps.Mass() < min_l ) min_l = aProps.Mass();
2912 // Compute tolerances
2913 Tol_1D = dl_l * min_l;
2914 Tol_2D = dl_l * ( min_l * min_l) * ( 2. + dl_l);
2915 Tol_3D = dl_l * ( min_l * min_l * min_l ) * ( 3. + (3 * dl_l) + (dl_l * dl_l) );
2918 if ( iType == TopAbs_EDGE ) Tol_Mass = Tol_1D;
2919 else if ( iType == TopAbs_FACE ) Tol_Mass = Tol_2D;
2921 // Compute the ShapeWhat Mass
2922 for ( ; Exp_aWhat.More(); Exp_aWhat.Next() ) {
2923 if ( iType == TopAbs_EDGE ) BRepGProp::LinearProperties(Exp_aWhat.Current(), aProps);
2924 else if ( iType == TopAbs_FACE ) BRepGProp::SurfaceProperties(Exp_aWhat.Current(), aProps);
2925 else BRepGProp::VolumeProperties(Exp_aWhat.Current(), aProps);
2926 aWhat_Mass += aProps.Mass();
2929 // Searching for the sub-shapes inside the ShapeWhere shape
2930 for ( Exp_aWhere.ReInit(); Exp_aWhere.More(); Exp_aWhere.Next() ) {
2931 GetShapeProperties( Exp_aWhere.Current(), tab_aWhere, aPnt );
2932 for ( Exp_aWhat.ReInit(); Exp_aWhat.More(); Exp_aWhat.Next() ) {
2933 GetShapeProperties( Exp_aWhat.Current(), tab_aWhat, aPnt_aWhat );
2934 if ( fabs(tab_aWhat[3] - tab_aWhere[3]) <= Tol_Mass && aPnt_aWhat.Distance(aPnt) <= Tol_1D ) isFound = true;
2936 if ( (tab_aWhat[3] - tab_aWhere[3]) > Tol_Mass ) {
2937 aPntShape = BRepBuilderAPI_MakeVertex( aPnt ).Shape();
2938 aVertex = TopoDS::Vertex( aPntShape );
2939 BRepExtrema_DistShapeShape aWhereDistance ( aVertex, Exp_aWhere.Current() );
2940 BRepExtrema_DistShapeShape aWhatDistance ( aVertex, Exp_aWhat.Current() );
2941 if ( fabs(aWhereDistance.Value() - aWhatDistance.Value()) <= Tol_1D ) isFound = true;
2945 aWhereIndex = aWhereIndices.FindIndex(Exp_aWhere.Current());
2946 aModifiedList.Append(aWhereIndex);
2947 aWhere_Mass += tab_aWhere[3];
2952 if ( fabs( aWhat_Mass - aWhere_Mass ) <= Tol_Mass ) break;
2955 if (aModifiedList.Extent() == 0) { // Not found any Results
2956 SetErrorCode(NOT_FOUND_ANY);
2960 aModifiedArray = new TColStd_HArray1OfInteger (1, aModifiedList.Extent());
2961 TColStd_ListIteratorOfListOfInteger anIterModif (aModifiedList);
2962 for (Standard_Integer imod = 1; anIterModif.More(); anIterModif.Next(), imod++)
2963 aModifiedArray->SetValue(imod, anIterModif.Value());
2966 aResult = GetEngine()->AddSubShape(theShapeWhere, aModifiedArray);
2967 if (aResult.IsNull()) {
2968 SetErrorCode("Error in algorithm: result found, but cannot be returned.");
2972 if (aModifiedArray->Length() > 1) {
2974 aResult->SetType(GEOM_GROUP);
2976 //Set a sub shape type
2977 TopoDS_Shape aFirstFound = aWhereIndices.FindKey(aModifiedArray->Value(1));
2978 TopAbs_ShapeEnum aShapeType = aFirstFound.ShapeType();
2980 TDF_Label aFreeLabel = aResult->GetFreeLabel();
2981 TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aShapeType);
2984 //Make a Python command
2985 Handle(GEOM_Function) aFunction = aResult->GetFunction(1);
2987 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetInPlace("
2988 << theShapeWhere << ", " << theShapeWhat << ")";
2994 //=======================================================================
2995 //function : GetInPlaceByHistory
2997 //=======================================================================
2998 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlaceByHistory
2999 (Handle(GEOM_Object) theShapeWhere,
3000 Handle(GEOM_Object) theShapeWhat)
3004 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
3006 TopoDS_Shape aWhere = theShapeWhere->GetValue();
3007 TopoDS_Shape aWhat = theShapeWhat->GetValue();
3009 if (aWhere.IsNull() || aWhat.IsNull()) return NULL;
3011 Handle(GEOM_Function) aWhereFunction = theShapeWhere->GetLastFunction();
3012 if (aWhereFunction.IsNull()) return NULL;
3014 //Fill array of indices
3015 TopTools_IndexedMapOfShape aWhereIndices;
3016 TopExp::MapShapes(aWhere, aWhereIndices);
3019 TColStd_ListOfInteger aModifiedList;
3020 bool isFound = GetInPlaceOfShape(aWhereFunction, aWhereIndices, aWhat, aModifiedList);
3022 if (!isFound || aModifiedList.Extent() < 1) {
3023 SetErrorCode("Error: No history found for the sought shape or its sub-shapes.");
3027 Handle(TColStd_HArray1OfInteger) aModifiedArray =
3028 new TColStd_HArray1OfInteger (1, aModifiedList.Extent());
3029 TColStd_ListIteratorOfListOfInteger anIterModif (aModifiedList);
3030 for (Standard_Integer imod = 1; anIterModif.More(); anIterModif.Next(), imod++) {
3031 aModifiedArray->SetValue(imod, anIterModif.Value());
3035 Handle(GEOM_Object) aResult = GetEngine()->AddSubShape(theShapeWhere, aModifiedArray);
3036 if (aResult.IsNull()) {
3037 SetErrorCode("Error in algorithm: result found, but cannot be returned.");
3041 if (aModifiedArray->Length() > 1) {
3043 aResult->SetType(GEOM_GROUP);
3045 //Set a sub shape type
3046 TopoDS_Shape aFirstFound = aWhereIndices.FindKey(aModifiedArray->Value(1));
3047 TopAbs_ShapeEnum aShapeType = aFirstFound.ShapeType();
3049 TDF_Label aFreeLabel = aResult->GetFreeLabel();
3050 TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aShapeType);
3053 //Make a Python command
3054 Handle(GEOM_Function) aFunction = aResult->GetFunction(1);
3056 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetInPlace("
3057 << theShapeWhere << ", " << theShapeWhat << ")";
3063 //=======================================================================
3064 //function : SortShapes
3066 //=======================================================================
3067 void GEOMImpl_IShapesOperations::SortShapes(TopTools_ListOfShape& SL)
3069 Standard_Integer MaxShapes = SL.Extent();
3070 TopTools_Array1OfShape aShapes (1,MaxShapes);
3071 TColStd_Array1OfInteger OrderInd(1,MaxShapes);
3072 TColStd_Array1OfReal MidXYZ (1,MaxShapes); //X,Y,Z;
3073 TColStd_Array1OfReal Length (1,MaxShapes); //X,Y,Z;
3075 // Computing of CentreOfMass
3076 Standard_Integer Index;
3079 TopTools_ListIteratorOfListOfShape it(SL);
3080 for (Index=1; it.More(); Index++)
3082 TopoDS_Shape S = it.Value();
3083 SL.Remove( it ); // == it.Next()
3085 OrderInd.SetValue (Index, Index);
3086 if (S.ShapeType() == TopAbs_VERTEX)
3088 GPoint = BRep_Tool::Pnt( TopoDS::Vertex( S ));
3089 Length.SetValue( Index, (Standard_Real) S.Orientation());
3093 BRepGProp::LinearProperties (S, GPr);
3094 GPoint = GPr.CentreOfMass();
3095 Length.SetValue( Index, GPr.Mass() );
3097 MidXYZ.SetValue(Index,
3098 GPoint.X()*999 + GPoint.Y()*99 + GPoint.Z()*0.9);
3099 //cout << Index << " L: " << Length(Index) << "CG: " << MidXYZ(Index) << endl;
3103 Standard_Integer aTemp;
3104 Standard_Boolean exchange, Sort = Standard_True;
3105 Standard_Real tol = Precision::Confusion();
3108 Sort = Standard_False;
3109 for (Index=1; Index < MaxShapes; Index++)
3111 Standard_Real dMidXYZ = MidXYZ(OrderInd(Index)) - MidXYZ(OrderInd(Index+1));
3112 Standard_Real dLength = Length(OrderInd(Index)) - Length(OrderInd(Index+1));
3113 if ( dMidXYZ >= tol ) {
3114 // cout << "MidXYZ: " << MidXYZ(OrderInd(Index))<< " > " <<MidXYZ(OrderInd(Index+1))
3115 // << " d: " << dMidXYZ << endl;
3116 exchange = Standard_True;
3118 else if ( Abs(dMidXYZ) < tol && dLength >= tol ) {
3119 // cout << "Length: " << Length(OrderInd(Index))<< " > " <<Length(OrderInd(Index+1))
3120 // << " d: " << dLength << endl;
3121 exchange = Standard_True;
3123 else if ( Abs(dMidXYZ) < tol && Abs(dLength) < tol &&
3124 aShapes(OrderInd(Index)).ShapeType() <= TopAbs_FACE) {
3126 // equal values possible on shapes such as two halves of a sphere and
3127 // a membrane inside the sphere
3129 BRepBndLib::Add( aShapes( OrderInd(Index) ), box1 );
3130 if ( box1.IsVoid() ) continue;
3131 BRepBndLib::Add( aShapes( OrderInd(Index+1) ), box2 );
3132 Standard_Real dSquareExtent = box1.SquareExtent() - box2.SquareExtent();
3133 if ( dSquareExtent >= tol ) {
3134 // cout << "SquareExtent: " << box1.SquareExtent()<<" > "<<box2.SquareExtent() << endl;
3135 exchange = Standard_True;
3137 else if ( Abs(dSquareExtent) < tol ) {
3138 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax, val1, val2;
3139 box1.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
3140 val1 = (aXmin+aXmax)*999 + (aYmin+aYmax)*99 + (aZmin+aZmax)*0.9;
3141 box2.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
3142 val2 = (aXmin+aXmax)*999 + (aYmin+aYmax)*99 + (aZmin+aZmax)*0.9;
3143 exchange = val1 > val2;
3144 // cout << "box: " << val1<<" > "<<val2 << endl;
3148 exchange = Standard_False;
3152 // cout << "exchange " << Index << " & " << Index+1 << endl;
3153 aTemp = OrderInd(Index);
3154 OrderInd(Index) = OrderInd(Index+1);
3155 OrderInd(Index+1) = aTemp;
3156 Sort = Standard_True;
3161 for (Index=1; Index <= MaxShapes; Index++)
3162 SL.Append( aShapes( OrderInd(Index) ));
3165 //=======================================================================
3166 //function : CompsolidToCompound
3168 //=======================================================================
3169 TopoDS_Shape GEOMImpl_IShapesOperations::CompsolidToCompound (const TopoDS_Shape& theCompsolid)
3171 if (theCompsolid.ShapeType() != TopAbs_COMPSOLID) {
3172 return theCompsolid;
3175 TopoDS_Compound aCompound;
3177 B.MakeCompound(aCompound);
3179 TopTools_MapOfShape mapShape;
3180 TopoDS_Iterator It (theCompsolid, Standard_True, Standard_True);
3182 for (; It.More(); It.Next()) {
3183 TopoDS_Shape aShape_i = It.Value();
3184 if (mapShape.Add(aShape_i)) {
3185 B.Add(aCompound, aShape_i);
3192 //=======================================================================
3193 //function : CheckTriangulation
3195 //=======================================================================
3196 bool GEOMImpl_IShapesOperations::CheckTriangulation (const TopoDS_Shape& aShape)
3198 bool isTriangulation = true;
3200 TopExp_Explorer exp (aShape, TopAbs_FACE);
3203 TopLoc_Location aTopLoc;
3204 Handle(Poly_Triangulation) aTRF;
3205 aTRF = BRep_Tool::Triangulation(TopoDS::Face(exp.Current()), aTopLoc);
3206 if (aTRF.IsNull()) {
3207 isTriangulation = false;
3210 else // no faces, try edges
3212 TopExp_Explorer expe (aShape, TopAbs_EDGE);
3216 TopLoc_Location aLoc;
3217 Handle(Poly_Polygon3D) aPE = BRep_Tool::Polygon3D(TopoDS::Edge(expe.Current()), aLoc);
3219 isTriangulation = false;
3223 if (!isTriangulation) {
3224 // calculate deflection
3225 Standard_Real aDeviationCoefficient = 0.001;
3228 BRepBndLib::Add(aShape, B);
3229 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
3230 B.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
3232 Standard_Real dx = aXmax - aXmin, dy = aYmax - aYmin, dz = aZmax - aZmin;
3233 Standard_Real aDeflection = Max(Max(dx, dy), dz) * aDeviationCoefficient * 4;
3234 Standard_Real aHLRAngle = 0.349066;
3236 BRepMesh_IncrementalMesh Inc (aShape, aDeflection, Standard_False, aHLRAngle);
3242 #define MAX_TOLERANCE 1.e-7
3245 //=======================================================================
3246 //function : isSameEdge
3247 //purpose : Returns True if two edges coincide
3248 //=======================================================================
3249 static bool isSameEdge(const TopoDS_Edge& theEdge1, const TopoDS_Edge& theEdge2)
3251 TopoDS_Vertex V11, V12, V21, V22;
3252 TopExp::Vertices(theEdge1, V11, V12);
3253 TopExp::Vertices(theEdge2, V21, V22);
3254 gp_Pnt P11 = BRep_Tool::Pnt(V11);
3255 gp_Pnt P12 = BRep_Tool::Pnt(V12);
3256 gp_Pnt P21 = BRep_Tool::Pnt(V21);
3257 gp_Pnt P22 = BRep_Tool::Pnt(V22);
3258 bool coincide = false;
3260 //Check that ends of edges coincide
3261 if(P11.Distance(P21) <= MAX_TOLERANCE) {
3262 if(P12.Distance(P22) <= MAX_TOLERANCE) coincide = true;
3264 else if(P11.Distance(P22) <= MAX_TOLERANCE) {
3265 if(P12.Distance(P21) <= MAX_TOLERANCE) coincide = true;
3268 if(!coincide) return false;
3270 double U11, U12, U21, U22;
3271 Handle(Geom_Curve) C1 = BRep_Tool::Curve(theEdge1, U11, U12);
3272 Handle(Geom_Curve) C2 = BRep_Tool::Curve(theEdge2, U21, U22);
3273 if(C1->DynamicType() == C2->DynamicType()) return true;
3275 //Check that both edges has the same geometry
3276 double range = U12-U11;
3277 double U = U11+ range/3.0;
3278 gp_Pnt P1 = C1->Value(U); //Compute a point on one third of the edge's length
3279 U = U11+range*2.0/3.0;
3280 gp_Pnt P2 = C1->Value(U); //Compute a point on two thirds of the edge's length
3282 if(!GeomLib_Tool::Parameter(C2, P1, MAX_TOLERANCE, U) || U < U21 || U > U22)
3285 if(P1.Distance(C2->Value(U)) > MAX_TOLERANCE) return false;
3287 if(!GeomLib_Tool::Parameter(C2, P2, MAX_TOLERANCE, U) || U < U21 || U > U22)
3290 if(P2.Distance(C2->Value(U)) > MAX_TOLERANCE) return false;
3295 #include <TopoDS_TShape.hxx>
3296 //=======================================================================
3297 //function : isSameFace
3298 //purpose : Returns True if two faces coincide
3299 //=======================================================================
3300 static bool isSameFace(const TopoDS_Face& theFace1, const TopoDS_Face& theFace2)
3302 TopExp_Explorer E(theFace1, TopAbs_EDGE);
3303 TopTools_ListOfShape LS1, LS2;
3304 for(; E.More(); E.Next()) LS1.Append(E.Current());
3306 E.Init(theFace2, TopAbs_EDGE);
3307 for(; E.More(); E.Next()) LS2.Append(E.Current());
3309 //Compare the number of edges in the faces
3310 if(LS1.Extent() != LS2.Extent()) return false;
3312 double aMin = RealFirst(), aMax = RealLast();
3313 double xminB1=aMax, yminB1=aMax, zminB1=aMax, xminB2=aMax, yminB2=aMax, zminB2=aMax;
3314 double xmaxB1=aMin, ymaxB1=aMin, zmaxB1=aMin, xmaxB2=aMin, ymaxB2=aMin, zmaxB2=aMin;
3316 for(E.Init(theFace1, TopAbs_VERTEX); E.More(); E.Next()) {
3317 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
3318 if(P.X() < xminB1) xminB1 = P.X();
3319 if(P.Y() < yminB1) yminB1 = P.Y();
3320 if(P.Z() < zminB1) zminB1 = P.Z();
3321 if(P.X() > xmaxB1) xmaxB1 = P.X();
3322 if(P.Y() > ymaxB1) ymaxB1 = P.Y();
3323 if(P.Z() > zmaxB1) zmaxB1 = P.Z();
3326 for(E.Init(theFace2, TopAbs_VERTEX); E.More(); E.Next()) {
3327 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
3328 if(P.X() < xminB2) xminB2 = P.X();
3329 if(P.Y() < yminB2) yminB2 = P.Y();
3330 if(P.Z() < zminB2) zminB2 = P.Z();
3331 if(P.X() > xmaxB2) xmaxB2 = P.X();
3332 if(P.Y() > ymaxB2) ymaxB2 = P.Y();
3333 if(P.Z() > zmaxB2) zmaxB2 = P.Z();
3337 //Compare the bounding boxes of both faces
3338 if(gp_Pnt(xminB1, yminB1, zminB1).Distance(gp_Pnt(xminB2, yminB2, zminB2)) > MAX_TOLERANCE)
3341 if(gp_Pnt(xmaxB1, ymaxB1, zmaxB1).Distance(gp_Pnt(xmaxB2, ymaxB2, zmaxB2)) > MAX_TOLERANCE)
3344 Handle(Geom_Surface) S1 = BRep_Tool::Surface(theFace1);
3345 Handle(Geom_Surface) S2 = BRep_Tool::Surface(theFace2);
3347 //Check if there a coincidence of two surfaces at least in two points
3348 double U11, U12, V11, V12, U21, U22, V21, V22;
3349 BRepTools::UVBounds(theFace1, U11, U12, V11, V12);
3350 BRepTools::UVBounds(theFace2, U21, U22, V21, V22);
3352 double rangeU = U12-U11;
3353 double rangeV = V12-V11;
3354 double U = U11 + rangeU/3.0;
3355 double V = V11 + rangeV/3.0;
3356 gp_Pnt P1 = S1->Value(U, V);
3357 U = U11+rangeU*2.0/3.0;
3358 V = V11+rangeV*2.0/3.0;
3359 gp_Pnt P2 = S1->Value(U, V);
3361 if(!GeomLib_Tool::Parameters(S2, P1, MAX_TOLERANCE, U, V) || U < U21 || U > U22 || V < V21 || V > V22)
3364 if(P1.Distance(S2->Value(U,V)) > MAX_TOLERANCE) return false;
3366 if(!GeomLib_Tool::Parameters(S2, P2, MAX_TOLERANCE, U, V) || U < U21 || U > U22 || V < V21 || V > V22)
3369 if(P2.Distance(S2->Value(U, V)) > MAX_TOLERANCE) return false;
3371 //Check that each edge of the Face1 has a counterpart in the Face2
3372 TopTools_MapOfOrientedShape aMap;
3373 TopTools_ListIteratorOfListOfShape LSI1(LS1);
3374 for(; LSI1.More(); LSI1.Next()) {
3375 TopoDS_Edge E = TopoDS::Edge(LSI1.Value());
3376 bool isFound = false;
3377 TopTools_ListIteratorOfListOfShape LSI2(LS2);
3378 for(; LSI2.More(); LSI2.Next()) {
3379 TopoDS_Shape aValue = LSI2.Value();
3380 if(aMap.Contains(aValue)) continue; //To avoid checking already found edge several times
3381 if(isSameEdge(E, TopoDS::Edge(aValue))) {
3387 if(!isFound) return false;
3393 //=======================================================================
3394 //function : isSameSolid
3395 //purpose : Returns True if two solids coincide
3396 //=======================================================================
3397 bool isSameSolid(const TopoDS_Solid& theSolid1, const TopoDS_Solid& theSolid2)
3399 TopExp_Explorer E(theSolid1, TopAbs_FACE);
3400 TopTools_ListOfShape LS1, LS2;
3401 for(; E.More(); E.Next()) LS1.Append(E.Current());
3402 E.Init(theSolid2, TopAbs_FACE);
3403 for(; E.More(); E.Next()) LS2.Append(E.Current());
3405 if(LS1.Extent() != LS2.Extent()) return false;
3407 double aMin = RealFirst(), aMax = RealLast();
3408 double xminB1=aMax, yminB1=aMax, zminB1=aMax, xminB2=aMax, yminB2=aMax, zminB2=aMax;
3409 double xmaxB1=aMin, ymaxB1=aMin, zmaxB1=aMin, xmaxB2=aMin, ymaxB2=aMin, zmaxB2=aMin;
3411 for(E.Init(theSolid1, TopAbs_VERTEX); E.More(); E.Next()) {
3412 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
3413 if(P.X() < xminB1) xminB1 = P.X();
3414 if(P.Y() < yminB1) yminB1 = P.Y();
3415 if(P.Z() < zminB1) zminB1 = P.Z();
3416 if(P.X() > xmaxB1) xmaxB1 = P.X();
3417 if(P.Y() > ymaxB1) ymaxB1 = P.Y();
3418 if(P.Z() > zmaxB1) zmaxB1 = P.Z();
3421 for(E.Init(theSolid2, TopAbs_VERTEX); E.More(); E.Next()) {
3422 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
3423 if(P.X() < xminB2) xminB2 = P.X();
3424 if(P.Y() < yminB2) yminB2 = P.Y();
3425 if(P.Z() < zminB2) zminB2 = P.Z();
3426 if(P.X() > xmaxB2) xmaxB2 = P.X();
3427 if(P.Y() > ymaxB2) ymaxB2 = P.Y();
3428 if(P.Z() > zmaxB2) zmaxB2 = P.Z();
3431 //Compare the bounding boxes of both solids
3432 if(gp_Pnt(xminB1, yminB1, zminB1).Distance(gp_Pnt(xminB2, yminB2, zminB2)) > MAX_TOLERANCE)
3435 if(gp_Pnt(xmaxB1, ymaxB1, zmaxB1).Distance(gp_Pnt(xmaxB2, ymaxB2, zmaxB2)) > MAX_TOLERANCE)
3438 //Check that each face of the Solid1 has a counterpart in the Solid2
3439 TopTools_MapOfOrientedShape aMap;
3440 TopTools_ListIteratorOfListOfShape LSI1(LS1);
3441 for(; LSI1.More(); LSI1.Next()) {
3442 TopoDS_Face F = TopoDS::Face(LSI1.Value());
3443 bool isFound = false;
3444 TopTools_ListIteratorOfListOfShape LSI2(LS2);
3445 for(; LSI2.More(); LSI2.Next()) {
3446 if(aMap.Contains(LSI2.Value())) continue; //To avoid checking already found faces several times
3447 if(isSameFace(F, TopoDS::Face(LSI2.Value()))) {
3448 aMap.Add(LSI2.Value());
3453 if(!isFound) return false;
3459 //=======================================================================
3460 //function : GetSame
3462 //=======================================================================
3463 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetSame(const Handle(GEOM_Object)& theShapeWhere,
3464 const Handle(GEOM_Object)& theShapeWhat)
3467 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
3469 TopoDS_Shape aWhere = theShapeWhere->GetValue();
3470 TopoDS_Shape aWhat = theShapeWhat->GetValue();
3472 if (aWhere.IsNull() || aWhat.IsNull()) return NULL;
3475 bool isFound = false;
3476 TopoDS_Shape aSubShape;
3477 TopTools_MapOfShape aMap;
3479 switch(aWhat.ShapeType()) {
3480 case TopAbs_VERTEX: {
3481 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(aWhat));
3482 TopExp_Explorer E(aWhere, TopAbs_VERTEX);
3483 for(; E.More(); E.Next()) {
3484 if(!aMap.Add(E.Current())) continue;
3485 gp_Pnt P2 = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
3486 if(P.Distance(P2) <= MAX_TOLERANCE) {
3488 aSubShape = E.Current();
3495 TopoDS_Face aFace = TopoDS::Face(aWhat);
3496 TopExp_Explorer E(aWhere, TopAbs_FACE);
3497 for(; E.More(); E.Next()) {
3498 if(!aMap.Add(E.Current())) continue;
3499 if(isSameFace(aFace, TopoDS::Face(E.Current()))) {
3500 aSubShape = E.Current();
3508 TopoDS_Edge anEdge = TopoDS::Edge(aWhat);
3509 TopExp_Explorer E(aWhere, TopAbs_EDGE);
3510 for(; E.More(); E.Next()) {
3511 if(!aMap.Add(E.Current())) continue;
3512 if(isSameEdge(anEdge, TopoDS::Edge(E.Current()))) {
3513 aSubShape = E.Current();
3520 case TopAbs_SOLID: {
3521 TopoDS_Solid aSolid = TopoDS::Solid(aWhat);
3522 TopExp_Explorer E(aWhere, TopAbs_SOLID);
3523 for(; E.More(); E.Next()) {
3524 if(!aMap.Add(E.Current())) continue;
3525 if(isSameSolid(aSolid, TopoDS::Solid(E.Current()))) {
3526 aSubShape = E.Current();
3538 TopTools_IndexedMapOfShape anIndices;
3539 TopExp::MapShapes(aWhere, anIndices);
3540 if (anIndices.Contains(aSubShape))
3541 anIndex = anIndices.FindIndex(aSubShape);
3544 if(anIndex < 0) return NULL;
3546 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
3548 anArray->SetValue(1, anIndex);
3550 Handle(GEOM_Object) aResult = GetEngine()->AddSubShape(theShapeWhere, anArray);
3551 Handle(GEOM_Function) aFunction = aResult->GetLastFunction();
3553 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetSame("
3554 << theShapeWhere << ", " << theShapeWhat << ")";