1 // Copyright (C) 2007-2014 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, or (at your option) any later version.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 // File : GEOMImpl_IShapesOperations.cxx
25 // Author : modified by Lioka RAZAFINDRAZAKA (CEA) 22/06/2007
28 #include <Standard_Stream.hxx>
30 #include "GEOMImpl_IShapesOperations.hxx"
32 #include "GEOMImpl_Types.hxx"
34 #include "GEOMImpl_VectorDriver.hxx"
35 #include "GEOMImpl_ShapeDriver.hxx"
36 #include "GEOMImpl_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 "GEOMUtils.hxx"
53 #include "GEOMAlgo_ClsfBox.hxx"
54 #include "GEOMAlgo_ClsfSolid.hxx"
55 #include "GEOMAlgo_CoupleOfShapes.hxx"
56 #include "GEOMAlgo_FinderShapeOn1.hxx"
57 #include "GEOMAlgo_FinderShapeOnQuad.hxx"
58 #include "GEOMAlgo_FinderShapeOn2.hxx"
59 #include "GEOMAlgo_GetInPlace.hxx"
60 #include "GEOMAlgo_GlueDetector.hxx"
61 #include "GEOMAlgo_ListIteratorOfListOfCoupleOfShapes.hxx"
62 #include "GEOMAlgo_ListOfCoupleOfShapes.hxx"
64 #include <Basics_OCCTVersion.hxx>
66 #include <utilities.h>
68 #include <Utils_ExceptHandlers.hxx>
70 #include <TFunction_DriverTable.hxx>
71 #include <TFunction_Driver.hxx>
72 #include <TFunction_Logbook.hxx>
73 #include <TDataStd_Integer.hxx>
74 #include <TDataStd_IntegerArray.hxx>
75 #include <TDataStd_ListIteratorOfListOfExtendedString.hxx>
76 #include <TDF_Tool.hxx>
78 #include <BRepExtrema_ExtCF.hxx>
79 #include <BRepExtrema_DistShapeShape.hxx>
81 #include <BRep_Tool.hxx>
82 #include <BRep_Builder.hxx>
83 #include <BRepTools.hxx>
84 #include <BRepGProp.hxx>
85 #include <BRepAdaptor_Curve.hxx>
86 #include <BRepAdaptor_Surface.hxx>
87 #include <BRepBndLib.hxx>
88 #include <BRepMesh_IncrementalMesh.hxx>
92 #include <TopExp_Explorer.hxx>
93 #include <TopLoc_Location.hxx>
95 #include <TopoDS_Shape.hxx>
96 #include <TopoDS_Solid.hxx>
97 #include <TopoDS_Face.hxx>
98 #include <TopoDS_Edge.hxx>
99 #include <TopoDS_Vertex.hxx>
100 #include <TopoDS_Compound.hxx>
101 #include <TopoDS_Iterator.hxx>
102 #include <TopTools_Array1OfShape.hxx>
103 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
104 #include <TopTools_IndexedMapOfShape.hxx>
105 #include <TopTools_ListIteratorOfListOfShape.hxx>
106 #include <TopTools_MapOfShape.hxx>
107 #include <TopTools_MapOfOrientedShape.hxx>
109 #include <Geom_Surface.hxx>
110 #include <Geom_Plane.hxx>
111 #include <Geom_SphericalSurface.hxx>
112 #include <Geom_CylindricalSurface.hxx>
113 #include <GeomAdaptor_Surface.hxx>
115 #include <GeomLib_Tool.hxx>
116 #include <Geom2d_Curve.hxx>
118 #include <Bnd_Box.hxx>
119 #include <GProp_GProps.hxx>
120 #include <TColStd_Array1OfReal.hxx>
121 #include <TColStd_HArray1OfInteger.hxx>
122 #include <TColStd_ListIteratorOfListOfInteger.hxx>
123 #include <TColStd_ListOfInteger.hxx>
124 #include <gp_Cylinder.hxx>
125 #include <gp_Lin.hxx>
126 #include <gp_Pnt.hxx>
130 #include <functional>
132 #include <Standard_NullObject.hxx>
133 #include <Standard_Failure.hxx>
134 #include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
136 // Includes added for GetInPlace algorithm improvement
138 #include <GEOMImpl_MeasureDriver.hxx>
139 #include <GEOMImpl_IMeasure.hxx>
140 #include <BRepBuilderAPI_MakeVertex.hxx>
142 #include <BRepClass_FaceClassifier.hxx>
143 #include <BRepClass3d_SolidClassifier.hxx>
144 #include <Precision.hxx>
148 const double MAX_TOLERANCE = 1.e-7;
151 * \brief Returns the vertex from theWhere shape that is coincident with
154 * \param theWhere the shape where the coinsident vertex is searched.
155 * \param theVertex the vertex to be searched.
156 * \return the coincident vertex if it is found. Otherwise null object.
158 static TopoDS_Vertex getSameVertex(const TopoDS_Shape &theWhere,
159 const TopoDS_Vertex &theVertex)
161 TopoDS_Vertex aResult;
162 gp_Pnt aPoint = BRep_Tool::Pnt(theVertex);
163 TopExp_Explorer anExp(theWhere, TopAbs_VERTEX);
164 TopTools_MapOfShape aMap;
166 for(; anExp.More(); anExp.Next()) {
167 const TopoDS_Shape &aLocalShape = anExp.Current();
169 if(!aMap.Add(aLocalShape)) {
173 TopoDS_Vertex aVertex = TopoDS::Vertex(aLocalShape);
174 gp_Pnt aPoint2 = BRep_Tool::Pnt(aVertex);
176 if(aPoint.Distance(aPoint2) <= MAX_TOLERANCE) {
184 } // end of namespace
186 //=============================================================================
190 //=============================================================================
191 GEOMImpl_IShapesOperations::GEOMImpl_IShapesOperations (GEOM_Engine* theEngine, int theDocID)
192 : GEOM_IOperations(theEngine, theDocID)
194 MESSAGE("GEOMImpl_IShapesOperations::GEOMImpl_IShapesOperations");
197 //=============================================================================
201 //=============================================================================
202 GEOMImpl_IShapesOperations::~GEOMImpl_IShapesOperations()
204 MESSAGE("GEOMImpl_IShapesOperations::~GEOMImpl_IShapesOperations");
207 //=============================================================================
211 //=============================================================================
212 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeEdge
213 (Handle(GEOM_Object) thePnt1, Handle(GEOM_Object) thePnt2)
217 if (thePnt1.IsNull() || thePnt2.IsNull()) return NULL;
219 //Add a new Edge object
220 Handle(GEOM_Object) anEdge = GetEngine()->AddObject(GetDocID(), GEOM_EDGE);
222 //Add a new Vector function
223 Handle(GEOM_Function) aFunction =
224 anEdge->AddFunction(GEOMImpl_VectorDriver::GetID(), VECTOR_TWO_PNT);
226 //Check if the function is set correctly
227 if (aFunction->GetDriverGUID() != GEOMImpl_VectorDriver::GetID()) return NULL;
229 GEOMImpl_IVector aPI (aFunction);
231 Handle(GEOM_Function) aRef1 = thePnt1->GetLastFunction();
232 Handle(GEOM_Function) aRef2 = thePnt2->GetLastFunction();
233 if (aRef1.IsNull() || aRef2.IsNull()) return NULL;
235 aPI.SetPoint1(aRef1);
236 aPI.SetPoint2(aRef2);
238 //Compute the Edge value
241 if (!GetSolver()->ComputeFunction(aFunction)) {
242 SetErrorCode("Vector driver failed");
246 catch (Standard_Failure) {
247 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
248 SetErrorCode(aFail->GetMessageString());
252 //Make a Python command
253 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdge("
254 << thePnt1 << ", " << thePnt2 << ")";
260 //=============================================================================
262 * MakeEdgeOnCurveByLength
264 //=============================================================================
265 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeEdgeOnCurveByLength
266 (Handle(GEOM_Object) theRefCurve,
267 const Standard_Real theLength,
268 Handle(GEOM_Object) theStartPoint)
272 if (theRefCurve.IsNull()) return NULL;
274 //Add a new Edge object
275 Handle(GEOM_Object) anEdge = GetEngine()->AddObject(GetDocID(), GEOM_EDGE);
277 //Add a new Vector function
278 Handle(GEOM_Function) aFunction =
279 anEdge->AddFunction(GEOMImpl_ShapeDriver::GetID(), EDGE_CURVE_LENGTH);
281 //Check if the function is set correctly
282 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
284 GEOMImpl_IVector aPI (aFunction);
286 Handle(GEOM_Function) aRef1 = theRefCurve->GetLastFunction();
287 if (aRef1.IsNull()) return NULL;
288 aPI.SetPoint1(aRef1);
290 if (!theStartPoint.IsNull()) {
291 Handle(GEOM_Function) aRef2 = theStartPoint->GetLastFunction();
292 aPI.SetPoint2(aRef2);
295 aPI.SetParameter(theLength);
297 //Compute the Edge value
300 if (!GetSolver()->ComputeFunction(aFunction)) {
301 SetErrorCode("Vector driver failed");
305 catch (Standard_Failure) {
306 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
307 SetErrorCode(aFail->GetMessageString());
311 //Make a Python command
312 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdgeOnCurveByLength("
313 << theRefCurve << ", " << theLength << ", " << theStartPoint << ")";
319 //=============================================================================
323 //=============================================================================
324 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeEdgeWire
325 (Handle(GEOM_Object) theWire,
326 const Standard_Real theLinearTolerance,
327 const Standard_Real theAngularTolerance)
331 if (theWire.IsNull()) return NULL;
333 //Add a new Edge object
334 Handle(GEOM_Object) anEdge = GetEngine()->AddObject(GetDocID(), GEOM_EDGE);
336 //Add a new Vector function
337 Handle(GEOM_Function) aFunction =
338 anEdge->AddFunction(GEOMImpl_ShapeDriver::GetID(), EDGE_WIRE);
340 //Check if the function is set correctly
341 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
343 GEOMImpl_IShapes aCI (aFunction);
345 Handle(GEOM_Function) aWire = theWire->GetLastFunction();
347 if (aWire.IsNull()) return NULL;
350 aCI.SetTolerance(theLinearTolerance);
351 aCI.SetAngularTolerance(theAngularTolerance);
353 //Compute the Edge value
356 if (!GetSolver()->ComputeFunction(aFunction)) {
357 SetErrorCode("Shape driver failed");
361 catch (Standard_Failure) {
362 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
363 SetErrorCode(aFail->GetMessageString());
367 const double DEF_LIN_TOL = Precision::Confusion();
368 const double DEF_ANG_TOL = Precision::Angular();
369 //Make a Python command
370 if ( theAngularTolerance == DEF_ANG_TOL ) {
371 if ( theLinearTolerance == DEF_LIN_TOL )
372 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdgeWire("
375 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdgeWire("
376 << theWire << ", " << theLinearTolerance << ")";
379 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdgeWire("
380 << theWire << ", " << theLinearTolerance << ", "
381 << theAngularTolerance << ")";
388 //=============================================================================
392 //=============================================================================
393 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeWire
394 (std::list<Handle(GEOM_Object)> theShapes,
395 const Standard_Real theTolerance)
400 Handle(GEOM_Object) aWire = GetEngine()->AddObject(GetDocID(), GEOM_WIRE);
403 Handle(GEOM_Function) aFunction =
404 aWire->AddFunction(GEOMImpl_ShapeDriver::GetID(), WIRE_EDGES);
405 if (aFunction.IsNull()) return NULL;
407 //Check if the function is set correctly
408 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
410 GEOMImpl_IShapes aCI (aFunction);
411 aCI.SetTolerance(theTolerance);
413 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
416 std::list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
417 for (; it != theShapes.end(); it++) {
418 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
419 if (aRefSh.IsNull()) {
420 SetErrorCode("NULL argument shape for the shape construction");
423 aShapesSeq->Append(aRefSh);
425 aCI.SetShapes(aShapesSeq);
430 if (!GetSolver()->ComputeFunction(aFunction)) {
431 SetErrorCode("Shape driver failed");
435 catch (Standard_Failure) {
436 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
437 SetErrorCode(aFail->GetMessageString());
441 //Make a Python command
442 GEOM::TPythonDump pd (aFunction);
443 pd << aWire << " = geompy.MakeWire([";
446 it = theShapes.begin();
447 if (it != theShapes.end()) {
449 while (it != theShapes.end()) {
450 pd << ", " << (*it++);
453 pd << "], " << theTolerance << ")";
459 //=============================================================================
463 //=============================================================================
464 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFace (Handle(GEOM_Object) theWire,
465 const bool isPlanarWanted)
469 if (theWire.IsNull()) return NULL;
471 //Add a new Face object
472 Handle(GEOM_Object) aFace = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
474 //Add a new Shape function for creation of a face from a wire
475 Handle(GEOM_Function) aFunction =
476 aFace->AddFunction(GEOMImpl_ShapeDriver::GetID(), FACE_WIRE);
477 if (aFunction.IsNull()) return NULL;
479 //Check if the function is set correctly
480 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
482 GEOMImpl_IShapes aCI (aFunction);
484 Handle(GEOM_Function) aRefWire = theWire->GetLastFunction();
486 if (aRefWire.IsNull()) return NULL;
488 aCI.SetBase(aRefWire);
489 aCI.SetIsPlanar(isPlanarWanted);
491 //Compute the Face value
492 Standard_Boolean isWarning = Standard_False;
495 if (!GetSolver()->ComputeFunction(aFunction)) {
496 SetErrorCode("Shape driver failed to compute a face");
500 catch (Standard_Failure) {
501 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
502 SetErrorCode(aFail->GetMessageString());
503 // to provide warning
504 if (!aFunction->GetValue().IsNull()) {
505 isWarning = Standard_True;
511 //Make a Python command
512 GEOM::TPythonDump(aFunction) << aFace << " = geompy.MakeFace("
513 << theWire << ", " << (int)isPlanarWanted << ")";
515 // to provide warning
516 if (!isWarning) SetErrorCode(OK);
520 //=============================================================================
524 //=============================================================================
525 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFaceWires
526 (std::list<Handle(GEOM_Object)> theShapes,
527 const bool isPlanarWanted)
532 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
535 Handle(GEOM_Function) aFunction =
536 aShape->AddFunction(GEOMImpl_ShapeDriver::GetID(), FACE_WIRES);
537 if (aFunction.IsNull()) return NULL;
539 //Check if the function is set correctly
540 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
542 GEOMImpl_IShapes aCI (aFunction);
544 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
547 std::list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
548 for (; it != theShapes.end(); it++) {
549 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
550 if (aRefSh.IsNull()) {
551 SetErrorCode("NULL argument shape for the face construction");
554 aShapesSeq->Append(aRefSh);
556 aCI.SetShapes(aShapesSeq);
558 aCI.SetIsPlanar(isPlanarWanted);
561 Standard_Boolean isWarning = Standard_False;
564 if (!GetSolver()->ComputeFunction(aFunction)) {
565 SetErrorCode("Shape driver failed");
569 catch (Standard_Failure) {
570 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
571 SetErrorCode(aFail->GetMessageString());
572 // to provide warning
573 if (!aFunction->GetValue().IsNull()) {
574 isWarning = Standard_True;
580 //Make a Python command
581 GEOM::TPythonDump pd (aFunction);
582 pd << aShape << " = geompy.MakeFaceWires([";
585 it = theShapes.begin();
586 if (it != theShapes.end()) {
588 while (it != theShapes.end()) {
589 pd << ", " << (*it++);
592 pd << "], " << (int)isPlanarWanted << ")";
594 // to provide warning
595 if (!isWarning) SetErrorCode(OK);
599 //=============================================================================
603 //=============================================================================
604 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeShell
605 (std::list<Handle(GEOM_Object)> theShapes)
607 return MakeShape(theShapes, GEOM_SHELL, SHELL_FACES, "MakeShell");
610 //=============================================================================
614 //=============================================================================
615 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeSolidShells
616 (std::list<Handle(GEOM_Object)> theShapes)
618 return MakeShape(theShapes, GEOM_SOLID, SOLID_SHELLS, "MakeSolid");
621 //=============================================================================
625 //=============================================================================
626 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeCompound
627 (std::list<Handle(GEOM_Object)> theShapes)
629 return MakeShape(theShapes, GEOM_COMPOUND, COMPOUND_SHAPES, "MakeCompound");
632 //=============================================================================
636 //=============================================================================
637 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeShape
638 (std::list<Handle(GEOM_Object)> theShapes,
639 const Standard_Integer theObjectType,
640 const Standard_Integer theFunctionType,
641 const TCollection_AsciiString& theMethodName)
646 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), theObjectType);
649 Handle(GEOM_Function) aFunction =
650 aShape->AddFunction(GEOMImpl_ShapeDriver::GetID(), theFunctionType);
651 if (aFunction.IsNull()) return NULL;
653 //Check if the function is set correctly
654 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
656 GEOMImpl_IShapes aCI (aFunction);
658 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
661 std::list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
662 for (; it != theShapes.end(); it++) {
663 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
664 if (aRefSh.IsNull()) {
665 SetErrorCode("NULL argument shape for the shape construction");
668 aShapesSeq->Append(aRefSh);
670 aCI.SetShapes(aShapesSeq);
675 if (!GetSolver()->ComputeFunction(aFunction)) {
676 SetErrorCode("Shape driver failed");
680 catch (Standard_Failure) {
681 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
682 SetErrorCode(aFail->GetMessageString());
686 //Make a Python command
687 GEOM::TPythonDump pd (aFunction);
688 pd << aShape << " = geompy." << theMethodName.ToCString() << "([";
691 it = theShapes.begin();
692 if (it != theShapes.end()) {
694 while (it != theShapes.end()) {
695 pd << ", " << (*it++);
704 //=============================================================================
708 //=============================================================================
709 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeGlueFaces
710 (Handle(GEOM_Object) theShape,
711 const Standard_Real theTolerance,
712 const Standard_Boolean doKeepNonSolids)
716 if (theShape.IsNull()) return NULL;
718 //Add a new Glued object
719 Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
721 //Add a new Glue function
722 Handle(GEOM_Function) aFunction;
723 aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_FACES);
724 if (aFunction.IsNull()) return NULL;
726 //Check if the function is set correctly
727 if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
729 GEOMImpl_IGlue aCI (aFunction);
731 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
732 if (aRefShape.IsNull()) return NULL;
734 aCI.SetBase(aRefShape);
735 aCI.SetTolerance(theTolerance);
736 aCI.SetKeepNonSolids(doKeepNonSolids);
738 //Compute the sub-shape value
739 Standard_Boolean isWarning = Standard_False;
742 if (!GetSolver()->ComputeFunction(aFunction)) {
743 SetErrorCode("Shape driver failed to glue faces");
747 catch (Standard_Failure) {
748 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
749 SetErrorCode(aFail->GetMessageString());
750 // to provide warning
751 if (!aFunction->GetValue().IsNull()) {
752 isWarning = Standard_True;
758 //Make a Python command
759 GEOM::TPythonDump(aFunction) << aGlued << " = geompy.MakeGlueFaces("
760 << theShape << ", " << theTolerance << ")";
762 // to provide warning
763 if (!isWarning) SetErrorCode(OK);
767 //=============================================================================
771 //=============================================================================
773 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetGlueFaces
774 (Handle(GEOM_Object) theShape,
775 const Standard_Real theTolerance)
779 if (theShape.IsNull()) return NULL;
780 TopoDS_Shape aShape = theShape->GetValue();
781 if (aShape.IsNull()) return NULL;
783 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
785 Standard_Integer iErr;
787 GEOMAlgo_Gluer1 aGluer;
788 GEOMAlgo_ListIteratorOfListOfCoupleOfShapes aItCS;
789 GEOMAlgo_CoupleOfShapes aCS;
790 GEOMAlgo_ListOfCoupleOfShapes aLCS;
792 //aGluer = new GEOMAlgo_Gluer1;
793 aGluer.SetShape(aShape);
794 aGluer.SetTolerance(theTolerance);
796 iErr = aGluer.ErrorStatus();
797 if (iErr) return NULL;
799 TopTools_ListOfShape listShape;
800 const GEOMAlgo_ListOfCoupleOfShapes& aLCSG = aGluer.GluedFaces();
802 aItCS.Initialize(aLCSG);
803 for (; aItCS.More(); aItCS.Next()) {
804 const GEOMAlgo_CoupleOfShapes& aCSG = aItCS.Value();
805 listShape.Append(aCSG.Shape1());
808 TopTools_ListIteratorOfListOfShape itSub (listShape);
809 TCollection_AsciiString anAsciiList, anEntry;
810 TopTools_IndexedMapOfShape anIndices;
811 TopExp::MapShapes(aShape, anIndices);
812 Handle(TColStd_HArray1OfInteger) anArray;
813 Handle(GEOM_Object) anObj;
814 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
815 TopoDS_Shape aValue = itSub.Value();
816 anArray = new TColStd_HArray1OfInteger(1,1);
817 anArray->SetValue(1, anIndices.FindIndex(aValue));
818 anObj = GetEngine()->AddSubShape(theShape, anArray);
819 if (!anObj.IsNull()) {
822 // for python command
823 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
824 anAsciiList += anEntry;
829 //Make a Python command
830 if( anAsciiList.Length() > 0 ) {
831 anAsciiList.Trunc(anAsciiList.Length() - 1);
832 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
833 GEOM::TPythonDump pd (aFunction, true);
834 pd << "[" << anAsciiList.ToCString();
835 pd << "] = geompy.GetGlueFaces(" << theShape << ", " << theTolerance << ")";
844 //=============================================================================
846 * MakeGlueFacesByList
848 //=============================================================================
849 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeGlueFacesByList
850 (Handle(GEOM_Object) theShape,
851 const Standard_Real theTolerance,
852 std::list<Handle(GEOM_Object)> theFaces,
853 const Standard_Boolean doKeepNonSolids,
854 const Standard_Boolean doGlueAllEdges)
858 if (theShape.IsNull()) return NULL;
860 //Add a new Glued object
861 Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
863 //Add a new Glue function
864 Handle(GEOM_Function) aFunction;
865 aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_FACES_BY_LIST);
866 if (aFunction.IsNull()) return NULL;
868 //Check if the function is set correctly
869 if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
871 GEOMImpl_IGlue aCI (aFunction);
873 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
874 if (aRefShape.IsNull()) return NULL;
876 aCI.SetBase(aRefShape);
877 aCI.SetTolerance(theTolerance);
878 aCI.SetKeepNonSolids(doKeepNonSolids);
879 aCI.SetGlueAllEdges(doGlueAllEdges);
881 Handle(TColStd_HSequenceOfTransient) aFaces = new TColStd_HSequenceOfTransient;
882 std::list<Handle(GEOM_Object)>::iterator it = theFaces.begin();
883 for (; it != theFaces.end(); it++) {
884 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
885 if (aRefSh.IsNull()) {
886 SetErrorCode("NULL argument shape for the shape construction");
889 aFaces->Append(aRefSh);
891 aCI.SetFaces(aFaces);
893 //Compute the sub-shape value
894 Standard_Boolean isWarning = Standard_False;
897 if (!GetSolver()->ComputeFunction(aFunction)) {
898 SetErrorCode("Shape driver failed to glue faces");
902 catch (Standard_Failure) {
903 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
904 SetErrorCode(aFail->GetMessageString());
905 // to provide warning
906 if (!aFunction->GetValue().IsNull()) {
907 isWarning = Standard_True;
913 //Make a Python command
915 GEOM::TPythonDump pd(aFunction);
916 pd << aGlued << " = geompy.MakeGlueFacesByList("
917 << theShape << ", " << theTolerance << ", [";
919 it = theFaces.begin();
920 if (it != theFaces.end()) {
922 while (it != theFaces.end()) {
923 pd << ", " << (*it++);
926 pd << "], " << (bool)doKeepNonSolids << ", " << (bool)doGlueAllEdges << ")";
928 // to provide warning
929 if (!isWarning) SetErrorCode(OK);
933 //=============================================================================
937 //=============================================================================
938 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeGlueEdges
939 (Handle(GEOM_Object) theShape,
940 const Standard_Real theTolerance)
944 if (theShape.IsNull()) return NULL;
946 //Add a new Glued object
947 Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
949 //Add a new Glue function
950 Handle(GEOM_Function) aFunction;
951 aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_EDGES);
952 if (aFunction.IsNull()) return NULL;
954 //Check if the function is set correctly
955 if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
957 GEOMImpl_IGlue aCI (aFunction);
959 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
960 if (aRefShape.IsNull()) return NULL;
962 aCI.SetBase(aRefShape);
963 aCI.SetTolerance(theTolerance);
964 aCI.SetKeepNonSolids(true);
966 //Compute the sub-shape value
967 Standard_Boolean isWarning = Standard_False;
970 if (!GetSolver()->ComputeFunction(aFunction)) {
971 SetErrorCode("Shape driver failed to glue edges");
975 catch (Standard_Failure) {
976 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
977 SetErrorCode(aFail->GetMessageString());
978 // to provide warning
979 if (!aFunction->GetValue().IsNull()) {
980 isWarning = Standard_True;
986 //Make a Python command
987 GEOM::TPythonDump(aFunction) << aGlued << " = geompy.MakeGlueEdges("
988 << theShape << ", " << theTolerance << ")";
990 // to provide warning
991 if (!isWarning) SetErrorCode(OK);
995 //=============================================================================
999 //=============================================================================
1000 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetGlueShapes
1001 (Handle(GEOM_Object) theShape,
1002 const Standard_Real theTolerance,
1003 const TopAbs_ShapeEnum theType)
1007 if (theShape.IsNull()) return NULL;
1008 TopoDS_Shape aShape = theShape->GetValue();
1009 if (aShape.IsNull()) return NULL;
1011 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1013 GEOMAlgo_GlueDetector aGluer;
1014 aGluer.SetArgument(aShape);
1015 aGluer.SetTolerance(theTolerance);
1017 Standard_Integer iErr = aGluer.ErrorStatus();
1018 if (iErr) return NULL;
1020 TCollection_AsciiString anAsciiList, anEntry;
1021 TopTools_IndexedMapOfShape anIndices;
1022 TopExp::MapShapes(aShape, anIndices);
1023 Handle(TColStd_HArray1OfInteger) anArray;
1024 Handle(GEOM_Object) anObj;
1026 TopTools_ListOfShape listOnePerSet;
1028 const TopTools_DataMapOfShapeListOfShape& aImages = aGluer.Images();
1029 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape aItDMSLS (aImages);
1030 for (int index = 1; aItDMSLS.More(); aItDMSLS.Next(), ++index) {
1032 //const TopoDS_Shape& aSkey = aItDMSLS.Key();
1034 // list of shapes of the argument that can be glued
1035 const TopTools_ListOfShape& aLSD = aItDMSLS.Value();
1037 //listShape.Append(aLSD.First());
1038 TopoDS_Shape aValue = aLSD.First();
1040 if (aValue.ShapeType() == theType) {
1041 listOnePerSet.Append(aValue);
1045 // for stable order of returned entities
1046 GEOMUtils::SortShapes(listOnePerSet, Standard_False);
1048 TopTools_ListIteratorOfListOfShape aListIt (listOnePerSet);
1049 for (; aListIt.More(); aListIt.Next()) {
1050 TopoDS_Shape aValue = aListIt.Value();
1051 anArray = new TColStd_HArray1OfInteger(1,1);
1052 anArray->SetValue(1, anIndices.FindIndex(aValue));
1053 anObj = GetEngine()->AddSubShape(theShape, anArray);
1054 if (!anObj.IsNull()) {
1055 aSeq->Append(anObj);
1057 // for python command
1058 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
1059 anAsciiList += anEntry;
1064 // Make a Python command
1065 if (anAsciiList.Length() > 0) {
1066 anAsciiList.Trunc(anAsciiList.Length() - 1);
1067 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
1068 GEOM::TPythonDump pd (aFunction, /*append=*/true);
1069 pd << "[" << anAsciiList.ToCString();
1070 if (theType == TopAbs_FACE)
1071 pd << "] = geompy.GetGlueFaces(" << theShape << ", " << theTolerance << ")";
1072 else if (theType == TopAbs_EDGE)
1073 pd << "] = geompy.GetGlueEdges(" << theShape << ", " << theTolerance << ")";
1081 //=============================================================================
1083 * MakeGlueEdgesByList
1085 //=============================================================================
1086 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeGlueEdgesByList
1087 (Handle(GEOM_Object) theShape,
1088 const Standard_Real theTolerance,
1089 std::list<Handle(GEOM_Object)> theEdges)
1093 if (theShape.IsNull()) return NULL;
1095 //Add a new Glued object
1096 Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
1098 //Add a new Glue function
1099 Handle(GEOM_Function) aFunction;
1100 aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_EDGES_BY_LIST);
1101 if (aFunction.IsNull()) return NULL;
1103 //Check if the function is set correctly
1104 if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
1106 GEOMImpl_IGlue aCI (aFunction);
1108 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
1109 if (aRefShape.IsNull()) return NULL;
1111 aCI.SetBase(aRefShape);
1112 aCI.SetTolerance(theTolerance);
1113 aCI.SetKeepNonSolids(true);
1115 Handle(TColStd_HSequenceOfTransient) anEdges = new TColStd_HSequenceOfTransient;
1116 std::list<Handle(GEOM_Object)>::iterator it = theEdges.begin();
1117 for (; it != theEdges.end(); it++) {
1118 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
1119 if (aRefSh.IsNull()) {
1120 SetErrorCode("NULL argument shape for the shape construction");
1123 anEdges->Append(aRefSh);
1125 aCI.SetFaces(anEdges);
1127 //Compute the sub-shape value
1128 Standard_Boolean isWarning = Standard_False;
1131 if (!GetSolver()->ComputeFunction(aFunction)) {
1132 SetErrorCode("Shape driver failed to glue edges");
1136 catch (Standard_Failure) {
1137 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1138 SetErrorCode(aFail->GetMessageString());
1139 // to provide warning
1140 if (!aFunction->GetValue().IsNull()) {
1141 isWarning = Standard_True;
1147 //Make a Python command
1149 GEOM::TPythonDump pd (aFunction);
1150 pd << aGlued << " = geompy.MakeGlueEdgesByList("
1151 << theShape << ", " << theTolerance << ", [";
1153 it = theEdges.begin();
1154 if (it != theEdges.end()) {
1156 while (it != theEdges.end()) {
1157 pd << ", " << (*it++);
1162 // to provide warning
1163 if (!isWarning) SetErrorCode(OK);
1167 //=============================================================================
1169 * GetExistingSubObjects
1171 //=============================================================================
1172 Handle(TColStd_HSequenceOfTransient)
1173 GEOMImpl_IShapesOperations::GetExistingSubObjects(Handle(GEOM_Object) theShape,
1174 const Standard_Boolean theGroupsOnly)
1176 // note: this method does not return fields
1178 Standard_Integer types = theGroupsOnly ? Groups : Groups|SubShapes;
1179 Handle(TColStd_HSequenceOfTransient) results = GetExistingSubObjects(theShape, types);
1181 if (results->Length() > 0) {
1182 //Make a Python command
1183 TCollection_AsciiString anAsciiList;
1184 for (int i = 1; i <= results->Length(); i++)
1186 Handle(GEOM_BaseObject) obj = Handle(GEOM_BaseObject)::DownCast( results->Value(i));
1187 obj->GetEntryString();
1188 if ( i < results->Length() )
1192 GEOM::TPythonDump pd (theShape->GetLastFunction(), /*append=*/true);
1193 pd << "[" << anAsciiList.ToCString();
1194 pd << "] = geompy.GetExistingSubObjects(";
1195 pd << theShape << ", " << (bool)theGroupsOnly << ")";
1201 Handle(TColStd_HSequenceOfTransient)
1202 GEOMImpl_IShapesOperations::GetExistingSubObjects(Handle(GEOM_Object) theShape,
1203 const Standard_Integer theTypes)
1207 if (theShape.IsNull()) return NULL;
1209 Handle(GEOM_Function) aMainShape = theShape->GetLastFunction();
1210 if (aMainShape.IsNull()) return NULL;
1212 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1213 SetErrorCode(NOT_FOUND_ANY);
1215 if (!aMainShape->HasSubShapeReferences()) return aSeq;
1216 const TDataStd_ListOfExtendedString& aListEntries = aMainShape->GetSubShapeReferences();
1217 if (aListEntries.IsEmpty()) return aSeq;
1221 TDataStd_ListIteratorOfListOfExtendedString anIt (aListEntries);
1222 for (; anIt.More(); anIt.Next()) {
1223 TCollection_ExtendedString anEntry = anIt.Value();
1224 Standard_Integer aStrLen = anEntry.LengthOfCString();
1225 char* anEntryStr = new char[aStrLen+1];
1226 anEntry.ToUTF8CString(anEntryStr);
1227 Handle(GEOM_BaseObject) anObj = GetEngine()->GetObject(GetDocID(), anEntryStr, false);
1228 if (!anObj.IsNull() ) {
1229 bool isGroup = anObj->IsKind(STANDARD_TYPE(GEOM_Object)) && anObj->GetType() == GEOM_GROUP;
1230 bool isSubShape = anObj->IsKind(STANDARD_TYPE(GEOM_Object)) && anObj->GetType() != GEOM_GROUP;
1231 bool isField = anObj->IsKind(STANDARD_TYPE(GEOM_Field));
1232 if (theTypes & Groups && isGroup ||
1233 theTypes & SubShapes && isSubShape ||
1234 theTypes & Fields && isField) {
1235 aSeq->Append(anObj);
1238 delete [] anEntryStr;
1241 if (aSeq->Length() == 0) {
1242 SetErrorCode(NOT_FOUND_ANY);
1251 //=============================================================================
1255 //=============================================================================
1256 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::MakeExplode
1257 (Handle(GEOM_Object) theShape,
1258 const Standard_Integer theShapeType,
1259 const Standard_Boolean isSorted,
1260 const ExplodeType theExplodeType)
1264 if (theShape.IsNull()) return NULL;
1265 TopoDS_Shape aShape = theShape->GetValue();
1266 if (aShape.IsNull()) return NULL;
1268 Handle(GEOM_Function) aMainShape = theShape->GetLastFunction();
1270 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1271 Handle(GEOM_Object) anObj;
1272 TopTools_MapOfShape mapShape;
1273 TopTools_ListOfShape listShape;
1275 if (aShape.ShapeType() == TopAbs_COMPOUND &&
1276 (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
1277 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPSOLID ||
1278 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPOUND))
1280 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
1281 for (; It.More(); It.Next()) {
1282 if (mapShape.Add(It.Value())) {
1283 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
1284 TopAbs_ShapeEnum(theShapeType) == It.Value().ShapeType()) {
1285 listShape.Append(It.Value());
1290 else if (theExplodeType != EXPLODE_NEW_EXCLUDE_MAIN || aShape.ShapeType() != theShapeType) // issue 0021079
1292 TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
1293 for (; exp.More(); exp.Next())
1294 if (mapShape.Add(exp.Current()))
1295 listShape.Append(exp.Current());
1298 if (listShape.IsEmpty()) {
1299 //SetErrorCode("The given shape has no sub-shapes of the requested type");
1300 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
1305 bool isOldSorting = false;
1306 if (theExplodeType == EXPLODE_OLD_INCLUDE_MAIN)
1307 isOldSorting = true;
1308 GEOMUtils::SortShapes(listShape, isOldSorting);
1311 TopTools_IndexedMapOfShape anIndices;
1312 TopExp::MapShapes(aShape, anIndices);
1313 Handle(TColStd_HArray1OfInteger) anArray;
1315 TopTools_ListIteratorOfListOfShape itSub (listShape);
1316 TCollection_AsciiString anAsciiList, anEntry;
1317 for (int index = 1; itSub.More(); itSub.Next(), ++index)
1319 TopoDS_Shape aValue = itSub.Value();
1320 anArray = new TColStd_HArray1OfInteger(1,1);
1321 anArray->SetValue(1, anIndices.FindIndex(aValue));
1323 //anObj = GetEngine()->AddSubShape(theShape, anArray);
1325 anObj = GetEngine()->AddObject(GetDocID(), GEOM_SUBSHAPE);
1326 Handle(GEOM_Function) aFunction = anObj->AddFunction(GEOM_Object::GetSubShapeID(), 1);
1327 if (aFunction.IsNull()) return aSeq;
1329 GEOM_ISubShape aSSI (aFunction);
1330 aSSI.SetMainShape(aMainShape);
1331 aSSI.SetIndices(anArray);
1333 // Set function value directly, as we know it.
1334 // Usage of Solver here would lead to significant loss of time,
1335 // because GEOM_SubShapeDriver will build TopTools_IndexedMapOfShape
1336 // on the main shape for each being calculated sub-shape separately.
1337 aFunction->SetValue(aValue);
1339 // Put this subshape in the list of sub-shapes of theMainShape
1340 aMainShape->AddSubShapeReference(aFunction);
1343 if (!anObj.IsNull()) {
1344 aSeq->Append(anObj);
1346 // for python command
1347 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
1348 anAsciiList += anEntry;
1353 //Make a Python command
1354 anAsciiList.Trunc(anAsciiList.Length() - 1);
1356 GEOM::TPythonDump pd (aMainShape, /*append=*/true);
1357 pd << "[" << anAsciiList.ToCString() << "] = geompy.";
1358 switch (theExplodeType) {
1359 case EXPLODE_NEW_EXCLUDE_MAIN:
1360 pd << "ExtractShapes(" << theShape << ", "
1361 << TopAbs_ShapeEnum(theShapeType) << ", " << (isSorted ? "True" : "False") << ")";
1363 case EXPLODE_NEW_INCLUDE_MAIN:
1364 pd << "SubShapeAll" << (isSorted ? "SortedCentres(" : "(")
1365 << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
1367 case EXPLODE_OLD_INCLUDE_MAIN:
1368 pd << "SubShapeAll" << (isSorted ? "Sorted(" : "(")
1369 << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
1378 //=============================================================================
1382 //=============================================================================
1383 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::SubShapeAllIDs
1384 (Handle(GEOM_Object) theShape,
1385 const Standard_Integer theShapeType,
1386 const Standard_Boolean isSorted,
1387 const ExplodeType theExplodeType)
1391 if (theShape.IsNull()) return NULL;
1392 TopoDS_Shape aShape = theShape->GetValue();
1393 if (aShape.IsNull()) return NULL;
1395 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
1396 TopTools_MapOfShape mapShape;
1397 TopTools_ListOfShape listShape;
1399 if (aShape.ShapeType() == TopAbs_COMPOUND &&
1400 (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
1401 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPSOLID ||
1402 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPOUND))
1404 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
1405 for (; It.More(); It.Next()) {
1406 if (mapShape.Add(It.Value())) {
1407 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
1408 TopAbs_ShapeEnum(theShapeType) == It.Value().ShapeType()) {
1409 listShape.Append(It.Value());
1414 else if (theExplodeType != EXPLODE_NEW_EXCLUDE_MAIN || aShape.ShapeType() != theShapeType) // issue 0021079
1416 TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
1417 for (; exp.More(); exp.Next())
1418 if (mapShape.Add(exp.Current()))
1419 listShape.Append(exp.Current());
1422 if (listShape.IsEmpty()) {
1423 //SetErrorCode("The given shape has no sub-shapes of the requested type");
1424 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
1429 bool isOldSorting = false;
1430 if (theExplodeType == EXPLODE_OLD_INCLUDE_MAIN)
1431 isOldSorting = true;
1432 GEOMUtils::SortShapes(listShape, isOldSorting);
1435 TopTools_IndexedMapOfShape anIndices;
1436 TopExp::MapShapes(aShape, anIndices);
1437 Handle(TColStd_HArray1OfInteger) anArray;
1439 TopTools_ListIteratorOfListOfShape itSub (listShape);
1440 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
1441 TopoDS_Shape aValue = itSub.Value();
1442 aSeq->Append(anIndices.FindIndex(aValue));
1445 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
1447 //Make a Python command
1448 GEOM::TPythonDump pd (aFunction, /*append=*/true);
1449 pd << "listSubShapeIDs = geompy.SubShapeAll";
1450 switch (theExplodeType) {
1451 case EXPLODE_NEW_EXCLUDE_MAIN:
1453 case EXPLODE_NEW_INCLUDE_MAIN:
1454 pd << (isSorted ? "SortedCentresIDs(" : "IDs(")
1455 << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
1457 case EXPLODE_OLD_INCLUDE_MAIN:
1458 pd << (isSorted ? "SortedIDs(" : "IDs(")
1459 << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
1468 //=============================================================================
1472 //=============================================================================
1473 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetSubShape
1474 (Handle(GEOM_Object) theMainShape,
1475 const Standard_Integer theID)
1479 if (theMainShape.IsNull()) return NULL;
1481 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
1482 anArray->SetValue(1, theID);
1483 Handle(GEOM_Object) anObj = GetEngine()->AddSubShape(theMainShape, anArray,true);
1484 if (anObj.IsNull()) {
1485 SetErrorCode("Can not get a sub-shape with the given ID");
1489 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1491 //Make a Python command
1492 GEOM::TPythonDump(aFunction) << anObj << " = geompy.GetSubShape("
1493 << theMainShape << ", [" << theID << "])";
1499 //=============================================================================
1503 //=============================================================================
1504 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::MakeSubShapes
1505 (Handle(GEOM_Object) theMainShape,
1506 Handle(TColStd_HArray1OfInteger) theIndices)
1510 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1512 if (!theIndices->Length()) {
1513 SetErrorCode(NOT_FOUND_ANY);
1517 if (theMainShape.IsNull()) return NULL;
1518 TopoDS_Shape aShape = theMainShape->GetValue();
1519 if (aShape.IsNull()) return NULL;
1521 Handle(GEOM_Function) aMainShape = theMainShape->GetLastFunction();
1523 TopTools_IndexedMapOfShape anIndices;
1524 TopExp::MapShapes(aShape, anIndices);
1526 Handle(TColStd_HArray1OfInteger) anArray;
1527 Handle(GEOM_Object) anObj;
1529 TCollection_AsciiString anAsciiList, anEntry;
1530 Standard_Integer i, low = theIndices->Lower(), up = theIndices->Upper();
1531 for (i = low; i <= up; i++) {
1532 int id = theIndices->Value(i);
1533 if (1 <= id && id <= anIndices.Extent()) {
1534 TopoDS_Shape aValue = anIndices.FindKey(id);
1535 anArray = new TColStd_HArray1OfInteger(1,1);
1536 anArray->SetValue(1, id);
1538 anObj = GetEngine()->AddObject(GetDocID(), GEOM_SUBSHAPE);
1539 if (!anObj.IsNull()) {
1540 Handle(GEOM_Function) aFunction = anObj->AddFunction(GEOM_Object::GetSubShapeID(), 1);
1541 if (aFunction.IsNull()) return aSeq;
1543 GEOM_ISubShape aSSI (aFunction);
1544 aSSI.SetMainShape(aMainShape);
1545 aSSI.SetIndices(anArray);
1547 // Set function value directly, as we know it.
1548 // Usage of Solver here would lead to significant loss of time,
1549 // because GEOM_SubShapeDriver will build TopTools_IndexedMapOfShape
1550 // on the main shape for each being calculated sub-shape separately.
1551 aFunction->SetValue(aValue);
1553 // Put this sub-shape in the list of sub-shapes of theMainShape
1554 aMainShape->AddSubShapeReference(aFunction);
1556 aSeq->Append(anObj);
1558 // for python command
1559 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
1560 anAsciiList += anEntry;
1566 //Make a Python command
1567 anAsciiList.Trunc(anAsciiList.Length() - 1);
1569 GEOM::TPythonDump pd (aMainShape, /*append=*/true);
1570 pd << "[" << anAsciiList.ToCString() << "] = geompy.SubShapes("
1571 << theMainShape << ", [" ;
1572 for (i = low; i <= up - 1; i++) {
1573 pd << theIndices->Value(i) << ", ";
1575 pd << theIndices->Value(up) << "])";
1582 //=============================================================================
1586 //=============================================================================
1587 Standard_Integer GEOMImpl_IShapesOperations::GetSubShapeIndex (Handle(GEOM_Object) theMainShape,
1588 Handle(GEOM_Object) theSubShape)
1592 TopoDS_Shape aMainShape = theMainShape->GetValue();
1593 TopoDS_Shape aSubShape = theSubShape->GetValue();
1595 if (aMainShape.IsNull() || aSubShape.IsNull()) return -1;
1597 TopTools_IndexedMapOfShape anIndices;
1598 TopExp::MapShapes(aMainShape, anIndices);
1599 // if (anIndices.Contains(aSubShape)) {
1600 // SetErrorCode(OK);
1601 // return anIndices.FindIndex(aSubShape);
1603 int id = anIndices.FindIndex(aSubShape);
1614 //=============================================================================
1616 * GetSubShapeIndices
1618 //=============================================================================
1619 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetSubShapesIndices (Handle(GEOM_Object) theMainShape,
1620 std::list<Handle(GEOM_Object)> theSubShapes)
1622 MESSAGE("GEOMImpl_IShapesOperations::GetSubShapesIndices")
1625 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
1627 TopoDS_Shape aMainShape = theMainShape->GetValue();
1628 if (aMainShape.IsNull())
1630 MESSAGE("NULL main shape")
1634 TopTools_IndexedMapOfShape anIndices;
1635 TopExp::MapShapes(aMainShape, anIndices);
1637 std::list<Handle(GEOM_Object)>::iterator it;
1638 for (it=theSubShapes.begin(); it != theSubShapes.end(); ++it)
1640 TopoDS_Shape aSubShape = (*it)->GetValue();
1641 if (aSubShape.IsNull())
1643 MESSAGE("NULL subshape")
1646 int id = anIndices.FindIndex(aSubShape);
1655 //=============================================================================
1659 //=============================================================================
1660 Standard_Integer GEOMImpl_IShapesOperations::GetTopologyIndex (Handle(GEOM_Object) theMainShape,
1661 Handle(GEOM_Object) theSubShape)
1665 TopoDS_Shape aMainShape = theMainShape->GetValue();
1666 TopoDS_Shape aSubShape = theSubShape->GetValue();
1668 if (aMainShape.IsNull() || aSubShape.IsNull()) {
1669 SetErrorCode("Null argument shape given");
1674 if (aSubShape.ShapeType() == TopAbs_COMPOUND) {
1676 TopTools_ListOfShape CL;
1677 CL.Append(aMainShape);
1678 TopTools_ListIteratorOfListOfShape itC;
1679 for (itC.Initialize(CL); itC.More(); itC.Next()) {
1680 for (it.Initialize(itC.Value()); it.More(); it.Next()) {
1681 if (it.Value().ShapeType() == TopAbs_COMPOUND) {
1682 if (it.Value().IsSame(aSubShape))
1686 CL.Append(it.Value());
1691 TopExp_Explorer anExp (aMainShape, aSubShape.ShapeType());
1692 TopTools_MapOfShape M;
1693 for (; anExp.More(); anExp.Next()) {
1694 if (M.Add(anExp.Current())) {
1695 if (anExp.Current().IsSame(aSubShape))
1702 SetErrorCode("The sub-shape does not belong to the main shape");
1706 //=============================================================================
1708 * GetShapeTypeString
1710 //=============================================================================
1711 TCollection_AsciiString GEOMImpl_IShapesOperations::GetShapeTypeString (Handle(GEOM_Object) theShape)
1715 TCollection_AsciiString aTypeName ("Null Shape");
1717 TopoDS_Shape aShape = theShape->GetValue();
1718 if (aShape.IsNull())
1721 switch (aShape.ShapeType() )
1723 case TopAbs_COMPOUND:
1724 aTypeName = "Compound";
1726 case TopAbs_COMPSOLID:
1727 aTypeName = "Compound Solid";
1730 aTypeName = "Solid";
1733 aTypeName = "Shell";
1737 BRepAdaptor_Surface surf (TopoDS::Face(aShape));
1738 if (surf.GetType() == GeomAbs_Plane)
1739 aTypeName = "Plane";
1740 else if (surf.GetType() == GeomAbs_Cylinder)
1741 aTypeName = "Cylindrical Face";
1742 else if (surf.GetType() == GeomAbs_Sphere)
1743 aTypeName = "Spherical Face";
1744 else if (surf.GetType() == GeomAbs_Torus)
1745 aTypeName = "Toroidal Face";
1746 else if (surf.GetType() == GeomAbs_Cone)
1747 aTypeName = "Conical Face";
1749 aTypeName = "GEOM::FACE";
1757 BRepAdaptor_Curve curv (TopoDS::Edge(aShape));
1758 if (curv.GetType() == GeomAbs_Line) {
1759 if ((Abs(curv.FirstParameter()) >= 1E6) ||
1760 (Abs(curv.LastParameter()) >= 1E6))
1764 } else if (curv.GetType() == GeomAbs_Circle) {
1765 if (curv.IsClosed())
1766 aTypeName = "Circle";
1775 aTypeName = "Vertex";
1778 aTypeName = "Shape";
1781 aTypeName = "Shape of unknown type";
1787 //=============================================================================
1791 //=============================================================================
1792 Standard_Integer GEOMImpl_IShapesOperations::NumberOfSubShapes
1793 (Handle(GEOM_Object) theShape,
1794 const Standard_Integer theShapeType)
1797 Standard_Integer nbShapes = 0;
1799 if (theShape.IsNull()) return -1;
1800 TopoDS_Shape aShape = theShape->GetValue();
1801 if (aShape.IsNull()) return -1;
1804 TopTools_MapOfShape mapShape;
1806 if (aShape.ShapeType() == TopAbs_COMPOUND &&
1807 (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
1808 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPSOLID ||
1809 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPOUND)) {
1810 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
1811 for (; It.More(); It.Next()) {
1812 if (mapShape.Add(It.Value())) {
1813 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
1814 TopAbs_ShapeEnum(theShapeType) == It.Value().ShapeType()) {
1820 TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
1821 for (; exp.More(); exp.Next())
1822 if (mapShape.Add(exp.Current()))
1829 int iType, nbTypes [TopAbs_SHAPE];
1830 for (iType = 0; iType < TopAbs_SHAPE; ++iType)
1832 nbTypes[aShape.ShapeType()]++;
1834 TopTools_MapOfShape aMapOfShape;
1835 aMapOfShape.Add(aShape);
1836 TopTools_ListOfShape aListOfShape;
1837 aListOfShape.Append(aShape);
1839 TopTools_ListIteratorOfListOfShape itL (aListOfShape);
1840 for (; itL.More(); itL.Next()) {
1841 TopoDS_Iterator it (itL.Value());
1842 for (; it.More(); it.Next()) {
1843 TopoDS_Shape s = it.Value();
1844 if (aMapOfShape.Add(s)) {
1845 aListOfShape.Append(s);
1846 nbTypes[s.ShapeType()]++;
1851 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE)
1852 nbShapes = aMapOfShape.Extent();
1854 nbShapes = nbTypes[theShapeType];
1856 catch (Standard_Failure) {
1857 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1858 SetErrorCode(aFail->GetMessageString());
1866 //=============================================================================
1870 //=============================================================================
1871 Handle(GEOM_Object) GEOMImpl_IShapesOperations::ReverseShape(Handle(GEOM_Object) theShape)
1875 if (theShape.IsNull()) return NULL;
1878 //Add a new reversed object
1879 Handle(GEOM_Object) aReversed = GetEngine()->AddObject(GetDocID(), theShape->GetType());
1881 //Add a new Revese function
1882 Handle(GEOM_Function) aFunction;
1883 aFunction = aReversed->AddFunction(GEOMImpl_ShapeDriver::GetID(), REVERSE_ORIENTATION);
1884 if (aFunction.IsNull()) return NULL;
1886 //Check if the function is set correctly
1887 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
1889 GEOMImpl_IShapes aSI (aFunction);
1891 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
1892 if (aRefShape.IsNull()) return NULL;
1894 aSI.SetBase(aRefShape);
1896 //Compute the sub-shape value
1899 if (!GetSolver()->ComputeFunction(aFunction)) {
1900 SetErrorCode("Shape driver failed to reverse shape");
1904 catch (Standard_Failure) {
1905 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1906 SetErrorCode(aFail->GetMessageString());
1910 //Make a Python command
1911 GEOM::TPythonDump(aFunction) << aReversed
1912 << " = geompy.ChangeOrientation(" << theShape << ")";
1917 Handle(GEOM_Object) aReversed;
1919 GEOM_Engine* anEngine = GetEngine();
1920 //GEOMImpl_Gen* aGen = dynamic_cast<GEOMImpl_Gen*>(anEngine);
1921 GEOMImpl_Gen* aGen = (GEOMImpl_Gen*)anEngine;
1924 GEOMImpl_IHealingOperations* anIHealingOperations =
1925 aGen->GetIHealingOperations(GetDocID());
1926 aReversed = anIHealingOperations->ChangeOrientationCopy(theShape);
1927 SetErrorCode(anIHealingOperations->GetErrorCode());
1933 //=============================================================================
1937 //=============================================================================
1938 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetFreeFacesIDs
1939 (Handle(GEOM_Object) theShape)
1943 if (theShape.IsNull()) return NULL;
1944 TopoDS_Shape aShape = theShape->GetValue();
1945 if (aShape.IsNull()) return NULL;
1947 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
1949 TopTools_IndexedDataMapOfShapeListOfShape mapFaceBlocks;
1950 GEOMImpl_Block6Explorer::MapShapesAndAncestors
1951 (aShape, TopAbs_FACE, TopAbs_SOLID, mapFaceBlocks);
1953 Standard_Integer ind = 1, nbFaces = mapFaceBlocks.Extent();
1956 SetErrorCode("The given shape has no faces");
1960 TopTools_IndexedMapOfShape anIndices;
1961 TopExp::MapShapes(aShape, anIndices);
1963 Standard_Integer id;
1964 for (; ind <= nbFaces; ind++) {
1965 if (mapFaceBlocks.FindFromIndex(ind).Extent() != 2) {
1966 id = anIndices.FindIndex(mapFaceBlocks.FindKey(ind));
1971 //The explode doesn't change object so no new function is required.
1972 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
1974 //Make a Python command
1975 GEOM::TPythonDump(aFunction, /*append=*/true)
1976 << "listFreeFacesIDs = geompy.GetFreeFacesIDs(" << theShape << ")";
1982 //=======================================================================
1983 //function : GetSharedShapes
1985 //=======================================================================
1986 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetSharedShapes
1987 (Handle(GEOM_Object) theShape1,
1988 Handle(GEOM_Object) theShape2,
1989 const Standard_Integer theShapeType)
1993 if (theShape1.IsNull() || theShape2.IsNull()) return NULL;
1995 TopoDS_Shape aShape1 = theShape1->GetValue();
1996 TopoDS_Shape aShape2 = theShape2->GetValue();
1998 if (aShape1.IsNull() || aShape2.IsNull()) return NULL;
2000 TopTools_IndexedMapOfShape anIndices;
2001 TopExp::MapShapes(aShape1, anIndices);
2002 Handle(TColStd_HArray1OfInteger) anArray;
2004 TopTools_IndexedMapOfShape mapShape1;
2005 TopExp::MapShapes(aShape1, TopAbs_ShapeEnum(theShapeType), mapShape1);
2007 Handle(GEOM_Object) anObj;
2008 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
2009 TCollection_AsciiString anAsciiList, anEntry;
2011 TopTools_MapOfShape mapShape2;
2012 TopExp_Explorer exp (aShape2, TopAbs_ShapeEnum(theShapeType));
2013 for (; exp.More(); exp.Next()) {
2014 TopoDS_Shape aSS = exp.Current();
2015 if (mapShape2.Add(aSS) && mapShape1.Contains(aSS)) {
2016 anArray = new TColStd_HArray1OfInteger(1,1);
2017 anArray->SetValue(1, anIndices.FindIndex(aSS));
2018 anObj = GetEngine()->AddSubShape(theShape1, anArray);
2019 aSeq->Append(anObj);
2021 // for python command
2022 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
2023 anAsciiList += anEntry;
2028 if (aSeq->IsEmpty()) {
2029 SetErrorCode("The given shapes have no shared sub-shapes of the requested type");
2033 //Make a Python command
2034 anAsciiList.Trunc(anAsciiList.Length() - 1);
2036 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2038 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
2039 << "] = geompy.GetSharedShapes(" << theShape1 << ", "
2040 << theShape2 << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
2046 //=======================================================================
2047 //function : GetSharedShapes
2049 //=======================================================================
2050 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetSharedShapes
2051 (std::list<Handle(GEOM_Object)> theShapes,
2052 const Standard_Integer theShapeType)
2056 int aLen = theShapes.size();
2057 if (aLen < 1) return NULL;
2060 std::list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
2062 Handle(GEOM_Object) aMainObj = (*it++);
2063 Handle(GEOM_Function) aMainShape = aMainObj->GetLastFunction();
2064 if (aMainShape.IsNull()) {
2065 SetErrorCode("NULL shape for GetSharedShapes");
2069 TopoDS_Shape aShape1 = aMainShape->GetValue();
2070 if (aShape1.IsNull()) return NULL;
2072 TopTools_IndexedMapOfShape anIndices;
2073 TopExp::MapShapes(aShape1, anIndices);
2075 TopTools_IndexedMapOfShape mapSelected;
2076 TopExp::MapShapes(aShape1, TopAbs_ShapeEnum(theShapeType), mapSelected);
2078 // Find shared shapes
2080 TopoDS_Compound aCurrSelection;
2082 for (; it != theShapes.end(); it++, ind++) {
2083 Handle(GEOM_Function) aRefShape = (*it)->GetLastFunction();
2084 if (aRefShape.IsNull()) {
2085 SetErrorCode("NULL shape for GetSharedShapes");
2089 TopoDS_Compound aCompound;
2090 B.MakeCompound(aCompound);
2092 TopoDS_Shape aShape2 = aRefShape->GetValue();
2093 if (aShape2.IsNull()) return NULL;
2095 TopTools_MapOfShape mapShape2;
2096 TopExp_Explorer exp (aShape2, TopAbs_ShapeEnum(theShapeType));
2097 for (; exp.More(); exp.Next()) {
2098 TopoDS_Shape aSS = exp.Current();
2099 if (mapShape2.Add(aSS) && mapSelected.Contains(aSS)) {
2100 B.Add(aCompound, aSS);
2104 mapSelected.Clear();
2105 TopExp::MapShapes(aCompound, TopAbs_ShapeEnum(theShapeType), mapSelected);
2106 aCurrSelection = aCompound;
2109 // Create GEOM_Object for each found shared shape (collected in aCurrSelection)
2110 Handle(GEOM_Object) anObj;
2111 Handle(TColStd_HArray1OfInteger) anArray;
2112 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
2113 TCollection_AsciiString anAsciiList, anEntry;
2115 TopoDS_Iterator itSel (aCurrSelection, Standard_True, Standard_True);
2116 for (; itSel.More(); itSel.Next()) {
2117 anArray = new TColStd_HArray1OfInteger(1,1);
2118 anArray->SetValue(1, anIndices.FindIndex(itSel.Value()));
2119 anObj = GetEngine()->AddSubShape(aMainObj, anArray);
2120 aSeq->Append(anObj);
2122 // for python command
2123 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
2124 anAsciiList += anEntry;
2128 if (aSeq->IsEmpty()) {
2129 SetErrorCode("The given shapes have no shared sub-shapes of the requested type");
2133 // Make a Python command
2134 anAsciiList.Trunc(anAsciiList.Length() - 1);
2136 // IPAL22904: TC6.5.0: order of python commands is wrong after dump study
2137 Handle(TColStd_HSequenceOfTransient) anObjects = new TColStd_HSequenceOfTransient;
2138 for( it = theShapes.begin(); it != theShapes.end(); it++ )
2140 Handle(GEOM_Object) anObj = *it;
2141 if( !anObj.IsNull() )
2142 anObjects->Append( anObj );
2145 // Get the function of the latest published object
2146 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast( anObjects )->GetLastFunction();
2147 if( aFunction.IsNull() ) // just in case
2148 aFunction = aMainShape;
2150 GEOM::TPythonDump pd (aFunction, /*append=*/true);
2151 pd << "[" << anAsciiList.ToCString()
2152 << "] = geompy.GetSharedShapesMulti([";
2154 it = theShapes.begin();
2156 while (it != theShapes.end()) {
2157 pd << ", " << (*it++);
2160 pd << "], " << TopAbs_ShapeEnum(theShapeType) << ")";
2166 //=============================================================================
2170 //=============================================================================
2171 static GEOM::TPythonDump& operator<< (GEOM::TPythonDump& theDump,
2172 const GEOMAlgo_State theState)
2175 case GEOMAlgo_ST_IN:
2176 theDump << "GEOM.ST_IN";
2178 case GEOMAlgo_ST_OUT:
2179 theDump << "GEOM.ST_OUT";
2181 case GEOMAlgo_ST_ON:
2182 theDump << "GEOM.ST_ON";
2184 case GEOMAlgo_ST_ONIN:
2185 theDump << "GEOM.ST_ONIN";
2187 case GEOMAlgo_ST_ONOUT:
2188 theDump << "GEOM.ST_ONOUT";
2191 theDump << "GEOM.ST_UNKNOWN";
2197 //=======================================================================
2198 //function : checkTypeShapesOn
2200 * \brief Checks if theShapeType parameter of GetShapesOnXXX() is OK
2201 * \param theShapeType - the shape type to check
2202 * \retval bool - result of the check
2204 //=======================================================================
2205 bool GEOMImpl_IShapesOperations::checkTypeShapesOn(const Standard_Integer theShapeType)
2207 if (theShapeType != TopAbs_VERTEX &&
2208 theShapeType != TopAbs_EDGE &&
2209 theShapeType != TopAbs_FACE &&
2210 theShapeType != TopAbs_SOLID) {
2211 SetErrorCode("Only solids, vertices, edges or faces can be found by this method");
2217 //=======================================================================
2218 //function : makePlane
2220 * \brief Creates Geom_Plane
2221 * \param theAx1 - shape object defining plane parameters
2222 * \retval Handle(Geom_Surface) - resulting surface
2224 //=======================================================================
2225 Handle(Geom_Surface) GEOMImpl_IShapesOperations::makePlane(const TopoDS_Shape& anAx1)
2227 if (anAx1.ShapeType() != TopAbs_EDGE) return NULL;
2228 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
2229 TopoDS_Vertex V1, V2;
2230 TopExp::Vertices(anEdge, V1, V2, Standard_True);
2231 if (V1.IsNull() || V2.IsNull()) {
2232 SetErrorCode("Bad edge given for the plane normal vector");
2235 gp_Pnt aLoc = BRep_Tool::Pnt(V1);
2236 gp_Vec aVec (aLoc, BRep_Tool::Pnt(V2));
2237 if (aVec.Magnitude() < Precision::Confusion()) {
2238 SetErrorCode("Vector with null magnitude given");
2241 return new Geom_Plane(aLoc, aVec);
2244 //=======================================================================
2245 //function : makeCylinder
2247 * \brief Creates Geom_CylindricalSurface
2248 * \param theAx1 - edge defining cylinder axis
2249 * \param theRadius - cylinder radius
2250 * \retval Handle(Geom_Surface) - resulting surface
2252 //=======================================================================
2253 Handle(Geom_Surface) GEOMImpl_IShapesOperations::makeCylinder(const TopoDS_Shape& anAxis,
2254 const Standard_Real theRadius)
2256 //Axis of the cylinder
2257 if (anAxis.ShapeType() != TopAbs_EDGE) {
2258 SetErrorCode("Not an edge given for the axis");
2261 TopoDS_Edge anEdge = TopoDS::Edge(anAxis);
2262 TopoDS_Vertex V1, V2;
2263 TopExp::Vertices(anEdge, V1, V2, Standard_True);
2264 if (V1.IsNull() || V2.IsNull()) {
2265 SetErrorCode("Bad edge given for the axis");
2268 gp_Pnt aLoc = BRep_Tool::Pnt(V1);
2269 gp_Vec aVec (aLoc, BRep_Tool::Pnt(V2));
2270 if (aVec.Magnitude() < Precision::Confusion()) {
2271 SetErrorCode("Vector with null magnitude given");
2275 gp_Ax3 anAx3 (aLoc, aVec);
2276 return new Geom_CylindricalSurface(anAx3, theRadius);
2279 //=======================================================================
2280 //function : getShapesOnBoxIDs
2282 * \brief Find IDs of sub-shapes complying with given status about surface
2283 * \param theBox - the box to check state of sub-shapes against
2284 * \param theShape - the shape to explore
2285 * \param theShapeType - type of sub-shape of theShape
2286 * \param theState - required state
2287 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
2289 //=======================================================================
2290 Handle(TColStd_HSequenceOfInteger)
2291 GEOMImpl_IShapesOperations::getShapesOnBoxIDs(const Handle(GEOM_Object)& theBox,
2292 const Handle(GEOM_Object)& theShape,
2293 const Standard_Integer theShapeType,
2294 GEOMAlgo_State theState)
2296 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
2298 TopoDS_Shape aBox = theBox->GetValue();
2299 TopoDS_Shape aShape = theShape->GetValue();
2301 // Check presence of triangulation, build if need
2302 if (!GEOMUtils::CheckTriangulation(aShape)) {
2303 SetErrorCode("Cannot build triangulation on the shape");
2308 GEOMAlgo_FinderShapeOn2 aFinder;
2309 Standard_Real aTol = 0.0001; // default value
2311 Handle(GEOMAlgo_ClsfBox) aClsfBox = new GEOMAlgo_ClsfBox;
2312 aClsfBox->SetBox(aBox);
2314 aFinder.SetShape(aShape);
2315 aFinder.SetTolerance(aTol);
2316 aFinder.SetClsf(aClsfBox);
2317 aFinder.SetShapeType( (TopAbs_ShapeEnum)theShapeType );
2318 aFinder.SetState(theState);
2321 // Interprete results
2322 Standard_Integer iErr = aFinder.ErrorStatus();
2323 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
2325 MESSAGE(" iErr : " << iErr);
2326 TCollection_AsciiString aMsg (" iErr : ");
2327 aMsg += TCollection_AsciiString(iErr);
2331 Standard_Integer iWrn = aFinder.WarningStatus();
2332 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
2334 MESSAGE(" *** iWrn : " << iWrn);
2337 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
2339 if (listSS.Extent() < 1) {
2340 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
2341 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
2345 // Fill sequence of object IDs
2346 aSeqOfIDs = new TColStd_HSequenceOfInteger;
2348 TopTools_IndexedMapOfShape anIndices;
2349 TopExp::MapShapes(aShape, anIndices);
2351 TopTools_ListIteratorOfListOfShape itSub (listSS);
2352 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
2353 int id = anIndices.FindIndex(itSub.Value());
2354 aSeqOfIDs->Append(id);
2360 //=======================================================================
2361 //function : GetShapesOnBoxIDs
2363 * \brief Find sub-shapes complying with given status about surface
2364 * \param theBox - the box to check state of sub-shapes against
2365 * \param theShape - the shape to explore
2366 * \param theShapeType - type of sub-shape of theShape
2367 * \param theState - required state
2368 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
2370 //=======================================================================
2371 Handle(TColStd_HSequenceOfInteger)
2372 GEOMImpl_IShapesOperations::GetShapesOnBoxIDs(const Handle(GEOM_Object)& theBox,
2373 const Handle(GEOM_Object)& theShape,
2374 const Standard_Integer theShapeType,
2375 GEOMAlgo_State theState)
2377 // Find sub-shapes ids
2378 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2379 getShapesOnBoxIDs (theBox, theShape, theShapeType, theState);
2380 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2383 // The GetShapesOnBox() doesn't change object so no new function is required.
2384 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theBox)->GetLastFunction();
2386 // Make a Python command
2387 GEOM::TPythonDump(aFunction, /*append=*/true)
2388 << "listShapesOnBoxIDs = geompy.GetShapesOnBoxIDs("
2391 << TopAbs_ShapeEnum(theShapeType) << ", "
2398 //=======================================================================
2399 //function : GetShapesOnBox
2401 * \brief Find sub-shapes complying with given status about surface
2402 * \param theBox - the box to check state of sub-shapes against
2403 * \param theShape - the shape to explore
2404 * \param theShapeType - type of sub-shape of theShape
2405 * \param theState - required state
2406 * \retval Handle(TColStd_HSequenceOfTransient) - found sub-shapes
2408 //=======================================================================
2409 Handle(TColStd_HSequenceOfTransient)
2410 GEOMImpl_IShapesOperations::GetShapesOnBox(const Handle(GEOM_Object)& theBox,
2411 const Handle(GEOM_Object)& theShape,
2412 const Standard_Integer theShapeType,
2413 GEOMAlgo_State theState)
2415 // Find sub-shapes ids
2416 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2417 getShapesOnBoxIDs (theBox, theShape, theShapeType, theState);
2418 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2421 // Find objects by indices
2422 TCollection_AsciiString anAsciiList;
2423 Handle(TColStd_HSequenceOfTransient) aSeq;
2424 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
2425 if ( aSeq.IsNull() || aSeq->IsEmpty() )
2428 // Make a Python command
2430 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2431 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2433 GEOM::TPythonDump(aFunction)
2434 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnBox("
2437 << TopAbs_ShapeEnum(theShapeType) << ", "
2444 //=======================================================================
2445 //function : getShapesOnShapeIDs
2447 * \brief Find IDs of sub-shapes complying with given status about surface
2448 * \param theCheckShape - the shape to check state of sub-shapes against
2449 * \param theShape - the shape to explore
2450 * \param theShapeType - type of sub-shape of theShape
2451 * \param theState - required state
2452 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
2454 //=======================================================================
2455 Handle(TColStd_HSequenceOfInteger)
2456 GEOMImpl_IShapesOperations::getShapesOnShapeIDs
2457 (const Handle(GEOM_Object)& theCheckShape,
2458 const Handle(GEOM_Object)& theShape,
2459 const Standard_Integer theShapeType,
2460 GEOMAlgo_State theState)
2462 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
2464 TopoDS_Shape aCheckShape = theCheckShape->GetValue();
2465 TopoDS_Shape aShape = theShape->GetValue();
2466 TopTools_ListOfShape res;
2468 // Check presence of triangulation, build if need
2469 if (!GEOMUtils::CheckTriangulation(aShape)) {
2470 SetErrorCode("Cannot build triangulation on the shape");
2475 GEOMAlgo_FinderShapeOn2 aFinder;
2476 Standard_Real aTol = 0.0001; // default value
2478 Handle(GEOMAlgo_ClsfSolid) aClsfSolid = new GEOMAlgo_ClsfSolid;
2479 aClsfSolid->SetShape(aCheckShape);
2481 aFinder.SetShape(aShape);
2482 aFinder.SetTolerance(aTol);
2483 aFinder.SetClsf(aClsfSolid);
2484 aFinder.SetShapeType( (TopAbs_ShapeEnum)theShapeType );
2485 aFinder.SetState(theState);
2488 // Interprete results
2489 Standard_Integer iErr = aFinder.ErrorStatus();
2490 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
2493 SetErrorCode("theCheckShape must be a solid");
2496 MESSAGE(" iErr : " << iErr);
2497 TCollection_AsciiString aMsg (" iErr : ");
2498 aMsg += TCollection_AsciiString(iErr);
2503 Standard_Integer iWrn = aFinder.WarningStatus();
2504 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
2506 MESSAGE(" *** iWrn : " << iWrn);
2509 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
2511 if (listSS.Extent() < 1) {
2512 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
2513 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
2516 // Fill sequence of object IDs
2517 aSeqOfIDs = new TColStd_HSequenceOfInteger;
2519 TopTools_IndexedMapOfShape anIndices;
2520 TopExp::MapShapes(aShape, anIndices);
2522 TopTools_ListIteratorOfListOfShape itSub (listSS);
2523 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
2524 int id = anIndices.FindIndex(itSub.Value());
2525 aSeqOfIDs->Append(id);
2531 //=======================================================================
2532 //function : GetShapesOnShapeIDs
2534 * \brief Find sub-shapes complying with given status about surface
2535 * \param theCheckShape - the shape to check state of sub-shapes against
2536 * \param theShape - the shape to explore
2537 * \param theShapeType - type of sub-shape of theShape
2538 * \param theState - required state
2539 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
2541 //=======================================================================
2542 Handle(TColStd_HSequenceOfInteger)
2543 GEOMImpl_IShapesOperations::GetShapesOnShapeIDs
2544 (const Handle(GEOM_Object)& theCheckShape,
2545 const Handle(GEOM_Object)& theShape,
2546 const Standard_Integer theShapeType,
2547 GEOMAlgo_State theState)
2549 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2550 getShapesOnShapeIDs (theCheckShape, theShape, theShapeType, theState);
2552 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2555 // The GetShapesOnShape() doesn't change object so no new function is required.
2556 Handle(GEOM_Function) aFunction =
2557 GEOM::GetCreatedLast(theShape,theCheckShape)->GetLastFunction();
2559 // Make a Python command
2560 GEOM::TPythonDump(aFunction, /*append=*/true)
2561 << "listShapesOnBoxIDs = geompy.GetShapesOnShapeIDs("
2562 << theCheckShape << ", "
2564 << TopAbs_ShapeEnum(theShapeType) << ", "
2571 //=======================================================================
2572 //function : GetShapesOnShape
2574 * \brief Find sub-shapes complying with given status about surface
2575 * \param theCheckShape - the shape to check state of sub-shapes against
2576 * \param theShape - the shape to explore
2577 * \param theShapeType - type of sub-shape of theShape
2578 * \param theState - required state
2579 * \retval Handle(TColStd_HSequenceOfTransient) - found sub-shapes
2581 //=======================================================================
2582 Handle(TColStd_HSequenceOfTransient)
2583 GEOMImpl_IShapesOperations::GetShapesOnShape
2584 (const Handle(GEOM_Object)& theCheckShape,
2585 const Handle(GEOM_Object)& theShape,
2586 const Standard_Integer theShapeType,
2587 GEOMAlgo_State theState)
2589 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2590 getShapesOnShapeIDs (theCheckShape, theShape, theShapeType, theState);
2591 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2594 // Find objects by indices
2595 TCollection_AsciiString anAsciiList;
2596 Handle(TColStd_HSequenceOfTransient) aSeq;
2597 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
2599 if ( aSeq.IsNull() || aSeq->IsEmpty() )
2602 // Make a Python command
2604 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2605 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2607 GEOM::TPythonDump(aFunction)
2608 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnShape("
2609 << theCheckShape << ", "
2611 << TopAbs_ShapeEnum(theShapeType) << ", "
2618 //=======================================================================
2619 //function : GetShapesOnShapeAsCompound
2620 //=======================================================================
2621 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetShapesOnShapeAsCompound
2622 (const Handle(GEOM_Object)& theCheckShape,
2623 const Handle(GEOM_Object)& theShape,
2624 const Standard_Integer theShapeType,
2625 GEOMAlgo_State theState)
2627 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2628 getShapesOnShapeIDs (theCheckShape, theShape, theShapeType, theState);
2630 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2633 // Find objects by indices
2634 TCollection_AsciiString anAsciiList;
2635 Handle(TColStd_HSequenceOfTransient) aSeq;
2636 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
2638 if ( aSeq.IsNull() || aSeq->IsEmpty() )
2641 TopoDS_Compound aCompound;
2643 B.MakeCompound(aCompound);
2645 for(; i<=aSeq->Length(); i++) {
2646 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(aSeq->Value(i));
2647 TopoDS_Shape aShape_i = anObj->GetValue();
2648 B.Add(aCompound,aShape_i);
2651 //Add a new result object
2652 Handle(GEOM_Object) aRes = GetEngine()->AddObject(GetDocID(), GEOM_SHAPES_ON_SHAPE);
2653 Handle(GEOM_Function) aFunction =
2654 aRes->AddFunction(GEOMImpl_ShapeDriver::GetID(), SHAPES_ON_SHAPE);
2655 aFunction->SetValue(aCompound);
2658 aSeq->Append( theCheckShape->GetLastFunction() );
2659 aSeq->Append( theShape->GetLastFunction() );
2661 GEOMImpl_IShapes aCI( aFunction );
2662 aCI.SetShapes( aSeq );
2663 aCI.SetSubShapeType( theShapeType );
2664 aCI.SetTolerance( theState );
2666 GEOM::TPythonDump(aFunction)
2667 << aRes << " = geompy.GetShapesOnShapeAsCompound("
2668 << theCheckShape << ", "
2670 << TopAbs_ShapeEnum(theShapeType) << ", "
2678 //=============================================================================
2680 * GetSubShapeEdgeSorted
2682 //=============================================================================
2683 Handle(TColStd_HSequenceOfTransient)
2684 GEOMImpl_IShapesOperations::GetSubShapeEdgeSorted
2685 (const Handle(GEOM_Object) &theShape,
2686 const Handle(GEOM_Object) &theStartPoint)
2688 // Get the sorted edges indices.
2689 Handle(TColStd_HSequenceOfInteger) aSortedIDs =
2690 getSubShapeEdgeSortedIDs(theShape, theStartPoint);
2692 // Get object by indices.
2693 TCollection_AsciiString anAsciiList;
2694 Handle(TColStd_HSequenceOfTransient) aSeq =
2695 getObjectsShapesOn(theShape, aSortedIDs, anAsciiList);
2697 if (aSeq.IsNull() || aSeq->IsEmpty()) {
2698 SetErrorCode("Empty sequence of edges");
2702 // Make a Python command
2703 Handle(GEOM_Object) anObj =
2704 Handle(GEOM_Object)::DownCast(aSeq->Value(1));
2705 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2707 GEOM::TPythonDump(aFunction)
2708 << "[" << anAsciiList.ToCString() << "] = geompy.GetSubShapeEdgeSorted("
2709 << theShape << ", " << theStartPoint << ")";
2716 //=======================================================================
2717 //function : getShapesOnSurfaceIDs
2719 * \brief Find IDs of sub-shapes complying with given status about surface
2720 * \param theSurface - the surface to check state of sub-shapes against
2721 * \param theShape - the shape to explore
2722 * \param theShapeType - type of sub-shape of theShape
2723 * \param theState - required state
2724 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
2726 //=======================================================================
2727 Handle(TColStd_HSequenceOfInteger)
2728 GEOMImpl_IShapesOperations::getShapesOnSurfaceIDs(const Handle(Geom_Surface)& theSurface,
2729 const TopoDS_Shape& theShape,
2730 TopAbs_ShapeEnum theShapeType,
2731 GEOMAlgo_State theState)
2733 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
2735 // Check presence of triangulation, build if need
2736 if (!GEOMUtils::CheckTriangulation(theShape)) {
2737 SetErrorCode("Cannot build triangulation on the shape");
2741 // BEGIN: Mantis issue 0020961: Error on a pipe T-Shape
2742 // Compute tolerance
2743 Standard_Real T, VertMax = -RealLast();
2746 for (TopExp_Explorer ExV (theShape, TopAbs_VERTEX); ExV.More(); ExV.Next()) {
2747 TopoDS_Vertex Vertex = TopoDS::Vertex(ExV.Current());
2748 T = BRep_Tool::Tolerance(Vertex);
2753 catch (Standard_Failure) {
2754 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2755 SetErrorCode(aFail->GetMessageString());
2758 // END: Mantis issue 0020961
2761 GEOMAlgo_FinderShapeOn1 aFinder;
2762 //Standard_Real aTol = 0.0001; // default value
2763 Standard_Real aTol = VertMax; // Mantis issue 0020961
2765 aFinder.SetShape(theShape);
2766 aFinder.SetTolerance(aTol);
2767 aFinder.SetSurface(theSurface);
2768 aFinder.SetShapeType(theShapeType);
2769 aFinder.SetState(theState);
2771 // Sets the minimal number of inner points for the faces that do not have own
2772 // inner points at all (for e.g. rectangular planar faces have just 2 triangles).
2774 aFinder.SetNbPntsMin(3);
2775 // Sets the maximal number of inner points for edges or faces.
2776 // It is usefull for the cases when this number is very big (e.g =2000) to improve
2777 // the performance. If this value =0, all inner points will be taken into account.
2779 aFinder.SetNbPntsMax(100);
2783 // Interprete results
2784 Standard_Integer iErr = aFinder.ErrorStatus();
2785 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
2787 MESSAGE(" iErr : " << iErr);
2788 TCollection_AsciiString aMsg (" iErr : ");
2789 aMsg += TCollection_AsciiString(iErr);
2793 Standard_Integer iWrn = aFinder.WarningStatus();
2794 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
2796 MESSAGE(" *** iWrn : " << iWrn);
2799 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
2801 if (listSS.Extent() < 1) {
2802 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
2803 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
2807 // Fill sequence of object IDs
2808 aSeqOfIDs = new TColStd_HSequenceOfInteger;
2810 TopTools_IndexedMapOfShape anIndices;
2811 TopExp::MapShapes(theShape, anIndices);
2813 TopTools_ListIteratorOfListOfShape itSub (listSS);
2814 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
2815 int id = anIndices.FindIndex(itSub.Value());
2816 aSeqOfIDs->Append(id);
2822 //=======================================================================
2823 //function : getObjectsShapesOn
2825 * \brief Find shape objects and their entries by their ids
2826 * \param theShapeIDs - incoming shape ids
2827 * \param theShapeEntries - outgoing entries like "entry1, entry2, ..."
2828 * \retval Handle(TColStd_HSequenceOfTransient) - found shape objects
2830 //=======================================================================
2831 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::
2832 getObjectsShapesOn(const Handle(GEOM_Object)& theShape,
2833 const Handle(TColStd_HSequenceOfInteger)& theShapeIDs,
2834 TCollection_AsciiString & theShapeEntries)
2836 Handle(TColStd_HSequenceOfTransient) aSeq;
2838 if ( !theShapeIDs.IsNull() && theShapeIDs->Length() > 0 )
2840 aSeq = new TColStd_HSequenceOfTransient;
2841 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
2842 TCollection_AsciiString anEntry;
2843 for ( int i = 1; i <= theShapeIDs->Length(); ++i )
2845 anArray->SetValue(1, theShapeIDs->Value( i ));
2846 Handle(GEOM_Object) anObj = GetEngine()->AddSubShape(theShape, anArray);
2847 aSeq->Append( anObj );
2849 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
2850 if ( i != 1 ) theShapeEntries += ",";
2851 theShapeEntries += anEntry;
2857 //=============================================================================
2859 * getSubShapeEdgeSortedIDs
2861 //=============================================================================
2862 Handle(TColStd_HSequenceOfInteger)
2863 GEOMImpl_IShapesOperations::getSubShapeEdgeSortedIDs
2864 (const Handle(GEOM_Object) &theShape,
2865 const Handle(GEOM_Object) &theStartPoint)
2867 Handle(TColStd_HSequenceOfInteger) aResult;
2869 if (theShape.IsNull() || theStartPoint.IsNull()) {
2870 SetErrorCode("NULL GEOM object");
2874 const TopoDS_Shape aShape = theShape->GetValue();
2875 const TopoDS_Shape aStartPoint = theStartPoint->GetValue();
2877 if (aShape.IsNull() || aStartPoint.IsNull()) {
2878 SetErrorCode("NULL Shape");
2882 if (aStartPoint.ShapeType() != TopAbs_VERTEX) {
2883 SetErrorCode("Starting point is not a vertex");
2887 TopExp_Explorer anExp(aShape, TopAbs_EDGE);
2888 TopTools_MapOfShape aMapFence;
2889 TopTools_ListOfShape anEdges;
2891 for (; anExp.More(); anExp.Next()) {
2892 const TopoDS_Shape &anEdge = anExp.Current();
2894 if (aMapFence.Add(anEdge)) {
2895 anEdges.Append(anEdge);
2899 if (anEdges.IsEmpty()) {
2900 SetErrorCode("Shape doesn't contain edges");
2904 // Step 1: Sort edges
2905 GEOMUtils::SortShapes(anEdges, Standard_False);
2907 TopTools_ListIteratorOfListOfShape anIter(anEdges);
2908 TopoDS_Vertex aV[2];
2909 TopTools_DataMapOfShapeListOfShape aMapVE;
2911 // Step 2: Fill the map vertex - list of edges.
2912 for (; anIter.More(); anIter.Next()) {
2913 TopoDS_Edge anEdge = TopoDS::Edge(anIter.Value());
2915 TopExp::Vertices(anEdge, aV[0], aV[1]);
2917 const Standard_Integer aNbV = aV[0].IsSame(aV[1]) ? 1 : 2;
2920 for (i = 0; i < aNbV; ++i) {
2921 if (aV[i].IsNull() == Standard_False) {
2922 if (!aMapVE.IsBound(aV[i])) {
2923 // There is no this vertex in the map.
2924 aMapVE.Bind(aV[i], TopTools_ListOfShape());
2927 // Add the edge to the list bound with the vertex aV[i].
2928 TopTools_ListOfShape &aLEdges = aMapVE.ChangeFind(aV[i]);
2930 aLEdges.Append(anEdge);
2935 // Step 3: Find starting point in aMapVE.
2936 TopoDS_Vertex aStartVtx = TopoDS::Vertex(aStartPoint);
2938 if (!aMapVE.IsBound(aStartVtx)) {
2939 aStartVtx = getSameVertex(aShape, aStartVtx);
2941 if (aStartVtx.IsNull()) {
2942 SetErrorCode("Invalid Starting point");
2947 TopTools_IndexedMapOfShape anIndices;
2948 TopTools_MapOfShape aMapVFence;
2949 TopoDS_Shape aCurVtx = aStartVtx;
2950 TopoDS_Edge aCurEdge =
2951 TopoDS::Edge(aMapVE.Find(aCurVtx).First());
2953 aResult = new TColStd_HSequenceOfInteger;
2954 TopExp::MapShapes(aShape, anIndices);
2956 // Step 4: Fill the list of sorted edges.
2957 while (aMapVFence.Add(aCurVtx)) {
2958 // Append the ID of the current edge to the list of sorted.
2959 aResult->Append(anIndices.FindIndex(aCurEdge));
2960 TopExp::Vertices(aCurEdge, aV[0], aV[1]);
2962 // Get the next vertex.
2963 if (aCurVtx.IsSame(aV[0])) {
2964 if (aCurVtx.IsSame(aV[1])) {
2965 // There is no next vertex.
2974 if (aCurVtx.IsNull()) {
2975 // There is no next vertex.
2979 // Get the next edge.
2980 const TopTools_ListOfShape &aLEdges = aMapVE.Find(aCurVtx);
2981 TopTools_ListIteratorOfListOfShape anEIter(aLEdges);
2983 for (; anEIter.More(); anEIter.Next()) {
2984 const TopoDS_Shape &aLocalEdge = anEIter.Value();
2986 if (aLocalEdge.IsNull() == Standard_False) {
2987 if (!aCurEdge.IsSame(aLocalEdge)) {
2988 aCurEdge = TopoDS::Edge(aLocalEdge);
2994 if (!anEIter.More()) {
2995 // There is no next edge.
3003 //=======================================================================
3004 //function : getShapesOnSurface
3006 * \brief Find sub-shapes complying with given status about surface
3007 * \param theSurface - the surface to check state of sub-shapes against
3008 * \param theShape - the shape to explore
3009 * \param theShapeType - type of sub-shape of theShape
3010 * \param theState - required state
3011 * \param theShapeEntries - outgoing entries like "entry1, entry2, ..."
3012 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
3014 //=======================================================================
3015 Handle(TColStd_HSequenceOfTransient)
3016 GEOMImpl_IShapesOperations::getShapesOnSurface(const Handle(Geom_Surface)& theSurface,
3017 const Handle(GEOM_Object)& theShape,
3018 TopAbs_ShapeEnum theShapeType,
3019 GEOMAlgo_State theState,
3020 TCollection_AsciiString & theShapeEntries)
3022 // Find sub-shapes ids
3023 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
3024 getShapesOnSurfaceIDs (theSurface, theShape->GetValue(), theShapeType, theState);
3025 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
3028 return getObjectsShapesOn( theShape, aSeqOfIDs, theShapeEntries );
3031 //=============================================================================
3035 //=============================================================================
3036 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnPlane
3037 (const Handle(GEOM_Object)& theShape,
3038 const Standard_Integer theShapeType,
3039 const Handle(GEOM_Object)& theAx1,
3040 const GEOMAlgo_State theState)
3044 if (theShape.IsNull() || theAx1.IsNull()) return NULL;
3046 TopoDS_Shape aShape = theShape->GetValue();
3047 TopoDS_Shape anAx1 = theAx1->GetValue();
3049 if (aShape.IsNull() || anAx1.IsNull()) return NULL;
3051 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3052 if ( !checkTypeShapesOn( theShapeType ))
3056 Handle(Geom_Surface) aPlane = makePlane( anAx1 );
3057 if ( aPlane.IsNull() )
3061 TCollection_AsciiString anAsciiList;
3062 Handle(TColStd_HSequenceOfTransient) aSeq;
3063 aSeq = getShapesOnSurface( aPlane, theShape, aShapeType, theState, anAsciiList );
3064 if ( aSeq.IsNull() || aSeq->Length() == 0 )
3067 // Make a Python command
3069 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
3070 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
3072 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
3073 << "] = geompy.GetShapesOnPlane(" << theShape << ", "
3074 << aShapeType << ", " << theAx1 << ", " << theState << ")";
3080 //=============================================================================
3082 * GetShapesOnPlaneWithLocation
3084 //=============================================================================
3085 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnPlaneWithLocation
3086 (const Handle(GEOM_Object)& theShape,
3087 const Standard_Integer theShapeType,
3088 const Handle(GEOM_Object)& theAx1,
3089 const Handle(GEOM_Object)& thePnt,
3090 const GEOMAlgo_State theState)
3094 if (theShape.IsNull() || theAx1.IsNull() || thePnt.IsNull()) return NULL;
3096 TopoDS_Shape aShape = theShape->GetValue();
3097 TopoDS_Shape anAx1 = theAx1->GetValue();
3098 TopoDS_Shape anPnt = thePnt->GetValue();
3100 if (aShape.IsNull() || anAx1.IsNull() || anPnt.IsNull()) return NULL;
3102 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3103 if ( !checkTypeShapesOn( theShapeType ))
3107 if ( anAx1.ShapeType() != TopAbs_EDGE || anPnt.ShapeType() != TopAbs_VERTEX ) return NULL;
3108 TopoDS_Vertex V1, V2, V3;
3109 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
3110 TopExp::Vertices(anEdge, V1, V2, Standard_True);
3112 if (V1.IsNull() || V2.IsNull()) {
3113 SetErrorCode("Bad edge given for the plane normal vector");
3116 V3 = TopoDS::Vertex(anPnt);
3119 SetErrorCode("Bad vertex given for the plane location");
3122 gp_Pnt aLoc = BRep_Tool::Pnt(V3);
3123 gp_Vec aVec(BRep_Tool::Pnt(V1),BRep_Tool::Pnt(V2));
3125 if (aVec.Magnitude() < Precision::Confusion()) {
3126 SetErrorCode("Vector with null magnitude given");
3129 Handle(Geom_Surface) aPlane = new Geom_Plane(aLoc, aVec);
3131 if ( aPlane.IsNull() )
3135 TCollection_AsciiString anAsciiList;
3136 Handle(TColStd_HSequenceOfTransient) aSeq;
3137 aSeq = getShapesOnSurface( aPlane, theShape, aShapeType, theState, anAsciiList );
3138 if ( aSeq.IsNull() || aSeq->Length() == 0 )
3141 // Make a Python command
3143 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
3144 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
3146 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
3147 << "] = geompy.GetShapesOnPlaneWithLocation(" << theShape << ", "
3148 << aShapeType << ", " << theAx1 << ", "<< thePnt <<", " << theState << ")";
3154 //=============================================================================
3156 * GetShapesOnCylinder
3158 //=============================================================================
3159 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnCylinder
3160 (const Handle(GEOM_Object)& theShape,
3161 const Standard_Integer theShapeType,
3162 const Handle(GEOM_Object)& theAxis,
3163 const Standard_Real theRadius,
3164 const GEOMAlgo_State theState)
3168 if (theShape.IsNull() || theAxis.IsNull()) return NULL;
3170 TopoDS_Shape aShape = theShape->GetValue();
3171 TopoDS_Shape anAxis = theAxis->GetValue();
3173 if (aShape.IsNull() || anAxis.IsNull()) return NULL;
3175 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3176 if ( !checkTypeShapesOn( aShapeType ))
3179 // Create a cylinder surface
3180 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
3181 if ( aCylinder.IsNull() )
3185 TCollection_AsciiString anAsciiList;
3186 Handle(TColStd_HSequenceOfTransient) aSeq;
3187 aSeq = getShapesOnSurface( aCylinder, theShape, aShapeType, theState, anAsciiList );
3188 if ( aSeq.IsNull() || aSeq->Length() == 0 )
3191 // Make a Python command
3193 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
3194 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
3196 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
3197 << "] = geompy.GetShapesOnCylinder(" << theShape << ", " << aShapeType
3198 << ", " << theAxis << ", " << theRadius << ", " << theState << ")";
3204 //=============================================================================
3206 * GetShapesOnCylinderWithLocation
3208 //=============================================================================
3209 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnCylinderWithLocation
3210 (const Handle(GEOM_Object)& theShape,
3211 const Standard_Integer theShapeType,
3212 const Handle(GEOM_Object)& theAxis,
3213 const Handle(GEOM_Object)& thePnt,
3214 const Standard_Real theRadius,
3215 const GEOMAlgo_State theState)
3219 if (theShape.IsNull() || theAxis.IsNull() || thePnt.IsNull()) return NULL;
3221 TopoDS_Shape aShape = theShape->GetValue();
3222 TopoDS_Shape anAxis = theAxis->GetValue();
3223 TopoDS_Shape aPnt = thePnt->GetValue();
3225 if (aShape.IsNull() || anAxis.IsNull() || aPnt.IsNull()) return NULL;
3227 if (aPnt.ShapeType() != TopAbs_VERTEX )
3229 SetErrorCode("Bottom location point must be vertex");
3233 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3234 if ( !checkTypeShapesOn( aShapeType ))
3237 // Create a cylinder surface
3238 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
3239 if ( aCylinder.IsNull() )
3242 // translate the surface
3243 Handle(Geom_CylindricalSurface) aCylSurface =
3244 Handle(Geom_CylindricalSurface)::DownCast( aCylinder );
3245 if ( aCylSurface.IsNull() )
3247 SetErrorCode("Unexpected surface type instead of Geom_CylindricalSurface");
3250 gp_Pnt fromLoc = aCylSurface->Cylinder().Location();
3251 gp_Pnt toLoc = BRep_Tool::Pnt( TopoDS::Vertex( aPnt ));
3252 aCylinder->Translate( fromLoc, toLoc );
3255 TCollection_AsciiString anAsciiList;
3256 Handle(TColStd_HSequenceOfTransient) aSeq;
3257 aSeq = getShapesOnSurface( aCylinder, theShape, aShapeType, theState, anAsciiList );
3258 if ( aSeq.IsNull() || aSeq->Length() == 0 )
3261 // Make a Python command
3263 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
3264 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
3266 GEOM::TPythonDump(aFunction)
3267 << "[" << anAsciiList.ToCString()
3268 << "] = geompy.GetShapesOnCylinderWithLocation(" << theShape << ", " << aShapeType << ", "
3269 << theAxis << ", " << thePnt << ", " << theRadius << ", " << theState << ")";
3275 //=============================================================================
3279 //=============================================================================
3280 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnSphere
3281 (const Handle(GEOM_Object)& theShape,
3282 const Standard_Integer theShapeType,
3283 const Handle(GEOM_Object)& theCenter,
3284 const Standard_Real theRadius,
3285 const GEOMAlgo_State theState)
3289 if (theShape.IsNull() || theCenter.IsNull()) return NULL;
3291 TopoDS_Shape aShape = theShape->GetValue();
3292 TopoDS_Shape aCenter = theCenter->GetValue();
3294 if (aShape.IsNull() || aCenter.IsNull()) return NULL;
3296 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3297 if ( !checkTypeShapesOn( aShapeType ))
3300 // Center of the sphere
3301 if (aCenter.ShapeType() != TopAbs_VERTEX) return NULL;
3302 gp_Pnt aLoc = BRep_Tool::Pnt(TopoDS::Vertex(aCenter));
3304 gp_Ax3 anAx3 (aLoc, gp::DZ());
3305 Handle(Geom_SphericalSurface) aSphere =
3306 new Geom_SphericalSurface(anAx3, theRadius);
3309 TCollection_AsciiString anAsciiList;
3310 Handle(TColStd_HSequenceOfTransient) aSeq;
3311 aSeq = getShapesOnSurface( aSphere, theShape, aShapeType, theState, anAsciiList );
3312 if ( aSeq.IsNull() || aSeq->Length() == 0 )
3315 // Make a Python command
3317 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
3318 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
3320 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
3321 << "] = geompy.GetShapesOnSphere(" << theShape << ", " << aShapeType
3322 << ", " << theCenter << ", " << theRadius << ", " << theState << ")";
3328 //=============================================================================
3330 * GetShapesOnPlaneIDs
3332 //=============================================================================
3333 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnPlaneIDs
3334 (const Handle(GEOM_Object)& theShape,
3335 const Standard_Integer theShapeType,
3336 const Handle(GEOM_Object)& theAx1,
3337 const GEOMAlgo_State theState)
3341 if (theShape.IsNull() || theAx1.IsNull()) return NULL;
3343 TopoDS_Shape aShape = theShape->GetValue();
3344 TopoDS_Shape anAx1 = theAx1->GetValue();
3346 if (aShape.IsNull() || anAx1.IsNull()) return NULL;
3348 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3349 if ( !checkTypeShapesOn( aShapeType ))
3353 Handle(Geom_Surface) aPlane = makePlane( anAx1 );
3354 if ( aPlane.IsNull() )
3358 Handle(TColStd_HSequenceOfInteger) aSeq;
3359 aSeq = getShapesOnSurfaceIDs( aPlane, aShape, aShapeType, theState );
3361 // The GetShapesOnPlaneIDs() doesn't change object so no new function is required.
3362 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAx1)->GetLastFunction();
3364 // Make a Python command
3365 GEOM::TPythonDump(aFunction, /*append=*/true)
3366 << "listShapesOnPlane = geompy.GetShapesOnPlaneIDs"
3367 << "(" << theShape << "," << aShapeType << "," << theAx1 << "," << theState << ")";
3373 //=============================================================================
3375 * GetShapesOnPlaneWithLocationIDs
3377 //=============================================================================
3378 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnPlaneWithLocationIDs
3379 (const Handle(GEOM_Object)& theShape,
3380 const Standard_Integer theShapeType,
3381 const Handle(GEOM_Object)& theAx1,
3382 const Handle(GEOM_Object)& thePnt,
3383 const GEOMAlgo_State theState)
3387 if (theShape.IsNull() || theAx1.IsNull() || thePnt.IsNull()) return NULL;
3389 TopoDS_Shape aShape = theShape->GetValue();
3390 TopoDS_Shape anAx1 = theAx1->GetValue();
3391 TopoDS_Shape anPnt = thePnt->GetValue();
3393 if (aShape.IsNull() || anAx1.IsNull() || anPnt.IsNull()) return NULL;
3395 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3396 if ( !checkTypeShapesOn( aShapeType ))
3400 if (anAx1.ShapeType() != TopAbs_EDGE || anPnt.ShapeType() != TopAbs_VERTEX) return NULL;
3401 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
3402 TopoDS_Vertex V1, V2, V3;
3403 TopExp::Vertices(anEdge, V1, V2, Standard_True);
3404 if (V1.IsNull() || V2.IsNull()) {
3405 SetErrorCode("Bad edge given for the plane normal vector");
3408 V3 = TopoDS::Vertex(anPnt);
3410 SetErrorCode("Bad vertex given for the plane location");
3413 gp_Pnt aLoc = BRep_Tool::Pnt(V3);
3414 gp_Vec aVec(BRep_Tool::Pnt(V1),BRep_Tool::Pnt(V2));
3415 if (aVec.Magnitude() < Precision::Confusion()) {
3416 SetErrorCode("Vector with null magnitude given");
3420 Handle(Geom_Surface) aPlane = new Geom_Plane(aLoc, aVec);
3421 if ( aPlane.IsNull() )
3425 Handle(TColStd_HSequenceOfInteger) aSeq;
3426 aSeq = getShapesOnSurfaceIDs( aPlane, aShape, aShapeType, theState );
3428 // The GetShapesOnPlaneIDs() doesn't change object so no new function is required.
3429 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAx1)->GetLastFunction();
3431 // Make a Python command
3432 GEOM::TPythonDump(aFunction, /*append=*/true)
3433 << "listShapesOnPlane = geompy.GetShapesOnPlaneWithLocationIDs"
3434 << "(" << theShape << ", " << aShapeType << ", " << theAx1 << ", "<< thePnt << ", " << theState << ")";
3440 //=============================================================================
3442 * GetShapesOnCylinderIDs
3444 //=============================================================================
3445 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnCylinderIDs
3446 (const Handle(GEOM_Object)& theShape,
3447 const Standard_Integer theShapeType,
3448 const Handle(GEOM_Object)& theAxis,
3449 const Standard_Real theRadius,
3450 const GEOMAlgo_State theState)
3454 if (theShape.IsNull() || theAxis.IsNull()) return NULL;
3456 TopoDS_Shape aShape = theShape->GetValue();
3457 TopoDS_Shape anAxis = theAxis->GetValue();
3459 if (aShape.IsNull() || anAxis.IsNull()) return NULL;
3461 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3462 if ( !checkTypeShapesOn( aShapeType ))
3465 // Create a cylinder surface
3466 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
3467 if ( aCylinder.IsNull() )
3471 Handle(TColStd_HSequenceOfInteger) aSeq;
3472 aSeq = getShapesOnSurfaceIDs( aCylinder, aShape, aShapeType, theState );
3474 // The GetShapesOnCylinder() doesn't change object so no new function is required.
3475 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAxis)->GetLastFunction();
3477 // Make a Python command
3478 GEOM::TPythonDump(aFunction, /*append=*/true)
3479 << "listShapesOnCylinder = geompy.GetShapesOnCylinderIDs"
3480 << "(" << theShape << ", " << aShapeType << ", " << theAxis << ", "
3481 << theRadius << ", " << theState << ")";
3487 //=============================================================================
3489 * GetShapesOnCylinderWithLocationIDs
3491 //=============================================================================
3492 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnCylinderWithLocationIDs
3493 (const Handle(GEOM_Object)& theShape,
3494 const Standard_Integer theShapeType,
3495 const Handle(GEOM_Object)& theAxis,
3496 const Handle(GEOM_Object)& thePnt,
3497 const Standard_Real theRadius,
3498 const GEOMAlgo_State theState)
3502 if (theShape.IsNull() || theAxis.IsNull() || thePnt.IsNull()) return NULL;
3504 TopoDS_Shape aShape = theShape->GetValue();
3505 TopoDS_Shape anAxis = theAxis->GetValue();
3506 TopoDS_Shape aPnt = thePnt->GetValue();
3508 if (aShape.IsNull() || anAxis.IsNull() || aPnt.IsNull()) return NULL;
3510 if (aPnt.ShapeType() != TopAbs_VERTEX )
3512 SetErrorCode("Bottom location point must be vertex");
3516 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3517 if ( !checkTypeShapesOn( aShapeType ))
3520 // Create a cylinder surface
3521 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
3522 if ( aCylinder.IsNull() )
3525 // translate the surface
3526 Handle(Geom_CylindricalSurface) aCylSurface =
3527 Handle(Geom_CylindricalSurface)::DownCast( aCylinder );
3528 if ( aCylSurface.IsNull() )
3530 SetErrorCode("Unexpected surface type instead of Geom_CylindricalSurface");
3533 gp_Pnt fromLoc = aCylSurface->Cylinder().Location();
3534 gp_Pnt toLoc = BRep_Tool::Pnt( TopoDS::Vertex( aPnt ));
3535 aCylinder->Translate( fromLoc, toLoc );
3538 Handle(TColStd_HSequenceOfInteger) aSeq;
3539 aSeq = getShapesOnSurfaceIDs( aCylinder, aShape, aShapeType, theState );
3541 // The GetShapesOnCylinder() doesn't change object so no new function is required.
3542 Handle(GEOM_Function) aFunction =
3543 GEOM::GetCreatedLast(theShape, GEOM::GetCreatedLast(thePnt,theAxis))->GetLastFunction();
3545 // Make a Python command
3546 GEOM::TPythonDump(aFunction, /*append=*/true)
3547 << "listShapesOnCylinder = geompy.GetShapesOnCylinderWithLocationIDs"
3548 << "(" << theShape << ", " << aShapeType << ", " << theAxis << ", "
3549 << thePnt << ", " << theRadius << ", " << theState << ")";
3555 //=============================================================================
3557 * GetShapesOnSphereIDs
3559 //=============================================================================
3560 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnSphereIDs
3561 (const Handle(GEOM_Object)& theShape,
3562 const Standard_Integer theShapeType,
3563 const Handle(GEOM_Object)& theCenter,
3564 const Standard_Real theRadius,
3565 const GEOMAlgo_State theState)
3569 if (theShape.IsNull() || theCenter.IsNull()) return NULL;
3571 TopoDS_Shape aShape = theShape->GetValue();
3572 TopoDS_Shape aCenter = theCenter->GetValue();
3574 if (aShape.IsNull() || aCenter.IsNull()) return NULL;
3576 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3577 if ( !checkTypeShapesOn( aShapeType ))
3580 // Center of the sphere
3581 if (aCenter.ShapeType() != TopAbs_VERTEX) return NULL;
3582 gp_Pnt aLoc = BRep_Tool::Pnt(TopoDS::Vertex(aCenter));
3584 gp_Ax3 anAx3 (aLoc, gp::DZ());
3585 Handle(Geom_SphericalSurface) aSphere =
3586 new Geom_SphericalSurface(anAx3, theRadius);
3589 Handle(TColStd_HSequenceOfInteger) aSeq;
3590 aSeq = getShapesOnSurfaceIDs( aSphere, aShape, aShapeType, theState );
3592 // The GetShapesOnSphere() doesn't change object so no new function is required.
3593 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theCenter)->GetLastFunction();
3595 // Make a Python command
3596 GEOM::TPythonDump(aFunction, /*append=*/true)
3597 << "listShapesOnCylinder = geompy.GetShapesOnSphereIDs"
3598 << "(" << theShape << ", " << aShapeType << ", " << theCenter << ", "
3599 << theRadius << ", " << theState << ")";
3605 //=======================================================================
3606 //function : getShapesOnQuadrangleIDs
3608 * \brief Find IDs of sub-shapes complying with given status about quadrangle
3609 * \param theShape - the shape to explore
3610 * \param theShapeType - type of sub-shape of theShape
3611 * \param theTopLeftPoint - top left quadrangle corner
3612 * \param theTopRigthPoint - top right quadrangle corner
3613 * \param theBottomLeftPoint - bottom left quadrangle corner
3614 * \param theBottomRigthPoint - bottom right quadrangle corner
3615 * \param theState - required state
3616 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
3618 //=======================================================================
3619 Handle(TColStd_HSequenceOfInteger)
3620 GEOMImpl_IShapesOperations::getShapesOnQuadrangleIDs (const Handle(GEOM_Object)& theShape,
3621 const Standard_Integer theShapeType,
3622 const Handle(GEOM_Object)& theTopLeftPoint,
3623 const Handle(GEOM_Object)& theTopRigthPoint,
3624 const Handle(GEOM_Object)& theBottomLeftPoint,
3625 const Handle(GEOM_Object)& theBottomRigthPoint,
3626 const GEOMAlgo_State theState)
3630 if ( theShape.IsNull() ||
3631 theTopLeftPoint.IsNull() ||
3632 theTopRigthPoint.IsNull() ||
3633 theBottomLeftPoint.IsNull() ||
3634 theBottomRigthPoint.IsNull() )
3637 TopoDS_Shape aShape = theShape->GetValue();
3638 TopoDS_Shape aTL = theTopLeftPoint->GetValue();
3639 TopoDS_Shape aTR = theTopRigthPoint->GetValue();
3640 TopoDS_Shape aBL = theBottomLeftPoint->GetValue();
3641 TopoDS_Shape aBR = theBottomRigthPoint->GetValue();
3643 if (aShape.IsNull() ||
3648 aTL.ShapeType() != TopAbs_VERTEX ||
3649 aTR.ShapeType() != TopAbs_VERTEX ||
3650 aBL.ShapeType() != TopAbs_VERTEX ||
3651 aBR.ShapeType() != TopAbs_VERTEX )
3654 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3655 if ( !checkTypeShapesOn( aShapeType ))
3658 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
3660 // Check presence of triangulation, build if need
3661 if (!GEOMUtils::CheckTriangulation(aShape)) {
3662 SetErrorCode("Cannot build triangulation on the shape");
3667 gp_Pnt aPntTL = BRep_Tool::Pnt(TopoDS::Vertex(aTL));
3668 gp_Pnt aPntTR = BRep_Tool::Pnt(TopoDS::Vertex(aTR));
3669 gp_Pnt aPntBL = BRep_Tool::Pnt(TopoDS::Vertex(aBL));
3670 gp_Pnt aPntBR = BRep_Tool::Pnt(TopoDS::Vertex(aBR));
3672 GEOMAlgo_FinderShapeOnQuad aFinder( aPntTL, aPntTR, aPntBL, aPntBR );
3673 Standard_Real aTol = 0.0001; // default value
3675 aFinder.SetShape(aShape);
3676 aFinder.SetTolerance(aTol);
3677 //aFinder.SetSurface(theSurface);
3678 aFinder.SetShapeType(aShapeType);
3679 aFinder.SetState(theState);
3681 // Sets the minimal number of inner points for the faces that do not have own
3682 // inner points at all (for e.g. rectangular planar faces have just 2 triangles).
3684 aFinder.SetNbPntsMin(3);
3685 // Sets the maximal number of inner points for edges or faces.
3686 // It is usefull for the cases when this number is very big (e.g =2000) to improve
3687 // the performance. If this value =0, all inner points will be taken into account.
3689 aFinder.SetNbPntsMax(100);
3693 // Interprete results
3694 Standard_Integer iErr = aFinder.ErrorStatus();
3695 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
3697 MESSAGE(" iErr : " << iErr);
3698 TCollection_AsciiString aMsg (" iErr : ");
3699 aMsg += TCollection_AsciiString(iErr);
3703 Standard_Integer iWrn = aFinder.WarningStatus();
3704 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
3706 MESSAGE(" *** iWrn : " << iWrn);
3709 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
3711 if (listSS.Extent() < 1) {
3712 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
3713 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
3717 // Fill sequence of object IDs
3718 aSeqOfIDs = new TColStd_HSequenceOfInteger;
3720 TopTools_IndexedMapOfShape anIndices;
3721 TopExp::MapShapes(aShape, anIndices);
3723 TopTools_ListIteratorOfListOfShape itSub (listSS);
3724 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
3725 int id = anIndices.FindIndex(itSub.Value());
3726 aSeqOfIDs->Append(id);
3731 //=======================================================================
3732 //function : GetShapesOnQuadrangle
3734 * \brief Find sub-shapes complying with given status about quadrangle
3735 * \param theShape - the shape to explore
3736 * \param theShapeType - type of sub-shape of theShape
3737 * \param theTopLeftPoint - top left quadrangle corner
3738 * \param theTopRigthPoint - top right quadrangle corner
3739 * \param theBottomLeftPoint - bottom left quadrangle corner
3740 * \param theBottomRigthPoint - bottom right quadrangle corner
3741 * \param theState - required state
3742 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
3744 //=======================================================================
3745 Handle(TColStd_HSequenceOfTransient)
3746 GEOMImpl_IShapesOperations::GetShapesOnQuadrangle (const Handle(GEOM_Object)& theShape,
3747 const Standard_Integer theShapeType,
3748 const Handle(GEOM_Object)& theTopLeftPoint,
3749 const Handle(GEOM_Object)& theTopRigthPoint,
3750 const Handle(GEOM_Object)& theBottomLeftPoint,
3751 const Handle(GEOM_Object)& theBottomRigthPoint,
3752 const GEOMAlgo_State theState)
3755 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
3756 getShapesOnQuadrangleIDs( theShape,
3761 theBottomRigthPoint,
3763 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->IsEmpty() )
3766 // Find objects by indices
3767 TCollection_AsciiString anAsciiList;
3768 Handle(TColStd_HSequenceOfTransient) aSeq;
3769 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
3770 if ( aSeq.IsNull() || aSeq->IsEmpty() )
3773 // Make a Python command
3775 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
3776 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
3778 GEOM::TPythonDump(aFunction)
3779 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnQuadrangle("
3781 << TopAbs_ShapeEnum(theShapeType) << ", "
3782 << theTopLeftPoint << ", "
3783 << theTopRigthPoint << ", "
3784 << theBottomLeftPoint << ", "
3785 << theBottomRigthPoint << ", "
3792 //=======================================================================
3793 //function : GetShapesOnQuadrangleIDs
3795 * \brief Find IDs of sub-shapes complying with given status about quadrangle
3796 * \param theShape - the shape to explore
3797 * \param theShapeType - type of sub-shape of theShape
3798 * \param theTopLeftPoint - top left quadrangle corner
3799 * \param theTopRigthPoint - top right quadrangle corner
3800 * \param theBottomLeftPoint - bottom left quadrangle corner
3801 * \param theBottomRigthPoint - bottom right quadrangle corner
3802 * \param theState - required state
3803 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
3805 //=======================================================================
3806 Handle(TColStd_HSequenceOfInteger)
3807 GEOMImpl_IShapesOperations::GetShapesOnQuadrangleIDs (const Handle(GEOM_Object)& theShape,
3808 const Standard_Integer theShapeType,
3809 const Handle(GEOM_Object)& theTopLeftPoint,
3810 const Handle(GEOM_Object)& theTopRigthPoint,
3811 const Handle(GEOM_Object)& theBottomLeftPoint,
3812 const Handle(GEOM_Object)& theBottomRigthPoint,
3813 const GEOMAlgo_State theState)
3816 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
3817 getShapesOnQuadrangleIDs( theShape,
3822 theBottomRigthPoint,
3824 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->IsEmpty() )
3827 // Make a Python command
3829 // The GetShapesOnCylinder() doesn't change object so no new function is required.
3830 Handle(GEOM_Object) lastObj = GEOM::GetCreatedLast(theShape,theTopLeftPoint);
3831 lastObj = GEOM::GetCreatedLast(lastObj,theTopRigthPoint);
3832 lastObj = GEOM::GetCreatedLast(lastObj,theBottomRigthPoint);
3833 lastObj = GEOM::GetCreatedLast(lastObj,theBottomLeftPoint);
3834 Handle(GEOM_Function) aFunction = lastObj->GetLastFunction();
3836 GEOM::TPythonDump(aFunction, /*append=*/true)
3837 << "listShapesOnQuadrangle = geompy.GetShapesOnQuadrangleIDs("
3839 << TopAbs_ShapeEnum(theShapeType) << ", "
3840 << theTopLeftPoint << ", "
3841 << theTopRigthPoint << ", "
3842 << theBottomLeftPoint << ", "
3843 << theBottomRigthPoint << ", "
3850 //=============================================================================
3854 //=============================================================================
3855 static bool GetInPlaceOfShape (const Handle(GEOM_Function)& theWhereFunction,
3856 const TopTools_IndexedMapOfShape& theWhereIndices,
3857 const TopoDS_Shape& theWhat,
3858 TColStd_ListOfInteger& theModifiedList)
3860 if (theWhereFunction.IsNull() || theWhat.IsNull()) return false;
3862 if (theWhereIndices.Contains(theWhat)) {
3863 // entity was not changed by the operation
3864 Standard_Integer aWhatIndex = theWhereIndices.FindIndex(theWhat);
3865 theModifiedList.Append(aWhatIndex);
3869 // try to find in history
3870 TDF_Label aHistoryLabel = theWhereFunction->GetHistoryEntry(Standard_False);
3872 // search in history for all argument shapes
3873 Standard_Boolean isFound = Standard_False;
3874 Standard_Boolean isGood = Standard_False;
3876 TDF_LabelSequence aLabelSeq;
3877 theWhereFunction->GetDependency(aLabelSeq);
3878 Standard_Integer nbArg = aLabelSeq.Length();
3880 for (Standard_Integer iarg = 1; iarg <= nbArg && !isFound; iarg++) {
3882 TDF_Label anArgumentRefLabel = aLabelSeq.Value(iarg);
3884 Handle(GEOM_Object) anArgumentObject = GEOM_Object::GetReferencedObject(anArgumentRefLabel);
3885 TopoDS_Shape anArgumentShape = anArgumentObject->GetValue();
3887 TopTools_IndexedMapOfShape anArgumentIndices;
3888 TopExp::MapShapes(anArgumentShape, anArgumentIndices);
3890 if (anArgumentIndices.Contains(theWhat)) {
3891 isFound = Standard_True;
3892 Standard_Integer aWhatIndex = anArgumentIndices.FindIndex(theWhat);
3894 // Find corresponding label in history
3895 TDF_Label anArgumentHistoryLabel =
3896 theWhereFunction->GetArgumentHistoryEntry(anArgumentRefLabel, Standard_False);
3897 if (anArgumentHistoryLabel.IsNull()) {
3898 // Lost History of operation argument. Possibly, all its entities was removed.
3899 isGood = Standard_True;
3902 TDF_Label aWhatHistoryLabel = anArgumentHistoryLabel.FindChild(aWhatIndex, Standard_False);
3904 if (aWhatHistoryLabel.IsNull()) {
3905 // Removed entity ? Compound ? Compsolid ? Shell ? Wire
3906 isGood = Standard_False;
3908 Handle(TDataStd_IntegerArray) anIntegerArray;
3909 if (!aWhatHistoryLabel.FindAttribute(TDataStd_IntegerArray::GetID(), anIntegerArray)) {
3910 //Error: Empty modifications history for the sought shape.
3911 isGood = Standard_False;
3914 isGood = Standard_True;
3915 Standard_Integer imod, aModifLen = anIntegerArray->Array()->Length();
3916 for (imod = 1; imod <= aModifLen; imod++) {
3917 theModifiedList.Append(anIntegerArray->Array()->Value(imod));
3928 // try compound/compsolid/shell/wire element by element
3929 bool isFoundAny = false;
3930 TopTools_MapOfShape mapShape;
3932 if (theWhat.ShapeType() == TopAbs_COMPOUND ||
3933 theWhat.ShapeType() == TopAbs_COMPSOLID) {
3934 // recursive processing of compound/compsolid
3935 TopoDS_Iterator anIt (theWhat, Standard_True, Standard_True);
3936 for (; anIt.More(); anIt.Next()) {
3937 if (mapShape.Add(anIt.Value())) {
3938 TopoDS_Shape curWhat = anIt.Value();
3939 isFoundAny = GetInPlaceOfShape(theWhereFunction, theWhereIndices, curWhat, theModifiedList);
3940 if (isFoundAny) isFound = Standard_True;
3944 else if (theWhat.ShapeType() == TopAbs_SHELL) {
3945 // try to replace a shell by its faces images
3946 TopExp_Explorer anExp (theWhat, TopAbs_FACE);
3947 for (; anExp.More(); anExp.Next()) {
3948 if (mapShape.Add(anExp.Current())) {
3949 TopoDS_Shape curWhat = anExp.Current();
3950 isFoundAny = GetInPlaceOfShape(theWhereFunction, theWhereIndices, curWhat, theModifiedList);
3951 if (isFoundAny) isFound = Standard_True;
3955 else if (theWhat.ShapeType() == TopAbs_WIRE) {
3956 // try to replace a wire by its edges images
3957 TopExp_Explorer anExp (theWhat, TopAbs_EDGE);
3958 for (; anExp.More(); anExp.Next()) {
3959 if (mapShape.Add(anExp.Current())) {
3960 TopoDS_Shape curWhat = anExp.Current();
3961 isFoundAny = GetInPlaceOfShape(theWhereFunction, theWhereIndices, curWhat, theModifiedList);
3962 if (isFoundAny) isFound = Standard_True;
3974 //=============================================================================
3976 * GetShapeProperties
3978 //=============================================================================
3979 void GEOMImpl_IShapesOperations::GetShapeProperties( const TopoDS_Shape aShape, Standard_Real tab[],
3982 GProp_GProps theProps;
3984 //TopoDS_Shape aPntShape;
3985 Standard_Real aShapeSize;
3987 if (aShape.ShapeType() == TopAbs_VERTEX) aCenterMass = BRep_Tool::Pnt( TopoDS::Vertex( aShape ) );
3988 else if (aShape.ShapeType() == TopAbs_EDGE) BRepGProp::LinearProperties(aShape, theProps);
3989 else if (aShape.ShapeType() == TopAbs_FACE) BRepGProp::SurfaceProperties(aShape, theProps);
3990 else BRepGProp::VolumeProperties(aShape, theProps);
3992 if (aShape.ShapeType() == TopAbs_VERTEX)
3995 aCenterMass = theProps.CentreOfMass();
3996 aShapeSize = theProps.Mass();
3999 // aPntShape = BRepBuilderAPI_MakeVertex(aCenterMass).Shape();
4000 // aVertex = BRep_Tool::Pnt( TopoDS::Vertex( aPntShape ) );
4001 aVertex = aCenterMass;
4002 tab[0] = aVertex.X();
4003 tab[1] = aVertex.Y();
4004 tab[2] = aVertex.Z();
4005 tab[3] = aShapeSize;
4011 //================================================================================
4013 * \brief Return normal to face at extrema point
4015 //================================================================================
4017 gp_Vec GetNormal (const TopoDS_Face& face, const BRepExtrema_DistShapeShape& extrema)
4019 gp_Vec defaultNorm(1,0,0); // to have same normals on different faces
4021 // get UV at extrema point
4022 Standard_Real u,v, f,l;
4023 switch ( extrema.SupportTypeShape2(1) ) {
4024 case BRepExtrema_IsInFace: {
4025 extrema.ParOnFaceS2(1, u, v );
4028 case BRepExtrema_IsOnEdge: {
4029 TopoDS_Edge edge = TopoDS::Edge( extrema.SupportOnShape2(1));
4030 Handle(Geom2d_Curve) pcurve = BRep_Tool::CurveOnSurface( edge, face, f,l );
4031 extrema.ParOnEdgeS2( 1, u );
4032 gp_Pnt2d uv = pcurve->Value( u );
4037 case BRepExtrema_IsVertex: return defaultNorm;
4040 BRepAdaptor_Surface surface( face, false );
4041 gp_Vec du, dv; gp_Pnt p;
4042 surface.D1( u, v, p, du, dv );
4046 } catch (Standard_Failure ) {
4052 //=============================================================================
4057 //=============================================================================
4058 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlace (Handle(GEOM_Object) theShapeWhere,
4059 Handle(GEOM_Object) theShapeWhat)
4063 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
4065 TopoDS_Shape aWhere = theShapeWhere->GetValue();
4066 TopoDS_Shape aWhat = theShapeWhat->GetValue();
4068 if (aWhere.IsNull() || aWhat.IsNull()) {
4069 SetErrorCode("Error: aWhere and aWhat TopoDS_Shape are Null.");
4073 // Compute confusion tolerance.
4074 Standard_Real aTolConf = Precision::Confusion();
4077 for (i = 0; i < 2; ++i) {
4078 TopExp_Explorer anExp(i == 0 ? aWhere : aWhat, TopAbs_VERTEX);
4080 for (; anExp.More(); anExp.Next()) {
4081 const TopoDS_Vertex aVtx = TopoDS::Vertex(anExp.Current());
4082 const Standard_Real aTolVtx = BRep_Tool::Tolerance(aVtx);
4084 if (aTolVtx > aTolConf) {
4090 // Compute mass tolerance.
4091 Bnd_Box aBoundingBox;
4092 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
4093 Standard_Real aMassTol;
4095 BRepBndLib::Add(aWhere, aBoundingBox);
4096 BRepBndLib::Add(aWhat, aBoundingBox);
4097 aBoundingBox.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
4098 aMassTol = Max(aXmax - aXmin, aYmax - aYmin);
4099 aMassTol = Max(aMassTol, aZmax - aZmin);
4100 aMassTol *= aTolConf;
4102 // Searching for the sub-shapes inside the ShapeWhere shape
4103 GEOMAlgo_GetInPlace aGIP;
4104 aGIP.SetTolerance(aTolConf);
4105 aGIP.SetTolMass(aMassTol);
4106 aGIP.SetTolCG(aTolConf);
4108 aGIP.SetArgument(aWhat);
4109 aGIP.SetShapeWhere(aWhere);
4112 int iErr = aGIP.ErrorStatus();
4114 SetErrorCode("Error in GEOMAlgo_GetInPlace");
4118 // Add direct result.
4119 TopTools_ListOfShape aLSA;
4120 const TopoDS_Shape &aShapeResult = aGIP.Result();
4121 TopTools_MapOfShape aMFence;
4122 TopTools_IndexedMapOfShape aWhereIndices;
4124 TopExp::MapShapes(aWhere, aWhereIndices);
4126 if (aShapeResult.IsNull() == Standard_False) {
4127 TopoDS_Iterator anIt(aShapeResult);
4129 for (; anIt.More(); anIt.Next()) {
4130 const TopoDS_Shape &aPart = anIt.Value();
4132 if(aWhereIndices.Contains(aPart) && aMFence.Add(aPart)) {
4138 if (aLSA.Extent() == 0) {
4139 SetErrorCode(NOT_FOUND_ANY); // Not found any Results
4143 Handle(TColStd_HArray1OfInteger) aModifiedArray = new TColStd_HArray1OfInteger (1, aLSA.Extent());
4144 TopTools_ListIteratorOfListOfShape anIterModif (aLSA);
4145 for (Standard_Integer imod = 1; anIterModif.More(); anIterModif.Next(), imod++) {
4146 if (aWhereIndices.Contains(anIterModif.Value())) {
4147 aModifiedArray->SetValue(imod, aWhereIndices.FindIndex(anIterModif.Value()));
4150 SetErrorCode("Error: wrong sub-shape returned");
4156 Handle(GEOM_Object) aResult = GetEngine()->AddSubShape(theShapeWhere, aModifiedArray);
4157 if (aResult.IsNull()) {
4158 SetErrorCode("Error in algorithm: result found, but cannot be returned.");
4162 if (aModifiedArray->Length() > 1 || theShapeWhat->GetType() == GEOM_GROUP) {
4164 aResult->SetType(GEOM_GROUP);
4166 //Set a sub-shape type
4167 TopoDS_Shape aFirstFound = aLSA.First();
4168 TopAbs_ShapeEnum aShapeType = aFirstFound.ShapeType();
4170 TDF_Label aFreeLabel = aResult->GetFreeLabel();
4171 TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aShapeType);
4174 //Make a Python command
4175 Handle(GEOM_Function) aFunction = aResult->GetFunction(1);
4177 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetInPlace("
4178 << theShapeWhere << ", " << theShapeWhat << ", True)";
4184 //=============================================================================
4186 * case GetInPlaceOld:
4189 //=============================================================================
4190 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlaceOld (Handle(GEOM_Object) theShapeWhere,
4191 Handle(GEOM_Object) theShapeWhat)
4195 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
4197 TopoDS_Shape aWhere = theShapeWhere->GetValue();
4198 TopoDS_Shape aWhat = theShapeWhat->GetValue();
4199 TopoDS_Shape aPntShape;
4200 TopoDS_Vertex aVertex;
4202 if (aWhere.IsNull() || aWhat.IsNull()) {
4203 SetErrorCode("Error: aWhere and aWhat TopoDS_Shape are Null.");
4207 Handle(GEOM_Function) aWhereFunction = theShapeWhere->GetLastFunction();
4208 if (aWhereFunction.IsNull()) {
4209 SetErrorCode("Error: aWhereFunction is Null.");
4213 TopTools_IndexedMapOfShape aWhereIndices;
4214 TopExp::MapShapes(aWhere, aWhereIndices);
4216 TColStd_ListOfInteger aModifiedList;
4217 Standard_Integer aWhereIndex;
4218 Handle(TColStd_HArray1OfInteger) aModifiedArray;
4219 Handle(GEOM_Object) aResult;
4221 bool isFound = false;
4222 TopAbs_ShapeEnum iType = TopAbs_SOLID;
4223 //Standard_Real aWhat_Mass = 0., aWhere_Mass = 0.;
4224 Standard_Real tab_aWhat[4], tab_aWhere[4];
4225 Standard_Real dl_l = 1e-3;
4226 Standard_Real min_l, Tol_0D, Tol_1D, Tol_2D, Tol_3D, Tol_Mass;
4227 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
4228 Bnd_Box BoundingBox;
4229 gp_Pnt aPnt, aPnt_aWhat, tab_Pnt[2];
4230 GProp_GProps aProps;
4232 // Find the iType of the aWhat shape
4234 if ( aWhat.ShapeType() == TopAbs_VERTEX ) iType = TopAbs_VERTEX;
4235 else if ( aWhat.ShapeType() == TopAbs_EDGE || aWhat.ShapeType() == TopAbs_WIRE ) iType = TopAbs_EDGE;
4236 else if ( aWhat.ShapeType() == TopAbs_FACE || aWhat.ShapeType() == TopAbs_SHELL ) iType = TopAbs_FACE;
4237 else if ( aWhat.ShapeType() == TopAbs_SOLID || aWhat.ShapeType() == TopAbs_COMPSOLID ) iType = TopAbs_SOLID;
4238 else if ( aWhat.ShapeType() == TopAbs_COMPOUND ) {
4239 // Only the iType of the first shape in the compound is taken into account
4240 TopoDS_Iterator It (aWhat, Standard_False, Standard_False);
4242 SetErrorCode("Error: theShapeWhat is an empty COMPOUND.");
4245 TopAbs_ShapeEnum compType = It.Value().ShapeType();
4246 if ( compType == TopAbs_VERTEX ) iType = TopAbs_VERTEX;
4247 else if ( compType == TopAbs_EDGE || compType == TopAbs_WIRE ) iType = TopAbs_EDGE;
4248 else if ( compType == TopAbs_FACE || compType == TopAbs_SHELL) iType = TopAbs_FACE;
4249 else if ( compType == TopAbs_SOLID || compType == TopAbs_COMPSOLID) iType = TopAbs_SOLID;
4252 SetErrorCode("Error: An attempt to extract a shape of not supported type.");
4256 iType = GEOMUtils::GetTypeOfSimplePart(aWhat);
4257 if (iType == TopAbs_SHAPE) {
4258 SetErrorCode("Error: An attempt to extract a shape of not supported type.");
4262 TopExp_Explorer Exp_aWhat ( aWhat, iType );
4263 TopExp_Explorer Exp_aWhere ( aWhere, iType );
4264 TopExp_Explorer Exp_Edge ( aWhere, TopAbs_EDGE );
4266 // Find the shortest edge in theShapeWhere shape
4267 BRepBndLib::Add(aWhere, BoundingBox);
4268 BoundingBox.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
4269 min_l = fabs(aXmax - aXmin);
4270 if( min_l < fabs(aYmax - aYmin) ) min_l = fabs(aYmax - aYmin);
4271 if( min_l < fabs(aZmax - aZmin) ) min_l = fabs(aZmax - aZmin);
4273 // Mantis issue 0020908 BEGIN
4274 if (!Exp_Edge.More()) {
4275 min_l = Precision::Confusion();
4277 // Mantis issue 0020908 END
4278 for ( Standard_Integer nbEdge = 0; Exp_Edge.More(); Exp_Edge.Next(), nbEdge++ ) {
4279 TopExp_Explorer Exp_Vertex( Exp_Edge.Current(), TopAbs_VERTEX);
4280 for ( Standard_Integer nbVertex = 0; Exp_Vertex.More(); Exp_Vertex.Next(), nbVertex++ ) {
4281 aPnt = BRep_Tool::Pnt( TopoDS::Vertex( Exp_Vertex.Current() ) );
4282 tab_Pnt[nbVertex] = aPnt;
4284 if ( ! tab_Pnt[0].IsEqual(tab_Pnt[1], dl_l) ) {
4285 BRepGProp::LinearProperties(Exp_Edge.Current(), aProps);
4286 if ( aProps.Mass() < min_l ) min_l = aProps.Mass();
4290 // Compute tolerances
4292 Tol_1D = dl_l * min_l;
4293 Tol_2D = dl_l * ( min_l * min_l) * ( 2. + dl_l);
4294 Tol_3D = dl_l * ( min_l * min_l * min_l ) * ( 3. + (3 * dl_l) + (dl_l * dl_l) );
4296 if (Tol_0D < Precision::Confusion()) Tol_0D = Precision::Confusion();
4297 if (Tol_1D < Precision::Confusion()) Tol_1D = Precision::Confusion();
4298 if (Tol_2D < Precision::Confusion()) Tol_2D = Precision::Confusion();
4299 if (Tol_3D < Precision::Confusion()) Tol_3D = Precision::Confusion();
4301 //if (Tol_1D > 1.0) Tol_1D = 1.0;
4302 //if (Tol_2D > 1.0) Tol_2D = 1.0;
4303 //if (Tol_3D > 1.0) Tol_3D = 1.0;
4306 if ( iType == TopAbs_VERTEX ) Tol_Mass = Tol_0D;
4307 else if ( iType == TopAbs_EDGE ) Tol_Mass = Tol_1D;
4308 else if ( iType == TopAbs_FACE ) Tol_Mass = Tol_2D;
4310 // Compute the ShapeWhat Mass
4312 for ( ; Exp_aWhat.More(); Exp_aWhat.Next() ) {
4313 if ( iType == TopAbs_VERTEX ) {
4317 else if ( iType == TopAbs_EDGE ) BRepGProp::LinearProperties(Exp_aWhat.Current(), aProps);
4318 else if ( iType == TopAbs_FACE ) BRepGProp::SurfaceProperties(Exp_aWhat.Current(), aProps);
4319 else BRepGProp::VolumeProperties(Exp_aWhat.Current(), aProps);
4320 aWhat_Mass += aProps.Mass();
4324 // Searching for the sub-shapes inside the ShapeWhere shape
4325 TopTools_MapOfShape map_aWhere;
4326 for ( Exp_aWhere.ReInit(); Exp_aWhere.More(); Exp_aWhere.Next() ) {
4327 if (!map_aWhere.Add(Exp_aWhere.Current()))
4328 continue; // skip repeated shape to avoid mass addition
4329 GetShapeProperties( Exp_aWhere.Current(), tab_aWhere, aPnt );
4330 for ( Exp_aWhat.ReInit(); Exp_aWhat.More(); Exp_aWhat.Next() ) {
4331 GetShapeProperties( Exp_aWhat.Current(), tab_aWhat, aPnt_aWhat );
4332 if ( fabs(tab_aWhat[3] - tab_aWhere[3]) <= Tol_Mass && aPnt_aWhat.Distance(aPnt) <= Tol_1D )
4335 if ( (tab_aWhat[3] - tab_aWhere[3]) > Tol_Mass ) {
4336 aPntShape = BRepBuilderAPI_MakeVertex( aPnt ).Shape();
4337 aVertex = TopoDS::Vertex( aPntShape );
4338 BRepExtrema_DistShapeShape aWhereDistance ( aVertex, Exp_aWhere.Current() );
4339 BRepExtrema_DistShapeShape aWhatDistance ( aVertex, Exp_aWhat.Current() );
4340 if ( aWhereDistance.IsDone() && aWhatDistance.IsDone() &&
4341 fabs(aWhereDistance.Value() - aWhatDistance.Value()) <= Tol_1D )
4343 // 0020162: "EDF 961 GEOM : Getinplace is getting additionnal orthogonal faces"
4344 // aVertex must be projected to the same point on Where and on What
4345 gp_Pnt pOnWhat = aWhatDistance.PointOnShape2(1);
4346 gp_Pnt pOnWhere = aWhereDistance.PointOnShape2(1);
4347 isFound = ( pOnWhat.Distance(pOnWhere) <= Tol_1D );
4348 if ( isFound && iType == TopAbs_FACE )
4350 // check normals at pOnWhat and pOnWhere
4351 const double angleTol = M_PI/180.;
4352 gp_Vec normToWhat = GetNormal( TopoDS::Face(Exp_aWhat.Current()), aWhatDistance);
4353 gp_Vec normToWhere = GetNormal( TopoDS::Face(Exp_aWhere.Current()), aWhereDistance);
4354 if ( normToWhat * normToWhere < 0 )
4355 normToWhat.Reverse();
4356 isFound = ( normToWhat.Angle( normToWhere ) < angleTol );
4362 aWhereIndex = aWhereIndices.FindIndex(Exp_aWhere.Current());
4363 aModifiedList.Append(aWhereIndex);
4364 //aWhere_Mass += tab_aWhere[3];
4369 //if ( fabs( aWhat_Mass - aWhere_Mass ) <= Tol_Mass )
4373 if (aModifiedList.Extent() == 0) { // Not found any Results
4374 SetErrorCode(NOT_FOUND_ANY);
4378 aModifiedArray = new TColStd_HArray1OfInteger (1, aModifiedList.Extent());
4379 TColStd_ListIteratorOfListOfInteger anIterModif (aModifiedList);
4380 for (Standard_Integer imod = 1; anIterModif.More(); anIterModif.Next(), imod++)
4381 aModifiedArray->SetValue(imod, anIterModif.Value());
4384 aResult = GetEngine()->AddSubShape(theShapeWhere, aModifiedArray);
4385 if (aResult.IsNull()) {
4386 SetErrorCode("Error in algorithm: result found, but cannot be returned.");
4390 if (aModifiedArray->Length() > 1 || theShapeWhat->GetType() == GEOM_GROUP) {
4392 aResult->SetType(GEOM_GROUP);
4394 //Set a sub-shape type
4395 TopoDS_Shape aFirstFound = aWhereIndices.FindKey(aModifiedArray->Value(1));
4396 TopAbs_ShapeEnum aShapeType = aFirstFound.ShapeType();
4398 TDF_Label aFreeLabel = aResult->GetFreeLabel();
4399 TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aShapeType);
4402 //Make a Python command
4403 Handle(GEOM_Function) aFunction = aResult->GetFunction(1);
4405 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetInPlace("
4406 << theShapeWhere << ", " << theShapeWhat << ", False)";
4412 //=======================================================================
4413 //function : GetInPlaceByHistory
4415 //=======================================================================
4416 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlaceByHistory
4417 (Handle(GEOM_Object) theShapeWhere,
4418 Handle(GEOM_Object) theShapeWhat)
4422 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
4424 TopoDS_Shape aWhere = theShapeWhere->GetValue();
4425 TopoDS_Shape aWhat = theShapeWhat->GetValue();
4427 if (aWhere.IsNull() || aWhat.IsNull()) return NULL;
4429 Handle(GEOM_Function) aWhereFunction = theShapeWhere->GetLastFunction();
4430 if (aWhereFunction.IsNull()) return NULL;
4432 //Fill array of indices
4433 TopTools_IndexedMapOfShape aWhereIndices;
4434 TopExp::MapShapes(aWhere, aWhereIndices);
4437 TColStd_ListOfInteger aModifiedList;
4438 bool isFound = GetInPlaceOfShape(aWhereFunction, aWhereIndices, aWhat, aModifiedList);
4440 if (!isFound || aModifiedList.Extent() < 1) {
4441 SetErrorCode("Error: No history found for the sought shape or its sub-shapes.");
4445 Standard_Integer nbFound = aModifiedList.Extent();
4446 TColStd_ListIteratorOfListOfInteger anIterModif (aModifiedList);
4449 // remove sub-shapes inappropriate for group creation
4450 TopAbs_ShapeEnum subType = TopAbs_SHAPE;
4451 while ( anIterModif.More() ) {
4452 TopAbs_ShapeEnum type = aWhereIndices( anIterModif.Value() ).ShapeType();
4453 bool okForGroup = ( type == TopAbs_VERTEX || type == TopAbs_EDGE ||
4454 type == TopAbs_FACE || type == TopAbs_SOLID );
4456 if ( subType == TopAbs_SHAPE )
4459 okForGroup = ( subType == type );
4464 aModifiedList.Remove( anIterModif );
4465 nbFound -= ( !okForGroup );
4467 if ( nbFound == 0 ) {
4468 SetErrorCode("Error: result found but it's type is inappropriate for group creation.");
4473 Handle(TColStd_HArray1OfInteger) aModifiedArray =
4474 new TColStd_HArray1OfInteger( 1, nbFound );
4475 anIterModif.Initialize(aModifiedList);
4476 for (Standard_Integer imod = 1; anIterModif.More(); anIterModif.Next(), imod++)
4477 aModifiedArray->SetValue(imod, anIterModif.Value());
4480 Handle(GEOM_Object) aResult = GetEngine()->AddSubShape(theShapeWhere, aModifiedArray);
4481 if (aResult.IsNull()) {
4482 SetErrorCode("Error in algorithm: result found, but cannot be returned.");
4486 if (aModifiedArray->Length() > 1) {
4488 aResult->SetType(GEOM_GROUP);
4490 //Set a sub-shape type
4491 TopoDS_Shape aFirstFound = aWhereIndices.FindKey(aModifiedArray->Value(1));
4492 TopAbs_ShapeEnum aShapeType = aFirstFound.ShapeType();
4494 TDF_Label aFreeLabel = aResult->GetFreeLabel();
4495 TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aShapeType);
4498 //Make a Python command
4499 Handle(GEOM_Function) aFunction = aResult->GetFunction(1);
4501 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetInPlaceByHistory("
4502 << theShapeWhere << ", " << theShapeWhat << ")";
4508 //=======================================================================
4509 //function : isSameEdge
4510 //purpose : Returns True if two edges coincide
4511 //=======================================================================
4512 static bool isSameEdge(const TopoDS_Edge& theEdge1, const TopoDS_Edge& theEdge2)
4514 TopoDS_Vertex V11, V12, V21, V22;
4515 TopExp::Vertices(theEdge1, V11, V12);
4516 TopExp::Vertices(theEdge2, V21, V22);
4517 gp_Pnt P11 = BRep_Tool::Pnt(V11);
4518 gp_Pnt P12 = BRep_Tool::Pnt(V12);
4519 gp_Pnt P21 = BRep_Tool::Pnt(V21);
4520 gp_Pnt P22 = BRep_Tool::Pnt(V22);
4521 bool coincide = false;
4523 //Check that ends of edges coincide
4524 if(P11.Distance(P21) <= MAX_TOLERANCE) {
4525 if(P12.Distance(P22) <= MAX_TOLERANCE) coincide = true;
4527 else if(P11.Distance(P22) <= MAX_TOLERANCE) {
4528 if(P12.Distance(P21) <= MAX_TOLERANCE) coincide = true;
4531 if(!coincide) return false;
4533 if (BRep_Tool::Degenerated(theEdge1))
4534 if (BRep_Tool::Degenerated(theEdge2)) return true;
4537 if (BRep_Tool::Degenerated(theEdge2)) return false;
4539 double U11, U12, U21, U22;
4540 Handle(Geom_Curve) C1 = BRep_Tool::Curve(theEdge1, U11, U12);
4541 Handle(Geom_Curve) C2 = BRep_Tool::Curve(theEdge2, U21, U22);
4542 if(C1->DynamicType() == C2->DynamicType()) return true;
4544 //Check that both edges has the same geometry
4545 double range = U12-U11;
4546 double U = U11+ range/3.0;
4547 gp_Pnt P1 = C1->Value(U); //Compute a point on one third of the edge's length
4548 U = U11+range*2.0/3.0;
4549 gp_Pnt P2 = C1->Value(U); //Compute a point on two thirds of the edge's length
4551 if(!GeomLib_Tool::Parameter(C2, P1, MAX_TOLERANCE, U) || U < U21 || U > U22)
4554 if(P1.Distance(C2->Value(U)) > MAX_TOLERANCE) return false;
4556 if(!GeomLib_Tool::Parameter(C2, P2, MAX_TOLERANCE, U) || U < U21 || U > U22)
4559 if(P2.Distance(C2->Value(U)) > MAX_TOLERANCE) return false;
4564 #include <TopoDS_TShape.hxx>
4565 //=======================================================================
4566 //function : isSameFace
4567 //purpose : Returns True if two faces coincide
4568 //=======================================================================
4569 static bool isSameFace(const TopoDS_Face& theFace1, const TopoDS_Face& theFace2)
4571 TopExp_Explorer E(theFace1, TopAbs_EDGE);
4572 TopTools_ListOfShape LS1, LS2;
4573 for(; E.More(); E.Next()) LS1.Append(E.Current());
4575 E.Init(theFace2, TopAbs_EDGE);
4576 for(; E.More(); E.Next()) LS2.Append(E.Current());
4578 //Compare the number of edges in the faces
4579 if(LS1.Extent() != LS2.Extent()) return false;
4581 double aMin = RealFirst(), aMax = RealLast();
4582 double xminB1=aMax, yminB1=aMax, zminB1=aMax, xminB2=aMax, yminB2=aMax, zminB2=aMax;
4583 double xmaxB1=aMin, ymaxB1=aMin, zmaxB1=aMin, xmaxB2=aMin, ymaxB2=aMin, zmaxB2=aMin;
4585 for(E.Init(theFace1, TopAbs_VERTEX); E.More(); E.Next()) {
4586 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4587 if(P.X() < xminB1) xminB1 = P.X();
4588 if(P.Y() < yminB1) yminB1 = P.Y();
4589 if(P.Z() < zminB1) zminB1 = P.Z();
4590 if(P.X() > xmaxB1) xmaxB1 = P.X();
4591 if(P.Y() > ymaxB1) ymaxB1 = P.Y();
4592 if(P.Z() > zmaxB1) zmaxB1 = P.Z();
4595 for(E.Init(theFace2, TopAbs_VERTEX); E.More(); E.Next()) {
4596 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4597 if(P.X() < xminB2) xminB2 = P.X();
4598 if(P.Y() < yminB2) yminB2 = P.Y();
4599 if(P.Z() < zminB2) zminB2 = P.Z();
4600 if(P.X() > xmaxB2) xmaxB2 = P.X();
4601 if(P.Y() > ymaxB2) ymaxB2 = P.Y();
4602 if(P.Z() > zmaxB2) zmaxB2 = P.Z();
4605 //Compare the bounding boxes of both faces
4606 if(gp_Pnt(xminB1, yminB1, zminB1).Distance(gp_Pnt(xminB2, yminB2, zminB2)) > MAX_TOLERANCE)
4609 if(gp_Pnt(xmaxB1, ymaxB1, zmaxB1).Distance(gp_Pnt(xmaxB2, ymaxB2, zmaxB2)) > MAX_TOLERANCE)
4612 Handle(Geom_Surface) S1 = BRep_Tool::Surface(theFace1);
4613 Handle(Geom_Surface) S2 = BRep_Tool::Surface(theFace2);
4615 //Check if there a coincidence of two surfaces at least in two points
4616 double U11, U12, V11, V12, U21, U22, V21, V22;
4617 BRepTools::UVBounds(theFace1, U11, U12, V11, V12);
4618 BRepTools::UVBounds(theFace2, U21, U22, V21, V22);
4620 double rangeU = U12-U11;
4621 double rangeV = V12-V11;
4622 double U = U11 + rangeU/3.0;
4623 double V = V11 + rangeV/3.0;
4624 gp_Pnt P1 = S1->Value(U, V);
4625 U = U11+rangeU*2.0/3.0;
4626 V = V11+rangeV*2.0/3.0;
4627 gp_Pnt P2 = S1->Value(U, V);
4629 if (!GeomLib_Tool::Parameters(S2, P1, MAX_TOLERANCE, U, V) || U < U21 || U > U22 || V < V21 || V > V22)
4632 if (P1.Distance(S2->Value(U,V)) > MAX_TOLERANCE) return false;
4634 if (!GeomLib_Tool::Parameters(S2, P2, MAX_TOLERANCE, U, V) || U < U21 || U > U22 || V < V21 || V > V22)
4637 if (P2.Distance(S2->Value(U, V)) > MAX_TOLERANCE) return false;
4639 //Check that each edge of the Face1 has a counterpart in the Face2
4640 TopTools_MapOfOrientedShape aMap;
4641 TopTools_ListIteratorOfListOfShape LSI1(LS1);
4642 for(; LSI1.More(); LSI1.Next()) {
4643 TopoDS_Edge E = TopoDS::Edge(LSI1.Value());
4644 bool isFound = false;
4645 TopTools_ListIteratorOfListOfShape LSI2(LS2);
4646 for(; LSI2.More(); LSI2.Next()) {
4647 TopoDS_Shape aValue = LSI2.Value();
4648 if(aMap.Contains(aValue)) continue; //To avoid checking already found edge several times
4649 if(isSameEdge(E, TopoDS::Edge(aValue))) {
4655 if(!isFound) return false;
4661 //=======================================================================
4662 //function : isSameSolid
4663 //purpose : Returns True if two solids coincide
4664 //=======================================================================
4665 bool isSameSolid(const TopoDS_Solid& theSolid1, const TopoDS_Solid& theSolid2)
4667 TopExp_Explorer E(theSolid1, TopAbs_FACE);
4668 TopTools_ListOfShape LS1, LS2;
4669 for(; E.More(); E.Next()) LS1.Append(E.Current());
4670 E.Init(theSolid2, TopAbs_FACE);
4671 for(; E.More(); E.Next()) LS2.Append(E.Current());
4673 if(LS1.Extent() != LS2.Extent()) return false;
4675 double aMin = RealFirst(), aMax = RealLast();
4676 double xminB1=aMax, yminB1=aMax, zminB1=aMax, xminB2=aMax, yminB2=aMax, zminB2=aMax;
4677 double xmaxB1=aMin, ymaxB1=aMin, zmaxB1=aMin, xmaxB2=aMin, ymaxB2=aMin, zmaxB2=aMin;
4679 for(E.Init(theSolid1, TopAbs_VERTEX); E.More(); E.Next()) {
4680 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4681 if(P.X() < xminB1) xminB1 = P.X();
4682 if(P.Y() < yminB1) yminB1 = P.Y();
4683 if(P.Z() < zminB1) zminB1 = P.Z();
4684 if(P.X() > xmaxB1) xmaxB1 = P.X();
4685 if(P.Y() > ymaxB1) ymaxB1 = P.Y();
4686 if(P.Z() > zmaxB1) zmaxB1 = P.Z();
4689 for(E.Init(theSolid2, TopAbs_VERTEX); E.More(); E.Next()) {
4690 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4691 if(P.X() < xminB2) xminB2 = P.X();
4692 if(P.Y() < yminB2) yminB2 = P.Y();
4693 if(P.Z() < zminB2) zminB2 = P.Z();
4694 if(P.X() > xmaxB2) xmaxB2 = P.X();
4695 if(P.Y() > ymaxB2) ymaxB2 = P.Y();
4696 if(P.Z() > zmaxB2) zmaxB2 = P.Z();
4699 //Compare the bounding boxes of both solids
4700 if(gp_Pnt(xminB1, yminB1, zminB1).Distance(gp_Pnt(xminB2, yminB2, zminB2)) > MAX_TOLERANCE)
4703 if(gp_Pnt(xmaxB1, ymaxB1, zmaxB1).Distance(gp_Pnt(xmaxB2, ymaxB2, zmaxB2)) > MAX_TOLERANCE)
4706 //Check that each face of the Solid1 has a counterpart in the Solid2
4707 TopTools_MapOfOrientedShape aMap;
4708 TopTools_ListIteratorOfListOfShape LSI1(LS1);
4709 for(; LSI1.More(); LSI1.Next()) {
4710 TopoDS_Face F = TopoDS::Face(LSI1.Value());
4711 bool isFound = false;
4712 TopTools_ListIteratorOfListOfShape LSI2(LS2);
4713 for(; LSI2.More(); LSI2.Next()) {
4714 if(aMap.Contains(LSI2.Value())) continue; //To avoid checking already found faces several times
4715 if(isSameFace(F, TopoDS::Face(LSI2.Value()))) {
4716 aMap.Add(LSI2.Value());
4721 if(!isFound) return false;
4727 //=======================================================================
4728 //function : GetSame
4730 //=======================================================================
4731 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetSame(const Handle(GEOM_Object)& theShapeWhere,
4732 const Handle(GEOM_Object)& theShapeWhat)
4735 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
4737 TopoDS_Shape aWhere = theShapeWhere->GetValue();
4738 TopoDS_Shape aWhat = theShapeWhat->GetValue();
4740 if (aWhere.IsNull() || aWhat.IsNull()) return NULL;
4743 bool isFound = false;
4744 TopoDS_Shape aSubShape;
4745 TopTools_MapOfShape aMap;
4747 if (aWhat.ShapeType() == TopAbs_COMPOUND || aWhat.ShapeType() == TopAbs_COMPSOLID) {
4748 TopoDS_Iterator It (aWhat, Standard_True, Standard_True);
4749 if (It.More()) aWhat = It.Value();
4752 SetErrorCode("Compounds of two or more shapes are not allowed for aWhat argument");
4757 switch (aWhat.ShapeType()) {
4758 case TopAbs_VERTEX: {
4759 aSubShape = getSameVertex(aWhere, TopoDS::Vertex(aWhat));
4760 isFound = !aSubShape.IsNull();
4764 TopoDS_Edge anEdge = TopoDS::Edge(aWhat);
4765 TopExp_Explorer E(aWhere, TopAbs_EDGE);
4766 for(; E.More(); E.Next()) {
4767 if(!aMap.Add(E.Current())) continue;
4768 if(isSameEdge(anEdge, TopoDS::Edge(E.Current()))) {
4769 aSubShape = E.Current();
4777 TopoDS_Face aFace = TopoDS::Face(aWhat);
4778 TopExp_Explorer E(aWhere, TopAbs_FACE);
4779 for(; E.More(); E.Next()) {
4780 if(!aMap.Add(E.Current())) continue;
4781 if(isSameFace(aFace, TopoDS::Face(E.Current()))) {
4782 aSubShape = E.Current();
4789 case TopAbs_SOLID: {
4790 TopoDS_Solid aSolid = TopoDS::Solid(aWhat);
4791 TopExp_Explorer E(aWhere, TopAbs_SOLID);
4792 for(; E.More(); E.Next()) {
4793 if(!aMap.Add(E.Current())) continue;
4794 if(isSameSolid(aSolid, TopoDS::Solid(E.Current()))) {
4795 aSubShape = E.Current();
4807 TopTools_IndexedMapOfShape anIndices;
4808 TopExp::MapShapes(aWhere, anIndices);
4809 if (anIndices.Contains(aSubShape))
4810 anIndex = anIndices.FindIndex(aSubShape);
4813 if (anIndex < 0) return NULL;
4815 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
4817 anArray->SetValue(1, anIndex);
4819 Handle(GEOM_Object) aResult = GetEngine()->AddSubShape(theShapeWhere, anArray);
4820 Handle(GEOM_Function) aFunction = aResult->GetLastFunction();
4822 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetSame("
4823 << theShapeWhere << ", " << theShapeWhat << ")";
4831 //=======================================================================
4832 //function : GetSameIDs
4834 //=======================================================================
4835 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetSameIDs
4836 (const Handle(GEOM_Object)& theShapeWhere,
4837 const Handle(GEOM_Object)& theShapeWhat)
4840 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
4842 TopoDS_Shape aWhere = theShapeWhere->GetValue();
4843 TopoDS_Shape aWhat = theShapeWhat->GetValue();
4845 if (aWhere.IsNull() || aWhat.IsNull()) return NULL;
4847 TopTools_ListOfShape listShape;
4848 TopTools_MapOfShape aMap;
4850 if (aWhat.ShapeType() == TopAbs_COMPOUND || aWhat.ShapeType() == TopAbs_COMPSOLID) {
4851 TopoDS_Iterator It (aWhat, Standard_True, Standard_True);
4852 if (It.More()) aWhat = It.Value();
4855 SetErrorCode("Compounds of two or more shapes are not allowed for aWhat argument");
4860 switch (aWhat.ShapeType()) {
4861 case TopAbs_VERTEX: {
4862 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(aWhat));
4863 TopExp_Explorer E(aWhere, TopAbs_VERTEX);
4864 for(; E.More(); E.Next()) {
4865 if(!aMap.Add(E.Current())) continue;
4866 gp_Pnt P2 = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4867 if(P.Distance(P2) <= MAX_TOLERANCE) {
4868 listShape.Append(E.Current());
4874 TopoDS_Edge anEdge = TopoDS::Edge(aWhat);
4875 TopExp_Explorer E(aWhere, TopAbs_EDGE);
4876 for(; E.More(); E.Next()) {
4877 if(!aMap.Add(E.Current())) continue;
4878 if(isSameEdge(anEdge, TopoDS::Edge(E.Current()))) {
4879 listShape.Append(E.Current());
4885 TopoDS_Face aFace = TopoDS::Face(aWhat);
4886 TopExp_Explorer E(aWhere, TopAbs_FACE);
4887 for(; E.More(); E.Next()) {
4888 if(!aMap.Add(E.Current())) continue;
4889 if(isSameFace(aFace, TopoDS::Face(E.Current()))) {
4890 listShape.Append(E.Current());
4895 case TopAbs_SOLID: {
4896 TopoDS_Solid aSolid = TopoDS::Solid(aWhat);
4897 TopExp_Explorer E(aWhere, TopAbs_SOLID);
4898 for(; E.More(); E.Next()) {
4899 if(!aMap.Add(E.Current())) continue;
4900 if(isSameSolid(aSolid, TopoDS::Solid(E.Current()))) {
4901 listShape.Append(E.Current());
4910 if ( !listShape.IsEmpty() ) {
4911 TopTools_IndexedMapOfShape anIndices;
4912 TopExp::MapShapes(aWhere, anIndices);
4913 TopTools_ListIteratorOfListOfShape itSub (listShape);
4914 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
4915 for (; itSub.More(); itSub.Next()) {
4916 if (anIndices.Contains(itSub.Value()))
4917 aSeq->Append(anIndices.FindIndex(itSub.Value()));
4920 // The GetSameIDs() doesn't change object so no new function is required.
4921 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShapeWhere,theShapeWhat)->GetLastFunction();
4923 // Make a Python command
4924 GEOM::TPythonDump(aFunction, /*append=*/true)
4925 << "listSameIDs = geompy.GetSameIDs("
4926 << theShapeWhere << ", "
4927 << theShapeWhat << ")";
4930 SetErrorCode(NOT_FOUND_ANY);