1 // Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 // File : GEOMImpl_IShapesOperations.cxx
24 // Author : modified by Lioka RAZAFINDRAZAKA (CEA) 22/06/2007
28 #include <Standard_Stream.hxx>
30 #include "GEOMImpl_IShapesOperations.hxx"
32 #include "GEOMImpl_Types.hxx"
34 #include "GEOMImpl_VectorDriver.hxx"
35 #include "GEOMImpl_ShapeDriver.hxx"
36 #include "GEOMImpl_CopyDriver.hxx"
37 #include "GEOMImpl_GlueDriver.hxx"
39 #include "GEOMImpl_IVector.hxx"
40 #include "GEOMImpl_IShapes.hxx"
41 #include "GEOMImpl_IGlue.hxx"
43 #include "GEOMImpl_Block6Explorer.hxx"
45 #include "GEOM_Function.hxx"
46 #include "GEOM_ISubShape.hxx"
47 #include "GEOM_PythonDump.hxx"
49 #include "GEOMAlgo_FinderShapeOn1.hxx"
50 #include "GEOMAlgo_FinderShapeOnQuad.hxx"
51 #include "GEOMAlgo_FinderShapeOn2.hxx"
52 #include "GEOMAlgo_ClsfBox.hxx"
53 #include "GEOMAlgo_ClsfSolid.hxx"
54 #include "GEOMAlgo_Gluer1.hxx"
55 #include "GEOMAlgo_ListIteratorOfListOfCoupleOfShapes.hxx"
56 #include "GEOMAlgo_CoupleOfShapes.hxx"
57 #include "GEOMAlgo_ListOfCoupleOfShapes.hxx"
59 #include "utilities.h"
61 #include "Utils_ExceptHandlers.hxx"
63 #include <TFunction_DriverTable.hxx>
64 #include <TFunction_Driver.hxx>
65 #include <TFunction_Logbook.hxx>
66 #include <TDataStd_Integer.hxx>
67 #include <TDataStd_IntegerArray.hxx>
68 #include <TDataStd_ListIteratorOfListOfExtendedString.hxx>
69 #include <TDF_Tool.hxx>
71 #include <BRepExtrema_ExtCF.hxx>
72 #include <BRepExtrema_DistShapeShape.hxx>
74 #include <BRep_Tool.hxx>
75 #include <BRep_Builder.hxx>
76 #include <BRepTools.hxx>
77 #include <BRepGProp.hxx>
78 #include <BRepAdaptor_Curve.hxx>
79 #include <BRepAdaptor_Surface.hxx>
80 #include <BRepBndLib.hxx>
81 #include <BRepBuilderAPI_MakeFace.hxx>
82 #include <BRepMesh_IncrementalMesh.hxx>
87 #include <TopoDS_Shape.hxx>
88 #include <TopoDS_Solid.hxx>
89 #include <TopoDS_Face.hxx>
90 #include <TopoDS_Edge.hxx>
91 #include <TopoDS_Vertex.hxx>
92 #include <TopoDS_Compound.hxx>
93 #include <TopoDS_Iterator.hxx>
94 #include <TopExp_Explorer.hxx>
95 #include <TopLoc_Location.hxx>
96 #include <TopTools_MapOfShape.hxx>
97 #include <TopTools_MapOfOrientedShape.hxx>
98 #include <TopTools_Array1OfShape.hxx>
99 #include <TopTools_ListIteratorOfListOfShape.hxx>
100 #include <TopTools_IndexedMapOfShape.hxx>
102 #include <Geom_Surface.hxx>
103 #include <Geom_Plane.hxx>
104 #include <Geom_SphericalSurface.hxx>
105 #include <Geom_CylindricalSurface.hxx>
106 #include <GeomAdaptor_Surface.hxx>
108 #include <GeomLib_Tool.hxx>
109 #include <Geom2d_Curve.hxx>
111 #include <Bnd_Box.hxx>
112 #include <GProp_GProps.hxx>
113 #include <TColStd_Array1OfReal.hxx>
114 #include <TColStd_HArray1OfInteger.hxx>
115 #include <TColStd_ListIteratorOfListOfInteger.hxx>
116 #include <TColStd_ListOfInteger.hxx>
117 #include <gp_Cylinder.hxx>
118 #include <gp_Lin.hxx>
119 #include <gp_Pnt.hxx>
123 #include <Standard_NullObject.hxx>
124 #include <Standard_Failure.hxx>
125 #include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
127 // Includes added for GetInPlace algorithm improvement
129 #include <GEOMImpl_MeasureDriver.hxx>
130 #include <GEOMImpl_IMeasure.hxx>
131 #include <BRepBuilderAPI_MakeVertex.hxx>
133 #include <BRepClass_FaceClassifier.hxx>
134 #include <BRepClass3d_SolidClassifier.hxx>
135 #include <Precision.hxx>
137 //=============================================================================
141 //=============================================================================
142 GEOMImpl_IShapesOperations::GEOMImpl_IShapesOperations (GEOM_Engine* theEngine, int theDocID)
143 : GEOM_IOperations(theEngine, theDocID)
145 MESSAGE("GEOMImpl_IShapesOperations::GEOMImpl_IShapesOperations");
148 //=============================================================================
152 //=============================================================================
153 GEOMImpl_IShapesOperations::~GEOMImpl_IShapesOperations()
155 MESSAGE("GEOMImpl_IShapesOperations::~GEOMImpl_IShapesOperations");
158 //=============================================================================
162 //=============================================================================
163 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeEdge
164 (Handle(GEOM_Object) thePnt1, Handle(GEOM_Object) thePnt2)
168 if (thePnt1.IsNull() || thePnt2.IsNull()) return NULL;
170 //Add a new Edge object
171 Handle(GEOM_Object) anEdge = GetEngine()->AddObject(GetDocID(), GEOM_EDGE);
173 //Add a new Vector function
174 Handle(GEOM_Function) aFunction =
175 anEdge->AddFunction(GEOMImpl_VectorDriver::GetID(), VECTOR_TWO_PNT);
177 //Check if the function is set correctly
178 if (aFunction->GetDriverGUID() != GEOMImpl_VectorDriver::GetID()) return NULL;
180 GEOMImpl_IVector aPI (aFunction);
182 Handle(GEOM_Function) aRef1 = thePnt1->GetLastFunction();
183 Handle(GEOM_Function) aRef2 = thePnt2->GetLastFunction();
184 if (aRef1.IsNull() || aRef2.IsNull()) return NULL;
186 aPI.SetPoint1(aRef1);
187 aPI.SetPoint2(aRef2);
189 //Compute the Edge value
191 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
194 if (!GetSolver()->ComputeFunction(aFunction)) {
195 SetErrorCode("Vector driver failed");
199 catch (Standard_Failure) {
200 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
201 SetErrorCode(aFail->GetMessageString());
205 //Make a Python command
206 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdge("
207 << thePnt1 << ", " << thePnt2 << ")";
213 //=============================================================================
217 //=============================================================================
218 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeEdgeWire
219 (Handle(GEOM_Object) theWire,
220 const Standard_Real theLinearTolerance,
221 const Standard_Real theAngularTolerance)
225 if (theWire.IsNull()) return NULL;
227 //Add a new Edge object
228 Handle(GEOM_Object) anEdge = GetEngine()->AddObject(GetDocID(), GEOM_EDGE);
230 //Add a new Vector function
231 Handle(GEOM_Function) aFunction =
232 anEdge->AddFunction(GEOMImpl_ShapeDriver::GetID(), EDGE_WIRE);
234 //Check if the function is set correctly
235 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
237 GEOMImpl_IShapes aCI (aFunction);
239 Handle(GEOM_Function) aWire = theWire->GetLastFunction();
241 if (aWire.IsNull()) return NULL;
244 aCI.SetTolerance(theLinearTolerance);
245 aCI.SetAngularTolerance(theAngularTolerance);
247 //Compute the Edge value
249 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
252 if (!GetSolver()->ComputeFunction(aFunction)) {
253 SetErrorCode("Shape driver failed");
257 catch (Standard_Failure) {
258 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
259 SetErrorCode(aFail->GetMessageString());
263 const double DEF_LIN_TOL = Precision::Confusion();
264 const double DEF_ANG_TOL = Precision::Angular();
265 //Make a Python command
266 if ( theAngularTolerance == DEF_ANG_TOL ) {
267 if ( theLinearTolerance == DEF_LIN_TOL )
268 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdgeWire("
271 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdgeWire("
272 << theWire << ", " << theLinearTolerance << ")";
275 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdgeWire("
276 << theWire << ", " << theLinearTolerance << ", "
277 << theAngularTolerance << ")";
284 //=============================================================================
288 //=============================================================================
289 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeWire
290 (std::list<Handle(GEOM_Object)> theShapes,
291 const Standard_Real theTolerance)
296 Handle(GEOM_Object) aWire = GetEngine()->AddObject(GetDocID(), GEOM_WIRE);
299 Handle(GEOM_Function) aFunction =
300 aWire->AddFunction(GEOMImpl_ShapeDriver::GetID(), WIRE_EDGES);
301 if (aFunction.IsNull()) return NULL;
303 //Check if the function is set correctly
304 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
306 GEOMImpl_IShapes aCI (aFunction);
307 aCI.SetTolerance(theTolerance);
309 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
312 std::list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
313 for (; it != theShapes.end(); it++) {
314 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
315 if (aRefSh.IsNull()) {
316 SetErrorCode("NULL argument shape for the shape construction");
319 aShapesSeq->Append(aRefSh);
321 aCI.SetShapes(aShapesSeq);
325 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
328 if (!GetSolver()->ComputeFunction(aFunction)) {
329 SetErrorCode("Shape driver failed");
333 catch (Standard_Failure) {
334 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
335 SetErrorCode(aFail->GetMessageString());
339 //Make a Python command
340 GEOM::TPythonDump pd (aFunction);
341 pd << aWire << " = geompy.MakeWire([";
344 it = theShapes.begin();
345 if (it != theShapes.end()) {
347 while (it != theShapes.end()) {
348 pd << ", " << (*it++);
351 pd << "], " << theTolerance << ")";
357 //=============================================================================
361 //=============================================================================
362 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFace (Handle(GEOM_Object) theWire,
363 const bool isPlanarWanted)
367 if (theWire.IsNull()) return NULL;
369 //Add a new Face object
370 Handle(GEOM_Object) aFace = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
372 //Add a new Shape function for creation of a face from a wire
373 Handle(GEOM_Function) aFunction =
374 aFace->AddFunction(GEOMImpl_ShapeDriver::GetID(), FACE_WIRE);
375 if (aFunction.IsNull()) return NULL;
377 //Check if the function is set correctly
378 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
380 GEOMImpl_IShapes aCI (aFunction);
382 Handle(GEOM_Function) aRefWire = theWire->GetLastFunction();
384 if (aRefWire.IsNull()) return NULL;
386 aCI.SetBase(aRefWire);
387 aCI.SetIsPlanar(isPlanarWanted);
389 //Compute the Face value
391 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
394 if (!GetSolver()->ComputeFunction(aFunction)) {
395 SetErrorCode("Shape driver failed to compute a face");
399 catch (Standard_Failure) {
400 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
401 SetErrorCode(aFail->GetMessageString());
405 //Make a Python command
406 GEOM::TPythonDump(aFunction) << aFace << " = geompy.MakeFace("
407 << theWire << ", " << (int)isPlanarWanted << ")";
413 //=============================================================================
417 //=============================================================================
418 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFaceWires
419 (std::list<Handle(GEOM_Object)> theShapes,
420 const bool isPlanarWanted)
425 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
428 Handle(GEOM_Function) aFunction =
429 aShape->AddFunction(GEOMImpl_ShapeDriver::GetID(), FACE_WIRES);
430 if (aFunction.IsNull()) return NULL;
432 //Check if the function is set correctly
433 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
435 GEOMImpl_IShapes aCI (aFunction);
437 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
440 std::list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
441 for (; it != theShapes.end(); it++) {
442 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
443 if (aRefSh.IsNull()) {
444 SetErrorCode("NULL argument shape for the face construction");
447 aShapesSeq->Append(aRefSh);
449 aCI.SetShapes(aShapesSeq);
451 aCI.SetIsPlanar(isPlanarWanted);
455 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
458 if (!GetSolver()->ComputeFunction(aFunction)) {
459 SetErrorCode("Shape driver failed");
463 catch (Standard_Failure) {
464 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
465 SetErrorCode(aFail->GetMessageString());
469 //Make a Python command
470 GEOM::TPythonDump pd (aFunction);
471 pd << aShape << " = geompy.MakeFaceWires([";
474 it = theShapes.begin();
475 if (it != theShapes.end()) {
477 while (it != theShapes.end()) {
478 pd << ", " << (*it++);
481 pd << "], " << (int)isPlanarWanted << ")";
487 //=============================================================================
491 //=============================================================================
492 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeShell
493 (std::list<Handle(GEOM_Object)> theShapes)
495 return MakeShape(theShapes, GEOM_SHELL, SHELL_FACES, "MakeShell");
498 //=============================================================================
502 //=============================================================================
503 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeSolidShells
504 (std::list<Handle(GEOM_Object)> theShapes)
506 return MakeShape(theShapes, GEOM_SOLID, SOLID_SHELLS, "MakeSolid");
509 //=============================================================================
513 //=============================================================================
514 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeCompound
515 (std::list<Handle(GEOM_Object)> theShapes)
517 return MakeShape(theShapes, GEOM_COMPOUND, COMPOUND_SHAPES, "MakeCompound");
520 //=============================================================================
524 //=============================================================================
525 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeShape
526 (std::list<Handle(GEOM_Object)> theShapes,
527 const Standard_Integer theObjectType,
528 const Standard_Integer theFunctionType,
529 const TCollection_AsciiString& theMethodName)
534 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), theObjectType);
537 Handle(GEOM_Function) aFunction =
538 aShape->AddFunction(GEOMImpl_ShapeDriver::GetID(), theFunctionType);
539 if (aFunction.IsNull()) return NULL;
541 //Check if the function is set correctly
542 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
544 GEOMImpl_IShapes aCI (aFunction);
546 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
549 std::list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
550 for (; it != theShapes.end(); it++) {
551 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
552 if (aRefSh.IsNull()) {
553 SetErrorCode("NULL argument shape for the shape construction");
556 aShapesSeq->Append(aRefSh);
558 aCI.SetShapes(aShapesSeq);
562 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
565 if (!GetSolver()->ComputeFunction(aFunction)) {
566 SetErrorCode("Shape driver failed");
570 catch (Standard_Failure) {
571 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
572 SetErrorCode(aFail->GetMessageString());
576 //Make a Python command
577 GEOM::TPythonDump pd (aFunction);
578 pd << aShape << " = geompy." << theMethodName.ToCString() << "([";
581 it = theShapes.begin();
582 if (it != theShapes.end()) {
584 while (it != theShapes.end()) {
585 pd << ", " << (*it++);
594 //=============================================================================
598 //=============================================================================
599 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeGlueFaces
600 (Handle(GEOM_Object) theShape,
601 const Standard_Real theTolerance,
602 const Standard_Boolean doKeepNonSolids)
606 if (theShape.IsNull()) return NULL;
608 //Add a new Glued object
609 Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
611 //Add a new Glue function
612 Handle(GEOM_Function) aFunction;
613 aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_FACES);
614 if (aFunction.IsNull()) return NULL;
616 //Check if the function is set correctly
617 if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
619 GEOMImpl_IGlue aCI (aFunction);
621 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
622 if (aRefShape.IsNull()) return NULL;
624 aCI.SetBase(aRefShape);
625 aCI.SetTolerance(theTolerance);
626 aCI.SetKeepNonSolids(doKeepNonSolids);
628 //Compute the sub-shape value
629 Standard_Boolean isWarning = Standard_False;
631 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
634 if (!GetSolver()->ComputeFunction(aFunction)) {
635 SetErrorCode("Shape driver failed to glue faces");
639 catch (Standard_Failure) {
640 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
641 SetErrorCode(aFail->GetMessageString());
642 // to provide warning
643 if (!aFunction->GetValue().IsNull()) {
644 isWarning = Standard_True;
650 //Make a Python command
651 GEOM::TPythonDump(aFunction) << aGlued << " = geompy.MakeGlueFaces("
652 << theShape << ", " << theTolerance << ")";
654 // to provide warning
655 if (!isWarning) SetErrorCode(OK);
659 //=============================================================================
663 //=============================================================================
664 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetGlueFaces
665 (Handle(GEOM_Object) theShape,
666 const Standard_Real theTolerance)
670 if (theShape.IsNull()) return NULL;
671 TopoDS_Shape aShape = theShape->GetValue();
672 if (aShape.IsNull()) return NULL;
674 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
676 Standard_Integer iErr;
678 GEOMAlgo_Gluer1 aGluer;
679 GEOMAlgo_ListIteratorOfListOfCoupleOfShapes aItCS;
680 GEOMAlgo_CoupleOfShapes aCS;
681 GEOMAlgo_ListOfCoupleOfShapes aLCS;
683 //aGluer = new GEOMAlgo_Gluer1;
684 aGluer.SetShape(aShape);
685 aGluer.SetTolerance(theTolerance);
687 iErr = aGluer.ErrorStatus();
688 if (iErr) return NULL;
690 TopTools_ListOfShape listShape;
691 const GEOMAlgo_ListOfCoupleOfShapes& aLCSG = aGluer.GluedFaces();
693 aItCS.Initialize(aLCSG);
694 for (; aItCS.More(); aItCS.Next()) {
695 const GEOMAlgo_CoupleOfShapes& aCSG = aItCS.Value();
696 listShape.Append(aCSG.Shape1());
699 TopTools_ListIteratorOfListOfShape itSub (listShape);
700 TCollection_AsciiString anAsciiList, anEntry;
701 TopTools_IndexedMapOfShape anIndices;
702 TopExp::MapShapes(aShape, anIndices);
703 Handle(TColStd_HArray1OfInteger) anArray;
704 Handle(GEOM_Object) anObj;
705 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
706 TopoDS_Shape aValue = itSub.Value();
707 anArray = new TColStd_HArray1OfInteger(1,1);
708 anArray->SetValue(1, anIndices.FindIndex(aValue));
709 anObj = GetEngine()->AddSubShape(theShape, anArray);
710 if (!anObj.IsNull()) {
713 // for python command
714 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
715 anAsciiList += anEntry;
720 //Make a Python command
721 if( anAsciiList.Length() > 0 ) {
722 anAsciiList.Trunc(anAsciiList.Length() - 1);
723 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
724 GEOM::TPythonDump pd (aFunction, /*append=*/true);
725 pd << "[" << anAsciiList.ToCString();
726 pd << "] = geompy.GetGlueFaces(" << theShape << ", " << theTolerance << ")";
734 //=============================================================================
736 * MakeGlueFacesByList
738 //=============================================================================
739 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeGlueFacesByList
740 (Handle(GEOM_Object) theShape,
741 const Standard_Real theTolerance,
742 std::list<Handle(GEOM_Object)> theFaces,
743 const Standard_Boolean doKeepNonSolids)
747 if (theShape.IsNull()) return NULL;
749 //Add a new Glued object
750 Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
752 //Add a new Glue function
753 Handle(GEOM_Function) aFunction;
754 aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_FACES_BY_LIST);
755 if (aFunction.IsNull()) return NULL;
757 //Check if the function is set correctly
758 if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
760 GEOMImpl_IGlue aCI (aFunction);
762 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
763 if (aRefShape.IsNull()) return NULL;
765 aCI.SetBase(aRefShape);
766 aCI.SetTolerance(theTolerance);
767 aCI.SetKeepNonSolids(doKeepNonSolids);
769 Handle(TColStd_HSequenceOfTransient) aFaces = new TColStd_HSequenceOfTransient;
770 std::list<Handle(GEOM_Object)>::iterator it = theFaces.begin();
771 for (; it != theFaces.end(); it++) {
772 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
773 if (aRefSh.IsNull()) {
774 SetErrorCode("NULL argument shape for the shape construction");
777 aFaces->Append(aRefSh);
779 aCI.SetFaces(aFaces);
781 //Compute the sub-shape value
782 Standard_Boolean isWarning = Standard_False;
784 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
787 if (!GetSolver()->ComputeFunction(aFunction)) {
788 SetErrorCode("Shape driver failed to glue faces");
792 catch (Standard_Failure) {
793 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
794 SetErrorCode(aFail->GetMessageString());
795 // to provide warning
796 if (!aFunction->GetValue().IsNull()) {
797 isWarning = Standard_True;
803 //Make a Python command
805 GEOM::TPythonDump pd(aFunction);
806 pd << aGlued << " = geompy.MakeGlueFacesByList("
807 << theShape << ", " << theTolerance << ", [";
809 it = theFaces.begin();
810 if (it != theFaces.end()) {
812 while (it != theFaces.end()) {
813 pd << ", " << (*it++);
818 // to provide warning
819 if (!isWarning) SetErrorCode(OK);
823 //=============================================================================
825 * GetExistingSubObjects
827 //=============================================================================
828 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetExistingSubObjects
829 (Handle(GEOM_Object) theShape,
830 const Standard_Boolean theGroupsOnly)
834 if (theShape.IsNull()) return NULL;
836 Handle(GEOM_Function) aMainShape = theShape->GetLastFunction();
837 if (aMainShape.IsNull()) return NULL;
839 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
840 SetErrorCode(NOT_FOUND_ANY);
842 if (!aMainShape->HasSubShapeReferences()) return aSeq;
843 const TDataStd_ListOfExtendedString& aListEntries = aMainShape->GetSubShapeReferences();
844 if (aListEntries.IsEmpty()) return aSeq;
848 TCollection_AsciiString anAsciiList;
850 TDataStd_ListIteratorOfListOfExtendedString anIt (aListEntries);
851 for (; anIt.More(); anIt.Next()) {
852 TCollection_ExtendedString anEntry = anIt.Value();
853 Standard_Integer aStrLen = anEntry.LengthOfCString();
854 char* anEntryStr = new char[aStrLen];
855 anEntry.ToUTF8CString(anEntryStr);
856 Handle(GEOM_Object) anObj = GetEngine()->GetObject(GetDocID(), anEntryStr, false);
857 if (!anObj.IsNull()) {
858 if (!theGroupsOnly || anObj->GetType() == GEOM_GROUP) {
861 // for python command
862 anAsciiList += anEntryStr;
866 delete [] anEntryStr;
869 if (aSeq->Length() == 0) {
870 SetErrorCode(NOT_FOUND_ANY);
874 //Make a Python command
875 anAsciiList.Trunc(anAsciiList.Length() - 1);
877 GEOM::TPythonDump pd (aMainShape, /*append=*/true);
878 pd << "[" << anAsciiList.ToCString();
879 pd << "] = geompy.GetExistingSubObjects(";
880 pd << theShape << ", " << (int)theGroupsOnly << ")";
887 //=============================================================================
891 //=============================================================================
892 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::MakeExplode
893 (Handle(GEOM_Object) theShape,
894 const Standard_Integer theShapeType,
895 const Standard_Boolean isSorted,
896 const Standard_Boolean isOldSorting)
900 if (theShape.IsNull()) return NULL;
901 TopoDS_Shape aShape = theShape->GetValue();
902 if (aShape.IsNull()) return NULL;
904 Handle(GEOM_Function) aMainShape = theShape->GetLastFunction();
906 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
907 Handle(GEOM_Object) anObj;
908 TopTools_MapOfShape mapShape;
909 TopTools_ListOfShape listShape;
911 if (aShape.ShapeType() == TopAbs_COMPOUND &&
912 (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
913 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPSOLID ||
914 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPOUND)) {
915 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
916 for (; It.More(); It.Next()) {
917 if (mapShape.Add(It.Value())) {
918 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
919 TopAbs_ShapeEnum(theShapeType) == It.Value().ShapeType()) {
920 listShape.Append(It.Value());
925 else if ( aShape.ShapeType() != theShapeType ) // issue 0021079, prevent from returning aShape
927 TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
928 for (; exp.More(); exp.Next())
929 if (mapShape.Add(exp.Current()))
930 listShape.Append(exp.Current());
933 if (listShape.IsEmpty()) {
934 //SetErrorCode("The given shape has no sub-shapes of the requested type");
935 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
940 SortShapes(listShape, isOldSorting);
942 TopTools_IndexedMapOfShape anIndices;
943 TopExp::MapShapes(aShape, anIndices);
944 Handle(TColStd_HArray1OfInteger) anArray;
946 TopTools_ListIteratorOfListOfShape itSub (listShape);
947 TCollection_AsciiString anAsciiList, anEntry;
948 for (int index = 1; itSub.More(); itSub.Next(), ++index)
950 TopoDS_Shape aValue = itSub.Value();
951 anArray = new TColStd_HArray1OfInteger(1,1);
952 anArray->SetValue(1, anIndices.FindIndex(aValue));
954 //anObj = GetEngine()->AddSubShape(theShape, anArray);
956 anObj = GetEngine()->AddObject(GetDocID(), GEOM_SUBSHAPE);
957 Handle(GEOM_Function) aFunction = anObj->AddFunction(GEOM_Object::GetSubShapeID(), 1);
958 if (aFunction.IsNull()) return aSeq;
960 GEOM_ISubShape aSSI (aFunction);
961 aSSI.SetMainShape(aMainShape);
962 aSSI.SetIndices(anArray);
964 // Set function value directly, as we know it.
965 // Usage of Solver here would lead to significant loss of time,
966 // because GEOM_SubShapeDriver will build TopTools_IndexedMapOfShape
967 // on the main shape for each being calculated sub-shape separately.
968 aFunction->SetValue(aValue);
971 if (!anObj.IsNull()) {
974 // for python command
975 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
976 anAsciiList += anEntry;
981 //Make a Python command
982 anAsciiList.Trunc(anAsciiList.Length() - 1);
984 GEOM::TPythonDump pd (aMainShape, /*append=*/true);
985 pd << "[" << anAsciiList.ToCString();
987 pd << "] = geompy.SubShapeAllSorted" << (isOldSorting ? "(" : "Centres(");
989 pd << "] = geompy.SubShapeAll(";
990 pd << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
997 //=============================================================================
1001 //=============================================================================
1002 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::SubShapeAllIDs
1003 (Handle(GEOM_Object) theShape,
1004 const Standard_Integer theShapeType,
1005 const Standard_Boolean isSorted,
1006 const Standard_Boolean isOldSorting)
1010 if (theShape.IsNull()) return NULL;
1011 TopoDS_Shape aShape = theShape->GetValue();
1012 if (aShape.IsNull()) return NULL;
1014 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
1015 TopTools_MapOfShape mapShape;
1016 TopTools_ListOfShape listShape;
1018 if (aShape.ShapeType() == TopAbs_COMPOUND &&
1019 (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
1020 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPSOLID ||
1021 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPOUND)) {
1022 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
1023 for (; It.More(); It.Next()) {
1024 if (mapShape.Add(It.Value())) {
1025 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
1026 TopAbs_ShapeEnum(theShapeType) == It.Value().ShapeType()) {
1027 listShape.Append(It.Value());
1031 } else if ( aShape.ShapeType() != theShapeType ) // issue 0021079, prevent from returning aShape
1033 TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
1034 for (; exp.More(); exp.Next())
1035 if (mapShape.Add(exp.Current()))
1036 listShape.Append(exp.Current());
1039 if (listShape.IsEmpty()) {
1040 //SetErrorCode("The given shape has no sub-shapes of the requested type");
1041 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
1046 SortShapes(listShape, isOldSorting);
1048 TopTools_IndexedMapOfShape anIndices;
1049 TopExp::MapShapes(aShape, anIndices);
1050 Handle(TColStd_HArray1OfInteger) anArray;
1052 TopTools_ListIteratorOfListOfShape itSub (listShape);
1053 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
1054 TopoDS_Shape aValue = itSub.Value();
1055 aSeq->Append(anIndices.FindIndex(aValue));
1058 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
1060 //Make a Python command
1061 GEOM::TPythonDump pd (aFunction, /*append=*/true);
1062 pd << "listSubShapeIDs = geompy.SubShapeAll";
1064 pd << "Sorted" << (isOldSorting ? "IDs(" : "CentresIDs(");
1067 pd << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
1073 //=============================================================================
1077 //=============================================================================
1078 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetSubShape
1079 (Handle(GEOM_Object) theMainShape,
1080 const Standard_Integer theID)
1084 if (theMainShape.IsNull()) return NULL;
1086 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
1087 anArray->SetValue(1, theID);
1088 Handle(GEOM_Object) anObj = GetEngine()->AddSubShape(theMainShape, anArray,true);
1089 if (anObj.IsNull()) {
1090 SetErrorCode("Can not get a sub-shape with the given ID");
1094 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1096 //Make a Python command
1097 GEOM::TPythonDump(aFunction) << anObj << " = geompy.GetSubShape("
1098 << theMainShape << ", [" << theID << "])";
1104 //=============================================================================
1108 //=============================================================================
1109 Standard_Integer GEOMImpl_IShapesOperations::GetSubShapeIndex (Handle(GEOM_Object) theMainShape,
1110 Handle(GEOM_Object) theSubShape)
1114 TopoDS_Shape aMainShape = theMainShape->GetValue();
1115 TopoDS_Shape aSubShape = theSubShape->GetValue();
1117 if (aMainShape.IsNull() || aSubShape.IsNull()) return -1;
1119 TopTools_IndexedMapOfShape anIndices;
1120 TopExp::MapShapes(aMainShape, anIndices);
1121 if (anIndices.Contains(aSubShape)) {
1123 return anIndices.FindIndex(aSubShape);
1129 //=============================================================================
1133 //=============================================================================
1134 Standard_Integer GEOMImpl_IShapesOperations::GetTopologyIndex (Handle(GEOM_Object) theMainShape,
1135 Handle(GEOM_Object) theSubShape)
1139 TopoDS_Shape aMainShape = theMainShape->GetValue();
1140 TopoDS_Shape aSubShape = theSubShape->GetValue();
1142 if (aMainShape.IsNull() || aSubShape.IsNull()) {
1143 SetErrorCode("Null argument shape given");
1148 if (aSubShape.ShapeType() == TopAbs_COMPOUND) {
1150 TopTools_ListOfShape CL;
1151 CL.Append(aMainShape);
1152 TopTools_ListIteratorOfListOfShape itC;
1153 for (itC.Initialize(CL); itC.More(); itC.Next()) {
1154 for (it.Initialize(itC.Value()); it.More(); it.Next()) {
1155 if (it.Value().ShapeType() == TopAbs_COMPOUND) {
1156 if (it.Value().IsSame(aSubShape))
1160 CL.Append(it.Value());
1165 TopExp_Explorer anExp (aMainShape, aSubShape.ShapeType());
1166 TopTools_MapOfShape M;
1167 for (; anExp.More(); anExp.Next()) {
1168 if (M.Add(anExp.Current())) {
1169 if (anExp.Current().IsSame(aSubShape))
1176 SetErrorCode("The sub-shape does not belong to the main shape");
1180 //=============================================================================
1182 * GetShapeTypeString
1184 //=============================================================================
1185 TCollection_AsciiString GEOMImpl_IShapesOperations::GetShapeTypeString (Handle(GEOM_Object) theShape)
1189 TCollection_AsciiString aTypeName ("Null Shape");
1191 TopoDS_Shape aShape = theShape->GetValue();
1192 if (aShape.IsNull())
1195 switch (aShape.ShapeType() )
1197 case TopAbs_COMPOUND:
1198 aTypeName = "Compound";
1200 case TopAbs_COMPSOLID:
1201 aTypeName = "Compound Solid";
1204 aTypeName = "Solid";
1207 aTypeName = "Shell";
1211 BRepAdaptor_Surface surf (TopoDS::Face(aShape));
1212 if (surf.GetType() == GeomAbs_Plane)
1213 aTypeName = "Plane";
1214 else if (surf.GetType() == GeomAbs_Cylinder)
1215 aTypeName = "Cylindrical Face";
1216 else if (surf.GetType() == GeomAbs_Sphere)
1217 aTypeName = "Spherical Face";
1218 else if (surf.GetType() == GeomAbs_Torus)
1219 aTypeName = "Toroidal Face";
1220 else if (surf.GetType() == GeomAbs_Cone)
1221 aTypeName = "Conical Face";
1223 aTypeName = "GEOM::FACE";
1231 BRepAdaptor_Curve curv (TopoDS::Edge(aShape));
1232 if (curv.GetType() == GeomAbs_Line) {
1233 if ((Abs(curv.FirstParameter()) >= 1E6) ||
1234 (Abs(curv.LastParameter()) >= 1E6))
1238 } else if (curv.GetType() == GeomAbs_Circle) {
1239 if (curv.IsClosed())
1240 aTypeName = "Circle";
1249 aTypeName = "Vertex";
1252 aTypeName = "Shape";
1255 aTypeName = "Shape of unknown type";
1261 //=============================================================================
1265 //=============================================================================
1266 Standard_Integer GEOMImpl_IShapesOperations::NumberOfSubShapes
1267 (Handle(GEOM_Object) theShape,
1268 const Standard_Integer theShapeType)
1271 Standard_Integer nbShapes = 0;
1273 if (theShape.IsNull()) return -1;
1274 TopoDS_Shape aShape = theShape->GetValue();
1275 if (aShape.IsNull()) return -1;
1278 TopTools_MapOfShape mapShape;
1280 if (aShape.ShapeType() == TopAbs_COMPOUND &&
1281 (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
1282 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPSOLID ||
1283 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPOUND)) {
1284 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
1285 for (; It.More(); It.Next()) {
1286 if (mapShape.Add(It.Value())) {
1287 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
1288 TopAbs_ShapeEnum(theShapeType) == It.Value().ShapeType()) {
1294 TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
1295 for (; exp.More(); exp.Next())
1296 if (mapShape.Add(exp.Current()))
1302 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
1305 int iType, nbTypes [TopAbs_SHAPE];
1306 for (iType = 0; iType < TopAbs_SHAPE; ++iType)
1308 nbTypes[aShape.ShapeType()]++;
1310 TopTools_MapOfShape aMapOfShape;
1311 aMapOfShape.Add(aShape);
1312 TopTools_ListOfShape aListOfShape;
1313 aListOfShape.Append(aShape);
1315 TopTools_ListIteratorOfListOfShape itL (aListOfShape);
1316 for (; itL.More(); itL.Next()) {
1317 TopoDS_Iterator it (itL.Value());
1318 for (; it.More(); it.Next()) {
1319 TopoDS_Shape s = it.Value();
1320 if (aMapOfShape.Add(s)) {
1321 aListOfShape.Append(s);
1322 nbTypes[s.ShapeType()]++;
1327 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE)
1328 nbShapes = aMapOfShape.Extent();
1330 nbShapes = nbTypes[theShapeType];
1332 catch (Standard_Failure) {
1333 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1334 SetErrorCode(aFail->GetMessageString());
1342 //=============================================================================
1346 //=============================================================================
1347 Handle(GEOM_Object) GEOMImpl_IShapesOperations::ReverseShape(Handle(GEOM_Object) theShape)
1351 if (theShape.IsNull()) return NULL;
1353 //Add a new reversed object
1354 Handle(GEOM_Object) aReversed = GetEngine()->AddObject(GetDocID(), theShape->GetType());
1356 //Add a new Revese function
1357 Handle(GEOM_Function) aFunction;
1358 aFunction = aReversed->AddFunction(GEOMImpl_ShapeDriver::GetID(), REVERSE_ORIENTATION);
1359 if (aFunction.IsNull()) return NULL;
1361 //Check if the function is set correctly
1362 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
1364 GEOMImpl_IShapes aSI (aFunction);
1366 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
1367 if (aRefShape.IsNull()) return NULL;
1369 aSI.SetBase(aRefShape);
1371 //Compute the sub-shape value
1373 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
1376 if (!GetSolver()->ComputeFunction(aFunction)) {
1377 SetErrorCode("Shape driver failed to reverse shape");
1381 catch (Standard_Failure) {
1382 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1383 SetErrorCode(aFail->GetMessageString());
1387 //Make a Python command
1388 GEOM::TPythonDump(aFunction) << aReversed
1389 << " = geompy.ChangeOrientation(" << theShape << ")";
1395 //=============================================================================
1399 //=============================================================================
1400 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetFreeFacesIDs
1401 (Handle(GEOM_Object) theShape)
1405 if (theShape.IsNull()) return NULL;
1406 TopoDS_Shape aShape = theShape->GetValue();
1407 if (aShape.IsNull()) return NULL;
1409 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
1411 TopTools_IndexedDataMapOfShapeListOfShape mapFaceBlocks;
1412 GEOMImpl_Block6Explorer::MapShapesAndAncestors
1413 (aShape, TopAbs_FACE, TopAbs_SOLID, mapFaceBlocks);
1415 Standard_Integer ind = 1, nbFaces = mapFaceBlocks.Extent();
1418 SetErrorCode("The given shape has no faces");
1422 TopTools_IndexedMapOfShape anIndices;
1423 TopExp::MapShapes(aShape, anIndices);
1425 Standard_Integer id;
1426 for (; ind <= nbFaces; ind++) {
1427 if (mapFaceBlocks.FindFromIndex(ind).Extent() != 2) {
1428 id = anIndices.FindIndex(mapFaceBlocks.FindKey(ind));
1433 //The explode doesn't change object so no new function is required.
1434 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
1436 //Make a Python command
1437 GEOM::TPythonDump(aFunction, /*append=*/true)
1438 << "listFreeFacesIDs = geompy.GetFreeFacesIDs(" << theShape << ")";
1444 //=======================================================================
1445 //function : GetSharedShapes
1447 //=======================================================================
1448 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetSharedShapes
1449 (Handle(GEOM_Object) theShape1,
1450 Handle(GEOM_Object) theShape2,
1451 const Standard_Integer theShapeType)
1455 if (theShape1.IsNull() || theShape2.IsNull()) return NULL;
1457 TopoDS_Shape aShape1 = theShape1->GetValue();
1458 TopoDS_Shape aShape2 = theShape2->GetValue();
1460 if (aShape1.IsNull() || aShape2.IsNull()) return NULL;
1462 TopTools_IndexedMapOfShape anIndices;
1463 TopExp::MapShapes(aShape1, anIndices);
1464 Handle(TColStd_HArray1OfInteger) anArray;
1466 TopTools_IndexedMapOfShape mapShape1;
1467 TopExp::MapShapes(aShape1, TopAbs_ShapeEnum(theShapeType), mapShape1);
1469 Handle(GEOM_Object) anObj;
1470 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1471 TCollection_AsciiString anAsciiList, anEntry;
1473 TopTools_MapOfShape mapShape2;
1474 TopExp_Explorer exp (aShape2, TopAbs_ShapeEnum(theShapeType));
1475 for (; exp.More(); exp.Next()) {
1476 TopoDS_Shape aSS = exp.Current();
1477 if (mapShape2.Add(aSS) && mapShape1.Contains(aSS)) {
1478 anArray = new TColStd_HArray1OfInteger(1,1);
1479 anArray->SetValue(1, anIndices.FindIndex(aSS));
1480 anObj = GetEngine()->AddSubShape(theShape1, anArray);
1481 aSeq->Append(anObj);
1483 // for python command
1484 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
1485 anAsciiList += anEntry;
1490 if (aSeq->IsEmpty()) {
1491 SetErrorCode("The given shapes have no shared sub-shapes of the requested type");
1495 //Make a Python command
1496 anAsciiList.Trunc(anAsciiList.Length() - 1);
1498 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1500 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
1501 << "] = geompy.GetSharedShapes(" << theShape1 << ", "
1502 << theShape2 << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
1508 //=======================================================================
1509 //function : GetSharedShapes
1511 //=======================================================================
1512 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetSharedShapes
1513 (std::list<Handle(GEOM_Object)> theShapes,
1514 const Standard_Integer theShapeType)
1518 int aLen = theShapes.size();
1519 if (aLen < 1) return NULL;
1522 std::list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
1524 Handle(GEOM_Object) aMainObj = (*it++);
1525 Handle(GEOM_Function) aMainShape = aMainObj->GetLastFunction();
1526 if (aMainShape.IsNull()) {
1527 SetErrorCode("NULL shape for GetSharedShapes");
1531 TopoDS_Shape aShape1 = aMainShape->GetValue();
1532 if (aShape1.IsNull()) return NULL;
1534 TopTools_IndexedMapOfShape anIndices;
1535 TopExp::MapShapes(aShape1, anIndices);
1537 TopTools_IndexedMapOfShape mapSelected;
1538 TopExp::MapShapes(aShape1, TopAbs_ShapeEnum(theShapeType), mapSelected);
1540 // Find shared shapes
1542 TopoDS_Compound aCurrSelection;
1544 for (; it != theShapes.end(); it++, ind++) {
1545 Handle(GEOM_Function) aRefShape = (*it)->GetLastFunction();
1546 if (aRefShape.IsNull()) {
1547 SetErrorCode("NULL shape for GetSharedShapes");
1551 TopoDS_Compound aCompound;
1552 B.MakeCompound(aCompound);
1554 TopoDS_Shape aShape2 = aRefShape->GetValue();
1555 if (aShape2.IsNull()) return NULL;
1557 TopTools_MapOfShape mapShape2;
1558 TopExp_Explorer exp (aShape2, TopAbs_ShapeEnum(theShapeType));
1559 for (; exp.More(); exp.Next()) {
1560 TopoDS_Shape aSS = exp.Current();
1561 if (mapShape2.Add(aSS) && mapSelected.Contains(aSS)) {
1562 B.Add(aCompound, aSS);
1566 mapSelected.Clear();
1567 TopExp::MapShapes(aCompound, TopAbs_ShapeEnum(theShapeType), mapSelected);
1568 aCurrSelection = aCompound;
1571 // Create GEOM_Object for each found shared shape (collected in aCurrSelection)
1572 Handle(GEOM_Object) anObj;
1573 Handle(TColStd_HArray1OfInteger) anArray;
1574 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1575 TCollection_AsciiString anAsciiList, anEntry;
1577 TopoDS_Iterator itSel (aCurrSelection, Standard_True, Standard_True);
1578 for (; itSel.More(); itSel.Next()) {
1579 anArray = new TColStd_HArray1OfInteger(1,1);
1580 anArray->SetValue(1, anIndices.FindIndex(itSel.Value()));
1581 anObj = GetEngine()->AddSubShape(aMainObj, anArray);
1582 aSeq->Append(anObj);
1584 // for python command
1585 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
1586 anAsciiList += anEntry;
1590 if (aSeq->IsEmpty()) {
1591 SetErrorCode("The given shapes have no shared sub-shapes of the requested type");
1595 // Make a Python command
1596 anAsciiList.Trunc(anAsciiList.Length() - 1);
1598 GEOM::TPythonDump pd (aMainShape, /*append=*/true);
1599 pd << "[" << anAsciiList.ToCString()
1600 << "] = geompy.GetSharedShapesMulti([";
1602 it = theShapes.begin();
1604 while (it != theShapes.end()) {
1605 pd << ", " << (*it++);
1608 pd << "], " << TopAbs_ShapeEnum(theShapeType) << ")";
1614 //=============================================================================
1618 //=============================================================================
1619 static GEOM::TPythonDump& operator<< (GEOM::TPythonDump& theDump,
1620 const GEOMAlgo_State theState)
1623 case GEOMAlgo_ST_IN:
1624 theDump << "geompy.GEOM.ST_IN";
1626 case GEOMAlgo_ST_OUT:
1627 theDump << "geompy.GEOM.ST_OUT";
1629 case GEOMAlgo_ST_ON:
1630 theDump << "geompy.GEOM.ST_ON";
1632 case GEOMAlgo_ST_ONIN:
1633 theDump << "geompy.GEOM.ST_ONIN";
1635 case GEOMAlgo_ST_ONOUT:
1636 theDump << "geompy.GEOM.ST_ONOUT";
1639 theDump << "geompy.GEOM.ST_UNKNOWN";
1645 //=======================================================================
1646 //function : checkTypeShapesOn
1648 * \brief Checks if theShapeType parameter of GetShapesOnXXX() is OK
1649 * \param theShapeType - the shape type to check
1650 * \retval bool - result of the check
1652 //=======================================================================
1653 bool GEOMImpl_IShapesOperations::checkTypeShapesOn(const Standard_Integer theShapeType)
1655 if (theShapeType != TopAbs_VERTEX &&
1656 theShapeType != TopAbs_EDGE &&
1657 theShapeType != TopAbs_FACE &&
1658 theShapeType != TopAbs_SOLID) {
1659 SetErrorCode("Only solids, vertices, edges or faces can be found by this method");
1665 //=======================================================================
1666 //function : makePlane
1668 * \brief Creates Geom_Plane
1669 * \param theAx1 - shape object defining plane parameters
1670 * \retval Handle(Geom_Surface) - resulting surface
1672 //=======================================================================
1673 Handle(Geom_Surface) GEOMImpl_IShapesOperations::makePlane(const TopoDS_Shape& anAx1)
1675 if (anAx1.ShapeType() != TopAbs_EDGE) return NULL;
1676 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
1677 TopoDS_Vertex V1, V2;
1678 TopExp::Vertices(anEdge, V1, V2, Standard_True);
1679 if (V1.IsNull() || V2.IsNull()) {
1680 SetErrorCode("Bad edge given for the plane normal vector");
1683 gp_Pnt aLoc = BRep_Tool::Pnt(V1);
1684 gp_Vec aVec (aLoc, BRep_Tool::Pnt(V2));
1685 if (aVec.Magnitude() < Precision::Confusion()) {
1686 SetErrorCode("Vector with null magnitude given");
1689 return new Geom_Plane(aLoc, aVec);
1692 //=======================================================================
1693 //function : makeCylinder
1695 * \brief Creates Geom_CylindricalSurface
1696 * \param theAx1 - edge defining cylinder axis
1697 * \param theRadius - cylinder radius
1698 * \retval Handle(Geom_Surface) - resulting surface
1700 //=======================================================================
1701 Handle(Geom_Surface) GEOMImpl_IShapesOperations::makeCylinder(const TopoDS_Shape& anAxis,
1702 const Standard_Real theRadius)
1704 //Axis of the cylinder
1705 if (anAxis.ShapeType() != TopAbs_EDGE) {
1706 SetErrorCode("Not an edge given for the axis");
1709 TopoDS_Edge anEdge = TopoDS::Edge(anAxis);
1710 TopoDS_Vertex V1, V2;
1711 TopExp::Vertices(anEdge, V1, V2, Standard_True);
1712 if (V1.IsNull() || V2.IsNull()) {
1713 SetErrorCode("Bad edge given for the axis");
1716 gp_Pnt aLoc = BRep_Tool::Pnt(V1);
1717 gp_Vec aVec (aLoc, BRep_Tool::Pnt(V2));
1718 if (aVec.Magnitude() < Precision::Confusion()) {
1719 SetErrorCode("Vector with null magnitude given");
1723 gp_Ax3 anAx3 (aLoc, aVec);
1724 return new Geom_CylindricalSurface(anAx3, theRadius);
1727 //=======================================================================
1728 //function : getShapesOnBoxIDs
1730 * \brief Find IDs of subshapes complying with given status about surface
1731 * \param theBox - the box to check state of subshapes against
1732 * \param theShape - the shape to explore
1733 * \param theShapeType - type of subshape of theShape
1734 * \param theState - required state
1735 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1737 //=======================================================================
1738 Handle(TColStd_HSequenceOfInteger)
1739 GEOMImpl_IShapesOperations::getShapesOnBoxIDs(const Handle(GEOM_Object)& theBox,
1740 const Handle(GEOM_Object)& theShape,
1741 const Standard_Integer theShapeType,
1742 GEOMAlgo_State theState)
1744 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
1746 TopoDS_Shape aBox = theBox->GetValue();
1747 TopoDS_Shape aShape = theShape->GetValue();
1749 // Check presence of triangulation, build if need
1750 if (!CheckTriangulation(aShape)) {
1751 SetErrorCode("Cannot build triangulation on the shape");
1756 GEOMAlgo_FinderShapeOn2 aFinder;
1757 Standard_Real aTol = 0.0001; // default value
1759 Handle(GEOMAlgo_ClsfBox) aClsfBox = new GEOMAlgo_ClsfBox;
1760 aClsfBox->SetBox(aBox);
1762 aFinder.SetShape(aShape);
1763 aFinder.SetTolerance(aTol);
1764 aFinder.SetClsf(aClsfBox);
1765 aFinder.SetShapeType( (TopAbs_ShapeEnum)theShapeType );
1766 aFinder.SetState(theState);
1769 // Interprete results
1770 Standard_Integer iErr = aFinder.ErrorStatus();
1771 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
1773 MESSAGE(" iErr : " << iErr);
1774 TCollection_AsciiString aMsg (" iErr : ");
1775 aMsg += TCollection_AsciiString(iErr);
1779 Standard_Integer iWrn = aFinder.WarningStatus();
1780 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
1782 MESSAGE(" *** iWrn : " << iWrn);
1785 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
1787 if (listSS.Extent() < 1) {
1788 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
1789 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
1793 // Fill sequence of object IDs
1794 aSeqOfIDs = new TColStd_HSequenceOfInteger;
1796 TopTools_IndexedMapOfShape anIndices;
1797 TopExp::MapShapes(aShape, anIndices);
1799 TopTools_ListIteratorOfListOfShape itSub (listSS);
1800 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
1801 int id = anIndices.FindIndex(itSub.Value());
1802 aSeqOfIDs->Append(id);
1808 //=======================================================================
1809 //function : GetShapesOnBoxIDs
1811 * \brief Find subshapes complying with given status about surface
1812 * \param theBox - the box to check state of subshapes against
1813 * \param theShape - the shape to explore
1814 * \param theShapeType - type of subshape of theShape
1815 * \param theState - required state
1816 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1818 //=======================================================================
1819 Handle(TColStd_HSequenceOfInteger)
1820 GEOMImpl_IShapesOperations::GetShapesOnBoxIDs(const Handle(GEOM_Object)& theBox,
1821 const Handle(GEOM_Object)& theShape,
1822 const Standard_Integer theShapeType,
1823 GEOMAlgo_State theState)
1825 // Find subshapes ids
1826 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
1827 getShapesOnBoxIDs (theBox, theShape, theShapeType, theState);
1828 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
1831 // The GetShapesOnBox() doesn't change object so no new function is required.
1832 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theBox)->GetLastFunction();
1834 // Make a Python command
1835 GEOM::TPythonDump(aFunction)
1836 << "listShapesOnBoxIDs = geompy.GetShapesOnBoxIDs("
1839 << TopAbs_ShapeEnum(theShapeType) << ", "
1846 //=======================================================================
1847 //function : GetShapesOnBox
1849 * \brief Find subshapes complying with given status about surface
1850 * \param theBox - the box to check state of subshapes against
1851 * \param theShape - the shape to explore
1852 * \param theShapeType - type of subshape of theShape
1853 * \param theState - required state
1854 * \retval Handle(TColStd_HSequenceOfTransient) - found subshapes
1856 //=======================================================================
1857 Handle(TColStd_HSequenceOfTransient)
1858 GEOMImpl_IShapesOperations::GetShapesOnBox(const Handle(GEOM_Object)& theBox,
1859 const Handle(GEOM_Object)& theShape,
1860 const Standard_Integer theShapeType,
1861 GEOMAlgo_State theState)
1863 // Find subshapes ids
1864 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
1865 getShapesOnBoxIDs (theBox, theShape, theShapeType, theState);
1866 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
1869 // Find objects by indices
1870 TCollection_AsciiString anAsciiList;
1871 Handle(TColStd_HSequenceOfTransient) aSeq;
1872 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
1873 if ( aSeq.IsNull() || aSeq->IsEmpty() )
1876 // Make a Python command
1878 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
1879 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1881 GEOM::TPythonDump(aFunction)
1882 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnBox("
1885 << TopAbs_ShapeEnum(theShapeType) << ", "
1892 //=======================================================================
1893 //function : getShapesOnShapeIDs
1895 * \brief Find IDs of subshapes complying with given status about surface
1896 * \param theCheckShape - the shape to check state of subshapes against
1897 * \param theShape - the shape to explore
1898 * \param theShapeType - type of subshape of theShape
1899 * \param theState - required state
1900 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1902 //=======================================================================
1903 Handle(TColStd_HSequenceOfInteger)
1904 GEOMImpl_IShapesOperations::getShapesOnShapeIDs
1905 (const Handle(GEOM_Object)& theCheckShape,
1906 const Handle(GEOM_Object)& theShape,
1907 const Standard_Integer theShapeType,
1908 GEOMAlgo_State theState)
1910 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
1912 TopoDS_Shape aCheckShape = theCheckShape->GetValue();
1913 TopoDS_Shape aShape = theShape->GetValue();
1914 TopTools_ListOfShape res;
1916 // Check presence of triangulation, build if need
1917 if (!CheckTriangulation(aShape)) {
1918 SetErrorCode("Cannot build triangulation on the shape");
1923 GEOMAlgo_FinderShapeOn2 aFinder;
1924 Standard_Real aTol = 0.0001; // default value
1926 Handle(GEOMAlgo_ClsfSolid) aClsfSolid = new GEOMAlgo_ClsfSolid;
1927 aClsfSolid->SetShape(aCheckShape);
1929 aFinder.SetShape(aShape);
1930 aFinder.SetTolerance(aTol);
1931 aFinder.SetClsf(aClsfSolid);
1932 aFinder.SetShapeType( (TopAbs_ShapeEnum)theShapeType );
1933 aFinder.SetState(theState);
1936 // Interprete results
1937 Standard_Integer iErr = aFinder.ErrorStatus();
1938 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
1941 SetErrorCode("theCheckShape must be a solid");
1944 MESSAGE(" iErr : " << iErr);
1945 TCollection_AsciiString aMsg (" iErr : ");
1946 aMsg += TCollection_AsciiString(iErr);
1951 Standard_Integer iWrn = aFinder.WarningStatus();
1952 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
1954 MESSAGE(" *** iWrn : " << iWrn);
1957 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
1959 if (listSS.Extent() < 1) {
1960 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
1961 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
1964 // Fill sequence of object IDs
1965 aSeqOfIDs = new TColStd_HSequenceOfInteger;
1967 TopTools_IndexedMapOfShape anIndices;
1968 TopExp::MapShapes(aShape, anIndices);
1970 TopTools_ListIteratorOfListOfShape itSub (listSS);
1971 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
1972 int id = anIndices.FindIndex(itSub.Value());
1973 aSeqOfIDs->Append(id);
1979 //=======================================================================
1980 //function : GetShapesOnShapeIDs
1982 * \brief Find subshapes complying with given status about surface
1983 * \param theCheckShape - the shape to check state of subshapes against
1984 * \param theShape - the shape to explore
1985 * \param theShapeType - type of subshape of theShape
1986 * \param theState - required state
1987 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1989 //=======================================================================
1990 Handle(TColStd_HSequenceOfInteger)
1991 GEOMImpl_IShapesOperations::GetShapesOnShapeIDs
1992 (const Handle(GEOM_Object)& theCheckShape,
1993 const Handle(GEOM_Object)& theShape,
1994 const Standard_Integer theShapeType,
1995 GEOMAlgo_State theState)
1997 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
1998 getShapesOnShapeIDs (theCheckShape, theShape, theShapeType, theState);
2000 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2003 // The GetShapesOnShape() doesn't change object so no new function is required.
2004 Handle(GEOM_Function) aFunction =
2005 GEOM::GetCreatedLast(theShape,theCheckShape)->GetLastFunction();
2007 // Make a Python command
2008 GEOM::TPythonDump(aFunction)
2009 << "listShapesOnBoxIDs = geompy.GetShapesOnShapeIDs("
2010 << theCheckShape << ", "
2012 << TopAbs_ShapeEnum(theShapeType) << ", "
2019 //=======================================================================
2020 //function : GetShapesOnShape
2022 * \brief Find subshapes complying with given status about surface
2023 * \param theCheckShape - the shape to check state of subshapes against
2024 * \param theShape - the shape to explore
2025 * \param theShapeType - type of subshape of theShape
2026 * \param theState - required state
2027 * \retval Handle(TColStd_HSequenceOfTransient) - found subshapes
2029 //=======================================================================
2030 Handle(TColStd_HSequenceOfTransient)
2031 GEOMImpl_IShapesOperations::GetShapesOnShape
2032 (const Handle(GEOM_Object)& theCheckShape,
2033 const Handle(GEOM_Object)& theShape,
2034 const Standard_Integer theShapeType,
2035 GEOMAlgo_State theState)
2037 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2038 getShapesOnShapeIDs (theCheckShape, theShape, theShapeType, theState);
2039 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2042 // Find objects by indices
2043 TCollection_AsciiString anAsciiList;
2044 Handle(TColStd_HSequenceOfTransient) aSeq;
2045 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
2047 if ( aSeq.IsNull() || aSeq->IsEmpty() )
2050 // Make a Python command
2052 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2053 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2055 GEOM::TPythonDump(aFunction)
2056 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnShape("
2057 << theCheckShape << ", "
2059 << TopAbs_ShapeEnum(theShapeType) << ", "
2066 //=======================================================================
2067 //function : GetShapesOnShapeAsCompound
2068 //=======================================================================
2069 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetShapesOnShapeAsCompound
2070 (const Handle(GEOM_Object)& theCheckShape,
2071 const Handle(GEOM_Object)& theShape,
2072 const Standard_Integer theShapeType,
2073 GEOMAlgo_State theState)
2075 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2076 getShapesOnShapeIDs (theCheckShape, theShape, theShapeType, theState);
2078 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2081 // Find objects by indices
2082 TCollection_AsciiString anAsciiList;
2083 Handle(TColStd_HSequenceOfTransient) aSeq;
2084 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
2086 if ( aSeq.IsNull() || aSeq->IsEmpty() )
2089 TopoDS_Compound aCompound;
2091 B.MakeCompound(aCompound);
2093 for(; i<=aSeq->Length(); i++) {
2094 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(aSeq->Value(i));
2095 TopoDS_Shape aShape_i = anObj->GetValue();
2096 B.Add(aCompound,aShape_i);
2099 //Add a new result object
2100 Handle(GEOM_Object) aRes = GetEngine()->AddObject(GetDocID(), GEOM_SHAPES_ON_SHAPE);
2101 Handle(GEOM_Function) aFunction =
2102 aRes->AddFunction(GEOMImpl_ShapeDriver::GetID(), SHAPES_ON_SHAPE);
2103 aFunction->SetValue(aCompound);
2105 GEOM::TPythonDump(aFunction)
2106 << aRes << " = geompy.GetShapesOnShapeAsCompound("
2107 << theCheckShape << ", "
2109 << TopAbs_ShapeEnum(theShapeType) << ", "
2117 //=======================================================================
2118 //function : getShapesOnSurfaceIDs
2120 * \brief Find IDs of subshapes complying with given status about surface
2121 * \param theSurface - the surface to check state of subshapes against
2122 * \param theShape - the shape to explore
2123 * \param theShapeType - type of subshape of theShape
2124 * \param theState - required state
2125 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
2127 //=======================================================================
2128 Handle(TColStd_HSequenceOfInteger)
2129 GEOMImpl_IShapesOperations::getShapesOnSurfaceIDs(const Handle(Geom_Surface)& theSurface,
2130 const TopoDS_Shape& theShape,
2131 TopAbs_ShapeEnum theShapeType,
2132 GEOMAlgo_State theState)
2134 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
2136 // Check presence of triangulation, build if need
2137 if (!CheckTriangulation(theShape)) {
2138 SetErrorCode("Cannot build triangulation on the shape");
2142 // BEGIN: Mantis issue 0020961: Error on a pipe T-Shape
2143 // Compute tolerance
2144 Standard_Real T, VertMax = -RealLast();
2146 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
2149 for (TopExp_Explorer ExV (theShape, TopAbs_VERTEX); ExV.More(); ExV.Next()) {
2150 TopoDS_Vertex Vertex = TopoDS::Vertex(ExV.Current());
2151 T = BRep_Tool::Tolerance(Vertex);
2156 catch (Standard_Failure) {
2157 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2158 SetErrorCode(aFail->GetMessageString());
2161 // END: Mantis issue 0020961
2164 GEOMAlgo_FinderShapeOn1 aFinder;
2165 //Standard_Real aTol = 0.0001; // default value
2166 Standard_Real aTol = VertMax; // Mantis issue 0020961
2168 aFinder.SetShape(theShape);
2169 aFinder.SetTolerance(aTol);
2170 aFinder.SetSurface(theSurface);
2171 aFinder.SetShapeType(theShapeType);
2172 aFinder.SetState(theState);
2174 // Sets the minimal number of inner points for the faces that do not have own
2175 // inner points at all (for e.g. rectangular planar faces have just 2 triangles).
2177 aFinder.SetNbPntsMin(3);
2178 // Sets the maximal number of inner points for edges or faces.
2179 // It is usefull for the cases when this number is very big (e.g =2000) to improve
2180 // the performance. If this value =0, all inner points will be taken into account.
2182 aFinder.SetNbPntsMax(100);
2186 // Interprete results
2187 Standard_Integer iErr = aFinder.ErrorStatus();
2188 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
2190 MESSAGE(" iErr : " << iErr);
2191 TCollection_AsciiString aMsg (" iErr : ");
2192 aMsg += TCollection_AsciiString(iErr);
2196 Standard_Integer iWrn = aFinder.WarningStatus();
2197 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
2199 MESSAGE(" *** iWrn : " << iWrn);
2202 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
2204 if (listSS.Extent() < 1) {
2205 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
2206 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
2210 // Fill sequence of object IDs
2211 aSeqOfIDs = new TColStd_HSequenceOfInteger;
2213 TopTools_IndexedMapOfShape anIndices;
2214 TopExp::MapShapes(theShape, anIndices);
2216 TopTools_ListIteratorOfListOfShape itSub (listSS);
2217 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
2218 int id = anIndices.FindIndex(itSub.Value());
2219 aSeqOfIDs->Append(id);
2225 //=======================================================================
2226 //function : getObjectsShapesOn
2228 * \brief Find shape objects and their entries by their ids
2229 * \param theShapeIDs - incoming shape ids
2230 * \param theShapeEntries - outgoing entries like "entry1, entry2, ..."
2231 * \retval Handle(TColStd_HSequenceOfTransient) - found shape objects
2233 //=======================================================================
2234 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::
2235 getObjectsShapesOn(const Handle(GEOM_Object)& theShape,
2236 const Handle(TColStd_HSequenceOfInteger)& theShapeIDs,
2237 TCollection_AsciiString & theShapeEntries)
2239 Handle(TColStd_HSequenceOfTransient) aSeq;
2241 if ( !theShapeIDs.IsNull() && theShapeIDs->Length() > 0 )
2243 aSeq = new TColStd_HSequenceOfTransient;
2244 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
2245 TCollection_AsciiString anEntry;
2246 for ( int i = 1; i <= theShapeIDs->Length(); ++i )
2248 anArray->SetValue(1, theShapeIDs->Value( i ));
2249 Handle(GEOM_Object) anObj = GetEngine()->AddSubShape(theShape, anArray);
2250 aSeq->Append( anObj );
2252 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
2253 if ( i != 1 ) theShapeEntries += ",";
2254 theShapeEntries += anEntry;
2260 //=======================================================================
2261 //function : getShapesOnSurface
2263 * \brief Find subshapes complying with given status about surface
2264 * \param theSurface - the surface to check state of subshapes against
2265 * \param theShape - the shape to explore
2266 * \param theShapeType - type of subshape of theShape
2267 * \param theState - required state
2268 * \param theShapeEntries - outgoing entries like "entry1, entry2, ..."
2269 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
2271 //=======================================================================
2272 Handle(TColStd_HSequenceOfTransient)
2273 GEOMImpl_IShapesOperations::getShapesOnSurface(const Handle(Geom_Surface)& theSurface,
2274 const Handle(GEOM_Object)& theShape,
2275 TopAbs_ShapeEnum theShapeType,
2276 GEOMAlgo_State theState,
2277 TCollection_AsciiString & theShapeEntries)
2279 // Find subshapes ids
2280 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2281 getShapesOnSurfaceIDs (theSurface, theShape->GetValue(), theShapeType, theState);
2282 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2285 return getObjectsShapesOn( theShape, aSeqOfIDs, theShapeEntries );
2288 //=============================================================================
2292 //=============================================================================
2293 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnPlane
2294 (const Handle(GEOM_Object)& theShape,
2295 const Standard_Integer theShapeType,
2296 const Handle(GEOM_Object)& theAx1,
2297 const GEOMAlgo_State theState)
2301 if (theShape.IsNull() || theAx1.IsNull()) return NULL;
2303 TopoDS_Shape aShape = theShape->GetValue();
2304 TopoDS_Shape anAx1 = theAx1->GetValue();
2306 if (aShape.IsNull() || anAx1.IsNull()) return NULL;
2308 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2309 if ( !checkTypeShapesOn( theShapeType ))
2313 Handle(Geom_Surface) aPlane = makePlane( anAx1 );
2314 if ( aPlane.IsNull() )
2318 TCollection_AsciiString anAsciiList;
2319 Handle(TColStd_HSequenceOfTransient) aSeq;
2320 aSeq = getShapesOnSurface( aPlane, theShape, aShapeType, theState, anAsciiList );
2321 if ( aSeq.IsNull() || aSeq->Length() == 0 )
2324 // Make a Python command
2326 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2327 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2329 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
2330 << "] = geompy.GetShapesOnPlane(" << theShape << ", "
2331 << aShapeType << ", " << theAx1 << ", " << theState << ")";
2337 //=============================================================================
2339 * GetShapesOnPlaneWithLocation
2341 //=============================================================================
2342 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnPlaneWithLocation
2343 (const Handle(GEOM_Object)& theShape,
2344 const Standard_Integer theShapeType,
2345 const Handle(GEOM_Object)& theAx1,
2346 const Handle(GEOM_Object)& thePnt,
2347 const GEOMAlgo_State theState)
2351 if (theShape.IsNull() || theAx1.IsNull() || thePnt.IsNull()) return NULL;
2353 TopoDS_Shape aShape = theShape->GetValue();
2354 TopoDS_Shape anAx1 = theAx1->GetValue();
2355 TopoDS_Shape anPnt = thePnt->GetValue();
2357 if (aShape.IsNull() || anAx1.IsNull() || anPnt.IsNull()) return NULL;
2359 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2360 if ( !checkTypeShapesOn( theShapeType ))
2364 if ( anAx1.ShapeType() != TopAbs_EDGE || anPnt.ShapeType() != TopAbs_VERTEX ) return NULL;
2365 TopoDS_Vertex V1, V2, V3;
2366 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
2367 TopExp::Vertices(anEdge, V1, V2, Standard_True);
2369 if (V1.IsNull() || V2.IsNull()) {
2370 SetErrorCode("Bad edge given for the plane normal vector");
2373 V3 = TopoDS::Vertex(anPnt);
2376 SetErrorCode("Bad vertex given for the plane location");
2379 gp_Pnt aLoc = BRep_Tool::Pnt(V3);
2380 gp_Vec aVec(BRep_Tool::Pnt(V1),BRep_Tool::Pnt(V2));
2382 if (aVec.Magnitude() < Precision::Confusion()) {
2383 SetErrorCode("Vector with null magnitude given");
2386 Handle(Geom_Surface) aPlane = new Geom_Plane(aLoc, aVec);
2388 if ( aPlane.IsNull() )
2392 TCollection_AsciiString anAsciiList;
2393 Handle(TColStd_HSequenceOfTransient) aSeq;
2394 aSeq = getShapesOnSurface( aPlane, theShape, aShapeType, theState, anAsciiList );
2395 if ( aSeq.IsNull() || aSeq->Length() == 0 )
2398 // Make a Python command
2400 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2401 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2403 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
2404 << "] = geompy.GetShapesOnPlaneWithLocation(" << theShape << ", "
2405 << aShapeType << ", " << theAx1 << ", "<< thePnt <<", " << theState << ")";
2411 //=============================================================================
2413 * GetShapesOnCylinder
2415 //=============================================================================
2416 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnCylinder
2417 (const Handle(GEOM_Object)& theShape,
2418 const Standard_Integer theShapeType,
2419 const Handle(GEOM_Object)& theAxis,
2420 const Standard_Real theRadius,
2421 const GEOMAlgo_State theState)
2425 if (theShape.IsNull() || theAxis.IsNull()) return NULL;
2427 TopoDS_Shape aShape = theShape->GetValue();
2428 TopoDS_Shape anAxis = theAxis->GetValue();
2430 if (aShape.IsNull() || anAxis.IsNull()) return NULL;
2432 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2433 if ( !checkTypeShapesOn( aShapeType ))
2436 // Create a cylinder surface
2437 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
2438 if ( aCylinder.IsNull() )
2442 TCollection_AsciiString anAsciiList;
2443 Handle(TColStd_HSequenceOfTransient) aSeq;
2444 aSeq = getShapesOnSurface( aCylinder, theShape, aShapeType, theState, anAsciiList );
2445 if ( aSeq.IsNull() || aSeq->Length() == 0 )
2448 // Make a Python command
2450 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2451 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2453 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
2454 << "] = geompy.GetShapesOnCylinder(" << theShape << ", " << aShapeType
2455 << ", " << theAxis << ", " << theRadius << ", " << theState << ")";
2461 //=============================================================================
2463 * GetShapesOnCylinderWithLocation
2465 //=============================================================================
2466 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnCylinderWithLocation
2467 (const Handle(GEOM_Object)& theShape,
2468 const Standard_Integer theShapeType,
2469 const Handle(GEOM_Object)& theAxis,
2470 const Handle(GEOM_Object)& thePnt,
2471 const Standard_Real theRadius,
2472 const GEOMAlgo_State theState)
2476 if (theShape.IsNull() || theAxis.IsNull() || thePnt.IsNull()) return NULL;
2478 TopoDS_Shape aShape = theShape->GetValue();
2479 TopoDS_Shape anAxis = theAxis->GetValue();
2480 TopoDS_Shape aPnt = thePnt->GetValue();
2482 if (aShape.IsNull() || anAxis.IsNull() || aPnt.IsNull()) return NULL;
2484 if (aPnt.ShapeType() != TopAbs_VERTEX )
2486 SetErrorCode("Bottom location point must be vertex");
2490 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2491 if ( !checkTypeShapesOn( aShapeType ))
2494 // Create a cylinder surface
2495 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
2496 if ( aCylinder.IsNull() )
2499 // translate the surface
2500 Handle(Geom_CylindricalSurface) aCylSurface =
2501 Handle(Geom_CylindricalSurface)::DownCast( aCylinder );
2502 if ( aCylSurface.IsNull() )
2504 SetErrorCode("Unexpected surface type instead of Geom_CylindricalSurface");
2507 gp_Pnt fromLoc = aCylSurface->Cylinder().Location();
2508 gp_Pnt toLoc = BRep_Tool::Pnt( TopoDS::Vertex( aPnt ));
2509 aCylinder->Translate( fromLoc, toLoc );
2512 TCollection_AsciiString anAsciiList;
2513 Handle(TColStd_HSequenceOfTransient) aSeq;
2514 aSeq = getShapesOnSurface( aCylinder, theShape, aShapeType, theState, anAsciiList );
2515 if ( aSeq.IsNull() || aSeq->Length() == 0 )
2518 // Make a Python command
2520 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2521 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2523 GEOM::TPythonDump(aFunction)
2524 << "[" << anAsciiList.ToCString()
2525 << "] = geompy.GetShapesOnCylinderWithLocation(" << theShape << ", " << aShapeType << ", "
2526 << theAxis << ", " << thePnt << ", " << theRadius << ", " << theState << ")";
2532 //=============================================================================
2536 //=============================================================================
2537 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnSphere
2538 (const Handle(GEOM_Object)& theShape,
2539 const Standard_Integer theShapeType,
2540 const Handle(GEOM_Object)& theCenter,
2541 const Standard_Real theRadius,
2542 const GEOMAlgo_State theState)
2546 if (theShape.IsNull() || theCenter.IsNull()) return NULL;
2548 TopoDS_Shape aShape = theShape->GetValue();
2549 TopoDS_Shape aCenter = theCenter->GetValue();
2551 if (aShape.IsNull() || aCenter.IsNull()) return NULL;
2553 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2554 if ( !checkTypeShapesOn( aShapeType ))
2557 // Center of the sphere
2558 if (aCenter.ShapeType() != TopAbs_VERTEX) return NULL;
2559 gp_Pnt aLoc = BRep_Tool::Pnt(TopoDS::Vertex(aCenter));
2561 gp_Ax3 anAx3 (aLoc, gp::DZ());
2562 Handle(Geom_SphericalSurface) aSphere =
2563 new Geom_SphericalSurface(anAx3, theRadius);
2566 TCollection_AsciiString anAsciiList;
2567 Handle(TColStd_HSequenceOfTransient) aSeq;
2568 aSeq = getShapesOnSurface( aSphere, theShape, aShapeType, theState, anAsciiList );
2569 if ( aSeq.IsNull() || aSeq->Length() == 0 )
2572 // Make a Python command
2574 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2575 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2577 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
2578 << "] = geompy.GetShapesOnSphere(" << theShape << ", " << aShapeType
2579 << ", " << theCenter << ", " << theRadius << ", " << theState << ")";
2585 //=============================================================================
2587 * GetShapesOnPlaneIDs
2589 //=============================================================================
2590 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnPlaneIDs
2591 (const Handle(GEOM_Object)& theShape,
2592 const Standard_Integer theShapeType,
2593 const Handle(GEOM_Object)& theAx1,
2594 const GEOMAlgo_State theState)
2598 if (theShape.IsNull() || theAx1.IsNull()) return NULL;
2600 TopoDS_Shape aShape = theShape->GetValue();
2601 TopoDS_Shape anAx1 = theAx1->GetValue();
2603 if (aShape.IsNull() || anAx1.IsNull()) return NULL;
2605 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2606 if ( !checkTypeShapesOn( aShapeType ))
2610 Handle(Geom_Surface) aPlane = makePlane( anAx1 );
2611 if ( aPlane.IsNull() )
2615 Handle(TColStd_HSequenceOfInteger) aSeq;
2616 aSeq = getShapesOnSurfaceIDs( aPlane, aShape, aShapeType, theState );
2618 // The GetShapesOnPlaneIDs() doesn't change object so no new function is required.
2619 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAx1)->GetLastFunction();
2621 // Make a Python command
2622 GEOM::TPythonDump(aFunction, /*append=*/true)
2623 << "listShapesOnPlane = geompy.GetShapesOnPlaneIDs"
2624 << "(" << theShape << "," << aShapeType << "," << theAx1 << "," << theState << ")";
2630 //=============================================================================
2632 * GetShapesOnPlaneWithLocationIDs
2634 //=============================================================================
2635 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnPlaneWithLocationIDs
2636 (const Handle(GEOM_Object)& theShape,
2637 const Standard_Integer theShapeType,
2638 const Handle(GEOM_Object)& theAx1,
2639 const Handle(GEOM_Object)& thePnt,
2640 const GEOMAlgo_State theState)
2644 if (theShape.IsNull() || theAx1.IsNull() || thePnt.IsNull()) return NULL;
2646 TopoDS_Shape aShape = theShape->GetValue();
2647 TopoDS_Shape anAx1 = theAx1->GetValue();
2648 TopoDS_Shape anPnt = thePnt->GetValue();
2650 if (aShape.IsNull() || anAx1.IsNull() || anPnt.IsNull()) return NULL;
2652 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2653 if ( !checkTypeShapesOn( aShapeType ))
2657 if (anAx1.ShapeType() != TopAbs_EDGE || anPnt.ShapeType() != TopAbs_VERTEX) return NULL;
2658 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
2659 TopoDS_Vertex V1, V2, V3;
2660 TopExp::Vertices(anEdge, V1, V2, Standard_True);
2661 if (V1.IsNull() || V2.IsNull()) {
2662 SetErrorCode("Bad edge given for the plane normal vector");
2665 V3 = TopoDS::Vertex(anPnt);
2667 SetErrorCode("Bad vertex given for the plane location");
2670 gp_Pnt aLoc = BRep_Tool::Pnt(V3);
2671 gp_Vec aVec(BRep_Tool::Pnt(V1),BRep_Tool::Pnt(V2));
2672 if (aVec.Magnitude() < Precision::Confusion()) {
2673 SetErrorCode("Vector with null magnitude given");
2677 Handle(Geom_Surface) aPlane = new Geom_Plane(aLoc, aVec);
2678 if ( aPlane.IsNull() )
2682 Handle(TColStd_HSequenceOfInteger) aSeq;
2683 aSeq = getShapesOnSurfaceIDs( aPlane, aShape, aShapeType, theState );
2685 // The GetShapesOnPlaneIDs() doesn't change object so no new function is required.
2686 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAx1)->GetLastFunction();
2688 // Make a Python command
2689 GEOM::TPythonDump(aFunction, /*append=*/true)
2690 << "listShapesOnPlane = geompy.GetShapesOnPlaneWithLocationIDs"
2691 << "(" << theShape << ", " << aShapeType << ", " << theAx1 << ", "<< thePnt << ", " << theState << ")";
2697 //=============================================================================
2699 * GetShapesOnCylinderIDs
2701 //=============================================================================
2702 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnCylinderIDs
2703 (const Handle(GEOM_Object)& theShape,
2704 const Standard_Integer theShapeType,
2705 const Handle(GEOM_Object)& theAxis,
2706 const Standard_Real theRadius,
2707 const GEOMAlgo_State theState)
2711 if (theShape.IsNull() || theAxis.IsNull()) return NULL;
2713 TopoDS_Shape aShape = theShape->GetValue();
2714 TopoDS_Shape anAxis = theAxis->GetValue();
2716 if (aShape.IsNull() || anAxis.IsNull()) return NULL;
2718 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2719 if ( !checkTypeShapesOn( aShapeType ))
2722 // Create a cylinder surface
2723 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
2724 if ( aCylinder.IsNull() )
2728 Handle(TColStd_HSequenceOfInteger) aSeq;
2729 aSeq = getShapesOnSurfaceIDs( aCylinder, aShape, aShapeType, theState );
2731 // The GetShapesOnCylinder() doesn't change object so no new function is required.
2732 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAxis)->GetLastFunction();
2734 // Make a Python command
2735 GEOM::TPythonDump(aFunction, /*append=*/true)
2736 << "listShapesOnCylinder = geompy.GetShapesOnCylinderIDs"
2737 << "(" << theShape << ", " << aShapeType << ", " << theAxis << ", "
2738 << theRadius << ", " << theState << ")";
2744 //=============================================================================
2746 * GetShapesOnCylinderWithLocationIDs
2748 //=============================================================================
2749 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnCylinderWithLocationIDs
2750 (const Handle(GEOM_Object)& theShape,
2751 const Standard_Integer theShapeType,
2752 const Handle(GEOM_Object)& theAxis,
2753 const Handle(GEOM_Object)& thePnt,
2754 const Standard_Real theRadius,
2755 const GEOMAlgo_State theState)
2759 if (theShape.IsNull() || theAxis.IsNull() || thePnt.IsNull()) return NULL;
2761 TopoDS_Shape aShape = theShape->GetValue();
2762 TopoDS_Shape anAxis = theAxis->GetValue();
2763 TopoDS_Shape aPnt = thePnt->GetValue();
2765 if (aShape.IsNull() || anAxis.IsNull() || aPnt.IsNull()) return NULL;
2767 if (aPnt.ShapeType() != TopAbs_VERTEX )
2769 SetErrorCode("Bottom location point must be vertex");
2773 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2774 if ( !checkTypeShapesOn( aShapeType ))
2777 // Create a cylinder surface
2778 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
2779 if ( aCylinder.IsNull() )
2782 // translate the surface
2783 Handle(Geom_CylindricalSurface) aCylSurface =
2784 Handle(Geom_CylindricalSurface)::DownCast( aCylinder );
2785 if ( aCylSurface.IsNull() )
2787 SetErrorCode("Unexpected surface type instead of Geom_CylindricalSurface");
2790 gp_Pnt fromLoc = aCylSurface->Cylinder().Location();
2791 gp_Pnt toLoc = BRep_Tool::Pnt( TopoDS::Vertex( aPnt ));
2792 aCylinder->Translate( fromLoc, toLoc );
2795 Handle(TColStd_HSequenceOfInteger) aSeq;
2796 aSeq = getShapesOnSurfaceIDs( aCylinder, aShape, aShapeType, theState );
2798 // The GetShapesOnCylinder() doesn't change object so no new function is required.
2799 Handle(GEOM_Function) aFunction =
2800 GEOM::GetCreatedLast(theShape, GEOM::GetCreatedLast(thePnt,theAxis))->GetLastFunction();
2802 // Make a Python command
2803 GEOM::TPythonDump(aFunction, /*append=*/true)
2804 << "listShapesOnCylinder = geompy.GetShapesOnCylinderWithLocationIDs"
2805 << "(" << theShape << ", " << aShapeType << ", " << theAxis << ", "
2806 << thePnt << ", " << theRadius << ", " << theState << ")";
2812 //=============================================================================
2814 * GetShapesOnSphereIDs
2816 //=============================================================================
2817 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnSphereIDs
2818 (const Handle(GEOM_Object)& theShape,
2819 const Standard_Integer theShapeType,
2820 const Handle(GEOM_Object)& theCenter,
2821 const Standard_Real theRadius,
2822 const GEOMAlgo_State theState)
2826 if (theShape.IsNull() || theCenter.IsNull()) return NULL;
2828 TopoDS_Shape aShape = theShape->GetValue();
2829 TopoDS_Shape aCenter = theCenter->GetValue();
2831 if (aShape.IsNull() || aCenter.IsNull()) return NULL;
2833 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2834 if ( !checkTypeShapesOn( aShapeType ))
2837 // Center of the sphere
2838 if (aCenter.ShapeType() != TopAbs_VERTEX) return NULL;
2839 gp_Pnt aLoc = BRep_Tool::Pnt(TopoDS::Vertex(aCenter));
2841 gp_Ax3 anAx3 (aLoc, gp::DZ());
2842 Handle(Geom_SphericalSurface) aSphere =
2843 new Geom_SphericalSurface(anAx3, theRadius);
2846 Handle(TColStd_HSequenceOfInteger) aSeq;
2847 aSeq = getShapesOnSurfaceIDs( aSphere, aShape, aShapeType, theState );
2849 // The GetShapesOnSphere() doesn't change object so no new function is required.
2850 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theCenter)->GetLastFunction();
2852 // Make a Python command
2853 GEOM::TPythonDump(aFunction, /*append=*/true)
2854 << "listShapesOnCylinder = geompy.GetShapesOnCylinderIDs"
2855 << "(" << theShape << ", " << aShapeType << ", " << theCenter << ", "
2856 << theRadius << ", " << theState << ")";
2862 //=======================================================================
2863 //function : getShapesOnQuadrangleIDs
2865 * \brief Find IDs of subshapes complying with given status about quadrangle
2866 * \param theShape - the shape to explore
2867 * \param theShapeType - type of subshape of theShape
2868 * \param theTopLeftPoint - top left quadrangle corner
2869 * \param theTopRigthPoint - top right quadrangle corner
2870 * \param theBottomLeftPoint - bottom left quadrangle corner
2871 * \param theBottomRigthPoint - bottom right quadrangle corner
2872 * \param theState - required state
2873 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
2875 //=======================================================================
2876 Handle(TColStd_HSequenceOfInteger)
2877 GEOMImpl_IShapesOperations::getShapesOnQuadrangleIDs (const Handle(GEOM_Object)& theShape,
2878 const Standard_Integer theShapeType,
2879 const Handle(GEOM_Object)& theTopLeftPoint,
2880 const Handle(GEOM_Object)& theTopRigthPoint,
2881 const Handle(GEOM_Object)& theBottomLeftPoint,
2882 const Handle(GEOM_Object)& theBottomRigthPoint,
2883 const GEOMAlgo_State theState)
2887 if ( theShape.IsNull() ||
2888 theTopLeftPoint.IsNull() ||
2889 theTopRigthPoint.IsNull() ||
2890 theBottomLeftPoint.IsNull() ||
2891 theBottomRigthPoint.IsNull() )
2894 TopoDS_Shape aShape = theShape->GetValue();
2895 TopoDS_Shape aTL = theTopLeftPoint->GetValue();
2896 TopoDS_Shape aTR = theTopRigthPoint->GetValue();
2897 TopoDS_Shape aBL = theBottomLeftPoint->GetValue();
2898 TopoDS_Shape aBR = theBottomRigthPoint->GetValue();
2900 if (aShape.IsNull() ||
2905 aTL.ShapeType() != TopAbs_VERTEX ||
2906 aTR.ShapeType() != TopAbs_VERTEX ||
2907 aBL.ShapeType() != TopAbs_VERTEX ||
2908 aBR.ShapeType() != TopAbs_VERTEX )
2911 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2912 if ( !checkTypeShapesOn( aShapeType ))
2915 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
2917 // Check presence of triangulation, build if need
2918 if (!CheckTriangulation(aShape)) {
2919 SetErrorCode("Cannot build triangulation on the shape");
2924 gp_Pnt aPntTL = BRep_Tool::Pnt(TopoDS::Vertex(aTL));
2925 gp_Pnt aPntTR = BRep_Tool::Pnt(TopoDS::Vertex(aTR));
2926 gp_Pnt aPntBL = BRep_Tool::Pnt(TopoDS::Vertex(aBL));
2927 gp_Pnt aPntBR = BRep_Tool::Pnt(TopoDS::Vertex(aBR));
2929 GEOMAlgo_FinderShapeOnQuad aFinder( aPntTL, aPntTR, aPntBL, aPntBR );
2930 Standard_Real aTol = 0.0001; // default value
2932 aFinder.SetShape(aShape);
2933 aFinder.SetTolerance(aTol);
2934 //aFinder.SetSurface(theSurface);
2935 aFinder.SetShapeType(aShapeType);
2936 aFinder.SetState(theState);
2938 // Sets the minimal number of inner points for the faces that do not have own
2939 // inner points at all (for e.g. rectangular planar faces have just 2 triangles).
2941 aFinder.SetNbPntsMin(3);
2942 // Sets the maximal number of inner points for edges or faces.
2943 // It is usefull for the cases when this number is very big (e.g =2000) to improve
2944 // the performance. If this value =0, all inner points will be taken into account.
2946 aFinder.SetNbPntsMax(100);
2950 // Interprete results
2951 Standard_Integer iErr = aFinder.ErrorStatus();
2952 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
2954 MESSAGE(" iErr : " << iErr);
2955 TCollection_AsciiString aMsg (" iErr : ");
2956 aMsg += TCollection_AsciiString(iErr);
2960 Standard_Integer iWrn = aFinder.WarningStatus();
2961 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
2963 MESSAGE(" *** iWrn : " << iWrn);
2966 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
2968 if (listSS.Extent() < 1) {
2969 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
2970 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
2974 // Fill sequence of object IDs
2975 aSeqOfIDs = new TColStd_HSequenceOfInteger;
2977 TopTools_IndexedMapOfShape anIndices;
2978 TopExp::MapShapes(aShape, anIndices);
2980 TopTools_ListIteratorOfListOfShape itSub (listSS);
2981 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
2982 int id = anIndices.FindIndex(itSub.Value());
2983 aSeqOfIDs->Append(id);
2988 //=======================================================================
2989 //function : GetShapesOnQuadrangle
2991 * \brief Find subshapes complying with given status about quadrangle
2992 * \param theShape - the shape to explore
2993 * \param theShapeType - type of subshape of theShape
2994 * \param theTopLeftPoint - top left quadrangle corner
2995 * \param theTopRigthPoint - top right quadrangle corner
2996 * \param theBottomLeftPoint - bottom left quadrangle corner
2997 * \param theBottomRigthPoint - bottom right quadrangle corner
2998 * \param theState - required state
2999 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
3001 //=======================================================================
3002 Handle(TColStd_HSequenceOfTransient)
3003 GEOMImpl_IShapesOperations::GetShapesOnQuadrangle (const Handle(GEOM_Object)& theShape,
3004 const Standard_Integer theShapeType,
3005 const Handle(GEOM_Object)& theTopLeftPoint,
3006 const Handle(GEOM_Object)& theTopRigthPoint,
3007 const Handle(GEOM_Object)& theBottomLeftPoint,
3008 const Handle(GEOM_Object)& theBottomRigthPoint,
3009 const GEOMAlgo_State theState)
3012 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
3013 getShapesOnQuadrangleIDs( theShape,
3018 theBottomRigthPoint,
3020 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->IsEmpty() )
3023 // Find objects by indices
3024 TCollection_AsciiString anAsciiList;
3025 Handle(TColStd_HSequenceOfTransient) aSeq;
3026 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
3027 if ( aSeq.IsNull() || aSeq->IsEmpty() )
3030 // Make a Python command
3032 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
3033 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
3035 GEOM::TPythonDump(aFunction)
3036 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnQuadrangle("
3038 << TopAbs_ShapeEnum(theShapeType) << ", "
3039 << theTopLeftPoint << ", "
3040 << theTopRigthPoint << ", "
3041 << theBottomLeftPoint << ", "
3042 << theBottomRigthPoint << ", "
3049 //=======================================================================
3050 //function : GetShapesOnQuadrangleIDs
3052 * \brief Find IDs of subshapes complying with given status about quadrangle
3053 * \param theShape - the shape to explore
3054 * \param theShapeType - type of subshape of theShape
3055 * \param theTopLeftPoint - top left quadrangle corner
3056 * \param theTopRigthPoint - top right quadrangle corner
3057 * \param theBottomLeftPoint - bottom left quadrangle corner
3058 * \param theBottomRigthPoint - bottom right quadrangle corner
3059 * \param theState - required state
3060 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
3062 //=======================================================================
3063 Handle(TColStd_HSequenceOfInteger)
3064 GEOMImpl_IShapesOperations::GetShapesOnQuadrangleIDs (const Handle(GEOM_Object)& theShape,
3065 const Standard_Integer theShapeType,
3066 const Handle(GEOM_Object)& theTopLeftPoint,
3067 const Handle(GEOM_Object)& theTopRigthPoint,
3068 const Handle(GEOM_Object)& theBottomLeftPoint,
3069 const Handle(GEOM_Object)& theBottomRigthPoint,
3070 const GEOMAlgo_State theState)
3073 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
3074 getShapesOnQuadrangleIDs( theShape,
3079 theBottomRigthPoint,
3081 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->IsEmpty() )
3084 // Make a Python command
3086 // The GetShapesOnCylinder() doesn't change object so no new function is required.
3087 Handle(GEOM_Object) lastObj = GEOM::GetCreatedLast(theShape,theTopLeftPoint);
3088 lastObj = GEOM::GetCreatedLast(lastObj,theTopRigthPoint);
3089 lastObj = GEOM::GetCreatedLast(lastObj,theBottomRigthPoint);
3090 lastObj = GEOM::GetCreatedLast(lastObj,theBottomLeftPoint);
3091 Handle(GEOM_Function) aFunction = lastObj->GetLastFunction();
3093 GEOM::TPythonDump(aFunction, /*append=*/true)
3094 << "listShapesOnQuadrangle = geompy.GetShapesOnQuadrangleIDs("
3096 << TopAbs_ShapeEnum(theShapeType) << ", "
3097 << theTopLeftPoint << ", "
3098 << theTopRigthPoint << ", "
3099 << theBottomLeftPoint << ", "
3100 << theBottomRigthPoint << ", "
3107 //=============================================================================
3111 //=============================================================================
3112 static bool GetInPlaceOfShape (const Handle(GEOM_Function)& theWhereFunction,
3113 const TopTools_IndexedMapOfShape& theWhereIndices,
3114 const TopoDS_Shape& theWhat,
3115 TColStd_ListOfInteger& theModifiedList)
3117 if (theWhereFunction.IsNull() || theWhat.IsNull()) return false;
3119 if (theWhereIndices.Contains(theWhat)) {
3120 // entity was not changed by the operation
3121 Standard_Integer aWhatIndex = theWhereIndices.FindIndex(theWhat);
3122 theModifiedList.Append(aWhatIndex);
3126 // try to find in history
3127 TDF_Label aHistoryLabel = theWhereFunction->GetHistoryEntry(Standard_False);
3129 // search in history for all argument shapes
3130 Standard_Boolean isFound = Standard_False;
3131 Standard_Boolean isGood = Standard_False;
3133 TDF_LabelSequence aLabelSeq;
3134 theWhereFunction->GetDependency(aLabelSeq);
3135 Standard_Integer nbArg = aLabelSeq.Length();
3137 for (Standard_Integer iarg = 1; iarg <= nbArg && !isFound; iarg++) {
3139 TDF_Label anArgumentRefLabel = aLabelSeq.Value(iarg);
3141 Handle(GEOM_Object) anArgumentObject = GEOM_Object::GetReferencedObject(anArgumentRefLabel);
3142 TopoDS_Shape anArgumentShape = anArgumentObject->GetValue();
3144 TopTools_IndexedMapOfShape anArgumentIndices;
3145 TopExp::MapShapes(anArgumentShape, anArgumentIndices);
3147 if (anArgumentIndices.Contains(theWhat)) {
3148 isFound = Standard_True;
3149 Standard_Integer aWhatIndex = anArgumentIndices.FindIndex(theWhat);
3151 // Find corresponding label in history
3152 TDF_Label anArgumentHistoryLabel =
3153 theWhereFunction->GetArgumentHistoryEntry(anArgumentRefLabel, Standard_False);
3154 if (anArgumentHistoryLabel.IsNull()) {
3155 // Lost History of operation argument. Possibly, all its entities was removed.
3156 isGood = Standard_True;
3159 TDF_Label aWhatHistoryLabel = anArgumentHistoryLabel.FindChild(aWhatIndex, Standard_False);
3161 if (aWhatHistoryLabel.IsNull()) {
3162 // Removed entity ? Compound ? Compsolid ? Shell ? Wire
3163 isGood = Standard_False;
3165 Handle(TDataStd_IntegerArray) anIntegerArray;
3166 if (!aWhatHistoryLabel.FindAttribute(TDataStd_IntegerArray::GetID(), anIntegerArray)) {
3167 //Error: Empty modifications history for the sought shape.
3168 isGood = Standard_False;
3171 isGood = Standard_True;
3172 Standard_Integer imod, aModifLen = anIntegerArray->Array()->Length();
3173 for (imod = 1; imod <= aModifLen; imod++) {
3174 theModifiedList.Append(anIntegerArray->Array()->Value(imod));
3185 // try compound/compsolid/shell/wire element by element
3186 bool isFoundAny = false;
3187 TopTools_MapOfShape mapShape;
3189 if (theWhat.ShapeType() == TopAbs_COMPOUND ||
3190 theWhat.ShapeType() == TopAbs_COMPSOLID) {
3191 // recursive processing of compound/compsolid
3192 TopoDS_Iterator anIt (theWhat, Standard_True, Standard_True);
3193 for (; anIt.More(); anIt.Next()) {
3194 if (mapShape.Add(anIt.Value())) {
3195 TopoDS_Shape curWhat = anIt.Value();
3196 isFoundAny = GetInPlaceOfShape(theWhereFunction, theWhereIndices, curWhat, theModifiedList);
3197 if (isFoundAny) isFound = Standard_True;
3201 else if (theWhat.ShapeType() == TopAbs_SHELL) {
3202 // try to replace a shell by its faces images
3203 TopExp_Explorer anExp (theWhat, TopAbs_FACE);
3204 for (; anExp.More(); anExp.Next()) {
3205 if (mapShape.Add(anExp.Current())) {
3206 TopoDS_Shape curWhat = anExp.Current();
3207 isFoundAny = GetInPlaceOfShape(theWhereFunction, theWhereIndices, curWhat, theModifiedList);
3208 if (isFoundAny) isFound = Standard_True;
3212 else if (theWhat.ShapeType() == TopAbs_WIRE) {
3213 // try to replace a wire by its edges images
3214 TopExp_Explorer anExp (theWhat, TopAbs_EDGE);
3215 for (; anExp.More(); anExp.Next()) {
3216 if (mapShape.Add(anExp.Current())) {
3217 TopoDS_Shape curWhat = anExp.Current();
3218 isFoundAny = GetInPlaceOfShape(theWhereFunction, theWhereIndices, curWhat, theModifiedList);
3219 if (isFoundAny) isFound = Standard_True;
3231 //=============================================================================
3233 * GetShapeProperties
3235 //=============================================================================
3236 void GEOMImpl_IShapesOperations::GetShapeProperties( const TopoDS_Shape aShape, Standard_Real tab[],
3239 GProp_GProps theProps;
3241 //TopoDS_Shape aPntShape;
3242 Standard_Real aShapeSize;
3244 if (aShape.ShapeType() == TopAbs_VERTEX) aCenterMass = BRep_Tool::Pnt( TopoDS::Vertex( aShape ) );
3245 else if (aShape.ShapeType() == TopAbs_EDGE) BRepGProp::LinearProperties(aShape, theProps);
3246 else if (aShape.ShapeType() == TopAbs_FACE) BRepGProp::SurfaceProperties(aShape, theProps);
3247 else BRepGProp::VolumeProperties(aShape, theProps);
3249 if (aShape.ShapeType() == TopAbs_VERTEX)
3252 aCenterMass = theProps.CentreOfMass();
3253 aShapeSize = theProps.Mass();
3256 // aPntShape = BRepBuilderAPI_MakeVertex(aCenterMass).Shape();
3257 // aVertex = BRep_Tool::Pnt( TopoDS::Vertex( aPntShape ) );
3258 aVertex = aCenterMass;
3259 tab[0] = aVertex.X();
3260 tab[1] = aVertex.Y();
3261 tab[2] = aVertex.Z();
3262 tab[3] = aShapeSize;
3268 //================================================================================
3270 * \brief Return normal to face at extrema point
3272 //================================================================================
3274 gp_Vec GetNormal (const TopoDS_Face& face, const BRepExtrema_DistShapeShape& extrema)
3276 gp_Vec defaultNorm(1,0,0); // to have same normals on different faces
3278 // get UV at extrema point
3279 Standard_Real u,v, f,l;
3280 switch ( extrema.SupportTypeShape2(1) ) {
3281 case BRepExtrema_IsInFace: {
3282 extrema.ParOnFaceS2(1, u, v );
3285 case BRepExtrema_IsOnEdge: {
3286 TopoDS_Edge edge = TopoDS::Edge( extrema.SupportOnShape2(1));
3287 Handle(Geom2d_Curve) pcurve = BRep_Tool::CurveOnSurface( edge, face, f,l );
3288 extrema.ParOnEdgeS2( 1, u );
3289 gp_Pnt2d uv = pcurve->Value( u );
3294 case BRepExtrema_IsVertex: return defaultNorm;
3297 BRepAdaptor_Surface surface( face, false );
3298 gp_Vec du, dv; gp_Pnt p;
3299 surface.D1( u, v, p, du, dv );
3303 } catch (Standard_Failure ) {
3308 //================================================================================
3310 * \brief Return type of shape for explode. In case of compound it will be a type of sub shape.
3312 //================================================================================
3314 TopAbs_ShapeEnum GetTypeOfSimplePart (const TopoDS_Shape& theShape)
3316 TopAbs_ShapeEnum aType = theShape.ShapeType();
3317 if (aType == TopAbs_VERTEX) return TopAbs_VERTEX;
3318 else if (aType == TopAbs_EDGE || aType == TopAbs_WIRE) return TopAbs_EDGE;
3319 else if (aType == TopAbs_FACE || aType == TopAbs_SHELL) return TopAbs_FACE;
3320 else if (aType == TopAbs_SOLID || aType == TopAbs_COMPSOLID) return TopAbs_SOLID;
3321 else if (aType == TopAbs_COMPOUND) {
3322 // Only the iType of the first shape in the compound is taken into account
3323 TopoDS_Iterator It (theShape, Standard_False, Standard_False);
3325 return GetTypeOfSimplePart(It.Value());
3328 return TopAbs_SHAPE;
3332 //=============================================================================
3337 //=============================================================================
3338 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlace (Handle(GEOM_Object) theShapeWhere,
3339 Handle(GEOM_Object) theShapeWhat)
3343 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
3345 TopoDS_Shape aWhere = theShapeWhere->GetValue();
3346 TopoDS_Shape aWhat = theShapeWhat->GetValue();
3347 TopoDS_Shape aPntShape;
3348 TopoDS_Vertex aVertex;
3350 if (aWhere.IsNull() || aWhat.IsNull()) {
3351 SetErrorCode("Error: aWhere and aWhat TopoDS_Shape are Null.");
3355 Handle(GEOM_Function) aWhereFunction = theShapeWhere->GetLastFunction();
3356 if (aWhereFunction.IsNull()) {
3357 SetErrorCode("Error: aWhereFunction is Null.");
3361 TopTools_IndexedMapOfShape aWhereIndices;
3362 TopExp::MapShapes(aWhere, aWhereIndices);
3364 TColStd_ListOfInteger aModifiedList;
3365 Standard_Integer aWhereIndex;
3366 Handle(TColStd_HArray1OfInteger) aModifiedArray;
3367 Handle(GEOM_Object) aResult;
3369 bool isFound = false;
3370 TopAbs_ShapeEnum iType = TopAbs_SOLID;
3371 //Standard_Real aWhat_Mass = 0., aWhere_Mass = 0.;
3372 Standard_Real tab_aWhat[4], tab_aWhere[4];
3373 Standard_Real dl_l = 1e-3;
3374 Standard_Real min_l, Tol_0D, Tol_1D, Tol_2D, Tol_3D, Tol_Mass;
3375 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
3376 Bnd_Box BoundingBox;
3377 gp_Pnt aPnt, aPnt_aWhat, tab_Pnt[2];
3378 GProp_GProps aProps;
3380 // Find the iType of the aWhat shape
3382 if ( aWhat.ShapeType() == TopAbs_VERTEX ) iType = TopAbs_VERTEX;
3383 else if ( aWhat.ShapeType() == TopAbs_EDGE || aWhat.ShapeType() == TopAbs_WIRE ) iType = TopAbs_EDGE;
3384 else if ( aWhat.ShapeType() == TopAbs_FACE || aWhat.ShapeType() == TopAbs_SHELL ) iType = TopAbs_FACE;
3385 else if ( aWhat.ShapeType() == TopAbs_SOLID || aWhat.ShapeType() == TopAbs_COMPSOLID ) iType = TopAbs_SOLID;
3386 else if ( aWhat.ShapeType() == TopAbs_COMPOUND ) {
3387 // Only the iType of the first shape in the compound is taken into account
3388 TopoDS_Iterator It (aWhat, Standard_False, Standard_False);
3390 SetErrorCode("Error: theShapeWhat is an empty COMPOUND.");
3393 TopAbs_ShapeEnum compType = It.Value().ShapeType();
3394 if ( compType == TopAbs_VERTEX ) iType = TopAbs_VERTEX;
3395 else if ( compType == TopAbs_EDGE || compType == TopAbs_WIRE ) iType = TopAbs_EDGE;
3396 else if ( compType == TopAbs_FACE || compType == TopAbs_SHELL) iType = TopAbs_FACE;
3397 else if ( compType == TopAbs_SOLID || compType == TopAbs_COMPSOLID) iType = TopAbs_SOLID;
3400 SetErrorCode("Error: An attempt to extract a shape of not supported type.");
3404 iType = GetTypeOfSimplePart(aWhat);
3405 if (iType == TopAbs_SHAPE) {
3406 SetErrorCode("Error: An attempt to extract a shape of not supported type.");
3410 TopExp_Explorer Exp_aWhat ( aWhat, iType );
3411 TopExp_Explorer Exp_aWhere ( aWhere, iType );
3412 TopExp_Explorer Exp_Edge ( aWhere, TopAbs_EDGE );
3414 // Find the shortest edge in theShapeWhere shape
3415 BRepBndLib::Add(aWhere, BoundingBox);
3416 BoundingBox.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
3417 min_l = fabs(aXmax - aXmin);
3418 if( min_l < fabs(aYmax - aYmin) ) min_l = fabs(aYmax - aYmin);
3419 if( min_l < fabs(aZmax - aZmin) ) min_l = fabs(aZmax - aZmin);
3421 // Mantis issue 0020908 BEGIN
3422 if (!Exp_Edge.More()) {
3423 min_l = Precision::Confusion();
3425 // Mantis issue 0020908 END
3426 for ( Standard_Integer nbEdge = 0; Exp_Edge.More(); Exp_Edge.Next(), nbEdge++ ) {
3427 TopExp_Explorer Exp_Vertex( Exp_Edge.Current(), TopAbs_VERTEX);
3428 for ( Standard_Integer nbVertex = 0; Exp_Vertex.More(); Exp_Vertex.Next(), nbVertex++ ) {
3429 aPnt = BRep_Tool::Pnt( TopoDS::Vertex( Exp_Vertex.Current() ) );
3430 tab_Pnt[nbVertex] = aPnt;
3432 if ( ! tab_Pnt[0].IsEqual(tab_Pnt[1], dl_l) ) {
3433 BRepGProp::LinearProperties(Exp_Edge.Current(), aProps);
3434 if ( aProps.Mass() < min_l ) min_l = aProps.Mass();
3438 // Compute tolerances
3440 Tol_1D = dl_l * min_l;
3441 Tol_2D = dl_l * ( min_l * min_l) * ( 2. + dl_l);
3442 Tol_3D = dl_l * ( min_l * min_l * min_l ) * ( 3. + (3 * dl_l) + (dl_l * dl_l) );
3444 if (Tol_0D < Precision::Confusion()) Tol_0D = Precision::Confusion();
3445 if (Tol_1D < Precision::Confusion()) Tol_1D = Precision::Confusion();
3446 if (Tol_2D < Precision::Confusion()) Tol_2D = Precision::Confusion();
3447 if (Tol_3D < Precision::Confusion()) Tol_3D = Precision::Confusion();
3449 //if (Tol_1D > 1.0) Tol_1D = 1.0;
3450 //if (Tol_2D > 1.0) Tol_2D = 1.0;
3451 //if (Tol_3D > 1.0) Tol_3D = 1.0;
3454 if ( iType == TopAbs_VERTEX ) Tol_Mass = Tol_0D;
3455 else if ( iType == TopAbs_EDGE ) Tol_Mass = Tol_1D;
3456 else if ( iType == TopAbs_FACE ) Tol_Mass = Tol_2D;
3458 // Compute the ShapeWhat Mass
3460 for ( ; Exp_aWhat.More(); Exp_aWhat.Next() ) {
3461 if ( iType == TopAbs_VERTEX ) {
3465 else if ( iType == TopAbs_EDGE ) BRepGProp::LinearProperties(Exp_aWhat.Current(), aProps);
3466 else if ( iType == TopAbs_FACE ) BRepGProp::SurfaceProperties(Exp_aWhat.Current(), aProps);
3467 else BRepGProp::VolumeProperties(Exp_aWhat.Current(), aProps);
3468 aWhat_Mass += aProps.Mass();
3472 // Searching for the sub-shapes inside the ShapeWhere shape
3473 TopTools_MapOfShape map_aWhere;
3474 for ( Exp_aWhere.ReInit(); Exp_aWhere.More(); Exp_aWhere.Next() ) {
3475 if (!map_aWhere.Add(Exp_aWhere.Current()))
3476 continue; // skip repeated shape to avoid mass addition
3477 GetShapeProperties( Exp_aWhere.Current(), tab_aWhere, aPnt );
3478 for ( Exp_aWhat.ReInit(); Exp_aWhat.More(); Exp_aWhat.Next() ) {
3479 GetShapeProperties( Exp_aWhat.Current(), tab_aWhat, aPnt_aWhat );
3480 if ( fabs(tab_aWhat[3] - tab_aWhere[3]) <= Tol_Mass && aPnt_aWhat.Distance(aPnt) <= Tol_1D )
3483 if ( (tab_aWhat[3] - tab_aWhere[3]) > Tol_Mass ) {
3484 aPntShape = BRepBuilderAPI_MakeVertex( aPnt ).Shape();
3485 aVertex = TopoDS::Vertex( aPntShape );
3486 BRepExtrema_DistShapeShape aWhereDistance ( aVertex, Exp_aWhere.Current() );
3487 BRepExtrema_DistShapeShape aWhatDistance ( aVertex, Exp_aWhat.Current() );
3488 if ( aWhereDistance.IsDone() && aWhatDistance.IsDone() &&
3489 fabs(aWhereDistance.Value() - aWhatDistance.Value()) <= Tol_1D )
3491 // 0020162: "EDF 961 GEOM : Getinplace is getting additionnal orthogonal faces"
3492 // aVertex must be projected to the same point on Where and on What
3493 gp_Pnt pOnWhat = aWhatDistance.PointOnShape2(1);
3494 gp_Pnt pOnWhere = aWhereDistance.PointOnShape2(1);
3495 isFound = ( pOnWhat.Distance(pOnWhere) <= Tol_1D );
3496 if ( isFound && iType == TopAbs_FACE )
3498 // check normals at pOnWhat and pOnWhere
3499 const double angleTol = PI/180.;
3500 gp_Vec normToWhat = GetNormal( TopoDS::Face(Exp_aWhat.Current()), aWhatDistance);
3501 gp_Vec normToWhere = GetNormal( TopoDS::Face(Exp_aWhere.Current()), aWhereDistance);
3502 if ( normToWhat * normToWhere < 0 )
3503 normToWhat.Reverse();
3504 isFound = ( normToWhat.Angle( normToWhere ) < angleTol );
3510 aWhereIndex = aWhereIndices.FindIndex(Exp_aWhere.Current());
3511 aModifiedList.Append(aWhereIndex);
3512 //aWhere_Mass += tab_aWhere[3];
3517 //if ( fabs( aWhat_Mass - aWhere_Mass ) <= Tol_Mass )
3521 if (aModifiedList.Extent() == 0) { // Not found any Results
3522 SetErrorCode(NOT_FOUND_ANY);
3526 aModifiedArray = new TColStd_HArray1OfInteger (1, aModifiedList.Extent());
3527 TColStd_ListIteratorOfListOfInteger anIterModif (aModifiedList);
3528 for (Standard_Integer imod = 1; anIterModif.More(); anIterModif.Next(), imod++)
3529 aModifiedArray->SetValue(imod, anIterModif.Value());
3532 aResult = GetEngine()->AddSubShape(theShapeWhere, aModifiedArray);
3533 if (aResult.IsNull()) {
3534 SetErrorCode("Error in algorithm: result found, but cannot be returned.");
3538 if (aModifiedArray->Length() > 1) {
3540 aResult->SetType(GEOM_GROUP);
3542 //Set a sub shape type
3543 TopoDS_Shape aFirstFound = aWhereIndices.FindKey(aModifiedArray->Value(1));
3544 TopAbs_ShapeEnum aShapeType = aFirstFound.ShapeType();
3546 TDF_Label aFreeLabel = aResult->GetFreeLabel();
3547 TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aShapeType);
3550 //Make a Python command
3551 Handle(GEOM_Function) aFunction = aResult->GetFunction(1);
3553 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetInPlace("
3554 << theShapeWhere << ", " << theShapeWhat << ")";
3560 //=======================================================================
3561 //function : GetInPlaceByHistory
3563 //=======================================================================
3564 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlaceByHistory
3565 (Handle(GEOM_Object) theShapeWhere,
3566 Handle(GEOM_Object) theShapeWhat)
3570 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
3572 TopoDS_Shape aWhere = theShapeWhere->GetValue();
3573 TopoDS_Shape aWhat = theShapeWhat->GetValue();
3575 if (aWhere.IsNull() || aWhat.IsNull()) return NULL;
3577 Handle(GEOM_Function) aWhereFunction = theShapeWhere->GetLastFunction();
3578 if (aWhereFunction.IsNull()) return NULL;
3580 //Fill array of indices
3581 TopTools_IndexedMapOfShape aWhereIndices;
3582 TopExp::MapShapes(aWhere, aWhereIndices);
3585 TColStd_ListOfInteger aModifiedList;
3586 bool isFound = GetInPlaceOfShape(aWhereFunction, aWhereIndices, aWhat, aModifiedList);
3588 if (!isFound || aModifiedList.Extent() < 1) {
3589 SetErrorCode("Error: No history found for the sought shape or its sub-shapes.");
3593 Handle(TColStd_HArray1OfInteger) aModifiedArray =
3594 new TColStd_HArray1OfInteger (1, aModifiedList.Extent());
3595 TColStd_ListIteratorOfListOfInteger anIterModif (aModifiedList);
3596 for (Standard_Integer imod = 1; anIterModif.More(); anIterModif.Next(), imod++) {
3597 aModifiedArray->SetValue(imod, anIterModif.Value());
3601 Handle(GEOM_Object) aResult = GetEngine()->AddSubShape(theShapeWhere, aModifiedArray);
3602 if (aResult.IsNull()) {
3603 SetErrorCode("Error in algorithm: result found, but cannot be returned.");
3607 if (aModifiedArray->Length() > 1) {
3609 aResult->SetType(GEOM_GROUP);
3611 //Set a sub shape type
3612 TopoDS_Shape aFirstFound = aWhereIndices.FindKey(aModifiedArray->Value(1));
3613 TopAbs_ShapeEnum aShapeType = aFirstFound.ShapeType();
3615 TDF_Label aFreeLabel = aResult->GetFreeLabel();
3616 TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aShapeType);
3619 //Make a Python command
3620 Handle(GEOM_Function) aFunction = aResult->GetFunction(1);
3622 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetInPlaceByHistory("
3623 << theShapeWhere << ", " << theShapeWhat << ")";
3629 //=======================================================================
3630 //function : SortShapes
3632 //=======================================================================
3633 void GEOMImpl_IShapesOperations::SortShapes(TopTools_ListOfShape& SL,
3634 const Standard_Boolean isOldSorting)
3636 Standard_Integer MaxShapes = SL.Extent();
3637 TopTools_Array1OfShape aShapes (1,MaxShapes);
3638 TColStd_Array1OfInteger OrderInd(1,MaxShapes);
3639 TColStd_Array1OfReal MidXYZ (1,MaxShapes); //X,Y,Z;
3640 TColStd_Array1OfReal Length (1,MaxShapes); //X,Y,Z;
3642 // Computing of CentreOfMass
3643 Standard_Integer Index;
3646 TopTools_ListIteratorOfListOfShape it(SL);
3647 for (Index=1; it.More(); Index++)
3649 TopoDS_Shape S = it.Value();
3650 SL.Remove( it ); // == it.Next()
3652 OrderInd.SetValue (Index, Index);
3653 if (S.ShapeType() == TopAbs_VERTEX) {
3654 GPoint = BRep_Tool::Pnt( TopoDS::Vertex( S ));
3655 Length.SetValue( Index, (Standard_Real) S.Orientation());
3658 // BEGIN: fix for Mantis issue 0020842
3660 BRepGProp::LinearProperties (S, GPr);
3663 if (S.ShapeType() == TopAbs_EDGE || S.ShapeType() == TopAbs_WIRE) {
3664 BRepGProp::LinearProperties (S, GPr);
3666 else if (S.ShapeType() == TopAbs_FACE || S.ShapeType() == TopAbs_SHELL) {
3667 BRepGProp::SurfaceProperties(S, GPr);
3670 BRepGProp::VolumeProperties(S, GPr);
3673 // END: fix for Mantis issue 0020842
3674 GPoint = GPr.CentreOfMass();
3675 Length.SetValue(Index, GPr.Mass());
3677 MidXYZ.SetValue(Index,
3678 GPoint.X()*999 + GPoint.Y()*99 + GPoint.Z()*0.9);
3679 //cout << Index << " L: " << Length(Index) << "CG: " << MidXYZ(Index) << endl;
3683 Standard_Integer aTemp;
3684 Standard_Boolean exchange, Sort = Standard_True;
3685 Standard_Real tol = Precision::Confusion();
3688 Sort = Standard_False;
3689 for (Index=1; Index < MaxShapes; Index++)
3691 exchange = Standard_False;
3692 Standard_Real dMidXYZ = MidXYZ(OrderInd(Index)) - MidXYZ(OrderInd(Index+1));
3693 Standard_Real dLength = Length(OrderInd(Index)) - Length(OrderInd(Index+1));
3694 if ( dMidXYZ >= tol ) {
3695 // cout << "MidXYZ: " << MidXYZ(OrderInd(Index))<< " > " <<MidXYZ(OrderInd(Index+1))
3696 // << " d: " << dMidXYZ << endl;
3697 exchange = Standard_True;
3699 else if ( Abs(dMidXYZ) < tol && dLength >= tol ) {
3700 // cout << "Length: " << Length(OrderInd(Index))<< " > " <<Length(OrderInd(Index+1))
3701 // << " d: " << dLength << endl;
3702 exchange = Standard_True;
3704 else if ( Abs(dMidXYZ) < tol && Abs(dLength) < tol &&
3705 aShapes(OrderInd(Index)).ShapeType() <= TopAbs_FACE) {
3707 // equal values possible on shapes such as two halves of a sphere and
3708 // a membrane inside the sphere
3710 BRepBndLib::Add( aShapes( OrderInd(Index) ), box1 );
3711 if ( box1.IsVoid() ) continue;
3712 BRepBndLib::Add( aShapes( OrderInd(Index+1) ), box2 );
3713 Standard_Real dSquareExtent = box1.SquareExtent() - box2.SquareExtent();
3714 if ( dSquareExtent >= tol ) {
3715 // cout << "SquareExtent: " << box1.SquareExtent()<<" > "<<box2.SquareExtent() << endl;
3716 exchange = Standard_True;
3718 else if ( Abs(dSquareExtent) < tol ) {
3719 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax, val1, val2;
3720 box1.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
3721 val1 = (aXmin+aXmax)*999 + (aYmin+aYmax)*99 + (aZmin+aZmax)*0.9;
3722 box2.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
3723 val2 = (aXmin+aXmax)*999 + (aYmin+aYmax)*99 + (aZmin+aZmax)*0.9;
3724 //exchange = val1 > val2;
3725 if ((val1 - val2) >= tol) {
3726 exchange = Standard_True;
3728 //cout << "box: " << val1<<" > "<<val2 << endl;
3734 // cout << "exchange " << Index << " & " << Index+1 << endl;
3735 aTemp = OrderInd(Index);
3736 OrderInd(Index) = OrderInd(Index+1);
3737 OrderInd(Index+1) = aTemp;
3738 Sort = Standard_True;
3743 for (Index=1; Index <= MaxShapes; Index++)
3744 SL.Append( aShapes( OrderInd(Index) ));
3747 //=======================================================================
3748 //function : CompsolidToCompound
3750 //=======================================================================
3751 TopoDS_Shape GEOMImpl_IShapesOperations::CompsolidToCompound (const TopoDS_Shape& theCompsolid)
3753 if (theCompsolid.ShapeType() != TopAbs_COMPSOLID) {
3754 return theCompsolid;
3757 TopoDS_Compound aCompound;
3759 B.MakeCompound(aCompound);
3761 TopTools_MapOfShape mapShape;
3762 TopoDS_Iterator It (theCompsolid, Standard_True, Standard_True);
3764 for (; It.More(); It.Next()) {
3765 TopoDS_Shape aShape_i = It.Value();
3766 if (mapShape.Add(aShape_i)) {
3767 B.Add(aCompound, aShape_i);
3774 //=======================================================================
3775 //function : CheckTriangulation
3777 //=======================================================================
3778 bool GEOMImpl_IShapesOperations::CheckTriangulation (const TopoDS_Shape& aShape)
3780 bool isTriangulation = true;
3782 TopExp_Explorer exp (aShape, TopAbs_FACE);
3785 TopLoc_Location aTopLoc;
3786 Handle(Poly_Triangulation) aTRF;
3787 aTRF = BRep_Tool::Triangulation(TopoDS::Face(exp.Current()), aTopLoc);
3788 if (aTRF.IsNull()) {
3789 isTriangulation = false;
3792 else // no faces, try edges
3794 TopExp_Explorer expe (aShape, TopAbs_EDGE);
3798 TopLoc_Location aLoc;
3799 Handle(Poly_Polygon3D) aPE = BRep_Tool::Polygon3D(TopoDS::Edge(expe.Current()), aLoc);
3801 isTriangulation = false;
3805 if (!isTriangulation) {
3806 // calculate deflection
3807 Standard_Real aDeviationCoefficient = 0.001;
3810 BRepBndLib::Add(aShape, B);
3811 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
3812 B.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
3814 Standard_Real dx = aXmax - aXmin, dy = aYmax - aYmin, dz = aZmax - aZmin;
3815 Standard_Real aDeflection = Max(Max(dx, dy), dz) * aDeviationCoefficient * 4;
3816 Standard_Real aHLRAngle = 0.349066;
3818 BRepMesh_IncrementalMesh Inc (aShape, aDeflection, Standard_False, aHLRAngle);
3824 #define MAX_TOLERANCE 1.e-7
3826 //=======================================================================
3827 //function : isSameEdge
3828 //purpose : Returns True if two edges coincide
3829 //=======================================================================
3830 static bool isSameEdge(const TopoDS_Edge& theEdge1, const TopoDS_Edge& theEdge2)
3832 TopoDS_Vertex V11, V12, V21, V22;
3833 TopExp::Vertices(theEdge1, V11, V12);
3834 TopExp::Vertices(theEdge2, V21, V22);
3835 gp_Pnt P11 = BRep_Tool::Pnt(V11);
3836 gp_Pnt P12 = BRep_Tool::Pnt(V12);
3837 gp_Pnt P21 = BRep_Tool::Pnt(V21);
3838 gp_Pnt P22 = BRep_Tool::Pnt(V22);
3839 bool coincide = false;
3841 //Check that ends of edges coincide
3842 if(P11.Distance(P21) <= MAX_TOLERANCE) {
3843 if(P12.Distance(P22) <= MAX_TOLERANCE) coincide = true;
3845 else if(P11.Distance(P22) <= MAX_TOLERANCE) {
3846 if(P12.Distance(P21) <= MAX_TOLERANCE) coincide = true;
3849 if(!coincide) return false;
3851 if (BRep_Tool::Degenerated(theEdge1))
3852 if (BRep_Tool::Degenerated(theEdge2)) return true;
3855 if (BRep_Tool::Degenerated(theEdge2)) return false;
3857 double U11, U12, U21, U22;
3858 Handle(Geom_Curve) C1 = BRep_Tool::Curve(theEdge1, U11, U12);
3859 Handle(Geom_Curve) C2 = BRep_Tool::Curve(theEdge2, U21, U22);
3860 if(C1->DynamicType() == C2->DynamicType()) return true;
3862 //Check that both edges has the same geometry
3863 double range = U12-U11;
3864 double U = U11+ range/3.0;
3865 gp_Pnt P1 = C1->Value(U); //Compute a point on one third of the edge's length
3866 U = U11+range*2.0/3.0;
3867 gp_Pnt P2 = C1->Value(U); //Compute a point on two thirds of the edge's length
3869 if(!GeomLib_Tool::Parameter(C2, P1, MAX_TOLERANCE, U) || U < U21 || U > U22)
3872 if(P1.Distance(C2->Value(U)) > MAX_TOLERANCE) return false;
3874 if(!GeomLib_Tool::Parameter(C2, P2, MAX_TOLERANCE, U) || U < U21 || U > U22)
3877 if(P2.Distance(C2->Value(U)) > MAX_TOLERANCE) return false;
3882 #include <TopoDS_TShape.hxx>
3883 //=======================================================================
3884 //function : isSameFace
3885 //purpose : Returns True if two faces coincide
3886 //=======================================================================
3887 static bool isSameFace(const TopoDS_Face& theFace1, const TopoDS_Face& theFace2)
3889 TopExp_Explorer E(theFace1, TopAbs_EDGE);
3890 TopTools_ListOfShape LS1, LS2;
3891 for(; E.More(); E.Next()) LS1.Append(E.Current());
3893 E.Init(theFace2, TopAbs_EDGE);
3894 for(; E.More(); E.Next()) LS2.Append(E.Current());
3896 //Compare the number of edges in the faces
3897 if(LS1.Extent() != LS2.Extent()) return false;
3899 double aMin = RealFirst(), aMax = RealLast();
3900 double xminB1=aMax, yminB1=aMax, zminB1=aMax, xminB2=aMax, yminB2=aMax, zminB2=aMax;
3901 double xmaxB1=aMin, ymaxB1=aMin, zmaxB1=aMin, xmaxB2=aMin, ymaxB2=aMin, zmaxB2=aMin;
3903 for(E.Init(theFace1, TopAbs_VERTEX); E.More(); E.Next()) {
3904 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
3905 if(P.X() < xminB1) xminB1 = P.X();
3906 if(P.Y() < yminB1) yminB1 = P.Y();
3907 if(P.Z() < zminB1) zminB1 = P.Z();
3908 if(P.X() > xmaxB1) xmaxB1 = P.X();
3909 if(P.Y() > ymaxB1) ymaxB1 = P.Y();
3910 if(P.Z() > zmaxB1) zmaxB1 = P.Z();
3913 for(E.Init(theFace2, TopAbs_VERTEX); E.More(); E.Next()) {
3914 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
3915 if(P.X() < xminB2) xminB2 = P.X();
3916 if(P.Y() < yminB2) yminB2 = P.Y();
3917 if(P.Z() < zminB2) zminB2 = P.Z();
3918 if(P.X() > xmaxB2) xmaxB2 = P.X();
3919 if(P.Y() > ymaxB2) ymaxB2 = P.Y();
3920 if(P.Z() > zmaxB2) zmaxB2 = P.Z();
3923 //Compare the bounding boxes of both faces
3924 if(gp_Pnt(xminB1, yminB1, zminB1).Distance(gp_Pnt(xminB2, yminB2, zminB2)) > MAX_TOLERANCE)
3927 if(gp_Pnt(xmaxB1, ymaxB1, zmaxB1).Distance(gp_Pnt(xmaxB2, ymaxB2, zmaxB2)) > MAX_TOLERANCE)
3930 Handle(Geom_Surface) S1 = BRep_Tool::Surface(theFace1);
3931 Handle(Geom_Surface) S2 = BRep_Tool::Surface(theFace2);
3933 //Check if there a coincidence of two surfaces at least in two points
3934 double U11, U12, V11, V12, U21, U22, V21, V22;
3935 BRepTools::UVBounds(theFace1, U11, U12, V11, V12);
3936 BRepTools::UVBounds(theFace2, U21, U22, V21, V22);
3938 double rangeU = U12-U11;
3939 double rangeV = V12-V11;
3940 double U = U11 + rangeU/3.0;
3941 double V = V11 + rangeV/3.0;
3942 gp_Pnt P1 = S1->Value(U, V);
3943 U = U11+rangeU*2.0/3.0;
3944 V = V11+rangeV*2.0/3.0;
3945 gp_Pnt P2 = S1->Value(U, V);
3947 if (!GeomLib_Tool::Parameters(S2, P1, MAX_TOLERANCE, U, V) || U < U21 || U > U22 || V < V21 || V > V22)
3950 if (P1.Distance(S2->Value(U,V)) > MAX_TOLERANCE) return false;
3952 if (!GeomLib_Tool::Parameters(S2, P2, MAX_TOLERANCE, U, V) || U < U21 || U > U22 || V < V21 || V > V22)
3955 if (P2.Distance(S2->Value(U, V)) > MAX_TOLERANCE) return false;
3957 //Check that each edge of the Face1 has a counterpart in the Face2
3958 TopTools_MapOfOrientedShape aMap;
3959 TopTools_ListIteratorOfListOfShape LSI1(LS1);
3960 for(; LSI1.More(); LSI1.Next()) {
3961 TopoDS_Edge E = TopoDS::Edge(LSI1.Value());
3962 bool isFound = false;
3963 TopTools_ListIteratorOfListOfShape LSI2(LS2);
3964 for(; LSI2.More(); LSI2.Next()) {
3965 TopoDS_Shape aValue = LSI2.Value();
3966 if(aMap.Contains(aValue)) continue; //To avoid checking already found edge several times
3967 if(isSameEdge(E, TopoDS::Edge(aValue))) {
3973 if(!isFound) return false;
3979 //=======================================================================
3980 //function : isSameSolid
3981 //purpose : Returns True if two solids coincide
3982 //=======================================================================
3983 bool isSameSolid(const TopoDS_Solid& theSolid1, const TopoDS_Solid& theSolid2)
3985 TopExp_Explorer E(theSolid1, TopAbs_FACE);
3986 TopTools_ListOfShape LS1, LS2;
3987 for(; E.More(); E.Next()) LS1.Append(E.Current());
3988 E.Init(theSolid2, TopAbs_FACE);
3989 for(; E.More(); E.Next()) LS2.Append(E.Current());
3991 if(LS1.Extent() != LS2.Extent()) return false;
3993 double aMin = RealFirst(), aMax = RealLast();
3994 double xminB1=aMax, yminB1=aMax, zminB1=aMax, xminB2=aMax, yminB2=aMax, zminB2=aMax;
3995 double xmaxB1=aMin, ymaxB1=aMin, zmaxB1=aMin, xmaxB2=aMin, ymaxB2=aMin, zmaxB2=aMin;
3997 for(E.Init(theSolid1, TopAbs_VERTEX); E.More(); E.Next()) {
3998 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
3999 if(P.X() < xminB1) xminB1 = P.X();
4000 if(P.Y() < yminB1) yminB1 = P.Y();
4001 if(P.Z() < zminB1) zminB1 = P.Z();
4002 if(P.X() > xmaxB1) xmaxB1 = P.X();
4003 if(P.Y() > ymaxB1) ymaxB1 = P.Y();
4004 if(P.Z() > zmaxB1) zmaxB1 = P.Z();
4007 for(E.Init(theSolid2, TopAbs_VERTEX); E.More(); E.Next()) {
4008 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4009 if(P.X() < xminB2) xminB2 = P.X();
4010 if(P.Y() < yminB2) yminB2 = P.Y();
4011 if(P.Z() < zminB2) zminB2 = P.Z();
4012 if(P.X() > xmaxB2) xmaxB2 = P.X();
4013 if(P.Y() > ymaxB2) ymaxB2 = P.Y();
4014 if(P.Z() > zmaxB2) zmaxB2 = P.Z();
4017 //Compare the bounding boxes of both solids
4018 if(gp_Pnt(xminB1, yminB1, zminB1).Distance(gp_Pnt(xminB2, yminB2, zminB2)) > MAX_TOLERANCE)
4021 if(gp_Pnt(xmaxB1, ymaxB1, zmaxB1).Distance(gp_Pnt(xmaxB2, ymaxB2, zmaxB2)) > MAX_TOLERANCE)
4024 //Check that each face of the Solid1 has a counterpart in the Solid2
4025 TopTools_MapOfOrientedShape aMap;
4026 TopTools_ListIteratorOfListOfShape LSI1(LS1);
4027 for(; LSI1.More(); LSI1.Next()) {
4028 TopoDS_Face F = TopoDS::Face(LSI1.Value());
4029 bool isFound = false;
4030 TopTools_ListIteratorOfListOfShape LSI2(LS2);
4031 for(; LSI2.More(); LSI2.Next()) {
4032 if(aMap.Contains(LSI2.Value())) continue; //To avoid checking already found faces several times
4033 if(isSameFace(F, TopoDS::Face(LSI2.Value()))) {
4034 aMap.Add(LSI2.Value());
4039 if(!isFound) return false;
4045 //=======================================================================
4046 //function : GetSame
4048 //=======================================================================
4049 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetSame(const Handle(GEOM_Object)& theShapeWhere,
4050 const Handle(GEOM_Object)& theShapeWhat)
4053 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
4055 TopoDS_Shape aWhere = theShapeWhere->GetValue();
4056 TopoDS_Shape aWhat = theShapeWhat->GetValue();
4058 if (aWhere.IsNull() || aWhat.IsNull()) return NULL;
4061 bool isFound = false;
4062 TopoDS_Shape aSubShape;
4063 TopTools_MapOfShape aMap;
4065 switch(aWhat.ShapeType()) {
4066 case TopAbs_VERTEX: {
4067 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(aWhat));
4068 TopExp_Explorer E(aWhere, TopAbs_VERTEX);
4069 for(; E.More(); E.Next()) {
4070 if(!aMap.Add(E.Current())) continue;
4071 gp_Pnt P2 = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4072 if(P.Distance(P2) <= MAX_TOLERANCE) {
4074 aSubShape = E.Current();
4081 TopoDS_Face aFace = TopoDS::Face(aWhat);
4082 TopExp_Explorer E(aWhere, TopAbs_FACE);
4083 for(; E.More(); E.Next()) {
4084 if(!aMap.Add(E.Current())) continue;
4085 if(isSameFace(aFace, TopoDS::Face(E.Current()))) {
4086 aSubShape = E.Current();
4094 TopoDS_Edge anEdge = TopoDS::Edge(aWhat);
4095 TopExp_Explorer E(aWhere, TopAbs_EDGE);
4096 for(; E.More(); E.Next()) {
4097 if(!aMap.Add(E.Current())) continue;
4098 if(isSameEdge(anEdge, TopoDS::Edge(E.Current()))) {
4099 aSubShape = E.Current();
4106 case TopAbs_SOLID: {
4107 TopoDS_Solid aSolid = TopoDS::Solid(aWhat);
4108 TopExp_Explorer E(aWhere, TopAbs_SOLID);
4109 for(; E.More(); E.Next()) {
4110 if(!aMap.Add(E.Current())) continue;
4111 if(isSameSolid(aSolid, TopoDS::Solid(E.Current()))) {
4112 aSubShape = E.Current();
4124 TopTools_IndexedMapOfShape anIndices;
4125 TopExp::MapShapes(aWhere, anIndices);
4126 if (anIndices.Contains(aSubShape))
4127 anIndex = anIndices.FindIndex(aSubShape);
4130 if(anIndex < 0) return NULL;
4132 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
4134 anArray->SetValue(1, anIndex);
4136 Handle(GEOM_Object) aResult = GetEngine()->AddSubShape(theShapeWhere, anArray);
4137 Handle(GEOM_Function) aFunction = aResult->GetLastFunction();
4139 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetSame("
4140 << theShapeWhere << ", " << theShapeWhat << ")";