1 // Copyright (C) 2007-2012 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 sub-shapes 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 sub-shape in the list of sub-shapes 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 // IPAL22904: TC6.5.0: order of python commands is wrong after dump study
2055 Handle(TColStd_HSequenceOfTransient) anObjects = new TColStd_HSequenceOfTransient;
2056 for( it = theShapes.begin(); it != theShapes.end(); it++ )
2058 Handle(GEOM_Object) anObj = *it;
2059 if( !anObj.IsNull() )
2060 anObjects->Append( anObj );
2063 // Get the function of the latest published object
2064 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast( anObjects )->GetLastFunction();
2065 if( aFunction.IsNull() ) // just in case
2066 aFunction = aMainShape;
2068 GEOM::TPythonDump pd (aFunction, /*append=*/true);
2069 pd << "[" << anAsciiList.ToCString()
2070 << "] = geompy.GetSharedShapesMulti([";
2072 it = theShapes.begin();
2074 while (it != theShapes.end()) {
2075 pd << ", " << (*it++);
2078 pd << "], " << TopAbs_ShapeEnum(theShapeType) << ")";
2084 //=============================================================================
2088 //=============================================================================
2089 static GEOM::TPythonDump& operator<< (GEOM::TPythonDump& theDump,
2090 const GEOMAlgo_State theState)
2093 case GEOMAlgo_ST_IN:
2094 theDump << "geompy.GEOM.ST_IN";
2096 case GEOMAlgo_ST_OUT:
2097 theDump << "geompy.GEOM.ST_OUT";
2099 case GEOMAlgo_ST_ON:
2100 theDump << "geompy.GEOM.ST_ON";
2102 case GEOMAlgo_ST_ONIN:
2103 theDump << "geompy.GEOM.ST_ONIN";
2105 case GEOMAlgo_ST_ONOUT:
2106 theDump << "geompy.GEOM.ST_ONOUT";
2109 theDump << "geompy.GEOM.ST_UNKNOWN";
2115 //=======================================================================
2116 //function : checkTypeShapesOn
2118 * \brief Checks if theShapeType parameter of GetShapesOnXXX() is OK
2119 * \param theShapeType - the shape type to check
2120 * \retval bool - result of the check
2122 //=======================================================================
2123 bool GEOMImpl_IShapesOperations::checkTypeShapesOn(const Standard_Integer theShapeType)
2125 if (theShapeType != TopAbs_VERTEX &&
2126 theShapeType != TopAbs_EDGE &&
2127 theShapeType != TopAbs_FACE &&
2128 theShapeType != TopAbs_SOLID) {
2129 SetErrorCode("Only solids, vertices, edges or faces can be found by this method");
2135 //=======================================================================
2136 //function : makePlane
2138 * \brief Creates Geom_Plane
2139 * \param theAx1 - shape object defining plane parameters
2140 * \retval Handle(Geom_Surface) - resulting surface
2142 //=======================================================================
2143 Handle(Geom_Surface) GEOMImpl_IShapesOperations::makePlane(const TopoDS_Shape& anAx1)
2145 if (anAx1.ShapeType() != TopAbs_EDGE) return NULL;
2146 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
2147 TopoDS_Vertex V1, V2;
2148 TopExp::Vertices(anEdge, V1, V2, Standard_True);
2149 if (V1.IsNull() || V2.IsNull()) {
2150 SetErrorCode("Bad edge given for the plane normal vector");
2153 gp_Pnt aLoc = BRep_Tool::Pnt(V1);
2154 gp_Vec aVec (aLoc, BRep_Tool::Pnt(V2));
2155 if (aVec.Magnitude() < Precision::Confusion()) {
2156 SetErrorCode("Vector with null magnitude given");
2159 return new Geom_Plane(aLoc, aVec);
2162 //=======================================================================
2163 //function : makeCylinder
2165 * \brief Creates Geom_CylindricalSurface
2166 * \param theAx1 - edge defining cylinder axis
2167 * \param theRadius - cylinder radius
2168 * \retval Handle(Geom_Surface) - resulting surface
2170 //=======================================================================
2171 Handle(Geom_Surface) GEOMImpl_IShapesOperations::makeCylinder(const TopoDS_Shape& anAxis,
2172 const Standard_Real theRadius)
2174 //Axis of the cylinder
2175 if (anAxis.ShapeType() != TopAbs_EDGE) {
2176 SetErrorCode("Not an edge given for the axis");
2179 TopoDS_Edge anEdge = TopoDS::Edge(anAxis);
2180 TopoDS_Vertex V1, V2;
2181 TopExp::Vertices(anEdge, V1, V2, Standard_True);
2182 if (V1.IsNull() || V2.IsNull()) {
2183 SetErrorCode("Bad edge given for the axis");
2186 gp_Pnt aLoc = BRep_Tool::Pnt(V1);
2187 gp_Vec aVec (aLoc, BRep_Tool::Pnt(V2));
2188 if (aVec.Magnitude() < Precision::Confusion()) {
2189 SetErrorCode("Vector with null magnitude given");
2193 gp_Ax3 anAx3 (aLoc, aVec);
2194 return new Geom_CylindricalSurface(anAx3, theRadius);
2197 //=======================================================================
2198 //function : getShapesOnBoxIDs
2200 * \brief Find IDs of sub-shapes complying with given status about surface
2201 * \param theBox - the box to check state of sub-shapes against
2202 * \param theShape - the shape to explore
2203 * \param theShapeType - type of sub-shape of theShape
2204 * \param theState - required state
2205 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
2207 //=======================================================================
2208 Handle(TColStd_HSequenceOfInteger)
2209 GEOMImpl_IShapesOperations::getShapesOnBoxIDs(const Handle(GEOM_Object)& theBox,
2210 const Handle(GEOM_Object)& theShape,
2211 const Standard_Integer theShapeType,
2212 GEOMAlgo_State theState)
2214 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
2216 TopoDS_Shape aBox = theBox->GetValue();
2217 TopoDS_Shape aShape = theShape->GetValue();
2219 // Check presence of triangulation, build if need
2220 if (!CheckTriangulation(aShape)) {
2221 SetErrorCode("Cannot build triangulation on the shape");
2226 GEOMAlgo_FinderShapeOn2 aFinder;
2227 Standard_Real aTol = 0.0001; // default value
2229 Handle(GEOMAlgo_ClsfBox) aClsfBox = new GEOMAlgo_ClsfBox;
2230 aClsfBox->SetBox(aBox);
2232 aFinder.SetShape(aShape);
2233 aFinder.SetTolerance(aTol);
2234 aFinder.SetClsf(aClsfBox);
2235 aFinder.SetShapeType( (TopAbs_ShapeEnum)theShapeType );
2236 aFinder.SetState(theState);
2239 // Interprete results
2240 Standard_Integer iErr = aFinder.ErrorStatus();
2241 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
2243 MESSAGE(" iErr : " << iErr);
2244 TCollection_AsciiString aMsg (" iErr : ");
2245 aMsg += TCollection_AsciiString(iErr);
2249 Standard_Integer iWrn = aFinder.WarningStatus();
2250 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
2252 MESSAGE(" *** iWrn : " << iWrn);
2255 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
2257 if (listSS.Extent() < 1) {
2258 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
2259 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
2263 // Fill sequence of object IDs
2264 aSeqOfIDs = new TColStd_HSequenceOfInteger;
2266 TopTools_IndexedMapOfShape anIndices;
2267 TopExp::MapShapes(aShape, anIndices);
2269 TopTools_ListIteratorOfListOfShape itSub (listSS);
2270 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
2271 int id = anIndices.FindIndex(itSub.Value());
2272 aSeqOfIDs->Append(id);
2278 //=======================================================================
2279 //function : GetShapesOnBoxIDs
2281 * \brief Find sub-shapes complying with given status about surface
2282 * \param theBox - the box to check state of sub-shapes against
2283 * \param theShape - the shape to explore
2284 * \param theShapeType - type of sub-shape of theShape
2285 * \param theState - required state
2286 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
2288 //=======================================================================
2289 Handle(TColStd_HSequenceOfInteger)
2290 GEOMImpl_IShapesOperations::GetShapesOnBoxIDs(const Handle(GEOM_Object)& theBox,
2291 const Handle(GEOM_Object)& theShape,
2292 const Standard_Integer theShapeType,
2293 GEOMAlgo_State theState)
2295 // Find sub-shapes ids
2296 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2297 getShapesOnBoxIDs (theBox, theShape, theShapeType, theState);
2298 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2301 // The GetShapesOnBox() doesn't change object so no new function is required.
2302 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theBox)->GetLastFunction();
2304 // Make a Python command
2305 GEOM::TPythonDump(aFunction)
2306 << "listShapesOnBoxIDs = geompy.GetShapesOnBoxIDs("
2309 << TopAbs_ShapeEnum(theShapeType) << ", "
2316 //=======================================================================
2317 //function : GetShapesOnBox
2319 * \brief Find sub-shapes complying with given status about surface
2320 * \param theBox - the box to check state of sub-shapes against
2321 * \param theShape - the shape to explore
2322 * \param theShapeType - type of sub-shape of theShape
2323 * \param theState - required state
2324 * \retval Handle(TColStd_HSequenceOfTransient) - found sub-shapes
2326 //=======================================================================
2327 Handle(TColStd_HSequenceOfTransient)
2328 GEOMImpl_IShapesOperations::GetShapesOnBox(const Handle(GEOM_Object)& theBox,
2329 const Handle(GEOM_Object)& theShape,
2330 const Standard_Integer theShapeType,
2331 GEOMAlgo_State theState)
2333 // Find sub-shapes ids
2334 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2335 getShapesOnBoxIDs (theBox, theShape, theShapeType, theState);
2336 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2339 // Find objects by indices
2340 TCollection_AsciiString anAsciiList;
2341 Handle(TColStd_HSequenceOfTransient) aSeq;
2342 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
2343 if ( aSeq.IsNull() || aSeq->IsEmpty() )
2346 // Make a Python command
2348 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2349 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2351 GEOM::TPythonDump(aFunction)
2352 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnBox("
2355 << TopAbs_ShapeEnum(theShapeType) << ", "
2362 //=======================================================================
2363 //function : getShapesOnShapeIDs
2365 * \brief Find IDs of sub-shapes complying with given status about surface
2366 * \param theCheckShape - the shape to check state of sub-shapes against
2367 * \param theShape - the shape to explore
2368 * \param theShapeType - type of sub-shape of theShape
2369 * \param theState - required state
2370 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
2372 //=======================================================================
2373 Handle(TColStd_HSequenceOfInteger)
2374 GEOMImpl_IShapesOperations::getShapesOnShapeIDs
2375 (const Handle(GEOM_Object)& theCheckShape,
2376 const Handle(GEOM_Object)& theShape,
2377 const Standard_Integer theShapeType,
2378 GEOMAlgo_State theState)
2380 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
2382 TopoDS_Shape aCheckShape = theCheckShape->GetValue();
2383 TopoDS_Shape aShape = theShape->GetValue();
2384 TopTools_ListOfShape res;
2386 // Check presence of triangulation, build if need
2387 if (!CheckTriangulation(aShape)) {
2388 SetErrorCode("Cannot build triangulation on the shape");
2393 GEOMAlgo_FinderShapeOn2 aFinder;
2394 Standard_Real aTol = 0.0001; // default value
2396 Handle(GEOMAlgo_ClsfSolid) aClsfSolid = new GEOMAlgo_ClsfSolid;
2397 aClsfSolid->SetShape(aCheckShape);
2399 aFinder.SetShape(aShape);
2400 aFinder.SetTolerance(aTol);
2401 aFinder.SetClsf(aClsfSolid);
2402 aFinder.SetShapeType( (TopAbs_ShapeEnum)theShapeType );
2403 aFinder.SetState(theState);
2406 // Interprete results
2407 Standard_Integer iErr = aFinder.ErrorStatus();
2408 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
2411 SetErrorCode("theCheckShape must be a solid");
2414 MESSAGE(" iErr : " << iErr);
2415 TCollection_AsciiString aMsg (" iErr : ");
2416 aMsg += TCollection_AsciiString(iErr);
2421 Standard_Integer iWrn = aFinder.WarningStatus();
2422 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
2424 MESSAGE(" *** iWrn : " << iWrn);
2427 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
2429 if (listSS.Extent() < 1) {
2430 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
2431 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
2434 // Fill sequence of object IDs
2435 aSeqOfIDs = new TColStd_HSequenceOfInteger;
2437 TopTools_IndexedMapOfShape anIndices;
2438 TopExp::MapShapes(aShape, anIndices);
2440 TopTools_ListIteratorOfListOfShape itSub (listSS);
2441 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
2442 int id = anIndices.FindIndex(itSub.Value());
2443 aSeqOfIDs->Append(id);
2449 //=======================================================================
2450 //function : GetShapesOnShapeIDs
2452 * \brief Find sub-shapes complying with given status about surface
2453 * \param theCheckShape - the shape to check state of sub-shapes against
2454 * \param theShape - the shape to explore
2455 * \param theShapeType - type of sub-shape of theShape
2456 * \param theState - required state
2457 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
2459 //=======================================================================
2460 Handle(TColStd_HSequenceOfInteger)
2461 GEOMImpl_IShapesOperations::GetShapesOnShapeIDs
2462 (const Handle(GEOM_Object)& theCheckShape,
2463 const Handle(GEOM_Object)& theShape,
2464 const Standard_Integer theShapeType,
2465 GEOMAlgo_State theState)
2467 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2468 getShapesOnShapeIDs (theCheckShape, theShape, theShapeType, theState);
2470 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2473 // The GetShapesOnShape() doesn't change object so no new function is required.
2474 Handle(GEOM_Function) aFunction =
2475 GEOM::GetCreatedLast(theShape,theCheckShape)->GetLastFunction();
2477 // Make a Python command
2478 GEOM::TPythonDump(aFunction)
2479 << "listShapesOnBoxIDs = geompy.GetShapesOnShapeIDs("
2480 << theCheckShape << ", "
2482 << TopAbs_ShapeEnum(theShapeType) << ", "
2489 //=======================================================================
2490 //function : GetShapesOnShape
2492 * \brief Find sub-shapes complying with given status about surface
2493 * \param theCheckShape - the shape to check state of sub-shapes against
2494 * \param theShape - the shape to explore
2495 * \param theShapeType - type of sub-shape of theShape
2496 * \param theState - required state
2497 * \retval Handle(TColStd_HSequenceOfTransient) - found sub-shapes
2499 //=======================================================================
2500 Handle(TColStd_HSequenceOfTransient)
2501 GEOMImpl_IShapesOperations::GetShapesOnShape
2502 (const Handle(GEOM_Object)& theCheckShape,
2503 const Handle(GEOM_Object)& theShape,
2504 const Standard_Integer theShapeType,
2505 GEOMAlgo_State theState)
2507 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2508 getShapesOnShapeIDs (theCheckShape, theShape, theShapeType, theState);
2509 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2512 // Find objects by indices
2513 TCollection_AsciiString anAsciiList;
2514 Handle(TColStd_HSequenceOfTransient) aSeq;
2515 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
2517 if ( aSeq.IsNull() || aSeq->IsEmpty() )
2520 // Make a Python command
2522 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2523 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2525 GEOM::TPythonDump(aFunction)
2526 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnShape("
2527 << theCheckShape << ", "
2529 << TopAbs_ShapeEnum(theShapeType) << ", "
2536 //=======================================================================
2537 //function : GetShapesOnShapeAsCompound
2538 //=======================================================================
2539 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetShapesOnShapeAsCompound
2540 (const Handle(GEOM_Object)& theCheckShape,
2541 const Handle(GEOM_Object)& theShape,
2542 const Standard_Integer theShapeType,
2543 GEOMAlgo_State theState)
2545 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2546 getShapesOnShapeIDs (theCheckShape, theShape, theShapeType, theState);
2548 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2551 // Find objects by indices
2552 TCollection_AsciiString anAsciiList;
2553 Handle(TColStd_HSequenceOfTransient) aSeq;
2554 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
2556 if ( aSeq.IsNull() || aSeq->IsEmpty() )
2559 TopoDS_Compound aCompound;
2561 B.MakeCompound(aCompound);
2563 for(; i<=aSeq->Length(); i++) {
2564 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(aSeq->Value(i));
2565 TopoDS_Shape aShape_i = anObj->GetValue();
2566 B.Add(aCompound,aShape_i);
2569 //Add a new result object
2570 Handle(GEOM_Object) aRes = GetEngine()->AddObject(GetDocID(), GEOM_SHAPES_ON_SHAPE);
2571 Handle(GEOM_Function) aFunction =
2572 aRes->AddFunction(GEOMImpl_ShapeDriver::GetID(), SHAPES_ON_SHAPE);
2573 aFunction->SetValue(aCompound);
2575 GEOM::TPythonDump(aFunction)
2576 << aRes << " = geompy.GetShapesOnShapeAsCompound("
2577 << theCheckShape << ", "
2579 << TopAbs_ShapeEnum(theShapeType) << ", "
2587 //=======================================================================
2588 //function : getShapesOnSurfaceIDs
2590 * \brief Find IDs of sub-shapes complying with given status about surface
2591 * \param theSurface - the surface to check state of sub-shapes against
2592 * \param theShape - the shape to explore
2593 * \param theShapeType - type of sub-shape of theShape
2594 * \param theState - required state
2595 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
2597 //=======================================================================
2598 Handle(TColStd_HSequenceOfInteger)
2599 GEOMImpl_IShapesOperations::getShapesOnSurfaceIDs(const Handle(Geom_Surface)& theSurface,
2600 const TopoDS_Shape& theShape,
2601 TopAbs_ShapeEnum theShapeType,
2602 GEOMAlgo_State theState)
2604 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
2606 // Check presence of triangulation, build if need
2607 if (!CheckTriangulation(theShape)) {
2608 SetErrorCode("Cannot build triangulation on the shape");
2612 // BEGIN: Mantis issue 0020961: Error on a pipe T-Shape
2613 // Compute tolerance
2614 Standard_Real T, VertMax = -RealLast();
2616 #if OCC_VERSION_LARGE > 0x06010000
2619 for (TopExp_Explorer ExV (theShape, TopAbs_VERTEX); ExV.More(); ExV.Next()) {
2620 TopoDS_Vertex Vertex = TopoDS::Vertex(ExV.Current());
2621 T = BRep_Tool::Tolerance(Vertex);
2626 catch (Standard_Failure) {
2627 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2628 SetErrorCode(aFail->GetMessageString());
2631 // END: Mantis issue 0020961
2634 GEOMAlgo_FinderShapeOn1 aFinder;
2635 //Standard_Real aTol = 0.0001; // default value
2636 Standard_Real aTol = VertMax; // Mantis issue 0020961
2638 aFinder.SetShape(theShape);
2639 aFinder.SetTolerance(aTol);
2640 aFinder.SetSurface(theSurface);
2641 aFinder.SetShapeType(theShapeType);
2642 aFinder.SetState(theState);
2644 // Sets the minimal number of inner points for the faces that do not have own
2645 // inner points at all (for e.g. rectangular planar faces have just 2 triangles).
2647 aFinder.SetNbPntsMin(3);
2648 // Sets the maximal number of inner points for edges or faces.
2649 // It is usefull for the cases when this number is very big (e.g =2000) to improve
2650 // the performance. If this value =0, all inner points will be taken into account.
2652 aFinder.SetNbPntsMax(100);
2656 // Interprete results
2657 Standard_Integer iErr = aFinder.ErrorStatus();
2658 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
2660 MESSAGE(" iErr : " << iErr);
2661 TCollection_AsciiString aMsg (" iErr : ");
2662 aMsg += TCollection_AsciiString(iErr);
2666 Standard_Integer iWrn = aFinder.WarningStatus();
2667 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
2669 MESSAGE(" *** iWrn : " << iWrn);
2672 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
2674 if (listSS.Extent() < 1) {
2675 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
2676 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
2680 // Fill sequence of object IDs
2681 aSeqOfIDs = new TColStd_HSequenceOfInteger;
2683 TopTools_IndexedMapOfShape anIndices;
2684 TopExp::MapShapes(theShape, anIndices);
2686 TopTools_ListIteratorOfListOfShape itSub (listSS);
2687 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
2688 int id = anIndices.FindIndex(itSub.Value());
2689 aSeqOfIDs->Append(id);
2695 //=======================================================================
2696 //function : getObjectsShapesOn
2698 * \brief Find shape objects and their entries by their ids
2699 * \param theShapeIDs - incoming shape ids
2700 * \param theShapeEntries - outgoing entries like "entry1, entry2, ..."
2701 * \retval Handle(TColStd_HSequenceOfTransient) - found shape objects
2703 //=======================================================================
2704 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::
2705 getObjectsShapesOn(const Handle(GEOM_Object)& theShape,
2706 const Handle(TColStd_HSequenceOfInteger)& theShapeIDs,
2707 TCollection_AsciiString & theShapeEntries)
2709 Handle(TColStd_HSequenceOfTransient) aSeq;
2711 if ( !theShapeIDs.IsNull() && theShapeIDs->Length() > 0 )
2713 aSeq = new TColStd_HSequenceOfTransient;
2714 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
2715 TCollection_AsciiString anEntry;
2716 for ( int i = 1; i <= theShapeIDs->Length(); ++i )
2718 anArray->SetValue(1, theShapeIDs->Value( i ));
2719 Handle(GEOM_Object) anObj = GetEngine()->AddSubShape(theShape, anArray);
2720 aSeq->Append( anObj );
2722 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
2723 if ( i != 1 ) theShapeEntries += ",";
2724 theShapeEntries += anEntry;
2730 //=======================================================================
2731 //function : getShapesOnSurface
2733 * \brief Find sub-shapes complying with given status about surface
2734 * \param theSurface - the surface to check state of sub-shapes against
2735 * \param theShape - the shape to explore
2736 * \param theShapeType - type of sub-shape of theShape
2737 * \param theState - required state
2738 * \param theShapeEntries - outgoing entries like "entry1, entry2, ..."
2739 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
2741 //=======================================================================
2742 Handle(TColStd_HSequenceOfTransient)
2743 GEOMImpl_IShapesOperations::getShapesOnSurface(const Handle(Geom_Surface)& theSurface,
2744 const Handle(GEOM_Object)& theShape,
2745 TopAbs_ShapeEnum theShapeType,
2746 GEOMAlgo_State theState,
2747 TCollection_AsciiString & theShapeEntries)
2749 // Find sub-shapes ids
2750 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2751 getShapesOnSurfaceIDs (theSurface, theShape->GetValue(), theShapeType, theState);
2752 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2755 return getObjectsShapesOn( theShape, aSeqOfIDs, theShapeEntries );
2758 //=============================================================================
2762 //=============================================================================
2763 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnPlane
2764 (const Handle(GEOM_Object)& theShape,
2765 const Standard_Integer theShapeType,
2766 const Handle(GEOM_Object)& theAx1,
2767 const GEOMAlgo_State theState)
2771 if (theShape.IsNull() || theAx1.IsNull()) return NULL;
2773 TopoDS_Shape aShape = theShape->GetValue();
2774 TopoDS_Shape anAx1 = theAx1->GetValue();
2776 if (aShape.IsNull() || anAx1.IsNull()) return NULL;
2778 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2779 if ( !checkTypeShapesOn( theShapeType ))
2783 Handle(Geom_Surface) aPlane = makePlane( anAx1 );
2784 if ( aPlane.IsNull() )
2788 TCollection_AsciiString anAsciiList;
2789 Handle(TColStd_HSequenceOfTransient) aSeq;
2790 aSeq = getShapesOnSurface( aPlane, theShape, aShapeType, theState, anAsciiList );
2791 if ( aSeq.IsNull() || aSeq->Length() == 0 )
2794 // Make a Python command
2796 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2797 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2799 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
2800 << "] = geompy.GetShapesOnPlane(" << theShape << ", "
2801 << aShapeType << ", " << theAx1 << ", " << theState << ")";
2807 //=============================================================================
2809 * GetShapesOnPlaneWithLocation
2811 //=============================================================================
2812 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnPlaneWithLocation
2813 (const Handle(GEOM_Object)& theShape,
2814 const Standard_Integer theShapeType,
2815 const Handle(GEOM_Object)& theAx1,
2816 const Handle(GEOM_Object)& thePnt,
2817 const GEOMAlgo_State theState)
2821 if (theShape.IsNull() || theAx1.IsNull() || thePnt.IsNull()) return NULL;
2823 TopoDS_Shape aShape = theShape->GetValue();
2824 TopoDS_Shape anAx1 = theAx1->GetValue();
2825 TopoDS_Shape anPnt = thePnt->GetValue();
2827 if (aShape.IsNull() || anAx1.IsNull() || anPnt.IsNull()) return NULL;
2829 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2830 if ( !checkTypeShapesOn( theShapeType ))
2834 if ( anAx1.ShapeType() != TopAbs_EDGE || anPnt.ShapeType() != TopAbs_VERTEX ) return NULL;
2835 TopoDS_Vertex V1, V2, V3;
2836 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
2837 TopExp::Vertices(anEdge, V1, V2, Standard_True);
2839 if (V1.IsNull() || V2.IsNull()) {
2840 SetErrorCode("Bad edge given for the plane normal vector");
2843 V3 = TopoDS::Vertex(anPnt);
2846 SetErrorCode("Bad vertex given for the plane location");
2849 gp_Pnt aLoc = BRep_Tool::Pnt(V3);
2850 gp_Vec aVec(BRep_Tool::Pnt(V1),BRep_Tool::Pnt(V2));
2852 if (aVec.Magnitude() < Precision::Confusion()) {
2853 SetErrorCode("Vector with null magnitude given");
2856 Handle(Geom_Surface) aPlane = new Geom_Plane(aLoc, aVec);
2858 if ( aPlane.IsNull() )
2862 TCollection_AsciiString anAsciiList;
2863 Handle(TColStd_HSequenceOfTransient) aSeq;
2864 aSeq = getShapesOnSurface( aPlane, theShape, aShapeType, theState, anAsciiList );
2865 if ( aSeq.IsNull() || aSeq->Length() == 0 )
2868 // Make a Python command
2870 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2871 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2873 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
2874 << "] = geompy.GetShapesOnPlaneWithLocation(" << theShape << ", "
2875 << aShapeType << ", " << theAx1 << ", "<< thePnt <<", " << theState << ")";
2881 //=============================================================================
2883 * GetShapesOnCylinder
2885 //=============================================================================
2886 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnCylinder
2887 (const Handle(GEOM_Object)& theShape,
2888 const Standard_Integer theShapeType,
2889 const Handle(GEOM_Object)& theAxis,
2890 const Standard_Real theRadius,
2891 const GEOMAlgo_State theState)
2895 if (theShape.IsNull() || theAxis.IsNull()) return NULL;
2897 TopoDS_Shape aShape = theShape->GetValue();
2898 TopoDS_Shape anAxis = theAxis->GetValue();
2900 if (aShape.IsNull() || anAxis.IsNull()) return NULL;
2902 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2903 if ( !checkTypeShapesOn( aShapeType ))
2906 // Create a cylinder surface
2907 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
2908 if ( aCylinder.IsNull() )
2912 TCollection_AsciiString anAsciiList;
2913 Handle(TColStd_HSequenceOfTransient) aSeq;
2914 aSeq = getShapesOnSurface( aCylinder, theShape, aShapeType, theState, anAsciiList );
2915 if ( aSeq.IsNull() || aSeq->Length() == 0 )
2918 // Make a Python command
2920 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2921 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2923 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
2924 << "] = geompy.GetShapesOnCylinder(" << theShape << ", " << aShapeType
2925 << ", " << theAxis << ", " << theRadius << ", " << theState << ")";
2931 //=============================================================================
2933 * GetShapesOnCylinderWithLocation
2935 //=============================================================================
2936 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnCylinderWithLocation
2937 (const Handle(GEOM_Object)& theShape,
2938 const Standard_Integer theShapeType,
2939 const Handle(GEOM_Object)& theAxis,
2940 const Handle(GEOM_Object)& thePnt,
2941 const Standard_Real theRadius,
2942 const GEOMAlgo_State theState)
2946 if (theShape.IsNull() || theAxis.IsNull() || thePnt.IsNull()) return NULL;
2948 TopoDS_Shape aShape = theShape->GetValue();
2949 TopoDS_Shape anAxis = theAxis->GetValue();
2950 TopoDS_Shape aPnt = thePnt->GetValue();
2952 if (aShape.IsNull() || anAxis.IsNull() || aPnt.IsNull()) return NULL;
2954 if (aPnt.ShapeType() != TopAbs_VERTEX )
2956 SetErrorCode("Bottom location point must be vertex");
2960 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2961 if ( !checkTypeShapesOn( aShapeType ))
2964 // Create a cylinder surface
2965 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
2966 if ( aCylinder.IsNull() )
2969 // translate the surface
2970 Handle(Geom_CylindricalSurface) aCylSurface =
2971 Handle(Geom_CylindricalSurface)::DownCast( aCylinder );
2972 if ( aCylSurface.IsNull() )
2974 SetErrorCode("Unexpected surface type instead of Geom_CylindricalSurface");
2977 gp_Pnt fromLoc = aCylSurface->Cylinder().Location();
2978 gp_Pnt toLoc = BRep_Tool::Pnt( TopoDS::Vertex( aPnt ));
2979 aCylinder->Translate( fromLoc, toLoc );
2982 TCollection_AsciiString anAsciiList;
2983 Handle(TColStd_HSequenceOfTransient) aSeq;
2984 aSeq = getShapesOnSurface( aCylinder, theShape, aShapeType, theState, anAsciiList );
2985 if ( aSeq.IsNull() || aSeq->Length() == 0 )
2988 // Make a Python command
2990 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2991 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2993 GEOM::TPythonDump(aFunction)
2994 << "[" << anAsciiList.ToCString()
2995 << "] = geompy.GetShapesOnCylinderWithLocation(" << theShape << ", " << aShapeType << ", "
2996 << theAxis << ", " << thePnt << ", " << theRadius << ", " << theState << ")";
3002 //=============================================================================
3006 //=============================================================================
3007 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnSphere
3008 (const Handle(GEOM_Object)& theShape,
3009 const Standard_Integer theShapeType,
3010 const Handle(GEOM_Object)& theCenter,
3011 const Standard_Real theRadius,
3012 const GEOMAlgo_State theState)
3016 if (theShape.IsNull() || theCenter.IsNull()) return NULL;
3018 TopoDS_Shape aShape = theShape->GetValue();
3019 TopoDS_Shape aCenter = theCenter->GetValue();
3021 if (aShape.IsNull() || aCenter.IsNull()) return NULL;
3023 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3024 if ( !checkTypeShapesOn( aShapeType ))
3027 // Center of the sphere
3028 if (aCenter.ShapeType() != TopAbs_VERTEX) return NULL;
3029 gp_Pnt aLoc = BRep_Tool::Pnt(TopoDS::Vertex(aCenter));
3031 gp_Ax3 anAx3 (aLoc, gp::DZ());
3032 Handle(Geom_SphericalSurface) aSphere =
3033 new Geom_SphericalSurface(anAx3, theRadius);
3036 TCollection_AsciiString anAsciiList;
3037 Handle(TColStd_HSequenceOfTransient) aSeq;
3038 aSeq = getShapesOnSurface( aSphere, theShape, aShapeType, theState, anAsciiList );
3039 if ( aSeq.IsNull() || aSeq->Length() == 0 )
3042 // Make a Python command
3044 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
3045 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
3047 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
3048 << "] = geompy.GetShapesOnSphere(" << theShape << ", " << aShapeType
3049 << ", " << theCenter << ", " << theRadius << ", " << theState << ")";
3055 //=============================================================================
3057 * GetShapesOnPlaneIDs
3059 //=============================================================================
3060 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnPlaneIDs
3061 (const Handle(GEOM_Object)& theShape,
3062 const Standard_Integer theShapeType,
3063 const Handle(GEOM_Object)& theAx1,
3064 const GEOMAlgo_State theState)
3068 if (theShape.IsNull() || theAx1.IsNull()) return NULL;
3070 TopoDS_Shape aShape = theShape->GetValue();
3071 TopoDS_Shape anAx1 = theAx1->GetValue();
3073 if (aShape.IsNull() || anAx1.IsNull()) return NULL;
3075 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3076 if ( !checkTypeShapesOn( aShapeType ))
3080 Handle(Geom_Surface) aPlane = makePlane( anAx1 );
3081 if ( aPlane.IsNull() )
3085 Handle(TColStd_HSequenceOfInteger) aSeq;
3086 aSeq = getShapesOnSurfaceIDs( aPlane, aShape, aShapeType, theState );
3088 // The GetShapesOnPlaneIDs() doesn't change object so no new function is required.
3089 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAx1)->GetLastFunction();
3091 // Make a Python command
3092 GEOM::TPythonDump(aFunction, /*append=*/true)
3093 << "listShapesOnPlane = geompy.GetShapesOnPlaneIDs"
3094 << "(" << theShape << "," << aShapeType << "," << theAx1 << "," << theState << ")";
3100 //=============================================================================
3102 * GetShapesOnPlaneWithLocationIDs
3104 //=============================================================================
3105 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnPlaneWithLocationIDs
3106 (const Handle(GEOM_Object)& theShape,
3107 const Standard_Integer theShapeType,
3108 const Handle(GEOM_Object)& theAx1,
3109 const Handle(GEOM_Object)& thePnt,
3110 const GEOMAlgo_State theState)
3114 if (theShape.IsNull() || theAx1.IsNull() || thePnt.IsNull()) return NULL;
3116 TopoDS_Shape aShape = theShape->GetValue();
3117 TopoDS_Shape anAx1 = theAx1->GetValue();
3118 TopoDS_Shape anPnt = thePnt->GetValue();
3120 if (aShape.IsNull() || anAx1.IsNull() || anPnt.IsNull()) return NULL;
3122 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3123 if ( !checkTypeShapesOn( aShapeType ))
3127 if (anAx1.ShapeType() != TopAbs_EDGE || anPnt.ShapeType() != TopAbs_VERTEX) return NULL;
3128 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
3129 TopoDS_Vertex V1, V2, V3;
3130 TopExp::Vertices(anEdge, V1, V2, Standard_True);
3131 if (V1.IsNull() || V2.IsNull()) {
3132 SetErrorCode("Bad edge given for the plane normal vector");
3135 V3 = TopoDS::Vertex(anPnt);
3137 SetErrorCode("Bad vertex given for the plane location");
3140 gp_Pnt aLoc = BRep_Tool::Pnt(V3);
3141 gp_Vec aVec(BRep_Tool::Pnt(V1),BRep_Tool::Pnt(V2));
3142 if (aVec.Magnitude() < Precision::Confusion()) {
3143 SetErrorCode("Vector with null magnitude given");
3147 Handle(Geom_Surface) aPlane = new Geom_Plane(aLoc, aVec);
3148 if ( aPlane.IsNull() )
3152 Handle(TColStd_HSequenceOfInteger) aSeq;
3153 aSeq = getShapesOnSurfaceIDs( aPlane, aShape, aShapeType, theState );
3155 // The GetShapesOnPlaneIDs() doesn't change object so no new function is required.
3156 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAx1)->GetLastFunction();
3158 // Make a Python command
3159 GEOM::TPythonDump(aFunction, /*append=*/true)
3160 << "listShapesOnPlane = geompy.GetShapesOnPlaneWithLocationIDs"
3161 << "(" << theShape << ", " << aShapeType << ", " << theAx1 << ", "<< thePnt << ", " << theState << ")";
3167 //=============================================================================
3169 * GetShapesOnCylinderIDs
3171 //=============================================================================
3172 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnCylinderIDs
3173 (const Handle(GEOM_Object)& theShape,
3174 const Standard_Integer theShapeType,
3175 const Handle(GEOM_Object)& theAxis,
3176 const Standard_Real theRadius,
3177 const GEOMAlgo_State theState)
3181 if (theShape.IsNull() || theAxis.IsNull()) return NULL;
3183 TopoDS_Shape aShape = theShape->GetValue();
3184 TopoDS_Shape anAxis = theAxis->GetValue();
3186 if (aShape.IsNull() || anAxis.IsNull()) return NULL;
3188 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3189 if ( !checkTypeShapesOn( aShapeType ))
3192 // Create a cylinder surface
3193 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
3194 if ( aCylinder.IsNull() )
3198 Handle(TColStd_HSequenceOfInteger) aSeq;
3199 aSeq = getShapesOnSurfaceIDs( aCylinder, aShape, aShapeType, theState );
3201 // The GetShapesOnCylinder() doesn't change object so no new function is required.
3202 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAxis)->GetLastFunction();
3204 // Make a Python command
3205 GEOM::TPythonDump(aFunction, /*append=*/true)
3206 << "listShapesOnCylinder = geompy.GetShapesOnCylinderIDs"
3207 << "(" << theShape << ", " << aShapeType << ", " << theAxis << ", "
3208 << theRadius << ", " << theState << ")";
3214 //=============================================================================
3216 * GetShapesOnCylinderWithLocationIDs
3218 //=============================================================================
3219 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnCylinderWithLocationIDs
3220 (const Handle(GEOM_Object)& theShape,
3221 const Standard_Integer theShapeType,
3222 const Handle(GEOM_Object)& theAxis,
3223 const Handle(GEOM_Object)& thePnt,
3224 const Standard_Real theRadius,
3225 const GEOMAlgo_State theState)
3229 if (theShape.IsNull() || theAxis.IsNull() || thePnt.IsNull()) return NULL;
3231 TopoDS_Shape aShape = theShape->GetValue();
3232 TopoDS_Shape anAxis = theAxis->GetValue();
3233 TopoDS_Shape aPnt = thePnt->GetValue();
3235 if (aShape.IsNull() || anAxis.IsNull() || aPnt.IsNull()) return NULL;
3237 if (aPnt.ShapeType() != TopAbs_VERTEX )
3239 SetErrorCode("Bottom location point must be vertex");
3243 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3244 if ( !checkTypeShapesOn( aShapeType ))
3247 // Create a cylinder surface
3248 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
3249 if ( aCylinder.IsNull() )
3252 // translate the surface
3253 Handle(Geom_CylindricalSurface) aCylSurface =
3254 Handle(Geom_CylindricalSurface)::DownCast( aCylinder );
3255 if ( aCylSurface.IsNull() )
3257 SetErrorCode("Unexpected surface type instead of Geom_CylindricalSurface");
3260 gp_Pnt fromLoc = aCylSurface->Cylinder().Location();
3261 gp_Pnt toLoc = BRep_Tool::Pnt( TopoDS::Vertex( aPnt ));
3262 aCylinder->Translate( fromLoc, toLoc );
3265 Handle(TColStd_HSequenceOfInteger) aSeq;
3266 aSeq = getShapesOnSurfaceIDs( aCylinder, aShape, aShapeType, theState );
3268 // The GetShapesOnCylinder() doesn't change object so no new function is required.
3269 Handle(GEOM_Function) aFunction =
3270 GEOM::GetCreatedLast(theShape, GEOM::GetCreatedLast(thePnt,theAxis))->GetLastFunction();
3272 // Make a Python command
3273 GEOM::TPythonDump(aFunction, /*append=*/true)
3274 << "listShapesOnCylinder = geompy.GetShapesOnCylinderWithLocationIDs"
3275 << "(" << theShape << ", " << aShapeType << ", " << theAxis << ", "
3276 << thePnt << ", " << theRadius << ", " << theState << ")";
3282 //=============================================================================
3284 * GetShapesOnSphereIDs
3286 //=============================================================================
3287 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnSphereIDs
3288 (const Handle(GEOM_Object)& theShape,
3289 const Standard_Integer theShapeType,
3290 const Handle(GEOM_Object)& theCenter,
3291 const Standard_Real theRadius,
3292 const GEOMAlgo_State theState)
3296 if (theShape.IsNull() || theCenter.IsNull()) return NULL;
3298 TopoDS_Shape aShape = theShape->GetValue();
3299 TopoDS_Shape aCenter = theCenter->GetValue();
3301 if (aShape.IsNull() || aCenter.IsNull()) return NULL;
3303 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3304 if ( !checkTypeShapesOn( aShapeType ))
3307 // Center of the sphere
3308 if (aCenter.ShapeType() != TopAbs_VERTEX) return NULL;
3309 gp_Pnt aLoc = BRep_Tool::Pnt(TopoDS::Vertex(aCenter));
3311 gp_Ax3 anAx3 (aLoc, gp::DZ());
3312 Handle(Geom_SphericalSurface) aSphere =
3313 new Geom_SphericalSurface(anAx3, theRadius);
3316 Handle(TColStd_HSequenceOfInteger) aSeq;
3317 aSeq = getShapesOnSurfaceIDs( aSphere, aShape, aShapeType, theState );
3319 // The GetShapesOnSphere() doesn't change object so no new function is required.
3320 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theCenter)->GetLastFunction();
3322 // Make a Python command
3323 GEOM::TPythonDump(aFunction, /*append=*/true)
3324 << "listShapesOnCylinder = geompy.GetShapesOnCylinderIDs"
3325 << "(" << theShape << ", " << aShapeType << ", " << theCenter << ", "
3326 << theRadius << ", " << theState << ")";
3332 //=======================================================================
3333 //function : getShapesOnQuadrangleIDs
3335 * \brief Find IDs of sub-shapes complying with given status about quadrangle
3336 * \param theShape - the shape to explore
3337 * \param theShapeType - type of sub-shape of theShape
3338 * \param theTopLeftPoint - top left quadrangle corner
3339 * \param theTopRigthPoint - top right quadrangle corner
3340 * \param theBottomLeftPoint - bottom left quadrangle corner
3341 * \param theBottomRigthPoint - bottom right quadrangle corner
3342 * \param theState - required state
3343 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
3345 //=======================================================================
3346 Handle(TColStd_HSequenceOfInteger)
3347 GEOMImpl_IShapesOperations::getShapesOnQuadrangleIDs (const Handle(GEOM_Object)& theShape,
3348 const Standard_Integer theShapeType,
3349 const Handle(GEOM_Object)& theTopLeftPoint,
3350 const Handle(GEOM_Object)& theTopRigthPoint,
3351 const Handle(GEOM_Object)& theBottomLeftPoint,
3352 const Handle(GEOM_Object)& theBottomRigthPoint,
3353 const GEOMAlgo_State theState)
3357 if ( theShape.IsNull() ||
3358 theTopLeftPoint.IsNull() ||
3359 theTopRigthPoint.IsNull() ||
3360 theBottomLeftPoint.IsNull() ||
3361 theBottomRigthPoint.IsNull() )
3364 TopoDS_Shape aShape = theShape->GetValue();
3365 TopoDS_Shape aTL = theTopLeftPoint->GetValue();
3366 TopoDS_Shape aTR = theTopRigthPoint->GetValue();
3367 TopoDS_Shape aBL = theBottomLeftPoint->GetValue();
3368 TopoDS_Shape aBR = theBottomRigthPoint->GetValue();
3370 if (aShape.IsNull() ||
3375 aTL.ShapeType() != TopAbs_VERTEX ||
3376 aTR.ShapeType() != TopAbs_VERTEX ||
3377 aBL.ShapeType() != TopAbs_VERTEX ||
3378 aBR.ShapeType() != TopAbs_VERTEX )
3381 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3382 if ( !checkTypeShapesOn( aShapeType ))
3385 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
3387 // Check presence of triangulation, build if need
3388 if (!CheckTriangulation(aShape)) {
3389 SetErrorCode("Cannot build triangulation on the shape");
3394 gp_Pnt aPntTL = BRep_Tool::Pnt(TopoDS::Vertex(aTL));
3395 gp_Pnt aPntTR = BRep_Tool::Pnt(TopoDS::Vertex(aTR));
3396 gp_Pnt aPntBL = BRep_Tool::Pnt(TopoDS::Vertex(aBL));
3397 gp_Pnt aPntBR = BRep_Tool::Pnt(TopoDS::Vertex(aBR));
3399 GEOMAlgo_FinderShapeOnQuad aFinder( aPntTL, aPntTR, aPntBL, aPntBR );
3400 Standard_Real aTol = 0.0001; // default value
3402 aFinder.SetShape(aShape);
3403 aFinder.SetTolerance(aTol);
3404 //aFinder.SetSurface(theSurface);
3405 aFinder.SetShapeType(aShapeType);
3406 aFinder.SetState(theState);
3408 // Sets the minimal number of inner points for the faces that do not have own
3409 // inner points at all (for e.g. rectangular planar faces have just 2 triangles).
3411 aFinder.SetNbPntsMin(3);
3412 // Sets the maximal number of inner points for edges or faces.
3413 // It is usefull for the cases when this number is very big (e.g =2000) to improve
3414 // the performance. If this value =0, all inner points will be taken into account.
3416 aFinder.SetNbPntsMax(100);
3420 // Interprete results
3421 Standard_Integer iErr = aFinder.ErrorStatus();
3422 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
3424 MESSAGE(" iErr : " << iErr);
3425 TCollection_AsciiString aMsg (" iErr : ");
3426 aMsg += TCollection_AsciiString(iErr);
3430 Standard_Integer iWrn = aFinder.WarningStatus();
3431 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
3433 MESSAGE(" *** iWrn : " << iWrn);
3436 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
3438 if (listSS.Extent() < 1) {
3439 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
3440 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
3444 // Fill sequence of object IDs
3445 aSeqOfIDs = new TColStd_HSequenceOfInteger;
3447 TopTools_IndexedMapOfShape anIndices;
3448 TopExp::MapShapes(aShape, anIndices);
3450 TopTools_ListIteratorOfListOfShape itSub (listSS);
3451 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
3452 int id = anIndices.FindIndex(itSub.Value());
3453 aSeqOfIDs->Append(id);
3458 //=======================================================================
3459 //function : GetShapesOnQuadrangle
3461 * \brief Find sub-shapes complying with given status about quadrangle
3462 * \param theShape - the shape to explore
3463 * \param theShapeType - type of sub-shape of theShape
3464 * \param theTopLeftPoint - top left quadrangle corner
3465 * \param theTopRigthPoint - top right quadrangle corner
3466 * \param theBottomLeftPoint - bottom left quadrangle corner
3467 * \param theBottomRigthPoint - bottom right quadrangle corner
3468 * \param theState - required state
3469 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
3471 //=======================================================================
3472 Handle(TColStd_HSequenceOfTransient)
3473 GEOMImpl_IShapesOperations::GetShapesOnQuadrangle (const Handle(GEOM_Object)& theShape,
3474 const Standard_Integer theShapeType,
3475 const Handle(GEOM_Object)& theTopLeftPoint,
3476 const Handle(GEOM_Object)& theTopRigthPoint,
3477 const Handle(GEOM_Object)& theBottomLeftPoint,
3478 const Handle(GEOM_Object)& theBottomRigthPoint,
3479 const GEOMAlgo_State theState)
3482 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
3483 getShapesOnQuadrangleIDs( theShape,
3488 theBottomRigthPoint,
3490 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->IsEmpty() )
3493 // Find objects by indices
3494 TCollection_AsciiString anAsciiList;
3495 Handle(TColStd_HSequenceOfTransient) aSeq;
3496 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
3497 if ( aSeq.IsNull() || aSeq->IsEmpty() )
3500 // Make a Python command
3502 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
3503 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
3505 GEOM::TPythonDump(aFunction)
3506 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnQuadrangle("
3508 << TopAbs_ShapeEnum(theShapeType) << ", "
3509 << theTopLeftPoint << ", "
3510 << theTopRigthPoint << ", "
3511 << theBottomLeftPoint << ", "
3512 << theBottomRigthPoint << ", "
3519 //=======================================================================
3520 //function : GetShapesOnQuadrangleIDs
3522 * \brief Find IDs of sub-shapes complying with given status about quadrangle
3523 * \param theShape - the shape to explore
3524 * \param theShapeType - type of sub-shape of theShape
3525 * \param theTopLeftPoint - top left quadrangle corner
3526 * \param theTopRigthPoint - top right quadrangle corner
3527 * \param theBottomLeftPoint - bottom left quadrangle corner
3528 * \param theBottomRigthPoint - bottom right quadrangle corner
3529 * \param theState - required state
3530 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
3532 //=======================================================================
3533 Handle(TColStd_HSequenceOfInteger)
3534 GEOMImpl_IShapesOperations::GetShapesOnQuadrangleIDs (const Handle(GEOM_Object)& theShape,
3535 const Standard_Integer theShapeType,
3536 const Handle(GEOM_Object)& theTopLeftPoint,
3537 const Handle(GEOM_Object)& theTopRigthPoint,
3538 const Handle(GEOM_Object)& theBottomLeftPoint,
3539 const Handle(GEOM_Object)& theBottomRigthPoint,
3540 const GEOMAlgo_State theState)
3543 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
3544 getShapesOnQuadrangleIDs( theShape,
3549 theBottomRigthPoint,
3551 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->IsEmpty() )
3554 // Make a Python command
3556 // The GetShapesOnCylinder() doesn't change object so no new function is required.
3557 Handle(GEOM_Object) lastObj = GEOM::GetCreatedLast(theShape,theTopLeftPoint);
3558 lastObj = GEOM::GetCreatedLast(lastObj,theTopRigthPoint);
3559 lastObj = GEOM::GetCreatedLast(lastObj,theBottomRigthPoint);
3560 lastObj = GEOM::GetCreatedLast(lastObj,theBottomLeftPoint);
3561 Handle(GEOM_Function) aFunction = lastObj->GetLastFunction();
3563 GEOM::TPythonDump(aFunction, /*append=*/true)
3564 << "listShapesOnQuadrangle = geompy.GetShapesOnQuadrangleIDs("
3566 << TopAbs_ShapeEnum(theShapeType) << ", "
3567 << theTopLeftPoint << ", "
3568 << theTopRigthPoint << ", "
3569 << theBottomLeftPoint << ", "
3570 << theBottomRigthPoint << ", "
3577 //=============================================================================
3581 //=============================================================================
3582 static bool GetInPlaceOfShape (const Handle(GEOM_Function)& theWhereFunction,
3583 const TopTools_IndexedMapOfShape& theWhereIndices,
3584 const TopoDS_Shape& theWhat,
3585 TColStd_ListOfInteger& theModifiedList)
3587 if (theWhereFunction.IsNull() || theWhat.IsNull()) return false;
3589 if (theWhereIndices.Contains(theWhat)) {
3590 // entity was not changed by the operation
3591 Standard_Integer aWhatIndex = theWhereIndices.FindIndex(theWhat);
3592 theModifiedList.Append(aWhatIndex);
3596 // try to find in history
3597 TDF_Label aHistoryLabel = theWhereFunction->GetHistoryEntry(Standard_False);
3599 // search in history for all argument shapes
3600 Standard_Boolean isFound = Standard_False;
3601 Standard_Boolean isGood = Standard_False;
3603 TDF_LabelSequence aLabelSeq;
3604 theWhereFunction->GetDependency(aLabelSeq);
3605 Standard_Integer nbArg = aLabelSeq.Length();
3607 for (Standard_Integer iarg = 1; iarg <= nbArg && !isFound; iarg++) {
3609 TDF_Label anArgumentRefLabel = aLabelSeq.Value(iarg);
3611 Handle(GEOM_Object) anArgumentObject = GEOM_Object::GetReferencedObject(anArgumentRefLabel);
3612 TopoDS_Shape anArgumentShape = anArgumentObject->GetValue();
3614 TopTools_IndexedMapOfShape anArgumentIndices;
3615 TopExp::MapShapes(anArgumentShape, anArgumentIndices);
3617 if (anArgumentIndices.Contains(theWhat)) {
3618 isFound = Standard_True;
3619 Standard_Integer aWhatIndex = anArgumentIndices.FindIndex(theWhat);
3621 // Find corresponding label in history
3622 TDF_Label anArgumentHistoryLabel =
3623 theWhereFunction->GetArgumentHistoryEntry(anArgumentRefLabel, Standard_False);
3624 if (anArgumentHistoryLabel.IsNull()) {
3625 // Lost History of operation argument. Possibly, all its entities was removed.
3626 isGood = Standard_True;
3629 TDF_Label aWhatHistoryLabel = anArgumentHistoryLabel.FindChild(aWhatIndex, Standard_False);
3631 if (aWhatHistoryLabel.IsNull()) {
3632 // Removed entity ? Compound ? Compsolid ? Shell ? Wire
3633 isGood = Standard_False;
3635 Handle(TDataStd_IntegerArray) anIntegerArray;
3636 if (!aWhatHistoryLabel.FindAttribute(TDataStd_IntegerArray::GetID(), anIntegerArray)) {
3637 //Error: Empty modifications history for the sought shape.
3638 isGood = Standard_False;
3641 isGood = Standard_True;
3642 Standard_Integer imod, aModifLen = anIntegerArray->Array()->Length();
3643 for (imod = 1; imod <= aModifLen; imod++) {
3644 theModifiedList.Append(anIntegerArray->Array()->Value(imod));
3655 // try compound/compsolid/shell/wire element by element
3656 bool isFoundAny = false;
3657 TopTools_MapOfShape mapShape;
3659 if (theWhat.ShapeType() == TopAbs_COMPOUND ||
3660 theWhat.ShapeType() == TopAbs_COMPSOLID) {
3661 // recursive processing of compound/compsolid
3662 TopoDS_Iterator anIt (theWhat, Standard_True, Standard_True);
3663 for (; anIt.More(); anIt.Next()) {
3664 if (mapShape.Add(anIt.Value())) {
3665 TopoDS_Shape curWhat = anIt.Value();
3666 isFoundAny = GetInPlaceOfShape(theWhereFunction, theWhereIndices, curWhat, theModifiedList);
3667 if (isFoundAny) isFound = Standard_True;
3671 else if (theWhat.ShapeType() == TopAbs_SHELL) {
3672 // try to replace a shell by its faces images
3673 TopExp_Explorer anExp (theWhat, TopAbs_FACE);
3674 for (; anExp.More(); anExp.Next()) {
3675 if (mapShape.Add(anExp.Current())) {
3676 TopoDS_Shape curWhat = anExp.Current();
3677 isFoundAny = GetInPlaceOfShape(theWhereFunction, theWhereIndices, curWhat, theModifiedList);
3678 if (isFoundAny) isFound = Standard_True;
3682 else if (theWhat.ShapeType() == TopAbs_WIRE) {
3683 // try to replace a wire by its edges images
3684 TopExp_Explorer anExp (theWhat, TopAbs_EDGE);
3685 for (; anExp.More(); anExp.Next()) {
3686 if (mapShape.Add(anExp.Current())) {
3687 TopoDS_Shape curWhat = anExp.Current();
3688 isFoundAny = GetInPlaceOfShape(theWhereFunction, theWhereIndices, curWhat, theModifiedList);
3689 if (isFoundAny) isFound = Standard_True;
3701 //=============================================================================
3703 * GetShapeProperties
3705 //=============================================================================
3706 void GEOMImpl_IShapesOperations::GetShapeProperties( const TopoDS_Shape aShape, Standard_Real tab[],
3709 GProp_GProps theProps;
3711 //TopoDS_Shape aPntShape;
3712 Standard_Real aShapeSize;
3714 if (aShape.ShapeType() == TopAbs_VERTEX) aCenterMass = BRep_Tool::Pnt( TopoDS::Vertex( aShape ) );
3715 else if (aShape.ShapeType() == TopAbs_EDGE) BRepGProp::LinearProperties(aShape, theProps);
3716 else if (aShape.ShapeType() == TopAbs_FACE) BRepGProp::SurfaceProperties(aShape, theProps);
3717 else BRepGProp::VolumeProperties(aShape, theProps);
3719 if (aShape.ShapeType() == TopAbs_VERTEX)
3722 aCenterMass = theProps.CentreOfMass();
3723 aShapeSize = theProps.Mass();
3726 // aPntShape = BRepBuilderAPI_MakeVertex(aCenterMass).Shape();
3727 // aVertex = BRep_Tool::Pnt( TopoDS::Vertex( aPntShape ) );
3728 aVertex = aCenterMass;
3729 tab[0] = aVertex.X();
3730 tab[1] = aVertex.Y();
3731 tab[2] = aVertex.Z();
3732 tab[3] = aShapeSize;
3738 //================================================================================
3740 * \brief Return normal to face at extrema point
3742 //================================================================================
3744 gp_Vec GetNormal (const TopoDS_Face& face, const BRepExtrema_DistShapeShape& extrema)
3746 gp_Vec defaultNorm(1,0,0); // to have same normals on different faces
3748 // get UV at extrema point
3749 Standard_Real u,v, f,l;
3750 switch ( extrema.SupportTypeShape2(1) ) {
3751 case BRepExtrema_IsInFace: {
3752 extrema.ParOnFaceS2(1, u, v );
3755 case BRepExtrema_IsOnEdge: {
3756 TopoDS_Edge edge = TopoDS::Edge( extrema.SupportOnShape2(1));
3757 Handle(Geom2d_Curve) pcurve = BRep_Tool::CurveOnSurface( edge, face, f,l );
3758 extrema.ParOnEdgeS2( 1, u );
3759 gp_Pnt2d uv = pcurve->Value( u );
3764 case BRepExtrema_IsVertex: return defaultNorm;
3767 BRepAdaptor_Surface surface( face, false );
3768 gp_Vec du, dv; gp_Pnt p;
3769 surface.D1( u, v, p, du, dv );
3773 } catch (Standard_Failure ) {
3779 //================================================================================
3781 * \brief Return type of shape for explode. In case of compound it will be a type of sub-shape.
3783 //================================================================================
3784 TopAbs_ShapeEnum GEOMImpl_IShapesOperations::GetTypeOfSimplePart (const TopoDS_Shape& theShape)
3786 TopAbs_ShapeEnum aType = theShape.ShapeType();
3787 if (aType == TopAbs_VERTEX) return TopAbs_VERTEX;
3788 else if (aType == TopAbs_EDGE || aType == TopAbs_WIRE) return TopAbs_EDGE;
3789 else if (aType == TopAbs_FACE || aType == TopAbs_SHELL) return TopAbs_FACE;
3790 else if (aType == TopAbs_SOLID || aType == TopAbs_COMPSOLID) return TopAbs_SOLID;
3791 else if (aType == TopAbs_COMPOUND) {
3792 // Only the iType of the first shape in the compound is taken into account
3793 TopoDS_Iterator It (theShape, Standard_False, Standard_False);
3795 return GetTypeOfSimplePart(It.Value());
3798 return TopAbs_SHAPE;
3801 //=============================================================================
3806 //=============================================================================
3807 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlace (Handle(GEOM_Object) theShapeWhere,
3808 Handle(GEOM_Object) theShapeWhat)
3812 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
3814 TopoDS_Shape aWhere = theShapeWhere->GetValue();
3815 TopoDS_Shape aWhat = theShapeWhat->GetValue();
3816 TopoDS_Shape aPntShape;
3817 TopoDS_Vertex aVertex;
3819 if (aWhere.IsNull() || aWhat.IsNull()) {
3820 SetErrorCode("Error: aWhere and aWhat TopoDS_Shape are Null.");
3824 Handle(GEOM_Function) aWhereFunction = theShapeWhere->GetLastFunction();
3825 if (aWhereFunction.IsNull()) {
3826 SetErrorCode("Error: aWhereFunction is Null.");
3830 TopTools_IndexedMapOfShape aWhereIndices;
3831 TopExp::MapShapes(aWhere, aWhereIndices);
3833 TopAbs_ShapeEnum iType = TopAbs_SOLID;
3834 Standard_Real dl_l = 1e-3;
3835 Standard_Real min_l, Tol_0D, Tol_1D, Tol_2D, Tol_3D, Tol_Mass;
3836 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
3837 Bnd_Box BoundingBox;
3838 gp_Pnt aPnt, aPnt_aWhat, tab_Pnt[2];
3839 GProp_GProps aProps;
3841 // Find the iType of the aWhat shape
3842 iType = GetTypeOfSimplePart(aWhat);
3843 if (iType == TopAbs_SHAPE) {
3844 SetErrorCode("Error: An attempt to extract a shape of not supported type.");
3848 TopExp_Explorer Exp_aWhat ( aWhat, iType );
3849 TopExp_Explorer Exp_aWhere ( aWhere, iType );
3850 TopExp_Explorer Exp_Edge ( aWhere, TopAbs_EDGE );
3852 // Find the shortest edge in theShapeWhere shape
3853 BRepBndLib::Add(aWhere, BoundingBox);
3854 BoundingBox.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
3855 min_l = fabs(aXmax - aXmin);
3856 if( min_l < fabs(aYmax - aYmin) ) min_l = fabs(aYmax - aYmin);
3857 if( min_l < fabs(aZmax - aZmin) ) min_l = fabs(aZmax - aZmin);
3859 // Mantis issue 0020908 BEGIN
3860 if (!Exp_Edge.More()) {
3861 min_l = Precision::Confusion();
3863 // Mantis issue 0020908 END
3864 for ( Standard_Integer nbEdge = 0; Exp_Edge.More(); Exp_Edge.Next(), nbEdge++ ) {
3865 TopExp_Explorer Exp_Vertex( Exp_Edge.Current(), TopAbs_VERTEX);
3866 for ( Standard_Integer nbVertex = 0; Exp_Vertex.More(); Exp_Vertex.Next(), nbVertex++ ) {
3867 aPnt = BRep_Tool::Pnt( TopoDS::Vertex( Exp_Vertex.Current() ) );
3868 tab_Pnt[nbVertex] = aPnt;
3870 if ( ! tab_Pnt[0].IsEqual(tab_Pnt[1], dl_l) ) {
3871 BRepGProp::LinearProperties(Exp_Edge.Current(), aProps);
3872 if ( aProps.Mass() < min_l ) min_l = aProps.Mass();
3876 // Compute tolerances
3878 Tol_1D = dl_l * min_l;
3879 Tol_2D = dl_l * ( min_l * min_l) * ( 2. + dl_l);
3880 Tol_3D = dl_l * ( min_l * min_l * min_l ) * ( 3. + (3 * dl_l) + (dl_l * dl_l) );
3882 if (Tol_0D < Precision::Confusion()) Tol_0D = Precision::Confusion();
3883 if (Tol_1D < Precision::Confusion()) Tol_1D = Precision::Confusion();
3884 if (Tol_2D < Precision::Confusion()) Tol_2D = Precision::Confusion();
3885 if (Tol_3D < Precision::Confusion()) Tol_3D = Precision::Confusion();
3888 if ( iType == TopAbs_VERTEX ) Tol_Mass = Tol_0D;
3889 else if ( iType == TopAbs_EDGE ) Tol_Mass = Tol_1D;
3890 else if ( iType == TopAbs_FACE ) Tol_Mass = Tol_2D;
3892 // Searching for the sub-shapes inside the ShapeWhere shape
3893 GEOMAlgo_GetInPlace aGIP;
3894 aGIP.SetTolerance(Tol_1D);
3895 aGIP.SetTolMass(Tol_Mass);
3896 aGIP.SetTolCG(Tol_1D);
3898 aGIP.SetArgument(aWhat);
3899 aGIP.SetShapeWhere(aWhere);
3902 int iErr = aGIP.ErrorStatus();
3904 SetErrorCode("Error in GEOMAlgo_GetInPlace");
3908 // aGIP.IsFound() returns true only when the whole theShapeWhat
3909 // is found (as one shape or several parts). But we are also interested
3910 // in the partial result, that is why this check is commented.
3911 //if (!aGIP.IsFound()) {
3912 // SetErrorCode(NOT_FOUND_ANY);
3916 const TopTools_DataMapOfShapeListOfShape& aDMSLS = aGIP.Images();
3917 if (!aDMSLS.IsBound(aWhat)) {
3918 SetErrorCode(NOT_FOUND_ANY);
3922 // the list of shapes aLSA contains the shapes
3923 // of the Shape For Search that corresponds
3924 // to the Argument aWhat
3925 const TopTools_ListOfShape& aLSA = aDMSLS.Find(aWhat);
3926 if (aLSA.Extent() == 0) {
3927 SetErrorCode(NOT_FOUND_ANY); // Not found any Results
3931 Handle(TColStd_HArray1OfInteger) aModifiedArray = new TColStd_HArray1OfInteger (1, aLSA.Extent());
3932 TopTools_ListIteratorOfListOfShape anIterModif (aLSA);
3933 for (Standard_Integer imod = 1; anIterModif.More(); anIterModif.Next(), imod++) {
3934 if (aWhereIndices.Contains(anIterModif.Value())) {
3935 aModifiedArray->SetValue(imod, aWhereIndices.FindIndex(anIterModif.Value()));
3938 SetErrorCode("Error: wrong sub-shape returned");
3944 Handle(GEOM_Object) aResult = GetEngine()->AddSubShape(theShapeWhere, aModifiedArray);
3945 if (aResult.IsNull()) {
3946 SetErrorCode("Error in algorithm: result found, but cannot be returned.");
3950 if (aModifiedArray->Length() > 1 || theShapeWhat->GetType() == GEOM_GROUP) {
3952 aResult->SetType(GEOM_GROUP);
3954 //Set a sub-shape type
3955 TopoDS_Shape aFirstFound = aLSA.First();
3956 TopAbs_ShapeEnum aShapeType = aFirstFound.ShapeType();
3958 TDF_Label aFreeLabel = aResult->GetFreeLabel();
3959 TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aShapeType);
3962 //Make a Python command
3963 Handle(GEOM_Function) aFunction = aResult->GetFunction(1);
3965 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetInPlace("
3966 << theShapeWhere << ", " << theShapeWhat << ", True)";
3972 //=============================================================================
3974 * case GetInPlaceOld:
3977 //=============================================================================
3978 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlaceOld (Handle(GEOM_Object) theShapeWhere,
3979 Handle(GEOM_Object) theShapeWhat)
3983 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
3985 TopoDS_Shape aWhere = theShapeWhere->GetValue();
3986 TopoDS_Shape aWhat = theShapeWhat->GetValue();
3987 TopoDS_Shape aPntShape;
3988 TopoDS_Vertex aVertex;
3990 if (aWhere.IsNull() || aWhat.IsNull()) {
3991 SetErrorCode("Error: aWhere and aWhat TopoDS_Shape are Null.");
3995 Handle(GEOM_Function) aWhereFunction = theShapeWhere->GetLastFunction();
3996 if (aWhereFunction.IsNull()) {
3997 SetErrorCode("Error: aWhereFunction is Null.");
4001 TopTools_IndexedMapOfShape aWhereIndices;
4002 TopExp::MapShapes(aWhere, aWhereIndices);
4004 TColStd_ListOfInteger aModifiedList;
4005 Standard_Integer aWhereIndex;
4006 Handle(TColStd_HArray1OfInteger) aModifiedArray;
4007 Handle(GEOM_Object) aResult;
4009 bool isFound = false;
4010 TopAbs_ShapeEnum iType = TopAbs_SOLID;
4011 //Standard_Real aWhat_Mass = 0., aWhere_Mass = 0.;
4012 Standard_Real tab_aWhat[4], tab_aWhere[4];
4013 Standard_Real dl_l = 1e-3;
4014 Standard_Real min_l, Tol_0D, Tol_1D, Tol_2D, Tol_3D, Tol_Mass;
4015 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
4016 Bnd_Box BoundingBox;
4017 gp_Pnt aPnt, aPnt_aWhat, tab_Pnt[2];
4018 GProp_GProps aProps;
4020 // Find the iType of the aWhat shape
4022 if ( aWhat.ShapeType() == TopAbs_VERTEX ) iType = TopAbs_VERTEX;
4023 else if ( aWhat.ShapeType() == TopAbs_EDGE || aWhat.ShapeType() == TopAbs_WIRE ) iType = TopAbs_EDGE;
4024 else if ( aWhat.ShapeType() == TopAbs_FACE || aWhat.ShapeType() == TopAbs_SHELL ) iType = TopAbs_FACE;
4025 else if ( aWhat.ShapeType() == TopAbs_SOLID || aWhat.ShapeType() == TopAbs_COMPSOLID ) iType = TopAbs_SOLID;
4026 else if ( aWhat.ShapeType() == TopAbs_COMPOUND ) {
4027 // Only the iType of the first shape in the compound is taken into account
4028 TopoDS_Iterator It (aWhat, Standard_False, Standard_False);
4030 SetErrorCode("Error: theShapeWhat is an empty COMPOUND.");
4033 TopAbs_ShapeEnum compType = It.Value().ShapeType();
4034 if ( compType == TopAbs_VERTEX ) iType = TopAbs_VERTEX;
4035 else if ( compType == TopAbs_EDGE || compType == TopAbs_WIRE ) iType = TopAbs_EDGE;
4036 else if ( compType == TopAbs_FACE || compType == TopAbs_SHELL) iType = TopAbs_FACE;
4037 else if ( compType == TopAbs_SOLID || compType == TopAbs_COMPSOLID) iType = TopAbs_SOLID;
4040 SetErrorCode("Error: An attempt to extract a shape of not supported type.");
4044 iType = GetTypeOfSimplePart(aWhat);
4045 if (iType == TopAbs_SHAPE) {
4046 SetErrorCode("Error: An attempt to extract a shape of not supported type.");
4050 TopExp_Explorer Exp_aWhat ( aWhat, iType );
4051 TopExp_Explorer Exp_aWhere ( aWhere, iType );
4052 TopExp_Explorer Exp_Edge ( aWhere, TopAbs_EDGE );
4054 // Find the shortest edge in theShapeWhere shape
4055 BRepBndLib::Add(aWhere, BoundingBox);
4056 BoundingBox.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
4057 min_l = fabs(aXmax - aXmin);
4058 if( min_l < fabs(aYmax - aYmin) ) min_l = fabs(aYmax - aYmin);
4059 if( min_l < fabs(aZmax - aZmin) ) min_l = fabs(aZmax - aZmin);
4061 // Mantis issue 0020908 BEGIN
4062 if (!Exp_Edge.More()) {
4063 min_l = Precision::Confusion();
4065 // Mantis issue 0020908 END
4066 for ( Standard_Integer nbEdge = 0; Exp_Edge.More(); Exp_Edge.Next(), nbEdge++ ) {
4067 TopExp_Explorer Exp_Vertex( Exp_Edge.Current(), TopAbs_VERTEX);
4068 for ( Standard_Integer nbVertex = 0; Exp_Vertex.More(); Exp_Vertex.Next(), nbVertex++ ) {
4069 aPnt = BRep_Tool::Pnt( TopoDS::Vertex( Exp_Vertex.Current() ) );
4070 tab_Pnt[nbVertex] = aPnt;
4072 if ( ! tab_Pnt[0].IsEqual(tab_Pnt[1], dl_l) ) {
4073 BRepGProp::LinearProperties(Exp_Edge.Current(), aProps);
4074 if ( aProps.Mass() < min_l ) min_l = aProps.Mass();
4078 // Compute tolerances
4080 Tol_1D = dl_l * min_l;
4081 Tol_2D = dl_l * ( min_l * min_l) * ( 2. + dl_l);
4082 Tol_3D = dl_l * ( min_l * min_l * min_l ) * ( 3. + (3 * dl_l) + (dl_l * dl_l) );
4084 if (Tol_0D < Precision::Confusion()) Tol_0D = Precision::Confusion();
4085 if (Tol_1D < Precision::Confusion()) Tol_1D = Precision::Confusion();
4086 if (Tol_2D < Precision::Confusion()) Tol_2D = Precision::Confusion();
4087 if (Tol_3D < Precision::Confusion()) Tol_3D = Precision::Confusion();
4089 //if (Tol_1D > 1.0) Tol_1D = 1.0;
4090 //if (Tol_2D > 1.0) Tol_2D = 1.0;
4091 //if (Tol_3D > 1.0) Tol_3D = 1.0;
4094 if ( iType == TopAbs_VERTEX ) Tol_Mass = Tol_0D;
4095 else if ( iType == TopAbs_EDGE ) Tol_Mass = Tol_1D;
4096 else if ( iType == TopAbs_FACE ) Tol_Mass = Tol_2D;
4098 // Compute the ShapeWhat Mass
4100 for ( ; Exp_aWhat.More(); Exp_aWhat.Next() ) {
4101 if ( iType == TopAbs_VERTEX ) {
4105 else if ( iType == TopAbs_EDGE ) BRepGProp::LinearProperties(Exp_aWhat.Current(), aProps);
4106 else if ( iType == TopAbs_FACE ) BRepGProp::SurfaceProperties(Exp_aWhat.Current(), aProps);
4107 else BRepGProp::VolumeProperties(Exp_aWhat.Current(), aProps);
4108 aWhat_Mass += aProps.Mass();
4112 // Searching for the sub-shapes inside the ShapeWhere shape
4113 TopTools_MapOfShape map_aWhere;
4114 for ( Exp_aWhere.ReInit(); Exp_aWhere.More(); Exp_aWhere.Next() ) {
4115 if (!map_aWhere.Add(Exp_aWhere.Current()))
4116 continue; // skip repeated shape to avoid mass addition
4117 GetShapeProperties( Exp_aWhere.Current(), tab_aWhere, aPnt );
4118 for ( Exp_aWhat.ReInit(); Exp_aWhat.More(); Exp_aWhat.Next() ) {
4119 GetShapeProperties( Exp_aWhat.Current(), tab_aWhat, aPnt_aWhat );
4120 if ( fabs(tab_aWhat[3] - tab_aWhere[3]) <= Tol_Mass && aPnt_aWhat.Distance(aPnt) <= Tol_1D )
4123 if ( (tab_aWhat[3] - tab_aWhere[3]) > Tol_Mass ) {
4124 aPntShape = BRepBuilderAPI_MakeVertex( aPnt ).Shape();
4125 aVertex = TopoDS::Vertex( aPntShape );
4126 BRepExtrema_DistShapeShape aWhereDistance ( aVertex, Exp_aWhere.Current() );
4127 BRepExtrema_DistShapeShape aWhatDistance ( aVertex, Exp_aWhat.Current() );
4128 if ( aWhereDistance.IsDone() && aWhatDistance.IsDone() &&
4129 fabs(aWhereDistance.Value() - aWhatDistance.Value()) <= Tol_1D )
4131 // 0020162: "EDF 961 GEOM : Getinplace is getting additionnal orthogonal faces"
4132 // aVertex must be projected to the same point on Where and on What
4133 gp_Pnt pOnWhat = aWhatDistance.PointOnShape2(1);
4134 gp_Pnt pOnWhere = aWhereDistance.PointOnShape2(1);
4135 isFound = ( pOnWhat.Distance(pOnWhere) <= Tol_1D );
4136 if ( isFound && iType == TopAbs_FACE )
4138 // check normals at pOnWhat and pOnWhere
4139 const double angleTol = M_PI/180.;
4140 gp_Vec normToWhat = GetNormal( TopoDS::Face(Exp_aWhat.Current()), aWhatDistance);
4141 gp_Vec normToWhere = GetNormal( TopoDS::Face(Exp_aWhere.Current()), aWhereDistance);
4142 if ( normToWhat * normToWhere < 0 )
4143 normToWhat.Reverse();
4144 isFound = ( normToWhat.Angle( normToWhere ) < angleTol );
4150 aWhereIndex = aWhereIndices.FindIndex(Exp_aWhere.Current());
4151 aModifiedList.Append(aWhereIndex);
4152 //aWhere_Mass += tab_aWhere[3];
4157 //if ( fabs( aWhat_Mass - aWhere_Mass ) <= Tol_Mass )
4161 if (aModifiedList.Extent() == 0) { // Not found any Results
4162 SetErrorCode(NOT_FOUND_ANY);
4166 aModifiedArray = new TColStd_HArray1OfInteger (1, aModifiedList.Extent());
4167 TColStd_ListIteratorOfListOfInteger anIterModif (aModifiedList);
4168 for (Standard_Integer imod = 1; anIterModif.More(); anIterModif.Next(), imod++)
4169 aModifiedArray->SetValue(imod, anIterModif.Value());
4172 aResult = GetEngine()->AddSubShape(theShapeWhere, aModifiedArray);
4173 if (aResult.IsNull()) {
4174 SetErrorCode("Error in algorithm: result found, but cannot be returned.");
4178 if (aModifiedArray->Length() > 1 || theShapeWhat->GetType() == GEOM_GROUP) {
4180 aResult->SetType(GEOM_GROUP);
4182 //Set a sub-shape type
4183 TopoDS_Shape aFirstFound = aWhereIndices.FindKey(aModifiedArray->Value(1));
4184 TopAbs_ShapeEnum aShapeType = aFirstFound.ShapeType();
4186 TDF_Label aFreeLabel = aResult->GetFreeLabel();
4187 TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aShapeType);
4190 //Make a Python command
4191 Handle(GEOM_Function) aFunction = aResult->GetFunction(1);
4193 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetInPlace("
4194 << theShapeWhere << ", " << theShapeWhat << ", False)";
4200 //=======================================================================
4201 //function : GetInPlaceByHistory
4203 //=======================================================================
4204 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlaceByHistory
4205 (Handle(GEOM_Object) theShapeWhere,
4206 Handle(GEOM_Object) theShapeWhat)
4210 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
4212 TopoDS_Shape aWhere = theShapeWhere->GetValue();
4213 TopoDS_Shape aWhat = theShapeWhat->GetValue();
4215 if (aWhere.IsNull() || aWhat.IsNull()) return NULL;
4217 Handle(GEOM_Function) aWhereFunction = theShapeWhere->GetLastFunction();
4218 if (aWhereFunction.IsNull()) return NULL;
4220 //Fill array of indices
4221 TopTools_IndexedMapOfShape aWhereIndices;
4222 TopExp::MapShapes(aWhere, aWhereIndices);
4225 TColStd_ListOfInteger aModifiedList;
4226 bool isFound = GetInPlaceOfShape(aWhereFunction, aWhereIndices, aWhat, aModifiedList);
4228 if (!isFound || aModifiedList.Extent() < 1) {
4229 SetErrorCode("Error: No history found for the sought shape or its sub-shapes.");
4233 Handle(TColStd_HArray1OfInteger) aModifiedArray =
4234 new TColStd_HArray1OfInteger (1, aModifiedList.Extent());
4235 TColStd_ListIteratorOfListOfInteger anIterModif (aModifiedList);
4236 for (Standard_Integer imod = 1; anIterModif.More(); anIterModif.Next(), imod++) {
4237 aModifiedArray->SetValue(imod, anIterModif.Value());
4241 Handle(GEOM_Object) aResult = GetEngine()->AddSubShape(theShapeWhere, aModifiedArray);
4242 if (aResult.IsNull()) {
4243 SetErrorCode("Error in algorithm: result found, but cannot be returned.");
4247 if (aModifiedArray->Length() > 1) {
4249 aResult->SetType(GEOM_GROUP);
4251 //Set a sub-shape type
4252 TopoDS_Shape aFirstFound = aWhereIndices.FindKey(aModifiedArray->Value(1));
4253 TopAbs_ShapeEnum aShapeType = aFirstFound.ShapeType();
4255 TDF_Label aFreeLabel = aResult->GetFreeLabel();
4256 TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aShapeType);
4259 //Make a Python command
4260 Handle(GEOM_Function) aFunction = aResult->GetFunction(1);
4262 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetInPlaceByHistory("
4263 << theShapeWhere << ", " << theShapeWhat << ")";
4269 //=======================================================================
4270 //function : ShapeToDouble
4271 //purpose : used by CompareShapes::operator()
4272 //=======================================================================
4273 std::pair<double, double> ShapeToDouble (const TopoDS_Shape& S, bool isOldSorting)
4275 // Computing of CentreOfMass
4279 if (S.ShapeType() == TopAbs_VERTEX) {
4280 GPoint = BRep_Tool::Pnt(TopoDS::Vertex(S));
4281 Len = (double)S.Orientation();
4285 // BEGIN: fix for Mantis issue 0020842
4287 BRepGProp::LinearProperties(S, GPr);
4290 if (S.ShapeType() == TopAbs_EDGE || S.ShapeType() == TopAbs_WIRE) {
4291 BRepGProp::LinearProperties(S, GPr);
4293 else if (S.ShapeType() == TopAbs_FACE || S.ShapeType() == TopAbs_SHELL) {
4294 BRepGProp::SurfaceProperties(S, GPr);
4297 BRepGProp::VolumeProperties(S, GPr);
4300 // END: fix for Mantis issue 0020842
4301 GPoint = GPr.CentreOfMass();
4305 double dMidXYZ = GPoint.X() * 999.0 + GPoint.Y() * 99.0 + GPoint.Z() * 0.9;
4306 return std::make_pair(dMidXYZ, Len);
4309 //=======================================================================
4310 //function : CompareShapes::operator()
4311 //purpose : used by std::sort(), called from SortShapes()
4312 //=======================================================================
4313 bool GEOMImpl_IShapesOperations::CompareShapes::operator()(const TopoDS_Shape& theShape1,
4314 const TopoDS_Shape& theShape2)
4316 if (!myMap.IsBound(theShape1)) {
4317 myMap.Bind(theShape1, ShapeToDouble(theShape1, myIsOldSorting));
4320 if (!myMap.IsBound(theShape2)) {
4321 myMap.Bind(theShape2, ShapeToDouble(theShape2, myIsOldSorting));
4324 std::pair<double, double> val1 = myMap.Find(theShape1);
4325 std::pair<double, double> val2 = myMap.Find(theShape2);
4327 double tol = Precision::Confusion();
4328 bool exchange = Standard_False;
4330 double dMidXYZ = val1.first - val2.first;
4331 if (dMidXYZ >= tol) {
4332 exchange = Standard_True;
4334 else if (Abs(dMidXYZ) < tol) {
4335 double dLength = val1.second - val2.second;
4336 if (dLength >= tol) {
4337 exchange = Standard_True;
4339 else if (Abs(dLength) < tol && theShape1.ShapeType() <= TopAbs_FACE) {
4341 // equal values possible on shapes such as two halves of a sphere and
4342 // a membrane inside the sphere
4344 BRepBndLib::Add(theShape1, box1);
4345 if (!box1.IsVoid()) {
4346 BRepBndLib::Add(theShape2, box2);
4347 Standard_Real dSquareExtent = box1.SquareExtent() - box2.SquareExtent();
4348 if (dSquareExtent >= tol) {
4349 exchange = Standard_True;
4351 else if (Abs(dSquareExtent) < tol) {
4352 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax, val1, val2;
4353 box1.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
4354 val1 = (aXmin+aXmax)*999.0 + (aYmin+aYmax)*99.0 + (aZmin+aZmax)*0.9;
4355 box2.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
4356 val2 = (aXmin+aXmax)*999.0 + (aYmin+aYmax)*99.0 + (aZmin+aZmax)*0.9;
4357 if ((val1 - val2) >= tol) {
4358 exchange = Standard_True;
4365 //return val1 < val2;
4369 //=======================================================================
4370 //function : SortShapes
4372 //=======================================================================
4373 void GEOMImpl_IShapesOperations::SortShapes(TopTools_ListOfShape& SL,
4374 const Standard_Boolean isOldSorting)
4376 #ifdef STD_SORT_ALGO
4377 std::vector<TopoDS_Shape> aShapesVec;
4378 aShapesVec.reserve(SL.Extent());
4380 TopTools_ListIteratorOfListOfShape it (SL);
4381 for (; it.More(); it.Next()) {
4382 aShapesVec.push_back(it.Value());
4386 CompareShapes shComp (isOldSorting);
4387 std::stable_sort(aShapesVec.begin(), aShapesVec.end(), shComp);
4388 //std::sort(aShapesVec.begin(), aShapesVec.end(), shComp);
4390 std::vector<TopoDS_Shape>::const_iterator anIter = aShapesVec.begin();
4391 for (; anIter != aShapesVec.end(); ++anIter) {
4395 // old implementation
4396 Standard_Integer MaxShapes = SL.Extent();
4397 TopTools_Array1OfShape aShapes (1,MaxShapes);
4398 TColStd_Array1OfInteger OrderInd(1,MaxShapes);
4399 TColStd_Array1OfReal MidXYZ (1,MaxShapes); //X,Y,Z;
4400 TColStd_Array1OfReal Length (1,MaxShapes); //X,Y,Z;
4402 // Computing of CentreOfMass
4403 Standard_Integer Index;
4406 TopTools_ListIteratorOfListOfShape it(SL);
4407 for (Index=1; it.More(); Index++)
4409 TopoDS_Shape S = it.Value();
4410 SL.Remove( it ); // == it.Next()
4412 OrderInd.SetValue (Index, Index);
4413 if (S.ShapeType() == TopAbs_VERTEX) {
4414 GPoint = BRep_Tool::Pnt( TopoDS::Vertex( S ));
4415 Length.SetValue( Index, (Standard_Real) S.Orientation());
4418 // BEGIN: fix for Mantis issue 0020842
4420 BRepGProp::LinearProperties (S, GPr);
4423 if (S.ShapeType() == TopAbs_EDGE || S.ShapeType() == TopAbs_WIRE) {
4424 BRepGProp::LinearProperties (S, GPr);
4426 else if (S.ShapeType() == TopAbs_FACE || S.ShapeType() == TopAbs_SHELL) {
4427 BRepGProp::SurfaceProperties(S, GPr);
4430 BRepGProp::VolumeProperties(S, GPr);
4433 // END: fix for Mantis issue 0020842
4434 GPoint = GPr.CentreOfMass();
4435 Length.SetValue(Index, GPr.Mass());
4437 MidXYZ.SetValue(Index, GPoint.X()*999.0 + GPoint.Y()*99.0 + GPoint.Z()*0.9);
4438 //cout << Index << " L: " << Length(Index) << "CG: " << MidXYZ(Index) << endl;
4442 Standard_Integer aTemp;
4443 Standard_Boolean exchange, Sort = Standard_True;
4444 Standard_Real tol = Precision::Confusion();
4447 Sort = Standard_False;
4448 for (Index=1; Index < MaxShapes; Index++)
4450 exchange = Standard_False;
4451 Standard_Real dMidXYZ = MidXYZ(OrderInd(Index)) - MidXYZ(OrderInd(Index+1));
4452 Standard_Real dLength = Length(OrderInd(Index)) - Length(OrderInd(Index+1));
4453 if ( dMidXYZ >= tol ) {
4454 // cout << "MidXYZ: " << MidXYZ(OrderInd(Index))<< " > " <<MidXYZ(OrderInd(Index+1))
4455 // << " d: " << dMidXYZ << endl;
4456 exchange = Standard_True;
4458 else if ( Abs(dMidXYZ) < tol && dLength >= tol ) {
4459 // cout << "Length: " << Length(OrderInd(Index))<< " > " <<Length(OrderInd(Index+1))
4460 // << " d: " << dLength << endl;
4461 exchange = Standard_True;
4463 else if ( Abs(dMidXYZ) < tol && Abs(dLength) < tol &&
4464 aShapes(OrderInd(Index)).ShapeType() <= TopAbs_FACE) {
4466 // equal values possible on shapes such as two halves of a sphere and
4467 // a membrane inside the sphere
4469 BRepBndLib::Add( aShapes( OrderInd(Index) ), box1 );
4470 if ( box1.IsVoid() ) continue;
4471 BRepBndLib::Add( aShapes( OrderInd(Index+1) ), box2 );
4472 Standard_Real dSquareExtent = box1.SquareExtent() - box2.SquareExtent();
4473 if ( dSquareExtent >= tol ) {
4474 // cout << "SquareExtent: " << box1.SquareExtent()<<" > "<<box2.SquareExtent() << endl;
4475 exchange = Standard_True;
4477 else if ( Abs(dSquareExtent) < tol ) {
4478 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax, val1, val2;
4479 box1.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
4480 val1 = (aXmin+aXmax)*999 + (aYmin+aYmax)*99 + (aZmin+aZmax)*0.9;
4481 box2.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
4482 val2 = (aXmin+aXmax)*999 + (aYmin+aYmax)*99 + (aZmin+aZmax)*0.9;
4483 //exchange = val1 > val2;
4484 if ((val1 - val2) >= tol) {
4485 exchange = Standard_True;
4487 //cout << "box: " << val1<<" > "<<val2 << endl;
4493 // cout << "exchange " << Index << " & " << Index+1 << endl;
4494 aTemp = OrderInd(Index);
4495 OrderInd(Index) = OrderInd(Index+1);
4496 OrderInd(Index+1) = aTemp;
4497 Sort = Standard_True;
4502 for (Index=1; Index <= MaxShapes; Index++)
4503 SL.Append( aShapes( OrderInd(Index) ));
4507 //=======================================================================
4508 //function : CompsolidToCompound
4510 //=======================================================================
4511 TopoDS_Shape GEOMImpl_IShapesOperations::CompsolidToCompound (const TopoDS_Shape& theCompsolid)
4513 if (theCompsolid.ShapeType() != TopAbs_COMPSOLID) {
4514 return theCompsolid;
4517 TopoDS_Compound aCompound;
4519 B.MakeCompound(aCompound);
4521 TopTools_MapOfShape mapShape;
4522 TopoDS_Iterator It (theCompsolid, Standard_True, Standard_True);
4524 for (; It.More(); It.Next()) {
4525 TopoDS_Shape aShape_i = It.Value();
4526 if (mapShape.Add(aShape_i)) {
4527 B.Add(aCompound, aShape_i);
4534 //=======================================================================
4535 //function : CheckTriangulation
4537 //=======================================================================
4538 bool GEOMImpl_IShapesOperations::CheckTriangulation (const TopoDS_Shape& aShape)
4540 bool isTriangulation = true;
4542 TopExp_Explorer exp (aShape, TopAbs_FACE);
4545 TopLoc_Location aTopLoc;
4546 Handle(Poly_Triangulation) aTRF;
4547 aTRF = BRep_Tool::Triangulation(TopoDS::Face(exp.Current()), aTopLoc);
4548 if (aTRF.IsNull()) {
4549 isTriangulation = false;
4552 else // no faces, try edges
4554 TopExp_Explorer expe (aShape, TopAbs_EDGE);
4558 TopLoc_Location aLoc;
4559 Handle(Poly_Polygon3D) aPE = BRep_Tool::Polygon3D(TopoDS::Edge(expe.Current()), aLoc);
4561 isTriangulation = false;
4565 if (!isTriangulation) {
4566 // calculate deflection
4567 Standard_Real aDeviationCoefficient = 0.001;
4570 BRepBndLib::Add(aShape, B);
4571 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
4572 B.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
4574 Standard_Real dx = aXmax - aXmin, dy = aYmax - aYmin, dz = aZmax - aZmin;
4575 Standard_Real aDeflection = Max(Max(dx, dy), dz) * aDeviationCoefficient * 4;
4576 Standard_Real aHLRAngle = 0.349066;
4578 BRepMesh_IncrementalMesh Inc (aShape, aDeflection, Standard_False, aHLRAngle);
4584 #define MAX_TOLERANCE 1.e-7
4586 //=======================================================================
4587 //function : isSameEdge
4588 //purpose : Returns True if two edges coincide
4589 //=======================================================================
4590 static bool isSameEdge(const TopoDS_Edge& theEdge1, const TopoDS_Edge& theEdge2)
4592 TopoDS_Vertex V11, V12, V21, V22;
4593 TopExp::Vertices(theEdge1, V11, V12);
4594 TopExp::Vertices(theEdge2, V21, V22);
4595 gp_Pnt P11 = BRep_Tool::Pnt(V11);
4596 gp_Pnt P12 = BRep_Tool::Pnt(V12);
4597 gp_Pnt P21 = BRep_Tool::Pnt(V21);
4598 gp_Pnt P22 = BRep_Tool::Pnt(V22);
4599 bool coincide = false;
4601 //Check that ends of edges coincide
4602 if(P11.Distance(P21) <= MAX_TOLERANCE) {
4603 if(P12.Distance(P22) <= MAX_TOLERANCE) coincide = true;
4605 else if(P11.Distance(P22) <= MAX_TOLERANCE) {
4606 if(P12.Distance(P21) <= MAX_TOLERANCE) coincide = true;
4609 if(!coincide) return false;
4611 if (BRep_Tool::Degenerated(theEdge1))
4612 if (BRep_Tool::Degenerated(theEdge2)) return true;
4615 if (BRep_Tool::Degenerated(theEdge2)) return false;
4617 double U11, U12, U21, U22;
4618 Handle(Geom_Curve) C1 = BRep_Tool::Curve(theEdge1, U11, U12);
4619 Handle(Geom_Curve) C2 = BRep_Tool::Curve(theEdge2, U21, U22);
4620 if(C1->DynamicType() == C2->DynamicType()) return true;
4622 //Check that both edges has the same geometry
4623 double range = U12-U11;
4624 double U = U11+ range/3.0;
4625 gp_Pnt P1 = C1->Value(U); //Compute a point on one third of the edge's length
4626 U = U11+range*2.0/3.0;
4627 gp_Pnt P2 = C1->Value(U); //Compute a point on two thirds of the edge's length
4629 if(!GeomLib_Tool::Parameter(C2, P1, MAX_TOLERANCE, U) || U < U21 || U > U22)
4632 if(P1.Distance(C2->Value(U)) > MAX_TOLERANCE) return false;
4634 if(!GeomLib_Tool::Parameter(C2, P2, MAX_TOLERANCE, U) || U < U21 || U > U22)
4637 if(P2.Distance(C2->Value(U)) > MAX_TOLERANCE) return false;
4642 #include <TopoDS_TShape.hxx>
4643 //=======================================================================
4644 //function : isSameFace
4645 //purpose : Returns True if two faces coincide
4646 //=======================================================================
4647 static bool isSameFace(const TopoDS_Face& theFace1, const TopoDS_Face& theFace2)
4649 TopExp_Explorer E(theFace1, TopAbs_EDGE);
4650 TopTools_ListOfShape LS1, LS2;
4651 for(; E.More(); E.Next()) LS1.Append(E.Current());
4653 E.Init(theFace2, TopAbs_EDGE);
4654 for(; E.More(); E.Next()) LS2.Append(E.Current());
4656 //Compare the number of edges in the faces
4657 if(LS1.Extent() != LS2.Extent()) return false;
4659 double aMin = RealFirst(), aMax = RealLast();
4660 double xminB1=aMax, yminB1=aMax, zminB1=aMax, xminB2=aMax, yminB2=aMax, zminB2=aMax;
4661 double xmaxB1=aMin, ymaxB1=aMin, zmaxB1=aMin, xmaxB2=aMin, ymaxB2=aMin, zmaxB2=aMin;
4663 for(E.Init(theFace1, TopAbs_VERTEX); E.More(); E.Next()) {
4664 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4665 if(P.X() < xminB1) xminB1 = P.X();
4666 if(P.Y() < yminB1) yminB1 = P.Y();
4667 if(P.Z() < zminB1) zminB1 = P.Z();
4668 if(P.X() > xmaxB1) xmaxB1 = P.X();
4669 if(P.Y() > ymaxB1) ymaxB1 = P.Y();
4670 if(P.Z() > zmaxB1) zmaxB1 = P.Z();
4673 for(E.Init(theFace2, TopAbs_VERTEX); E.More(); E.Next()) {
4674 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4675 if(P.X() < xminB2) xminB2 = P.X();
4676 if(P.Y() < yminB2) yminB2 = P.Y();
4677 if(P.Z() < zminB2) zminB2 = P.Z();
4678 if(P.X() > xmaxB2) xmaxB2 = P.X();
4679 if(P.Y() > ymaxB2) ymaxB2 = P.Y();
4680 if(P.Z() > zmaxB2) zmaxB2 = P.Z();
4683 //Compare the bounding boxes of both faces
4684 if(gp_Pnt(xminB1, yminB1, zminB1).Distance(gp_Pnt(xminB2, yminB2, zminB2)) > MAX_TOLERANCE)
4687 if(gp_Pnt(xmaxB1, ymaxB1, zmaxB1).Distance(gp_Pnt(xmaxB2, ymaxB2, zmaxB2)) > MAX_TOLERANCE)
4690 Handle(Geom_Surface) S1 = BRep_Tool::Surface(theFace1);
4691 Handle(Geom_Surface) S2 = BRep_Tool::Surface(theFace2);
4693 //Check if there a coincidence of two surfaces at least in two points
4694 double U11, U12, V11, V12, U21, U22, V21, V22;
4695 BRepTools::UVBounds(theFace1, U11, U12, V11, V12);
4696 BRepTools::UVBounds(theFace2, U21, U22, V21, V22);
4698 double rangeU = U12-U11;
4699 double rangeV = V12-V11;
4700 double U = U11 + rangeU/3.0;
4701 double V = V11 + rangeV/3.0;
4702 gp_Pnt P1 = S1->Value(U, V);
4703 U = U11+rangeU*2.0/3.0;
4704 V = V11+rangeV*2.0/3.0;
4705 gp_Pnt P2 = S1->Value(U, V);
4707 if (!GeomLib_Tool::Parameters(S2, P1, MAX_TOLERANCE, U, V) || U < U21 || U > U22 || V < V21 || V > V22)
4710 if (P1.Distance(S2->Value(U,V)) > MAX_TOLERANCE) return false;
4712 if (!GeomLib_Tool::Parameters(S2, P2, MAX_TOLERANCE, U, V) || U < U21 || U > U22 || V < V21 || V > V22)
4715 if (P2.Distance(S2->Value(U, V)) > MAX_TOLERANCE) return false;
4717 //Check that each edge of the Face1 has a counterpart in the Face2
4718 TopTools_MapOfOrientedShape aMap;
4719 TopTools_ListIteratorOfListOfShape LSI1(LS1);
4720 for(; LSI1.More(); LSI1.Next()) {
4721 TopoDS_Edge E = TopoDS::Edge(LSI1.Value());
4722 bool isFound = false;
4723 TopTools_ListIteratorOfListOfShape LSI2(LS2);
4724 for(; LSI2.More(); LSI2.Next()) {
4725 TopoDS_Shape aValue = LSI2.Value();
4726 if(aMap.Contains(aValue)) continue; //To avoid checking already found edge several times
4727 if(isSameEdge(E, TopoDS::Edge(aValue))) {
4733 if(!isFound) return false;
4739 //=======================================================================
4740 //function : isSameSolid
4741 //purpose : Returns True if two solids coincide
4742 //=======================================================================
4743 bool isSameSolid(const TopoDS_Solid& theSolid1, const TopoDS_Solid& theSolid2)
4745 TopExp_Explorer E(theSolid1, TopAbs_FACE);
4746 TopTools_ListOfShape LS1, LS2;
4747 for(; E.More(); E.Next()) LS1.Append(E.Current());
4748 E.Init(theSolid2, TopAbs_FACE);
4749 for(; E.More(); E.Next()) LS2.Append(E.Current());
4751 if(LS1.Extent() != LS2.Extent()) return false;
4753 double aMin = RealFirst(), aMax = RealLast();
4754 double xminB1=aMax, yminB1=aMax, zminB1=aMax, xminB2=aMax, yminB2=aMax, zminB2=aMax;
4755 double xmaxB1=aMin, ymaxB1=aMin, zmaxB1=aMin, xmaxB2=aMin, ymaxB2=aMin, zmaxB2=aMin;
4757 for(E.Init(theSolid1, TopAbs_VERTEX); E.More(); E.Next()) {
4758 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4759 if(P.X() < xminB1) xminB1 = P.X();
4760 if(P.Y() < yminB1) yminB1 = P.Y();
4761 if(P.Z() < zminB1) zminB1 = P.Z();
4762 if(P.X() > xmaxB1) xmaxB1 = P.X();
4763 if(P.Y() > ymaxB1) ymaxB1 = P.Y();
4764 if(P.Z() > zmaxB1) zmaxB1 = P.Z();
4767 for(E.Init(theSolid2, TopAbs_VERTEX); E.More(); E.Next()) {
4768 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4769 if(P.X() < xminB2) xminB2 = P.X();
4770 if(P.Y() < yminB2) yminB2 = P.Y();
4771 if(P.Z() < zminB2) zminB2 = P.Z();
4772 if(P.X() > xmaxB2) xmaxB2 = P.X();
4773 if(P.Y() > ymaxB2) ymaxB2 = P.Y();
4774 if(P.Z() > zmaxB2) zmaxB2 = P.Z();
4777 //Compare the bounding boxes of both solids
4778 if(gp_Pnt(xminB1, yminB1, zminB1).Distance(gp_Pnt(xminB2, yminB2, zminB2)) > MAX_TOLERANCE)
4781 if(gp_Pnt(xmaxB1, ymaxB1, zmaxB1).Distance(gp_Pnt(xmaxB2, ymaxB2, zmaxB2)) > MAX_TOLERANCE)
4784 //Check that each face of the Solid1 has a counterpart in the Solid2
4785 TopTools_MapOfOrientedShape aMap;
4786 TopTools_ListIteratorOfListOfShape LSI1(LS1);
4787 for(; LSI1.More(); LSI1.Next()) {
4788 TopoDS_Face F = TopoDS::Face(LSI1.Value());
4789 bool isFound = false;
4790 TopTools_ListIteratorOfListOfShape LSI2(LS2);
4791 for(; LSI2.More(); LSI2.Next()) {
4792 if(aMap.Contains(LSI2.Value())) continue; //To avoid checking already found faces several times
4793 if(isSameFace(F, TopoDS::Face(LSI2.Value()))) {
4794 aMap.Add(LSI2.Value());
4799 if(!isFound) return false;
4805 //=======================================================================
4806 //function : GetSame
4808 //=======================================================================
4809 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetSame(const Handle(GEOM_Object)& theShapeWhere,
4810 const Handle(GEOM_Object)& theShapeWhat)
4813 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
4815 TopoDS_Shape aWhere = theShapeWhere->GetValue();
4816 TopoDS_Shape aWhat = theShapeWhat->GetValue();
4818 if (aWhere.IsNull() || aWhat.IsNull()) return NULL;
4821 bool isFound = false;
4822 TopoDS_Shape aSubShape;
4823 TopTools_MapOfShape aMap;
4825 if (aWhat.ShapeType() == TopAbs_COMPOUND || aWhat.ShapeType() == TopAbs_COMPSOLID) {
4826 TopoDS_Iterator It (aWhat, Standard_True, Standard_True);
4827 if (It.More()) aWhat = It.Value();
4830 SetErrorCode("Compounds of two or more shapes are not allowed for aWhat argument");
4835 switch (aWhat.ShapeType()) {
4836 case TopAbs_VERTEX: {
4837 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(aWhat));
4838 TopExp_Explorer E(aWhere, TopAbs_VERTEX);
4839 for(; E.More(); E.Next()) {
4840 if(!aMap.Add(E.Current())) continue;
4841 gp_Pnt P2 = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4842 if(P.Distance(P2) <= MAX_TOLERANCE) {
4844 aSubShape = E.Current();
4851 TopoDS_Edge anEdge = TopoDS::Edge(aWhat);
4852 TopExp_Explorer E(aWhere, TopAbs_EDGE);
4853 for(; E.More(); E.Next()) {
4854 if(!aMap.Add(E.Current())) continue;
4855 if(isSameEdge(anEdge, TopoDS::Edge(E.Current()))) {
4856 aSubShape = E.Current();
4864 TopoDS_Face aFace = TopoDS::Face(aWhat);
4865 TopExp_Explorer E(aWhere, TopAbs_FACE);
4866 for(; E.More(); E.Next()) {
4867 if(!aMap.Add(E.Current())) continue;
4868 if(isSameFace(aFace, TopoDS::Face(E.Current()))) {
4869 aSubShape = E.Current();
4876 case TopAbs_SOLID: {
4877 TopoDS_Solid aSolid = TopoDS::Solid(aWhat);
4878 TopExp_Explorer E(aWhere, TopAbs_SOLID);
4879 for(; E.More(); E.Next()) {
4880 if(!aMap.Add(E.Current())) continue;
4881 if(isSameSolid(aSolid, TopoDS::Solid(E.Current()))) {
4882 aSubShape = E.Current();
4894 TopTools_IndexedMapOfShape anIndices;
4895 TopExp::MapShapes(aWhere, anIndices);
4896 if (anIndices.Contains(aSubShape))
4897 anIndex = anIndices.FindIndex(aSubShape);
4900 if (anIndex < 0) return NULL;
4902 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
4904 anArray->SetValue(1, anIndex);
4906 Handle(GEOM_Object) aResult = GetEngine()->AddSubShape(theShapeWhere, anArray);
4907 Handle(GEOM_Function) aFunction = aResult->GetLastFunction();
4909 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetSame("
4910 << theShapeWhere << ", " << theShapeWhat << ")";
4918 //=======================================================================
4919 //function : GetSameIDs
4921 //=======================================================================
4922 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetSameIDs
4923 (const Handle(GEOM_Object)& theShapeWhere,
4924 const Handle(GEOM_Object)& theShapeWhat)
4927 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
4929 TopoDS_Shape aWhere = theShapeWhere->GetValue();
4930 TopoDS_Shape aWhat = theShapeWhat->GetValue();
4932 if (aWhere.IsNull() || aWhat.IsNull()) return NULL;
4934 TopTools_ListOfShape listShape;
4935 TopTools_MapOfShape aMap;
4937 if (aWhat.ShapeType() == TopAbs_COMPOUND || aWhat.ShapeType() == TopAbs_COMPSOLID) {
4938 TopoDS_Iterator It (aWhat, Standard_True, Standard_True);
4939 if (It.More()) aWhat = It.Value();
4942 SetErrorCode("Compounds of two or more shapes are not allowed for aWhat argument");
4947 switch (aWhat.ShapeType()) {
4948 case TopAbs_VERTEX: {
4949 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(aWhat));
4950 TopExp_Explorer E(aWhere, TopAbs_VERTEX);
4951 for(; E.More(); E.Next()) {
4952 if(!aMap.Add(E.Current())) continue;
4953 gp_Pnt P2 = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4954 if(P.Distance(P2) <= MAX_TOLERANCE) {
4955 listShape.Append(E.Current());
4961 TopoDS_Edge anEdge = TopoDS::Edge(aWhat);
4962 TopExp_Explorer E(aWhere, TopAbs_EDGE);
4963 for(; E.More(); E.Next()) {
4964 if(!aMap.Add(E.Current())) continue;
4965 if(isSameEdge(anEdge, TopoDS::Edge(E.Current()))) {
4966 listShape.Append(E.Current());
4972 TopoDS_Face aFace = TopoDS::Face(aWhat);
4973 TopExp_Explorer E(aWhere, TopAbs_FACE);
4974 for(; E.More(); E.Next()) {
4975 if(!aMap.Add(E.Current())) continue;
4976 if(isSameFace(aFace, TopoDS::Face(E.Current()))) {
4977 listShape.Append(E.Current());
4982 case TopAbs_SOLID: {
4983 TopoDS_Solid aSolid = TopoDS::Solid(aWhat);
4984 TopExp_Explorer E(aWhere, TopAbs_SOLID);
4985 for(; E.More(); E.Next()) {
4986 if(!aMap.Add(E.Current())) continue;
4987 if(isSameSolid(aSolid, TopoDS::Solid(E.Current()))) {
4988 listShape.Append(E.Current());
4997 if ( !listShape.IsEmpty() ) {
4998 TopTools_IndexedMapOfShape anIndices;
4999 TopExp::MapShapes(aWhere, anIndices);
5000 TopTools_ListIteratorOfListOfShape itSub (listShape);
5001 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
5002 for (; itSub.More(); itSub.Next()) {
5003 if (anIndices.Contains(itSub.Value()))
5004 aSeq->Append(anIndices.FindIndex(itSub.Value()));
5007 // The GetSameIDs() doesn't change object so no new function is required.
5008 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShapeWhere,theShapeWhat)->GetLastFunction();
5010 // Make a Python command
5011 GEOM::TPythonDump(aFunction)
5012 << "listSameIDs = geompy.GetSameIDs("
5013 << theShapeWhere << ", "
5014 << theShapeWhat << ")";
5017 SetErrorCode(NOT_FOUND_ANY);