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
22 // File : GEOMImpl_IShapesOperations.cxx
24 // Author : modified by Lioka RAZAFINDRAZAKA (CEA) 22/06/2007
27 #include <Standard_Stream.hxx>
29 #include "GEOMImpl_IShapesOperations.hxx"
31 #include "GEOMImpl_Types.hxx"
33 #include "GEOMImpl_VectorDriver.hxx"
34 #include "GEOMImpl_ShapeDriver.hxx"
35 #include "GEOMImpl_CopyDriver.hxx"
36 #include "GEOMImpl_GlueDriver.hxx"
38 #include "GEOMImpl_IVector.hxx"
39 #include "GEOMImpl_IShapes.hxx"
40 #include "GEOMImpl_IGlue.hxx"
42 #include "GEOMImpl_Block6Explorer.hxx"
43 #include "GEOMImpl_IHealingOperations.hxx"
45 #include <GEOMImpl_Gen.hxx>
47 #include "GEOM_Function.hxx"
48 #include "GEOM_ISubShape.hxx"
49 #include "GEOM_PythonDump.hxx"
51 #include "GEOMAlgo_ClsfBox.hxx"
52 #include "GEOMAlgo_ClsfSolid.hxx"
53 #include "GEOMAlgo_CoupleOfShapes.hxx"
54 #include "GEOMAlgo_FinderShapeOn1.hxx"
55 #include "GEOMAlgo_FinderShapeOnQuad.hxx"
56 #include "GEOMAlgo_FinderShapeOn2.hxx"
57 #include "GEOMAlgo_GetInPlace.hxx"
58 #include "GEOMAlgo_GlueDetector.hxx"
59 #include "GEOMAlgo_ListIteratorOfListOfCoupleOfShapes.hxx"
60 #include "GEOMAlgo_ListOfCoupleOfShapes.hxx"
62 #include <Basics_OCCTVersion.hxx>
64 #include "utilities.h"
66 #include "Utils_ExceptHandlers.hxx"
68 #include <TFunction_DriverTable.hxx>
69 #include <TFunction_Driver.hxx>
70 #include <TFunction_Logbook.hxx>
71 #include <TDataStd_Integer.hxx>
72 #include <TDataStd_IntegerArray.hxx>
73 #include <TDataStd_ListIteratorOfListOfExtendedString.hxx>
74 #include <TDF_Tool.hxx>
76 #include <BRepExtrema_ExtCF.hxx>
77 #include <BRepExtrema_DistShapeShape.hxx>
79 #include <BRep_Tool.hxx>
80 #include <BRep_Builder.hxx>
81 #include <BRepTools.hxx>
82 #include <BRepGProp.hxx>
83 #include <BRepAdaptor_Curve.hxx>
84 #include <BRepAdaptor_Surface.hxx>
85 #include <BRepBndLib.hxx>
86 #include <BRepMesh_IncrementalMesh.hxx>
90 #include <TopExp_Explorer.hxx>
91 #include <TopLoc_Location.hxx>
93 #include <TopoDS_Shape.hxx>
94 #include <TopoDS_Solid.hxx>
95 #include <TopoDS_Face.hxx>
96 #include <TopoDS_Edge.hxx>
97 #include <TopoDS_Vertex.hxx>
98 #include <TopoDS_Compound.hxx>
99 #include <TopoDS_Iterator.hxx>
100 #include <TopTools_Array1OfShape.hxx>
101 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
102 #include <TopTools_IndexedMapOfShape.hxx>
103 #include <TopTools_ListIteratorOfListOfShape.hxx>
104 #include <TopTools_MapOfShape.hxx>
105 #include <TopTools_MapOfOrientedShape.hxx>
107 #include <Geom_Surface.hxx>
108 #include <Geom_Plane.hxx>
109 #include <Geom_SphericalSurface.hxx>
110 #include <Geom_CylindricalSurface.hxx>
111 #include <GeomAdaptor_Surface.hxx>
113 #include <GeomLib_Tool.hxx>
114 #include <Geom2d_Curve.hxx>
116 #include <Bnd_Box.hxx>
117 #include <GProp_GProps.hxx>
118 #include <TColStd_Array1OfReal.hxx>
119 #include <TColStd_HArray1OfInteger.hxx>
120 #include <TColStd_ListIteratorOfListOfInteger.hxx>
121 #include <TColStd_ListOfInteger.hxx>
122 #include <gp_Cylinder.hxx>
123 #include <gp_Lin.hxx>
124 #include <gp_Pnt.hxx>
128 #include <functional>
130 #include <Standard_NullObject.hxx>
131 #include <Standard_Failure.hxx>
132 #include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
134 // Includes added for GetInPlace algorithm improvement
136 #include <GEOMImpl_MeasureDriver.hxx>
137 #include <GEOMImpl_IMeasure.hxx>
138 #include <BRepBuilderAPI_MakeVertex.hxx>
140 #include <BRepClass_FaceClassifier.hxx>
141 #include <BRepClass3d_SolidClassifier.hxx>
142 #include <Precision.hxx>
144 #define STD_SORT_ALGO 1
146 //=============================================================================
150 //=============================================================================
151 GEOMImpl_IShapesOperations::GEOMImpl_IShapesOperations (GEOM_Engine* theEngine, int theDocID)
152 : GEOM_IOperations(theEngine, theDocID)
154 MESSAGE("GEOMImpl_IShapesOperations::GEOMImpl_IShapesOperations");
157 //=============================================================================
161 //=============================================================================
162 GEOMImpl_IShapesOperations::~GEOMImpl_IShapesOperations()
164 MESSAGE("GEOMImpl_IShapesOperations::~GEOMImpl_IShapesOperations");
167 //=============================================================================
171 //=============================================================================
172 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeEdge
173 (Handle(GEOM_Object) thePnt1, Handle(GEOM_Object) thePnt2)
177 if (thePnt1.IsNull() || thePnt2.IsNull()) return NULL;
179 //Add a new Edge object
180 Handle(GEOM_Object) anEdge = GetEngine()->AddObject(GetDocID(), GEOM_EDGE);
182 //Add a new Vector function
183 Handle(GEOM_Function) aFunction =
184 anEdge->AddFunction(GEOMImpl_VectorDriver::GetID(), VECTOR_TWO_PNT);
186 //Check if the function is set correctly
187 if (aFunction->GetDriverGUID() != GEOMImpl_VectorDriver::GetID()) return NULL;
189 GEOMImpl_IVector aPI (aFunction);
191 Handle(GEOM_Function) aRef1 = thePnt1->GetLastFunction();
192 Handle(GEOM_Function) aRef2 = thePnt2->GetLastFunction();
193 if (aRef1.IsNull() || aRef2.IsNull()) return NULL;
195 aPI.SetPoint1(aRef1);
196 aPI.SetPoint2(aRef2);
198 //Compute the Edge value
200 #if OCC_VERSION_LARGE > 0x06010000
203 if (!GetSolver()->ComputeFunction(aFunction)) {
204 SetErrorCode("Vector driver failed");
208 catch (Standard_Failure) {
209 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
210 SetErrorCode(aFail->GetMessageString());
214 //Make a Python command
215 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdge("
216 << thePnt1 << ", " << thePnt2 << ")";
222 //=============================================================================
224 * MakeEdgeOnCurveByLength
226 //=============================================================================
227 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeEdgeOnCurveByLength
228 (Handle(GEOM_Object) theRefCurve,
229 const Standard_Real theLength,
230 Handle(GEOM_Object) theStartPoint)
234 if (theRefCurve.IsNull()) return NULL;
236 //Add a new Edge object
237 Handle(GEOM_Object) anEdge = GetEngine()->AddObject(GetDocID(), GEOM_EDGE);
239 //Add a new Vector function
240 Handle(GEOM_Function) aFunction =
241 anEdge->AddFunction(GEOMImpl_ShapeDriver::GetID(), EDGE_CURVE_LENGTH);
243 //Check if the function is set correctly
244 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
246 GEOMImpl_IVector aPI (aFunction);
248 Handle(GEOM_Function) aRef1 = theRefCurve->GetLastFunction();
249 if (aRef1.IsNull()) return NULL;
250 aPI.SetPoint1(aRef1);
252 if (!theStartPoint.IsNull()) {
253 Handle(GEOM_Function) aRef2 = theStartPoint->GetLastFunction();
254 aPI.SetPoint2(aRef2);
257 aPI.SetParameter(theLength);
259 //Compute the Edge value
261 #if OCC_VERSION_LARGE > 0x06010000
264 if (!GetSolver()->ComputeFunction(aFunction)) {
265 SetErrorCode("Vector driver failed");
269 catch (Standard_Failure) {
270 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
271 SetErrorCode(aFail->GetMessageString());
275 //Make a Python command
276 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdgeOnCurveByLength("
277 << theRefCurve << ", " << theLength << ", " << theStartPoint << ")";
283 //=============================================================================
287 //=============================================================================
288 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeEdgeWire
289 (Handle(GEOM_Object) theWire,
290 const Standard_Real theLinearTolerance,
291 const Standard_Real theAngularTolerance)
295 if (theWire.IsNull()) return NULL;
297 //Add a new Edge object
298 Handle(GEOM_Object) anEdge = GetEngine()->AddObject(GetDocID(), GEOM_EDGE);
300 //Add a new Vector function
301 Handle(GEOM_Function) aFunction =
302 anEdge->AddFunction(GEOMImpl_ShapeDriver::GetID(), EDGE_WIRE);
304 //Check if the function is set correctly
305 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
307 GEOMImpl_IShapes aCI (aFunction);
309 Handle(GEOM_Function) aWire = theWire->GetLastFunction();
311 if (aWire.IsNull()) return NULL;
314 aCI.SetTolerance(theLinearTolerance);
315 aCI.SetAngularTolerance(theAngularTolerance);
317 //Compute the Edge value
319 #if OCC_VERSION_LARGE > 0x06010000
322 if (!GetSolver()->ComputeFunction(aFunction)) {
323 SetErrorCode("Shape driver failed");
327 catch (Standard_Failure) {
328 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
329 SetErrorCode(aFail->GetMessageString());
333 const double DEF_LIN_TOL = Precision::Confusion();
334 const double DEF_ANG_TOL = Precision::Angular();
335 //Make a Python command
336 if ( theAngularTolerance == DEF_ANG_TOL ) {
337 if ( theLinearTolerance == DEF_LIN_TOL )
338 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdgeWire("
341 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdgeWire("
342 << theWire << ", " << theLinearTolerance << ")";
345 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdgeWire("
346 << theWire << ", " << theLinearTolerance << ", "
347 << theAngularTolerance << ")";
354 //=============================================================================
358 //=============================================================================
359 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeWire
360 (std::list<Handle(GEOM_Object)> theShapes,
361 const Standard_Real theTolerance)
366 Handle(GEOM_Object) aWire = GetEngine()->AddObject(GetDocID(), GEOM_WIRE);
369 Handle(GEOM_Function) aFunction =
370 aWire->AddFunction(GEOMImpl_ShapeDriver::GetID(), WIRE_EDGES);
371 if (aFunction.IsNull()) return NULL;
373 //Check if the function is set correctly
374 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
376 GEOMImpl_IShapes aCI (aFunction);
377 aCI.SetTolerance(theTolerance);
379 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
382 std::list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
383 for (; it != theShapes.end(); it++) {
384 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
385 if (aRefSh.IsNull()) {
386 SetErrorCode("NULL argument shape for the shape construction");
389 aShapesSeq->Append(aRefSh);
391 aCI.SetShapes(aShapesSeq);
395 #if OCC_VERSION_LARGE > 0x06010000
398 if (!GetSolver()->ComputeFunction(aFunction)) {
399 SetErrorCode("Shape driver failed");
403 catch (Standard_Failure) {
404 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
405 SetErrorCode(aFail->GetMessageString());
409 //Make a Python command
410 GEOM::TPythonDump pd (aFunction);
411 pd << aWire << " = geompy.MakeWire([";
414 it = theShapes.begin();
415 if (it != theShapes.end()) {
417 while (it != theShapes.end()) {
418 pd << ", " << (*it++);
421 pd << "], " << theTolerance << ")";
427 //=============================================================================
431 //=============================================================================
432 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFace (Handle(GEOM_Object) theWire,
433 const bool isPlanarWanted)
437 if (theWire.IsNull()) return NULL;
439 //Add a new Face object
440 Handle(GEOM_Object) aFace = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
442 //Add a new Shape function for creation of a face from a wire
443 Handle(GEOM_Function) aFunction =
444 aFace->AddFunction(GEOMImpl_ShapeDriver::GetID(), FACE_WIRE);
445 if (aFunction.IsNull()) return NULL;
447 //Check if the function is set correctly
448 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
450 GEOMImpl_IShapes aCI (aFunction);
452 Handle(GEOM_Function) aRefWire = theWire->GetLastFunction();
454 if (aRefWire.IsNull()) return NULL;
456 aCI.SetBase(aRefWire);
457 aCI.SetIsPlanar(isPlanarWanted);
459 //Compute the Face value
460 Standard_Boolean isWarning = Standard_False;
462 #if OCC_VERSION_LARGE > 0x06010000
465 if (!GetSolver()->ComputeFunction(aFunction)) {
466 SetErrorCode("Shape driver failed to compute a face");
470 catch (Standard_Failure) {
471 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
472 SetErrorCode(aFail->GetMessageString());
473 // to provide warning
474 if (!aFunction->GetValue().IsNull()) {
475 isWarning = Standard_True;
481 //Make a Python command
482 GEOM::TPythonDump(aFunction) << aFace << " = geompy.MakeFace("
483 << theWire << ", " << (int)isPlanarWanted << ")";
485 // to provide warning
486 if (!isWarning) SetErrorCode(OK);
490 //=============================================================================
494 //=============================================================================
495 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFaceWires
496 (std::list<Handle(GEOM_Object)> theShapes,
497 const bool isPlanarWanted)
502 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
505 Handle(GEOM_Function) aFunction =
506 aShape->AddFunction(GEOMImpl_ShapeDriver::GetID(), FACE_WIRES);
507 if (aFunction.IsNull()) return NULL;
509 //Check if the function is set correctly
510 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
512 GEOMImpl_IShapes aCI (aFunction);
514 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
517 std::list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
518 for (; it != theShapes.end(); it++) {
519 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
520 if (aRefSh.IsNull()) {
521 SetErrorCode("NULL argument shape for the face construction");
524 aShapesSeq->Append(aRefSh);
526 aCI.SetShapes(aShapesSeq);
528 aCI.SetIsPlanar(isPlanarWanted);
531 Standard_Boolean isWarning = Standard_False;
533 #if OCC_VERSION_LARGE > 0x06010000
536 if (!GetSolver()->ComputeFunction(aFunction)) {
537 SetErrorCode("Shape driver failed");
541 catch (Standard_Failure) {
542 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
543 SetErrorCode(aFail->GetMessageString());
544 // to provide warning
545 if (!aFunction->GetValue().IsNull()) {
546 isWarning = Standard_True;
552 //Make a Python command
553 GEOM::TPythonDump pd (aFunction);
554 pd << aShape << " = geompy.MakeFaceWires([";
557 it = theShapes.begin();
558 if (it != theShapes.end()) {
560 while (it != theShapes.end()) {
561 pd << ", " << (*it++);
564 pd << "], " << (int)isPlanarWanted << ")";
566 // to provide warning
567 if (!isWarning) SetErrorCode(OK);
571 //=============================================================================
575 //=============================================================================
576 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeShell
577 (std::list<Handle(GEOM_Object)> theShapes)
579 return MakeShape(theShapes, GEOM_SHELL, SHELL_FACES, "MakeShell");
582 //=============================================================================
586 //=============================================================================
587 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeSolidShells
588 (std::list<Handle(GEOM_Object)> theShapes)
590 return MakeShape(theShapes, GEOM_SOLID, SOLID_SHELLS, "MakeSolid");
593 //=============================================================================
597 //=============================================================================
598 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeCompound
599 (std::list<Handle(GEOM_Object)> theShapes)
601 return MakeShape(theShapes, GEOM_COMPOUND, COMPOUND_SHAPES, "MakeCompound");
604 //=============================================================================
608 //=============================================================================
609 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeShape
610 (std::list<Handle(GEOM_Object)> theShapes,
611 const Standard_Integer theObjectType,
612 const Standard_Integer theFunctionType,
613 const TCollection_AsciiString& theMethodName)
618 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), theObjectType);
621 Handle(GEOM_Function) aFunction =
622 aShape->AddFunction(GEOMImpl_ShapeDriver::GetID(), theFunctionType);
623 if (aFunction.IsNull()) return NULL;
625 //Check if the function is set correctly
626 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
628 GEOMImpl_IShapes aCI (aFunction);
630 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
633 std::list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
634 for (; it != theShapes.end(); it++) {
635 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
636 if (aRefSh.IsNull()) {
637 SetErrorCode("NULL argument shape for the shape construction");
640 aShapesSeq->Append(aRefSh);
642 aCI.SetShapes(aShapesSeq);
646 #if OCC_VERSION_LARGE > 0x06010000
649 if (!GetSolver()->ComputeFunction(aFunction)) {
650 SetErrorCode("Shape driver failed");
654 catch (Standard_Failure) {
655 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
656 SetErrorCode(aFail->GetMessageString());
660 //Make a Python command
661 GEOM::TPythonDump pd (aFunction);
662 pd << aShape << " = geompy." << theMethodName.ToCString() << "([";
665 it = theShapes.begin();
666 if (it != theShapes.end()) {
668 while (it != theShapes.end()) {
669 pd << ", " << (*it++);
678 //=============================================================================
682 //=============================================================================
683 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeGlueFaces
684 (Handle(GEOM_Object) theShape,
685 const Standard_Real theTolerance,
686 const Standard_Boolean doKeepNonSolids)
690 if (theShape.IsNull()) return NULL;
692 //Add a new Glued object
693 Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
695 //Add a new Glue function
696 Handle(GEOM_Function) aFunction;
697 aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_FACES);
698 if (aFunction.IsNull()) return NULL;
700 //Check if the function is set correctly
701 if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
703 GEOMImpl_IGlue aCI (aFunction);
705 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
706 if (aRefShape.IsNull()) return NULL;
708 aCI.SetBase(aRefShape);
709 aCI.SetTolerance(theTolerance);
710 aCI.SetKeepNonSolids(doKeepNonSolids);
712 //Compute the sub-shape value
713 Standard_Boolean isWarning = Standard_False;
715 #if OCC_VERSION_LARGE > 0x06010000
718 if (!GetSolver()->ComputeFunction(aFunction)) {
719 SetErrorCode("Shape driver failed to glue faces");
723 catch (Standard_Failure) {
724 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
725 SetErrorCode(aFail->GetMessageString());
726 // to provide warning
727 if (!aFunction->GetValue().IsNull()) {
728 isWarning = Standard_True;
734 //Make a Python command
735 GEOM::TPythonDump(aFunction) << aGlued << " = geompy.MakeGlueFaces("
736 << theShape << ", " << theTolerance << ")";
738 // to provide warning
739 if (!isWarning) SetErrorCode(OK);
743 //=============================================================================
747 //=============================================================================
749 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetGlueFaces
750 (Handle(GEOM_Object) theShape,
751 const Standard_Real theTolerance)
755 if (theShape.IsNull()) return NULL;
756 TopoDS_Shape aShape = theShape->GetValue();
757 if (aShape.IsNull()) return NULL;
759 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
761 Standard_Integer iErr;
763 GEOMAlgo_Gluer1 aGluer;
764 GEOMAlgo_ListIteratorOfListOfCoupleOfShapes aItCS;
765 GEOMAlgo_CoupleOfShapes aCS;
766 GEOMAlgo_ListOfCoupleOfShapes aLCS;
768 //aGluer = new GEOMAlgo_Gluer1;
769 aGluer.SetShape(aShape);
770 aGluer.SetTolerance(theTolerance);
772 iErr = aGluer.ErrorStatus();
773 if (iErr) return NULL;
775 TopTools_ListOfShape listShape;
776 const GEOMAlgo_ListOfCoupleOfShapes& aLCSG = aGluer.GluedFaces();
778 aItCS.Initialize(aLCSG);
779 for (; aItCS.More(); aItCS.Next()) {
780 const GEOMAlgo_CoupleOfShapes& aCSG = aItCS.Value();
781 listShape.Append(aCSG.Shape1());
784 TopTools_ListIteratorOfListOfShape itSub (listShape);
785 TCollection_AsciiString anAsciiList, anEntry;
786 TopTools_IndexedMapOfShape anIndices;
787 TopExp::MapShapes(aShape, anIndices);
788 Handle(TColStd_HArray1OfInteger) anArray;
789 Handle(GEOM_Object) anObj;
790 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
791 TopoDS_Shape aValue = itSub.Value();
792 anArray = new TColStd_HArray1OfInteger(1,1);
793 anArray->SetValue(1, anIndices.FindIndex(aValue));
794 anObj = GetEngine()->AddSubShape(theShape, anArray);
795 if (!anObj.IsNull()) {
798 // for python command
799 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
800 anAsciiList += anEntry;
805 //Make a Python command
806 if( anAsciiList.Length() > 0 ) {
807 anAsciiList.Trunc(anAsciiList.Length() - 1);
808 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
809 GEOM::TPythonDump pd (aFunction, true);
810 pd << "[" << anAsciiList.ToCString();
811 pd << "] = geompy.GetGlueFaces(" << theShape << ", " << theTolerance << ")";
820 //=============================================================================
822 * MakeGlueFacesByList
824 //=============================================================================
825 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeGlueFacesByList
826 (Handle(GEOM_Object) theShape,
827 const Standard_Real theTolerance,
828 std::list<Handle(GEOM_Object)> theFaces,
829 const Standard_Boolean doKeepNonSolids,
830 const Standard_Boolean doGlueAllEdges)
834 if (theShape.IsNull()) return NULL;
836 //Add a new Glued object
837 Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
839 //Add a new Glue function
840 Handle(GEOM_Function) aFunction;
841 aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_FACES_BY_LIST);
842 if (aFunction.IsNull()) return NULL;
844 //Check if the function is set correctly
845 if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
847 GEOMImpl_IGlue aCI (aFunction);
849 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
850 if (aRefShape.IsNull()) return NULL;
852 aCI.SetBase(aRefShape);
853 aCI.SetTolerance(theTolerance);
854 aCI.SetKeepNonSolids(doKeepNonSolids);
855 aCI.SetGlueAllEdges(doGlueAllEdges);
857 Handle(TColStd_HSequenceOfTransient) aFaces = new TColStd_HSequenceOfTransient;
858 std::list<Handle(GEOM_Object)>::iterator it = theFaces.begin();
859 for (; it != theFaces.end(); it++) {
860 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
861 if (aRefSh.IsNull()) {
862 SetErrorCode("NULL argument shape for the shape construction");
865 aFaces->Append(aRefSh);
867 aCI.SetFaces(aFaces);
869 //Compute the sub-shape value
870 Standard_Boolean isWarning = Standard_False;
872 #if OCC_VERSION_LARGE > 0x06010000
875 if (!GetSolver()->ComputeFunction(aFunction)) {
876 SetErrorCode("Shape driver failed to glue faces");
880 catch (Standard_Failure) {
881 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
882 SetErrorCode(aFail->GetMessageString());
883 // to provide warning
884 if (!aFunction->GetValue().IsNull()) {
885 isWarning = Standard_True;
891 //Make a Python command
893 GEOM::TPythonDump pd(aFunction);
894 pd << aGlued << " = geompy.MakeGlueFacesByList("
895 << theShape << ", " << theTolerance << ", [";
897 it = theFaces.begin();
898 if (it != theFaces.end()) {
900 while (it != theFaces.end()) {
901 pd << ", " << (*it++);
904 pd << "], " << (bool)doKeepNonSolids << ", " << (bool)doGlueAllEdges << ")";
906 // to provide warning
907 if (!isWarning) SetErrorCode(OK);
911 //=============================================================================
915 //=============================================================================
916 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeGlueEdges
917 (Handle(GEOM_Object) theShape,
918 const Standard_Real theTolerance)
922 if (theShape.IsNull()) return NULL;
924 //Add a new Glued object
925 Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
927 //Add a new Glue function
928 Handle(GEOM_Function) aFunction;
929 aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_EDGES);
930 if (aFunction.IsNull()) return NULL;
932 //Check if the function is set correctly
933 if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
935 GEOMImpl_IGlue aCI (aFunction);
937 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
938 if (aRefShape.IsNull()) return NULL;
940 aCI.SetBase(aRefShape);
941 aCI.SetTolerance(theTolerance);
942 aCI.SetKeepNonSolids(true);
944 //Compute the sub-shape value
945 Standard_Boolean isWarning = Standard_False;
947 #if OCC_VERSION_LARGE > 0x06010000
950 if (!GetSolver()->ComputeFunction(aFunction)) {
951 SetErrorCode("Shape driver failed to glue edges");
955 catch (Standard_Failure) {
956 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
957 SetErrorCode(aFail->GetMessageString());
958 // to provide warning
959 if (!aFunction->GetValue().IsNull()) {
960 isWarning = Standard_True;
966 //Make a Python command
967 GEOM::TPythonDump(aFunction) << aGlued << " = geompy.MakeGlueEdges("
968 << theShape << ", " << theTolerance << ")";
970 // to provide warning
971 if (!isWarning) SetErrorCode(OK);
975 //=============================================================================
979 //=============================================================================
980 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetGlueShapes
981 (Handle(GEOM_Object) theShape,
982 const Standard_Real theTolerance,
983 const TopAbs_ShapeEnum theType)
987 if (theShape.IsNull()) return NULL;
988 TopoDS_Shape aShape = theShape->GetValue();
989 if (aShape.IsNull()) return NULL;
991 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
993 GEOMAlgo_GlueDetector aGluer;
994 aGluer.SetArgument(aShape);
995 aGluer.SetTolerance(theTolerance);
997 Standard_Integer iErr = aGluer.ErrorStatus();
998 if (iErr) return NULL;
1000 TCollection_AsciiString anAsciiList, anEntry;
1001 TopTools_IndexedMapOfShape anIndices;
1002 TopExp::MapShapes(aShape, anIndices);
1003 Handle(TColStd_HArray1OfInteger) anArray;
1004 Handle(GEOM_Object) anObj;
1006 TopTools_ListOfShape listOnePerSet;
1008 const TopTools_DataMapOfShapeListOfShape& aImages = aGluer.Images();
1009 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape aItDMSLS (aImages);
1010 for (int index = 1; aItDMSLS.More(); aItDMSLS.Next(), ++index) {
1012 //const TopoDS_Shape& aSkey = aItDMSLS.Key();
1014 // list of shapes of the argument that can be glued
1015 const TopTools_ListOfShape& aLSD = aItDMSLS.Value();
1017 //listShape.Append(aLSD.First());
1018 TopoDS_Shape aValue = aLSD.First();
1020 if (aValue.ShapeType() == theType) {
1021 listOnePerSet.Append(aValue);
1025 // for stable order of returned entities
1026 GEOMImpl_IShapesOperations::SortShapes(listOnePerSet, Standard_False);
1028 TopTools_ListIteratorOfListOfShape aListIt (listOnePerSet);
1029 for (; aListIt.More(); aListIt.Next()) {
1030 TopoDS_Shape aValue = aListIt.Value();
1031 anArray = new TColStd_HArray1OfInteger(1,1);
1032 anArray->SetValue(1, anIndices.FindIndex(aValue));
1033 anObj = GetEngine()->AddSubShape(theShape, anArray);
1034 if (!anObj.IsNull()) {
1035 aSeq->Append(anObj);
1037 // for python command
1038 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
1039 anAsciiList += anEntry;
1044 // Make a Python command
1045 if (anAsciiList.Length() > 0) {
1046 anAsciiList.Trunc(anAsciiList.Length() - 1);
1047 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
1048 GEOM::TPythonDump pd (aFunction, /*append=*/true);
1049 pd << "[" << anAsciiList.ToCString();
1050 if (theType == TopAbs_FACE)
1051 pd << "] = geompy.GetGlueFaces(" << theShape << ", " << theTolerance << ")";
1052 else if (theType == TopAbs_EDGE)
1053 pd << "] = geompy.GetGlueEdges(" << theShape << ", " << theTolerance << ")";
1061 //=============================================================================
1063 * MakeGlueEdgesByList
1065 //=============================================================================
1066 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeGlueEdgesByList
1067 (Handle(GEOM_Object) theShape,
1068 const Standard_Real theTolerance,
1069 std::list<Handle(GEOM_Object)> theEdges)
1073 if (theShape.IsNull()) return NULL;
1075 //Add a new Glued object
1076 Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
1078 //Add a new Glue function
1079 Handle(GEOM_Function) aFunction;
1080 aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_EDGES_BY_LIST);
1081 if (aFunction.IsNull()) return NULL;
1083 //Check if the function is set correctly
1084 if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
1086 GEOMImpl_IGlue aCI (aFunction);
1088 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
1089 if (aRefShape.IsNull()) return NULL;
1091 aCI.SetBase(aRefShape);
1092 aCI.SetTolerance(theTolerance);
1093 aCI.SetKeepNonSolids(true);
1095 Handle(TColStd_HSequenceOfTransient) anEdges = new TColStd_HSequenceOfTransient;
1096 std::list<Handle(GEOM_Object)>::iterator it = theEdges.begin();
1097 for (; it != theEdges.end(); it++) {
1098 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
1099 if (aRefSh.IsNull()) {
1100 SetErrorCode("NULL argument shape for the shape construction");
1103 anEdges->Append(aRefSh);
1105 aCI.SetFaces(anEdges);
1107 //Compute the sub-shape value
1108 Standard_Boolean isWarning = Standard_False;
1110 #if OCC_VERSION_LARGE > 0x06010000
1113 if (!GetSolver()->ComputeFunction(aFunction)) {
1114 SetErrorCode("Shape driver failed to glue edges");
1118 catch (Standard_Failure) {
1119 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1120 SetErrorCode(aFail->GetMessageString());
1121 // to provide warning
1122 if (!aFunction->GetValue().IsNull()) {
1123 isWarning = Standard_True;
1129 //Make a Python command
1131 GEOM::TPythonDump pd (aFunction);
1132 pd << aGlued << " = geompy.MakeGlueEdgesByList("
1133 << theShape << ", " << theTolerance << ", [";
1135 it = theEdges.begin();
1136 if (it != theEdges.end()) {
1138 while (it != theEdges.end()) {
1139 pd << ", " << (*it++);
1144 // to provide warning
1145 if (!isWarning) SetErrorCode(OK);
1149 //=============================================================================
1151 * GetExistingSubObjects
1153 //=============================================================================
1154 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetExistingSubObjects
1155 (Handle(GEOM_Object) theShape,
1156 const Standard_Boolean theGroupsOnly)
1160 if (theShape.IsNull()) return NULL;
1162 Handle(GEOM_Function) aMainShape = theShape->GetLastFunction();
1163 if (aMainShape.IsNull()) return NULL;
1165 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1166 SetErrorCode(NOT_FOUND_ANY);
1168 if (!aMainShape->HasSubShapeReferences()) return aSeq;
1169 const TDataStd_ListOfExtendedString& aListEntries = aMainShape->GetSubShapeReferences();
1170 if (aListEntries.IsEmpty()) return aSeq;
1174 TCollection_AsciiString anAsciiList;
1176 TDataStd_ListIteratorOfListOfExtendedString anIt (aListEntries);
1177 for (; anIt.More(); anIt.Next()) {
1178 TCollection_ExtendedString anEntry = anIt.Value();
1179 Standard_Integer aStrLen = anEntry.LengthOfCString();
1180 char* anEntryStr = new char[aStrLen];
1181 anEntry.ToUTF8CString(anEntryStr);
1182 Handle(GEOM_Object) anObj = GetEngine()->GetObject(GetDocID(), anEntryStr, false);
1183 if (!anObj.IsNull()) {
1184 if (!theGroupsOnly || anObj->GetType() == GEOM_GROUP) {
1185 aSeq->Append(anObj);
1187 // for python command
1188 anAsciiList += anEntryStr;
1192 delete [] anEntryStr;
1195 if (aSeq->Length() == 0) {
1196 SetErrorCode(NOT_FOUND_ANY);
1200 //Make a Python command
1201 anAsciiList.Trunc(anAsciiList.Length() - 1);
1203 GEOM::TPythonDump pd (aMainShape, /*append=*/true);
1204 pd << "[" << anAsciiList.ToCString();
1205 pd << "] = geompy.GetExistingSubObjects(";
1206 pd << theShape << ", " << (bool)theGroupsOnly << ")";
1213 //=============================================================================
1217 //=============================================================================
1218 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::MakeExplode
1219 (Handle(GEOM_Object) theShape,
1220 const Standard_Integer theShapeType,
1221 const Standard_Boolean isSorted,
1222 const ExplodeType theExplodeType)
1226 if (theShape.IsNull()) return NULL;
1227 TopoDS_Shape aShape = theShape->GetValue();
1228 if (aShape.IsNull()) return NULL;
1230 Handle(GEOM_Function) aMainShape = theShape->GetLastFunction();
1232 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1233 Handle(GEOM_Object) anObj;
1234 TopTools_MapOfShape mapShape;
1235 TopTools_ListOfShape listShape;
1237 if (aShape.ShapeType() == TopAbs_COMPOUND &&
1238 (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
1239 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPSOLID ||
1240 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPOUND))
1242 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
1243 for (; It.More(); It.Next()) {
1244 if (mapShape.Add(It.Value())) {
1245 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
1246 TopAbs_ShapeEnum(theShapeType) == It.Value().ShapeType()) {
1247 listShape.Append(It.Value());
1252 else if (theExplodeType != EXPLODE_NEW_EXCLUDE_MAIN || aShape.ShapeType() != theShapeType) // issue 0021079
1254 TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
1255 for (; exp.More(); exp.Next())
1256 if (mapShape.Add(exp.Current()))
1257 listShape.Append(exp.Current());
1260 if (listShape.IsEmpty()) {
1261 //SetErrorCode("The given shape has no sub-shapes of the requested type");
1262 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
1267 bool isOldSorting = false;
1268 if (theExplodeType == EXPLODE_OLD_INCLUDE_MAIN)
1269 isOldSorting = true;
1270 SortShapes(listShape, isOldSorting);
1273 TopTools_IndexedMapOfShape anIndices;
1274 TopExp::MapShapes(aShape, anIndices);
1275 Handle(TColStd_HArray1OfInteger) anArray;
1277 TopTools_ListIteratorOfListOfShape itSub (listShape);
1278 TCollection_AsciiString anAsciiList, anEntry;
1279 for (int index = 1; itSub.More(); itSub.Next(), ++index)
1281 TopoDS_Shape aValue = itSub.Value();
1282 anArray = new TColStd_HArray1OfInteger(1,1);
1283 anArray->SetValue(1, anIndices.FindIndex(aValue));
1285 //anObj = GetEngine()->AddSubShape(theShape, anArray);
1287 anObj = GetEngine()->AddObject(GetDocID(), GEOM_SUBSHAPE);
1288 Handle(GEOM_Function) aFunction = anObj->AddFunction(GEOM_Object::GetSubShapeID(), 1);
1289 if (aFunction.IsNull()) return aSeq;
1291 GEOM_ISubShape aSSI (aFunction);
1292 aSSI.SetMainShape(aMainShape);
1293 aSSI.SetIndices(anArray);
1295 // Set function value directly, as we know it.
1296 // Usage of Solver here would lead to significant loss of time,
1297 // because GEOM_SubShapeDriver will build TopTools_IndexedMapOfShape
1298 // on the main shape for each being calculated sub-shape separately.
1299 aFunction->SetValue(aValue);
1301 // Put this subshape in the list of subshapes of theMainShape
1302 aMainShape->AddSubShapeReference(aFunction);
1305 if (!anObj.IsNull()) {
1306 aSeq->Append(anObj);
1308 // for python command
1309 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
1310 anAsciiList += anEntry;
1315 //Make a Python command
1316 anAsciiList.Trunc(anAsciiList.Length() - 1);
1318 GEOM::TPythonDump pd (aMainShape, /*append=*/true);
1319 pd << "[" << anAsciiList.ToCString() << "] = geompy.";
1320 switch (theExplodeType) {
1321 case EXPLODE_NEW_EXCLUDE_MAIN:
1322 pd << "ExtractShapes(" << theShape << ", "
1323 << TopAbs_ShapeEnum(theShapeType) << ", " << (isSorted ? "True" : "False") << ")";
1325 case EXPLODE_NEW_INCLUDE_MAIN:
1326 pd << "SubShapeAll" << (isSorted ? "SortedCentres(" : "(")
1327 << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
1329 case EXPLODE_OLD_INCLUDE_MAIN:
1330 pd << "SubShapeAll" << (isSorted ? "Sorted(" : "(")
1331 << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
1340 //=============================================================================
1344 //=============================================================================
1345 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::SubShapeAllIDs
1346 (Handle(GEOM_Object) theShape,
1347 const Standard_Integer theShapeType,
1348 const Standard_Boolean isSorted,
1349 const ExplodeType theExplodeType)
1353 if (theShape.IsNull()) return NULL;
1354 TopoDS_Shape aShape = theShape->GetValue();
1355 if (aShape.IsNull()) return NULL;
1357 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
1358 TopTools_MapOfShape mapShape;
1359 TopTools_ListOfShape listShape;
1361 if (aShape.ShapeType() == TopAbs_COMPOUND &&
1362 (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
1363 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPSOLID ||
1364 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPOUND))
1366 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
1367 for (; It.More(); It.Next()) {
1368 if (mapShape.Add(It.Value())) {
1369 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
1370 TopAbs_ShapeEnum(theShapeType) == It.Value().ShapeType()) {
1371 listShape.Append(It.Value());
1376 else if (theExplodeType != EXPLODE_NEW_EXCLUDE_MAIN || aShape.ShapeType() != theShapeType) // issue 0021079
1378 TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
1379 for (; exp.More(); exp.Next())
1380 if (mapShape.Add(exp.Current()))
1381 listShape.Append(exp.Current());
1384 if (listShape.IsEmpty()) {
1385 //SetErrorCode("The given shape has no sub-shapes of the requested type");
1386 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
1391 bool isOldSorting = false;
1392 if (theExplodeType == EXPLODE_OLD_INCLUDE_MAIN)
1393 isOldSorting = true;
1394 SortShapes(listShape, isOldSorting);
1397 TopTools_IndexedMapOfShape anIndices;
1398 TopExp::MapShapes(aShape, anIndices);
1399 Handle(TColStd_HArray1OfInteger) anArray;
1401 TopTools_ListIteratorOfListOfShape itSub (listShape);
1402 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
1403 TopoDS_Shape aValue = itSub.Value();
1404 aSeq->Append(anIndices.FindIndex(aValue));
1407 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
1409 //Make a Python command
1410 GEOM::TPythonDump pd (aFunction, /*append=*/true);
1411 pd << "listSubShapeIDs = geompy.SubShapeAll";
1412 switch (theExplodeType) {
1413 case EXPLODE_NEW_EXCLUDE_MAIN:
1415 case EXPLODE_NEW_INCLUDE_MAIN:
1416 pd << (isSorted ? "SortedCentresIDs(" : "IDs(")
1417 << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
1419 case EXPLODE_OLD_INCLUDE_MAIN:
1420 pd << (isSorted ? "SortedIDs(" : "IDs(")
1421 << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
1430 //=============================================================================
1434 //=============================================================================
1435 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetSubShape
1436 (Handle(GEOM_Object) theMainShape,
1437 const Standard_Integer theID)
1441 if (theMainShape.IsNull()) return NULL;
1443 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
1444 anArray->SetValue(1, theID);
1445 Handle(GEOM_Object) anObj = GetEngine()->AddSubShape(theMainShape, anArray,true);
1446 if (anObj.IsNull()) {
1447 SetErrorCode("Can not get a sub-shape with the given ID");
1451 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1453 //Make a Python command
1454 GEOM::TPythonDump(aFunction) << anObj << " = geompy.GetSubShape("
1455 << theMainShape << ", [" << theID << "])";
1461 //=============================================================================
1465 //=============================================================================
1466 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::MakeSubShapes
1467 (Handle(GEOM_Object) theMainShape,
1468 Handle(TColStd_HArray1OfInteger) theIndices)
1472 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1474 if (!theIndices->Length()) {
1475 SetErrorCode(NOT_FOUND_ANY);
1479 if (theMainShape.IsNull()) return NULL;
1480 TopoDS_Shape aShape = theMainShape->GetValue();
1481 if (aShape.IsNull()) return NULL;
1483 Handle(GEOM_Function) aMainShape = theMainShape->GetLastFunction();
1485 TopTools_IndexedMapOfShape anIndices;
1486 TopExp::MapShapes(aShape, anIndices);
1488 Handle(TColStd_HArray1OfInteger) anArray;
1489 Handle(GEOM_Object) anObj;
1491 TCollection_AsciiString anAsciiList, anEntry;
1492 Standard_Integer i, low = theIndices->Lower(), up = theIndices->Upper();
1493 for (i = low; i <= up; i++) {
1494 int id = theIndices->Value(i);
1495 if (1 <= id && id <= anIndices.Extent()) {
1496 TopoDS_Shape aValue = anIndices.FindKey(id);
1497 anArray = new TColStd_HArray1OfInteger(1,1);
1498 anArray->SetValue(1, id);
1500 anObj = GetEngine()->AddObject(GetDocID(), GEOM_SUBSHAPE);
1501 if (!anObj.IsNull()) {
1502 Handle(GEOM_Function) aFunction = anObj->AddFunction(GEOM_Object::GetSubShapeID(), 1);
1503 if (aFunction.IsNull()) return aSeq;
1505 GEOM_ISubShape aSSI (aFunction);
1506 aSSI.SetMainShape(aMainShape);
1507 aSSI.SetIndices(anArray);
1509 // Set function value directly, as we know it.
1510 // Usage of Solver here would lead to significant loss of time,
1511 // because GEOM_SubShapeDriver will build TopTools_IndexedMapOfShape
1512 // on the main shape for each being calculated sub-shape separately.
1513 aFunction->SetValue(aValue);
1515 // Put this subshape in the list of subshapes of theMainShape
1516 aMainShape->AddSubShapeReference(aFunction);
1518 aSeq->Append(anObj);
1520 // for python command
1521 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
1522 anAsciiList += anEntry;
1528 //Make a Python command
1529 anAsciiList.Trunc(anAsciiList.Length() - 1);
1531 GEOM::TPythonDump pd (aMainShape, /*append=*/true);
1532 pd << "[" << anAsciiList.ToCString() << "] = geompy.SubShapes("
1533 << theMainShape << ", [" ;
1534 for (i = low; i <= up - 1; i++) {
1535 pd << theIndices->Value(i) << ", ";
1537 pd << theIndices->Value(up) << "])";
1544 //=============================================================================
1548 //=============================================================================
1549 Standard_Integer GEOMImpl_IShapesOperations::GetSubShapeIndex (Handle(GEOM_Object) theMainShape,
1550 Handle(GEOM_Object) theSubShape)
1554 TopoDS_Shape aMainShape = theMainShape->GetValue();
1555 TopoDS_Shape aSubShape = theSubShape->GetValue();
1557 if (aMainShape.IsNull() || aSubShape.IsNull()) return -1;
1559 TopTools_IndexedMapOfShape anIndices;
1560 TopExp::MapShapes(aMainShape, anIndices);
1561 if (anIndices.Contains(aSubShape)) {
1563 return anIndices.FindIndex(aSubShape);
1569 //=============================================================================
1573 //=============================================================================
1574 Standard_Integer GEOMImpl_IShapesOperations::GetTopologyIndex (Handle(GEOM_Object) theMainShape,
1575 Handle(GEOM_Object) theSubShape)
1579 TopoDS_Shape aMainShape = theMainShape->GetValue();
1580 TopoDS_Shape aSubShape = theSubShape->GetValue();
1582 if (aMainShape.IsNull() || aSubShape.IsNull()) {
1583 SetErrorCode("Null argument shape given");
1588 if (aSubShape.ShapeType() == TopAbs_COMPOUND) {
1590 TopTools_ListOfShape CL;
1591 CL.Append(aMainShape);
1592 TopTools_ListIteratorOfListOfShape itC;
1593 for (itC.Initialize(CL); itC.More(); itC.Next()) {
1594 for (it.Initialize(itC.Value()); it.More(); it.Next()) {
1595 if (it.Value().ShapeType() == TopAbs_COMPOUND) {
1596 if (it.Value().IsSame(aSubShape))
1600 CL.Append(it.Value());
1605 TopExp_Explorer anExp (aMainShape, aSubShape.ShapeType());
1606 TopTools_MapOfShape M;
1607 for (; anExp.More(); anExp.Next()) {
1608 if (M.Add(anExp.Current())) {
1609 if (anExp.Current().IsSame(aSubShape))
1616 SetErrorCode("The sub-shape does not belong to the main shape");
1620 //=============================================================================
1622 * GetShapeTypeString
1624 //=============================================================================
1625 TCollection_AsciiString GEOMImpl_IShapesOperations::GetShapeTypeString (Handle(GEOM_Object) theShape)
1629 TCollection_AsciiString aTypeName ("Null Shape");
1631 TopoDS_Shape aShape = theShape->GetValue();
1632 if (aShape.IsNull())
1635 switch (aShape.ShapeType() )
1637 case TopAbs_COMPOUND:
1638 aTypeName = "Compound";
1640 case TopAbs_COMPSOLID:
1641 aTypeName = "Compound Solid";
1644 aTypeName = "Solid";
1647 aTypeName = "Shell";
1651 BRepAdaptor_Surface surf (TopoDS::Face(aShape));
1652 if (surf.GetType() == GeomAbs_Plane)
1653 aTypeName = "Plane";
1654 else if (surf.GetType() == GeomAbs_Cylinder)
1655 aTypeName = "Cylindrical Face";
1656 else if (surf.GetType() == GeomAbs_Sphere)
1657 aTypeName = "Spherical Face";
1658 else if (surf.GetType() == GeomAbs_Torus)
1659 aTypeName = "Toroidal Face";
1660 else if (surf.GetType() == GeomAbs_Cone)
1661 aTypeName = "Conical Face";
1663 aTypeName = "GEOM::FACE";
1671 BRepAdaptor_Curve curv (TopoDS::Edge(aShape));
1672 if (curv.GetType() == GeomAbs_Line) {
1673 if ((Abs(curv.FirstParameter()) >= 1E6) ||
1674 (Abs(curv.LastParameter()) >= 1E6))
1678 } else if (curv.GetType() == GeomAbs_Circle) {
1679 if (curv.IsClosed())
1680 aTypeName = "Circle";
1689 aTypeName = "Vertex";
1692 aTypeName = "Shape";
1695 aTypeName = "Shape of unknown type";
1701 //=============================================================================
1705 //=============================================================================
1706 Standard_Integer GEOMImpl_IShapesOperations::NumberOfSubShapes
1707 (Handle(GEOM_Object) theShape,
1708 const Standard_Integer theShapeType)
1711 Standard_Integer nbShapes = 0;
1713 if (theShape.IsNull()) return -1;
1714 TopoDS_Shape aShape = theShape->GetValue();
1715 if (aShape.IsNull()) return -1;
1718 TopTools_MapOfShape mapShape;
1720 if (aShape.ShapeType() == TopAbs_COMPOUND &&
1721 (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
1722 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPSOLID ||
1723 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPOUND)) {
1724 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
1725 for (; It.More(); It.Next()) {
1726 if (mapShape.Add(It.Value())) {
1727 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
1728 TopAbs_ShapeEnum(theShapeType) == It.Value().ShapeType()) {
1734 TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
1735 for (; exp.More(); exp.Next())
1736 if (mapShape.Add(exp.Current()))
1742 #if OCC_VERSION_LARGE > 0x06010000
1745 int iType, nbTypes [TopAbs_SHAPE];
1746 for (iType = 0; iType < TopAbs_SHAPE; ++iType)
1748 nbTypes[aShape.ShapeType()]++;
1750 TopTools_MapOfShape aMapOfShape;
1751 aMapOfShape.Add(aShape);
1752 TopTools_ListOfShape aListOfShape;
1753 aListOfShape.Append(aShape);
1755 TopTools_ListIteratorOfListOfShape itL (aListOfShape);
1756 for (; itL.More(); itL.Next()) {
1757 TopoDS_Iterator it (itL.Value());
1758 for (; it.More(); it.Next()) {
1759 TopoDS_Shape s = it.Value();
1760 if (aMapOfShape.Add(s)) {
1761 aListOfShape.Append(s);
1762 nbTypes[s.ShapeType()]++;
1767 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE)
1768 nbShapes = aMapOfShape.Extent();
1770 nbShapes = nbTypes[theShapeType];
1772 catch (Standard_Failure) {
1773 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1774 SetErrorCode(aFail->GetMessageString());
1782 //=============================================================================
1786 //=============================================================================
1787 Handle(GEOM_Object) GEOMImpl_IShapesOperations::ReverseShape(Handle(GEOM_Object) theShape)
1791 if (theShape.IsNull()) return NULL;
1794 //Add a new reversed object
1795 Handle(GEOM_Object) aReversed = GetEngine()->AddObject(GetDocID(), theShape->GetType());
1797 //Add a new Revese function
1798 Handle(GEOM_Function) aFunction;
1799 aFunction = aReversed->AddFunction(GEOMImpl_ShapeDriver::GetID(), REVERSE_ORIENTATION);
1800 if (aFunction.IsNull()) return NULL;
1802 //Check if the function is set correctly
1803 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
1805 GEOMImpl_IShapes aSI (aFunction);
1807 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
1808 if (aRefShape.IsNull()) return NULL;
1810 aSI.SetBase(aRefShape);
1812 //Compute the sub-shape value
1814 #if OCC_VERSION_LARGE > 0x06010000
1817 if (!GetSolver()->ComputeFunction(aFunction)) {
1818 SetErrorCode("Shape driver failed to reverse shape");
1822 catch (Standard_Failure) {
1823 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1824 SetErrorCode(aFail->GetMessageString());
1828 //Make a Python command
1829 GEOM::TPythonDump(aFunction) << aReversed
1830 << " = geompy.ChangeOrientation(" << theShape << ")";
1835 Handle(GEOM_Object) aReversed;
1837 GEOM_Engine* anEngine = GetEngine();
1838 //GEOMImpl_Gen* aGen = dynamic_cast<GEOMImpl_Gen*>(anEngine);
1839 GEOMImpl_Gen* aGen = (GEOMImpl_Gen*)anEngine;
1842 GEOMImpl_IHealingOperations* anIHealingOperations =
1843 aGen->GetIHealingOperations(GetDocID());
1844 aReversed = anIHealingOperations->ChangeOrientationCopy(theShape);
1845 SetErrorCode(anIHealingOperations->GetErrorCode());
1851 //=============================================================================
1855 //=============================================================================
1856 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetFreeFacesIDs
1857 (Handle(GEOM_Object) theShape)
1861 if (theShape.IsNull()) return NULL;
1862 TopoDS_Shape aShape = theShape->GetValue();
1863 if (aShape.IsNull()) return NULL;
1865 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
1867 TopTools_IndexedDataMapOfShapeListOfShape mapFaceBlocks;
1868 GEOMImpl_Block6Explorer::MapShapesAndAncestors
1869 (aShape, TopAbs_FACE, TopAbs_SOLID, mapFaceBlocks);
1871 Standard_Integer ind = 1, nbFaces = mapFaceBlocks.Extent();
1874 SetErrorCode("The given shape has no faces");
1878 TopTools_IndexedMapOfShape anIndices;
1879 TopExp::MapShapes(aShape, anIndices);
1881 Standard_Integer id;
1882 for (; ind <= nbFaces; ind++) {
1883 if (mapFaceBlocks.FindFromIndex(ind).Extent() != 2) {
1884 id = anIndices.FindIndex(mapFaceBlocks.FindKey(ind));
1889 //The explode doesn't change object so no new function is required.
1890 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
1892 //Make a Python command
1893 GEOM::TPythonDump(aFunction, /*append=*/true)
1894 << "listFreeFacesIDs = geompy.GetFreeFacesIDs(" << theShape << ")";
1900 //=======================================================================
1901 //function : GetSharedShapes
1903 //=======================================================================
1904 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetSharedShapes
1905 (Handle(GEOM_Object) theShape1,
1906 Handle(GEOM_Object) theShape2,
1907 const Standard_Integer theShapeType)
1911 if (theShape1.IsNull() || theShape2.IsNull()) return NULL;
1913 TopoDS_Shape aShape1 = theShape1->GetValue();
1914 TopoDS_Shape aShape2 = theShape2->GetValue();
1916 if (aShape1.IsNull() || aShape2.IsNull()) return NULL;
1918 TopTools_IndexedMapOfShape anIndices;
1919 TopExp::MapShapes(aShape1, anIndices);
1920 Handle(TColStd_HArray1OfInteger) anArray;
1922 TopTools_IndexedMapOfShape mapShape1;
1923 TopExp::MapShapes(aShape1, TopAbs_ShapeEnum(theShapeType), mapShape1);
1925 Handle(GEOM_Object) anObj;
1926 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1927 TCollection_AsciiString anAsciiList, anEntry;
1929 TopTools_MapOfShape mapShape2;
1930 TopExp_Explorer exp (aShape2, TopAbs_ShapeEnum(theShapeType));
1931 for (; exp.More(); exp.Next()) {
1932 TopoDS_Shape aSS = exp.Current();
1933 if (mapShape2.Add(aSS) && mapShape1.Contains(aSS)) {
1934 anArray = new TColStd_HArray1OfInteger(1,1);
1935 anArray->SetValue(1, anIndices.FindIndex(aSS));
1936 anObj = GetEngine()->AddSubShape(theShape1, anArray);
1937 aSeq->Append(anObj);
1939 // for python command
1940 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
1941 anAsciiList += anEntry;
1946 if (aSeq->IsEmpty()) {
1947 SetErrorCode("The given shapes have no shared sub-shapes of the requested type");
1951 //Make a Python command
1952 anAsciiList.Trunc(anAsciiList.Length() - 1);
1954 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1956 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
1957 << "] = geompy.GetSharedShapes(" << theShape1 << ", "
1958 << theShape2 << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
1964 //=======================================================================
1965 //function : GetSharedShapes
1967 //=======================================================================
1968 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetSharedShapes
1969 (std::list<Handle(GEOM_Object)> theShapes,
1970 const Standard_Integer theShapeType)
1974 int aLen = theShapes.size();
1975 if (aLen < 1) return NULL;
1978 std::list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
1980 Handle(GEOM_Object) aMainObj = (*it++);
1981 Handle(GEOM_Function) aMainShape = aMainObj->GetLastFunction();
1982 if (aMainShape.IsNull()) {
1983 SetErrorCode("NULL shape for GetSharedShapes");
1987 TopoDS_Shape aShape1 = aMainShape->GetValue();
1988 if (aShape1.IsNull()) return NULL;
1990 TopTools_IndexedMapOfShape anIndices;
1991 TopExp::MapShapes(aShape1, anIndices);
1993 TopTools_IndexedMapOfShape mapSelected;
1994 TopExp::MapShapes(aShape1, TopAbs_ShapeEnum(theShapeType), mapSelected);
1996 // Find shared shapes
1998 TopoDS_Compound aCurrSelection;
2000 for (; it != theShapes.end(); it++, ind++) {
2001 Handle(GEOM_Function) aRefShape = (*it)->GetLastFunction();
2002 if (aRefShape.IsNull()) {
2003 SetErrorCode("NULL shape for GetSharedShapes");
2007 TopoDS_Compound aCompound;
2008 B.MakeCompound(aCompound);
2010 TopoDS_Shape aShape2 = aRefShape->GetValue();
2011 if (aShape2.IsNull()) return NULL;
2013 TopTools_MapOfShape mapShape2;
2014 TopExp_Explorer exp (aShape2, TopAbs_ShapeEnum(theShapeType));
2015 for (; exp.More(); exp.Next()) {
2016 TopoDS_Shape aSS = exp.Current();
2017 if (mapShape2.Add(aSS) && mapSelected.Contains(aSS)) {
2018 B.Add(aCompound, aSS);
2022 mapSelected.Clear();
2023 TopExp::MapShapes(aCompound, TopAbs_ShapeEnum(theShapeType), mapSelected);
2024 aCurrSelection = aCompound;
2027 // Create GEOM_Object for each found shared shape (collected in aCurrSelection)
2028 Handle(GEOM_Object) anObj;
2029 Handle(TColStd_HArray1OfInteger) anArray;
2030 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
2031 TCollection_AsciiString anAsciiList, anEntry;
2033 TopoDS_Iterator itSel (aCurrSelection, Standard_True, Standard_True);
2034 for (; itSel.More(); itSel.Next()) {
2035 anArray = new TColStd_HArray1OfInteger(1,1);
2036 anArray->SetValue(1, anIndices.FindIndex(itSel.Value()));
2037 anObj = GetEngine()->AddSubShape(aMainObj, anArray);
2038 aSeq->Append(anObj);
2040 // for python command
2041 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
2042 anAsciiList += anEntry;
2046 if (aSeq->IsEmpty()) {
2047 SetErrorCode("The given shapes have no shared sub-shapes of the requested type");
2051 // Make a Python command
2052 anAsciiList.Trunc(anAsciiList.Length() - 1);
2054 GEOM::TPythonDump pd (aMainShape, /*append=*/true);
2055 pd << "[" << anAsciiList.ToCString()
2056 << "] = geompy.GetSharedShapesMulti([";
2058 it = theShapes.begin();
2060 while (it != theShapes.end()) {
2061 pd << ", " << (*it++);
2064 pd << "], " << TopAbs_ShapeEnum(theShapeType) << ")";
2070 //=============================================================================
2074 //=============================================================================
2075 static GEOM::TPythonDump& operator<< (GEOM::TPythonDump& theDump,
2076 const GEOMAlgo_State theState)
2079 case GEOMAlgo_ST_IN:
2080 theDump << "geompy.GEOM.ST_IN";
2082 case GEOMAlgo_ST_OUT:
2083 theDump << "geompy.GEOM.ST_OUT";
2085 case GEOMAlgo_ST_ON:
2086 theDump << "geompy.GEOM.ST_ON";
2088 case GEOMAlgo_ST_ONIN:
2089 theDump << "geompy.GEOM.ST_ONIN";
2091 case GEOMAlgo_ST_ONOUT:
2092 theDump << "geompy.GEOM.ST_ONOUT";
2095 theDump << "geompy.GEOM.ST_UNKNOWN";
2101 //=======================================================================
2102 //function : checkTypeShapesOn
2104 * \brief Checks if theShapeType parameter of GetShapesOnXXX() is OK
2105 * \param theShapeType - the shape type to check
2106 * \retval bool - result of the check
2108 //=======================================================================
2109 bool GEOMImpl_IShapesOperations::checkTypeShapesOn(const Standard_Integer theShapeType)
2111 if (theShapeType != TopAbs_VERTEX &&
2112 theShapeType != TopAbs_EDGE &&
2113 theShapeType != TopAbs_FACE &&
2114 theShapeType != TopAbs_SOLID) {
2115 SetErrorCode("Only solids, vertices, edges or faces can be found by this method");
2121 //=======================================================================
2122 //function : makePlane
2124 * \brief Creates Geom_Plane
2125 * \param theAx1 - shape object defining plane parameters
2126 * \retval Handle(Geom_Surface) - resulting surface
2128 //=======================================================================
2129 Handle(Geom_Surface) GEOMImpl_IShapesOperations::makePlane(const TopoDS_Shape& anAx1)
2131 if (anAx1.ShapeType() != TopAbs_EDGE) return NULL;
2132 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
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 plane normal vector");
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");
2145 return new Geom_Plane(aLoc, aVec);
2148 //=======================================================================
2149 //function : makeCylinder
2151 * \brief Creates Geom_CylindricalSurface
2152 * \param theAx1 - edge defining cylinder axis
2153 * \param theRadius - cylinder radius
2154 * \retval Handle(Geom_Surface) - resulting surface
2156 //=======================================================================
2157 Handle(Geom_Surface) GEOMImpl_IShapesOperations::makeCylinder(const TopoDS_Shape& anAxis,
2158 const Standard_Real theRadius)
2160 //Axis of the cylinder
2161 if (anAxis.ShapeType() != TopAbs_EDGE) {
2162 SetErrorCode("Not an edge given for the axis");
2165 TopoDS_Edge anEdge = TopoDS::Edge(anAxis);
2166 TopoDS_Vertex V1, V2;
2167 TopExp::Vertices(anEdge, V1, V2, Standard_True);
2168 if (V1.IsNull() || V2.IsNull()) {
2169 SetErrorCode("Bad edge given for the axis");
2172 gp_Pnt aLoc = BRep_Tool::Pnt(V1);
2173 gp_Vec aVec (aLoc, BRep_Tool::Pnt(V2));
2174 if (aVec.Magnitude() < Precision::Confusion()) {
2175 SetErrorCode("Vector with null magnitude given");
2179 gp_Ax3 anAx3 (aLoc, aVec);
2180 return new Geom_CylindricalSurface(anAx3, theRadius);
2183 //=======================================================================
2184 //function : getShapesOnBoxIDs
2186 * \brief Find IDs of subshapes complying with given status about surface
2187 * \param theBox - the box to check state of subshapes against
2188 * \param theShape - the shape to explore
2189 * \param theShapeType - type of subshape of theShape
2190 * \param theState - required state
2191 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
2193 //=======================================================================
2194 Handle(TColStd_HSequenceOfInteger)
2195 GEOMImpl_IShapesOperations::getShapesOnBoxIDs(const Handle(GEOM_Object)& theBox,
2196 const Handle(GEOM_Object)& theShape,
2197 const Standard_Integer theShapeType,
2198 GEOMAlgo_State theState)
2200 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
2202 TopoDS_Shape aBox = theBox->GetValue();
2203 TopoDS_Shape aShape = theShape->GetValue();
2205 // Check presence of triangulation, build if need
2206 if (!CheckTriangulation(aShape)) {
2207 SetErrorCode("Cannot build triangulation on the shape");
2212 GEOMAlgo_FinderShapeOn2 aFinder;
2213 Standard_Real aTol = 0.0001; // default value
2215 Handle(GEOMAlgo_ClsfBox) aClsfBox = new GEOMAlgo_ClsfBox;
2216 aClsfBox->SetBox(aBox);
2218 aFinder.SetShape(aShape);
2219 aFinder.SetTolerance(aTol);
2220 aFinder.SetClsf(aClsfBox);
2221 aFinder.SetShapeType( (TopAbs_ShapeEnum)theShapeType );
2222 aFinder.SetState(theState);
2225 // Interprete results
2226 Standard_Integer iErr = aFinder.ErrorStatus();
2227 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
2229 MESSAGE(" iErr : " << iErr);
2230 TCollection_AsciiString aMsg (" iErr : ");
2231 aMsg += TCollection_AsciiString(iErr);
2235 Standard_Integer iWrn = aFinder.WarningStatus();
2236 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
2238 MESSAGE(" *** iWrn : " << iWrn);
2241 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
2243 if (listSS.Extent() < 1) {
2244 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
2245 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
2249 // Fill sequence of object IDs
2250 aSeqOfIDs = new TColStd_HSequenceOfInteger;
2252 TopTools_IndexedMapOfShape anIndices;
2253 TopExp::MapShapes(aShape, anIndices);
2255 TopTools_ListIteratorOfListOfShape itSub (listSS);
2256 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
2257 int id = anIndices.FindIndex(itSub.Value());
2258 aSeqOfIDs->Append(id);
2264 //=======================================================================
2265 //function : GetShapesOnBoxIDs
2267 * \brief Find subshapes complying with given status about surface
2268 * \param theBox - the box to check state of subshapes against
2269 * \param theShape - the shape to explore
2270 * \param theShapeType - type of subshape of theShape
2271 * \param theState - required state
2272 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
2274 //=======================================================================
2275 Handle(TColStd_HSequenceOfInteger)
2276 GEOMImpl_IShapesOperations::GetShapesOnBoxIDs(const Handle(GEOM_Object)& theBox,
2277 const Handle(GEOM_Object)& theShape,
2278 const Standard_Integer theShapeType,
2279 GEOMAlgo_State theState)
2281 // Find subshapes ids
2282 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2283 getShapesOnBoxIDs (theBox, theShape, theShapeType, theState);
2284 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2287 // The GetShapesOnBox() doesn't change object so no new function is required.
2288 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theBox)->GetLastFunction();
2290 // Make a Python command
2291 GEOM::TPythonDump(aFunction)
2292 << "listShapesOnBoxIDs = geompy.GetShapesOnBoxIDs("
2295 << TopAbs_ShapeEnum(theShapeType) << ", "
2302 //=======================================================================
2303 //function : GetShapesOnBox
2305 * \brief Find subshapes complying with given status about surface
2306 * \param theBox - the box to check state of subshapes against
2307 * \param theShape - the shape to explore
2308 * \param theShapeType - type of subshape of theShape
2309 * \param theState - required state
2310 * \retval Handle(TColStd_HSequenceOfTransient) - found subshapes
2312 //=======================================================================
2313 Handle(TColStd_HSequenceOfTransient)
2314 GEOMImpl_IShapesOperations::GetShapesOnBox(const Handle(GEOM_Object)& theBox,
2315 const Handle(GEOM_Object)& theShape,
2316 const Standard_Integer theShapeType,
2317 GEOMAlgo_State theState)
2319 // Find subshapes ids
2320 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2321 getShapesOnBoxIDs (theBox, theShape, theShapeType, theState);
2322 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2325 // Find objects by indices
2326 TCollection_AsciiString anAsciiList;
2327 Handle(TColStd_HSequenceOfTransient) aSeq;
2328 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
2329 if ( aSeq.IsNull() || aSeq->IsEmpty() )
2332 // Make a Python command
2334 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2335 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2337 GEOM::TPythonDump(aFunction)
2338 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnBox("
2341 << TopAbs_ShapeEnum(theShapeType) << ", "
2348 //=======================================================================
2349 //function : getShapesOnShapeIDs
2351 * \brief Find IDs of subshapes complying with given status about surface
2352 * \param theCheckShape - the shape to check state of subshapes against
2353 * \param theShape - the shape to explore
2354 * \param theShapeType - type of subshape of theShape
2355 * \param theState - required state
2356 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
2358 //=======================================================================
2359 Handle(TColStd_HSequenceOfInteger)
2360 GEOMImpl_IShapesOperations::getShapesOnShapeIDs
2361 (const Handle(GEOM_Object)& theCheckShape,
2362 const Handle(GEOM_Object)& theShape,
2363 const Standard_Integer theShapeType,
2364 GEOMAlgo_State theState)
2366 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
2368 TopoDS_Shape aCheckShape = theCheckShape->GetValue();
2369 TopoDS_Shape aShape = theShape->GetValue();
2370 TopTools_ListOfShape res;
2372 // Check presence of triangulation, build if need
2373 if (!CheckTriangulation(aShape)) {
2374 SetErrorCode("Cannot build triangulation on the shape");
2379 GEOMAlgo_FinderShapeOn2 aFinder;
2380 Standard_Real aTol = 0.0001; // default value
2382 Handle(GEOMAlgo_ClsfSolid) aClsfSolid = new GEOMAlgo_ClsfSolid;
2383 aClsfSolid->SetShape(aCheckShape);
2385 aFinder.SetShape(aShape);
2386 aFinder.SetTolerance(aTol);
2387 aFinder.SetClsf(aClsfSolid);
2388 aFinder.SetShapeType( (TopAbs_ShapeEnum)theShapeType );
2389 aFinder.SetState(theState);
2392 // Interprete results
2393 Standard_Integer iErr = aFinder.ErrorStatus();
2394 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
2397 SetErrorCode("theCheckShape must be a solid");
2400 MESSAGE(" iErr : " << iErr);
2401 TCollection_AsciiString aMsg (" iErr : ");
2402 aMsg += TCollection_AsciiString(iErr);
2407 Standard_Integer iWrn = aFinder.WarningStatus();
2408 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
2410 MESSAGE(" *** iWrn : " << iWrn);
2413 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
2415 if (listSS.Extent() < 1) {
2416 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
2417 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
2420 // Fill sequence of object IDs
2421 aSeqOfIDs = new TColStd_HSequenceOfInteger;
2423 TopTools_IndexedMapOfShape anIndices;
2424 TopExp::MapShapes(aShape, anIndices);
2426 TopTools_ListIteratorOfListOfShape itSub (listSS);
2427 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
2428 int id = anIndices.FindIndex(itSub.Value());
2429 aSeqOfIDs->Append(id);
2435 //=======================================================================
2436 //function : GetShapesOnShapeIDs
2438 * \brief Find subshapes complying with given status about surface
2439 * \param theCheckShape - the shape to check state of subshapes against
2440 * \param theShape - the shape to explore
2441 * \param theShapeType - type of subshape of theShape
2442 * \param theState - required state
2443 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
2445 //=======================================================================
2446 Handle(TColStd_HSequenceOfInteger)
2447 GEOMImpl_IShapesOperations::GetShapesOnShapeIDs
2448 (const Handle(GEOM_Object)& theCheckShape,
2449 const Handle(GEOM_Object)& theShape,
2450 const Standard_Integer theShapeType,
2451 GEOMAlgo_State theState)
2453 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2454 getShapesOnShapeIDs (theCheckShape, theShape, theShapeType, theState);
2456 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2459 // The GetShapesOnShape() doesn't change object so no new function is required.
2460 Handle(GEOM_Function) aFunction =
2461 GEOM::GetCreatedLast(theShape,theCheckShape)->GetLastFunction();
2463 // Make a Python command
2464 GEOM::TPythonDump(aFunction)
2465 << "listShapesOnBoxIDs = geompy.GetShapesOnShapeIDs("
2466 << theCheckShape << ", "
2468 << TopAbs_ShapeEnum(theShapeType) << ", "
2475 //=======================================================================
2476 //function : GetShapesOnShape
2478 * \brief Find subshapes complying with given status about surface
2479 * \param theCheckShape - the shape to check state of subshapes against
2480 * \param theShape - the shape to explore
2481 * \param theShapeType - type of subshape of theShape
2482 * \param theState - required state
2483 * \retval Handle(TColStd_HSequenceOfTransient) - found subshapes
2485 //=======================================================================
2486 Handle(TColStd_HSequenceOfTransient)
2487 GEOMImpl_IShapesOperations::GetShapesOnShape
2488 (const Handle(GEOM_Object)& theCheckShape,
2489 const Handle(GEOM_Object)& theShape,
2490 const Standard_Integer theShapeType,
2491 GEOMAlgo_State theState)
2493 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2494 getShapesOnShapeIDs (theCheckShape, theShape, theShapeType, theState);
2495 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2498 // Find objects by indices
2499 TCollection_AsciiString anAsciiList;
2500 Handle(TColStd_HSequenceOfTransient) aSeq;
2501 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
2503 if ( aSeq.IsNull() || aSeq->IsEmpty() )
2506 // Make a Python command
2508 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2509 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2511 GEOM::TPythonDump(aFunction)
2512 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnShape("
2513 << theCheckShape << ", "
2515 << TopAbs_ShapeEnum(theShapeType) << ", "
2522 //=======================================================================
2523 //function : GetShapesOnShapeAsCompound
2524 //=======================================================================
2525 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetShapesOnShapeAsCompound
2526 (const Handle(GEOM_Object)& theCheckShape,
2527 const Handle(GEOM_Object)& theShape,
2528 const Standard_Integer theShapeType,
2529 GEOMAlgo_State theState)
2531 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2532 getShapesOnShapeIDs (theCheckShape, theShape, theShapeType, theState);
2534 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2537 // Find objects by indices
2538 TCollection_AsciiString anAsciiList;
2539 Handle(TColStd_HSequenceOfTransient) aSeq;
2540 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
2542 if ( aSeq.IsNull() || aSeq->IsEmpty() )
2545 TopoDS_Compound aCompound;
2547 B.MakeCompound(aCompound);
2549 for(; i<=aSeq->Length(); i++) {
2550 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(aSeq->Value(i));
2551 TopoDS_Shape aShape_i = anObj->GetValue();
2552 B.Add(aCompound,aShape_i);
2555 //Add a new result object
2556 Handle(GEOM_Object) aRes = GetEngine()->AddObject(GetDocID(), GEOM_SHAPES_ON_SHAPE);
2557 Handle(GEOM_Function) aFunction =
2558 aRes->AddFunction(GEOMImpl_ShapeDriver::GetID(), SHAPES_ON_SHAPE);
2559 aFunction->SetValue(aCompound);
2561 GEOM::TPythonDump(aFunction)
2562 << aRes << " = geompy.GetShapesOnShapeAsCompound("
2563 << theCheckShape << ", "
2565 << TopAbs_ShapeEnum(theShapeType) << ", "
2573 //=======================================================================
2574 //function : getShapesOnSurfaceIDs
2576 * \brief Find IDs of subshapes complying with given status about surface
2577 * \param theSurface - the surface to check state of subshapes against
2578 * \param theShape - the shape to explore
2579 * \param theShapeType - type of subshape of theShape
2580 * \param theState - required state
2581 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
2583 //=======================================================================
2584 Handle(TColStd_HSequenceOfInteger)
2585 GEOMImpl_IShapesOperations::getShapesOnSurfaceIDs(const Handle(Geom_Surface)& theSurface,
2586 const TopoDS_Shape& theShape,
2587 TopAbs_ShapeEnum theShapeType,
2588 GEOMAlgo_State theState)
2590 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
2592 // Check presence of triangulation, build if need
2593 if (!CheckTriangulation(theShape)) {
2594 SetErrorCode("Cannot build triangulation on the shape");
2598 // BEGIN: Mantis issue 0020961: Error on a pipe T-Shape
2599 // Compute tolerance
2600 Standard_Real T, VertMax = -RealLast();
2602 #if OCC_VERSION_LARGE > 0x06010000
2605 for (TopExp_Explorer ExV (theShape, TopAbs_VERTEX); ExV.More(); ExV.Next()) {
2606 TopoDS_Vertex Vertex = TopoDS::Vertex(ExV.Current());
2607 T = BRep_Tool::Tolerance(Vertex);
2612 catch (Standard_Failure) {
2613 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2614 SetErrorCode(aFail->GetMessageString());
2617 // END: Mantis issue 0020961
2620 GEOMAlgo_FinderShapeOn1 aFinder;
2621 //Standard_Real aTol = 0.0001; // default value
2622 Standard_Real aTol = VertMax; // Mantis issue 0020961
2624 aFinder.SetShape(theShape);
2625 aFinder.SetTolerance(aTol);
2626 aFinder.SetSurface(theSurface);
2627 aFinder.SetShapeType(theShapeType);
2628 aFinder.SetState(theState);
2630 // Sets the minimal number of inner points for the faces that do not have own
2631 // inner points at all (for e.g. rectangular planar faces have just 2 triangles).
2633 aFinder.SetNbPntsMin(3);
2634 // Sets the maximal number of inner points for edges or faces.
2635 // It is usefull for the cases when this number is very big (e.g =2000) to improve
2636 // the performance. If this value =0, all inner points will be taken into account.
2638 aFinder.SetNbPntsMax(100);
2642 // Interprete results
2643 Standard_Integer iErr = aFinder.ErrorStatus();
2644 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
2646 MESSAGE(" iErr : " << iErr);
2647 TCollection_AsciiString aMsg (" iErr : ");
2648 aMsg += TCollection_AsciiString(iErr);
2652 Standard_Integer iWrn = aFinder.WarningStatus();
2653 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
2655 MESSAGE(" *** iWrn : " << iWrn);
2658 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
2660 if (listSS.Extent() < 1) {
2661 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
2662 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
2666 // Fill sequence of object IDs
2667 aSeqOfIDs = new TColStd_HSequenceOfInteger;
2669 TopTools_IndexedMapOfShape anIndices;
2670 TopExp::MapShapes(theShape, anIndices);
2672 TopTools_ListIteratorOfListOfShape itSub (listSS);
2673 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
2674 int id = anIndices.FindIndex(itSub.Value());
2675 aSeqOfIDs->Append(id);
2681 //=======================================================================
2682 //function : getObjectsShapesOn
2684 * \brief Find shape objects and their entries by their ids
2685 * \param theShapeIDs - incoming shape ids
2686 * \param theShapeEntries - outgoing entries like "entry1, entry2, ..."
2687 * \retval Handle(TColStd_HSequenceOfTransient) - found shape objects
2689 //=======================================================================
2690 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::
2691 getObjectsShapesOn(const Handle(GEOM_Object)& theShape,
2692 const Handle(TColStd_HSequenceOfInteger)& theShapeIDs,
2693 TCollection_AsciiString & theShapeEntries)
2695 Handle(TColStd_HSequenceOfTransient) aSeq;
2697 if ( !theShapeIDs.IsNull() && theShapeIDs->Length() > 0 )
2699 aSeq = new TColStd_HSequenceOfTransient;
2700 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
2701 TCollection_AsciiString anEntry;
2702 for ( int i = 1; i <= theShapeIDs->Length(); ++i )
2704 anArray->SetValue(1, theShapeIDs->Value( i ));
2705 Handle(GEOM_Object) anObj = GetEngine()->AddSubShape(theShape, anArray);
2706 aSeq->Append( anObj );
2708 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
2709 if ( i != 1 ) theShapeEntries += ",";
2710 theShapeEntries += anEntry;
2716 //=======================================================================
2717 //function : getShapesOnSurface
2719 * \brief Find subshapes complying with given status about surface
2720 * \param theSurface - the surface to check state of subshapes against
2721 * \param theShape - the shape to explore
2722 * \param theShapeType - type of subshape of theShape
2723 * \param theState - required state
2724 * \param theShapeEntries - outgoing entries like "entry1, entry2, ..."
2725 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
2727 //=======================================================================
2728 Handle(TColStd_HSequenceOfTransient)
2729 GEOMImpl_IShapesOperations::getShapesOnSurface(const Handle(Geom_Surface)& theSurface,
2730 const Handle(GEOM_Object)& theShape,
2731 TopAbs_ShapeEnum theShapeType,
2732 GEOMAlgo_State theState,
2733 TCollection_AsciiString & theShapeEntries)
2735 // Find subshapes ids
2736 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2737 getShapesOnSurfaceIDs (theSurface, theShape->GetValue(), theShapeType, theState);
2738 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2741 return getObjectsShapesOn( theShape, aSeqOfIDs, theShapeEntries );
2744 //=============================================================================
2748 //=============================================================================
2749 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnPlane
2750 (const Handle(GEOM_Object)& theShape,
2751 const Standard_Integer theShapeType,
2752 const Handle(GEOM_Object)& theAx1,
2753 const GEOMAlgo_State theState)
2757 if (theShape.IsNull() || theAx1.IsNull()) return NULL;
2759 TopoDS_Shape aShape = theShape->GetValue();
2760 TopoDS_Shape anAx1 = theAx1->GetValue();
2762 if (aShape.IsNull() || anAx1.IsNull()) return NULL;
2764 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2765 if ( !checkTypeShapesOn( theShapeType ))
2769 Handle(Geom_Surface) aPlane = makePlane( anAx1 );
2770 if ( aPlane.IsNull() )
2774 TCollection_AsciiString anAsciiList;
2775 Handle(TColStd_HSequenceOfTransient) aSeq;
2776 aSeq = getShapesOnSurface( aPlane, theShape, aShapeType, theState, anAsciiList );
2777 if ( aSeq.IsNull() || aSeq->Length() == 0 )
2780 // Make a Python command
2782 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2783 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2785 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
2786 << "] = geompy.GetShapesOnPlane(" << theShape << ", "
2787 << aShapeType << ", " << theAx1 << ", " << theState << ")";
2793 //=============================================================================
2795 * GetShapesOnPlaneWithLocation
2797 //=============================================================================
2798 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnPlaneWithLocation
2799 (const Handle(GEOM_Object)& theShape,
2800 const Standard_Integer theShapeType,
2801 const Handle(GEOM_Object)& theAx1,
2802 const Handle(GEOM_Object)& thePnt,
2803 const GEOMAlgo_State theState)
2807 if (theShape.IsNull() || theAx1.IsNull() || thePnt.IsNull()) return NULL;
2809 TopoDS_Shape aShape = theShape->GetValue();
2810 TopoDS_Shape anAx1 = theAx1->GetValue();
2811 TopoDS_Shape anPnt = thePnt->GetValue();
2813 if (aShape.IsNull() || anAx1.IsNull() || anPnt.IsNull()) return NULL;
2815 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2816 if ( !checkTypeShapesOn( theShapeType ))
2820 if ( anAx1.ShapeType() != TopAbs_EDGE || anPnt.ShapeType() != TopAbs_VERTEX ) return NULL;
2821 TopoDS_Vertex V1, V2, V3;
2822 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
2823 TopExp::Vertices(anEdge, V1, V2, Standard_True);
2825 if (V1.IsNull() || V2.IsNull()) {
2826 SetErrorCode("Bad edge given for the plane normal vector");
2829 V3 = TopoDS::Vertex(anPnt);
2832 SetErrorCode("Bad vertex given for the plane location");
2835 gp_Pnt aLoc = BRep_Tool::Pnt(V3);
2836 gp_Vec aVec(BRep_Tool::Pnt(V1),BRep_Tool::Pnt(V2));
2838 if (aVec.Magnitude() < Precision::Confusion()) {
2839 SetErrorCode("Vector with null magnitude given");
2842 Handle(Geom_Surface) aPlane = new Geom_Plane(aLoc, aVec);
2844 if ( aPlane.IsNull() )
2848 TCollection_AsciiString anAsciiList;
2849 Handle(TColStd_HSequenceOfTransient) aSeq;
2850 aSeq = getShapesOnSurface( aPlane, theShape, aShapeType, theState, anAsciiList );
2851 if ( aSeq.IsNull() || aSeq->Length() == 0 )
2854 // Make a Python command
2856 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2857 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2859 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
2860 << "] = geompy.GetShapesOnPlaneWithLocation(" << theShape << ", "
2861 << aShapeType << ", " << theAx1 << ", "<< thePnt <<", " << theState << ")";
2867 //=============================================================================
2869 * GetShapesOnCylinder
2871 //=============================================================================
2872 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnCylinder
2873 (const Handle(GEOM_Object)& theShape,
2874 const Standard_Integer theShapeType,
2875 const Handle(GEOM_Object)& theAxis,
2876 const Standard_Real theRadius,
2877 const GEOMAlgo_State theState)
2881 if (theShape.IsNull() || theAxis.IsNull()) return NULL;
2883 TopoDS_Shape aShape = theShape->GetValue();
2884 TopoDS_Shape anAxis = theAxis->GetValue();
2886 if (aShape.IsNull() || anAxis.IsNull()) return NULL;
2888 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2889 if ( !checkTypeShapesOn( aShapeType ))
2892 // Create a cylinder surface
2893 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
2894 if ( aCylinder.IsNull() )
2898 TCollection_AsciiString anAsciiList;
2899 Handle(TColStd_HSequenceOfTransient) aSeq;
2900 aSeq = getShapesOnSurface( aCylinder, theShape, aShapeType, theState, anAsciiList );
2901 if ( aSeq.IsNull() || aSeq->Length() == 0 )
2904 // Make a Python command
2906 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2907 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2909 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
2910 << "] = geompy.GetShapesOnCylinder(" << theShape << ", " << aShapeType
2911 << ", " << theAxis << ", " << theRadius << ", " << theState << ")";
2917 //=============================================================================
2919 * GetShapesOnCylinderWithLocation
2921 //=============================================================================
2922 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnCylinderWithLocation
2923 (const Handle(GEOM_Object)& theShape,
2924 const Standard_Integer theShapeType,
2925 const Handle(GEOM_Object)& theAxis,
2926 const Handle(GEOM_Object)& thePnt,
2927 const Standard_Real theRadius,
2928 const GEOMAlgo_State theState)
2932 if (theShape.IsNull() || theAxis.IsNull() || thePnt.IsNull()) return NULL;
2934 TopoDS_Shape aShape = theShape->GetValue();
2935 TopoDS_Shape anAxis = theAxis->GetValue();
2936 TopoDS_Shape aPnt = thePnt->GetValue();
2938 if (aShape.IsNull() || anAxis.IsNull() || aPnt.IsNull()) return NULL;
2940 if (aPnt.ShapeType() != TopAbs_VERTEX )
2942 SetErrorCode("Bottom location point must be vertex");
2946 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2947 if ( !checkTypeShapesOn( aShapeType ))
2950 // Create a cylinder surface
2951 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
2952 if ( aCylinder.IsNull() )
2955 // translate the surface
2956 Handle(Geom_CylindricalSurface) aCylSurface =
2957 Handle(Geom_CylindricalSurface)::DownCast( aCylinder );
2958 if ( aCylSurface.IsNull() )
2960 SetErrorCode("Unexpected surface type instead of Geom_CylindricalSurface");
2963 gp_Pnt fromLoc = aCylSurface->Cylinder().Location();
2964 gp_Pnt toLoc = BRep_Tool::Pnt( TopoDS::Vertex( aPnt ));
2965 aCylinder->Translate( fromLoc, toLoc );
2968 TCollection_AsciiString anAsciiList;
2969 Handle(TColStd_HSequenceOfTransient) aSeq;
2970 aSeq = getShapesOnSurface( aCylinder, theShape, aShapeType, theState, anAsciiList );
2971 if ( aSeq.IsNull() || aSeq->Length() == 0 )
2974 // Make a Python command
2976 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2977 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2979 GEOM::TPythonDump(aFunction)
2980 << "[" << anAsciiList.ToCString()
2981 << "] = geompy.GetShapesOnCylinderWithLocation(" << theShape << ", " << aShapeType << ", "
2982 << theAxis << ", " << thePnt << ", " << theRadius << ", " << theState << ")";
2988 //=============================================================================
2992 //=============================================================================
2993 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnSphere
2994 (const Handle(GEOM_Object)& theShape,
2995 const Standard_Integer theShapeType,
2996 const Handle(GEOM_Object)& theCenter,
2997 const Standard_Real theRadius,
2998 const GEOMAlgo_State theState)
3002 if (theShape.IsNull() || theCenter.IsNull()) return NULL;
3004 TopoDS_Shape aShape = theShape->GetValue();
3005 TopoDS_Shape aCenter = theCenter->GetValue();
3007 if (aShape.IsNull() || aCenter.IsNull()) return NULL;
3009 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3010 if ( !checkTypeShapesOn( aShapeType ))
3013 // Center of the sphere
3014 if (aCenter.ShapeType() != TopAbs_VERTEX) return NULL;
3015 gp_Pnt aLoc = BRep_Tool::Pnt(TopoDS::Vertex(aCenter));
3017 gp_Ax3 anAx3 (aLoc, gp::DZ());
3018 Handle(Geom_SphericalSurface) aSphere =
3019 new Geom_SphericalSurface(anAx3, theRadius);
3022 TCollection_AsciiString anAsciiList;
3023 Handle(TColStd_HSequenceOfTransient) aSeq;
3024 aSeq = getShapesOnSurface( aSphere, theShape, aShapeType, theState, anAsciiList );
3025 if ( aSeq.IsNull() || aSeq->Length() == 0 )
3028 // Make a Python command
3030 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
3031 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
3033 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
3034 << "] = geompy.GetShapesOnSphere(" << theShape << ", " << aShapeType
3035 << ", " << theCenter << ", " << theRadius << ", " << theState << ")";
3041 //=============================================================================
3043 * GetShapesOnPlaneIDs
3045 //=============================================================================
3046 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnPlaneIDs
3047 (const Handle(GEOM_Object)& theShape,
3048 const Standard_Integer theShapeType,
3049 const Handle(GEOM_Object)& theAx1,
3050 const GEOMAlgo_State theState)
3054 if (theShape.IsNull() || theAx1.IsNull()) return NULL;
3056 TopoDS_Shape aShape = theShape->GetValue();
3057 TopoDS_Shape anAx1 = theAx1->GetValue();
3059 if (aShape.IsNull() || anAx1.IsNull()) return NULL;
3061 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3062 if ( !checkTypeShapesOn( aShapeType ))
3066 Handle(Geom_Surface) aPlane = makePlane( anAx1 );
3067 if ( aPlane.IsNull() )
3071 Handle(TColStd_HSequenceOfInteger) aSeq;
3072 aSeq = getShapesOnSurfaceIDs( aPlane, aShape, aShapeType, theState );
3074 // The GetShapesOnPlaneIDs() doesn't change object so no new function is required.
3075 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAx1)->GetLastFunction();
3077 // Make a Python command
3078 GEOM::TPythonDump(aFunction, /*append=*/true)
3079 << "listShapesOnPlane = geompy.GetShapesOnPlaneIDs"
3080 << "(" << theShape << "," << aShapeType << "," << theAx1 << "," << theState << ")";
3086 //=============================================================================
3088 * GetShapesOnPlaneWithLocationIDs
3090 //=============================================================================
3091 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnPlaneWithLocationIDs
3092 (const Handle(GEOM_Object)& theShape,
3093 const Standard_Integer theShapeType,
3094 const Handle(GEOM_Object)& theAx1,
3095 const Handle(GEOM_Object)& thePnt,
3096 const GEOMAlgo_State theState)
3100 if (theShape.IsNull() || theAx1.IsNull() || thePnt.IsNull()) return NULL;
3102 TopoDS_Shape aShape = theShape->GetValue();
3103 TopoDS_Shape anAx1 = theAx1->GetValue();
3104 TopoDS_Shape anPnt = thePnt->GetValue();
3106 if (aShape.IsNull() || anAx1.IsNull() || anPnt.IsNull()) return NULL;
3108 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3109 if ( !checkTypeShapesOn( aShapeType ))
3113 if (anAx1.ShapeType() != TopAbs_EDGE || anPnt.ShapeType() != TopAbs_VERTEX) return NULL;
3114 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
3115 TopoDS_Vertex V1, V2, V3;
3116 TopExp::Vertices(anEdge, V1, V2, Standard_True);
3117 if (V1.IsNull() || V2.IsNull()) {
3118 SetErrorCode("Bad edge given for the plane normal vector");
3121 V3 = TopoDS::Vertex(anPnt);
3123 SetErrorCode("Bad vertex given for the plane location");
3126 gp_Pnt aLoc = BRep_Tool::Pnt(V3);
3127 gp_Vec aVec(BRep_Tool::Pnt(V1),BRep_Tool::Pnt(V2));
3128 if (aVec.Magnitude() < Precision::Confusion()) {
3129 SetErrorCode("Vector with null magnitude given");
3133 Handle(Geom_Surface) aPlane = new Geom_Plane(aLoc, aVec);
3134 if ( aPlane.IsNull() )
3138 Handle(TColStd_HSequenceOfInteger) aSeq;
3139 aSeq = getShapesOnSurfaceIDs( aPlane, aShape, aShapeType, theState );
3141 // The GetShapesOnPlaneIDs() doesn't change object so no new function is required.
3142 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAx1)->GetLastFunction();
3144 // Make a Python command
3145 GEOM::TPythonDump(aFunction, /*append=*/true)
3146 << "listShapesOnPlane = geompy.GetShapesOnPlaneWithLocationIDs"
3147 << "(" << theShape << ", " << aShapeType << ", " << theAx1 << ", "<< thePnt << ", " << theState << ")";
3153 //=============================================================================
3155 * GetShapesOnCylinderIDs
3157 //=============================================================================
3158 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnCylinderIDs
3159 (const Handle(GEOM_Object)& theShape,
3160 const Standard_Integer theShapeType,
3161 const Handle(GEOM_Object)& theAxis,
3162 const Standard_Real theRadius,
3163 const GEOMAlgo_State theState)
3167 if (theShape.IsNull() || theAxis.IsNull()) return NULL;
3169 TopoDS_Shape aShape = theShape->GetValue();
3170 TopoDS_Shape anAxis = theAxis->GetValue();
3172 if (aShape.IsNull() || anAxis.IsNull()) return NULL;
3174 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3175 if ( !checkTypeShapesOn( aShapeType ))
3178 // Create a cylinder surface
3179 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
3180 if ( aCylinder.IsNull() )
3184 Handle(TColStd_HSequenceOfInteger) aSeq;
3185 aSeq = getShapesOnSurfaceIDs( aCylinder, aShape, aShapeType, theState );
3187 // The GetShapesOnCylinder() doesn't change object so no new function is required.
3188 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAxis)->GetLastFunction();
3190 // Make a Python command
3191 GEOM::TPythonDump(aFunction, /*append=*/true)
3192 << "listShapesOnCylinder = geompy.GetShapesOnCylinderIDs"
3193 << "(" << theShape << ", " << aShapeType << ", " << theAxis << ", "
3194 << theRadius << ", " << theState << ")";
3200 //=============================================================================
3202 * GetShapesOnCylinderWithLocationIDs
3204 //=============================================================================
3205 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnCylinderWithLocationIDs
3206 (const Handle(GEOM_Object)& theShape,
3207 const Standard_Integer theShapeType,
3208 const Handle(GEOM_Object)& theAxis,
3209 const Handle(GEOM_Object)& thePnt,
3210 const Standard_Real theRadius,
3211 const GEOMAlgo_State theState)
3215 if (theShape.IsNull() || theAxis.IsNull() || thePnt.IsNull()) return NULL;
3217 TopoDS_Shape aShape = theShape->GetValue();
3218 TopoDS_Shape anAxis = theAxis->GetValue();
3219 TopoDS_Shape aPnt = thePnt->GetValue();
3221 if (aShape.IsNull() || anAxis.IsNull() || aPnt.IsNull()) return NULL;
3223 if (aPnt.ShapeType() != TopAbs_VERTEX )
3225 SetErrorCode("Bottom location point must be vertex");
3229 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3230 if ( !checkTypeShapesOn( aShapeType ))
3233 // Create a cylinder surface
3234 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
3235 if ( aCylinder.IsNull() )
3238 // translate the surface
3239 Handle(Geom_CylindricalSurface) aCylSurface =
3240 Handle(Geom_CylindricalSurface)::DownCast( aCylinder );
3241 if ( aCylSurface.IsNull() )
3243 SetErrorCode("Unexpected surface type instead of Geom_CylindricalSurface");
3246 gp_Pnt fromLoc = aCylSurface->Cylinder().Location();
3247 gp_Pnt toLoc = BRep_Tool::Pnt( TopoDS::Vertex( aPnt ));
3248 aCylinder->Translate( fromLoc, toLoc );
3251 Handle(TColStd_HSequenceOfInteger) aSeq;
3252 aSeq = getShapesOnSurfaceIDs( aCylinder, aShape, aShapeType, theState );
3254 // The GetShapesOnCylinder() doesn't change object so no new function is required.
3255 Handle(GEOM_Function) aFunction =
3256 GEOM::GetCreatedLast(theShape, GEOM::GetCreatedLast(thePnt,theAxis))->GetLastFunction();
3258 // Make a Python command
3259 GEOM::TPythonDump(aFunction, /*append=*/true)
3260 << "listShapesOnCylinder = geompy.GetShapesOnCylinderWithLocationIDs"
3261 << "(" << theShape << ", " << aShapeType << ", " << theAxis << ", "
3262 << thePnt << ", " << theRadius << ", " << theState << ")";
3268 //=============================================================================
3270 * GetShapesOnSphereIDs
3272 //=============================================================================
3273 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnSphereIDs
3274 (const Handle(GEOM_Object)& theShape,
3275 const Standard_Integer theShapeType,
3276 const Handle(GEOM_Object)& theCenter,
3277 const Standard_Real theRadius,
3278 const GEOMAlgo_State theState)
3282 if (theShape.IsNull() || theCenter.IsNull()) return NULL;
3284 TopoDS_Shape aShape = theShape->GetValue();
3285 TopoDS_Shape aCenter = theCenter->GetValue();
3287 if (aShape.IsNull() || aCenter.IsNull()) return NULL;
3289 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3290 if ( !checkTypeShapesOn( aShapeType ))
3293 // Center of the sphere
3294 if (aCenter.ShapeType() != TopAbs_VERTEX) return NULL;
3295 gp_Pnt aLoc = BRep_Tool::Pnt(TopoDS::Vertex(aCenter));
3297 gp_Ax3 anAx3 (aLoc, gp::DZ());
3298 Handle(Geom_SphericalSurface) aSphere =
3299 new Geom_SphericalSurface(anAx3, theRadius);
3302 Handle(TColStd_HSequenceOfInteger) aSeq;
3303 aSeq = getShapesOnSurfaceIDs( aSphere, aShape, aShapeType, theState );
3305 // The GetShapesOnSphere() doesn't change object so no new function is required.
3306 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theCenter)->GetLastFunction();
3308 // Make a Python command
3309 GEOM::TPythonDump(aFunction, /*append=*/true)
3310 << "listShapesOnCylinder = geompy.GetShapesOnCylinderIDs"
3311 << "(" << theShape << ", " << aShapeType << ", " << theCenter << ", "
3312 << theRadius << ", " << theState << ")";
3318 //=======================================================================
3319 //function : getShapesOnQuadrangleIDs
3321 * \brief Find IDs of subshapes complying with given status about quadrangle
3322 * \param theShape - the shape to explore
3323 * \param theShapeType - type of subshape of theShape
3324 * \param theTopLeftPoint - top left quadrangle corner
3325 * \param theTopRigthPoint - top right quadrangle corner
3326 * \param theBottomLeftPoint - bottom left quadrangle corner
3327 * \param theBottomRigthPoint - bottom right quadrangle corner
3328 * \param theState - required state
3329 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
3331 //=======================================================================
3332 Handle(TColStd_HSequenceOfInteger)
3333 GEOMImpl_IShapesOperations::getShapesOnQuadrangleIDs (const Handle(GEOM_Object)& theShape,
3334 const Standard_Integer theShapeType,
3335 const Handle(GEOM_Object)& theTopLeftPoint,
3336 const Handle(GEOM_Object)& theTopRigthPoint,
3337 const Handle(GEOM_Object)& theBottomLeftPoint,
3338 const Handle(GEOM_Object)& theBottomRigthPoint,
3339 const GEOMAlgo_State theState)
3343 if ( theShape.IsNull() ||
3344 theTopLeftPoint.IsNull() ||
3345 theTopRigthPoint.IsNull() ||
3346 theBottomLeftPoint.IsNull() ||
3347 theBottomRigthPoint.IsNull() )
3350 TopoDS_Shape aShape = theShape->GetValue();
3351 TopoDS_Shape aTL = theTopLeftPoint->GetValue();
3352 TopoDS_Shape aTR = theTopRigthPoint->GetValue();
3353 TopoDS_Shape aBL = theBottomLeftPoint->GetValue();
3354 TopoDS_Shape aBR = theBottomRigthPoint->GetValue();
3356 if (aShape.IsNull() ||
3361 aTL.ShapeType() != TopAbs_VERTEX ||
3362 aTR.ShapeType() != TopAbs_VERTEX ||
3363 aBL.ShapeType() != TopAbs_VERTEX ||
3364 aBR.ShapeType() != TopAbs_VERTEX )
3367 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3368 if ( !checkTypeShapesOn( aShapeType ))
3371 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
3373 // Check presence of triangulation, build if need
3374 if (!CheckTriangulation(aShape)) {
3375 SetErrorCode("Cannot build triangulation on the shape");
3380 gp_Pnt aPntTL = BRep_Tool::Pnt(TopoDS::Vertex(aTL));
3381 gp_Pnt aPntTR = BRep_Tool::Pnt(TopoDS::Vertex(aTR));
3382 gp_Pnt aPntBL = BRep_Tool::Pnt(TopoDS::Vertex(aBL));
3383 gp_Pnt aPntBR = BRep_Tool::Pnt(TopoDS::Vertex(aBR));
3385 GEOMAlgo_FinderShapeOnQuad aFinder( aPntTL, aPntTR, aPntBL, aPntBR );
3386 Standard_Real aTol = 0.0001; // default value
3388 aFinder.SetShape(aShape);
3389 aFinder.SetTolerance(aTol);
3390 //aFinder.SetSurface(theSurface);
3391 aFinder.SetShapeType(aShapeType);
3392 aFinder.SetState(theState);
3394 // Sets the minimal number of inner points for the faces that do not have own
3395 // inner points at all (for e.g. rectangular planar faces have just 2 triangles).
3397 aFinder.SetNbPntsMin(3);
3398 // Sets the maximal number of inner points for edges or faces.
3399 // It is usefull for the cases when this number is very big (e.g =2000) to improve
3400 // the performance. If this value =0, all inner points will be taken into account.
3402 aFinder.SetNbPntsMax(100);
3406 // Interprete results
3407 Standard_Integer iErr = aFinder.ErrorStatus();
3408 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
3410 MESSAGE(" iErr : " << iErr);
3411 TCollection_AsciiString aMsg (" iErr : ");
3412 aMsg += TCollection_AsciiString(iErr);
3416 Standard_Integer iWrn = aFinder.WarningStatus();
3417 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
3419 MESSAGE(" *** iWrn : " << iWrn);
3422 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
3424 if (listSS.Extent() < 1) {
3425 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
3426 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
3430 // Fill sequence of object IDs
3431 aSeqOfIDs = new TColStd_HSequenceOfInteger;
3433 TopTools_IndexedMapOfShape anIndices;
3434 TopExp::MapShapes(aShape, anIndices);
3436 TopTools_ListIteratorOfListOfShape itSub (listSS);
3437 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
3438 int id = anIndices.FindIndex(itSub.Value());
3439 aSeqOfIDs->Append(id);
3444 //=======================================================================
3445 //function : GetShapesOnQuadrangle
3447 * \brief Find subshapes complying with given status about quadrangle
3448 * \param theShape - the shape to explore
3449 * \param theShapeType - type of subshape of theShape
3450 * \param theTopLeftPoint - top left quadrangle corner
3451 * \param theTopRigthPoint - top right quadrangle corner
3452 * \param theBottomLeftPoint - bottom left quadrangle corner
3453 * \param theBottomRigthPoint - bottom right quadrangle corner
3454 * \param theState - required state
3455 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
3457 //=======================================================================
3458 Handle(TColStd_HSequenceOfTransient)
3459 GEOMImpl_IShapesOperations::GetShapesOnQuadrangle (const Handle(GEOM_Object)& theShape,
3460 const Standard_Integer theShapeType,
3461 const Handle(GEOM_Object)& theTopLeftPoint,
3462 const Handle(GEOM_Object)& theTopRigthPoint,
3463 const Handle(GEOM_Object)& theBottomLeftPoint,
3464 const Handle(GEOM_Object)& theBottomRigthPoint,
3465 const GEOMAlgo_State theState)
3468 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
3469 getShapesOnQuadrangleIDs( theShape,
3474 theBottomRigthPoint,
3476 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->IsEmpty() )
3479 // Find objects by indices
3480 TCollection_AsciiString anAsciiList;
3481 Handle(TColStd_HSequenceOfTransient) aSeq;
3482 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
3483 if ( aSeq.IsNull() || aSeq->IsEmpty() )
3486 // Make a Python command
3488 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
3489 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
3491 GEOM::TPythonDump(aFunction)
3492 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnQuadrangle("
3494 << TopAbs_ShapeEnum(theShapeType) << ", "
3495 << theTopLeftPoint << ", "
3496 << theTopRigthPoint << ", "
3497 << theBottomLeftPoint << ", "
3498 << theBottomRigthPoint << ", "
3505 //=======================================================================
3506 //function : GetShapesOnQuadrangleIDs
3508 * \brief Find IDs of subshapes complying with given status about quadrangle
3509 * \param theShape - the shape to explore
3510 * \param theShapeType - type of subshape of theShape
3511 * \param theTopLeftPoint - top left quadrangle corner
3512 * \param theTopRigthPoint - top right quadrangle corner
3513 * \param theBottomLeftPoint - bottom left quadrangle corner
3514 * \param theBottomRigthPoint - bottom right quadrangle corner
3515 * \param theState - required state
3516 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
3518 //=======================================================================
3519 Handle(TColStd_HSequenceOfInteger)
3520 GEOMImpl_IShapesOperations::GetShapesOnQuadrangleIDs (const Handle(GEOM_Object)& theShape,
3521 const Standard_Integer theShapeType,
3522 const Handle(GEOM_Object)& theTopLeftPoint,
3523 const Handle(GEOM_Object)& theTopRigthPoint,
3524 const Handle(GEOM_Object)& theBottomLeftPoint,
3525 const Handle(GEOM_Object)& theBottomRigthPoint,
3526 const GEOMAlgo_State theState)
3529 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
3530 getShapesOnQuadrangleIDs( theShape,
3535 theBottomRigthPoint,
3537 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->IsEmpty() )
3540 // Make a Python command
3542 // The GetShapesOnCylinder() doesn't change object so no new function is required.
3543 Handle(GEOM_Object) lastObj = GEOM::GetCreatedLast(theShape,theTopLeftPoint);
3544 lastObj = GEOM::GetCreatedLast(lastObj,theTopRigthPoint);
3545 lastObj = GEOM::GetCreatedLast(lastObj,theBottomRigthPoint);
3546 lastObj = GEOM::GetCreatedLast(lastObj,theBottomLeftPoint);
3547 Handle(GEOM_Function) aFunction = lastObj->GetLastFunction();
3549 GEOM::TPythonDump(aFunction, /*append=*/true)
3550 << "listShapesOnQuadrangle = geompy.GetShapesOnQuadrangleIDs("
3552 << TopAbs_ShapeEnum(theShapeType) << ", "
3553 << theTopLeftPoint << ", "
3554 << theTopRigthPoint << ", "
3555 << theBottomLeftPoint << ", "
3556 << theBottomRigthPoint << ", "
3563 //=============================================================================
3567 //=============================================================================
3568 static bool GetInPlaceOfShape (const Handle(GEOM_Function)& theWhereFunction,
3569 const TopTools_IndexedMapOfShape& theWhereIndices,
3570 const TopoDS_Shape& theWhat,
3571 TColStd_ListOfInteger& theModifiedList)
3573 if (theWhereFunction.IsNull() || theWhat.IsNull()) return false;
3575 if (theWhereIndices.Contains(theWhat)) {
3576 // entity was not changed by the operation
3577 Standard_Integer aWhatIndex = theWhereIndices.FindIndex(theWhat);
3578 theModifiedList.Append(aWhatIndex);
3582 // try to find in history
3583 TDF_Label aHistoryLabel = theWhereFunction->GetHistoryEntry(Standard_False);
3585 // search in history for all argument shapes
3586 Standard_Boolean isFound = Standard_False;
3587 Standard_Boolean isGood = Standard_False;
3589 TDF_LabelSequence aLabelSeq;
3590 theWhereFunction->GetDependency(aLabelSeq);
3591 Standard_Integer nbArg = aLabelSeq.Length();
3593 for (Standard_Integer iarg = 1; iarg <= nbArg && !isFound; iarg++) {
3595 TDF_Label anArgumentRefLabel = aLabelSeq.Value(iarg);
3597 Handle(GEOM_Object) anArgumentObject = GEOM_Object::GetReferencedObject(anArgumentRefLabel);
3598 TopoDS_Shape anArgumentShape = anArgumentObject->GetValue();
3600 TopTools_IndexedMapOfShape anArgumentIndices;
3601 TopExp::MapShapes(anArgumentShape, anArgumentIndices);
3603 if (anArgumentIndices.Contains(theWhat)) {
3604 isFound = Standard_True;
3605 Standard_Integer aWhatIndex = anArgumentIndices.FindIndex(theWhat);
3607 // Find corresponding label in history
3608 TDF_Label anArgumentHistoryLabel =
3609 theWhereFunction->GetArgumentHistoryEntry(anArgumentRefLabel, Standard_False);
3610 if (anArgumentHistoryLabel.IsNull()) {
3611 // Lost History of operation argument. Possibly, all its entities was removed.
3612 isGood = Standard_True;
3615 TDF_Label aWhatHistoryLabel = anArgumentHistoryLabel.FindChild(aWhatIndex, Standard_False);
3617 if (aWhatHistoryLabel.IsNull()) {
3618 // Removed entity ? Compound ? Compsolid ? Shell ? Wire
3619 isGood = Standard_False;
3621 Handle(TDataStd_IntegerArray) anIntegerArray;
3622 if (!aWhatHistoryLabel.FindAttribute(TDataStd_IntegerArray::GetID(), anIntegerArray)) {
3623 //Error: Empty modifications history for the sought shape.
3624 isGood = Standard_False;
3627 isGood = Standard_True;
3628 Standard_Integer imod, aModifLen = anIntegerArray->Array()->Length();
3629 for (imod = 1; imod <= aModifLen; imod++) {
3630 theModifiedList.Append(anIntegerArray->Array()->Value(imod));
3641 // try compound/compsolid/shell/wire element by element
3642 bool isFoundAny = false;
3643 TopTools_MapOfShape mapShape;
3645 if (theWhat.ShapeType() == TopAbs_COMPOUND ||
3646 theWhat.ShapeType() == TopAbs_COMPSOLID) {
3647 // recursive processing of compound/compsolid
3648 TopoDS_Iterator anIt (theWhat, Standard_True, Standard_True);
3649 for (; anIt.More(); anIt.Next()) {
3650 if (mapShape.Add(anIt.Value())) {
3651 TopoDS_Shape curWhat = anIt.Value();
3652 isFoundAny = GetInPlaceOfShape(theWhereFunction, theWhereIndices, curWhat, theModifiedList);
3653 if (isFoundAny) isFound = Standard_True;
3657 else if (theWhat.ShapeType() == TopAbs_SHELL) {
3658 // try to replace a shell by its faces images
3659 TopExp_Explorer anExp (theWhat, TopAbs_FACE);
3660 for (; anExp.More(); anExp.Next()) {
3661 if (mapShape.Add(anExp.Current())) {
3662 TopoDS_Shape curWhat = anExp.Current();
3663 isFoundAny = GetInPlaceOfShape(theWhereFunction, theWhereIndices, curWhat, theModifiedList);
3664 if (isFoundAny) isFound = Standard_True;
3668 else if (theWhat.ShapeType() == TopAbs_WIRE) {
3669 // try to replace a wire by its edges images
3670 TopExp_Explorer anExp (theWhat, TopAbs_EDGE);
3671 for (; anExp.More(); anExp.Next()) {
3672 if (mapShape.Add(anExp.Current())) {
3673 TopoDS_Shape curWhat = anExp.Current();
3674 isFoundAny = GetInPlaceOfShape(theWhereFunction, theWhereIndices, curWhat, theModifiedList);
3675 if (isFoundAny) isFound = Standard_True;
3687 //=============================================================================
3689 * GetShapeProperties
3691 //=============================================================================
3692 void GEOMImpl_IShapesOperations::GetShapeProperties( const TopoDS_Shape aShape, Standard_Real tab[],
3695 GProp_GProps theProps;
3697 //TopoDS_Shape aPntShape;
3698 Standard_Real aShapeSize;
3700 if (aShape.ShapeType() == TopAbs_VERTEX) aCenterMass = BRep_Tool::Pnt( TopoDS::Vertex( aShape ) );
3701 else if (aShape.ShapeType() == TopAbs_EDGE) BRepGProp::LinearProperties(aShape, theProps);
3702 else if (aShape.ShapeType() == TopAbs_FACE) BRepGProp::SurfaceProperties(aShape, theProps);
3703 else BRepGProp::VolumeProperties(aShape, theProps);
3705 if (aShape.ShapeType() == TopAbs_VERTEX)
3708 aCenterMass = theProps.CentreOfMass();
3709 aShapeSize = theProps.Mass();
3712 // aPntShape = BRepBuilderAPI_MakeVertex(aCenterMass).Shape();
3713 // aVertex = BRep_Tool::Pnt( TopoDS::Vertex( aPntShape ) );
3714 aVertex = aCenterMass;
3715 tab[0] = aVertex.X();
3716 tab[1] = aVertex.Y();
3717 tab[2] = aVertex.Z();
3718 tab[3] = aShapeSize;
3724 //================================================================================
3726 * \brief Return normal to face at extrema point
3728 //================================================================================
3730 gp_Vec GetNormal (const TopoDS_Face& face, const BRepExtrema_DistShapeShape& extrema)
3732 gp_Vec defaultNorm(1,0,0); // to have same normals on different faces
3734 // get UV at extrema point
3735 Standard_Real u,v, f,l;
3736 switch ( extrema.SupportTypeShape2(1) ) {
3737 case BRepExtrema_IsInFace: {
3738 extrema.ParOnFaceS2(1, u, v );
3741 case BRepExtrema_IsOnEdge: {
3742 TopoDS_Edge edge = TopoDS::Edge( extrema.SupportOnShape2(1));
3743 Handle(Geom2d_Curve) pcurve = BRep_Tool::CurveOnSurface( edge, face, f,l );
3744 extrema.ParOnEdgeS2( 1, u );
3745 gp_Pnt2d uv = pcurve->Value( u );
3750 case BRepExtrema_IsVertex: return defaultNorm;
3753 BRepAdaptor_Surface surface( face, false );
3754 gp_Vec du, dv; gp_Pnt p;
3755 surface.D1( u, v, p, du, dv );
3759 } catch (Standard_Failure ) {
3765 //================================================================================
3767 * \brief Return type of shape for explode. In case of compound it will be a type of sub shape.
3769 //================================================================================
3770 TopAbs_ShapeEnum GEOMImpl_IShapesOperations::GetTypeOfSimplePart (const TopoDS_Shape& theShape)
3772 TopAbs_ShapeEnum aType = theShape.ShapeType();
3773 if (aType == TopAbs_VERTEX) return TopAbs_VERTEX;
3774 else if (aType == TopAbs_EDGE || aType == TopAbs_WIRE) return TopAbs_EDGE;
3775 else if (aType == TopAbs_FACE || aType == TopAbs_SHELL) return TopAbs_FACE;
3776 else if (aType == TopAbs_SOLID || aType == TopAbs_COMPSOLID) return TopAbs_SOLID;
3777 else if (aType == TopAbs_COMPOUND) {
3778 // Only the iType of the first shape in the compound is taken into account
3779 TopoDS_Iterator It (theShape, Standard_False, Standard_False);
3781 return GetTypeOfSimplePart(It.Value());
3784 return TopAbs_SHAPE;
3787 //=============================================================================
3792 //=============================================================================
3793 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlace (Handle(GEOM_Object) theShapeWhere,
3794 Handle(GEOM_Object) theShapeWhat)
3798 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
3800 TopoDS_Shape aWhere = theShapeWhere->GetValue();
3801 TopoDS_Shape aWhat = theShapeWhat->GetValue();
3802 TopoDS_Shape aPntShape;
3803 TopoDS_Vertex aVertex;
3805 if (aWhere.IsNull() || aWhat.IsNull()) {
3806 SetErrorCode("Error: aWhere and aWhat TopoDS_Shape are Null.");
3810 Handle(GEOM_Function) aWhereFunction = theShapeWhere->GetLastFunction();
3811 if (aWhereFunction.IsNull()) {
3812 SetErrorCode("Error: aWhereFunction is Null.");
3816 TopTools_IndexedMapOfShape aWhereIndices;
3817 TopExp::MapShapes(aWhere, aWhereIndices);
3819 TopAbs_ShapeEnum iType = TopAbs_SOLID;
3820 Standard_Real dl_l = 1e-3;
3821 Standard_Real min_l, Tol_0D, Tol_1D, Tol_2D, Tol_3D, Tol_Mass;
3822 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
3823 Bnd_Box BoundingBox;
3824 gp_Pnt aPnt, aPnt_aWhat, tab_Pnt[2];
3825 GProp_GProps aProps;
3827 // Find the iType of the aWhat shape
3828 iType = GetTypeOfSimplePart(aWhat);
3829 if (iType == TopAbs_SHAPE) {
3830 SetErrorCode("Error: An attempt to extract a shape of not supported type.");
3834 TopExp_Explorer Exp_aWhat ( aWhat, iType );
3835 TopExp_Explorer Exp_aWhere ( aWhere, iType );
3836 TopExp_Explorer Exp_Edge ( aWhere, TopAbs_EDGE );
3838 // Find the shortest edge in theShapeWhere shape
3839 BRepBndLib::Add(aWhere, BoundingBox);
3840 BoundingBox.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
3841 min_l = fabs(aXmax - aXmin);
3842 if( min_l < fabs(aYmax - aYmin) ) min_l = fabs(aYmax - aYmin);
3843 if( min_l < fabs(aZmax - aZmin) ) min_l = fabs(aZmax - aZmin);
3845 // Mantis issue 0020908 BEGIN
3846 if (!Exp_Edge.More()) {
3847 min_l = Precision::Confusion();
3849 // Mantis issue 0020908 END
3850 for ( Standard_Integer nbEdge = 0; Exp_Edge.More(); Exp_Edge.Next(), nbEdge++ ) {
3851 TopExp_Explorer Exp_Vertex( Exp_Edge.Current(), TopAbs_VERTEX);
3852 for ( Standard_Integer nbVertex = 0; Exp_Vertex.More(); Exp_Vertex.Next(), nbVertex++ ) {
3853 aPnt = BRep_Tool::Pnt( TopoDS::Vertex( Exp_Vertex.Current() ) );
3854 tab_Pnt[nbVertex] = aPnt;
3856 if ( ! tab_Pnt[0].IsEqual(tab_Pnt[1], dl_l) ) {
3857 BRepGProp::LinearProperties(Exp_Edge.Current(), aProps);
3858 if ( aProps.Mass() < min_l ) min_l = aProps.Mass();
3862 // Compute tolerances
3864 Tol_1D = dl_l * min_l;
3865 Tol_2D = dl_l * ( min_l * min_l) * ( 2. + dl_l);
3866 Tol_3D = dl_l * ( min_l * min_l * min_l ) * ( 3. + (3 * dl_l) + (dl_l * dl_l) );
3868 if (Tol_0D < Precision::Confusion()) Tol_0D = Precision::Confusion();
3869 if (Tol_1D < Precision::Confusion()) Tol_1D = Precision::Confusion();
3870 if (Tol_2D < Precision::Confusion()) Tol_2D = Precision::Confusion();
3871 if (Tol_3D < Precision::Confusion()) Tol_3D = Precision::Confusion();
3874 if ( iType == TopAbs_VERTEX ) Tol_Mass = Tol_0D;
3875 else if ( iType == TopAbs_EDGE ) Tol_Mass = Tol_1D;
3876 else if ( iType == TopAbs_FACE ) Tol_Mass = Tol_2D;
3878 // Searching for the sub-shapes inside the ShapeWhere shape
3879 GEOMAlgo_GetInPlace aGIP;
3880 aGIP.SetTolerance(Tol_1D);
3881 aGIP.SetTolMass(Tol_Mass);
3882 aGIP.SetTolCG(Tol_1D);
3884 aGIP.SetArgument(aWhat);
3885 aGIP.SetShapeWhere(aWhere);
3888 int iErr = aGIP.ErrorStatus();
3890 SetErrorCode("Error in GEOMAlgo_GetInPlace");
3894 // aGIP.IsFound() returns true only when the whole theShapeWhat
3895 // is found (as one shape or several parts). But we are also interested
3896 // in the partial result, that is why this check is commented.
3897 //if (!aGIP.IsFound()) {
3898 // SetErrorCode(NOT_FOUND_ANY);
3902 const TopTools_DataMapOfShapeListOfShape& aDMSLS = aGIP.Images();
3903 if (!aDMSLS.IsBound(aWhat)) {
3904 SetErrorCode(NOT_FOUND_ANY);
3908 // the list of shapes aLSA contains the shapes
3909 // of the Shape For Search that corresponds
3910 // to the Argument aWhat
3911 const TopTools_ListOfShape& aLSA = aDMSLS.Find(aWhat);
3912 if (aLSA.Extent() == 0) {
3913 SetErrorCode(NOT_FOUND_ANY); // Not found any Results
3917 Handle(TColStd_HArray1OfInteger) aModifiedArray = new TColStd_HArray1OfInteger (1, aLSA.Extent());
3918 TopTools_ListIteratorOfListOfShape anIterModif (aLSA);
3919 for (Standard_Integer imod = 1; anIterModif.More(); anIterModif.Next(), imod++) {
3920 if (aWhereIndices.Contains(anIterModif.Value())) {
3921 aModifiedArray->SetValue(imod, aWhereIndices.FindIndex(anIterModif.Value()));
3924 SetErrorCode("Error: wrong sub shape returned");
3930 Handle(GEOM_Object) aResult = GetEngine()->AddSubShape(theShapeWhere, aModifiedArray);
3931 if (aResult.IsNull()) {
3932 SetErrorCode("Error in algorithm: result found, but cannot be returned.");
3936 if (aModifiedArray->Length() > 1) {
3938 aResult->SetType(GEOM_GROUP);
3940 //Set a sub shape type
3941 TopoDS_Shape aFirstFound = aLSA.First();
3942 TopAbs_ShapeEnum aShapeType = aFirstFound.ShapeType();
3944 TDF_Label aFreeLabel = aResult->GetFreeLabel();
3945 TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aShapeType);
3948 //Make a Python command
3949 Handle(GEOM_Function) aFunction = aResult->GetFunction(1);
3951 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetInPlace("
3952 << theShapeWhere << ", " << theShapeWhat << ", True)";
3958 //=============================================================================
3960 * case GetInPlaceOld:
3963 //=============================================================================
3964 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlaceOld (Handle(GEOM_Object) theShapeWhere,
3965 Handle(GEOM_Object) theShapeWhat)
3969 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
3971 TopoDS_Shape aWhere = theShapeWhere->GetValue();
3972 TopoDS_Shape aWhat = theShapeWhat->GetValue();
3973 TopoDS_Shape aPntShape;
3974 TopoDS_Vertex aVertex;
3976 if (aWhere.IsNull() || aWhat.IsNull()) {
3977 SetErrorCode("Error: aWhere and aWhat TopoDS_Shape are Null.");
3981 Handle(GEOM_Function) aWhereFunction = theShapeWhere->GetLastFunction();
3982 if (aWhereFunction.IsNull()) {
3983 SetErrorCode("Error: aWhereFunction is Null.");
3987 TopTools_IndexedMapOfShape aWhereIndices;
3988 TopExp::MapShapes(aWhere, aWhereIndices);
3990 TColStd_ListOfInteger aModifiedList;
3991 Standard_Integer aWhereIndex;
3992 Handle(TColStd_HArray1OfInteger) aModifiedArray;
3993 Handle(GEOM_Object) aResult;
3995 bool isFound = false;
3996 TopAbs_ShapeEnum iType = TopAbs_SOLID;
3997 //Standard_Real aWhat_Mass = 0., aWhere_Mass = 0.;
3998 Standard_Real tab_aWhat[4], tab_aWhere[4];
3999 Standard_Real dl_l = 1e-3;
4000 Standard_Real min_l, Tol_0D, Tol_1D, Tol_2D, Tol_3D, Tol_Mass;
4001 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
4002 Bnd_Box BoundingBox;
4003 gp_Pnt aPnt, aPnt_aWhat, tab_Pnt[2];
4004 GProp_GProps aProps;
4006 // Find the iType of the aWhat shape
4008 if ( aWhat.ShapeType() == TopAbs_VERTEX ) iType = TopAbs_VERTEX;
4009 else if ( aWhat.ShapeType() == TopAbs_EDGE || aWhat.ShapeType() == TopAbs_WIRE ) iType = TopAbs_EDGE;
4010 else if ( aWhat.ShapeType() == TopAbs_FACE || aWhat.ShapeType() == TopAbs_SHELL ) iType = TopAbs_FACE;
4011 else if ( aWhat.ShapeType() == TopAbs_SOLID || aWhat.ShapeType() == TopAbs_COMPSOLID ) iType = TopAbs_SOLID;
4012 else if ( aWhat.ShapeType() == TopAbs_COMPOUND ) {
4013 // Only the iType of the first shape in the compound is taken into account
4014 TopoDS_Iterator It (aWhat, Standard_False, Standard_False);
4016 SetErrorCode("Error: theShapeWhat is an empty COMPOUND.");
4019 TopAbs_ShapeEnum compType = It.Value().ShapeType();
4020 if ( compType == TopAbs_VERTEX ) iType = TopAbs_VERTEX;
4021 else if ( compType == TopAbs_EDGE || compType == TopAbs_WIRE ) iType = TopAbs_EDGE;
4022 else if ( compType == TopAbs_FACE || compType == TopAbs_SHELL) iType = TopAbs_FACE;
4023 else if ( compType == TopAbs_SOLID || compType == TopAbs_COMPSOLID) iType = TopAbs_SOLID;
4026 SetErrorCode("Error: An attempt to extract a shape of not supported type.");
4030 iType = GetTypeOfSimplePart(aWhat);
4031 if (iType == TopAbs_SHAPE) {
4032 SetErrorCode("Error: An attempt to extract a shape of not supported type.");
4036 TopExp_Explorer Exp_aWhat ( aWhat, iType );
4037 TopExp_Explorer Exp_aWhere ( aWhere, iType );
4038 TopExp_Explorer Exp_Edge ( aWhere, TopAbs_EDGE );
4040 // Find the shortest edge in theShapeWhere shape
4041 BRepBndLib::Add(aWhere, BoundingBox);
4042 BoundingBox.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
4043 min_l = fabs(aXmax - aXmin);
4044 if( min_l < fabs(aYmax - aYmin) ) min_l = fabs(aYmax - aYmin);
4045 if( min_l < fabs(aZmax - aZmin) ) min_l = fabs(aZmax - aZmin);
4047 // Mantis issue 0020908 BEGIN
4048 if (!Exp_Edge.More()) {
4049 min_l = Precision::Confusion();
4051 // Mantis issue 0020908 END
4052 for ( Standard_Integer nbEdge = 0; Exp_Edge.More(); Exp_Edge.Next(), nbEdge++ ) {
4053 TopExp_Explorer Exp_Vertex( Exp_Edge.Current(), TopAbs_VERTEX);
4054 for ( Standard_Integer nbVertex = 0; Exp_Vertex.More(); Exp_Vertex.Next(), nbVertex++ ) {
4055 aPnt = BRep_Tool::Pnt( TopoDS::Vertex( Exp_Vertex.Current() ) );
4056 tab_Pnt[nbVertex] = aPnt;
4058 if ( ! tab_Pnt[0].IsEqual(tab_Pnt[1], dl_l) ) {
4059 BRepGProp::LinearProperties(Exp_Edge.Current(), aProps);
4060 if ( aProps.Mass() < min_l ) min_l = aProps.Mass();
4064 // Compute tolerances
4066 Tol_1D = dl_l * min_l;
4067 Tol_2D = dl_l * ( min_l * min_l) * ( 2. + dl_l);
4068 Tol_3D = dl_l * ( min_l * min_l * min_l ) * ( 3. + (3 * dl_l) + (dl_l * dl_l) );
4070 if (Tol_0D < Precision::Confusion()) Tol_0D = Precision::Confusion();
4071 if (Tol_1D < Precision::Confusion()) Tol_1D = Precision::Confusion();
4072 if (Tol_2D < Precision::Confusion()) Tol_2D = Precision::Confusion();
4073 if (Tol_3D < Precision::Confusion()) Tol_3D = Precision::Confusion();
4075 //if (Tol_1D > 1.0) Tol_1D = 1.0;
4076 //if (Tol_2D > 1.0) Tol_2D = 1.0;
4077 //if (Tol_3D > 1.0) Tol_3D = 1.0;
4080 if ( iType == TopAbs_VERTEX ) Tol_Mass = Tol_0D;
4081 else if ( iType == TopAbs_EDGE ) Tol_Mass = Tol_1D;
4082 else if ( iType == TopAbs_FACE ) Tol_Mass = Tol_2D;
4084 // Compute the ShapeWhat Mass
4086 for ( ; Exp_aWhat.More(); Exp_aWhat.Next() ) {
4087 if ( iType == TopAbs_VERTEX ) {
4091 else if ( iType == TopAbs_EDGE ) BRepGProp::LinearProperties(Exp_aWhat.Current(), aProps);
4092 else if ( iType == TopAbs_FACE ) BRepGProp::SurfaceProperties(Exp_aWhat.Current(), aProps);
4093 else BRepGProp::VolumeProperties(Exp_aWhat.Current(), aProps);
4094 aWhat_Mass += aProps.Mass();
4098 // Searching for the sub-shapes inside the ShapeWhere shape
4099 TopTools_MapOfShape map_aWhere;
4100 for ( Exp_aWhere.ReInit(); Exp_aWhere.More(); Exp_aWhere.Next() ) {
4101 if (!map_aWhere.Add(Exp_aWhere.Current()))
4102 continue; // skip repeated shape to avoid mass addition
4103 GetShapeProperties( Exp_aWhere.Current(), tab_aWhere, aPnt );
4104 for ( Exp_aWhat.ReInit(); Exp_aWhat.More(); Exp_aWhat.Next() ) {
4105 GetShapeProperties( Exp_aWhat.Current(), tab_aWhat, aPnt_aWhat );
4106 if ( fabs(tab_aWhat[3] - tab_aWhere[3]) <= Tol_Mass && aPnt_aWhat.Distance(aPnt) <= Tol_1D )
4109 if ( (tab_aWhat[3] - tab_aWhere[3]) > Tol_Mass ) {
4110 aPntShape = BRepBuilderAPI_MakeVertex( aPnt ).Shape();
4111 aVertex = TopoDS::Vertex( aPntShape );
4112 BRepExtrema_DistShapeShape aWhereDistance ( aVertex, Exp_aWhere.Current() );
4113 BRepExtrema_DistShapeShape aWhatDistance ( aVertex, Exp_aWhat.Current() );
4114 if ( aWhereDistance.IsDone() && aWhatDistance.IsDone() &&
4115 fabs(aWhereDistance.Value() - aWhatDistance.Value()) <= Tol_1D )
4117 // 0020162: "EDF 961 GEOM : Getinplace is getting additionnal orthogonal faces"
4118 // aVertex must be projected to the same point on Where and on What
4119 gp_Pnt pOnWhat = aWhatDistance.PointOnShape2(1);
4120 gp_Pnt pOnWhere = aWhereDistance.PointOnShape2(1);
4121 isFound = ( pOnWhat.Distance(pOnWhere) <= Tol_1D );
4122 if ( isFound && iType == TopAbs_FACE )
4124 // check normals at pOnWhat and pOnWhere
4125 const double angleTol = M_PI/180.;
4126 gp_Vec normToWhat = GetNormal( TopoDS::Face(Exp_aWhat.Current()), aWhatDistance);
4127 gp_Vec normToWhere = GetNormal( TopoDS::Face(Exp_aWhere.Current()), aWhereDistance);
4128 if ( normToWhat * normToWhere < 0 )
4129 normToWhat.Reverse();
4130 isFound = ( normToWhat.Angle( normToWhere ) < angleTol );
4136 aWhereIndex = aWhereIndices.FindIndex(Exp_aWhere.Current());
4137 aModifiedList.Append(aWhereIndex);
4138 //aWhere_Mass += tab_aWhere[3];
4143 //if ( fabs( aWhat_Mass - aWhere_Mass ) <= Tol_Mass )
4147 if (aModifiedList.Extent() == 0) { // Not found any Results
4148 SetErrorCode(NOT_FOUND_ANY);
4152 aModifiedArray = new TColStd_HArray1OfInteger (1, aModifiedList.Extent());
4153 TColStd_ListIteratorOfListOfInteger anIterModif (aModifiedList);
4154 for (Standard_Integer imod = 1; anIterModif.More(); anIterModif.Next(), imod++)
4155 aModifiedArray->SetValue(imod, anIterModif.Value());
4158 aResult = GetEngine()->AddSubShape(theShapeWhere, aModifiedArray);
4159 if (aResult.IsNull()) {
4160 SetErrorCode("Error in algorithm: result found, but cannot be returned.");
4164 if (aModifiedArray->Length() > 1) {
4166 aResult->SetType(GEOM_GROUP);
4168 //Set a sub shape type
4169 TopoDS_Shape aFirstFound = aWhereIndices.FindKey(aModifiedArray->Value(1));
4170 TopAbs_ShapeEnum aShapeType = aFirstFound.ShapeType();
4172 TDF_Label aFreeLabel = aResult->GetFreeLabel();
4173 TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aShapeType);
4176 //Make a Python command
4177 Handle(GEOM_Function) aFunction = aResult->GetFunction(1);
4179 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetInPlace("
4180 << theShapeWhere << ", " << theShapeWhat << ", False)";
4186 //=======================================================================
4187 //function : GetInPlaceByHistory
4189 //=======================================================================
4190 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlaceByHistory
4191 (Handle(GEOM_Object) theShapeWhere,
4192 Handle(GEOM_Object) theShapeWhat)
4196 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
4198 TopoDS_Shape aWhere = theShapeWhere->GetValue();
4199 TopoDS_Shape aWhat = theShapeWhat->GetValue();
4201 if (aWhere.IsNull() || aWhat.IsNull()) return NULL;
4203 Handle(GEOM_Function) aWhereFunction = theShapeWhere->GetLastFunction();
4204 if (aWhereFunction.IsNull()) return NULL;
4206 //Fill array of indices
4207 TopTools_IndexedMapOfShape aWhereIndices;
4208 TopExp::MapShapes(aWhere, aWhereIndices);
4211 TColStd_ListOfInteger aModifiedList;
4212 bool isFound = GetInPlaceOfShape(aWhereFunction, aWhereIndices, aWhat, aModifiedList);
4214 if (!isFound || aModifiedList.Extent() < 1) {
4215 SetErrorCode("Error: No history found for the sought shape or its sub-shapes.");
4219 Handle(TColStd_HArray1OfInteger) aModifiedArray =
4220 new TColStd_HArray1OfInteger (1, aModifiedList.Extent());
4221 TColStd_ListIteratorOfListOfInteger anIterModif (aModifiedList);
4222 for (Standard_Integer imod = 1; anIterModif.More(); anIterModif.Next(), imod++) {
4223 aModifiedArray->SetValue(imod, anIterModif.Value());
4227 Handle(GEOM_Object) aResult = GetEngine()->AddSubShape(theShapeWhere, aModifiedArray);
4228 if (aResult.IsNull()) {
4229 SetErrorCode("Error in algorithm: result found, but cannot be returned.");
4233 if (aModifiedArray->Length() > 1) {
4235 aResult->SetType(GEOM_GROUP);
4237 //Set a sub shape type
4238 TopoDS_Shape aFirstFound = aWhereIndices.FindKey(aModifiedArray->Value(1));
4239 TopAbs_ShapeEnum aShapeType = aFirstFound.ShapeType();
4241 TDF_Label aFreeLabel = aResult->GetFreeLabel();
4242 TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aShapeType);
4245 //Make a Python command
4246 Handle(GEOM_Function) aFunction = aResult->GetFunction(1);
4248 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetInPlaceByHistory("
4249 << theShapeWhere << ", " << theShapeWhat << ")";
4255 //=======================================================================
4256 //function : ShapeToDouble
4257 //purpose : used by CompareShapes::operator()
4258 //=======================================================================
4259 std::pair<double, double> ShapeToDouble (const TopoDS_Shape& S, bool isOldSorting)
4261 // Computing of CentreOfMass
4265 if (S.ShapeType() == TopAbs_VERTEX) {
4266 GPoint = BRep_Tool::Pnt(TopoDS::Vertex(S));
4267 Len = (double)S.Orientation();
4271 // BEGIN: fix for Mantis issue 0020842
4273 BRepGProp::LinearProperties(S, GPr);
4276 if (S.ShapeType() == TopAbs_EDGE || S.ShapeType() == TopAbs_WIRE) {
4277 BRepGProp::LinearProperties(S, GPr);
4279 else if (S.ShapeType() == TopAbs_FACE || S.ShapeType() == TopAbs_SHELL) {
4280 BRepGProp::SurfaceProperties(S, GPr);
4283 BRepGProp::VolumeProperties(S, GPr);
4286 // END: fix for Mantis issue 0020842
4287 GPoint = GPr.CentreOfMass();
4291 double dMidXYZ = GPoint.X() * 999.0 + GPoint.Y() * 99.0 + GPoint.Z() * 0.9;
4292 return std::make_pair(dMidXYZ, Len);
4295 //=======================================================================
4296 //function : CompareShapes::operator()
4297 //purpose : used by std::sort(), called from SortShapes()
4298 //=======================================================================
4299 bool GEOMImpl_IShapesOperations::CompareShapes::operator()(const TopoDS_Shape& theShape1,
4300 const TopoDS_Shape& theShape2)
4302 if (!myMap.IsBound(theShape1)) {
4303 myMap.Bind(theShape1, ShapeToDouble(theShape1, myIsOldSorting));
4306 if (!myMap.IsBound(theShape2)) {
4307 myMap.Bind(theShape2, ShapeToDouble(theShape2, myIsOldSorting));
4310 std::pair<double, double> val1 = myMap.Find(theShape1);
4311 std::pair<double, double> val2 = myMap.Find(theShape2);
4313 double tol = Precision::Confusion();
4314 bool exchange = Standard_False;
4316 double dMidXYZ = val1.first - val2.first;
4317 if (dMidXYZ >= tol) {
4318 exchange = Standard_True;
4320 else if (Abs(dMidXYZ) < tol) {
4321 double dLength = val1.second - val2.second;
4322 if (dLength >= tol) {
4323 exchange = Standard_True;
4325 else if (Abs(dLength) < tol && theShape1.ShapeType() <= TopAbs_FACE) {
4327 // equal values possible on shapes such as two halves of a sphere and
4328 // a membrane inside the sphere
4330 BRepBndLib::Add(theShape1, box1);
4331 if (!box1.IsVoid()) {
4332 BRepBndLib::Add(theShape2, box2);
4333 Standard_Real dSquareExtent = box1.SquareExtent() - box2.SquareExtent();
4334 if (dSquareExtent >= tol) {
4335 exchange = Standard_True;
4337 else if (Abs(dSquareExtent) < tol) {
4338 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax, val1, val2;
4339 box1.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
4340 val1 = (aXmin+aXmax)*999.0 + (aYmin+aYmax)*99.0 + (aZmin+aZmax)*0.9;
4341 box2.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
4342 val2 = (aXmin+aXmax)*999.0 + (aYmin+aYmax)*99.0 + (aZmin+aZmax)*0.9;
4343 if ((val1 - val2) >= tol) {
4344 exchange = Standard_True;
4351 //return val1 < val2;
4355 //=======================================================================
4356 //function : SortShapes
4358 //=======================================================================
4359 void GEOMImpl_IShapesOperations::SortShapes(TopTools_ListOfShape& SL,
4360 const Standard_Boolean isOldSorting)
4362 #ifdef STD_SORT_ALGO
4363 std::vector<TopoDS_Shape> aShapesVec;
4364 aShapesVec.reserve(SL.Extent());
4366 TopTools_ListIteratorOfListOfShape it (SL);
4367 for (; it.More(); it.Next()) {
4368 aShapesVec.push_back(it.Value());
4372 CompareShapes shComp (isOldSorting);
4373 std::stable_sort(aShapesVec.begin(), aShapesVec.end(), shComp);
4374 //std::sort(aShapesVec.begin(), aShapesVec.end(), shComp);
4376 std::vector<TopoDS_Shape>::const_iterator anIter = aShapesVec.begin();
4377 for (; anIter != aShapesVec.end(); ++anIter) {
4381 // old implementation
4382 Standard_Integer MaxShapes = SL.Extent();
4383 TopTools_Array1OfShape aShapes (1,MaxShapes);
4384 TColStd_Array1OfInteger OrderInd(1,MaxShapes);
4385 TColStd_Array1OfReal MidXYZ (1,MaxShapes); //X,Y,Z;
4386 TColStd_Array1OfReal Length (1,MaxShapes); //X,Y,Z;
4388 // Computing of CentreOfMass
4389 Standard_Integer Index;
4392 TopTools_ListIteratorOfListOfShape it(SL);
4393 for (Index=1; it.More(); Index++)
4395 TopoDS_Shape S = it.Value();
4396 SL.Remove( it ); // == it.Next()
4398 OrderInd.SetValue (Index, Index);
4399 if (S.ShapeType() == TopAbs_VERTEX) {
4400 GPoint = BRep_Tool::Pnt( TopoDS::Vertex( S ));
4401 Length.SetValue( Index, (Standard_Real) S.Orientation());
4404 // BEGIN: fix for Mantis issue 0020842
4406 BRepGProp::LinearProperties (S, GPr);
4409 if (S.ShapeType() == TopAbs_EDGE || S.ShapeType() == TopAbs_WIRE) {
4410 BRepGProp::LinearProperties (S, GPr);
4412 else if (S.ShapeType() == TopAbs_FACE || S.ShapeType() == TopAbs_SHELL) {
4413 BRepGProp::SurfaceProperties(S, GPr);
4416 BRepGProp::VolumeProperties(S, GPr);
4419 // END: fix for Mantis issue 0020842
4420 GPoint = GPr.CentreOfMass();
4421 Length.SetValue(Index, GPr.Mass());
4423 MidXYZ.SetValue(Index, GPoint.X()*999.0 + GPoint.Y()*99.0 + GPoint.Z()*0.9);
4424 //cout << Index << " L: " << Length(Index) << "CG: " << MidXYZ(Index) << endl;
4428 Standard_Integer aTemp;
4429 Standard_Boolean exchange, Sort = Standard_True;
4430 Standard_Real tol = Precision::Confusion();
4433 Sort = Standard_False;
4434 for (Index=1; Index < MaxShapes; Index++)
4436 exchange = Standard_False;
4437 Standard_Real dMidXYZ = MidXYZ(OrderInd(Index)) - MidXYZ(OrderInd(Index+1));
4438 Standard_Real dLength = Length(OrderInd(Index)) - Length(OrderInd(Index+1));
4439 if ( dMidXYZ >= tol ) {
4440 // cout << "MidXYZ: " << MidXYZ(OrderInd(Index))<< " > " <<MidXYZ(OrderInd(Index+1))
4441 // << " d: " << dMidXYZ << endl;
4442 exchange = Standard_True;
4444 else if ( Abs(dMidXYZ) < tol && dLength >= tol ) {
4445 // cout << "Length: " << Length(OrderInd(Index))<< " > " <<Length(OrderInd(Index+1))
4446 // << " d: " << dLength << endl;
4447 exchange = Standard_True;
4449 else if ( Abs(dMidXYZ) < tol && Abs(dLength) < tol &&
4450 aShapes(OrderInd(Index)).ShapeType() <= TopAbs_FACE) {
4452 // equal values possible on shapes such as two halves of a sphere and
4453 // a membrane inside the sphere
4455 BRepBndLib::Add( aShapes( OrderInd(Index) ), box1 );
4456 if ( box1.IsVoid() ) continue;
4457 BRepBndLib::Add( aShapes( OrderInd(Index+1) ), box2 );
4458 Standard_Real dSquareExtent = box1.SquareExtent() - box2.SquareExtent();
4459 if ( dSquareExtent >= tol ) {
4460 // cout << "SquareExtent: " << box1.SquareExtent()<<" > "<<box2.SquareExtent() << endl;
4461 exchange = Standard_True;
4463 else if ( Abs(dSquareExtent) < tol ) {
4464 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax, val1, val2;
4465 box1.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
4466 val1 = (aXmin+aXmax)*999 + (aYmin+aYmax)*99 + (aZmin+aZmax)*0.9;
4467 box2.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
4468 val2 = (aXmin+aXmax)*999 + (aYmin+aYmax)*99 + (aZmin+aZmax)*0.9;
4469 //exchange = val1 > val2;
4470 if ((val1 - val2) >= tol) {
4471 exchange = Standard_True;
4473 //cout << "box: " << val1<<" > "<<val2 << endl;
4479 // cout << "exchange " << Index << " & " << Index+1 << endl;
4480 aTemp = OrderInd(Index);
4481 OrderInd(Index) = OrderInd(Index+1);
4482 OrderInd(Index+1) = aTemp;
4483 Sort = Standard_True;
4488 for (Index=1; Index <= MaxShapes; Index++)
4489 SL.Append( aShapes( OrderInd(Index) ));
4493 //=======================================================================
4494 //function : CompsolidToCompound
4496 //=======================================================================
4497 TopoDS_Shape GEOMImpl_IShapesOperations::CompsolidToCompound (const TopoDS_Shape& theCompsolid)
4499 if (theCompsolid.ShapeType() != TopAbs_COMPSOLID) {
4500 return theCompsolid;
4503 TopoDS_Compound aCompound;
4505 B.MakeCompound(aCompound);
4507 TopTools_MapOfShape mapShape;
4508 TopoDS_Iterator It (theCompsolid, Standard_True, Standard_True);
4510 for (; It.More(); It.Next()) {
4511 TopoDS_Shape aShape_i = It.Value();
4512 if (mapShape.Add(aShape_i)) {
4513 B.Add(aCompound, aShape_i);
4520 //=======================================================================
4521 //function : CheckTriangulation
4523 //=======================================================================
4524 bool GEOMImpl_IShapesOperations::CheckTriangulation (const TopoDS_Shape& aShape)
4526 bool isTriangulation = true;
4528 TopExp_Explorer exp (aShape, TopAbs_FACE);
4531 TopLoc_Location aTopLoc;
4532 Handle(Poly_Triangulation) aTRF;
4533 aTRF = BRep_Tool::Triangulation(TopoDS::Face(exp.Current()), aTopLoc);
4534 if (aTRF.IsNull()) {
4535 isTriangulation = false;
4538 else // no faces, try edges
4540 TopExp_Explorer expe (aShape, TopAbs_EDGE);
4544 TopLoc_Location aLoc;
4545 Handle(Poly_Polygon3D) aPE = BRep_Tool::Polygon3D(TopoDS::Edge(expe.Current()), aLoc);
4547 isTriangulation = false;
4551 if (!isTriangulation) {
4552 // calculate deflection
4553 Standard_Real aDeviationCoefficient = 0.001;
4556 BRepBndLib::Add(aShape, B);
4557 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
4558 B.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
4560 Standard_Real dx = aXmax - aXmin, dy = aYmax - aYmin, dz = aZmax - aZmin;
4561 Standard_Real aDeflection = Max(Max(dx, dy), dz) * aDeviationCoefficient * 4;
4562 Standard_Real aHLRAngle = 0.349066;
4564 BRepMesh_IncrementalMesh Inc (aShape, aDeflection, Standard_False, aHLRAngle);
4570 #define MAX_TOLERANCE 1.e-7
4572 //=======================================================================
4573 //function : isSameEdge
4574 //purpose : Returns True if two edges coincide
4575 //=======================================================================
4576 static bool isSameEdge(const TopoDS_Edge& theEdge1, const TopoDS_Edge& theEdge2)
4578 TopoDS_Vertex V11, V12, V21, V22;
4579 TopExp::Vertices(theEdge1, V11, V12);
4580 TopExp::Vertices(theEdge2, V21, V22);
4581 gp_Pnt P11 = BRep_Tool::Pnt(V11);
4582 gp_Pnt P12 = BRep_Tool::Pnt(V12);
4583 gp_Pnt P21 = BRep_Tool::Pnt(V21);
4584 gp_Pnt P22 = BRep_Tool::Pnt(V22);
4585 bool coincide = false;
4587 //Check that ends of edges coincide
4588 if(P11.Distance(P21) <= MAX_TOLERANCE) {
4589 if(P12.Distance(P22) <= MAX_TOLERANCE) coincide = true;
4591 else if(P11.Distance(P22) <= MAX_TOLERANCE) {
4592 if(P12.Distance(P21) <= MAX_TOLERANCE) coincide = true;
4595 if(!coincide) return false;
4597 if (BRep_Tool::Degenerated(theEdge1))
4598 if (BRep_Tool::Degenerated(theEdge2)) return true;
4601 if (BRep_Tool::Degenerated(theEdge2)) return false;
4603 double U11, U12, U21, U22;
4604 Handle(Geom_Curve) C1 = BRep_Tool::Curve(theEdge1, U11, U12);
4605 Handle(Geom_Curve) C2 = BRep_Tool::Curve(theEdge2, U21, U22);
4606 if(C1->DynamicType() == C2->DynamicType()) return true;
4608 //Check that both edges has the same geometry
4609 double range = U12-U11;
4610 double U = U11+ range/3.0;
4611 gp_Pnt P1 = C1->Value(U); //Compute a point on one third of the edge's length
4612 U = U11+range*2.0/3.0;
4613 gp_Pnt P2 = C1->Value(U); //Compute a point on two thirds of the edge's length
4615 if(!GeomLib_Tool::Parameter(C2, P1, MAX_TOLERANCE, U) || U < U21 || U > U22)
4618 if(P1.Distance(C2->Value(U)) > MAX_TOLERANCE) return false;
4620 if(!GeomLib_Tool::Parameter(C2, P2, MAX_TOLERANCE, U) || U < U21 || U > U22)
4623 if(P2.Distance(C2->Value(U)) > MAX_TOLERANCE) return false;
4628 #include <TopoDS_TShape.hxx>
4629 //=======================================================================
4630 //function : isSameFace
4631 //purpose : Returns True if two faces coincide
4632 //=======================================================================
4633 static bool isSameFace(const TopoDS_Face& theFace1, const TopoDS_Face& theFace2)
4635 TopExp_Explorer E(theFace1, TopAbs_EDGE);
4636 TopTools_ListOfShape LS1, LS2;
4637 for(; E.More(); E.Next()) LS1.Append(E.Current());
4639 E.Init(theFace2, TopAbs_EDGE);
4640 for(; E.More(); E.Next()) LS2.Append(E.Current());
4642 //Compare the number of edges in the faces
4643 if(LS1.Extent() != LS2.Extent()) return false;
4645 double aMin = RealFirst(), aMax = RealLast();
4646 double xminB1=aMax, yminB1=aMax, zminB1=aMax, xminB2=aMax, yminB2=aMax, zminB2=aMax;
4647 double xmaxB1=aMin, ymaxB1=aMin, zmaxB1=aMin, xmaxB2=aMin, ymaxB2=aMin, zmaxB2=aMin;
4649 for(E.Init(theFace1, TopAbs_VERTEX); E.More(); E.Next()) {
4650 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4651 if(P.X() < xminB1) xminB1 = P.X();
4652 if(P.Y() < yminB1) yminB1 = P.Y();
4653 if(P.Z() < zminB1) zminB1 = P.Z();
4654 if(P.X() > xmaxB1) xmaxB1 = P.X();
4655 if(P.Y() > ymaxB1) ymaxB1 = P.Y();
4656 if(P.Z() > zmaxB1) zmaxB1 = P.Z();
4659 for(E.Init(theFace2, TopAbs_VERTEX); E.More(); E.Next()) {
4660 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4661 if(P.X() < xminB2) xminB2 = P.X();
4662 if(P.Y() < yminB2) yminB2 = P.Y();
4663 if(P.Z() < zminB2) zminB2 = P.Z();
4664 if(P.X() > xmaxB2) xmaxB2 = P.X();
4665 if(P.Y() > ymaxB2) ymaxB2 = P.Y();
4666 if(P.Z() > zmaxB2) zmaxB2 = P.Z();
4669 //Compare the bounding boxes of both faces
4670 if(gp_Pnt(xminB1, yminB1, zminB1).Distance(gp_Pnt(xminB2, yminB2, zminB2)) > MAX_TOLERANCE)
4673 if(gp_Pnt(xmaxB1, ymaxB1, zmaxB1).Distance(gp_Pnt(xmaxB2, ymaxB2, zmaxB2)) > MAX_TOLERANCE)
4676 Handle(Geom_Surface) S1 = BRep_Tool::Surface(theFace1);
4677 Handle(Geom_Surface) S2 = BRep_Tool::Surface(theFace2);
4679 //Check if there a coincidence of two surfaces at least in two points
4680 double U11, U12, V11, V12, U21, U22, V21, V22;
4681 BRepTools::UVBounds(theFace1, U11, U12, V11, V12);
4682 BRepTools::UVBounds(theFace2, U21, U22, V21, V22);
4684 double rangeU = U12-U11;
4685 double rangeV = V12-V11;
4686 double U = U11 + rangeU/3.0;
4687 double V = V11 + rangeV/3.0;
4688 gp_Pnt P1 = S1->Value(U, V);
4689 U = U11+rangeU*2.0/3.0;
4690 V = V11+rangeV*2.0/3.0;
4691 gp_Pnt P2 = S1->Value(U, V);
4693 if (!GeomLib_Tool::Parameters(S2, P1, MAX_TOLERANCE, U, V) || U < U21 || U > U22 || V < V21 || V > V22)
4696 if (P1.Distance(S2->Value(U,V)) > MAX_TOLERANCE) return false;
4698 if (!GeomLib_Tool::Parameters(S2, P2, MAX_TOLERANCE, U, V) || U < U21 || U > U22 || V < V21 || V > V22)
4701 if (P2.Distance(S2->Value(U, V)) > MAX_TOLERANCE) return false;
4703 //Check that each edge of the Face1 has a counterpart in the Face2
4704 TopTools_MapOfOrientedShape aMap;
4705 TopTools_ListIteratorOfListOfShape LSI1(LS1);
4706 for(; LSI1.More(); LSI1.Next()) {
4707 TopoDS_Edge E = TopoDS::Edge(LSI1.Value());
4708 bool isFound = false;
4709 TopTools_ListIteratorOfListOfShape LSI2(LS2);
4710 for(; LSI2.More(); LSI2.Next()) {
4711 TopoDS_Shape aValue = LSI2.Value();
4712 if(aMap.Contains(aValue)) continue; //To avoid checking already found edge several times
4713 if(isSameEdge(E, TopoDS::Edge(aValue))) {
4719 if(!isFound) return false;
4725 //=======================================================================
4726 //function : isSameSolid
4727 //purpose : Returns True if two solids coincide
4728 //=======================================================================
4729 bool isSameSolid(const TopoDS_Solid& theSolid1, const TopoDS_Solid& theSolid2)
4731 TopExp_Explorer E(theSolid1, TopAbs_FACE);
4732 TopTools_ListOfShape LS1, LS2;
4733 for(; E.More(); E.Next()) LS1.Append(E.Current());
4734 E.Init(theSolid2, TopAbs_FACE);
4735 for(; E.More(); E.Next()) LS2.Append(E.Current());
4737 if(LS1.Extent() != LS2.Extent()) return false;
4739 double aMin = RealFirst(), aMax = RealLast();
4740 double xminB1=aMax, yminB1=aMax, zminB1=aMax, xminB2=aMax, yminB2=aMax, zminB2=aMax;
4741 double xmaxB1=aMin, ymaxB1=aMin, zmaxB1=aMin, xmaxB2=aMin, ymaxB2=aMin, zmaxB2=aMin;
4743 for(E.Init(theSolid1, TopAbs_VERTEX); E.More(); E.Next()) {
4744 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4745 if(P.X() < xminB1) xminB1 = P.X();
4746 if(P.Y() < yminB1) yminB1 = P.Y();
4747 if(P.Z() < zminB1) zminB1 = P.Z();
4748 if(P.X() > xmaxB1) xmaxB1 = P.X();
4749 if(P.Y() > ymaxB1) ymaxB1 = P.Y();
4750 if(P.Z() > zmaxB1) zmaxB1 = P.Z();
4753 for(E.Init(theSolid2, TopAbs_VERTEX); E.More(); E.Next()) {
4754 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4755 if(P.X() < xminB2) xminB2 = P.X();
4756 if(P.Y() < yminB2) yminB2 = P.Y();
4757 if(P.Z() < zminB2) zminB2 = P.Z();
4758 if(P.X() > xmaxB2) xmaxB2 = P.X();
4759 if(P.Y() > ymaxB2) ymaxB2 = P.Y();
4760 if(P.Z() > zmaxB2) zmaxB2 = P.Z();
4763 //Compare the bounding boxes of both solids
4764 if(gp_Pnt(xminB1, yminB1, zminB1).Distance(gp_Pnt(xminB2, yminB2, zminB2)) > MAX_TOLERANCE)
4767 if(gp_Pnt(xmaxB1, ymaxB1, zmaxB1).Distance(gp_Pnt(xmaxB2, ymaxB2, zmaxB2)) > MAX_TOLERANCE)
4770 //Check that each face of the Solid1 has a counterpart in the Solid2
4771 TopTools_MapOfOrientedShape aMap;
4772 TopTools_ListIteratorOfListOfShape LSI1(LS1);
4773 for(; LSI1.More(); LSI1.Next()) {
4774 TopoDS_Face F = TopoDS::Face(LSI1.Value());
4775 bool isFound = false;
4776 TopTools_ListIteratorOfListOfShape LSI2(LS2);
4777 for(; LSI2.More(); LSI2.Next()) {
4778 if(aMap.Contains(LSI2.Value())) continue; //To avoid checking already found faces several times
4779 if(isSameFace(F, TopoDS::Face(LSI2.Value()))) {
4780 aMap.Add(LSI2.Value());
4785 if(!isFound) return false;
4791 //=======================================================================
4792 //function : GetSame
4794 //=======================================================================
4795 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetSame(const Handle(GEOM_Object)& theShapeWhere,
4796 const Handle(GEOM_Object)& theShapeWhat)
4799 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
4801 TopoDS_Shape aWhere = theShapeWhere->GetValue();
4802 TopoDS_Shape aWhat = theShapeWhat->GetValue();
4804 if (aWhere.IsNull() || aWhat.IsNull()) return NULL;
4807 bool isFound = false;
4808 TopoDS_Shape aSubShape;
4809 TopTools_MapOfShape aMap;
4811 if (aWhat.ShapeType() == TopAbs_COMPOUND || aWhat.ShapeType() == TopAbs_COMPSOLID) {
4812 TopoDS_Iterator It (aWhat, Standard_True, Standard_True);
4813 if (It.More()) aWhat = It.Value();
4816 SetErrorCode("Compounds of two or more shapes are not allowed for aWhat argument");
4821 switch (aWhat.ShapeType()) {
4822 case TopAbs_VERTEX: {
4823 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(aWhat));
4824 TopExp_Explorer E(aWhere, TopAbs_VERTEX);
4825 for(; E.More(); E.Next()) {
4826 if(!aMap.Add(E.Current())) continue;
4827 gp_Pnt P2 = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4828 if(P.Distance(P2) <= MAX_TOLERANCE) {
4830 aSubShape = E.Current();
4837 TopoDS_Edge anEdge = TopoDS::Edge(aWhat);
4838 TopExp_Explorer E(aWhere, TopAbs_EDGE);
4839 for(; E.More(); E.Next()) {
4840 if(!aMap.Add(E.Current())) continue;
4841 if(isSameEdge(anEdge, TopoDS::Edge(E.Current()))) {
4842 aSubShape = E.Current();
4850 TopoDS_Face aFace = TopoDS::Face(aWhat);
4851 TopExp_Explorer E(aWhere, TopAbs_FACE);
4852 for(; E.More(); E.Next()) {
4853 if(!aMap.Add(E.Current())) continue;
4854 if(isSameFace(aFace, TopoDS::Face(E.Current()))) {
4855 aSubShape = E.Current();
4862 case TopAbs_SOLID: {
4863 TopoDS_Solid aSolid = TopoDS::Solid(aWhat);
4864 TopExp_Explorer E(aWhere, TopAbs_SOLID);
4865 for(; E.More(); E.Next()) {
4866 if(!aMap.Add(E.Current())) continue;
4867 if(isSameSolid(aSolid, TopoDS::Solid(E.Current()))) {
4868 aSubShape = E.Current();
4880 TopTools_IndexedMapOfShape anIndices;
4881 TopExp::MapShapes(aWhere, anIndices);
4882 if (anIndices.Contains(aSubShape))
4883 anIndex = anIndices.FindIndex(aSubShape);
4886 if (anIndex < 0) return NULL;
4888 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
4890 anArray->SetValue(1, anIndex);
4892 Handle(GEOM_Object) aResult = GetEngine()->AddSubShape(theShapeWhere, anArray);
4893 Handle(GEOM_Function) aFunction = aResult->GetLastFunction();
4895 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetSame("
4896 << theShapeWhere << ", " << theShapeWhat << ")";