1 // Copyright (C) 2007-2011 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
23 // File : GEOMImpl_IShapesOperations.cxx
25 // 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_ClsfBox.hxx"
50 #include "GEOMAlgo_ClsfSolid.hxx"
51 #include "GEOMAlgo_CoupleOfShapes.hxx"
52 #include "GEOMAlgo_FinderShapeOn1.hxx"
53 #include "GEOMAlgo_FinderShapeOnQuad.hxx"
54 #include "GEOMAlgo_FinderShapeOn2.hxx"
55 #include "GEOMAlgo_GetInPlace.hxx"
56 #include "GEOMAlgo_GlueDetector.hxx"
57 #include "GEOMAlgo_ListIteratorOfListOfCoupleOfShapes.hxx"
58 #include "GEOMAlgo_ListOfCoupleOfShapes.hxx"
60 #include "utilities.h"
62 #include "Utils_ExceptHandlers.hxx"
64 #include <TFunction_DriverTable.hxx>
65 #include <TFunction_Driver.hxx>
66 #include <TFunction_Logbook.hxx>
67 #include <TDataStd_Integer.hxx>
68 #include <TDataStd_IntegerArray.hxx>
69 #include <TDataStd_ListIteratorOfListOfExtendedString.hxx>
70 #include <TDF_Tool.hxx>
72 #include <BRepExtrema_ExtCF.hxx>
73 #include <BRepExtrema_DistShapeShape.hxx>
75 #include <BRep_Tool.hxx>
76 #include <BRep_Builder.hxx>
77 #include <BRepTools.hxx>
78 #include <BRepGProp.hxx>
79 #include <BRepAdaptor_Curve.hxx>
80 #include <BRepAdaptor_Surface.hxx>
81 #include <BRepBndLib.hxx>
82 #include <BRepBuilderAPI_MakeFace.hxx>
83 #include <BRepMesh_IncrementalMesh.hxx>
87 #include <TopExp_Explorer.hxx>
88 #include <TopLoc_Location.hxx>
90 #include <TopoDS_Shape.hxx>
91 #include <TopoDS_Solid.hxx>
92 #include <TopoDS_Face.hxx>
93 #include <TopoDS_Edge.hxx>
94 #include <TopoDS_Vertex.hxx>
95 #include <TopoDS_Compound.hxx>
96 #include <TopoDS_Iterator.hxx>
97 #include <TopTools_Array1OfShape.hxx>
98 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
99 #include <TopTools_IndexedMapOfShape.hxx>
100 #include <TopTools_ListIteratorOfListOfShape.hxx>
101 #include <TopTools_MapOfShape.hxx>
102 #include <TopTools_MapOfOrientedShape.hxx>
104 #include <Geom_Surface.hxx>
105 #include <Geom_Plane.hxx>
106 #include <Geom_SphericalSurface.hxx>
107 #include <Geom_CylindricalSurface.hxx>
108 #include <GeomAdaptor_Surface.hxx>
110 #include <GeomLib_Tool.hxx>
111 #include <Geom2d_Curve.hxx>
113 #include <Bnd_Box.hxx>
114 #include <GProp_GProps.hxx>
115 #include <TColStd_Array1OfReal.hxx>
116 #include <TColStd_HArray1OfInteger.hxx>
117 #include <TColStd_ListIteratorOfListOfInteger.hxx>
118 #include <TColStd_ListOfInteger.hxx>
119 #include <gp_Cylinder.hxx>
120 #include <gp_Lin.hxx>
121 #include <gp_Pnt.hxx>
125 #include <functional>
127 #include <Standard_NullObject.hxx>
128 #include <Standard_Failure.hxx>
129 #include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
131 // Includes added for GetInPlace algorithm improvement
133 #include <GEOMImpl_MeasureDriver.hxx>
134 #include <GEOMImpl_IMeasure.hxx>
135 #include <BRepBuilderAPI_MakeVertex.hxx>
137 #include <BRepClass_FaceClassifier.hxx>
138 #include <BRepClass3d_SolidClassifier.hxx>
139 #include <Precision.hxx>
141 #define STD_SORT_ALGO 1
143 //=============================================================================
147 //=============================================================================
148 GEOMImpl_IShapesOperations::GEOMImpl_IShapesOperations (GEOM_Engine* theEngine, int theDocID)
149 : GEOM_IOperations(theEngine, theDocID)
151 MESSAGE("GEOMImpl_IShapesOperations::GEOMImpl_IShapesOperations");
154 //=============================================================================
158 //=============================================================================
159 GEOMImpl_IShapesOperations::~GEOMImpl_IShapesOperations()
161 MESSAGE("GEOMImpl_IShapesOperations::~GEOMImpl_IShapesOperations");
164 //=============================================================================
168 //=============================================================================
169 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeEdge
170 (Handle(GEOM_Object) thePnt1, Handle(GEOM_Object) thePnt2)
174 if (thePnt1.IsNull() || thePnt2.IsNull()) return NULL;
176 //Add a new Edge object
177 Handle(GEOM_Object) anEdge = GetEngine()->AddObject(GetDocID(), GEOM_EDGE);
179 //Add a new Vector function
180 Handle(GEOM_Function) aFunction =
181 anEdge->AddFunction(GEOMImpl_VectorDriver::GetID(), VECTOR_TWO_PNT);
183 //Check if the function is set correctly
184 if (aFunction->GetDriverGUID() != GEOMImpl_VectorDriver::GetID()) return NULL;
186 GEOMImpl_IVector aPI (aFunction);
188 Handle(GEOM_Function) aRef1 = thePnt1->GetLastFunction();
189 Handle(GEOM_Function) aRef2 = thePnt2->GetLastFunction();
190 if (aRef1.IsNull() || aRef2.IsNull()) return NULL;
192 aPI.SetPoint1(aRef1);
193 aPI.SetPoint2(aRef2);
195 //Compute the Edge value
197 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
200 if (!GetSolver()->ComputeFunction(aFunction)) {
201 SetErrorCode("Vector driver failed");
205 catch (Standard_Failure) {
206 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
207 SetErrorCode(aFail->GetMessageString());
211 //Make a Python command
212 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdge("
213 << thePnt1 << ", " << thePnt2 << ")";
219 //=============================================================================
221 * MakeEdgeOnCurveByLength
223 //=============================================================================
224 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeEdgeOnCurveByLength
225 (Handle(GEOM_Object) theRefCurve,
226 const Standard_Real theLength,
227 Handle(GEOM_Object) theStartPoint)
231 if (theRefCurve.IsNull()) return NULL;
233 //Add a new Edge object
234 Handle(GEOM_Object) anEdge = GetEngine()->AddObject(GetDocID(), GEOM_EDGE);
236 //Add a new Vector function
237 Handle(GEOM_Function) aFunction =
238 anEdge->AddFunction(GEOMImpl_ShapeDriver::GetID(), EDGE_CURVE_LENGTH);
240 //Check if the function is set correctly
241 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
243 GEOMImpl_IVector aPI (aFunction);
245 Handle(GEOM_Function) aRef1 = theRefCurve->GetLastFunction();
246 if (aRef1.IsNull()) return NULL;
247 aPI.SetPoint1(aRef1);
249 if (!theStartPoint.IsNull()) {
250 Handle(GEOM_Function) aRef2 = theStartPoint->GetLastFunction();
251 aPI.SetPoint2(aRef2);
254 aPI.SetParameter(theLength);
256 //Compute the Edge value
258 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
261 if (!GetSolver()->ComputeFunction(aFunction)) {
262 SetErrorCode("Vector driver failed");
266 catch (Standard_Failure) {
267 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
268 SetErrorCode(aFail->GetMessageString());
272 //Make a Python command
273 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdgeOnCurveByLength("
274 << theRefCurve << ", " << theLength << ", " << theStartPoint << ")";
280 //=============================================================================
284 //=============================================================================
285 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeEdgeWire
286 (Handle(GEOM_Object) theWire,
287 const Standard_Real theLinearTolerance,
288 const Standard_Real theAngularTolerance)
292 if (theWire.IsNull()) return NULL;
294 //Add a new Edge object
295 Handle(GEOM_Object) anEdge = GetEngine()->AddObject(GetDocID(), GEOM_EDGE);
297 //Add a new Vector function
298 Handle(GEOM_Function) aFunction =
299 anEdge->AddFunction(GEOMImpl_ShapeDriver::GetID(), EDGE_WIRE);
301 //Check if the function is set correctly
302 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
304 GEOMImpl_IShapes aCI (aFunction);
306 Handle(GEOM_Function) aWire = theWire->GetLastFunction();
308 if (aWire.IsNull()) return NULL;
311 aCI.SetTolerance(theLinearTolerance);
312 aCI.SetAngularTolerance(theAngularTolerance);
314 //Compute the Edge value
316 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
319 if (!GetSolver()->ComputeFunction(aFunction)) {
320 SetErrorCode("Shape driver failed");
324 catch (Standard_Failure) {
325 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
326 SetErrorCode(aFail->GetMessageString());
330 const double DEF_LIN_TOL = Precision::Confusion();
331 const double DEF_ANG_TOL = Precision::Angular();
332 //Make a Python command
333 if ( theAngularTolerance == DEF_ANG_TOL ) {
334 if ( theLinearTolerance == DEF_LIN_TOL )
335 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdgeWire("
338 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdgeWire("
339 << theWire << ", " << theLinearTolerance << ")";
342 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdgeWire("
343 << theWire << ", " << theLinearTolerance << ", "
344 << theAngularTolerance << ")";
351 //=============================================================================
355 //=============================================================================
356 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeWire
357 (std::list<Handle(GEOM_Object)> theShapes,
358 const Standard_Real theTolerance)
363 Handle(GEOM_Object) aWire = GetEngine()->AddObject(GetDocID(), GEOM_WIRE);
366 Handle(GEOM_Function) aFunction =
367 aWire->AddFunction(GEOMImpl_ShapeDriver::GetID(), WIRE_EDGES);
368 if (aFunction.IsNull()) return NULL;
370 //Check if the function is set correctly
371 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
373 GEOMImpl_IShapes aCI (aFunction);
374 aCI.SetTolerance(theTolerance);
376 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
379 std::list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
380 for (; it != theShapes.end(); it++) {
381 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
382 if (aRefSh.IsNull()) {
383 SetErrorCode("NULL argument shape for the shape construction");
386 aShapesSeq->Append(aRefSh);
388 aCI.SetShapes(aShapesSeq);
392 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
395 if (!GetSolver()->ComputeFunction(aFunction)) {
396 SetErrorCode("Shape driver failed");
400 catch (Standard_Failure) {
401 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
402 SetErrorCode(aFail->GetMessageString());
406 //Make a Python command
407 GEOM::TPythonDump pd (aFunction);
408 pd << aWire << " = geompy.MakeWire([";
411 it = theShapes.begin();
412 if (it != theShapes.end()) {
414 while (it != theShapes.end()) {
415 pd << ", " << (*it++);
418 pd << "], " << theTolerance << ")";
424 //=============================================================================
428 //=============================================================================
429 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFace (Handle(GEOM_Object) theWire,
430 const bool isPlanarWanted)
434 if (theWire.IsNull()) return NULL;
436 //Add a new Face object
437 Handle(GEOM_Object) aFace = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
439 //Add a new Shape function for creation of a face from a wire
440 Handle(GEOM_Function) aFunction =
441 aFace->AddFunction(GEOMImpl_ShapeDriver::GetID(), FACE_WIRE);
442 if (aFunction.IsNull()) return NULL;
444 //Check if the function is set correctly
445 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
447 GEOMImpl_IShapes aCI (aFunction);
449 Handle(GEOM_Function) aRefWire = theWire->GetLastFunction();
451 if (aRefWire.IsNull()) return NULL;
453 aCI.SetBase(aRefWire);
454 aCI.SetIsPlanar(isPlanarWanted);
456 //Compute the Face value
458 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
461 if (!GetSolver()->ComputeFunction(aFunction)) {
462 SetErrorCode("Shape driver failed to compute a face");
466 catch (Standard_Failure) {
467 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
468 SetErrorCode(aFail->GetMessageString());
472 //Make a Python command
473 GEOM::TPythonDump(aFunction) << aFace << " = geompy.MakeFace("
474 << theWire << ", " << (int)isPlanarWanted << ")";
480 //=============================================================================
484 //=============================================================================
485 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFaceWires
486 (std::list<Handle(GEOM_Object)> theShapes,
487 const bool isPlanarWanted)
492 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
495 Handle(GEOM_Function) aFunction =
496 aShape->AddFunction(GEOMImpl_ShapeDriver::GetID(), FACE_WIRES);
497 if (aFunction.IsNull()) return NULL;
499 //Check if the function is set correctly
500 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
502 GEOMImpl_IShapes aCI (aFunction);
504 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
507 std::list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
508 for (; it != theShapes.end(); it++) {
509 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
510 if (aRefSh.IsNull()) {
511 SetErrorCode("NULL argument shape for the face construction");
514 aShapesSeq->Append(aRefSh);
516 aCI.SetShapes(aShapesSeq);
518 aCI.SetIsPlanar(isPlanarWanted);
522 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
525 if (!GetSolver()->ComputeFunction(aFunction)) {
526 SetErrorCode("Shape driver failed");
530 catch (Standard_Failure) {
531 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
532 SetErrorCode(aFail->GetMessageString());
536 //Make a Python command
537 GEOM::TPythonDump pd (aFunction);
538 pd << aShape << " = geompy.MakeFaceWires([";
541 it = theShapes.begin();
542 if (it != theShapes.end()) {
544 while (it != theShapes.end()) {
545 pd << ", " << (*it++);
548 pd << "], " << (int)isPlanarWanted << ")";
554 //=============================================================================
558 //=============================================================================
559 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeShell
560 (std::list<Handle(GEOM_Object)> theShapes)
562 return MakeShape(theShapes, GEOM_SHELL, SHELL_FACES, "MakeShell");
565 //=============================================================================
569 //=============================================================================
570 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeSolidShells
571 (std::list<Handle(GEOM_Object)> theShapes)
573 return MakeShape(theShapes, GEOM_SOLID, SOLID_SHELLS, "MakeSolid");
576 //=============================================================================
580 //=============================================================================
581 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeCompound
582 (std::list<Handle(GEOM_Object)> theShapes)
584 return MakeShape(theShapes, GEOM_COMPOUND, COMPOUND_SHAPES, "MakeCompound");
587 //=============================================================================
591 //=============================================================================
592 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeShape
593 (std::list<Handle(GEOM_Object)> theShapes,
594 const Standard_Integer theObjectType,
595 const Standard_Integer theFunctionType,
596 const TCollection_AsciiString& theMethodName)
601 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), theObjectType);
604 Handle(GEOM_Function) aFunction =
605 aShape->AddFunction(GEOMImpl_ShapeDriver::GetID(), theFunctionType);
606 if (aFunction.IsNull()) return NULL;
608 //Check if the function is set correctly
609 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
611 GEOMImpl_IShapes aCI (aFunction);
613 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
616 std::list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
617 for (; it != theShapes.end(); it++) {
618 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
619 if (aRefSh.IsNull()) {
620 SetErrorCode("NULL argument shape for the shape construction");
623 aShapesSeq->Append(aRefSh);
625 aCI.SetShapes(aShapesSeq);
629 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
632 if (!GetSolver()->ComputeFunction(aFunction)) {
633 SetErrorCode("Shape driver failed");
637 catch (Standard_Failure) {
638 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
639 SetErrorCode(aFail->GetMessageString());
643 //Make a Python command
644 GEOM::TPythonDump pd (aFunction);
645 pd << aShape << " = geompy." << theMethodName.ToCString() << "([";
648 it = theShapes.begin();
649 if (it != theShapes.end()) {
651 while (it != theShapes.end()) {
652 pd << ", " << (*it++);
661 //=============================================================================
665 //=============================================================================
666 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeGlueFaces
667 (Handle(GEOM_Object) theShape,
668 const Standard_Real theTolerance,
669 const Standard_Boolean doKeepNonSolids)
673 if (theShape.IsNull()) return NULL;
675 //Add a new Glued object
676 Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
678 //Add a new Glue function
679 Handle(GEOM_Function) aFunction;
680 aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_FACES);
681 if (aFunction.IsNull()) return NULL;
683 //Check if the function is set correctly
684 if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
686 GEOMImpl_IGlue aCI (aFunction);
688 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
689 if (aRefShape.IsNull()) return NULL;
691 aCI.SetBase(aRefShape);
692 aCI.SetTolerance(theTolerance);
693 aCI.SetKeepNonSolids(doKeepNonSolids);
695 //Compute the sub-shape value
696 Standard_Boolean isWarning = Standard_False;
698 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
701 if (!GetSolver()->ComputeFunction(aFunction)) {
702 SetErrorCode("Shape driver failed to glue faces");
706 catch (Standard_Failure) {
707 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
708 SetErrorCode(aFail->GetMessageString());
709 // to provide warning
710 if (!aFunction->GetValue().IsNull()) {
711 isWarning = Standard_True;
717 //Make a Python command
718 GEOM::TPythonDump(aFunction) << aGlued << " = geompy.MakeGlueFaces("
719 << theShape << ", " << theTolerance << ")";
721 // to provide warning
722 if (!isWarning) SetErrorCode(OK);
726 //=============================================================================
730 //=============================================================================
732 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetGlueFaces
733 (Handle(GEOM_Object) theShape,
734 const Standard_Real theTolerance)
738 if (theShape.IsNull()) return NULL;
739 TopoDS_Shape aShape = theShape->GetValue();
740 if (aShape.IsNull()) return NULL;
742 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
744 Standard_Integer iErr;
746 GEOMAlgo_Gluer1 aGluer;
747 GEOMAlgo_ListIteratorOfListOfCoupleOfShapes aItCS;
748 GEOMAlgo_CoupleOfShapes aCS;
749 GEOMAlgo_ListOfCoupleOfShapes aLCS;
751 //aGluer = new GEOMAlgo_Gluer1;
752 aGluer.SetShape(aShape);
753 aGluer.SetTolerance(theTolerance);
755 iErr = aGluer.ErrorStatus();
756 if (iErr) return NULL;
758 TopTools_ListOfShape listShape;
759 const GEOMAlgo_ListOfCoupleOfShapes& aLCSG = aGluer.GluedFaces();
761 aItCS.Initialize(aLCSG);
762 for (; aItCS.More(); aItCS.Next()) {
763 const GEOMAlgo_CoupleOfShapes& aCSG = aItCS.Value();
764 listShape.Append(aCSG.Shape1());
767 TopTools_ListIteratorOfListOfShape itSub (listShape);
768 TCollection_AsciiString anAsciiList, anEntry;
769 TopTools_IndexedMapOfShape anIndices;
770 TopExp::MapShapes(aShape, anIndices);
771 Handle(TColStd_HArray1OfInteger) anArray;
772 Handle(GEOM_Object) anObj;
773 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
774 TopoDS_Shape aValue = itSub.Value();
775 anArray = new TColStd_HArray1OfInteger(1,1);
776 anArray->SetValue(1, anIndices.FindIndex(aValue));
777 anObj = GetEngine()->AddSubShape(theShape, anArray);
778 if (!anObj.IsNull()) {
781 // for python command
782 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
783 anAsciiList += anEntry;
788 //Make a Python command
789 if( anAsciiList.Length() > 0 ) {
790 anAsciiList.Trunc(anAsciiList.Length() - 1);
791 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
792 GEOM::TPythonDump pd (aFunction, true);
793 pd << "[" << anAsciiList.ToCString();
794 pd << "] = geompy.GetGlueFaces(" << theShape << ", " << theTolerance << ")";
803 //=============================================================================
805 * MakeGlueFacesByList
807 //=============================================================================
808 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeGlueFacesByList
809 (Handle(GEOM_Object) theShape,
810 const Standard_Real theTolerance,
811 std::list<Handle(GEOM_Object)> theFaces,
812 const Standard_Boolean doKeepNonSolids,
813 const Standard_Boolean doGlueAllEdges)
817 if (theShape.IsNull()) return NULL;
819 //Add a new Glued object
820 Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
822 //Add a new Glue function
823 Handle(GEOM_Function) aFunction;
824 aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_FACES_BY_LIST);
825 if (aFunction.IsNull()) return NULL;
827 //Check if the function is set correctly
828 if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
830 GEOMImpl_IGlue aCI (aFunction);
832 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
833 if (aRefShape.IsNull()) return NULL;
835 aCI.SetBase(aRefShape);
836 aCI.SetTolerance(theTolerance);
837 aCI.SetKeepNonSolids(doKeepNonSolids);
838 aCI.SetGlueAllEdges(doGlueAllEdges);
840 Handle(TColStd_HSequenceOfTransient) aFaces = new TColStd_HSequenceOfTransient;
841 std::list<Handle(GEOM_Object)>::iterator it = theFaces.begin();
842 for (; it != theFaces.end(); it++) {
843 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
844 if (aRefSh.IsNull()) {
845 SetErrorCode("NULL argument shape for the shape construction");
848 aFaces->Append(aRefSh);
850 aCI.SetFaces(aFaces);
852 //Compute the sub-shape value
853 Standard_Boolean isWarning = Standard_False;
855 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
858 if (!GetSolver()->ComputeFunction(aFunction)) {
859 SetErrorCode("Shape driver failed to glue faces");
863 catch (Standard_Failure) {
864 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
865 SetErrorCode(aFail->GetMessageString());
866 // to provide warning
867 if (!aFunction->GetValue().IsNull()) {
868 isWarning = Standard_True;
874 //Make a Python command
876 GEOM::TPythonDump pd(aFunction);
877 pd << aGlued << " = geompy.MakeGlueFacesByList("
878 << theShape << ", " << theTolerance << ", [";
880 it = theFaces.begin();
881 if (it != theFaces.end()) {
883 while (it != theFaces.end()) {
884 pd << ", " << (*it++);
887 pd << "], " << (bool)doKeepNonSolids << ", " << (bool)doGlueAllEdges << ")";
889 // to provide warning
890 if (!isWarning) SetErrorCode(OK);
894 //=============================================================================
898 //=============================================================================
899 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeGlueEdges
900 (Handle(GEOM_Object) theShape,
901 const Standard_Real theTolerance)
905 if (theShape.IsNull()) return NULL;
907 //Add a new Glued object
908 Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
910 //Add a new Glue function
911 Handle(GEOM_Function) aFunction;
912 aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_EDGES);
913 if (aFunction.IsNull()) return NULL;
915 //Check if the function is set correctly
916 if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
918 GEOMImpl_IGlue aCI (aFunction);
920 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
921 if (aRefShape.IsNull()) return NULL;
923 aCI.SetBase(aRefShape);
924 aCI.SetTolerance(theTolerance);
925 aCI.SetKeepNonSolids(true);
927 //Compute the sub-shape value
928 Standard_Boolean isWarning = Standard_False;
930 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
933 if (!GetSolver()->ComputeFunction(aFunction)) {
934 SetErrorCode("Shape driver failed to glue edges");
938 catch (Standard_Failure) {
939 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
940 SetErrorCode(aFail->GetMessageString());
941 // to provide warning
942 if (!aFunction->GetValue().IsNull()) {
943 isWarning = Standard_True;
949 //Make a Python command
950 GEOM::TPythonDump(aFunction) << aGlued << " = geompy.MakeGlueEdges("
951 << theShape << ", " << theTolerance << ")";
953 // to provide warning
954 if (!isWarning) SetErrorCode(OK);
958 //=============================================================================
962 //=============================================================================
963 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetGlueShapes
964 (Handle(GEOM_Object) theShape,
965 const Standard_Real theTolerance,
966 const TopAbs_ShapeEnum theType)
970 if (theShape.IsNull()) return NULL;
971 TopoDS_Shape aShape = theShape->GetValue();
972 if (aShape.IsNull()) return NULL;
974 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
976 GEOMAlgo_GlueDetector aGluer;
977 aGluer.SetArgument(aShape);
978 aGluer.SetTolerance(theTolerance);
980 Standard_Integer iErr = aGluer.ErrorStatus();
981 if (iErr) return NULL;
983 TCollection_AsciiString anAsciiList, anEntry;
984 TopTools_IndexedMapOfShape anIndices;
985 TopExp::MapShapes(aShape, anIndices);
986 Handle(TColStd_HArray1OfInteger) anArray;
987 Handle(GEOM_Object) anObj;
989 TopTools_ListOfShape listOnePerSet;
991 const TopTools_DataMapOfShapeListOfShape& aImages = aGluer.Images();
992 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape aItDMSLS (aImages);
993 for (int index = 1; aItDMSLS.More(); aItDMSLS.Next(), ++index) {
995 //const TopoDS_Shape& aSkey = aItDMSLS.Key();
997 // list of shapes of the argument that can be glued
998 const TopTools_ListOfShape& aLSD = aItDMSLS.Value();
1000 //listShape.Append(aLSD.First());
1001 TopoDS_Shape aValue = aLSD.First();
1003 if (aValue.ShapeType() == theType) {
1004 listOnePerSet.Append(aValue);
1008 // for stable order of returned entities
1009 GEOMImpl_IShapesOperations::SortShapes(listOnePerSet, Standard_False);
1011 TopTools_ListIteratorOfListOfShape aListIt (listOnePerSet);
1012 for (; aListIt.More(); aListIt.Next()) {
1013 TopoDS_Shape aValue = aListIt.Value();
1014 anArray = new TColStd_HArray1OfInteger(1,1);
1015 anArray->SetValue(1, anIndices.FindIndex(aValue));
1016 anObj = GetEngine()->AddSubShape(theShape, anArray);
1017 if (!anObj.IsNull()) {
1018 aSeq->Append(anObj);
1020 // for python command
1021 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
1022 anAsciiList += anEntry;
1027 // Make a Python command
1028 if (anAsciiList.Length() > 0) {
1029 anAsciiList.Trunc(anAsciiList.Length() - 1);
1030 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
1031 GEOM::TPythonDump pd (aFunction, /*append=*/true);
1032 pd << "[" << anAsciiList.ToCString();
1033 if (theType == TopAbs_FACE)
1034 pd << "] = geompy.GetGlueFaces(" << theShape << ", " << theTolerance << ")";
1035 else if (theType == TopAbs_EDGE)
1036 pd << "] = geompy.GetGlueEdges(" << theShape << ", " << theTolerance << ")";
1044 //=============================================================================
1046 * MakeGlueEdgesByList
1048 //=============================================================================
1049 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeGlueEdgesByList
1050 (Handle(GEOM_Object) theShape,
1051 const Standard_Real theTolerance,
1052 std::list<Handle(GEOM_Object)> theEdges)
1056 if (theShape.IsNull()) return NULL;
1058 //Add a new Glued object
1059 Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
1061 //Add a new Glue function
1062 Handle(GEOM_Function) aFunction;
1063 aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_EDGES_BY_LIST);
1064 if (aFunction.IsNull()) return NULL;
1066 //Check if the function is set correctly
1067 if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
1069 GEOMImpl_IGlue aCI (aFunction);
1071 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
1072 if (aRefShape.IsNull()) return NULL;
1074 aCI.SetBase(aRefShape);
1075 aCI.SetTolerance(theTolerance);
1076 aCI.SetKeepNonSolids(true);
1078 Handle(TColStd_HSequenceOfTransient) anEdges = new TColStd_HSequenceOfTransient;
1079 std::list<Handle(GEOM_Object)>::iterator it = theEdges.begin();
1080 for (; it != theEdges.end(); it++) {
1081 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
1082 if (aRefSh.IsNull()) {
1083 SetErrorCode("NULL argument shape for the shape construction");
1086 anEdges->Append(aRefSh);
1088 aCI.SetFaces(anEdges);
1090 //Compute the sub-shape value
1091 Standard_Boolean isWarning = Standard_False;
1093 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
1096 if (!GetSolver()->ComputeFunction(aFunction)) {
1097 SetErrorCode("Shape driver failed to glue edges");
1101 catch (Standard_Failure) {
1102 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1103 SetErrorCode(aFail->GetMessageString());
1104 // to provide warning
1105 if (!aFunction->GetValue().IsNull()) {
1106 isWarning = Standard_True;
1112 //Make a Python command
1114 GEOM::TPythonDump pd (aFunction);
1115 pd << aGlued << " = geompy.MakeGlueEdgesByList("
1116 << theShape << ", " << theTolerance << ", [";
1118 it = theEdges.begin();
1119 if (it != theEdges.end()) {
1121 while (it != theEdges.end()) {
1122 pd << ", " << (*it++);
1127 // to provide warning
1128 if (!isWarning) SetErrorCode(OK);
1132 //=============================================================================
1134 * GetExistingSubObjects
1136 //=============================================================================
1137 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetExistingSubObjects
1138 (Handle(GEOM_Object) theShape,
1139 const Standard_Boolean theGroupsOnly)
1143 if (theShape.IsNull()) return NULL;
1145 Handle(GEOM_Function) aMainShape = theShape->GetLastFunction();
1146 if (aMainShape.IsNull()) return NULL;
1148 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1149 SetErrorCode(NOT_FOUND_ANY);
1151 if (!aMainShape->HasSubShapeReferences()) return aSeq;
1152 const TDataStd_ListOfExtendedString& aListEntries = aMainShape->GetSubShapeReferences();
1153 if (aListEntries.IsEmpty()) return aSeq;
1157 TCollection_AsciiString anAsciiList;
1159 TDataStd_ListIteratorOfListOfExtendedString anIt (aListEntries);
1160 for (; anIt.More(); anIt.Next()) {
1161 TCollection_ExtendedString anEntry = anIt.Value();
1162 Standard_Integer aStrLen = anEntry.LengthOfCString();
1163 char* anEntryStr = new char[aStrLen];
1164 anEntry.ToUTF8CString(anEntryStr);
1165 Handle(GEOM_Object) anObj = GetEngine()->GetObject(GetDocID(), anEntryStr, false);
1166 if (!anObj.IsNull()) {
1167 if (!theGroupsOnly || anObj->GetType() == GEOM_GROUP) {
1168 aSeq->Append(anObj);
1170 // for python command
1171 anAsciiList += anEntryStr;
1175 delete [] anEntryStr;
1178 if (aSeq->Length() == 0) {
1179 SetErrorCode(NOT_FOUND_ANY);
1183 //Make a Python command
1184 anAsciiList.Trunc(anAsciiList.Length() - 1);
1186 GEOM::TPythonDump pd (aMainShape, /*append=*/true);
1187 pd << "[" << anAsciiList.ToCString();
1188 pd << "] = geompy.GetExistingSubObjects(";
1189 pd << theShape << ", " << (bool)theGroupsOnly << ")";
1196 //=============================================================================
1200 //=============================================================================
1201 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::MakeExplode
1202 (Handle(GEOM_Object) theShape,
1203 const Standard_Integer theShapeType,
1204 const Standard_Boolean isSorted,
1205 const ExplodeType theExplodeType)
1209 if (theShape.IsNull()) return NULL;
1210 TopoDS_Shape aShape = theShape->GetValue();
1211 if (aShape.IsNull()) return NULL;
1213 Handle(GEOM_Function) aMainShape = theShape->GetLastFunction();
1215 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1216 Handle(GEOM_Object) anObj;
1217 TopTools_MapOfShape mapShape;
1218 TopTools_ListOfShape listShape;
1220 if (aShape.ShapeType() == TopAbs_COMPOUND &&
1221 (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
1222 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPSOLID ||
1223 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPOUND))
1225 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
1226 for (; It.More(); It.Next()) {
1227 if (mapShape.Add(It.Value())) {
1228 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
1229 TopAbs_ShapeEnum(theShapeType) == It.Value().ShapeType()) {
1230 listShape.Append(It.Value());
1235 else if (theExplodeType != EXPLODE_NEW_EXCLUDE_MAIN || aShape.ShapeType() != theShapeType) // issue 0021079
1237 TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
1238 for (; exp.More(); exp.Next())
1239 if (mapShape.Add(exp.Current()))
1240 listShape.Append(exp.Current());
1243 if (listShape.IsEmpty()) {
1244 //SetErrorCode("The given shape has no sub-shapes of the requested type");
1245 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
1250 bool isOldSorting = false;
1251 if (theExplodeType == EXPLODE_OLD_INCLUDE_MAIN)
1252 isOldSorting = true;
1253 SortShapes(listShape, isOldSorting);
1256 TopTools_IndexedMapOfShape anIndices;
1257 TopExp::MapShapes(aShape, anIndices);
1258 Handle(TColStd_HArray1OfInteger) anArray;
1260 TopTools_ListIteratorOfListOfShape itSub (listShape);
1261 TCollection_AsciiString anAsciiList, anEntry;
1262 for (int index = 1; itSub.More(); itSub.Next(), ++index)
1264 TopoDS_Shape aValue = itSub.Value();
1265 anArray = new TColStd_HArray1OfInteger(1,1);
1266 anArray->SetValue(1, anIndices.FindIndex(aValue));
1268 //anObj = GetEngine()->AddSubShape(theShape, anArray);
1270 anObj = GetEngine()->AddObject(GetDocID(), GEOM_SUBSHAPE);
1271 Handle(GEOM_Function) aFunction = anObj->AddFunction(GEOM_Object::GetSubShapeID(), 1);
1272 if (aFunction.IsNull()) return aSeq;
1274 GEOM_ISubShape aSSI (aFunction);
1275 aSSI.SetMainShape(aMainShape);
1276 aSSI.SetIndices(anArray);
1278 // Set function value directly, as we know it.
1279 // Usage of Solver here would lead to significant loss of time,
1280 // because GEOM_SubShapeDriver will build TopTools_IndexedMapOfShape
1281 // on the main shape for each being calculated sub-shape separately.
1282 aFunction->SetValue(aValue);
1284 // Put this subshape in the list of subshapes of theMainShape
1285 aMainShape->AddSubShapeReference(aFunction);
1288 if (!anObj.IsNull()) {
1289 aSeq->Append(anObj);
1291 // for python command
1292 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
1293 anAsciiList += anEntry;
1298 //Make a Python command
1299 anAsciiList.Trunc(anAsciiList.Length() - 1);
1301 GEOM::TPythonDump pd (aMainShape, /*append=*/true);
1302 pd << "[" << anAsciiList.ToCString() << "] = geompy.";
1303 switch (theExplodeType) {
1304 case EXPLODE_NEW_EXCLUDE_MAIN:
1305 pd << "ExtractShapes(" << theShape << ", "
1306 << TopAbs_ShapeEnum(theShapeType) << ", " << (isSorted ? "True" : "False") << ")";
1308 case EXPLODE_NEW_INCLUDE_MAIN:
1309 pd << "SubShapeAll" << (isSorted ? "SortedCentres(" : "(")
1310 << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
1312 case EXPLODE_OLD_INCLUDE_MAIN:
1313 pd << "SubShapeAll" << (isSorted ? "Sorted(" : "(")
1314 << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
1323 //=============================================================================
1327 //=============================================================================
1328 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::SubShapeAllIDs
1329 (Handle(GEOM_Object) theShape,
1330 const Standard_Integer theShapeType,
1331 const Standard_Boolean isSorted,
1332 const ExplodeType theExplodeType)
1336 if (theShape.IsNull()) return NULL;
1337 TopoDS_Shape aShape = theShape->GetValue();
1338 if (aShape.IsNull()) return NULL;
1340 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
1341 TopTools_MapOfShape mapShape;
1342 TopTools_ListOfShape listShape;
1344 if (aShape.ShapeType() == TopAbs_COMPOUND &&
1345 (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
1346 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPSOLID ||
1347 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPOUND))
1349 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
1350 for (; It.More(); It.Next()) {
1351 if (mapShape.Add(It.Value())) {
1352 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
1353 TopAbs_ShapeEnum(theShapeType) == It.Value().ShapeType()) {
1354 listShape.Append(It.Value());
1359 else if (theExplodeType != EXPLODE_NEW_EXCLUDE_MAIN || aShape.ShapeType() != theShapeType) // issue 0021079
1361 TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
1362 for (; exp.More(); exp.Next())
1363 if (mapShape.Add(exp.Current()))
1364 listShape.Append(exp.Current());
1367 if (listShape.IsEmpty()) {
1368 //SetErrorCode("The given shape has no sub-shapes of the requested type");
1369 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
1374 bool isOldSorting = false;
1375 if (theExplodeType == EXPLODE_OLD_INCLUDE_MAIN)
1376 isOldSorting = true;
1377 SortShapes(listShape, isOldSorting);
1380 TopTools_IndexedMapOfShape anIndices;
1381 TopExp::MapShapes(aShape, anIndices);
1382 Handle(TColStd_HArray1OfInteger) anArray;
1384 TopTools_ListIteratorOfListOfShape itSub (listShape);
1385 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
1386 TopoDS_Shape aValue = itSub.Value();
1387 aSeq->Append(anIndices.FindIndex(aValue));
1390 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
1392 //Make a Python command
1393 GEOM::TPythonDump pd (aFunction, /*append=*/true);
1394 pd << "listSubShapeIDs = geompy.SubShapeAll";
1395 switch (theExplodeType) {
1396 case EXPLODE_NEW_EXCLUDE_MAIN:
1398 case EXPLODE_NEW_INCLUDE_MAIN:
1399 pd << (isSorted ? "SortedCentresIDs(" : "IDs(")
1400 << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
1402 case EXPLODE_OLD_INCLUDE_MAIN:
1403 pd << (isSorted ? "SortedIDs(" : "IDs(")
1404 << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
1413 //=============================================================================
1417 //=============================================================================
1418 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetSubShape
1419 (Handle(GEOM_Object) theMainShape,
1420 const Standard_Integer theID)
1424 if (theMainShape.IsNull()) return NULL;
1426 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
1427 anArray->SetValue(1, theID);
1428 Handle(GEOM_Object) anObj = GetEngine()->AddSubShape(theMainShape, anArray,true);
1429 if (anObj.IsNull()) {
1430 SetErrorCode("Can not get a sub-shape with the given ID");
1434 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1436 //Make a Python command
1437 GEOM::TPythonDump(aFunction) << anObj << " = geompy.GetSubShape("
1438 << theMainShape << ", [" << theID << "])";
1444 //=============================================================================
1448 //=============================================================================
1449 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::MakeSubShapes
1450 (Handle(GEOM_Object) theMainShape,
1451 Handle(TColStd_HArray1OfInteger) theIndices)
1455 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1457 if (!theIndices->Length()) {
1458 SetErrorCode(NOT_FOUND_ANY);
1462 if (theMainShape.IsNull()) return NULL;
1463 TopoDS_Shape aShape = theMainShape->GetValue();
1464 if (aShape.IsNull()) return NULL;
1466 Handle(GEOM_Function) aMainShape = theMainShape->GetLastFunction();
1468 TopTools_IndexedMapOfShape anIndices;
1469 TopExp::MapShapes(aShape, anIndices);
1471 Handle(TColStd_HArray1OfInteger) anArray;
1472 Handle(GEOM_Object) anObj;
1474 TCollection_AsciiString anAsciiList, anEntry;
1475 Standard_Integer i, low = theIndices->Lower(), up = theIndices->Upper();
1476 for (i = low; i <= up; i++) {
1477 int id = theIndices->Value(i);
1478 if (1 <= id && id <= anIndices.Extent()) {
1479 TopoDS_Shape aValue = anIndices.FindKey(id);
1480 anArray = new TColStd_HArray1OfInteger(1,1);
1481 anArray->SetValue(1, id);
1483 anObj = GetEngine()->AddObject(GetDocID(), GEOM_SUBSHAPE);
1484 if (!anObj.IsNull()) {
1485 Handle(GEOM_Function) aFunction = anObj->AddFunction(GEOM_Object::GetSubShapeID(), 1);
1486 if (aFunction.IsNull()) return aSeq;
1488 GEOM_ISubShape aSSI (aFunction);
1489 aSSI.SetMainShape(aMainShape);
1490 aSSI.SetIndices(anArray);
1492 // Set function value directly, as we know it.
1493 // Usage of Solver here would lead to significant loss of time,
1494 // because GEOM_SubShapeDriver will build TopTools_IndexedMapOfShape
1495 // on the main shape for each being calculated sub-shape separately.
1496 aFunction->SetValue(aValue);
1498 // Put this subshape in the list of subshapes of theMainShape
1499 aMainShape->AddSubShapeReference(aFunction);
1501 aSeq->Append(anObj);
1503 // for python command
1504 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
1505 anAsciiList += anEntry;
1511 //Make a Python command
1512 anAsciiList.Trunc(anAsciiList.Length() - 1);
1514 GEOM::TPythonDump pd (aMainShape, /*append=*/true);
1515 pd << "[" << anAsciiList.ToCString() << "] = geompy.SubShapes("
1516 << theMainShape << ", [" ;
1517 for (i = low; i <= up - 1; i++) {
1518 pd << theIndices->Value(i) << ", ";
1520 pd << theIndices->Value(up) << "])";
1527 //=============================================================================
1531 //=============================================================================
1532 Standard_Integer GEOMImpl_IShapesOperations::GetSubShapeIndex (Handle(GEOM_Object) theMainShape,
1533 Handle(GEOM_Object) theSubShape)
1537 TopoDS_Shape aMainShape = theMainShape->GetValue();
1538 TopoDS_Shape aSubShape = theSubShape->GetValue();
1540 if (aMainShape.IsNull() || aSubShape.IsNull()) return -1;
1542 TopTools_IndexedMapOfShape anIndices;
1543 TopExp::MapShapes(aMainShape, anIndices);
1544 if (anIndices.Contains(aSubShape)) {
1546 return anIndices.FindIndex(aSubShape);
1552 //=============================================================================
1556 //=============================================================================
1557 Standard_Integer GEOMImpl_IShapesOperations::GetTopologyIndex (Handle(GEOM_Object) theMainShape,
1558 Handle(GEOM_Object) theSubShape)
1562 TopoDS_Shape aMainShape = theMainShape->GetValue();
1563 TopoDS_Shape aSubShape = theSubShape->GetValue();
1565 if (aMainShape.IsNull() || aSubShape.IsNull()) {
1566 SetErrorCode("Null argument shape given");
1571 if (aSubShape.ShapeType() == TopAbs_COMPOUND) {
1573 TopTools_ListOfShape CL;
1574 CL.Append(aMainShape);
1575 TopTools_ListIteratorOfListOfShape itC;
1576 for (itC.Initialize(CL); itC.More(); itC.Next()) {
1577 for (it.Initialize(itC.Value()); it.More(); it.Next()) {
1578 if (it.Value().ShapeType() == TopAbs_COMPOUND) {
1579 if (it.Value().IsSame(aSubShape))
1583 CL.Append(it.Value());
1588 TopExp_Explorer anExp (aMainShape, aSubShape.ShapeType());
1589 TopTools_MapOfShape M;
1590 for (; anExp.More(); anExp.Next()) {
1591 if (M.Add(anExp.Current())) {
1592 if (anExp.Current().IsSame(aSubShape))
1599 SetErrorCode("The sub-shape does not belong to the main shape");
1603 //=============================================================================
1605 * GetShapeTypeString
1607 //=============================================================================
1608 TCollection_AsciiString GEOMImpl_IShapesOperations::GetShapeTypeString (Handle(GEOM_Object) theShape)
1612 TCollection_AsciiString aTypeName ("Null Shape");
1614 TopoDS_Shape aShape = theShape->GetValue();
1615 if (aShape.IsNull())
1618 switch (aShape.ShapeType() )
1620 case TopAbs_COMPOUND:
1621 aTypeName = "Compound";
1623 case TopAbs_COMPSOLID:
1624 aTypeName = "Compound Solid";
1627 aTypeName = "Solid";
1630 aTypeName = "Shell";
1634 BRepAdaptor_Surface surf (TopoDS::Face(aShape));
1635 if (surf.GetType() == GeomAbs_Plane)
1636 aTypeName = "Plane";
1637 else if (surf.GetType() == GeomAbs_Cylinder)
1638 aTypeName = "Cylindrical Face";
1639 else if (surf.GetType() == GeomAbs_Sphere)
1640 aTypeName = "Spherical Face";
1641 else if (surf.GetType() == GeomAbs_Torus)
1642 aTypeName = "Toroidal Face";
1643 else if (surf.GetType() == GeomAbs_Cone)
1644 aTypeName = "Conical Face";
1646 aTypeName = "GEOM::FACE";
1654 BRepAdaptor_Curve curv (TopoDS::Edge(aShape));
1655 if (curv.GetType() == GeomAbs_Line) {
1656 if ((Abs(curv.FirstParameter()) >= 1E6) ||
1657 (Abs(curv.LastParameter()) >= 1E6))
1661 } else if (curv.GetType() == GeomAbs_Circle) {
1662 if (curv.IsClosed())
1663 aTypeName = "Circle";
1672 aTypeName = "Vertex";
1675 aTypeName = "Shape";
1678 aTypeName = "Shape of unknown type";
1684 //=============================================================================
1688 //=============================================================================
1689 Standard_Integer GEOMImpl_IShapesOperations::NumberOfSubShapes
1690 (Handle(GEOM_Object) theShape,
1691 const Standard_Integer theShapeType)
1694 Standard_Integer nbShapes = 0;
1696 if (theShape.IsNull()) return -1;
1697 TopoDS_Shape aShape = theShape->GetValue();
1698 if (aShape.IsNull()) return -1;
1701 TopTools_MapOfShape mapShape;
1703 if (aShape.ShapeType() == TopAbs_COMPOUND &&
1704 (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
1705 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPSOLID ||
1706 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPOUND)) {
1707 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
1708 for (; It.More(); It.Next()) {
1709 if (mapShape.Add(It.Value())) {
1710 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
1711 TopAbs_ShapeEnum(theShapeType) == It.Value().ShapeType()) {
1717 TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
1718 for (; exp.More(); exp.Next())
1719 if (mapShape.Add(exp.Current()))
1725 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
1728 int iType, nbTypes [TopAbs_SHAPE];
1729 for (iType = 0; iType < TopAbs_SHAPE; ++iType)
1731 nbTypes[aShape.ShapeType()]++;
1733 TopTools_MapOfShape aMapOfShape;
1734 aMapOfShape.Add(aShape);
1735 TopTools_ListOfShape aListOfShape;
1736 aListOfShape.Append(aShape);
1738 TopTools_ListIteratorOfListOfShape itL (aListOfShape);
1739 for (; itL.More(); itL.Next()) {
1740 TopoDS_Iterator it (itL.Value());
1741 for (; it.More(); it.Next()) {
1742 TopoDS_Shape s = it.Value();
1743 if (aMapOfShape.Add(s)) {
1744 aListOfShape.Append(s);
1745 nbTypes[s.ShapeType()]++;
1750 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE)
1751 nbShapes = aMapOfShape.Extent();
1753 nbShapes = nbTypes[theShapeType];
1755 catch (Standard_Failure) {
1756 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1757 SetErrorCode(aFail->GetMessageString());
1765 //=============================================================================
1769 //=============================================================================
1770 Handle(GEOM_Object) GEOMImpl_IShapesOperations::ReverseShape(Handle(GEOM_Object) theShape)
1774 if (theShape.IsNull()) return NULL;
1776 //Add a new reversed object
1777 Handle(GEOM_Object) aReversed = GetEngine()->AddObject(GetDocID(), theShape->GetType());
1779 //Add a new Revese function
1780 Handle(GEOM_Function) aFunction;
1781 aFunction = aReversed->AddFunction(GEOMImpl_ShapeDriver::GetID(), REVERSE_ORIENTATION);
1782 if (aFunction.IsNull()) return NULL;
1784 //Check if the function is set correctly
1785 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
1787 GEOMImpl_IShapes aSI (aFunction);
1789 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
1790 if (aRefShape.IsNull()) return NULL;
1792 aSI.SetBase(aRefShape);
1794 //Compute the sub-shape value
1796 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
1799 if (!GetSolver()->ComputeFunction(aFunction)) {
1800 SetErrorCode("Shape driver failed to reverse shape");
1804 catch (Standard_Failure) {
1805 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1806 SetErrorCode(aFail->GetMessageString());
1810 //Make a Python command
1811 GEOM::TPythonDump(aFunction) << aReversed
1812 << " = geompy.ChangeOrientation(" << theShape << ")";
1818 //=============================================================================
1822 //=============================================================================
1823 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetFreeFacesIDs
1824 (Handle(GEOM_Object) theShape)
1828 if (theShape.IsNull()) return NULL;
1829 TopoDS_Shape aShape = theShape->GetValue();
1830 if (aShape.IsNull()) return NULL;
1832 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
1834 TopTools_IndexedDataMapOfShapeListOfShape mapFaceBlocks;
1835 GEOMImpl_Block6Explorer::MapShapesAndAncestors
1836 (aShape, TopAbs_FACE, TopAbs_SOLID, mapFaceBlocks);
1838 Standard_Integer ind = 1, nbFaces = mapFaceBlocks.Extent();
1841 SetErrorCode("The given shape has no faces");
1845 TopTools_IndexedMapOfShape anIndices;
1846 TopExp::MapShapes(aShape, anIndices);
1848 Standard_Integer id;
1849 for (; ind <= nbFaces; ind++) {
1850 if (mapFaceBlocks.FindFromIndex(ind).Extent() != 2) {
1851 id = anIndices.FindIndex(mapFaceBlocks.FindKey(ind));
1856 //The explode doesn't change object so no new function is required.
1857 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
1859 //Make a Python command
1860 GEOM::TPythonDump(aFunction, /*append=*/true)
1861 << "listFreeFacesIDs = geompy.GetFreeFacesIDs(" << theShape << ")";
1867 //=======================================================================
1868 //function : GetSharedShapes
1870 //=======================================================================
1871 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetSharedShapes
1872 (Handle(GEOM_Object) theShape1,
1873 Handle(GEOM_Object) theShape2,
1874 const Standard_Integer theShapeType)
1878 if (theShape1.IsNull() || theShape2.IsNull()) return NULL;
1880 TopoDS_Shape aShape1 = theShape1->GetValue();
1881 TopoDS_Shape aShape2 = theShape2->GetValue();
1883 if (aShape1.IsNull() || aShape2.IsNull()) return NULL;
1885 TopTools_IndexedMapOfShape anIndices;
1886 TopExp::MapShapes(aShape1, anIndices);
1887 Handle(TColStd_HArray1OfInteger) anArray;
1889 TopTools_IndexedMapOfShape mapShape1;
1890 TopExp::MapShapes(aShape1, TopAbs_ShapeEnum(theShapeType), mapShape1);
1892 Handle(GEOM_Object) anObj;
1893 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1894 TCollection_AsciiString anAsciiList, anEntry;
1896 TopTools_MapOfShape mapShape2;
1897 TopExp_Explorer exp (aShape2, TopAbs_ShapeEnum(theShapeType));
1898 for (; exp.More(); exp.Next()) {
1899 TopoDS_Shape aSS = exp.Current();
1900 if (mapShape2.Add(aSS) && mapShape1.Contains(aSS)) {
1901 anArray = new TColStd_HArray1OfInteger(1,1);
1902 anArray->SetValue(1, anIndices.FindIndex(aSS));
1903 anObj = GetEngine()->AddSubShape(theShape1, anArray);
1904 aSeq->Append(anObj);
1906 // for python command
1907 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
1908 anAsciiList += anEntry;
1913 if (aSeq->IsEmpty()) {
1914 SetErrorCode("The given shapes have no shared sub-shapes of the requested type");
1918 //Make a Python command
1919 anAsciiList.Trunc(anAsciiList.Length() - 1);
1921 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1923 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
1924 << "] = geompy.GetSharedShapes(" << theShape1 << ", "
1925 << theShape2 << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
1931 //=======================================================================
1932 //function : GetSharedShapes
1934 //=======================================================================
1935 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetSharedShapes
1936 (std::list<Handle(GEOM_Object)> theShapes,
1937 const Standard_Integer theShapeType)
1941 int aLen = theShapes.size();
1942 if (aLen < 1) return NULL;
1945 std::list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
1947 Handle(GEOM_Object) aMainObj = (*it++);
1948 Handle(GEOM_Function) aMainShape = aMainObj->GetLastFunction();
1949 if (aMainShape.IsNull()) {
1950 SetErrorCode("NULL shape for GetSharedShapes");
1954 TopoDS_Shape aShape1 = aMainShape->GetValue();
1955 if (aShape1.IsNull()) return NULL;
1957 TopTools_IndexedMapOfShape anIndices;
1958 TopExp::MapShapes(aShape1, anIndices);
1960 TopTools_IndexedMapOfShape mapSelected;
1961 TopExp::MapShapes(aShape1, TopAbs_ShapeEnum(theShapeType), mapSelected);
1963 // Find shared shapes
1965 TopoDS_Compound aCurrSelection;
1967 for (; it != theShapes.end(); it++, ind++) {
1968 Handle(GEOM_Function) aRefShape = (*it)->GetLastFunction();
1969 if (aRefShape.IsNull()) {
1970 SetErrorCode("NULL shape for GetSharedShapes");
1974 TopoDS_Compound aCompound;
1975 B.MakeCompound(aCompound);
1977 TopoDS_Shape aShape2 = aRefShape->GetValue();
1978 if (aShape2.IsNull()) return NULL;
1980 TopTools_MapOfShape mapShape2;
1981 TopExp_Explorer exp (aShape2, TopAbs_ShapeEnum(theShapeType));
1982 for (; exp.More(); exp.Next()) {
1983 TopoDS_Shape aSS = exp.Current();
1984 if (mapShape2.Add(aSS) && mapSelected.Contains(aSS)) {
1985 B.Add(aCompound, aSS);
1989 mapSelected.Clear();
1990 TopExp::MapShapes(aCompound, TopAbs_ShapeEnum(theShapeType), mapSelected);
1991 aCurrSelection = aCompound;
1994 // Create GEOM_Object for each found shared shape (collected in aCurrSelection)
1995 Handle(GEOM_Object) anObj;
1996 Handle(TColStd_HArray1OfInteger) anArray;
1997 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1998 TCollection_AsciiString anAsciiList, anEntry;
2000 TopoDS_Iterator itSel (aCurrSelection, Standard_True, Standard_True);
2001 for (; itSel.More(); itSel.Next()) {
2002 anArray = new TColStd_HArray1OfInteger(1,1);
2003 anArray->SetValue(1, anIndices.FindIndex(itSel.Value()));
2004 anObj = GetEngine()->AddSubShape(aMainObj, anArray);
2005 aSeq->Append(anObj);
2007 // for python command
2008 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
2009 anAsciiList += anEntry;
2013 if (aSeq->IsEmpty()) {
2014 SetErrorCode("The given shapes have no shared sub-shapes of the requested type");
2018 // Make a Python command
2019 anAsciiList.Trunc(anAsciiList.Length() - 1);
2021 GEOM::TPythonDump pd (aMainShape, /*append=*/true);
2022 pd << "[" << anAsciiList.ToCString()
2023 << "] = geompy.GetSharedShapesMulti([";
2025 it = theShapes.begin();
2027 while (it != theShapes.end()) {
2028 pd << ", " << (*it++);
2031 pd << "], " << TopAbs_ShapeEnum(theShapeType) << ")";
2037 //=============================================================================
2041 //=============================================================================
2042 static GEOM::TPythonDump& operator<< (GEOM::TPythonDump& theDump,
2043 const GEOMAlgo_State theState)
2046 case GEOMAlgo_ST_IN:
2047 theDump << "geompy.GEOM.ST_IN";
2049 case GEOMAlgo_ST_OUT:
2050 theDump << "geompy.GEOM.ST_OUT";
2052 case GEOMAlgo_ST_ON:
2053 theDump << "geompy.GEOM.ST_ON";
2055 case GEOMAlgo_ST_ONIN:
2056 theDump << "geompy.GEOM.ST_ONIN";
2058 case GEOMAlgo_ST_ONOUT:
2059 theDump << "geompy.GEOM.ST_ONOUT";
2062 theDump << "geompy.GEOM.ST_UNKNOWN";
2068 //=======================================================================
2069 //function : checkTypeShapesOn
2071 * \brief Checks if theShapeType parameter of GetShapesOnXXX() is OK
2072 * \param theShapeType - the shape type to check
2073 * \retval bool - result of the check
2075 //=======================================================================
2076 bool GEOMImpl_IShapesOperations::checkTypeShapesOn(const Standard_Integer theShapeType)
2078 if (theShapeType != TopAbs_VERTEX &&
2079 theShapeType != TopAbs_EDGE &&
2080 theShapeType != TopAbs_FACE &&
2081 theShapeType != TopAbs_SOLID) {
2082 SetErrorCode("Only solids, vertices, edges or faces can be found by this method");
2088 //=======================================================================
2089 //function : makePlane
2091 * \brief Creates Geom_Plane
2092 * \param theAx1 - shape object defining plane parameters
2093 * \retval Handle(Geom_Surface) - resulting surface
2095 //=======================================================================
2096 Handle(Geom_Surface) GEOMImpl_IShapesOperations::makePlane(const TopoDS_Shape& anAx1)
2098 if (anAx1.ShapeType() != TopAbs_EDGE) return NULL;
2099 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
2100 TopoDS_Vertex V1, V2;
2101 TopExp::Vertices(anEdge, V1, V2, Standard_True);
2102 if (V1.IsNull() || V2.IsNull()) {
2103 SetErrorCode("Bad edge given for the plane normal vector");
2106 gp_Pnt aLoc = BRep_Tool::Pnt(V1);
2107 gp_Vec aVec (aLoc, BRep_Tool::Pnt(V2));
2108 if (aVec.Magnitude() < Precision::Confusion()) {
2109 SetErrorCode("Vector with null magnitude given");
2112 return new Geom_Plane(aLoc, aVec);
2115 //=======================================================================
2116 //function : makeCylinder
2118 * \brief Creates Geom_CylindricalSurface
2119 * \param theAx1 - edge defining cylinder axis
2120 * \param theRadius - cylinder radius
2121 * \retval Handle(Geom_Surface) - resulting surface
2123 //=======================================================================
2124 Handle(Geom_Surface) GEOMImpl_IShapesOperations::makeCylinder(const TopoDS_Shape& anAxis,
2125 const Standard_Real theRadius)
2127 //Axis of the cylinder
2128 if (anAxis.ShapeType() != TopAbs_EDGE) {
2129 SetErrorCode("Not an edge given for the axis");
2132 TopoDS_Edge anEdge = TopoDS::Edge(anAxis);
2133 TopoDS_Vertex V1, V2;
2134 TopExp::Vertices(anEdge, V1, V2, Standard_True);
2135 if (V1.IsNull() || V2.IsNull()) {
2136 SetErrorCode("Bad edge given for the axis");
2139 gp_Pnt aLoc = BRep_Tool::Pnt(V1);
2140 gp_Vec aVec (aLoc, BRep_Tool::Pnt(V2));
2141 if (aVec.Magnitude() < Precision::Confusion()) {
2142 SetErrorCode("Vector with null magnitude given");
2146 gp_Ax3 anAx3 (aLoc, aVec);
2147 return new Geom_CylindricalSurface(anAx3, theRadius);
2150 //=======================================================================
2151 //function : getShapesOnBoxIDs
2153 * \brief Find IDs of subshapes complying with given status about surface
2154 * \param theBox - the box to check state of subshapes against
2155 * \param theShape - the shape to explore
2156 * \param theShapeType - type of subshape of theShape
2157 * \param theState - required state
2158 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
2160 //=======================================================================
2161 Handle(TColStd_HSequenceOfInteger)
2162 GEOMImpl_IShapesOperations::getShapesOnBoxIDs(const Handle(GEOM_Object)& theBox,
2163 const Handle(GEOM_Object)& theShape,
2164 const Standard_Integer theShapeType,
2165 GEOMAlgo_State theState)
2167 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
2169 TopoDS_Shape aBox = theBox->GetValue();
2170 TopoDS_Shape aShape = theShape->GetValue();
2172 // Check presence of triangulation, build if need
2173 if (!CheckTriangulation(aShape)) {
2174 SetErrorCode("Cannot build triangulation on the shape");
2179 GEOMAlgo_FinderShapeOn2 aFinder;
2180 Standard_Real aTol = 0.0001; // default value
2182 Handle(GEOMAlgo_ClsfBox) aClsfBox = new GEOMAlgo_ClsfBox;
2183 aClsfBox->SetBox(aBox);
2185 aFinder.SetShape(aShape);
2186 aFinder.SetTolerance(aTol);
2187 aFinder.SetClsf(aClsfBox);
2188 aFinder.SetShapeType( (TopAbs_ShapeEnum)theShapeType );
2189 aFinder.SetState(theState);
2192 // Interprete results
2193 Standard_Integer iErr = aFinder.ErrorStatus();
2194 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
2196 MESSAGE(" iErr : " << iErr);
2197 TCollection_AsciiString aMsg (" iErr : ");
2198 aMsg += TCollection_AsciiString(iErr);
2202 Standard_Integer iWrn = aFinder.WarningStatus();
2203 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
2205 MESSAGE(" *** iWrn : " << iWrn);
2208 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
2210 if (listSS.Extent() < 1) {
2211 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
2212 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
2216 // Fill sequence of object IDs
2217 aSeqOfIDs = new TColStd_HSequenceOfInteger;
2219 TopTools_IndexedMapOfShape anIndices;
2220 TopExp::MapShapes(aShape, anIndices);
2222 TopTools_ListIteratorOfListOfShape itSub (listSS);
2223 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
2224 int id = anIndices.FindIndex(itSub.Value());
2225 aSeqOfIDs->Append(id);
2231 //=======================================================================
2232 //function : GetShapesOnBoxIDs
2234 * \brief Find subshapes complying with given status about surface
2235 * \param theBox - the box to check state of subshapes against
2236 * \param theShape - the shape to explore
2237 * \param theShapeType - type of subshape of theShape
2238 * \param theState - required state
2239 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
2241 //=======================================================================
2242 Handle(TColStd_HSequenceOfInteger)
2243 GEOMImpl_IShapesOperations::GetShapesOnBoxIDs(const Handle(GEOM_Object)& theBox,
2244 const Handle(GEOM_Object)& theShape,
2245 const Standard_Integer theShapeType,
2246 GEOMAlgo_State theState)
2248 // Find subshapes ids
2249 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2250 getShapesOnBoxIDs (theBox, theShape, theShapeType, theState);
2251 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2254 // The GetShapesOnBox() doesn't change object so no new function is required.
2255 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theBox)->GetLastFunction();
2257 // Make a Python command
2258 GEOM::TPythonDump(aFunction)
2259 << "listShapesOnBoxIDs = geompy.GetShapesOnBoxIDs("
2262 << TopAbs_ShapeEnum(theShapeType) << ", "
2269 //=======================================================================
2270 //function : GetShapesOnBox
2272 * \brief Find subshapes complying with given status about surface
2273 * \param theBox - the box to check state of subshapes against
2274 * \param theShape - the shape to explore
2275 * \param theShapeType - type of subshape of theShape
2276 * \param theState - required state
2277 * \retval Handle(TColStd_HSequenceOfTransient) - found subshapes
2279 //=======================================================================
2280 Handle(TColStd_HSequenceOfTransient)
2281 GEOMImpl_IShapesOperations::GetShapesOnBox(const Handle(GEOM_Object)& theBox,
2282 const Handle(GEOM_Object)& theShape,
2283 const Standard_Integer theShapeType,
2284 GEOMAlgo_State theState)
2286 // Find subshapes ids
2287 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2288 getShapesOnBoxIDs (theBox, theShape, theShapeType, theState);
2289 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2292 // Find objects by indices
2293 TCollection_AsciiString anAsciiList;
2294 Handle(TColStd_HSequenceOfTransient) aSeq;
2295 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
2296 if ( aSeq.IsNull() || aSeq->IsEmpty() )
2299 // Make a Python command
2301 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2302 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2304 GEOM::TPythonDump(aFunction)
2305 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnBox("
2308 << TopAbs_ShapeEnum(theShapeType) << ", "
2315 //=======================================================================
2316 //function : getShapesOnShapeIDs
2318 * \brief Find IDs of subshapes complying with given status about surface
2319 * \param theCheckShape - the shape to check state of subshapes against
2320 * \param theShape - the shape to explore
2321 * \param theShapeType - type of subshape of theShape
2322 * \param theState - required state
2323 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
2325 //=======================================================================
2326 Handle(TColStd_HSequenceOfInteger)
2327 GEOMImpl_IShapesOperations::getShapesOnShapeIDs
2328 (const Handle(GEOM_Object)& theCheckShape,
2329 const Handle(GEOM_Object)& theShape,
2330 const Standard_Integer theShapeType,
2331 GEOMAlgo_State theState)
2333 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
2335 TopoDS_Shape aCheckShape = theCheckShape->GetValue();
2336 TopoDS_Shape aShape = theShape->GetValue();
2337 TopTools_ListOfShape res;
2339 // Check presence of triangulation, build if need
2340 if (!CheckTriangulation(aShape)) {
2341 SetErrorCode("Cannot build triangulation on the shape");
2346 GEOMAlgo_FinderShapeOn2 aFinder;
2347 Standard_Real aTol = 0.0001; // default value
2349 Handle(GEOMAlgo_ClsfSolid) aClsfSolid = new GEOMAlgo_ClsfSolid;
2350 aClsfSolid->SetShape(aCheckShape);
2352 aFinder.SetShape(aShape);
2353 aFinder.SetTolerance(aTol);
2354 aFinder.SetClsf(aClsfSolid);
2355 aFinder.SetShapeType( (TopAbs_ShapeEnum)theShapeType );
2356 aFinder.SetState(theState);
2359 // Interprete results
2360 Standard_Integer iErr = aFinder.ErrorStatus();
2361 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
2364 SetErrorCode("theCheckShape must be a solid");
2367 MESSAGE(" iErr : " << iErr);
2368 TCollection_AsciiString aMsg (" iErr : ");
2369 aMsg += TCollection_AsciiString(iErr);
2374 Standard_Integer iWrn = aFinder.WarningStatus();
2375 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
2377 MESSAGE(" *** iWrn : " << iWrn);
2380 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
2382 if (listSS.Extent() < 1) {
2383 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
2384 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
2387 // Fill sequence of object IDs
2388 aSeqOfIDs = new TColStd_HSequenceOfInteger;
2390 TopTools_IndexedMapOfShape anIndices;
2391 TopExp::MapShapes(aShape, anIndices);
2393 TopTools_ListIteratorOfListOfShape itSub (listSS);
2394 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
2395 int id = anIndices.FindIndex(itSub.Value());
2396 aSeqOfIDs->Append(id);
2402 //=======================================================================
2403 //function : GetShapesOnShapeIDs
2405 * \brief Find subshapes complying with given status about surface
2406 * \param theCheckShape - the shape to check state of subshapes against
2407 * \param theShape - the shape to explore
2408 * \param theShapeType - type of subshape of theShape
2409 * \param theState - required state
2410 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
2412 //=======================================================================
2413 Handle(TColStd_HSequenceOfInteger)
2414 GEOMImpl_IShapesOperations::GetShapesOnShapeIDs
2415 (const Handle(GEOM_Object)& theCheckShape,
2416 const Handle(GEOM_Object)& theShape,
2417 const Standard_Integer theShapeType,
2418 GEOMAlgo_State theState)
2420 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2421 getShapesOnShapeIDs (theCheckShape, theShape, theShapeType, theState);
2423 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2426 // The GetShapesOnShape() doesn't change object so no new function is required.
2427 Handle(GEOM_Function) aFunction =
2428 GEOM::GetCreatedLast(theShape,theCheckShape)->GetLastFunction();
2430 // Make a Python command
2431 GEOM::TPythonDump(aFunction)
2432 << "listShapesOnBoxIDs = geompy.GetShapesOnShapeIDs("
2433 << theCheckShape << ", "
2435 << TopAbs_ShapeEnum(theShapeType) << ", "
2442 //=======================================================================
2443 //function : GetShapesOnShape
2445 * \brief Find subshapes complying with given status about surface
2446 * \param theCheckShape - the shape to check state of subshapes against
2447 * \param theShape - the shape to explore
2448 * \param theShapeType - type of subshape of theShape
2449 * \param theState - required state
2450 * \retval Handle(TColStd_HSequenceOfTransient) - found subshapes
2452 //=======================================================================
2453 Handle(TColStd_HSequenceOfTransient)
2454 GEOMImpl_IShapesOperations::GetShapesOnShape
2455 (const Handle(GEOM_Object)& theCheckShape,
2456 const Handle(GEOM_Object)& theShape,
2457 const Standard_Integer theShapeType,
2458 GEOMAlgo_State theState)
2460 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2461 getShapesOnShapeIDs (theCheckShape, theShape, theShapeType, theState);
2462 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2465 // Find objects by indices
2466 TCollection_AsciiString anAsciiList;
2467 Handle(TColStd_HSequenceOfTransient) aSeq;
2468 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
2470 if ( aSeq.IsNull() || aSeq->IsEmpty() )
2473 // Make a Python command
2475 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2476 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2478 GEOM::TPythonDump(aFunction)
2479 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnShape("
2480 << theCheckShape << ", "
2482 << TopAbs_ShapeEnum(theShapeType) << ", "
2489 //=======================================================================
2490 //function : GetShapesOnShapeAsCompound
2491 //=======================================================================
2492 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetShapesOnShapeAsCompound
2493 (const Handle(GEOM_Object)& theCheckShape,
2494 const Handle(GEOM_Object)& theShape,
2495 const Standard_Integer theShapeType,
2496 GEOMAlgo_State theState)
2498 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2499 getShapesOnShapeIDs (theCheckShape, theShape, theShapeType, theState);
2501 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2504 // Find objects by indices
2505 TCollection_AsciiString anAsciiList;
2506 Handle(TColStd_HSequenceOfTransient) aSeq;
2507 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
2509 if ( aSeq.IsNull() || aSeq->IsEmpty() )
2512 TopoDS_Compound aCompound;
2514 B.MakeCompound(aCompound);
2516 for(; i<=aSeq->Length(); i++) {
2517 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(aSeq->Value(i));
2518 TopoDS_Shape aShape_i = anObj->GetValue();
2519 B.Add(aCompound,aShape_i);
2522 //Add a new result object
2523 Handle(GEOM_Object) aRes = GetEngine()->AddObject(GetDocID(), GEOM_SHAPES_ON_SHAPE);
2524 Handle(GEOM_Function) aFunction =
2525 aRes->AddFunction(GEOMImpl_ShapeDriver::GetID(), SHAPES_ON_SHAPE);
2526 aFunction->SetValue(aCompound);
2528 GEOM::TPythonDump(aFunction)
2529 << aRes << " = geompy.GetShapesOnShapeAsCompound("
2530 << theCheckShape << ", "
2532 << TopAbs_ShapeEnum(theShapeType) << ", "
2540 //=======================================================================
2541 //function : getShapesOnSurfaceIDs
2543 * \brief Find IDs of subshapes complying with given status about surface
2544 * \param theSurface - the surface to check state of subshapes against
2545 * \param theShape - the shape to explore
2546 * \param theShapeType - type of subshape of theShape
2547 * \param theState - required state
2548 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
2550 //=======================================================================
2551 Handle(TColStd_HSequenceOfInteger)
2552 GEOMImpl_IShapesOperations::getShapesOnSurfaceIDs(const Handle(Geom_Surface)& theSurface,
2553 const TopoDS_Shape& theShape,
2554 TopAbs_ShapeEnum theShapeType,
2555 GEOMAlgo_State theState)
2557 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
2559 // Check presence of triangulation, build if need
2560 if (!CheckTriangulation(theShape)) {
2561 SetErrorCode("Cannot build triangulation on the shape");
2565 // BEGIN: Mantis issue 0020961: Error on a pipe T-Shape
2566 // Compute tolerance
2567 Standard_Real T, VertMax = -RealLast();
2569 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
2572 for (TopExp_Explorer ExV (theShape, TopAbs_VERTEX); ExV.More(); ExV.Next()) {
2573 TopoDS_Vertex Vertex = TopoDS::Vertex(ExV.Current());
2574 T = BRep_Tool::Tolerance(Vertex);
2579 catch (Standard_Failure) {
2580 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2581 SetErrorCode(aFail->GetMessageString());
2584 // END: Mantis issue 0020961
2587 GEOMAlgo_FinderShapeOn1 aFinder;
2588 //Standard_Real aTol = 0.0001; // default value
2589 Standard_Real aTol = VertMax; // Mantis issue 0020961
2591 aFinder.SetShape(theShape);
2592 aFinder.SetTolerance(aTol);
2593 aFinder.SetSurface(theSurface);
2594 aFinder.SetShapeType(theShapeType);
2595 aFinder.SetState(theState);
2597 // Sets the minimal number of inner points for the faces that do not have own
2598 // inner points at all (for e.g. rectangular planar faces have just 2 triangles).
2600 aFinder.SetNbPntsMin(3);
2601 // Sets the maximal number of inner points for edges or faces.
2602 // It is usefull for the cases when this number is very big (e.g =2000) to improve
2603 // the performance. If this value =0, all inner points will be taken into account.
2605 aFinder.SetNbPntsMax(100);
2609 // Interprete results
2610 Standard_Integer iErr = aFinder.ErrorStatus();
2611 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
2613 MESSAGE(" iErr : " << iErr);
2614 TCollection_AsciiString aMsg (" iErr : ");
2615 aMsg += TCollection_AsciiString(iErr);
2619 Standard_Integer iWrn = aFinder.WarningStatus();
2620 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
2622 MESSAGE(" *** iWrn : " << iWrn);
2625 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
2627 if (listSS.Extent() < 1) {
2628 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
2629 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
2633 // Fill sequence of object IDs
2634 aSeqOfIDs = new TColStd_HSequenceOfInteger;
2636 TopTools_IndexedMapOfShape anIndices;
2637 TopExp::MapShapes(theShape, anIndices);
2639 TopTools_ListIteratorOfListOfShape itSub (listSS);
2640 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
2641 int id = anIndices.FindIndex(itSub.Value());
2642 aSeqOfIDs->Append(id);
2648 //=======================================================================
2649 //function : getObjectsShapesOn
2651 * \brief Find shape objects and their entries by their ids
2652 * \param theShapeIDs - incoming shape ids
2653 * \param theShapeEntries - outgoing entries like "entry1, entry2, ..."
2654 * \retval Handle(TColStd_HSequenceOfTransient) - found shape objects
2656 //=======================================================================
2657 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::
2658 getObjectsShapesOn(const Handle(GEOM_Object)& theShape,
2659 const Handle(TColStd_HSequenceOfInteger)& theShapeIDs,
2660 TCollection_AsciiString & theShapeEntries)
2662 Handle(TColStd_HSequenceOfTransient) aSeq;
2664 if ( !theShapeIDs.IsNull() && theShapeIDs->Length() > 0 )
2666 aSeq = new TColStd_HSequenceOfTransient;
2667 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
2668 TCollection_AsciiString anEntry;
2669 for ( int i = 1; i <= theShapeIDs->Length(); ++i )
2671 anArray->SetValue(1, theShapeIDs->Value( i ));
2672 Handle(GEOM_Object) anObj = GetEngine()->AddSubShape(theShape, anArray);
2673 aSeq->Append( anObj );
2675 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
2676 if ( i != 1 ) theShapeEntries += ",";
2677 theShapeEntries += anEntry;
2683 //=======================================================================
2684 //function : getShapesOnSurface
2686 * \brief Find subshapes complying with given status about surface
2687 * \param theSurface - the surface to check state of subshapes against
2688 * \param theShape - the shape to explore
2689 * \param theShapeType - type of subshape of theShape
2690 * \param theState - required state
2691 * \param theShapeEntries - outgoing entries like "entry1, entry2, ..."
2692 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
2694 //=======================================================================
2695 Handle(TColStd_HSequenceOfTransient)
2696 GEOMImpl_IShapesOperations::getShapesOnSurface(const Handle(Geom_Surface)& theSurface,
2697 const Handle(GEOM_Object)& theShape,
2698 TopAbs_ShapeEnum theShapeType,
2699 GEOMAlgo_State theState,
2700 TCollection_AsciiString & theShapeEntries)
2702 // Find subshapes ids
2703 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2704 getShapesOnSurfaceIDs (theSurface, theShape->GetValue(), theShapeType, theState);
2705 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2708 return getObjectsShapesOn( theShape, aSeqOfIDs, theShapeEntries );
2711 //=============================================================================
2715 //=============================================================================
2716 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnPlane
2717 (const Handle(GEOM_Object)& theShape,
2718 const Standard_Integer theShapeType,
2719 const Handle(GEOM_Object)& theAx1,
2720 const GEOMAlgo_State theState)
2724 if (theShape.IsNull() || theAx1.IsNull()) return NULL;
2726 TopoDS_Shape aShape = theShape->GetValue();
2727 TopoDS_Shape anAx1 = theAx1->GetValue();
2729 if (aShape.IsNull() || anAx1.IsNull()) return NULL;
2731 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2732 if ( !checkTypeShapesOn( theShapeType ))
2736 Handle(Geom_Surface) aPlane = makePlane( anAx1 );
2737 if ( aPlane.IsNull() )
2741 TCollection_AsciiString anAsciiList;
2742 Handle(TColStd_HSequenceOfTransient) aSeq;
2743 aSeq = getShapesOnSurface( aPlane, theShape, aShapeType, theState, anAsciiList );
2744 if ( aSeq.IsNull() || aSeq->Length() == 0 )
2747 // Make a Python command
2749 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2750 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2752 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
2753 << "] = geompy.GetShapesOnPlane(" << theShape << ", "
2754 << aShapeType << ", " << theAx1 << ", " << theState << ")";
2760 //=============================================================================
2762 * GetShapesOnPlaneWithLocation
2764 //=============================================================================
2765 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnPlaneWithLocation
2766 (const Handle(GEOM_Object)& theShape,
2767 const Standard_Integer theShapeType,
2768 const Handle(GEOM_Object)& theAx1,
2769 const Handle(GEOM_Object)& thePnt,
2770 const GEOMAlgo_State theState)
2774 if (theShape.IsNull() || theAx1.IsNull() || thePnt.IsNull()) return NULL;
2776 TopoDS_Shape aShape = theShape->GetValue();
2777 TopoDS_Shape anAx1 = theAx1->GetValue();
2778 TopoDS_Shape anPnt = thePnt->GetValue();
2780 if (aShape.IsNull() || anAx1.IsNull() || anPnt.IsNull()) return NULL;
2782 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2783 if ( !checkTypeShapesOn( theShapeType ))
2787 if ( anAx1.ShapeType() != TopAbs_EDGE || anPnt.ShapeType() != TopAbs_VERTEX ) return NULL;
2788 TopoDS_Vertex V1, V2, V3;
2789 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
2790 TopExp::Vertices(anEdge, V1, V2, Standard_True);
2792 if (V1.IsNull() || V2.IsNull()) {
2793 SetErrorCode("Bad edge given for the plane normal vector");
2796 V3 = TopoDS::Vertex(anPnt);
2799 SetErrorCode("Bad vertex given for the plane location");
2802 gp_Pnt aLoc = BRep_Tool::Pnt(V3);
2803 gp_Vec aVec(BRep_Tool::Pnt(V1),BRep_Tool::Pnt(V2));
2805 if (aVec.Magnitude() < Precision::Confusion()) {
2806 SetErrorCode("Vector with null magnitude given");
2809 Handle(Geom_Surface) aPlane = new Geom_Plane(aLoc, aVec);
2811 if ( aPlane.IsNull() )
2815 TCollection_AsciiString anAsciiList;
2816 Handle(TColStd_HSequenceOfTransient) aSeq;
2817 aSeq = getShapesOnSurface( aPlane, theShape, aShapeType, theState, anAsciiList );
2818 if ( aSeq.IsNull() || aSeq->Length() == 0 )
2821 // Make a Python command
2823 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2824 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2826 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
2827 << "] = geompy.GetShapesOnPlaneWithLocation(" << theShape << ", "
2828 << aShapeType << ", " << theAx1 << ", "<< thePnt <<", " << theState << ")";
2834 //=============================================================================
2836 * GetShapesOnCylinder
2838 //=============================================================================
2839 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnCylinder
2840 (const Handle(GEOM_Object)& theShape,
2841 const Standard_Integer theShapeType,
2842 const Handle(GEOM_Object)& theAxis,
2843 const Standard_Real theRadius,
2844 const GEOMAlgo_State theState)
2848 if (theShape.IsNull() || theAxis.IsNull()) return NULL;
2850 TopoDS_Shape aShape = theShape->GetValue();
2851 TopoDS_Shape anAxis = theAxis->GetValue();
2853 if (aShape.IsNull() || anAxis.IsNull()) return NULL;
2855 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2856 if ( !checkTypeShapesOn( aShapeType ))
2859 // Create a cylinder surface
2860 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
2861 if ( aCylinder.IsNull() )
2865 TCollection_AsciiString anAsciiList;
2866 Handle(TColStd_HSequenceOfTransient) aSeq;
2867 aSeq = getShapesOnSurface( aCylinder, theShape, aShapeType, theState, anAsciiList );
2868 if ( aSeq.IsNull() || aSeq->Length() == 0 )
2871 // Make a Python command
2873 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2874 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2876 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
2877 << "] = geompy.GetShapesOnCylinder(" << theShape << ", " << aShapeType
2878 << ", " << theAxis << ", " << theRadius << ", " << theState << ")";
2884 //=============================================================================
2886 * GetShapesOnCylinderWithLocation
2888 //=============================================================================
2889 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnCylinderWithLocation
2890 (const Handle(GEOM_Object)& theShape,
2891 const Standard_Integer theShapeType,
2892 const Handle(GEOM_Object)& theAxis,
2893 const Handle(GEOM_Object)& thePnt,
2894 const Standard_Real theRadius,
2895 const GEOMAlgo_State theState)
2899 if (theShape.IsNull() || theAxis.IsNull() || thePnt.IsNull()) return NULL;
2901 TopoDS_Shape aShape = theShape->GetValue();
2902 TopoDS_Shape anAxis = theAxis->GetValue();
2903 TopoDS_Shape aPnt = thePnt->GetValue();
2905 if (aShape.IsNull() || anAxis.IsNull() || aPnt.IsNull()) return NULL;
2907 if (aPnt.ShapeType() != TopAbs_VERTEX )
2909 SetErrorCode("Bottom location point must be vertex");
2913 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2914 if ( !checkTypeShapesOn( aShapeType ))
2917 // Create a cylinder surface
2918 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
2919 if ( aCylinder.IsNull() )
2922 // translate the surface
2923 Handle(Geom_CylindricalSurface) aCylSurface =
2924 Handle(Geom_CylindricalSurface)::DownCast( aCylinder );
2925 if ( aCylSurface.IsNull() )
2927 SetErrorCode("Unexpected surface type instead of Geom_CylindricalSurface");
2930 gp_Pnt fromLoc = aCylSurface->Cylinder().Location();
2931 gp_Pnt toLoc = BRep_Tool::Pnt( TopoDS::Vertex( aPnt ));
2932 aCylinder->Translate( fromLoc, toLoc );
2935 TCollection_AsciiString anAsciiList;
2936 Handle(TColStd_HSequenceOfTransient) aSeq;
2937 aSeq = getShapesOnSurface( aCylinder, theShape, aShapeType, theState, anAsciiList );
2938 if ( aSeq.IsNull() || aSeq->Length() == 0 )
2941 // Make a Python command
2943 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2944 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2946 GEOM::TPythonDump(aFunction)
2947 << "[" << anAsciiList.ToCString()
2948 << "] = geompy.GetShapesOnCylinderWithLocation(" << theShape << ", " << aShapeType << ", "
2949 << theAxis << ", " << thePnt << ", " << theRadius << ", " << theState << ")";
2955 //=============================================================================
2959 //=============================================================================
2960 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnSphere
2961 (const Handle(GEOM_Object)& theShape,
2962 const Standard_Integer theShapeType,
2963 const Handle(GEOM_Object)& theCenter,
2964 const Standard_Real theRadius,
2965 const GEOMAlgo_State theState)
2969 if (theShape.IsNull() || theCenter.IsNull()) return NULL;
2971 TopoDS_Shape aShape = theShape->GetValue();
2972 TopoDS_Shape aCenter = theCenter->GetValue();
2974 if (aShape.IsNull() || aCenter.IsNull()) return NULL;
2976 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2977 if ( !checkTypeShapesOn( aShapeType ))
2980 // Center of the sphere
2981 if (aCenter.ShapeType() != TopAbs_VERTEX) return NULL;
2982 gp_Pnt aLoc = BRep_Tool::Pnt(TopoDS::Vertex(aCenter));
2984 gp_Ax3 anAx3 (aLoc, gp::DZ());
2985 Handle(Geom_SphericalSurface) aSphere =
2986 new Geom_SphericalSurface(anAx3, theRadius);
2989 TCollection_AsciiString anAsciiList;
2990 Handle(TColStd_HSequenceOfTransient) aSeq;
2991 aSeq = getShapesOnSurface( aSphere, theShape, aShapeType, theState, anAsciiList );
2992 if ( aSeq.IsNull() || aSeq->Length() == 0 )
2995 // Make a Python command
2997 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2998 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
3000 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
3001 << "] = geompy.GetShapesOnSphere(" << theShape << ", " << aShapeType
3002 << ", " << theCenter << ", " << theRadius << ", " << theState << ")";
3008 //=============================================================================
3010 * GetShapesOnPlaneIDs
3012 //=============================================================================
3013 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnPlaneIDs
3014 (const Handle(GEOM_Object)& theShape,
3015 const Standard_Integer theShapeType,
3016 const Handle(GEOM_Object)& theAx1,
3017 const GEOMAlgo_State theState)
3021 if (theShape.IsNull() || theAx1.IsNull()) return NULL;
3023 TopoDS_Shape aShape = theShape->GetValue();
3024 TopoDS_Shape anAx1 = theAx1->GetValue();
3026 if (aShape.IsNull() || anAx1.IsNull()) return NULL;
3028 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3029 if ( !checkTypeShapesOn( aShapeType ))
3033 Handle(Geom_Surface) aPlane = makePlane( anAx1 );
3034 if ( aPlane.IsNull() )
3038 Handle(TColStd_HSequenceOfInteger) aSeq;
3039 aSeq = getShapesOnSurfaceIDs( aPlane, aShape, aShapeType, theState );
3041 // The GetShapesOnPlaneIDs() doesn't change object so no new function is required.
3042 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAx1)->GetLastFunction();
3044 // Make a Python command
3045 GEOM::TPythonDump(aFunction, /*append=*/true)
3046 << "listShapesOnPlane = geompy.GetShapesOnPlaneIDs"
3047 << "(" << theShape << "," << aShapeType << "," << theAx1 << "," << theState << ")";
3053 //=============================================================================
3055 * GetShapesOnPlaneWithLocationIDs
3057 //=============================================================================
3058 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnPlaneWithLocationIDs
3059 (const Handle(GEOM_Object)& theShape,
3060 const Standard_Integer theShapeType,
3061 const Handle(GEOM_Object)& theAx1,
3062 const Handle(GEOM_Object)& thePnt,
3063 const GEOMAlgo_State theState)
3067 if (theShape.IsNull() || theAx1.IsNull() || thePnt.IsNull()) return NULL;
3069 TopoDS_Shape aShape = theShape->GetValue();
3070 TopoDS_Shape anAx1 = theAx1->GetValue();
3071 TopoDS_Shape anPnt = thePnt->GetValue();
3073 if (aShape.IsNull() || anAx1.IsNull() || anPnt.IsNull()) return NULL;
3075 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3076 if ( !checkTypeShapesOn( aShapeType ))
3080 if (anAx1.ShapeType() != TopAbs_EDGE || anPnt.ShapeType() != TopAbs_VERTEX) return NULL;
3081 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
3082 TopoDS_Vertex V1, V2, V3;
3083 TopExp::Vertices(anEdge, V1, V2, Standard_True);
3084 if (V1.IsNull() || V2.IsNull()) {
3085 SetErrorCode("Bad edge given for the plane normal vector");
3088 V3 = TopoDS::Vertex(anPnt);
3090 SetErrorCode("Bad vertex given for the plane location");
3093 gp_Pnt aLoc = BRep_Tool::Pnt(V3);
3094 gp_Vec aVec(BRep_Tool::Pnt(V1),BRep_Tool::Pnt(V2));
3095 if (aVec.Magnitude() < Precision::Confusion()) {
3096 SetErrorCode("Vector with null magnitude given");
3100 Handle(Geom_Surface) aPlane = new Geom_Plane(aLoc, aVec);
3101 if ( aPlane.IsNull() )
3105 Handle(TColStd_HSequenceOfInteger) aSeq;
3106 aSeq = getShapesOnSurfaceIDs( aPlane, aShape, aShapeType, theState );
3108 // The GetShapesOnPlaneIDs() doesn't change object so no new function is required.
3109 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAx1)->GetLastFunction();
3111 // Make a Python command
3112 GEOM::TPythonDump(aFunction, /*append=*/true)
3113 << "listShapesOnPlane = geompy.GetShapesOnPlaneWithLocationIDs"
3114 << "(" << theShape << ", " << aShapeType << ", " << theAx1 << ", "<< thePnt << ", " << theState << ")";
3120 //=============================================================================
3122 * GetShapesOnCylinderIDs
3124 //=============================================================================
3125 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnCylinderIDs
3126 (const Handle(GEOM_Object)& theShape,
3127 const Standard_Integer theShapeType,
3128 const Handle(GEOM_Object)& theAxis,
3129 const Standard_Real theRadius,
3130 const GEOMAlgo_State theState)
3134 if (theShape.IsNull() || theAxis.IsNull()) return NULL;
3136 TopoDS_Shape aShape = theShape->GetValue();
3137 TopoDS_Shape anAxis = theAxis->GetValue();
3139 if (aShape.IsNull() || anAxis.IsNull()) return NULL;
3141 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3142 if ( !checkTypeShapesOn( aShapeType ))
3145 // Create a cylinder surface
3146 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
3147 if ( aCylinder.IsNull() )
3151 Handle(TColStd_HSequenceOfInteger) aSeq;
3152 aSeq = getShapesOnSurfaceIDs( aCylinder, aShape, aShapeType, theState );
3154 // The GetShapesOnCylinder() doesn't change object so no new function is required.
3155 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAxis)->GetLastFunction();
3157 // Make a Python command
3158 GEOM::TPythonDump(aFunction, /*append=*/true)
3159 << "listShapesOnCylinder = geompy.GetShapesOnCylinderIDs"
3160 << "(" << theShape << ", " << aShapeType << ", " << theAxis << ", "
3161 << theRadius << ", " << theState << ")";
3167 //=============================================================================
3169 * GetShapesOnCylinderWithLocationIDs
3171 //=============================================================================
3172 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnCylinderWithLocationIDs
3173 (const Handle(GEOM_Object)& theShape,
3174 const Standard_Integer theShapeType,
3175 const Handle(GEOM_Object)& theAxis,
3176 const Handle(GEOM_Object)& thePnt,
3177 const Standard_Real theRadius,
3178 const GEOMAlgo_State theState)
3182 if (theShape.IsNull() || theAxis.IsNull() || thePnt.IsNull()) return NULL;
3184 TopoDS_Shape aShape = theShape->GetValue();
3185 TopoDS_Shape anAxis = theAxis->GetValue();
3186 TopoDS_Shape aPnt = thePnt->GetValue();
3188 if (aShape.IsNull() || anAxis.IsNull() || aPnt.IsNull()) return NULL;
3190 if (aPnt.ShapeType() != TopAbs_VERTEX )
3192 SetErrorCode("Bottom location point must be vertex");
3196 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3197 if ( !checkTypeShapesOn( aShapeType ))
3200 // Create a cylinder surface
3201 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
3202 if ( aCylinder.IsNull() )
3205 // translate the surface
3206 Handle(Geom_CylindricalSurface) aCylSurface =
3207 Handle(Geom_CylindricalSurface)::DownCast( aCylinder );
3208 if ( aCylSurface.IsNull() )
3210 SetErrorCode("Unexpected surface type instead of Geom_CylindricalSurface");
3213 gp_Pnt fromLoc = aCylSurface->Cylinder().Location();
3214 gp_Pnt toLoc = BRep_Tool::Pnt( TopoDS::Vertex( aPnt ));
3215 aCylinder->Translate( fromLoc, toLoc );
3218 Handle(TColStd_HSequenceOfInteger) aSeq;
3219 aSeq = getShapesOnSurfaceIDs( aCylinder, aShape, aShapeType, theState );
3221 // The GetShapesOnCylinder() doesn't change object so no new function is required.
3222 Handle(GEOM_Function) aFunction =
3223 GEOM::GetCreatedLast(theShape, GEOM::GetCreatedLast(thePnt,theAxis))->GetLastFunction();
3225 // Make a Python command
3226 GEOM::TPythonDump(aFunction, /*append=*/true)
3227 << "listShapesOnCylinder = geompy.GetShapesOnCylinderWithLocationIDs"
3228 << "(" << theShape << ", " << aShapeType << ", " << theAxis << ", "
3229 << thePnt << ", " << theRadius << ", " << theState << ")";
3235 //=============================================================================
3237 * GetShapesOnSphereIDs
3239 //=============================================================================
3240 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnSphereIDs
3241 (const Handle(GEOM_Object)& theShape,
3242 const Standard_Integer theShapeType,
3243 const Handle(GEOM_Object)& theCenter,
3244 const Standard_Real theRadius,
3245 const GEOMAlgo_State theState)
3249 if (theShape.IsNull() || theCenter.IsNull()) return NULL;
3251 TopoDS_Shape aShape = theShape->GetValue();
3252 TopoDS_Shape aCenter = theCenter->GetValue();
3254 if (aShape.IsNull() || aCenter.IsNull()) return NULL;
3256 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3257 if ( !checkTypeShapesOn( aShapeType ))
3260 // Center of the sphere
3261 if (aCenter.ShapeType() != TopAbs_VERTEX) return NULL;
3262 gp_Pnt aLoc = BRep_Tool::Pnt(TopoDS::Vertex(aCenter));
3264 gp_Ax3 anAx3 (aLoc, gp::DZ());
3265 Handle(Geom_SphericalSurface) aSphere =
3266 new Geom_SphericalSurface(anAx3, theRadius);
3269 Handle(TColStd_HSequenceOfInteger) aSeq;
3270 aSeq = getShapesOnSurfaceIDs( aSphere, aShape, aShapeType, theState );
3272 // The GetShapesOnSphere() doesn't change object so no new function is required.
3273 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theCenter)->GetLastFunction();
3275 // Make a Python command
3276 GEOM::TPythonDump(aFunction, /*append=*/true)
3277 << "listShapesOnCylinder = geompy.GetShapesOnCylinderIDs"
3278 << "(" << theShape << ", " << aShapeType << ", " << theCenter << ", "
3279 << theRadius << ", " << theState << ")";
3285 //=======================================================================
3286 //function : getShapesOnQuadrangleIDs
3288 * \brief Find IDs of subshapes complying with given status about quadrangle
3289 * \param theShape - the shape to explore
3290 * \param theShapeType - type of subshape of theShape
3291 * \param theTopLeftPoint - top left quadrangle corner
3292 * \param theTopRigthPoint - top right quadrangle corner
3293 * \param theBottomLeftPoint - bottom left quadrangle corner
3294 * \param theBottomRigthPoint - bottom right quadrangle corner
3295 * \param theState - required state
3296 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
3298 //=======================================================================
3299 Handle(TColStd_HSequenceOfInteger)
3300 GEOMImpl_IShapesOperations::getShapesOnQuadrangleIDs (const Handle(GEOM_Object)& theShape,
3301 const Standard_Integer theShapeType,
3302 const Handle(GEOM_Object)& theTopLeftPoint,
3303 const Handle(GEOM_Object)& theTopRigthPoint,
3304 const Handle(GEOM_Object)& theBottomLeftPoint,
3305 const Handle(GEOM_Object)& theBottomRigthPoint,
3306 const GEOMAlgo_State theState)
3310 if ( theShape.IsNull() ||
3311 theTopLeftPoint.IsNull() ||
3312 theTopRigthPoint.IsNull() ||
3313 theBottomLeftPoint.IsNull() ||
3314 theBottomRigthPoint.IsNull() )
3317 TopoDS_Shape aShape = theShape->GetValue();
3318 TopoDS_Shape aTL = theTopLeftPoint->GetValue();
3319 TopoDS_Shape aTR = theTopRigthPoint->GetValue();
3320 TopoDS_Shape aBL = theBottomLeftPoint->GetValue();
3321 TopoDS_Shape aBR = theBottomRigthPoint->GetValue();
3323 if (aShape.IsNull() ||
3328 aTL.ShapeType() != TopAbs_VERTEX ||
3329 aTR.ShapeType() != TopAbs_VERTEX ||
3330 aBL.ShapeType() != TopAbs_VERTEX ||
3331 aBR.ShapeType() != TopAbs_VERTEX )
3334 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3335 if ( !checkTypeShapesOn( aShapeType ))
3338 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
3340 // Check presence of triangulation, build if need
3341 if (!CheckTriangulation(aShape)) {
3342 SetErrorCode("Cannot build triangulation on the shape");
3347 gp_Pnt aPntTL = BRep_Tool::Pnt(TopoDS::Vertex(aTL));
3348 gp_Pnt aPntTR = BRep_Tool::Pnt(TopoDS::Vertex(aTR));
3349 gp_Pnt aPntBL = BRep_Tool::Pnt(TopoDS::Vertex(aBL));
3350 gp_Pnt aPntBR = BRep_Tool::Pnt(TopoDS::Vertex(aBR));
3352 GEOMAlgo_FinderShapeOnQuad aFinder( aPntTL, aPntTR, aPntBL, aPntBR );
3353 Standard_Real aTol = 0.0001; // default value
3355 aFinder.SetShape(aShape);
3356 aFinder.SetTolerance(aTol);
3357 //aFinder.SetSurface(theSurface);
3358 aFinder.SetShapeType(aShapeType);
3359 aFinder.SetState(theState);
3361 // Sets the minimal number of inner points for the faces that do not have own
3362 // inner points at all (for e.g. rectangular planar faces have just 2 triangles).
3364 aFinder.SetNbPntsMin(3);
3365 // Sets the maximal number of inner points for edges or faces.
3366 // It is usefull for the cases when this number is very big (e.g =2000) to improve
3367 // the performance. If this value =0, all inner points will be taken into account.
3369 aFinder.SetNbPntsMax(100);
3373 // Interprete results
3374 Standard_Integer iErr = aFinder.ErrorStatus();
3375 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
3377 MESSAGE(" iErr : " << iErr);
3378 TCollection_AsciiString aMsg (" iErr : ");
3379 aMsg += TCollection_AsciiString(iErr);
3383 Standard_Integer iWrn = aFinder.WarningStatus();
3384 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
3386 MESSAGE(" *** iWrn : " << iWrn);
3389 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
3391 if (listSS.Extent() < 1) {
3392 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
3393 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
3397 // Fill sequence of object IDs
3398 aSeqOfIDs = new TColStd_HSequenceOfInteger;
3400 TopTools_IndexedMapOfShape anIndices;
3401 TopExp::MapShapes(aShape, anIndices);
3403 TopTools_ListIteratorOfListOfShape itSub (listSS);
3404 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
3405 int id = anIndices.FindIndex(itSub.Value());
3406 aSeqOfIDs->Append(id);
3411 //=======================================================================
3412 //function : GetShapesOnQuadrangle
3414 * \brief Find subshapes complying with given status about quadrangle
3415 * \param theShape - the shape to explore
3416 * \param theShapeType - type of subshape of theShape
3417 * \param theTopLeftPoint - top left quadrangle corner
3418 * \param theTopRigthPoint - top right quadrangle corner
3419 * \param theBottomLeftPoint - bottom left quadrangle corner
3420 * \param theBottomRigthPoint - bottom right quadrangle corner
3421 * \param theState - required state
3422 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
3424 //=======================================================================
3425 Handle(TColStd_HSequenceOfTransient)
3426 GEOMImpl_IShapesOperations::GetShapesOnQuadrangle (const Handle(GEOM_Object)& theShape,
3427 const Standard_Integer theShapeType,
3428 const Handle(GEOM_Object)& theTopLeftPoint,
3429 const Handle(GEOM_Object)& theTopRigthPoint,
3430 const Handle(GEOM_Object)& theBottomLeftPoint,
3431 const Handle(GEOM_Object)& theBottomRigthPoint,
3432 const GEOMAlgo_State theState)
3435 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
3436 getShapesOnQuadrangleIDs( theShape,
3441 theBottomRigthPoint,
3443 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->IsEmpty() )
3446 // Find objects by indices
3447 TCollection_AsciiString anAsciiList;
3448 Handle(TColStd_HSequenceOfTransient) aSeq;
3449 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
3450 if ( aSeq.IsNull() || aSeq->IsEmpty() )
3453 // Make a Python command
3455 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
3456 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
3458 GEOM::TPythonDump(aFunction)
3459 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnQuadrangle("
3461 << TopAbs_ShapeEnum(theShapeType) << ", "
3462 << theTopLeftPoint << ", "
3463 << theTopRigthPoint << ", "
3464 << theBottomLeftPoint << ", "
3465 << theBottomRigthPoint << ", "
3472 //=======================================================================
3473 //function : GetShapesOnQuadrangleIDs
3475 * \brief Find IDs of subshapes complying with given status about quadrangle
3476 * \param theShape - the shape to explore
3477 * \param theShapeType - type of subshape of theShape
3478 * \param theTopLeftPoint - top left quadrangle corner
3479 * \param theTopRigthPoint - top right quadrangle corner
3480 * \param theBottomLeftPoint - bottom left quadrangle corner
3481 * \param theBottomRigthPoint - bottom right quadrangle corner
3482 * \param theState - required state
3483 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
3485 //=======================================================================
3486 Handle(TColStd_HSequenceOfInteger)
3487 GEOMImpl_IShapesOperations::GetShapesOnQuadrangleIDs (const Handle(GEOM_Object)& theShape,
3488 const Standard_Integer theShapeType,
3489 const Handle(GEOM_Object)& theTopLeftPoint,
3490 const Handle(GEOM_Object)& theTopRigthPoint,
3491 const Handle(GEOM_Object)& theBottomLeftPoint,
3492 const Handle(GEOM_Object)& theBottomRigthPoint,
3493 const GEOMAlgo_State theState)
3496 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
3497 getShapesOnQuadrangleIDs( theShape,
3502 theBottomRigthPoint,
3504 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->IsEmpty() )
3507 // Make a Python command
3509 // The GetShapesOnCylinder() doesn't change object so no new function is required.
3510 Handle(GEOM_Object) lastObj = GEOM::GetCreatedLast(theShape,theTopLeftPoint);
3511 lastObj = GEOM::GetCreatedLast(lastObj,theTopRigthPoint);
3512 lastObj = GEOM::GetCreatedLast(lastObj,theBottomRigthPoint);
3513 lastObj = GEOM::GetCreatedLast(lastObj,theBottomLeftPoint);
3514 Handle(GEOM_Function) aFunction = lastObj->GetLastFunction();
3516 GEOM::TPythonDump(aFunction, /*append=*/true)
3517 << "listShapesOnQuadrangle = geompy.GetShapesOnQuadrangleIDs("
3519 << TopAbs_ShapeEnum(theShapeType) << ", "
3520 << theTopLeftPoint << ", "
3521 << theTopRigthPoint << ", "
3522 << theBottomLeftPoint << ", "
3523 << theBottomRigthPoint << ", "
3530 //=============================================================================
3534 //=============================================================================
3535 static bool GetInPlaceOfShape (const Handle(GEOM_Function)& theWhereFunction,
3536 const TopTools_IndexedMapOfShape& theWhereIndices,
3537 const TopoDS_Shape& theWhat,
3538 TColStd_ListOfInteger& theModifiedList)
3540 if (theWhereFunction.IsNull() || theWhat.IsNull()) return false;
3542 if (theWhereIndices.Contains(theWhat)) {
3543 // entity was not changed by the operation
3544 Standard_Integer aWhatIndex = theWhereIndices.FindIndex(theWhat);
3545 theModifiedList.Append(aWhatIndex);
3549 // try to find in history
3550 TDF_Label aHistoryLabel = theWhereFunction->GetHistoryEntry(Standard_False);
3552 // search in history for all argument shapes
3553 Standard_Boolean isFound = Standard_False;
3554 Standard_Boolean isGood = Standard_False;
3556 TDF_LabelSequence aLabelSeq;
3557 theWhereFunction->GetDependency(aLabelSeq);
3558 Standard_Integer nbArg = aLabelSeq.Length();
3560 for (Standard_Integer iarg = 1; iarg <= nbArg && !isFound; iarg++) {
3562 TDF_Label anArgumentRefLabel = aLabelSeq.Value(iarg);
3564 Handle(GEOM_Object) anArgumentObject = GEOM_Object::GetReferencedObject(anArgumentRefLabel);
3565 TopoDS_Shape anArgumentShape = anArgumentObject->GetValue();
3567 TopTools_IndexedMapOfShape anArgumentIndices;
3568 TopExp::MapShapes(anArgumentShape, anArgumentIndices);
3570 if (anArgumentIndices.Contains(theWhat)) {
3571 isFound = Standard_True;
3572 Standard_Integer aWhatIndex = anArgumentIndices.FindIndex(theWhat);
3574 // Find corresponding label in history
3575 TDF_Label anArgumentHistoryLabel =
3576 theWhereFunction->GetArgumentHistoryEntry(anArgumentRefLabel, Standard_False);
3577 if (anArgumentHistoryLabel.IsNull()) {
3578 // Lost History of operation argument. Possibly, all its entities was removed.
3579 isGood = Standard_True;
3582 TDF_Label aWhatHistoryLabel = anArgumentHistoryLabel.FindChild(aWhatIndex, Standard_False);
3584 if (aWhatHistoryLabel.IsNull()) {
3585 // Removed entity ? Compound ? Compsolid ? Shell ? Wire
3586 isGood = Standard_False;
3588 Handle(TDataStd_IntegerArray) anIntegerArray;
3589 if (!aWhatHistoryLabel.FindAttribute(TDataStd_IntegerArray::GetID(), anIntegerArray)) {
3590 //Error: Empty modifications history for the sought shape.
3591 isGood = Standard_False;
3594 isGood = Standard_True;
3595 Standard_Integer imod, aModifLen = anIntegerArray->Array()->Length();
3596 for (imod = 1; imod <= aModifLen; imod++) {
3597 theModifiedList.Append(anIntegerArray->Array()->Value(imod));
3608 // try compound/compsolid/shell/wire element by element
3609 bool isFoundAny = false;
3610 TopTools_MapOfShape mapShape;
3612 if (theWhat.ShapeType() == TopAbs_COMPOUND ||
3613 theWhat.ShapeType() == TopAbs_COMPSOLID) {
3614 // recursive processing of compound/compsolid
3615 TopoDS_Iterator anIt (theWhat, Standard_True, Standard_True);
3616 for (; anIt.More(); anIt.Next()) {
3617 if (mapShape.Add(anIt.Value())) {
3618 TopoDS_Shape curWhat = anIt.Value();
3619 isFoundAny = GetInPlaceOfShape(theWhereFunction, theWhereIndices, curWhat, theModifiedList);
3620 if (isFoundAny) isFound = Standard_True;
3624 else if (theWhat.ShapeType() == TopAbs_SHELL) {
3625 // try to replace a shell by its faces images
3626 TopExp_Explorer anExp (theWhat, TopAbs_FACE);
3627 for (; anExp.More(); anExp.Next()) {
3628 if (mapShape.Add(anExp.Current())) {
3629 TopoDS_Shape curWhat = anExp.Current();
3630 isFoundAny = GetInPlaceOfShape(theWhereFunction, theWhereIndices, curWhat, theModifiedList);
3631 if (isFoundAny) isFound = Standard_True;
3635 else if (theWhat.ShapeType() == TopAbs_WIRE) {
3636 // try to replace a wire by its edges images
3637 TopExp_Explorer anExp (theWhat, TopAbs_EDGE);
3638 for (; anExp.More(); anExp.Next()) {
3639 if (mapShape.Add(anExp.Current())) {
3640 TopoDS_Shape curWhat = anExp.Current();
3641 isFoundAny = GetInPlaceOfShape(theWhereFunction, theWhereIndices, curWhat, theModifiedList);
3642 if (isFoundAny) isFound = Standard_True;
3654 //=============================================================================
3656 * GetShapeProperties
3658 //=============================================================================
3659 void GEOMImpl_IShapesOperations::GetShapeProperties( const TopoDS_Shape aShape, Standard_Real tab[],
3662 GProp_GProps theProps;
3664 //TopoDS_Shape aPntShape;
3665 Standard_Real aShapeSize;
3667 if (aShape.ShapeType() == TopAbs_VERTEX) aCenterMass = BRep_Tool::Pnt( TopoDS::Vertex( aShape ) );
3668 else if (aShape.ShapeType() == TopAbs_EDGE) BRepGProp::LinearProperties(aShape, theProps);
3669 else if (aShape.ShapeType() == TopAbs_FACE) BRepGProp::SurfaceProperties(aShape, theProps);
3670 else BRepGProp::VolumeProperties(aShape, theProps);
3672 if (aShape.ShapeType() == TopAbs_VERTEX)
3675 aCenterMass = theProps.CentreOfMass();
3676 aShapeSize = theProps.Mass();
3679 // aPntShape = BRepBuilderAPI_MakeVertex(aCenterMass).Shape();
3680 // aVertex = BRep_Tool::Pnt( TopoDS::Vertex( aPntShape ) );
3681 aVertex = aCenterMass;
3682 tab[0] = aVertex.X();
3683 tab[1] = aVertex.Y();
3684 tab[2] = aVertex.Z();
3685 tab[3] = aShapeSize;
3691 //================================================================================
3693 * \brief Return normal to face at extrema point
3695 //================================================================================
3697 gp_Vec GetNormal (const TopoDS_Face& face, const BRepExtrema_DistShapeShape& extrema)
3699 gp_Vec defaultNorm(1,0,0); // to have same normals on different faces
3701 // get UV at extrema point
3702 Standard_Real u,v, f,l;
3703 switch ( extrema.SupportTypeShape2(1) ) {
3704 case BRepExtrema_IsInFace: {
3705 extrema.ParOnFaceS2(1, u, v );
3708 case BRepExtrema_IsOnEdge: {
3709 TopoDS_Edge edge = TopoDS::Edge( extrema.SupportOnShape2(1));
3710 Handle(Geom2d_Curve) pcurve = BRep_Tool::CurveOnSurface( edge, face, f,l );
3711 extrema.ParOnEdgeS2( 1, u );
3712 gp_Pnt2d uv = pcurve->Value( u );
3717 case BRepExtrema_IsVertex: return defaultNorm;
3720 BRepAdaptor_Surface surface( face, false );
3721 gp_Vec du, dv; gp_Pnt p;
3722 surface.D1( u, v, p, du, dv );
3726 } catch (Standard_Failure ) {
3732 //================================================================================
3734 * \brief Return type of shape for explode. In case of compound it will be a type of sub shape.
3736 //================================================================================
3737 TopAbs_ShapeEnum GEOMImpl_IShapesOperations::GetTypeOfSimplePart (const TopoDS_Shape& theShape)
3739 TopAbs_ShapeEnum aType = theShape.ShapeType();
3740 if (aType == TopAbs_VERTEX) return TopAbs_VERTEX;
3741 else if (aType == TopAbs_EDGE || aType == TopAbs_WIRE) return TopAbs_EDGE;
3742 else if (aType == TopAbs_FACE || aType == TopAbs_SHELL) return TopAbs_FACE;
3743 else if (aType == TopAbs_SOLID || aType == TopAbs_COMPSOLID) return TopAbs_SOLID;
3744 else if (aType == TopAbs_COMPOUND) {
3745 // Only the iType of the first shape in the compound is taken into account
3746 TopoDS_Iterator It (theShape, Standard_False, Standard_False);
3748 return GetTypeOfSimplePart(It.Value());
3751 return TopAbs_SHAPE;
3754 //=============================================================================
3759 //=============================================================================
3760 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlace (Handle(GEOM_Object) theShapeWhere,
3761 Handle(GEOM_Object) theShapeWhat)
3765 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
3767 TopoDS_Shape aWhere = theShapeWhere->GetValue();
3768 TopoDS_Shape aWhat = theShapeWhat->GetValue();
3769 TopoDS_Shape aPntShape;
3770 TopoDS_Vertex aVertex;
3772 if (aWhere.IsNull() || aWhat.IsNull()) {
3773 SetErrorCode("Error: aWhere and aWhat TopoDS_Shape are Null.");
3777 Handle(GEOM_Function) aWhereFunction = theShapeWhere->GetLastFunction();
3778 if (aWhereFunction.IsNull()) {
3779 SetErrorCode("Error: aWhereFunction is Null.");
3783 TopTools_IndexedMapOfShape aWhereIndices;
3784 TopExp::MapShapes(aWhere, aWhereIndices);
3786 TopAbs_ShapeEnum iType = TopAbs_SOLID;
3787 Standard_Real dl_l = 1e-3;
3788 Standard_Real min_l, Tol_0D, Tol_1D, Tol_2D, Tol_3D, Tol_Mass;
3789 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
3790 Bnd_Box BoundingBox;
3791 gp_Pnt aPnt, aPnt_aWhat, tab_Pnt[2];
3792 GProp_GProps aProps;
3794 // Find the iType of the aWhat shape
3795 iType = GetTypeOfSimplePart(aWhat);
3796 if (iType == TopAbs_SHAPE) {
3797 SetErrorCode("Error: An attempt to extract a shape of not supported type.");
3801 TopExp_Explorer Exp_aWhat ( aWhat, iType );
3802 TopExp_Explorer Exp_aWhere ( aWhere, iType );
3803 TopExp_Explorer Exp_Edge ( aWhere, TopAbs_EDGE );
3805 // Find the shortest edge in theShapeWhere shape
3806 BRepBndLib::Add(aWhere, BoundingBox);
3807 BoundingBox.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
3808 min_l = fabs(aXmax - aXmin);
3809 if( min_l < fabs(aYmax - aYmin) ) min_l = fabs(aYmax - aYmin);
3810 if( min_l < fabs(aZmax - aZmin) ) min_l = fabs(aZmax - aZmin);
3812 // Mantis issue 0020908 BEGIN
3813 if (!Exp_Edge.More()) {
3814 min_l = Precision::Confusion();
3816 // Mantis issue 0020908 END
3817 for ( Standard_Integer nbEdge = 0; Exp_Edge.More(); Exp_Edge.Next(), nbEdge++ ) {
3818 TopExp_Explorer Exp_Vertex( Exp_Edge.Current(), TopAbs_VERTEX);
3819 for ( Standard_Integer nbVertex = 0; Exp_Vertex.More(); Exp_Vertex.Next(), nbVertex++ ) {
3820 aPnt = BRep_Tool::Pnt( TopoDS::Vertex( Exp_Vertex.Current() ) );
3821 tab_Pnt[nbVertex] = aPnt;
3823 if ( ! tab_Pnt[0].IsEqual(tab_Pnt[1], dl_l) ) {
3824 BRepGProp::LinearProperties(Exp_Edge.Current(), aProps);
3825 if ( aProps.Mass() < min_l ) min_l = aProps.Mass();
3829 // Compute tolerances
3831 Tol_1D = dl_l * min_l;
3832 Tol_2D = dl_l * ( min_l * min_l) * ( 2. + dl_l);
3833 Tol_3D = dl_l * ( min_l * min_l * min_l ) * ( 3. + (3 * dl_l) + (dl_l * dl_l) );
3835 if (Tol_0D < Precision::Confusion()) Tol_0D = Precision::Confusion();
3836 if (Tol_1D < Precision::Confusion()) Tol_1D = Precision::Confusion();
3837 if (Tol_2D < Precision::Confusion()) Tol_2D = Precision::Confusion();
3838 if (Tol_3D < Precision::Confusion()) Tol_3D = Precision::Confusion();
3841 if ( iType == TopAbs_VERTEX ) Tol_Mass = Tol_0D;
3842 else if ( iType == TopAbs_EDGE ) Tol_Mass = Tol_1D;
3843 else if ( iType == TopAbs_FACE ) Tol_Mass = Tol_2D;
3845 // Searching for the sub-shapes inside the ShapeWhere shape
3846 GEOMAlgo_GetInPlace aGIP;
3847 aGIP.SetTolerance(Tol_1D);
3848 aGIP.SetTolMass(Tol_Mass);
3849 aGIP.SetTolCG(Tol_1D);
3851 aGIP.SetArgument(aWhat);
3852 aGIP.SetShapeWhere(aWhere);
3855 int iErr = aGIP.ErrorStatus();
3857 SetErrorCode("Error in GEOMAlgo_GetInPlace");
3861 if (!aGIP.IsFound()) {
3862 SetErrorCode(NOT_FOUND_ANY);
3866 const TopTools_DataMapOfShapeListOfShape& aDMSLS = aGIP.Images();
3867 if (!aDMSLS.IsBound(aWhat)) {
3868 SetErrorCode(NOT_FOUND_ANY);
3872 // the list of shapes aLSA contains the shapes
3873 // of the Shape For Search that corresponds
3874 // to the Argument aWhat
3875 const TopTools_ListOfShape& aLSA = aDMSLS.Find(aWhat);
3876 if (aLSA.Extent() == 0) {
3877 SetErrorCode(NOT_FOUND_ANY); // Not found any Results
3881 Handle(TColStd_HArray1OfInteger) aModifiedArray = new TColStd_HArray1OfInteger (1, aLSA.Extent());
3882 TopTools_ListIteratorOfListOfShape anIterModif (aLSA);
3883 for (Standard_Integer imod = 1; anIterModif.More(); anIterModif.Next(), imod++) {
3884 if (aWhereIndices.Contains(anIterModif.Value())) {
3885 aModifiedArray->SetValue(imod, aWhereIndices.FindIndex(anIterModif.Value()));
3888 SetErrorCode("Error: wrong sub shape returned");
3894 Handle(GEOM_Object) aResult = GetEngine()->AddSubShape(theShapeWhere, aModifiedArray);
3895 if (aResult.IsNull()) {
3896 SetErrorCode("Error in algorithm: result found, but cannot be returned.");
3900 if (aModifiedArray->Length() > 1) {
3902 aResult->SetType(GEOM_GROUP);
3904 //Set a sub shape type
3905 TopoDS_Shape aFirstFound = aLSA.First();
3906 TopAbs_ShapeEnum aShapeType = aFirstFound.ShapeType();
3908 TDF_Label aFreeLabel = aResult->GetFreeLabel();
3909 TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aShapeType);
3912 //Make a Python command
3913 Handle(GEOM_Function) aFunction = aResult->GetFunction(1);
3915 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetInPlace("
3916 << theShapeWhere << ", " << theShapeWhat << ", True)";
3922 //=============================================================================
3924 * case GetInPlaceOld:
3927 //=============================================================================
3928 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlaceOld (Handle(GEOM_Object) theShapeWhere,
3929 Handle(GEOM_Object) theShapeWhat)
3933 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
3935 TopoDS_Shape aWhere = theShapeWhere->GetValue();
3936 TopoDS_Shape aWhat = theShapeWhat->GetValue();
3937 TopoDS_Shape aPntShape;
3938 TopoDS_Vertex aVertex;
3940 if (aWhere.IsNull() || aWhat.IsNull()) {
3941 SetErrorCode("Error: aWhere and aWhat TopoDS_Shape are Null.");
3945 Handle(GEOM_Function) aWhereFunction = theShapeWhere->GetLastFunction();
3946 if (aWhereFunction.IsNull()) {
3947 SetErrorCode("Error: aWhereFunction is Null.");
3951 TopTools_IndexedMapOfShape aWhereIndices;
3952 TopExp::MapShapes(aWhere, aWhereIndices);
3954 TColStd_ListOfInteger aModifiedList;
3955 Standard_Integer aWhereIndex;
3956 Handle(TColStd_HArray1OfInteger) aModifiedArray;
3957 Handle(GEOM_Object) aResult;
3959 bool isFound = false;
3960 TopAbs_ShapeEnum iType = TopAbs_SOLID;
3961 //Standard_Real aWhat_Mass = 0., aWhere_Mass = 0.;
3962 Standard_Real tab_aWhat[4], tab_aWhere[4];
3963 Standard_Real dl_l = 1e-3;
3964 Standard_Real min_l, Tol_0D, Tol_1D, Tol_2D, Tol_3D, Tol_Mass;
3965 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
3966 Bnd_Box BoundingBox;
3967 gp_Pnt aPnt, aPnt_aWhat, tab_Pnt[2];
3968 GProp_GProps aProps;
3970 // Find the iType of the aWhat shape
3972 if ( aWhat.ShapeType() == TopAbs_VERTEX ) iType = TopAbs_VERTEX;
3973 else if ( aWhat.ShapeType() == TopAbs_EDGE || aWhat.ShapeType() == TopAbs_WIRE ) iType = TopAbs_EDGE;
3974 else if ( aWhat.ShapeType() == TopAbs_FACE || aWhat.ShapeType() == TopAbs_SHELL ) iType = TopAbs_FACE;
3975 else if ( aWhat.ShapeType() == TopAbs_SOLID || aWhat.ShapeType() == TopAbs_COMPSOLID ) iType = TopAbs_SOLID;
3976 else if ( aWhat.ShapeType() == TopAbs_COMPOUND ) {
3977 // Only the iType of the first shape in the compound is taken into account
3978 TopoDS_Iterator It (aWhat, Standard_False, Standard_False);
3980 SetErrorCode("Error: theShapeWhat is an empty COMPOUND.");
3983 TopAbs_ShapeEnum compType = It.Value().ShapeType();
3984 if ( compType == TopAbs_VERTEX ) iType = TopAbs_VERTEX;
3985 else if ( compType == TopAbs_EDGE || compType == TopAbs_WIRE ) iType = TopAbs_EDGE;
3986 else if ( compType == TopAbs_FACE || compType == TopAbs_SHELL) iType = TopAbs_FACE;
3987 else if ( compType == TopAbs_SOLID || compType == TopAbs_COMPSOLID) iType = TopAbs_SOLID;
3990 SetErrorCode("Error: An attempt to extract a shape of not supported type.");
3994 iType = GetTypeOfSimplePart(aWhat);
3995 if (iType == TopAbs_SHAPE) {
3996 SetErrorCode("Error: An attempt to extract a shape of not supported type.");
4000 TopExp_Explorer Exp_aWhat ( aWhat, iType );
4001 TopExp_Explorer Exp_aWhere ( aWhere, iType );
4002 TopExp_Explorer Exp_Edge ( aWhere, TopAbs_EDGE );
4004 // Find the shortest edge in theShapeWhere shape
4005 BRepBndLib::Add(aWhere, BoundingBox);
4006 BoundingBox.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
4007 min_l = fabs(aXmax - aXmin);
4008 if( min_l < fabs(aYmax - aYmin) ) min_l = fabs(aYmax - aYmin);
4009 if( min_l < fabs(aZmax - aZmin) ) min_l = fabs(aZmax - aZmin);
4011 // Mantis issue 0020908 BEGIN
4012 if (!Exp_Edge.More()) {
4013 min_l = Precision::Confusion();
4015 // Mantis issue 0020908 END
4016 for ( Standard_Integer nbEdge = 0; Exp_Edge.More(); Exp_Edge.Next(), nbEdge++ ) {
4017 TopExp_Explorer Exp_Vertex( Exp_Edge.Current(), TopAbs_VERTEX);
4018 for ( Standard_Integer nbVertex = 0; Exp_Vertex.More(); Exp_Vertex.Next(), nbVertex++ ) {
4019 aPnt = BRep_Tool::Pnt( TopoDS::Vertex( Exp_Vertex.Current() ) );
4020 tab_Pnt[nbVertex] = aPnt;
4022 if ( ! tab_Pnt[0].IsEqual(tab_Pnt[1], dl_l) ) {
4023 BRepGProp::LinearProperties(Exp_Edge.Current(), aProps);
4024 if ( aProps.Mass() < min_l ) min_l = aProps.Mass();
4028 // Compute tolerances
4030 Tol_1D = dl_l * min_l;
4031 Tol_2D = dl_l * ( min_l * min_l) * ( 2. + dl_l);
4032 Tol_3D = dl_l * ( min_l * min_l * min_l ) * ( 3. + (3 * dl_l) + (dl_l * dl_l) );
4034 if (Tol_0D < Precision::Confusion()) Tol_0D = Precision::Confusion();
4035 if (Tol_1D < Precision::Confusion()) Tol_1D = Precision::Confusion();
4036 if (Tol_2D < Precision::Confusion()) Tol_2D = Precision::Confusion();
4037 if (Tol_3D < Precision::Confusion()) Tol_3D = Precision::Confusion();
4039 //if (Tol_1D > 1.0) Tol_1D = 1.0;
4040 //if (Tol_2D > 1.0) Tol_2D = 1.0;
4041 //if (Tol_3D > 1.0) Tol_3D = 1.0;
4044 if ( iType == TopAbs_VERTEX ) Tol_Mass = Tol_0D;
4045 else if ( iType == TopAbs_EDGE ) Tol_Mass = Tol_1D;
4046 else if ( iType == TopAbs_FACE ) Tol_Mass = Tol_2D;
4048 // Compute the ShapeWhat Mass
4050 for ( ; Exp_aWhat.More(); Exp_aWhat.Next() ) {
4051 if ( iType == TopAbs_VERTEX ) {
4055 else if ( iType == TopAbs_EDGE ) BRepGProp::LinearProperties(Exp_aWhat.Current(), aProps);
4056 else if ( iType == TopAbs_FACE ) BRepGProp::SurfaceProperties(Exp_aWhat.Current(), aProps);
4057 else BRepGProp::VolumeProperties(Exp_aWhat.Current(), aProps);
4058 aWhat_Mass += aProps.Mass();
4062 // Searching for the sub-shapes inside the ShapeWhere shape
4063 TopTools_MapOfShape map_aWhere;
4064 for ( Exp_aWhere.ReInit(); Exp_aWhere.More(); Exp_aWhere.Next() ) {
4065 if (!map_aWhere.Add(Exp_aWhere.Current()))
4066 continue; // skip repeated shape to avoid mass addition
4067 GetShapeProperties( Exp_aWhere.Current(), tab_aWhere, aPnt );
4068 for ( Exp_aWhat.ReInit(); Exp_aWhat.More(); Exp_aWhat.Next() ) {
4069 GetShapeProperties( Exp_aWhat.Current(), tab_aWhat, aPnt_aWhat );
4070 if ( fabs(tab_aWhat[3] - tab_aWhere[3]) <= Tol_Mass && aPnt_aWhat.Distance(aPnt) <= Tol_1D )
4073 if ( (tab_aWhat[3] - tab_aWhere[3]) > Tol_Mass ) {
4074 aPntShape = BRepBuilderAPI_MakeVertex( aPnt ).Shape();
4075 aVertex = TopoDS::Vertex( aPntShape );
4076 BRepExtrema_DistShapeShape aWhereDistance ( aVertex, Exp_aWhere.Current() );
4077 BRepExtrema_DistShapeShape aWhatDistance ( aVertex, Exp_aWhat.Current() );
4078 if ( aWhereDistance.IsDone() && aWhatDistance.IsDone() &&
4079 fabs(aWhereDistance.Value() - aWhatDistance.Value()) <= Tol_1D )
4081 // 0020162: "EDF 961 GEOM : Getinplace is getting additionnal orthogonal faces"
4082 // aVertex must be projected to the same point on Where and on What
4083 gp_Pnt pOnWhat = aWhatDistance.PointOnShape2(1);
4084 gp_Pnt pOnWhere = aWhereDistance.PointOnShape2(1);
4085 isFound = ( pOnWhat.Distance(pOnWhere) <= Tol_1D );
4086 if ( isFound && iType == TopAbs_FACE )
4088 // check normals at pOnWhat and pOnWhere
4089 const double angleTol = PI/180.;
4090 gp_Vec normToWhat = GetNormal( TopoDS::Face(Exp_aWhat.Current()), aWhatDistance);
4091 gp_Vec normToWhere = GetNormal( TopoDS::Face(Exp_aWhere.Current()), aWhereDistance);
4092 if ( normToWhat * normToWhere < 0 )
4093 normToWhat.Reverse();
4094 isFound = ( normToWhat.Angle( normToWhere ) < angleTol );
4100 aWhereIndex = aWhereIndices.FindIndex(Exp_aWhere.Current());
4101 aModifiedList.Append(aWhereIndex);
4102 //aWhere_Mass += tab_aWhere[3];
4107 //if ( fabs( aWhat_Mass - aWhere_Mass ) <= Tol_Mass )
4111 if (aModifiedList.Extent() == 0) { // Not found any Results
4112 SetErrorCode(NOT_FOUND_ANY);
4116 aModifiedArray = new TColStd_HArray1OfInteger (1, aModifiedList.Extent());
4117 TColStd_ListIteratorOfListOfInteger anIterModif (aModifiedList);
4118 for (Standard_Integer imod = 1; anIterModif.More(); anIterModif.Next(), imod++)
4119 aModifiedArray->SetValue(imod, anIterModif.Value());
4122 aResult = GetEngine()->AddSubShape(theShapeWhere, aModifiedArray);
4123 if (aResult.IsNull()) {
4124 SetErrorCode("Error in algorithm: result found, but cannot be returned.");
4128 if (aModifiedArray->Length() > 1) {
4130 aResult->SetType(GEOM_GROUP);
4132 //Set a sub shape type
4133 TopoDS_Shape aFirstFound = aWhereIndices.FindKey(aModifiedArray->Value(1));
4134 TopAbs_ShapeEnum aShapeType = aFirstFound.ShapeType();
4136 TDF_Label aFreeLabel = aResult->GetFreeLabel();
4137 TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aShapeType);
4140 //Make a Python command
4141 Handle(GEOM_Function) aFunction = aResult->GetFunction(1);
4143 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetInPlace("
4144 << theShapeWhere << ", " << theShapeWhat << ", False)";
4150 //=======================================================================
4151 //function : GetInPlaceByHistory
4153 //=======================================================================
4154 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlaceByHistory
4155 (Handle(GEOM_Object) theShapeWhere,
4156 Handle(GEOM_Object) theShapeWhat)
4160 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
4162 TopoDS_Shape aWhere = theShapeWhere->GetValue();
4163 TopoDS_Shape aWhat = theShapeWhat->GetValue();
4165 if (aWhere.IsNull() || aWhat.IsNull()) return NULL;
4167 Handle(GEOM_Function) aWhereFunction = theShapeWhere->GetLastFunction();
4168 if (aWhereFunction.IsNull()) return NULL;
4170 //Fill array of indices
4171 TopTools_IndexedMapOfShape aWhereIndices;
4172 TopExp::MapShapes(aWhere, aWhereIndices);
4175 TColStd_ListOfInteger aModifiedList;
4176 bool isFound = GetInPlaceOfShape(aWhereFunction, aWhereIndices, aWhat, aModifiedList);
4178 if (!isFound || aModifiedList.Extent() < 1) {
4179 SetErrorCode("Error: No history found for the sought shape or its sub-shapes.");
4183 Handle(TColStd_HArray1OfInteger) aModifiedArray =
4184 new TColStd_HArray1OfInteger (1, aModifiedList.Extent());
4185 TColStd_ListIteratorOfListOfInteger anIterModif (aModifiedList);
4186 for (Standard_Integer imod = 1; anIterModif.More(); anIterModif.Next(), imod++) {
4187 aModifiedArray->SetValue(imod, anIterModif.Value());
4191 Handle(GEOM_Object) aResult = GetEngine()->AddSubShape(theShapeWhere, aModifiedArray);
4192 if (aResult.IsNull()) {
4193 SetErrorCode("Error in algorithm: result found, but cannot be returned.");
4197 if (aModifiedArray->Length() > 1) {
4199 aResult->SetType(GEOM_GROUP);
4201 //Set a sub shape type
4202 TopoDS_Shape aFirstFound = aWhereIndices.FindKey(aModifiedArray->Value(1));
4203 TopAbs_ShapeEnum aShapeType = aFirstFound.ShapeType();
4205 TDF_Label aFreeLabel = aResult->GetFreeLabel();
4206 TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aShapeType);
4209 //Make a Python command
4210 Handle(GEOM_Function) aFunction = aResult->GetFunction(1);
4212 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetInPlaceByHistory("
4213 << theShapeWhere << ", " << theShapeWhat << ")";
4219 //=======================================================================
4220 //function : ShapeToDouble
4221 //purpose : used by CompareShapes::operator()
4222 //=======================================================================
4223 std::pair<double, double> ShapeToDouble (const TopoDS_Shape& S, bool isOldSorting)
4225 // Computing of CentreOfMass
4229 if (S.ShapeType() == TopAbs_VERTEX) {
4230 GPoint = BRep_Tool::Pnt(TopoDS::Vertex(S));
4231 Len = (double)S.Orientation();
4235 // BEGIN: fix for Mantis issue 0020842
4237 BRepGProp::LinearProperties(S, GPr);
4240 if (S.ShapeType() == TopAbs_EDGE || S.ShapeType() == TopAbs_WIRE) {
4241 BRepGProp::LinearProperties(S, GPr);
4243 else if (S.ShapeType() == TopAbs_FACE || S.ShapeType() == TopAbs_SHELL) {
4244 BRepGProp::SurfaceProperties(S, GPr);
4247 BRepGProp::VolumeProperties(S, GPr);
4250 // END: fix for Mantis issue 0020842
4251 GPoint = GPr.CentreOfMass();
4255 double dMidXYZ = GPoint.X() * 999.0 + GPoint.Y() * 99.0 + GPoint.Z() * 0.9;
4256 return std::make_pair(dMidXYZ, Len);
4259 //=======================================================================
4260 //function : CompareShapes::operator()
4261 //purpose : used by std::sort(), called from SortShapes()
4262 //=======================================================================
4263 bool GEOMImpl_IShapesOperations::CompareShapes::operator()(const TopoDS_Shape& theShape1,
4264 const TopoDS_Shape& theShape2)
4266 if (!myMap.IsBound(theShape1)) {
4267 myMap.Bind(theShape1, ShapeToDouble(theShape1, myIsOldSorting));
4270 if (!myMap.IsBound(theShape2)) {
4271 myMap.Bind(theShape2, ShapeToDouble(theShape2, myIsOldSorting));
4274 std::pair<double, double> val1 = myMap.Find(theShape1);
4275 std::pair<double, double> val2 = myMap.Find(theShape2);
4277 double tol = Precision::Confusion();
4278 bool exchange = Standard_False;
4280 double dMidXYZ = val1.first - val2.first;
4281 if (dMidXYZ >= tol) {
4282 exchange = Standard_True;
4284 else if (Abs(dMidXYZ) < tol) {
4285 double dLength = val1.second - val2.second;
4286 if (dLength >= tol) {
4287 exchange = Standard_True;
4289 else if (Abs(dLength) < tol && theShape1.ShapeType() <= TopAbs_FACE) {
4291 // equal values possible on shapes such as two halves of a sphere and
4292 // a membrane inside the sphere
4294 BRepBndLib::Add(theShape1, box1);
4295 if (!box1.IsVoid()) {
4296 BRepBndLib::Add(theShape2, box2);
4297 Standard_Real dSquareExtent = box1.SquareExtent() - box2.SquareExtent();
4298 if (dSquareExtent >= tol) {
4299 exchange = Standard_True;
4301 else if (Abs(dSquareExtent) < tol) {
4302 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax, val1, val2;
4303 box1.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
4304 val1 = (aXmin+aXmax)*999.0 + (aYmin+aYmax)*99.0 + (aZmin+aZmax)*0.9;
4305 box2.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
4306 val2 = (aXmin+aXmax)*999.0 + (aYmin+aYmax)*99.0 + (aZmin+aZmax)*0.9;
4307 if ((val1 - val2) >= tol) {
4308 exchange = Standard_True;
4315 //return val1 < val2;
4319 //=======================================================================
4320 //function : SortShapes
4322 //=======================================================================
4323 void GEOMImpl_IShapesOperations::SortShapes(TopTools_ListOfShape& SL,
4324 const Standard_Boolean isOldSorting)
4326 #ifdef STD_SORT_ALGO
4327 std::vector<TopoDS_Shape> aShapesVec;
4328 aShapesVec.reserve(SL.Extent());
4330 TopTools_ListIteratorOfListOfShape it (SL);
4331 for (; it.More(); it.Next()) {
4332 aShapesVec.push_back(it.Value());
4336 CompareShapes shComp (isOldSorting);
4337 std::stable_sort(aShapesVec.begin(), aShapesVec.end(), shComp);
4338 //std::sort(aShapesVec.begin(), aShapesVec.end(), shComp);
4340 std::vector<TopoDS_Shape>::const_iterator anIter = aShapesVec.begin();
4341 for (; anIter != aShapesVec.end(); ++anIter) {
4345 // old implementation
4346 Standard_Integer MaxShapes = SL.Extent();
4347 TopTools_Array1OfShape aShapes (1,MaxShapes);
4348 TColStd_Array1OfInteger OrderInd(1,MaxShapes);
4349 TColStd_Array1OfReal MidXYZ (1,MaxShapes); //X,Y,Z;
4350 TColStd_Array1OfReal Length (1,MaxShapes); //X,Y,Z;
4352 // Computing of CentreOfMass
4353 Standard_Integer Index;
4356 TopTools_ListIteratorOfListOfShape it(SL);
4357 for (Index=1; it.More(); Index++)
4359 TopoDS_Shape S = it.Value();
4360 SL.Remove( it ); // == it.Next()
4362 OrderInd.SetValue (Index, Index);
4363 if (S.ShapeType() == TopAbs_VERTEX) {
4364 GPoint = BRep_Tool::Pnt( TopoDS::Vertex( S ));
4365 Length.SetValue( Index, (Standard_Real) S.Orientation());
4368 // BEGIN: fix for Mantis issue 0020842
4370 BRepGProp::LinearProperties (S, GPr);
4373 if (S.ShapeType() == TopAbs_EDGE || S.ShapeType() == TopAbs_WIRE) {
4374 BRepGProp::LinearProperties (S, GPr);
4376 else if (S.ShapeType() == TopAbs_FACE || S.ShapeType() == TopAbs_SHELL) {
4377 BRepGProp::SurfaceProperties(S, GPr);
4380 BRepGProp::VolumeProperties(S, GPr);
4383 // END: fix for Mantis issue 0020842
4384 GPoint = GPr.CentreOfMass();
4385 Length.SetValue(Index, GPr.Mass());
4387 MidXYZ.SetValue(Index, GPoint.X()*999.0 + GPoint.Y()*99.0 + GPoint.Z()*0.9);
4388 //cout << Index << " L: " << Length(Index) << "CG: " << MidXYZ(Index) << endl;
4392 Standard_Integer aTemp;
4393 Standard_Boolean exchange, Sort = Standard_True;
4394 Standard_Real tol = Precision::Confusion();
4397 Sort = Standard_False;
4398 for (Index=1; Index < MaxShapes; Index++)
4400 exchange = Standard_False;
4401 Standard_Real dMidXYZ = MidXYZ(OrderInd(Index)) - MidXYZ(OrderInd(Index+1));
4402 Standard_Real dLength = Length(OrderInd(Index)) - Length(OrderInd(Index+1));
4403 if ( dMidXYZ >= tol ) {
4404 // cout << "MidXYZ: " << MidXYZ(OrderInd(Index))<< " > " <<MidXYZ(OrderInd(Index+1))
4405 // << " d: " << dMidXYZ << endl;
4406 exchange = Standard_True;
4408 else if ( Abs(dMidXYZ) < tol && dLength >= tol ) {
4409 // cout << "Length: " << Length(OrderInd(Index))<< " > " <<Length(OrderInd(Index+1))
4410 // << " d: " << dLength << endl;
4411 exchange = Standard_True;
4413 else if ( Abs(dMidXYZ) < tol && Abs(dLength) < tol &&
4414 aShapes(OrderInd(Index)).ShapeType() <= TopAbs_FACE) {
4416 // equal values possible on shapes such as two halves of a sphere and
4417 // a membrane inside the sphere
4419 BRepBndLib::Add( aShapes( OrderInd(Index) ), box1 );
4420 if ( box1.IsVoid() ) continue;
4421 BRepBndLib::Add( aShapes( OrderInd(Index+1) ), box2 );
4422 Standard_Real dSquareExtent = box1.SquareExtent() - box2.SquareExtent();
4423 if ( dSquareExtent >= tol ) {
4424 // cout << "SquareExtent: " << box1.SquareExtent()<<" > "<<box2.SquareExtent() << endl;
4425 exchange = Standard_True;
4427 else if ( Abs(dSquareExtent) < tol ) {
4428 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax, val1, val2;
4429 box1.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
4430 val1 = (aXmin+aXmax)*999 + (aYmin+aYmax)*99 + (aZmin+aZmax)*0.9;
4431 box2.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
4432 val2 = (aXmin+aXmax)*999 + (aYmin+aYmax)*99 + (aZmin+aZmax)*0.9;
4433 //exchange = val1 > val2;
4434 if ((val1 - val2) >= tol) {
4435 exchange = Standard_True;
4437 //cout << "box: " << val1<<" > "<<val2 << endl;
4443 // cout << "exchange " << Index << " & " << Index+1 << endl;
4444 aTemp = OrderInd(Index);
4445 OrderInd(Index) = OrderInd(Index+1);
4446 OrderInd(Index+1) = aTemp;
4447 Sort = Standard_True;
4452 for (Index=1; Index <= MaxShapes; Index++)
4453 SL.Append( aShapes( OrderInd(Index) ));
4457 //=======================================================================
4458 //function : CompsolidToCompound
4460 //=======================================================================
4461 TopoDS_Shape GEOMImpl_IShapesOperations::CompsolidToCompound (const TopoDS_Shape& theCompsolid)
4463 if (theCompsolid.ShapeType() != TopAbs_COMPSOLID) {
4464 return theCompsolid;
4467 TopoDS_Compound aCompound;
4469 B.MakeCompound(aCompound);
4471 TopTools_MapOfShape mapShape;
4472 TopoDS_Iterator It (theCompsolid, Standard_True, Standard_True);
4474 for (; It.More(); It.Next()) {
4475 TopoDS_Shape aShape_i = It.Value();
4476 if (mapShape.Add(aShape_i)) {
4477 B.Add(aCompound, aShape_i);
4484 //=======================================================================
4485 //function : CheckTriangulation
4487 //=======================================================================
4488 bool GEOMImpl_IShapesOperations::CheckTriangulation (const TopoDS_Shape& aShape)
4490 bool isTriangulation = true;
4492 TopExp_Explorer exp (aShape, TopAbs_FACE);
4495 TopLoc_Location aTopLoc;
4496 Handle(Poly_Triangulation) aTRF;
4497 aTRF = BRep_Tool::Triangulation(TopoDS::Face(exp.Current()), aTopLoc);
4498 if (aTRF.IsNull()) {
4499 isTriangulation = false;
4502 else // no faces, try edges
4504 TopExp_Explorer expe (aShape, TopAbs_EDGE);
4508 TopLoc_Location aLoc;
4509 Handle(Poly_Polygon3D) aPE = BRep_Tool::Polygon3D(TopoDS::Edge(expe.Current()), aLoc);
4511 isTriangulation = false;
4515 if (!isTriangulation) {
4516 // calculate deflection
4517 Standard_Real aDeviationCoefficient = 0.001;
4520 BRepBndLib::Add(aShape, B);
4521 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
4522 B.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
4524 Standard_Real dx = aXmax - aXmin, dy = aYmax - aYmin, dz = aZmax - aZmin;
4525 Standard_Real aDeflection = Max(Max(dx, dy), dz) * aDeviationCoefficient * 4;
4526 Standard_Real aHLRAngle = 0.349066;
4528 BRepMesh_IncrementalMesh Inc (aShape, aDeflection, Standard_False, aHLRAngle);
4534 #define MAX_TOLERANCE 1.e-7
4536 //=======================================================================
4537 //function : isSameEdge
4538 //purpose : Returns True if two edges coincide
4539 //=======================================================================
4540 static bool isSameEdge(const TopoDS_Edge& theEdge1, const TopoDS_Edge& theEdge2)
4542 TopoDS_Vertex V11, V12, V21, V22;
4543 TopExp::Vertices(theEdge1, V11, V12);
4544 TopExp::Vertices(theEdge2, V21, V22);
4545 gp_Pnt P11 = BRep_Tool::Pnt(V11);
4546 gp_Pnt P12 = BRep_Tool::Pnt(V12);
4547 gp_Pnt P21 = BRep_Tool::Pnt(V21);
4548 gp_Pnt P22 = BRep_Tool::Pnt(V22);
4549 bool coincide = false;
4551 //Check that ends of edges coincide
4552 if(P11.Distance(P21) <= MAX_TOLERANCE) {
4553 if(P12.Distance(P22) <= MAX_TOLERANCE) coincide = true;
4555 else if(P11.Distance(P22) <= MAX_TOLERANCE) {
4556 if(P12.Distance(P21) <= MAX_TOLERANCE) coincide = true;
4559 if(!coincide) return false;
4561 if (BRep_Tool::Degenerated(theEdge1))
4562 if (BRep_Tool::Degenerated(theEdge2)) return true;
4565 if (BRep_Tool::Degenerated(theEdge2)) return false;
4567 double U11, U12, U21, U22;
4568 Handle(Geom_Curve) C1 = BRep_Tool::Curve(theEdge1, U11, U12);
4569 Handle(Geom_Curve) C2 = BRep_Tool::Curve(theEdge2, U21, U22);
4570 if(C1->DynamicType() == C2->DynamicType()) return true;
4572 //Check that both edges has the same geometry
4573 double range = U12-U11;
4574 double U = U11+ range/3.0;
4575 gp_Pnt P1 = C1->Value(U); //Compute a point on one third of the edge's length
4576 U = U11+range*2.0/3.0;
4577 gp_Pnt P2 = C1->Value(U); //Compute a point on two thirds of the edge's length
4579 if(!GeomLib_Tool::Parameter(C2, P1, MAX_TOLERANCE, U) || U < U21 || U > U22)
4582 if(P1.Distance(C2->Value(U)) > MAX_TOLERANCE) return false;
4584 if(!GeomLib_Tool::Parameter(C2, P2, MAX_TOLERANCE, U) || U < U21 || U > U22)
4587 if(P2.Distance(C2->Value(U)) > MAX_TOLERANCE) return false;
4592 #include <TopoDS_TShape.hxx>
4593 //=======================================================================
4594 //function : isSameFace
4595 //purpose : Returns True if two faces coincide
4596 //=======================================================================
4597 static bool isSameFace(const TopoDS_Face& theFace1, const TopoDS_Face& theFace2)
4599 TopExp_Explorer E(theFace1, TopAbs_EDGE);
4600 TopTools_ListOfShape LS1, LS2;
4601 for(; E.More(); E.Next()) LS1.Append(E.Current());
4603 E.Init(theFace2, TopAbs_EDGE);
4604 for(; E.More(); E.Next()) LS2.Append(E.Current());
4606 //Compare the number of edges in the faces
4607 if(LS1.Extent() != LS2.Extent()) return false;
4609 double aMin = RealFirst(), aMax = RealLast();
4610 double xminB1=aMax, yminB1=aMax, zminB1=aMax, xminB2=aMax, yminB2=aMax, zminB2=aMax;
4611 double xmaxB1=aMin, ymaxB1=aMin, zmaxB1=aMin, xmaxB2=aMin, ymaxB2=aMin, zmaxB2=aMin;
4613 for(E.Init(theFace1, TopAbs_VERTEX); E.More(); E.Next()) {
4614 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4615 if(P.X() < xminB1) xminB1 = P.X();
4616 if(P.Y() < yminB1) yminB1 = P.Y();
4617 if(P.Z() < zminB1) zminB1 = P.Z();
4618 if(P.X() > xmaxB1) xmaxB1 = P.X();
4619 if(P.Y() > ymaxB1) ymaxB1 = P.Y();
4620 if(P.Z() > zmaxB1) zmaxB1 = P.Z();
4623 for(E.Init(theFace2, TopAbs_VERTEX); E.More(); E.Next()) {
4624 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4625 if(P.X() < xminB2) xminB2 = P.X();
4626 if(P.Y() < yminB2) yminB2 = P.Y();
4627 if(P.Z() < zminB2) zminB2 = P.Z();
4628 if(P.X() > xmaxB2) xmaxB2 = P.X();
4629 if(P.Y() > ymaxB2) ymaxB2 = P.Y();
4630 if(P.Z() > zmaxB2) zmaxB2 = P.Z();
4633 //Compare the bounding boxes of both faces
4634 if(gp_Pnt(xminB1, yminB1, zminB1).Distance(gp_Pnt(xminB2, yminB2, zminB2)) > MAX_TOLERANCE)
4637 if(gp_Pnt(xmaxB1, ymaxB1, zmaxB1).Distance(gp_Pnt(xmaxB2, ymaxB2, zmaxB2)) > MAX_TOLERANCE)
4640 Handle(Geom_Surface) S1 = BRep_Tool::Surface(theFace1);
4641 Handle(Geom_Surface) S2 = BRep_Tool::Surface(theFace2);
4643 //Check if there a coincidence of two surfaces at least in two points
4644 double U11, U12, V11, V12, U21, U22, V21, V22;
4645 BRepTools::UVBounds(theFace1, U11, U12, V11, V12);
4646 BRepTools::UVBounds(theFace2, U21, U22, V21, V22);
4648 double rangeU = U12-U11;
4649 double rangeV = V12-V11;
4650 double U = U11 + rangeU/3.0;
4651 double V = V11 + rangeV/3.0;
4652 gp_Pnt P1 = S1->Value(U, V);
4653 U = U11+rangeU*2.0/3.0;
4654 V = V11+rangeV*2.0/3.0;
4655 gp_Pnt P2 = S1->Value(U, V);
4657 if (!GeomLib_Tool::Parameters(S2, P1, MAX_TOLERANCE, U, V) || U < U21 || U > U22 || V < V21 || V > V22)
4660 if (P1.Distance(S2->Value(U,V)) > MAX_TOLERANCE) return false;
4662 if (!GeomLib_Tool::Parameters(S2, P2, MAX_TOLERANCE, U, V) || U < U21 || U > U22 || V < V21 || V > V22)
4665 if (P2.Distance(S2->Value(U, V)) > MAX_TOLERANCE) return false;
4667 //Check that each edge of the Face1 has a counterpart in the Face2
4668 TopTools_MapOfOrientedShape aMap;
4669 TopTools_ListIteratorOfListOfShape LSI1(LS1);
4670 for(; LSI1.More(); LSI1.Next()) {
4671 TopoDS_Edge E = TopoDS::Edge(LSI1.Value());
4672 bool isFound = false;
4673 TopTools_ListIteratorOfListOfShape LSI2(LS2);
4674 for(; LSI2.More(); LSI2.Next()) {
4675 TopoDS_Shape aValue = LSI2.Value();
4676 if(aMap.Contains(aValue)) continue; //To avoid checking already found edge several times
4677 if(isSameEdge(E, TopoDS::Edge(aValue))) {
4683 if(!isFound) return false;
4689 //=======================================================================
4690 //function : isSameSolid
4691 //purpose : Returns True if two solids coincide
4692 //=======================================================================
4693 bool isSameSolid(const TopoDS_Solid& theSolid1, const TopoDS_Solid& theSolid2)
4695 TopExp_Explorer E(theSolid1, TopAbs_FACE);
4696 TopTools_ListOfShape LS1, LS2;
4697 for(; E.More(); E.Next()) LS1.Append(E.Current());
4698 E.Init(theSolid2, TopAbs_FACE);
4699 for(; E.More(); E.Next()) LS2.Append(E.Current());
4701 if(LS1.Extent() != LS2.Extent()) return false;
4703 double aMin = RealFirst(), aMax = RealLast();
4704 double xminB1=aMax, yminB1=aMax, zminB1=aMax, xminB2=aMax, yminB2=aMax, zminB2=aMax;
4705 double xmaxB1=aMin, ymaxB1=aMin, zmaxB1=aMin, xmaxB2=aMin, ymaxB2=aMin, zmaxB2=aMin;
4707 for(E.Init(theSolid1, TopAbs_VERTEX); E.More(); E.Next()) {
4708 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4709 if(P.X() < xminB1) xminB1 = P.X();
4710 if(P.Y() < yminB1) yminB1 = P.Y();
4711 if(P.Z() < zminB1) zminB1 = P.Z();
4712 if(P.X() > xmaxB1) xmaxB1 = P.X();
4713 if(P.Y() > ymaxB1) ymaxB1 = P.Y();
4714 if(P.Z() > zmaxB1) zmaxB1 = P.Z();
4717 for(E.Init(theSolid2, TopAbs_VERTEX); E.More(); E.Next()) {
4718 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4719 if(P.X() < xminB2) xminB2 = P.X();
4720 if(P.Y() < yminB2) yminB2 = P.Y();
4721 if(P.Z() < zminB2) zminB2 = P.Z();
4722 if(P.X() > xmaxB2) xmaxB2 = P.X();
4723 if(P.Y() > ymaxB2) ymaxB2 = P.Y();
4724 if(P.Z() > zmaxB2) zmaxB2 = P.Z();
4727 //Compare the bounding boxes of both solids
4728 if(gp_Pnt(xminB1, yminB1, zminB1).Distance(gp_Pnt(xminB2, yminB2, zminB2)) > MAX_TOLERANCE)
4731 if(gp_Pnt(xmaxB1, ymaxB1, zmaxB1).Distance(gp_Pnt(xmaxB2, ymaxB2, zmaxB2)) > MAX_TOLERANCE)
4734 //Check that each face of the Solid1 has a counterpart in the Solid2
4735 TopTools_MapOfOrientedShape aMap;
4736 TopTools_ListIteratorOfListOfShape LSI1(LS1);
4737 for(; LSI1.More(); LSI1.Next()) {
4738 TopoDS_Face F = TopoDS::Face(LSI1.Value());
4739 bool isFound = false;
4740 TopTools_ListIteratorOfListOfShape LSI2(LS2);
4741 for(; LSI2.More(); LSI2.Next()) {
4742 if(aMap.Contains(LSI2.Value())) continue; //To avoid checking already found faces several times
4743 if(isSameFace(F, TopoDS::Face(LSI2.Value()))) {
4744 aMap.Add(LSI2.Value());
4749 if(!isFound) return false;
4755 //=======================================================================
4756 //function : GetSame
4758 //=======================================================================
4759 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetSame(const Handle(GEOM_Object)& theShapeWhere,
4760 const Handle(GEOM_Object)& theShapeWhat)
4763 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
4765 TopoDS_Shape aWhere = theShapeWhere->GetValue();
4766 TopoDS_Shape aWhat = theShapeWhat->GetValue();
4768 if (aWhere.IsNull() || aWhat.IsNull()) return NULL;
4771 bool isFound = false;
4772 TopoDS_Shape aSubShape;
4773 TopTools_MapOfShape aMap;
4775 if (aWhat.ShapeType() == TopAbs_COMPOUND || aWhat.ShapeType() == TopAbs_COMPSOLID) {
4776 TopoDS_Iterator It (aWhat, Standard_True, Standard_True);
4777 if (It.More()) aWhat = It.Value();
4780 SetErrorCode("Compounds of two or more shapes are not allowed for aWhat argument");
4785 switch (aWhat.ShapeType()) {
4786 case TopAbs_VERTEX: {
4787 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(aWhat));
4788 TopExp_Explorer E(aWhere, TopAbs_VERTEX);
4789 for(; E.More(); E.Next()) {
4790 if(!aMap.Add(E.Current())) continue;
4791 gp_Pnt P2 = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4792 if(P.Distance(P2) <= MAX_TOLERANCE) {
4794 aSubShape = E.Current();
4801 TopoDS_Edge anEdge = TopoDS::Edge(aWhat);
4802 TopExp_Explorer E(aWhere, TopAbs_EDGE);
4803 for(; E.More(); E.Next()) {
4804 if(!aMap.Add(E.Current())) continue;
4805 if(isSameEdge(anEdge, TopoDS::Edge(E.Current()))) {
4806 aSubShape = E.Current();
4814 TopoDS_Face aFace = TopoDS::Face(aWhat);
4815 TopExp_Explorer E(aWhere, TopAbs_FACE);
4816 for(; E.More(); E.Next()) {
4817 if(!aMap.Add(E.Current())) continue;
4818 if(isSameFace(aFace, TopoDS::Face(E.Current()))) {
4819 aSubShape = E.Current();
4826 case TopAbs_SOLID: {
4827 TopoDS_Solid aSolid = TopoDS::Solid(aWhat);
4828 TopExp_Explorer E(aWhere, TopAbs_SOLID);
4829 for(; E.More(); E.Next()) {
4830 if(!aMap.Add(E.Current())) continue;
4831 if(isSameSolid(aSolid, TopoDS::Solid(E.Current()))) {
4832 aSubShape = E.Current();
4844 TopTools_IndexedMapOfShape anIndices;
4845 TopExp::MapShapes(aWhere, anIndices);
4846 if (anIndices.Contains(aSubShape))
4847 anIndex = anIndices.FindIndex(aSubShape);
4850 if (anIndex < 0) return NULL;
4852 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
4854 anArray->SetValue(1, anIndex);
4856 Handle(GEOM_Object) aResult = GetEngine()->AddSubShape(theShapeWhere, anArray);
4857 Handle(GEOM_Function) aFunction = aResult->GetLastFunction();
4859 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetSame("
4860 << theShapeWhere << ", " << theShapeWhat << ")";