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"
37 #include "GEOMImpl_FillingDriver.hxx"
39 #include "GEOMImpl_IVector.hxx"
40 #include "GEOMImpl_IShapes.hxx"
41 #include "GEOMImpl_IShapeExtend.hxx"
42 #include "GEOMImpl_IGlue.hxx"
43 #include "GEOMImpl_IFilling.hxx"
45 #include "GEOMImpl_Block6Explorer.hxx"
46 #include "GEOMImpl_IHealingOperations.hxx"
48 #include "GEOMImpl_Gen.hxx"
50 #include "GEOM_Function.hxx"
51 #include "GEOM_ISubShape.hxx"
52 #include "GEOM_PythonDump.hxx"
54 #include "GEOMUtils.hxx"
56 #include "GEOMAlgo_ClsfBox.hxx"
57 #include "GEOMAlgo_ClsfSolid.hxx"
58 #include "GEOMAlgo_CoupleOfShapes.hxx"
59 #include "GEOMAlgo_FinderShapeOn1.hxx"
60 #include "GEOMAlgo_FinderShapeOnQuad.hxx"
61 #include "GEOMAlgo_FinderShapeOn2.hxx"
62 #include "GEOMAlgo_GetInPlace.hxx"
63 #include "GEOMAlgo_GlueDetector.hxx"
64 #include "GEOMAlgo_ListIteratorOfListOfCoupleOfShapes.hxx"
65 #include "GEOMAlgo_ListOfCoupleOfShapes.hxx"
67 #include <Basics_OCCTVersion.hxx>
69 #include <utilities.h>
71 #include <Utils_ExceptHandlers.hxx>
73 #include <BRepAdaptor_Curve.hxx>
74 #include <BRepAdaptor_Surface.hxx>
75 #include <BRepBndLib.hxx>
76 #include <BRepBuilderAPI_MakeVertex.hxx>
77 #include <BRepClass3d_SolidClassifier.hxx>
78 #include <BRepClass_FaceClassifier.hxx>
79 #include <BRepExtrema_DistShapeShape.hxx>
80 #include <BRepExtrema_ExtCF.hxx>
81 #include <BRepGProp.hxx>
82 #include <BRepMesh_IncrementalMesh.hxx>
83 #include <BRepTools.hxx>
84 #include <BRep_Builder.hxx>
85 #include <BRep_Tool.hxx>
86 #include <Bnd_Box.hxx>
87 #include <GEOMImpl_IMeasure.hxx>
88 #include <GEOMImpl_MeasureDriver.hxx>
89 #include <GProp_GProps.hxx>
90 #include <Geom2d_Curve.hxx>
91 #include <GeomAdaptor_Surface.hxx>
92 #include <GeomLib_Tool.hxx>
93 #include <Geom_CylindricalSurface.hxx>
94 #include <Geom_Plane.hxx>
95 #include <Geom_SphericalSurface.hxx>
96 #include <Geom_Surface.hxx>
97 #include <Precision.hxx>
98 #include <TColStd_Array1OfReal.hxx>
99 #include <TColStd_HArray1OfInteger.hxx>
100 #include <TColStd_ListIteratorOfListOfInteger.hxx>
101 #include <TColStd_ListOfInteger.hxx>
102 #include <TDF_Tool.hxx>
103 #include <TDataStd_Integer.hxx>
104 #include <TDataStd_IntegerArray.hxx>
105 #include <TDataStd_ListIteratorOfListOfExtendedString.hxx>
106 #include <TFunction_Driver.hxx>
107 #include <TFunction_DriverTable.hxx>
108 #include <TFunction_Logbook.hxx>
109 #include <TopAbs.hxx>
110 #include <TopExp.hxx>
111 #include <TopExp_Explorer.hxx>
112 #include <TopLoc_Location.hxx>
113 #include <TopTools_Array1OfShape.hxx>
114 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
115 #include <TopTools_IndexedMapOfShape.hxx>
116 #include <TopTools_ListIteratorOfListOfShape.hxx>
117 #include <TopTools_MapOfOrientedShape.hxx>
118 #include <TopTools_MapOfShape.hxx>
119 #include <TopTools_SequenceOfShape.hxx>
120 #include <TopoDS.hxx>
121 #include <TopoDS_Compound.hxx>
122 #include <TopoDS_Edge.hxx>
123 #include <TopoDS_Face.hxx>
124 #include <TopoDS_Iterator.hxx>
125 #include <TopoDS_Shape.hxx>
126 #include <TopoDS_Solid.hxx>
127 #include <TopoDS_Vertex.hxx>
128 #include <gp_Cylinder.hxx>
129 #include <gp_Lin.hxx>
130 #include <gp_Pnt.hxx>
134 #include <functional>
136 #include <Standard_NullObject.hxx>
137 #include <Standard_Failure.hxx>
138 #include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
142 //================================================================================
144 * \brief Return normal to face at extrema point
146 //================================================================================
148 gp_Vec GetNormal (const TopoDS_Face& face, const BRepExtrema_DistShapeShape& extrema)
150 gp_Vec defaultNorm(1,0,0); // to have same normals on different faces
152 // get UV at extrema point
153 Standard_Real u,v, f,l;
154 switch ( extrema.SupportTypeShape2(1) ) {
155 case BRepExtrema_IsInFace: {
156 extrema.ParOnFaceS2(1, u, v );
159 case BRepExtrema_IsOnEdge: {
160 TopoDS_Edge edge = TopoDS::Edge( extrema.SupportOnShape2(1));
161 Handle(Geom2d_Curve) pcurve = BRep_Tool::CurveOnSurface( edge, face, f,l );
162 extrema.ParOnEdgeS2( 1, u );
163 gp_Pnt2d uv = pcurve->Value( u );
168 case BRepExtrema_IsVertex: return defaultNorm;
171 BRepAdaptor_Surface surface( face, false );
172 gp_Vec du, dv; gp_Pnt p;
173 surface.D1( u, v, p, du, dv );
177 } catch (Standard_Failure ) {
182 void AddFlatSubShapes(const TopoDS_Shape& S, TopTools_ListOfShape& L, TopTools_MapOfShape& M)
184 if (S.ShapeType() != TopAbs_COMPOUND) {
188 TopoDS_Iterator It(S, Standard_True, Standard_True);
189 for (; It.More(); It.Next()) {
190 TopoDS_Shape SS = It.Value();
192 AddFlatSubShapes(SS, L, M);
198 //=============================================================================
202 //=============================================================================
203 GEOMImpl_IShapesOperations::GEOMImpl_IShapesOperations (GEOM_Engine* theEngine, int theDocID)
204 : GEOM_IOperations(theEngine, theDocID)
206 MESSAGE("GEOMImpl_IShapesOperations::GEOMImpl_IShapesOperations");
209 //=============================================================================
213 //=============================================================================
214 GEOMImpl_IShapesOperations::~GEOMImpl_IShapesOperations()
216 MESSAGE("GEOMImpl_IShapesOperations::~GEOMImpl_IShapesOperations");
219 //=============================================================================
223 //=============================================================================
224 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeEdge
225 (Handle(GEOM_Object) thePnt1, Handle(GEOM_Object) thePnt2)
229 if (thePnt1.IsNull() || thePnt2.IsNull()) return NULL;
231 //Add a new Edge object
232 Handle(GEOM_Object) anEdge = GetEngine()->AddObject(GetDocID(), GEOM_EDGE);
234 //Add a new Vector function
235 Handle(GEOM_Function) aFunction =
236 anEdge->AddFunction(GEOMImpl_VectorDriver::GetID(), VECTOR_TWO_PNT);
238 //Check if the function is set correctly
239 if (aFunction->GetDriverGUID() != GEOMImpl_VectorDriver::GetID()) return NULL;
241 GEOMImpl_IVector aPI (aFunction);
243 Handle(GEOM_Function) aRef1 = thePnt1->GetLastFunction();
244 Handle(GEOM_Function) aRef2 = thePnt2->GetLastFunction();
245 if (aRef1.IsNull() || aRef2.IsNull()) return NULL;
247 aPI.SetPoint1(aRef1);
248 aPI.SetPoint2(aRef2);
250 //Compute the Edge value
253 if (!GetSolver()->ComputeFunction(aFunction)) {
254 SetErrorCode("Vector driver failed");
258 catch (Standard_Failure) {
259 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
260 SetErrorCode(aFail->GetMessageString());
264 //Make a Python command
265 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdge("
266 << thePnt1 << ", " << thePnt2 << ")";
272 //=============================================================================
274 * MakeEdgeOnCurveByLength
276 //=============================================================================
277 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeEdgeOnCurveByLength
278 (Handle(GEOM_Object) theRefCurve,
279 const Standard_Real theLength,
280 Handle(GEOM_Object) theStartPoint)
284 if (theRefCurve.IsNull()) return NULL;
286 //Add a new Edge object
287 Handle(GEOM_Object) anEdge = GetEngine()->AddObject(GetDocID(), GEOM_EDGE);
289 //Add a new Vector function
290 Handle(GEOM_Function) aFunction =
291 anEdge->AddFunction(GEOMImpl_ShapeDriver::GetID(), EDGE_CURVE_LENGTH);
293 //Check if the function is set correctly
294 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
296 GEOMImpl_IVector aPI (aFunction);
298 Handle(GEOM_Function) aRef1 = theRefCurve->GetLastFunction();
299 if (aRef1.IsNull()) return NULL;
300 aPI.SetPoint1(aRef1);
302 if (!theStartPoint.IsNull()) {
303 Handle(GEOM_Function) aRef2 = theStartPoint->GetLastFunction();
304 aPI.SetPoint2(aRef2);
307 aPI.SetParameter(theLength);
309 //Compute the Edge value
312 if (!GetSolver()->ComputeFunction(aFunction)) {
313 SetErrorCode("Vector driver failed");
317 catch (Standard_Failure) {
318 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
319 SetErrorCode(aFail->GetMessageString());
323 //Make a Python command
324 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdgeOnCurveByLength("
325 << theRefCurve << ", " << theLength << ", " << theStartPoint << ")";
331 //=============================================================================
335 //=============================================================================
336 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeEdgeWire
337 (Handle(GEOM_Object) theWire,
338 const Standard_Real theLinearTolerance,
339 const Standard_Real theAngularTolerance)
343 if (theWire.IsNull()) return NULL;
345 //Add a new Edge object
346 Handle(GEOM_Object) anEdge = GetEngine()->AddObject(GetDocID(), GEOM_EDGE);
348 //Add a new Vector function
349 Handle(GEOM_Function) aFunction =
350 anEdge->AddFunction(GEOMImpl_ShapeDriver::GetID(), EDGE_WIRE);
352 //Check if the function is set correctly
353 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
355 GEOMImpl_IShapes aCI (aFunction);
357 Handle(GEOM_Function) aWire = theWire->GetLastFunction();
359 if (aWire.IsNull()) return NULL;
362 aCI.SetTolerance(theLinearTolerance);
363 aCI.SetAngularTolerance(theAngularTolerance);
365 //Compute the Edge value
368 if (!GetSolver()->ComputeFunction(aFunction)) {
369 SetErrorCode("Shape driver failed");
373 catch (Standard_Failure) {
374 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
375 SetErrorCode(aFail->GetMessageString());
379 const double DEF_LIN_TOL = Precision::Confusion();
380 const double DEF_ANG_TOL = Precision::Angular();
381 //Make a Python command
382 if ( theAngularTolerance == DEF_ANG_TOL ) {
383 if ( theLinearTolerance == DEF_LIN_TOL )
384 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdgeWire("
387 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdgeWire("
388 << theWire << ", " << theLinearTolerance << ")";
391 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdgeWire("
392 << theWire << ", " << theLinearTolerance << ", "
393 << theAngularTolerance << ")";
400 //=============================================================================
404 //=============================================================================
405 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeWire
406 (std::list<Handle(GEOM_Object)> theShapes,
407 const Standard_Real theTolerance)
412 Handle(GEOM_Object) aWire = GetEngine()->AddObject(GetDocID(), GEOM_WIRE);
415 Handle(GEOM_Function) aFunction =
416 aWire->AddFunction(GEOMImpl_ShapeDriver::GetID(), WIRE_EDGES);
417 if (aFunction.IsNull()) return NULL;
419 //Check if the function is set correctly
420 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
422 GEOMImpl_IShapes aCI (aFunction);
423 aCI.SetTolerance(theTolerance);
425 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
428 std::list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
429 for (; it != theShapes.end(); it++) {
430 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
431 if (aRefSh.IsNull()) {
432 SetErrorCode("NULL argument shape for the shape construction");
435 aShapesSeq->Append(aRefSh);
437 aCI.SetShapes(aShapesSeq);
442 if (!GetSolver()->ComputeFunction(aFunction)) {
443 SetErrorCode("Shape driver failed");
447 catch (Standard_Failure) {
448 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
449 SetErrorCode(aFail->GetMessageString());
453 //Make a Python command
454 GEOM::TPythonDump pd (aFunction);
455 pd << aWire << " = geompy.MakeWire([";
458 it = theShapes.begin();
459 if (it != theShapes.end()) {
461 while (it != theShapes.end()) {
462 pd << ", " << (*it++);
465 pd << "], " << theTolerance << ")";
471 //=============================================================================
475 //=============================================================================
476 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFace (Handle(GEOM_Object) theWire,
477 const bool isPlanarWanted)
481 if (theWire.IsNull()) return NULL;
483 //Add a new Face object
484 Handle(GEOM_Object) aFace = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
486 //Add a new Shape function for creation of a face from a wire
487 Handle(GEOM_Function) aFunction =
488 aFace->AddFunction(GEOMImpl_ShapeDriver::GetID(), FACE_WIRE);
489 if (aFunction.IsNull()) return NULL;
491 //Check if the function is set correctly
492 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
494 GEOMImpl_IShapes aCI (aFunction);
496 Handle(GEOM_Function) aRefWire = theWire->GetLastFunction();
498 if (aRefWire.IsNull()) return NULL;
500 aCI.SetBase(aRefWire);
501 aCI.SetIsPlanar(isPlanarWanted);
503 //Compute the Face value
504 Standard_Boolean isWarning = Standard_False;
507 if (!GetSolver()->ComputeFunction(aFunction)) {
508 SetErrorCode("Shape driver failed to compute a face");
512 catch (Standard_Failure) {
513 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
514 SetErrorCode(aFail->GetMessageString());
515 // to provide warning
516 if (!aFunction->GetValue().IsNull()) {
517 isWarning = Standard_True;
523 //Make a Python command
524 GEOM::TPythonDump(aFunction) << aFace << " = geompy.MakeFace("
525 << theWire << ", " << (int)isPlanarWanted << ")";
527 // to provide warning
528 if (!isWarning) SetErrorCode(OK);
532 //=============================================================================
536 //=============================================================================
537 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFaceWires
538 (std::list<Handle(GEOM_Object)> theShapes,
539 const bool isPlanarWanted)
544 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
547 Handle(GEOM_Function) aFunction =
548 aShape->AddFunction(GEOMImpl_ShapeDriver::GetID(), FACE_WIRES);
549 if (aFunction.IsNull()) return NULL;
551 //Check if the function is set correctly
552 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
554 GEOMImpl_IShapes aCI (aFunction);
556 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
559 std::list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
560 for (; it != theShapes.end(); it++) {
561 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
562 if (aRefSh.IsNull()) {
563 SetErrorCode("NULL argument shape for the face construction");
566 aShapesSeq->Append(aRefSh);
568 aCI.SetShapes(aShapesSeq);
570 aCI.SetIsPlanar(isPlanarWanted);
573 Standard_Boolean isWarning = Standard_False;
576 if (!GetSolver()->ComputeFunction(aFunction)) {
577 SetErrorCode("Shape driver failed");
581 catch (Standard_Failure) {
582 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
583 SetErrorCode(aFail->GetMessageString());
584 // to provide warning
585 if (!aFunction->GetValue().IsNull()) {
586 isWarning = Standard_True;
592 //Make a Python command
593 GEOM::TPythonDump pd (aFunction);
594 pd << aShape << " = geompy.MakeFaceWires([";
597 it = theShapes.begin();
598 if (it != theShapes.end()) {
600 while (it != theShapes.end()) {
601 pd << ", " << (*it++);
604 pd << "], " << (int)isPlanarWanted << ")";
606 // to provide warning
607 if (!isWarning) SetErrorCode(OK);
611 //=============================================================================
613 * MakeFaceFromSurface
615 //=============================================================================
616 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFaceFromSurface
617 (Handle(GEOM_Object) theFace,
618 Handle(GEOM_Object) theWire)
623 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
626 Handle(GEOM_Function) aFunction =
627 aShape->AddFunction(GEOMImpl_ShapeDriver::GetID(), FACE_FROM_SURFACE);
629 if (aFunction.IsNull()) {
633 //Check if the function is set correctly
634 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) {
638 GEOMImpl_IShapes aCI (aFunction);
639 Handle(TColStd_HSequenceOfTransient) aShapesSeq =
640 new TColStd_HSequenceOfTransient;
641 Handle(GEOM_Function) aRefFace = theFace->GetLastFunction();
642 Handle(GEOM_Function) aRefWire = theWire->GetLastFunction();
644 if (aRefFace.IsNull()) {
645 SetErrorCode("NULL argument face for the face construction");
649 if (aRefWire.IsNull()) {
650 SetErrorCode("NULL argument wire for the face construction");
654 aShapesSeq->Append(aRefFace);
655 aShapesSeq->Append(aRefWire);
657 aCI.SetShapes(aShapesSeq);
662 if (!GetSolver()->ComputeFunction(aFunction)) {
663 SetErrorCode("Shape driver failed");
667 catch (Standard_Failure) {
668 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
669 SetErrorCode(aFail->GetMessageString());
673 //Make a Python command
674 GEOM::TPythonDump (aFunction) << aShape
675 << " = geompy.MakeFaceFromSurface(" << theFace << ", " << theWire << ")";
682 //=============================================================================
684 * MakeFaceWithConstraints
686 //=============================================================================
687 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFaceWithConstraints
688 (std::list<Handle(GEOM_Object)> theConstraints)
693 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_FILLING);
696 Handle(GEOM_Function) aFunction =
697 aShape->AddFunction(GEOMImpl_FillingDriver::GetID(), FILLING_ON_CONSTRAINTS);
698 if (aFunction.IsNull()) return NULL;
700 //Check if the function is set correctly
701 if (aFunction->GetDriverGUID() != GEOMImpl_FillingDriver::GetID()) return NULL;
703 GEOMImpl_IFilling aCI (aFunction);
704 Handle(TColStd_HSequenceOfTransient) aConstraints = new TColStd_HSequenceOfTransient;
707 std::list<Handle(GEOM_Object)>::iterator it = theConstraints.begin();
708 while (it != theConstraints.end()) {
709 Handle(GEOM_Object) anObject = (*it);
710 if ( anObject.IsNull() || anObject->GetValue().ShapeType() != TopAbs_EDGE ) {
711 SetErrorCode("NULL argument edge for the face construction");
714 Handle(GEOM_Function) aRefSh = anObject->GetLastFunction();
715 aConstraints->Append(aRefSh);
717 if ( it != theConstraints.end() ) {
718 Handle(GEOM_Object) aFace = (*it);
719 if ( aFace.IsNull() ) {
720 // null constraint face - it is a valid case
724 if ( aFace->GetValue().ShapeType() != TopAbs_FACE )
725 // constraint face can be omitted - it is a valid case
727 if ( IsSubShapeBelongsTo( anObject, 0, aFace, 0 ) ) {
729 aRefSh = aFace->GetLastFunction();
730 aConstraints->Append(aRefSh);
735 SetErrorCode("Face is NULL or not connected to the Edge");
740 aCI.SetShapes( aConstraints );
743 Standard_Boolean isWarning = Standard_False;
746 if (!GetSolver()->ComputeFunction(aFunction)) {
747 SetErrorCode("Shape driver failed");
751 catch (Standard_Failure) {
752 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
753 SetErrorCode(aFail->GetMessageString());
754 // to provide warning
755 if (!aFunction->GetValue().IsNull()) {
756 isWarning = Standard_True;
762 //Make a Python command
763 GEOM::TPythonDump pd (aFunction);
764 pd << aShape << " = geompy.MakeFaceWithConstraints([";
767 it = theConstraints.begin();
768 if (it != theConstraints.end() ) {
770 while (it != theConstraints.end()) {
771 Handle(GEOM_Object) anObject = (*it++);
772 if( !anObject.IsNull() )
773 pd << ", " << anObject;
778 // to provide warning
779 if (!isWarning) SetErrorCode(OK);
783 //=============================================================================
787 //=============================================================================
788 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeShell
789 (std::list<Handle(GEOM_Object)> theShapes)
791 return MakeShape(theShapes, GEOM_SHELL, SHELL_FACES, "MakeShell");
794 //=============================================================================
798 //=============================================================================
799 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeSolidShells
800 (std::list<Handle(GEOM_Object)> theShapes)
802 return MakeShape(theShapes, GEOM_SOLID, SOLID_SHELLS, "MakeSolid");
805 //=============================================================================
809 //=============================================================================
810 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeCompound
811 (std::list<Handle(GEOM_Object)> theShapes)
813 return MakeShape(theShapes, GEOM_COMPOUND, COMPOUND_SHAPES, "MakeCompound");
816 //=============================================================================
820 //=============================================================================
821 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeShape
822 (std::list<Handle(GEOM_Object)> theShapes,
823 const Standard_Integer theObjectType,
824 const Standard_Integer theFunctionType,
825 const TCollection_AsciiString& theMethodName)
830 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), theObjectType);
833 Handle(GEOM_Function) aFunction =
834 aShape->AddFunction(GEOMImpl_ShapeDriver::GetID(), theFunctionType);
835 if (aFunction.IsNull()) return NULL;
837 //Check if the function is set correctly
838 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
840 GEOMImpl_IShapes aCI (aFunction);
842 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
845 std::list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
846 for (; it != theShapes.end(); it++) {
847 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
848 if (aRefSh.IsNull()) {
849 SetErrorCode("NULL argument shape for the shape construction");
852 aShapesSeq->Append(aRefSh);
854 aCI.SetShapes(aShapesSeq);
859 if (!GetSolver()->ComputeFunction(aFunction)) {
860 SetErrorCode("Shape driver failed");
864 catch (Standard_Failure) {
865 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
866 SetErrorCode(aFail->GetMessageString());
870 //Make a Python command
871 GEOM::TPythonDump pd (aFunction);
872 pd << aShape << " = geompy." << theMethodName.ToCString() << "([";
875 it = theShapes.begin();
876 if (it != theShapes.end()) {
878 while (it != theShapes.end()) {
879 pd << ", " << (*it++);
888 //=============================================================================
890 * MakeSolidFromConnectedFaces
892 //=============================================================================
893 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeSolidFromConnectedFaces
894 (std::list<Handle(GEOM_Object)> theFacesOrShells,
895 const Standard_Boolean isIntersect)
900 Handle(GEOM_Object) aSolid = GetEngine()->AddObject(GetDocID(), GEOM_SOLID);
903 Handle(GEOM_Function) aFunction =
904 aSolid->AddFunction(GEOMImpl_ShapeDriver::GetID(), SOLID_FACES);
905 if (aFunction.IsNull()) return NULL;
907 //Check if the function is set correctly
908 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
910 GEOMImpl_IShapes aCI (aFunction);
912 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
915 std::list<Handle(GEOM_Object)>::iterator it = theFacesOrShells.begin();
916 for (; it != theFacesOrShells.end(); it++) {
917 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
918 if (aRefSh.IsNull()) {
919 SetErrorCode("NULL argument shape for the shape construction");
922 aShapesSeq->Append(aRefSh);
924 aCI.SetShapes(aShapesSeq);
925 aCI.SetIsIntersect(isIntersect);
930 if (!GetSolver()->ComputeFunction(aFunction)) {
931 SetErrorCode("Shape driver failed");
935 catch (Standard_Failure) {
936 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
937 SetErrorCode(aFail->GetMessageString());
941 //Make a Python command
942 GEOM::TPythonDump pd (aFunction);
943 pd << aSolid << " = geompy.MakeSolidFromConnectedFaces([";
946 it = theFacesOrShells.begin();
947 if (it != theFacesOrShells.end()) {
949 while (it != theFacesOrShells.end()) {
950 pd << ", " << (*it++);
953 pd << "]," << (isIntersect ? "True" : "False") << ")";
959 //=============================================================================
963 //=============================================================================
965 GEOMImpl_IShapesOperations::MakeGlueFaces (std::list< Handle(GEOM_Object) >& theShapes,
966 const Standard_Real theTolerance,
967 const Standard_Boolean doKeepNonSolids)
971 Handle(TColStd_HSequenceOfTransient) objects = GEOM_Object::GetLastFunctions( theShapes );
972 if ( objects.IsNull() || objects->IsEmpty() ) {
973 SetErrorCode("NULL argument shape");
977 //Add a new Glued object
978 Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
980 //Add a new Glue function
981 Handle(GEOM_Function) aFunction;
982 aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_FACES);
983 if (aFunction.IsNull()) return NULL;
985 //Check if the function is set correctly
986 if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
988 GEOMImpl_IGlue aCI (aFunction);
990 aCI.SetBase( objects );
991 aCI.SetTolerance(theTolerance);
992 aCI.SetKeepNonSolids(doKeepNonSolids);
994 //Compute the sub-shape value
995 Standard_Boolean isWarning = Standard_False;
998 if (!GetSolver()->ComputeFunction(aFunction)) {
999 SetErrorCode("Shape driver failed to glue faces");
1003 catch (Standard_Failure) {
1004 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1005 SetErrorCode(aFail->GetMessageString());
1006 // to provide warning
1007 if (!aFunction->GetValue().IsNull()) {
1008 isWarning = Standard_True;
1014 //Make a Python command
1015 GEOM::TPythonDump(aFunction) << aGlued << " = geompy.MakeGlueFaces("
1016 << theShapes << ", " << theTolerance << ")";
1018 // to provide warning
1019 if (!isWarning) SetErrorCode(OK);
1023 //=============================================================================
1027 //=============================================================================
1029 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetGlueFaces
1030 (Handle(GEOM_Object) theShape,
1031 const Standard_Real theTolerance)
1035 if (theShape.IsNull()) return NULL;
1036 TopoDS_Shape aShape = theShape->GetValue();
1037 if (aShape.IsNull()) return NULL;
1039 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1041 Standard_Integer iErr;
1043 GEOMAlgo_Gluer1 aGluer;
1044 GEOMAlgo_ListIteratorOfListOfCoupleOfShapes aItCS;
1045 GEOMAlgo_CoupleOfShapes aCS;
1046 GEOMAlgo_ListOfCoupleOfShapes aLCS;
1048 //aGluer = new GEOMAlgo_Gluer1;
1049 aGluer.SetShape(aShape);
1050 aGluer.SetTolerance(theTolerance);
1052 iErr = aGluer.ErrorStatus();
1053 if (iErr) return NULL;
1055 TopTools_ListOfShape listShape;
1056 const GEOMAlgo_ListOfCoupleOfShapes& aLCSG = aGluer.GluedFaces();
1058 aItCS.Initialize(aLCSG);
1059 for (; aItCS.More(); aItCS.Next()) {
1060 const GEOMAlgo_CoupleOfShapes& aCSG = aItCS.Value();
1061 listShape.Append(aCSG.Shape1());
1064 TopTools_ListIteratorOfListOfShape itSub (listShape);
1065 TCollection_AsciiString anAsciiList, anEntry;
1066 TopTools_IndexedMapOfShape anIndices;
1067 TopExp::MapShapes(aShape, anIndices);
1068 Handle(TColStd_HArray1OfInteger) anArray;
1069 Handle(GEOM_Object) anObj;
1070 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
1071 TopoDS_Shape aValue = itSub.Value();
1072 anArray = new TColStd_HArray1OfInteger(1,1);
1073 anArray->SetValue(1, anIndices.FindIndex(aValue));
1074 anObj = GetEngine()->AddSubShape(theShape, anArray);
1075 if (!anObj.IsNull()) {
1076 aSeq->Append(anObj);
1078 // for python command
1079 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
1080 anAsciiList += anEntry;
1085 //Make a Python command
1086 if( anAsciiList.Length() > 0 ) {
1087 anAsciiList.Trunc(anAsciiList.Length() - 1);
1088 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
1089 GEOM::TPythonDump pd (aFunction, true);
1090 pd << "[" << anAsciiList.ToCString();
1091 pd << "] = geompy.GetGlueFaces(" << theShape << ", " << theTolerance << ")";
1100 //=============================================================================
1102 * MakeGlueFacesByList
1104 //=============================================================================
1106 GEOMImpl_IShapesOperations::MakeGlueFacesByList(std::list< Handle(GEOM_Object) >& theShapes,
1107 const Standard_Real theTolerance,
1108 std::list<Handle(GEOM_Object)> & theFaces,
1109 const Standard_Boolean doKeepNonSolids,
1110 const Standard_Boolean doGlueAllEdges)
1114 Handle(TColStd_HSequenceOfTransient) objects = GEOM_Object::GetLastFunctions( theShapes );
1115 if ( objects.IsNull() || objects->IsEmpty() ) {
1116 SetErrorCode("NULL argument shape");
1119 Handle(TColStd_HSequenceOfTransient) aFaces = GEOM_Object::GetLastFunctions( theFaces );
1120 if ( aFaces.IsNull() ) {
1121 SetErrorCode("NULL argument shape for the shape construction");
1125 //Add a new Glued object
1126 Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
1128 //Add a new Glue function
1129 Handle(GEOM_Function) aFunction;
1130 aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_FACES_BY_LIST);
1131 if (aFunction.IsNull()) return NULL;
1133 //Check if the function is set correctly
1134 if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
1136 GEOMImpl_IGlue aCI (aFunction);
1138 aCI.SetBase( objects );
1139 aCI.SetTolerance(theTolerance);
1140 aCI.SetKeepNonSolids(doKeepNonSolids);
1141 aCI.SetGlueAllEdges(doGlueAllEdges);
1142 aCI.SetFaces(aFaces);
1144 //Compute the sub-shape value
1145 Standard_Boolean isWarning = Standard_False;
1148 if (!GetSolver()->ComputeFunction(aFunction)) {
1149 SetErrorCode("Shape driver failed to glue faces");
1153 catch (Standard_Failure) {
1154 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1155 SetErrorCode(aFail->GetMessageString());
1156 // to provide warning
1157 if (!aFunction->GetValue().IsNull()) {
1158 isWarning = Standard_True;
1164 //Make a Python command
1166 GEOM::TPythonDump pd(aFunction);
1167 pd << aGlued << " = geompy.MakeGlueFacesByList("
1168 << theShapes << ", " << theTolerance << ", " << theFaces << ", "
1169 << (bool)doKeepNonSolids << ", " << (bool)doGlueAllEdges << ")";
1171 // to provide warning
1172 if (!isWarning) SetErrorCode(OK);
1176 //=============================================================================
1180 //=============================================================================
1182 GEOMImpl_IShapesOperations::MakeGlueEdges (std::list< Handle(GEOM_Object) >& theShapes,
1183 const Standard_Real theTolerance)
1187 Handle(TColStd_HSequenceOfTransient) objects = GEOM_Object::GetLastFunctions( theShapes );
1188 if ( objects.IsNull() || objects->IsEmpty() ) {
1189 SetErrorCode("NULL argument shape");
1193 //Add a new Glued object
1194 Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
1196 //Add a new Glue function
1197 Handle(GEOM_Function) aFunction;
1198 aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_EDGES);
1199 if (aFunction.IsNull()) return NULL;
1201 //Check if the function is set correctly
1202 if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
1204 GEOMImpl_IGlue aCI (aFunction);
1206 aCI.SetBase( objects );
1207 aCI.SetTolerance(theTolerance);
1208 aCI.SetKeepNonSolids(true);
1210 //Compute the sub-shape value
1211 Standard_Boolean isWarning = Standard_False;
1214 if (!GetSolver()->ComputeFunction(aFunction)) {
1215 SetErrorCode("Shape driver failed to glue edges");
1219 catch (Standard_Failure) {
1220 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1221 SetErrorCode(aFail->GetMessageString());
1222 // to provide warning
1223 if (!aFunction->GetValue().IsNull()) {
1224 isWarning = Standard_True;
1230 //Make a Python command
1231 GEOM::TPythonDump(aFunction) << aGlued << " = geompy.MakeGlueEdges("
1232 << theShapes << ", " << theTolerance << ")";
1234 // to provide warning
1235 if (!isWarning) SetErrorCode(OK);
1239 //=============================================================================
1243 //=============================================================================
1244 Handle(TColStd_HSequenceOfTransient)
1245 GEOMImpl_IShapesOperations::GetGlueShapes (std::list< Handle(GEOM_Object) >& theShapes,
1246 const Standard_Real theTolerance,
1247 const TopAbs_ShapeEnum theType)
1251 TopoDS_Shape aShape;
1252 TopTools_SequenceOfShape shapes;
1253 std::list< Handle(GEOM_Object) >::iterator s = theShapes.begin();
1254 Handle(GEOM_Object) lastCreatedGO;
1255 for ( ; s != theShapes.end(); ++s )
1257 Handle(GEOM_Object) go = *s;
1258 if ( go.IsNull() ) return NULL;
1259 aShape = go->GetValue();
1260 if ( aShape.IsNull() ) return NULL;
1261 shapes.Append( aShape );
1262 lastCreatedGO = GEOM::GetCreatedLast( lastCreatedGO, go );
1264 if ( shapes.Length() > 1 )
1266 TopoDS_Compound compound;
1267 BRep_Builder builder;
1268 builder.MakeCompound( compound );
1269 for ( int i = 1; i <= shapes.Length(); ++i )
1270 builder.Add( compound, shapes( i ) );
1275 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1277 GEOMAlgo_GlueDetector aGluer;
1278 aGluer.SetArgument(aShape);
1279 aGluer.SetTolerance(theTolerance);
1281 Standard_Integer iErr = aGluer.ErrorStatus();
1282 if (iErr) return NULL;
1284 std::vector< TopTools_IndexedMapOfShape* > anIndices( shapes.Length(), NULL );
1285 Handle(TColStd_HArray1OfInteger) anArray;
1286 Handle(GEOM_Object) anObj;
1288 TopTools_ListOfShape listOnePerSet;
1290 const TopTools_DataMapOfShapeListOfShape& aImages = aGluer.Images();
1291 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape aItDMSLS (aImages);
1292 for (int index = 1; aItDMSLS.More(); aItDMSLS.Next(), ++index) {
1294 //const TopoDS_Shape& aSkey = aItDMSLS.Key();
1296 // list of shapes of the argument that can be glued
1297 const TopTools_ListOfShape& aLSD = aItDMSLS.Value();
1299 //listShape.Append(aLSD.First());
1300 TopoDS_Shape aValue = aLSD.First();
1302 if (aValue.ShapeType() == theType) {
1303 listOnePerSet.Append(aValue);
1307 // for stable order of returned entities
1308 GEOMUtils::SortShapes(listOnePerSet, Standard_False);
1310 TopTools_ListIteratorOfListOfShape aListIt (listOnePerSet);
1311 for (; aListIt.More(); aListIt.Next())
1313 TopoDS_Shape aValue = aListIt.Value();
1314 // find a shape to add aValue as a sub-shape
1316 s = theShapes.begin();
1317 for ( int i = 0; i < shapes.Length(); ++i, ++s )
1319 Handle(GEOM_Object) object = *s;
1320 if ( !anIndices[i] ) {
1321 anIndices[i] = new TopTools_IndexedMapOfShape;
1322 TopExp::MapShapes( object->GetValue(), *anIndices[i]);
1324 if (int index = anIndices[i]->FindIndex( aValue )) {
1325 anArray = new TColStd_HArray1OfInteger(1,1);
1326 anArray->SetValue(1, index);
1327 anObj = GetEngine()->AddSubShape( object, anArray);
1331 if (!anObj.IsNull())
1332 aSeq->Append(anObj);
1334 for ( size_t i = 0 ; i < anIndices.size(); ++i )
1335 delete anIndices[i];
1337 // Make a Python command
1338 if ( aSeq->Length() > 0)
1340 Handle(GEOM_Function) aFunction = lastCreatedGO->GetLastFunction();
1341 GEOM::TPythonDump pd (aFunction, /*append=*/true);
1343 << " = geompy." << (theType == TopAbs_FACE ? "GetGlueFaces" : "GetGlueEdges" )
1344 << "( " << theShapes << ", " << theTolerance << ")";
1352 //=============================================================================
1354 * MakeGlueEdgesByList
1356 //=============================================================================
1358 GEOMImpl_IShapesOperations::MakeGlueEdgesByList (std::list< Handle(GEOM_Object) >& theShapes,
1359 const Standard_Real theTolerance,
1360 std::list<Handle(GEOM_Object)>& theEdges)
1364 Handle(TColStd_HSequenceOfTransient) objects = GEOM_Object::GetLastFunctions( theShapes );
1365 if ( objects.IsNull() || objects->IsEmpty() ) {
1366 SetErrorCode("NULL argument shape");
1369 Handle(TColStd_HSequenceOfTransient) anEdges = GEOM_Object::GetLastFunctions( theEdges );
1370 if ( anEdges.IsNull() ) {
1371 SetErrorCode("NULL argument shape for the shape construction");
1374 //Add a new Glued object
1375 Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
1377 //Add a new Glue function
1378 Handle(GEOM_Function) aFunction;
1379 aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_EDGES_BY_LIST);
1380 if (aFunction.IsNull()) return NULL;
1382 //Check if the function is set correctly
1383 if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
1385 GEOMImpl_IGlue aCI (aFunction);
1387 aCI.SetBase( objects );
1388 aCI.SetTolerance(theTolerance);
1389 aCI.SetKeepNonSolids(true);
1390 aCI.SetFaces(anEdges);
1392 //Compute the sub-shape value
1393 Standard_Boolean isWarning = Standard_False;
1396 if (!GetSolver()->ComputeFunction(aFunction)) {
1397 SetErrorCode("Shape driver failed to glue edges");
1401 catch (Standard_Failure) {
1402 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1403 SetErrorCode(aFail->GetMessageString());
1404 // to provide warning
1405 if (!aFunction->GetValue().IsNull()) {
1406 isWarning = Standard_True;
1412 //Make a Python command
1414 GEOM::TPythonDump pd (aFunction);
1415 pd << aGlued << " = geompy.MakeGlueEdgesByList("
1416 << theShapes << ", " << theTolerance << ", " << theEdges << " )";
1418 // to provide warning
1419 if (!isWarning) SetErrorCode(OK);
1423 //=============================================================================
1425 * GetExistingSubObjects
1427 //=============================================================================
1428 Handle(TColStd_HSequenceOfTransient)
1429 GEOMImpl_IShapesOperations::GetExistingSubObjects(Handle(GEOM_Object) theShape,
1430 const Standard_Boolean theGroupsOnly)
1432 // note: this method does not return fields
1434 Standard_Integer types = theGroupsOnly ? Groups : Groups|SubShapes;
1435 Handle(TColStd_HSequenceOfTransient) results = GetExistingSubObjects(theShape, types);
1437 if (results->Length() > 0) {
1438 //Make a Python command
1439 TCollection_AsciiString anAsciiList;
1440 for (int i = 1; i <= results->Length(); i++)
1442 Handle(GEOM_BaseObject) obj = Handle(GEOM_BaseObject)::DownCast( results->Value(i));
1443 obj->GetEntryString();
1444 if ( i < results->Length() )
1448 GEOM::TPythonDump pd (theShape->GetLastFunction(), /*append=*/true);
1449 pd << "[" << anAsciiList.ToCString();
1450 pd << "] = geompy.GetExistingSubObjects(";
1451 pd << theShape << ", " << (bool)theGroupsOnly << ")";
1457 Handle(TColStd_HSequenceOfTransient)
1458 GEOMImpl_IShapesOperations::GetExistingSubObjects(Handle(GEOM_Object) theShape,
1459 const Standard_Integer theTypes)
1463 if (theShape.IsNull()) return NULL;
1465 Handle(GEOM_Function) aMainShape = theShape->GetLastFunction();
1466 if (aMainShape.IsNull()) return NULL;
1468 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1469 SetErrorCode(NOT_FOUND_ANY);
1471 if (!aMainShape->HasSubShapeReferences()) return aSeq;
1472 const TDataStd_ListOfExtendedString& aListEntries = aMainShape->GetSubShapeReferences();
1473 if (aListEntries.IsEmpty()) return aSeq;
1477 TDataStd_ListIteratorOfListOfExtendedString anIt (aListEntries);
1478 for (; anIt.More(); anIt.Next()) {
1479 TCollection_ExtendedString anEntry = anIt.Value();
1480 Standard_Integer aStrLen = anEntry.LengthOfCString();
1481 char* anEntryStr = new char[aStrLen+1];
1482 anEntry.ToUTF8CString(anEntryStr);
1483 Handle(GEOM_BaseObject) anObj = GetEngine()->GetObject(GetDocID(), anEntryStr, false);
1484 if (!anObj.IsNull() ) {
1485 bool isGroup = anObj->IsKind(STANDARD_TYPE(GEOM_Object)) && anObj->GetType() == GEOM_GROUP;
1486 bool isSubShape = anObj->IsKind(STANDARD_TYPE(GEOM_Object)) && anObj->GetType() != GEOM_GROUP;
1487 bool isField = anObj->IsKind(STANDARD_TYPE(GEOM_Field));
1488 if (theTypes & Groups && isGroup ||
1489 theTypes & SubShapes && isSubShape ||
1490 theTypes & Fields && isField) {
1491 aSeq->Append(anObj);
1494 delete [] anEntryStr;
1497 if (aSeq->Length() == 0) {
1498 SetErrorCode(NOT_FOUND_ANY);
1507 //=============================================================================
1511 //=============================================================================
1512 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::MakeExplode
1513 (Handle(GEOM_Object) theShape,
1514 const Standard_Integer theShapeType,
1515 const Standard_Boolean isSorted,
1516 const ExplodeType theExplodeType)
1520 if (theShape.IsNull()) return NULL;
1521 TopoDS_Shape aShape = theShape->GetValue();
1522 if (aShape.IsNull()) return NULL;
1524 Handle(GEOM_Function) aMainShape = theShape->GetLastFunction();
1526 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1527 Handle(GEOM_Object) anObj;
1528 TopTools_MapOfShape mapShape;
1529 TopTools_ListOfShape listShape;
1531 if (aShape.ShapeType() == TopAbs_COMPOUND &&
1532 (theShapeType == TopAbs_SHAPE || theShapeType == TopAbs_FLAT || theShapeType == TopAbs_COMPOUND))
1534 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
1535 for (; It.More(); It.Next()) {
1536 TopoDS_Shape SS = It.Value();
1537 if (mapShape.Add(SS)) {
1538 if (theShapeType == TopAbs_FLAT) {
1539 AddFlatSubShapes(SS, listShape, mapShape);
1541 else if (theShapeType == TopAbs_SHAPE || theShapeType == SS.ShapeType()) {
1542 listShape.Append(SS);
1544 // VSR: for EXPLODE_NEW_INCLUDE_MAIN and EXPLODE_OLD_INCLUDE_MAIN:
1545 // it seems it is necessary to add top-level shape if theShapeType == TopAbs_COMPOUND
1549 else if (theExplodeType != EXPLODE_NEW_EXCLUDE_MAIN || aShape.ShapeType() != theShapeType) // issue 0021079
1551 TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
1552 for (; exp.More(); exp.Next())
1553 if (mapShape.Add(exp.Current()))
1554 listShape.Append(exp.Current());
1557 if (listShape.IsEmpty()){
1558 //SetErrorCode("The given shape has no sub-shapes of the requested type");
1559 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
1564 bool isOldSorting = false;
1565 if (theExplodeType == EXPLODE_OLD_INCLUDE_MAIN)
1566 isOldSorting = true;
1567 GEOMUtils::SortShapes(listShape, isOldSorting);
1570 TopTools_IndexedMapOfShape anIndices;
1571 TopExp::MapShapes(aShape, anIndices);
1572 Handle(TColStd_HArray1OfInteger) anArray;
1574 TopTools_ListIteratorOfListOfShape itSub (listShape);
1575 TCollection_AsciiString anAsciiList, anEntry;
1576 for (int index = 1; itSub.More(); itSub.Next(), ++index)
1578 TopoDS_Shape aValue = itSub.Value();
1579 anArray = new TColStd_HArray1OfInteger(1,1);
1580 anArray->SetValue(1, anIndices.FindIndex(aValue));
1582 //anObj = GetEngine()->AddSubShape(theShape, anArray);
1584 anObj = GetEngine()->AddObject(GetDocID(), GEOM_SUBSHAPE);
1585 Handle(GEOM_Function) aFunction = anObj->AddFunction(GEOM_Object::GetSubShapeID(), 1);
1586 if (aFunction.IsNull()) return aSeq;
1588 GEOM_ISubShape aSSI (aFunction);
1589 aSSI.SetMainShape(aMainShape);
1590 aSSI.SetIndices(anArray);
1592 // Set function value directly, as we know it.
1593 // Usage of Solver here would lead to significant loss of time,
1594 // because GEOM_SubShapeDriver will build TopTools_IndexedMapOfShape
1595 // on the main shape for each being calculated sub-shape separately.
1596 aFunction->SetValue(aValue);
1598 // Put this subshape in the list of sub-shapes of theMainShape
1599 aMainShape->AddSubShapeReference(aFunction);
1601 if (!anObj.IsNull()) {
1602 aSeq->Append(anObj);
1604 // for python command
1605 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
1606 anAsciiList += anEntry;
1611 //Make a Python command
1612 anAsciiList.Trunc(anAsciiList.Length() - 1);
1614 GEOM::TPythonDump pd (aMainShape, /*append=*/true);
1615 pd << "[" << anAsciiList.ToCString() << "] = geompy.";
1616 switch (theExplodeType) {
1617 case EXPLODE_NEW_EXCLUDE_MAIN:
1618 pd << "ExtractShapes(" << theShape << ", "
1619 << TopAbs_ShapeEnum(theShapeType) << ", " << (isSorted ? "True" : "False") << ")";
1621 case EXPLODE_NEW_INCLUDE_MAIN:
1622 pd << "SubShapeAll" << (isSorted ? "SortedCentres(" : "(")
1623 << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
1625 case EXPLODE_OLD_INCLUDE_MAIN:
1626 pd << "SubShapeAll" << (isSorted ? "Sorted(" : "(")
1627 << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
1636 //=============================================================================
1640 //=============================================================================
1641 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::SubShapeAllIDs
1642 (Handle(GEOM_Object) theShape,
1643 const Standard_Integer theShapeType,
1644 const Standard_Boolean isSorted,
1645 const ExplodeType theExplodeType)
1649 if (theShape.IsNull()) return NULL;
1650 TopoDS_Shape aShape = theShape->GetValue();
1651 if (aShape.IsNull()) return NULL;
1653 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
1654 TopTools_MapOfShape mapShape;
1655 TopTools_ListOfShape listShape;
1657 if (aShape.ShapeType() == TopAbs_COMPOUND &&
1658 (theShapeType == TopAbs_SHAPE || theShapeType == TopAbs_FLAT || theShapeType == TopAbs_COMPOUND))
1660 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
1661 for (; It.More(); It.Next()) {
1662 TopoDS_Shape SS = It.Value();
1663 if (mapShape.Add(SS)) {
1664 if (theShapeType == TopAbs_FLAT) {
1665 AddFlatSubShapes(SS, listShape, mapShape);
1667 else if (theShapeType == TopAbs_SHAPE || theShapeType == SS.ShapeType()) {
1668 listShape.Append(SS);
1673 else if (theExplodeType != EXPLODE_NEW_EXCLUDE_MAIN || aShape.ShapeType() != theShapeType) // issue 0021079
1675 TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
1676 for (; exp.More(); exp.Next())
1677 if (mapShape.Add(exp.Current()))
1678 listShape.Append(exp.Current());
1681 if (listShape.IsEmpty()) {
1682 //SetErrorCode("The given shape has no sub-shapes of the requested type");
1683 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
1688 bool isOldSorting = false;
1689 if (theExplodeType == EXPLODE_OLD_INCLUDE_MAIN)
1690 isOldSorting = true;
1691 GEOMUtils::SortShapes(listShape, isOldSorting);
1694 TopTools_IndexedMapOfShape anIndices;
1695 TopExp::MapShapes(aShape, anIndices);
1696 Handle(TColStd_HArray1OfInteger) anArray;
1698 TopTools_ListIteratorOfListOfShape itSub (listShape);
1699 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
1700 TopoDS_Shape aValue = itSub.Value();
1701 aSeq->Append(anIndices.FindIndex(aValue));
1704 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
1706 //Make a Python command
1707 GEOM::TPythonDump pd (aFunction, /*append=*/true);
1708 pd << "listSubShapeIDs = geompy.SubShapeAll";
1709 switch (theExplodeType) {
1710 case EXPLODE_NEW_EXCLUDE_MAIN:
1712 case EXPLODE_NEW_INCLUDE_MAIN:
1713 pd << (isSorted ? "SortedCentresIDs(" : "IDs(")
1714 << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
1716 case EXPLODE_OLD_INCLUDE_MAIN:
1717 pd << (isSorted ? "SortedIDs(" : "IDs(")
1718 << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
1727 //=============================================================================
1731 //=============================================================================
1732 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetSubShape
1733 (Handle(GEOM_Object) theMainShape,
1734 const Standard_Integer theID)
1738 if (theMainShape.IsNull()) return NULL;
1740 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
1741 anArray->SetValue(1, theID);
1742 Handle(GEOM_Object) anObj = GetEngine()->AddSubShape(theMainShape, anArray,true);
1743 if (anObj.IsNull()) {
1744 SetErrorCode("Can not get a sub-shape with the given ID");
1748 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1750 //Make a Python command
1751 GEOM::TPythonDump(aFunction) << anObj << " = geompy.GetSubShape("
1752 << theMainShape << ", [" << theID << "])";
1758 //=============================================================================
1762 //=============================================================================
1763 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::MakeSubShapes
1764 (Handle(GEOM_Object) theMainShape,
1765 Handle(TColStd_HArray1OfInteger) theIndices)
1769 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1771 if (!theIndices->Length()) {
1772 SetErrorCode(NOT_FOUND_ANY);
1776 if (theMainShape.IsNull()) return NULL;
1777 TopoDS_Shape aShape = theMainShape->GetValue();
1778 if (aShape.IsNull()) return NULL;
1780 Handle(GEOM_Function) aMainShape = theMainShape->GetLastFunction();
1782 TopTools_IndexedMapOfShape anIndices;
1783 TopExp::MapShapes(aShape, anIndices);
1785 Handle(TColStd_HArray1OfInteger) anArray;
1786 Handle(GEOM_Object) anObj;
1788 TCollection_AsciiString anAsciiList, anEntry;
1789 Standard_Integer i, low = theIndices->Lower(), up = theIndices->Upper();
1790 for (i = low; i <= up; i++) {
1791 int id = theIndices->Value(i);
1792 if (1 <= id && id <= anIndices.Extent()) {
1793 TopoDS_Shape aValue = anIndices.FindKey(id);
1794 anArray = new TColStd_HArray1OfInteger(1,1);
1795 anArray->SetValue(1, id);
1797 anObj = GetEngine()->AddObject(GetDocID(), GEOM_SUBSHAPE);
1798 if (!anObj.IsNull()) {
1799 Handle(GEOM_Function) aFunction = anObj->AddFunction(GEOM_Object::GetSubShapeID(), 1);
1800 if (aFunction.IsNull()) return aSeq;
1802 GEOM_ISubShape aSSI (aFunction);
1803 aSSI.SetMainShape(aMainShape);
1804 aSSI.SetIndices(anArray);
1806 // Set function value directly, as we know it.
1807 // Usage of Solver here would lead to significant loss of time,
1808 // because GEOM_SubShapeDriver will build TopTools_IndexedMapOfShape
1809 // on the main shape for each being calculated sub-shape separately.
1810 aFunction->SetValue(aValue);
1812 // Put this sub-shape in the list of sub-shapes of theMainShape
1813 aMainShape->AddSubShapeReference(aFunction);
1815 aSeq->Append(anObj);
1817 // for python command
1818 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
1819 anAsciiList += anEntry;
1825 //Make a Python command
1826 anAsciiList.Trunc(anAsciiList.Length() - 1);
1828 GEOM::TPythonDump pd (aMainShape, /*append=*/true);
1829 pd << "[" << anAsciiList.ToCString() << "] = geompy.SubShapes("
1830 << theMainShape << ", [" ;
1831 for (i = low; i <= up - 1; i++) {
1832 pd << theIndices->Value(i) << ", ";
1834 pd << theIndices->Value(up) << "])";
1841 //=============================================================================
1845 //=============================================================================
1846 Standard_Integer GEOMImpl_IShapesOperations::GetSubShapeIndex (Handle(GEOM_Object) theMainShape,
1847 Handle(GEOM_Object) theSubShape)
1851 TopoDS_Shape aMainShape = theMainShape->GetValue();
1852 TopoDS_Shape aSubShape = theSubShape->GetValue();
1854 if (aMainShape.IsNull() || aSubShape.IsNull()) return -1;
1856 TopTools_IndexedMapOfShape anIndices;
1857 TopExp::MapShapes(aMainShape, anIndices);
1858 // if (anIndices.Contains(aSubShape)) {
1859 // SetErrorCode(OK);
1860 // return anIndices.FindIndex(aSubShape);
1862 int id = anIndices.FindIndex(aSubShape);
1873 //=============================================================================
1875 * GetSubShapeIndices
1877 //=============================================================================
1878 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetSubShapesIndices (Handle(GEOM_Object) theMainShape,
1879 std::list<Handle(GEOM_Object)> theSubShapes)
1881 MESSAGE("GEOMImpl_IShapesOperations::GetSubShapesIndices")
1884 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
1886 TopoDS_Shape aMainShape = theMainShape->GetValue();
1887 if (aMainShape.IsNull())
1889 MESSAGE("NULL main shape")
1893 TopTools_IndexedMapOfShape anIndices;
1894 TopExp::MapShapes(aMainShape, anIndices);
1896 std::list<Handle(GEOM_Object)>::iterator it;
1897 for (it=theSubShapes.begin(); it != theSubShapes.end(); ++it)
1899 TopoDS_Shape aSubShape = (*it)->GetValue();
1900 if (aSubShape.IsNull())
1902 MESSAGE("NULL subshape")
1905 int id = anIndices.FindIndex(aSubShape);
1914 //=============================================================================
1918 //=============================================================================
1919 Standard_Integer GEOMImpl_IShapesOperations::GetTopologyIndex (Handle(GEOM_Object) theMainShape,
1920 Handle(GEOM_Object) theSubShape)
1924 TopoDS_Shape aMainShape = theMainShape->GetValue();
1925 TopoDS_Shape aSubShape = theSubShape->GetValue();
1927 if (aMainShape.IsNull() || aSubShape.IsNull()) {
1928 SetErrorCode("Null argument shape given");
1933 if (aSubShape.ShapeType() == TopAbs_COMPOUND) {
1935 TopTools_ListOfShape CL;
1936 CL.Append(aMainShape);
1937 TopTools_ListIteratorOfListOfShape itC;
1938 for (itC.Initialize(CL); itC.More(); itC.Next()) {
1939 for (it.Initialize(itC.Value()); it.More(); it.Next()) {
1940 if (it.Value().ShapeType() == TopAbs_COMPOUND) {
1941 if (it.Value().IsSame(aSubShape))
1945 CL.Append(it.Value());
1950 TopExp_Explorer anExp (aMainShape, aSubShape.ShapeType());
1951 TopTools_MapOfShape M;
1952 for (; anExp.More(); anExp.Next()) {
1953 if (M.Add(anExp.Current())) {
1954 if (anExp.Current().IsSame(aSubShape))
1961 SetErrorCode("The sub-shape does not belong to the main shape");
1965 //=============================================================================
1967 * GetShapeTypeString
1969 //=============================================================================
1970 TCollection_AsciiString GEOMImpl_IShapesOperations::GetShapeTypeString (Handle(GEOM_Object) theShape)
1974 TCollection_AsciiString aTypeName ("Null Shape");
1976 TopoDS_Shape aShape = theShape->GetValue();
1977 if (aShape.IsNull())
1980 switch (aShape.ShapeType() )
1982 case TopAbs_COMPOUND:
1983 aTypeName = "Compound";
1985 case TopAbs_COMPSOLID:
1986 aTypeName = "Compound Solid";
1989 aTypeName = "Solid";
1992 aTypeName = "Shell";
1996 BRepAdaptor_Surface surf (TopoDS::Face(aShape));
1997 if (surf.GetType() == GeomAbs_Plane)
1998 aTypeName = "Plane";
1999 else if (surf.GetType() == GeomAbs_Cylinder)
2000 aTypeName = "Cylindrical Face";
2001 else if (surf.GetType() == GeomAbs_Sphere)
2002 aTypeName = "Spherical Face";
2003 else if (surf.GetType() == GeomAbs_Torus)
2004 aTypeName = "Toroidal Face";
2005 else if (surf.GetType() == GeomAbs_Cone)
2006 aTypeName = "Conical Face";
2008 aTypeName = "GEOM::FACE";
2016 BRepAdaptor_Curve curv (TopoDS::Edge(aShape));
2017 if (curv.GetType() == GeomAbs_Line) {
2018 if ((Abs(curv.FirstParameter()) >= 1E6) ||
2019 (Abs(curv.LastParameter()) >= 1E6))
2023 } else if (curv.GetType() == GeomAbs_Circle) {
2024 if (curv.IsClosed())
2025 aTypeName = "Circle";
2034 aTypeName = "Vertex";
2037 aTypeName = "Shape";
2040 aTypeName = "Shape of unknown type";
2046 //=============================================================================
2048 * IsSubShapeBelongsTo
2050 //=============================================================================
2051 Standard_Boolean GEOMImpl_IShapesOperations::IsSubShapeBelongsTo( Handle(GEOM_Object) theSubObject,
2052 const Standard_Integer theSubObjectIndex,
2053 Handle(GEOM_Object) theObject,
2054 const Standard_Integer theObjectIndex)
2056 if ( theObject.IsNull() || theSubObject.IsNull() )
2059 TopoDS_Shape shape = theObject->GetValue();
2060 TopoDS_Shape subShape = theSubObject->GetValue();
2062 if ( shape.IsNull() || subShape.IsNull() )
2065 TopTools_IndexedMapOfShape anIndices;
2066 if ( theObjectIndex > 0 ) {
2067 TopExp::MapShapes( shape, anIndices );
2068 shape = anIndices.FindKey(theObjectIndex);
2070 if ( theSubObjectIndex > 0 ) {
2071 TopExp::MapShapes( subShape, anIndices );
2072 subShape = anIndices.FindKey(theSubObjectIndex);
2075 TopExp::MapShapes( shape, anIndices );
2076 return anIndices.Contains( subShape );
2079 //=============================================================================
2083 //=============================================================================
2084 Standard_Integer GEOMImpl_IShapesOperations::NumberOfSubShapes
2085 (Handle(GEOM_Object) theShape,
2086 const Standard_Integer theShapeType)
2089 Standard_Integer nbShapes = 0;
2091 if (theShape.IsNull()) return -1;
2092 TopoDS_Shape aShape = theShape->GetValue();
2093 if (aShape.IsNull()) return -1;
2096 TopTools_MapOfShape mapShape;
2098 if (aShape.ShapeType() == TopAbs_COMPOUND &&
2099 (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
2100 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPSOLID ||
2101 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPOUND)) {
2102 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
2103 for (; It.More(); It.Next()) {
2104 if (mapShape.Add(It.Value())) {
2105 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
2106 TopAbs_ShapeEnum(theShapeType) == It.Value().ShapeType()) {
2112 TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
2113 for (; exp.More(); exp.Next())
2114 if (mapShape.Add(exp.Current()))
2120 if (theShapeType == TopAbs_FLAT) {
2121 TopTools_MapOfShape aMapOfShape;
2122 TopTools_ListOfShape aListOfShape;
2123 AddFlatSubShapes(aShape, aListOfShape, aMapOfShape);
2124 nbShapes = aListOfShape.Extent();
2128 int iType, nbTypes [TopAbs_SHAPE];
2129 for (iType = 0; iType < TopAbs_SHAPE; ++iType)
2131 nbTypes[aShape.ShapeType()]++;
2133 TopTools_MapOfShape aMapOfShape;
2134 aMapOfShape.Add(aShape);
2135 TopTools_ListOfShape aListOfShape;
2136 aListOfShape.Append(aShape);
2138 TopTools_ListIteratorOfListOfShape itL (aListOfShape);
2139 for (; itL.More(); itL.Next()) {
2140 TopoDS_Iterator it (itL.Value());
2141 for (; it.More(); it.Next()) {
2142 TopoDS_Shape s = it.Value();
2143 if (aMapOfShape.Add(s)) {
2144 aListOfShape.Append(s);
2145 nbTypes[s.ShapeType()]++;
2150 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE)
2151 nbShapes = aMapOfShape.Extent();
2153 nbShapes = nbTypes[theShapeType];
2156 catch (Standard_Failure) {
2157 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2158 SetErrorCode(aFail->GetMessageString());
2166 //=============================================================================
2170 //=============================================================================
2171 Handle(GEOM_Object) GEOMImpl_IShapesOperations::ReverseShape(Handle(GEOM_Object) theShape)
2175 if (theShape.IsNull()) return NULL;
2178 //Add a new reversed object
2179 Handle(GEOM_Object) aReversed = GetEngine()->AddObject(GetDocID(), theShape->GetType());
2181 //Add a new Revese function
2182 Handle(GEOM_Function) aFunction;
2183 aFunction = aReversed->AddFunction(GEOMImpl_ShapeDriver::GetID(), REVERSE_ORIENTATION);
2184 if (aFunction.IsNull()) return NULL;
2186 //Check if the function is set correctly
2187 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
2189 GEOMImpl_IShapes aSI (aFunction);
2191 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
2192 if (aRefShape.IsNull()) return NULL;
2194 aSI.SetBase(aRefShape);
2196 //Compute the sub-shape value
2199 if (!GetSolver()->ComputeFunction(aFunction)) {
2200 SetErrorCode("Shape driver failed to reverse shape");
2204 catch (Standard_Failure) {
2205 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2206 SetErrorCode(aFail->GetMessageString());
2210 //Make a Python command
2211 GEOM::TPythonDump(aFunction) << aReversed
2212 << " = geompy.ChangeOrientation(" << theShape << ")";
2217 Handle(GEOM_Object) aReversed;
2219 GEOM_Engine* anEngine = GetEngine();
2220 //GEOMImpl_Gen* aGen = dynamic_cast<GEOMImpl_Gen*>(anEngine);
2221 GEOMImpl_Gen* aGen = (GEOMImpl_Gen*)anEngine;
2224 GEOMImpl_IHealingOperations* anIHealingOperations =
2225 aGen->GetIHealingOperations(GetDocID());
2226 aReversed = anIHealingOperations->ChangeOrientationCopy(theShape);
2227 SetErrorCode(anIHealingOperations->GetErrorCode());
2233 //=============================================================================
2237 //=============================================================================
2238 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetFreeFacesIDs
2239 (Handle(GEOM_Object) theShape)
2243 if (theShape.IsNull()) return NULL;
2244 TopoDS_Shape aShape = theShape->GetValue();
2245 if (aShape.IsNull()) return NULL;
2247 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
2249 TopTools_IndexedDataMapOfShapeListOfShape mapFaceBlocks;
2250 GEOMImpl_Block6Explorer::MapShapesAndAncestors
2251 (aShape, TopAbs_FACE, TopAbs_SOLID, mapFaceBlocks);
2253 Standard_Integer ind = 1, nbFaces = mapFaceBlocks.Extent();
2256 SetErrorCode("The given shape has no faces");
2260 TopTools_IndexedMapOfShape anIndices;
2261 TopExp::MapShapes(aShape, anIndices);
2263 Standard_Integer id;
2264 for (; ind <= nbFaces; ind++) {
2265 if (mapFaceBlocks.FindFromIndex(ind).Extent() != 2) {
2266 id = anIndices.FindIndex(mapFaceBlocks.FindKey(ind));
2271 //The explode doesn't change object so no new function is required.
2272 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
2274 //Make a Python command
2275 GEOM::TPythonDump(aFunction, /*append=*/true)
2276 << "listFreeFacesIDs = geompy.GetFreeFacesIDs(" << theShape << ")";
2282 //=======================================================================
2283 //function : GetSharedShapes
2285 //=======================================================================
2286 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetSharedShapes
2287 (Handle(GEOM_Object) theShape1,
2288 Handle(GEOM_Object) theShape2,
2289 const Standard_Integer theShapeType)
2293 if (theShape1.IsNull() || theShape2.IsNull()) return NULL;
2295 TopoDS_Shape aShape1 = theShape1->GetValue();
2296 TopoDS_Shape aShape2 = theShape2->GetValue();
2298 if (aShape1.IsNull() || aShape2.IsNull()) return NULL;
2300 TopTools_IndexedMapOfShape anIndices;
2301 TopExp::MapShapes(aShape1, anIndices);
2302 Handle(TColStd_HArray1OfInteger) anArray;
2304 TopTools_IndexedMapOfShape mapShape1;
2305 TopExp::MapShapes(aShape1, TopAbs_ShapeEnum(theShapeType), mapShape1);
2307 Handle(GEOM_Object) anObj;
2308 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
2309 TCollection_AsciiString anAsciiList, anEntry;
2311 TopTools_MapOfShape mapShape2;
2312 TopExp_Explorer exp (aShape2, TopAbs_ShapeEnum(theShapeType));
2313 for (; exp.More(); exp.Next()) {
2314 TopoDS_Shape aSS = exp.Current();
2315 if (mapShape2.Add(aSS) && mapShape1.Contains(aSS)) {
2316 anArray = new TColStd_HArray1OfInteger(1,1);
2317 anArray->SetValue(1, anIndices.FindIndex(aSS));
2318 anObj = GetEngine()->AddSubShape(theShape1, anArray);
2319 aSeq->Append(anObj);
2321 // for python command
2322 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
2323 anAsciiList += anEntry;
2328 if (aSeq->IsEmpty()) {
2329 SetErrorCode("The given shapes have no shared sub-shapes of the requested type");
2333 //Make a Python command
2334 anAsciiList.Trunc(anAsciiList.Length() - 1);
2336 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2338 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
2339 << "] = geompy.GetSharedShapes(" << theShape1 << ", "
2340 << theShape2 << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
2346 //=======================================================================
2347 //function : GetSharedShapes
2349 //=======================================================================
2350 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetSharedShapes
2351 (std::list<Handle(GEOM_Object)> & theShapes,
2352 const Standard_Integer theShapeType)
2356 int aLen = theShapes.size();
2357 if (aLen < 1) return NULL;
2360 std::list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
2362 Handle(GEOM_Object) aMainObj = *it;
2363 Handle(GEOM_Function) aMainShape = aMainObj->GetLastFunction();
2365 TopTools_SequenceOfShape shapeSeq;
2366 for (; it != theShapes.end(); it++, ind++) {
2367 Handle(GEOM_Function) aRefShape = (*it)->GetLastFunction();
2368 if (aRefShape.IsNull()) {
2369 SetErrorCode("NULL shape for GetSharedShapes");
2372 TopoDS_Shape aShape2 = aRefShape->GetValue();
2373 if (aShape2.IsNull()) return NULL;
2374 shapeSeq.Append( aShape2 );
2377 TopoDS_Shape aShape1 = shapeSeq.First();
2379 if ( shapeSeq.Length() == 1 )
2382 for ( TopoDS_Iterator it( aShape1); it.More(); it.Next() )
2383 shapeSeq.Append( it.Value() );
2384 aShape1 = shapeSeq.First();
2387 TopTools_IndexedMapOfShape anIndices;
2388 TopExp::MapShapes(aMainShape->GetValue(), anIndices);
2390 TopTools_IndexedMapOfShape mapSelected;
2391 TopExp::MapShapes(aShape1, TopAbs_ShapeEnum(theShapeType), mapSelected);
2393 // Find shared shapes
2395 TopoDS_Compound aCurrSelection;
2397 for ( ind = 2; ind <= shapeSeq.Length(); ind++) {
2399 TopoDS_Compound aCompound;
2400 B.MakeCompound(aCompound);
2402 const TopoDS_Shape& aShape2 = shapeSeq.Value( ind );
2404 TopTools_MapOfShape mapShape2;
2405 TopExp_Explorer exp (aShape2, TopAbs_ShapeEnum(theShapeType));
2406 for (; exp.More(); exp.Next()) {
2407 const TopoDS_Shape& aSS = exp.Current();
2408 if (mapShape2.Add(aSS) && mapSelected.Contains(aSS)) {
2409 B.Add(aCompound, aSS);
2413 mapSelected.Clear();
2414 TopExp::MapShapes(aCompound, TopAbs_ShapeEnum(theShapeType), mapSelected);
2415 aCurrSelection = aCompound;
2418 // Create GEOM_Object for each found shared shape (collected in aCurrSelection)
2419 Handle(GEOM_Object) anObj, aLastCreated;
2420 Handle(TColStd_HArray1OfInteger) anArray;
2421 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
2422 TCollection_AsciiString anAsciiList, anEntry;
2424 TopoDS_Iterator itSel (aCurrSelection, Standard_True, Standard_True);
2425 for (; itSel.More(); itSel.Next()) {
2426 anArray = new TColStd_HArray1OfInteger(1,1);
2427 anArray->SetValue(1, anIndices.FindIndex(itSel.Value()));
2428 anObj = GetEngine()->AddSubShape(aMainObj, anArray);
2429 aSeq->Append(anObj);
2431 aLastCreated = GEOM::GetCreatedLast( aLastCreated, anObj );
2433 // for python command
2434 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
2435 anAsciiList += anEntry;
2439 if (aSeq->IsEmpty()) {
2440 SetErrorCode("The given shapes have no shared sub-shapes of the requested type");
2444 // Make a Python command
2445 anAsciiList.Trunc(anAsciiList.Length() - 1);
2447 // IPAL22904: TC6.5.0: order of python commands is wrong after dump study
2448 // Get the function of the latest published object
2449 Handle(GEOM_Function) aFunction = aLastCreated->GetLastFunction();
2450 if( aFunction.IsNull() ) // just in case
2451 aFunction = aMainShape;
2453 GEOM::TPythonDump pd (aFunction, /*append=*/true);
2454 pd << "[" << anAsciiList.ToCString()
2455 << "] = geompy.GetSharedShapesMulti([";
2457 it = theShapes.begin();
2459 while (it != theShapes.end()) {
2460 pd << ", " << (*it++);
2463 pd << "], " << TopAbs_ShapeEnum(theShapeType) << ")";
2469 //=============================================================================
2473 //=============================================================================
2474 static GEOM::TPythonDump& operator<< (GEOM::TPythonDump& theDump,
2475 const GEOMAlgo_State theState)
2478 case GEOMAlgo_ST_IN:
2479 theDump << "GEOM.ST_IN";
2481 case GEOMAlgo_ST_OUT:
2482 theDump << "GEOM.ST_OUT";
2484 case GEOMAlgo_ST_ON:
2485 theDump << "GEOM.ST_ON";
2487 case GEOMAlgo_ST_ONIN:
2488 theDump << "GEOM.ST_ONIN";
2490 case GEOMAlgo_ST_ONOUT:
2491 theDump << "GEOM.ST_ONOUT";
2494 theDump << "GEOM.ST_UNKNOWN";
2500 //=======================================================================
2501 //function : checkTypeShapesOn
2503 * \brief Checks if theShapeType parameter of GetShapesOnXXX() is OK
2504 * \param theShapeType - the shape type to check
2505 * \retval bool - result of the check
2507 //=======================================================================
2508 bool GEOMImpl_IShapesOperations::checkTypeShapesOn(const Standard_Integer theShapeType)
2510 if (theShapeType != TopAbs_VERTEX &&
2511 theShapeType != TopAbs_EDGE &&
2512 theShapeType != TopAbs_FACE &&
2513 theShapeType != TopAbs_SOLID) {
2514 SetErrorCode("Only solids, vertices, edges or faces can be found by this method");
2520 //=======================================================================
2521 //function : makePlane
2523 * \brief Creates Geom_Plane
2524 * \param theAx1 - shape object defining plane parameters
2525 * \retval Handle(Geom_Surface) - resulting surface
2527 //=======================================================================
2528 Handle(Geom_Surface) GEOMImpl_IShapesOperations::makePlane(const TopoDS_Shape& anAx1)
2530 if (anAx1.ShapeType() != TopAbs_EDGE) return NULL;
2531 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
2532 TopoDS_Vertex V1, V2;
2533 TopExp::Vertices(anEdge, V1, V2, Standard_True);
2534 if (V1.IsNull() || V2.IsNull()) {
2535 SetErrorCode("Bad edge given for the plane normal vector");
2538 gp_Pnt aLoc = BRep_Tool::Pnt(V1);
2539 gp_Vec aVec (aLoc, BRep_Tool::Pnt(V2));
2540 if (aVec.Magnitude() < Precision::Confusion()) {
2541 SetErrorCode("Vector with null magnitude given");
2544 return new Geom_Plane(aLoc, aVec);
2547 //=======================================================================
2548 //function : makeCylinder
2550 * \brief Creates Geom_CylindricalSurface
2551 * \param theAx1 - edge defining cylinder axis
2552 * \param theRadius - cylinder radius
2553 * \retval Handle(Geom_Surface) - resulting surface
2555 //=======================================================================
2556 Handle(Geom_Surface) GEOMImpl_IShapesOperations::makeCylinder(const TopoDS_Shape& anAxis,
2557 const Standard_Real theRadius)
2559 //Axis of the cylinder
2560 if (anAxis.ShapeType() != TopAbs_EDGE) {
2561 SetErrorCode("Not an edge given for the axis");
2564 TopoDS_Edge anEdge = TopoDS::Edge(anAxis);
2565 TopoDS_Vertex V1, V2;
2566 TopExp::Vertices(anEdge, V1, V2, Standard_True);
2567 if (V1.IsNull() || V2.IsNull()) {
2568 SetErrorCode("Bad edge given for the axis");
2571 gp_Pnt aLoc = BRep_Tool::Pnt(V1);
2572 gp_Vec aVec (aLoc, BRep_Tool::Pnt(V2));
2573 if (aVec.Magnitude() < Precision::Confusion()) {
2574 SetErrorCode("Vector with null magnitude given");
2578 gp_Ax3 anAx3 (aLoc, aVec);
2579 return new Geom_CylindricalSurface(anAx3, theRadius);
2582 //=======================================================================
2583 //function : getShapesOnBoxIDs
2585 * \brief Find IDs of sub-shapes complying with given status about surface
2586 * \param theBox - the box to check state of sub-shapes against
2587 * \param theShape - the shape to explore
2588 * \param theShapeType - type of sub-shape of theShape
2589 * \param theState - required state
2590 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
2592 //=======================================================================
2593 Handle(TColStd_HSequenceOfInteger)
2594 GEOMImpl_IShapesOperations::getShapesOnBoxIDs(const Handle(GEOM_Object)& theBox,
2595 const Handle(GEOM_Object)& theShape,
2596 const Standard_Integer theShapeType,
2597 GEOMAlgo_State theState)
2599 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
2601 TopoDS_Shape aBox = theBox->GetValue();
2602 TopoDS_Shape aShape = theShape->GetValue();
2604 // Check presence of triangulation, build if need
2605 if (!GEOMUtils::CheckTriangulation(aShape)) {
2606 SetErrorCode("Cannot build triangulation on the shape");
2611 GEOMAlgo_FinderShapeOn2 aFinder;
2612 Standard_Real aTol = 0.0001; // default value
2614 Handle(GEOMAlgo_ClsfBox) aClsfBox = new GEOMAlgo_ClsfBox;
2615 aClsfBox->SetBox(aBox);
2617 aFinder.SetShape(aShape);
2618 aFinder.SetTolerance(aTol);
2619 aFinder.SetClsf(aClsfBox);
2620 aFinder.SetShapeType( (TopAbs_ShapeEnum)theShapeType );
2621 aFinder.SetState(theState);
2624 // Interprete results
2625 Standard_Integer iErr = aFinder.ErrorStatus();
2626 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
2628 MESSAGE(" iErr : " << iErr);
2629 TCollection_AsciiString aMsg (" iErr : ");
2630 aMsg += TCollection_AsciiString(iErr);
2634 Standard_Integer iWrn = aFinder.WarningStatus();
2635 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
2637 MESSAGE(" *** iWrn : " << iWrn);
2640 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
2642 if (listSS.Extent() < 1) {
2643 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
2644 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
2648 // Fill sequence of object IDs
2649 aSeqOfIDs = new TColStd_HSequenceOfInteger;
2651 TopTools_IndexedMapOfShape anIndices;
2652 TopExp::MapShapes(aShape, anIndices);
2654 TopTools_ListIteratorOfListOfShape itSub (listSS);
2655 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
2656 int id = anIndices.FindIndex(itSub.Value());
2657 aSeqOfIDs->Append(id);
2663 //=======================================================================
2664 //function : GetShapesOnBoxIDs
2666 * \brief Find sub-shapes complying with given status about surface
2667 * \param theBox - the box to check state of sub-shapes against
2668 * \param theShape - the shape to explore
2669 * \param theShapeType - type of sub-shape of theShape
2670 * \param theState - required state
2671 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
2673 //=======================================================================
2674 Handle(TColStd_HSequenceOfInteger)
2675 GEOMImpl_IShapesOperations::GetShapesOnBoxIDs(const Handle(GEOM_Object)& theBox,
2676 const Handle(GEOM_Object)& theShape,
2677 const Standard_Integer theShapeType,
2678 GEOMAlgo_State theState)
2680 // Find sub-shapes ids
2681 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2682 getShapesOnBoxIDs (theBox, theShape, theShapeType, theState);
2683 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2686 // The GetShapesOnBox() doesn't change object so no new function is required.
2687 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theBox)->GetLastFunction();
2689 // Make a Python command
2690 GEOM::TPythonDump(aFunction, /*append=*/true)
2691 << "listShapesOnBoxIDs = geompy.GetShapesOnBoxIDs("
2694 << TopAbs_ShapeEnum(theShapeType) << ", "
2701 //=======================================================================
2702 //function : GetShapesOnBox
2704 * \brief Find sub-shapes complying with given status about surface
2705 * \param theBox - the box to check state of sub-shapes against
2706 * \param theShape - the shape to explore
2707 * \param theShapeType - type of sub-shape of theShape
2708 * \param theState - required state
2709 * \retval Handle(TColStd_HSequenceOfTransient) - found sub-shapes
2711 //=======================================================================
2712 Handle(TColStd_HSequenceOfTransient)
2713 GEOMImpl_IShapesOperations::GetShapesOnBox(const Handle(GEOM_Object)& theBox,
2714 const Handle(GEOM_Object)& theShape,
2715 const Standard_Integer theShapeType,
2716 GEOMAlgo_State theState)
2718 // Find sub-shapes ids
2719 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2720 getShapesOnBoxIDs (theBox, theShape, theShapeType, theState);
2721 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2724 // Find objects by indices
2725 TCollection_AsciiString anAsciiList;
2726 Handle(TColStd_HSequenceOfTransient) aSeq;
2727 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
2728 if ( aSeq.IsNull() || aSeq->IsEmpty() )
2731 // Make a Python command
2733 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2734 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2736 GEOM::TPythonDump(aFunction)
2737 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnBox("
2740 << TopAbs_ShapeEnum(theShapeType) << ", "
2747 //=======================================================================
2748 //function : getShapesOnShapeIDs
2750 * \brief Find IDs of sub-shapes complying with given status about surface
2751 * \param theCheckShape - the shape to check state of sub-shapes against
2752 * \param theShape - the shape to explore
2753 * \param theShapeType - type of sub-shape of theShape
2754 * \param theState - required state
2755 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
2757 //=======================================================================
2758 Handle(TColStd_HSequenceOfInteger)
2759 GEOMImpl_IShapesOperations::getShapesOnShapeIDs
2760 (const Handle(GEOM_Object)& theCheckShape,
2761 const Handle(GEOM_Object)& theShape,
2762 const Standard_Integer theShapeType,
2763 GEOMAlgo_State theState)
2765 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
2767 TopoDS_Shape aCheckShape = theCheckShape->GetValue();
2768 TopoDS_Shape aShape = theShape->GetValue();
2769 TopTools_ListOfShape res;
2771 // Check presence of triangulation, build if need
2772 if (!GEOMUtils::CheckTriangulation(aShape)) {
2773 SetErrorCode("Cannot build triangulation on the shape");
2778 GEOMAlgo_FinderShapeOn2 aFinder;
2779 Standard_Real aTol = 0.0001; // default value
2781 Handle(GEOMAlgo_ClsfSolid) aClsfSolid = new GEOMAlgo_ClsfSolid;
2782 aClsfSolid->SetShape(aCheckShape);
2784 aFinder.SetShape(aShape);
2785 aFinder.SetTolerance(aTol);
2786 aFinder.SetClsf(aClsfSolid);
2787 aFinder.SetShapeType( (TopAbs_ShapeEnum)theShapeType );
2788 aFinder.SetState(theState);
2791 // Interprete results
2792 Standard_Integer iErr = aFinder.ErrorStatus();
2793 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
2796 SetErrorCode("theCheckShape must be a solid");
2799 MESSAGE(" iErr : " << iErr);
2800 TCollection_AsciiString aMsg (" iErr : ");
2801 aMsg += TCollection_AsciiString(iErr);
2806 Standard_Integer iWrn = aFinder.WarningStatus();
2807 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
2809 MESSAGE(" *** iWrn : " << iWrn);
2812 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
2814 if (listSS.Extent() < 1) {
2815 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
2816 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
2819 // Fill sequence of object IDs
2820 aSeqOfIDs = new TColStd_HSequenceOfInteger;
2822 TopTools_IndexedMapOfShape anIndices;
2823 TopExp::MapShapes(aShape, anIndices);
2825 TopTools_ListIteratorOfListOfShape itSub (listSS);
2826 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
2827 int id = anIndices.FindIndex(itSub.Value());
2828 aSeqOfIDs->Append(id);
2834 //=======================================================================
2835 //function : GetShapesOnShapeIDs
2837 * \brief Find sub-shapes complying with given status about surface
2838 * \param theCheckShape - the shape to check state of sub-shapes against
2839 * \param theShape - the shape to explore
2840 * \param theShapeType - type of sub-shape of theShape
2841 * \param theState - required state
2842 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
2844 //=======================================================================
2845 Handle(TColStd_HSequenceOfInteger)
2846 GEOMImpl_IShapesOperations::GetShapesOnShapeIDs
2847 (const Handle(GEOM_Object)& theCheckShape,
2848 const Handle(GEOM_Object)& theShape,
2849 const Standard_Integer theShapeType,
2850 GEOMAlgo_State theState)
2852 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2853 getShapesOnShapeIDs (theCheckShape, theShape, theShapeType, theState);
2855 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2858 // The GetShapesOnShape() doesn't change object so no new function is required.
2859 Handle(GEOM_Function) aFunction =
2860 GEOM::GetCreatedLast(theShape,theCheckShape)->GetLastFunction();
2862 // Make a Python command
2863 GEOM::TPythonDump(aFunction, /*append=*/true)
2864 << "listShapesOnBoxIDs = geompy.GetShapesOnShapeIDs("
2865 << theCheckShape << ", "
2867 << TopAbs_ShapeEnum(theShapeType) << ", "
2874 //=======================================================================
2875 //function : GetShapesOnShape
2877 * \brief Find sub-shapes complying with given status about surface
2878 * \param theCheckShape - the shape to check state of sub-shapes against
2879 * \param theShape - the shape to explore
2880 * \param theShapeType - type of sub-shape of theShape
2881 * \param theState - required state
2882 * \retval Handle(TColStd_HSequenceOfTransient) - found sub-shapes
2884 //=======================================================================
2885 Handle(TColStd_HSequenceOfTransient)
2886 GEOMImpl_IShapesOperations::GetShapesOnShape
2887 (const Handle(GEOM_Object)& theCheckShape,
2888 const Handle(GEOM_Object)& theShape,
2889 const Standard_Integer theShapeType,
2890 GEOMAlgo_State theState)
2892 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2893 getShapesOnShapeIDs (theCheckShape, theShape, theShapeType, theState);
2894 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2897 // Find objects by indices
2898 TCollection_AsciiString anAsciiList;
2899 Handle(TColStd_HSequenceOfTransient) aSeq;
2900 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
2902 if ( aSeq.IsNull() || aSeq->IsEmpty() )
2905 // Make a Python command
2907 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2908 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2910 GEOM::TPythonDump(aFunction)
2911 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnShape("
2912 << theCheckShape << ", "
2914 << TopAbs_ShapeEnum(theShapeType) << ", "
2921 //=======================================================================
2922 //function : GetShapesOnShapeAsCompound
2923 //=======================================================================
2924 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetShapesOnShapeAsCompound
2925 (const Handle(GEOM_Object)& theCheckShape,
2926 const Handle(GEOM_Object)& theShape,
2927 const Standard_Integer theShapeType,
2928 GEOMAlgo_State theState)
2930 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2931 getShapesOnShapeIDs (theCheckShape, theShape, theShapeType, theState);
2933 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2936 // Find objects by indices
2937 TCollection_AsciiString anAsciiList;
2938 Handle(TColStd_HSequenceOfTransient) aSeq;
2939 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
2941 if ( aSeq.IsNull() || aSeq->IsEmpty() )
2944 TopoDS_Compound aCompound;
2946 B.MakeCompound(aCompound);
2948 for(; i<=aSeq->Length(); i++) {
2949 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(aSeq->Value(i));
2950 TopoDS_Shape aShape_i = anObj->GetValue();
2951 B.Add(aCompound,aShape_i);
2954 //Add a new result object
2955 Handle(GEOM_Object) aRes = GetEngine()->AddObject(GetDocID(), GEOM_SHAPES_ON_SHAPE);
2956 Handle(GEOM_Function) aFunction =
2957 aRes->AddFunction(GEOMImpl_ShapeDriver::GetID(), SHAPES_ON_SHAPE);
2958 aFunction->SetValue(aCompound);
2961 aSeq->Append( theCheckShape->GetLastFunction() );
2962 aSeq->Append( theShape->GetLastFunction() );
2964 GEOMImpl_IShapes aCI( aFunction );
2965 aCI.SetShapes( aSeq );
2966 aCI.SetSubShapeType( theShapeType );
2967 aCI.SetTolerance( theState );
2969 GEOM::TPythonDump(aFunction)
2970 << aRes << " = geompy.GetShapesOnShapeAsCompound("
2971 << theCheckShape << ", "
2973 << TopAbs_ShapeEnum(theShapeType) << ", "
2981 //=======================================================================
2982 //function : getShapesOnSurfaceIDs
2984 * \brief Find IDs of sub-shapes complying with given status about surface
2985 * \param theSurface - the surface to check state of sub-shapes against
2986 * \param theShape - the shape to explore
2987 * \param theShapeType - type of sub-shape of theShape
2988 * \param theState - required state
2989 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
2991 //=======================================================================
2992 Handle(TColStd_HSequenceOfInteger)
2993 GEOMImpl_IShapesOperations::getShapesOnSurfaceIDs(const Handle(Geom_Surface)& theSurface,
2994 const TopoDS_Shape& theShape,
2995 TopAbs_ShapeEnum theShapeType,
2996 GEOMAlgo_State theState)
2998 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
3000 // Check presence of triangulation, build if need
3001 if (!GEOMUtils::CheckTriangulation(theShape)) {
3002 SetErrorCode("Cannot build triangulation on the shape");
3006 // BEGIN: Mantis issue 0020961: Error on a pipe T-Shape
3007 // Compute tolerance
3008 Standard_Real T, VertMax = -RealLast();
3011 for (TopExp_Explorer ExV (theShape, TopAbs_VERTEX); ExV.More(); ExV.Next()) {
3012 TopoDS_Vertex Vertex = TopoDS::Vertex(ExV.Current());
3013 T = BRep_Tool::Tolerance(Vertex);
3018 catch (Standard_Failure) {
3019 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
3020 SetErrorCode(aFail->GetMessageString());
3023 // END: Mantis issue 0020961
3026 GEOMAlgo_FinderShapeOn1 aFinder;
3027 //Standard_Real aTol = 0.0001; // default value
3028 Standard_Real aTol = VertMax; // Mantis issue 0020961
3030 aFinder.SetShape(theShape);
3031 aFinder.SetTolerance(aTol);
3032 aFinder.SetSurface(theSurface);
3033 aFinder.SetShapeType(theShapeType);
3034 aFinder.SetState(theState);
3036 // Sets the minimal number of inner points for the faces that do not have own
3037 // inner points at all (for e.g. rectangular planar faces have just 2 triangles).
3039 aFinder.SetNbPntsMin(3);
3040 // Sets the maximal number of inner points for edges or faces.
3041 // It is usefull for the cases when this number is very big (e.g =2000) to improve
3042 // the performance. If this value =0, all inner points will be taken into account.
3044 aFinder.SetNbPntsMax(100);
3048 // Interprete results
3049 Standard_Integer iErr = aFinder.ErrorStatus();
3050 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
3052 MESSAGE(" iErr : " << iErr);
3053 TCollection_AsciiString aMsg (" iErr : ");
3054 aMsg += TCollection_AsciiString(iErr);
3058 Standard_Integer iWrn = aFinder.WarningStatus();
3059 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
3061 MESSAGE(" *** iWrn : " << iWrn);
3064 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
3066 if (listSS.Extent() < 1) {
3067 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
3068 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
3072 // Fill sequence of object IDs
3073 aSeqOfIDs = new TColStd_HSequenceOfInteger;
3075 TopTools_IndexedMapOfShape anIndices;
3076 TopExp::MapShapes(theShape, anIndices);
3078 TopTools_ListIteratorOfListOfShape itSub (listSS);
3079 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
3080 int id = anIndices.FindIndex(itSub.Value());
3081 aSeqOfIDs->Append(id);
3087 //=======================================================================
3088 //function : getObjectsShapesOn
3090 * \brief Find shape objects and their entries by their ids
3091 * \param theShapeIDs - incoming shape ids
3092 * \param theShapeEntries - outgoing entries like "entry1, entry2, ..."
3093 * \retval Handle(TColStd_HSequenceOfTransient) - found shape objects
3095 //=======================================================================
3096 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::
3097 getObjectsShapesOn(const Handle(GEOM_Object)& theShape,
3098 const Handle(TColStd_HSequenceOfInteger)& theShapeIDs,
3099 TCollection_AsciiString & theShapeEntries)
3101 Handle(TColStd_HSequenceOfTransient) aSeq;
3103 if ( !theShapeIDs.IsNull() && theShapeIDs->Length() > 0 )
3105 aSeq = new TColStd_HSequenceOfTransient;
3106 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
3107 TCollection_AsciiString anEntry;
3108 for ( int i = 1; i <= theShapeIDs->Length(); ++i )
3110 anArray->SetValue(1, theShapeIDs->Value( i ));
3111 Handle(GEOM_Object) anObj = GetEngine()->AddSubShape(theShape, anArray);
3112 aSeq->Append( anObj );
3114 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
3115 if ( i != 1 ) theShapeEntries += ",";
3116 theShapeEntries += anEntry;
3122 //=======================================================================
3123 //function : getShapesOnSurface
3125 * \brief Find sub-shapes complying with given status about surface
3126 * \param theSurface - the surface to check state of sub-shapes against
3127 * \param theShape - the shape to explore
3128 * \param theShapeType - type of sub-shape of theShape
3129 * \param theState - required state
3130 * \param theShapeEntries - outgoing entries like "entry1, entry2, ..."
3131 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
3133 //=======================================================================
3134 Handle(TColStd_HSequenceOfTransient)
3135 GEOMImpl_IShapesOperations::getShapesOnSurface(const Handle(Geom_Surface)& theSurface,
3136 const Handle(GEOM_Object)& theShape,
3137 TopAbs_ShapeEnum theShapeType,
3138 GEOMAlgo_State theState,
3139 TCollection_AsciiString & theShapeEntries)
3141 // Find sub-shapes ids
3142 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
3143 getShapesOnSurfaceIDs (theSurface, theShape->GetValue(), theShapeType, theState);
3144 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
3147 return getObjectsShapesOn( theShape, aSeqOfIDs, theShapeEntries );
3150 //=============================================================================
3154 //=============================================================================
3155 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnPlane
3156 (const Handle(GEOM_Object)& theShape,
3157 const Standard_Integer theShapeType,
3158 const Handle(GEOM_Object)& theAx1,
3159 const GEOMAlgo_State theState)
3163 if (theShape.IsNull() || theAx1.IsNull()) return NULL;
3165 TopoDS_Shape aShape = theShape->GetValue();
3166 TopoDS_Shape anAx1 = theAx1->GetValue();
3168 if (aShape.IsNull() || anAx1.IsNull()) return NULL;
3170 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3171 if ( !checkTypeShapesOn( theShapeType ))
3175 Handle(Geom_Surface) aPlane = makePlane( anAx1 );
3176 if ( aPlane.IsNull() )
3180 TCollection_AsciiString anAsciiList;
3181 Handle(TColStd_HSequenceOfTransient) aSeq;
3182 aSeq = getShapesOnSurface( aPlane, theShape, aShapeType, theState, anAsciiList );
3183 if ( aSeq.IsNull() || aSeq->Length() == 0 )
3186 // Make a Python command
3188 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
3189 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
3191 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
3192 << "] = geompy.GetShapesOnPlane(" << theShape << ", "
3193 << aShapeType << ", " << theAx1 << ", " << theState << ")";
3199 //=============================================================================
3201 * GetShapesOnPlaneWithLocation
3203 //=============================================================================
3204 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnPlaneWithLocation
3205 (const Handle(GEOM_Object)& theShape,
3206 const Standard_Integer theShapeType,
3207 const Handle(GEOM_Object)& theAx1,
3208 const Handle(GEOM_Object)& thePnt,
3209 const GEOMAlgo_State theState)
3213 if (theShape.IsNull() || theAx1.IsNull() || thePnt.IsNull()) return NULL;
3215 TopoDS_Shape aShape = theShape->GetValue();
3216 TopoDS_Shape anAx1 = theAx1->GetValue();
3217 TopoDS_Shape anPnt = thePnt->GetValue();
3219 if (aShape.IsNull() || anAx1.IsNull() || anPnt.IsNull()) return NULL;
3221 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3222 if ( !checkTypeShapesOn( theShapeType ))
3226 if ( anAx1.ShapeType() != TopAbs_EDGE || anPnt.ShapeType() != TopAbs_VERTEX ) return NULL;
3227 TopoDS_Vertex V1, V2, V3;
3228 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
3229 TopExp::Vertices(anEdge, V1, V2, Standard_True);
3231 if (V1.IsNull() || V2.IsNull()) {
3232 SetErrorCode("Bad edge given for the plane normal vector");
3235 V3 = TopoDS::Vertex(anPnt);
3238 SetErrorCode("Bad vertex given for the plane location");
3241 gp_Pnt aLoc = BRep_Tool::Pnt(V3);
3242 gp_Vec aVec(BRep_Tool::Pnt(V1),BRep_Tool::Pnt(V2));
3244 if (aVec.Magnitude() < Precision::Confusion()) {
3245 SetErrorCode("Vector with null magnitude given");
3248 Handle(Geom_Surface) aPlane = new Geom_Plane(aLoc, aVec);
3250 if ( aPlane.IsNull() )
3254 TCollection_AsciiString anAsciiList;
3255 Handle(TColStd_HSequenceOfTransient) aSeq;
3256 aSeq = getShapesOnSurface( aPlane, theShape, aShapeType, theState, anAsciiList );
3257 if ( aSeq.IsNull() || aSeq->Length() == 0 )
3260 // Make a Python command
3262 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
3263 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
3265 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
3266 << "] = geompy.GetShapesOnPlaneWithLocation(" << theShape << ", "
3267 << aShapeType << ", " << theAx1 << ", "<< thePnt <<", " << theState << ")";
3273 //=============================================================================
3275 * GetShapesOnCylinder
3277 //=============================================================================
3278 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnCylinder
3279 (const Handle(GEOM_Object)& theShape,
3280 const Standard_Integer theShapeType,
3281 const Handle(GEOM_Object)& theAxis,
3282 const Standard_Real theRadius,
3283 const GEOMAlgo_State theState)
3287 if (theShape.IsNull() || theAxis.IsNull()) return NULL;
3289 TopoDS_Shape aShape = theShape->GetValue();
3290 TopoDS_Shape anAxis = theAxis->GetValue();
3292 if (aShape.IsNull() || anAxis.IsNull()) return NULL;
3294 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3295 if ( !checkTypeShapesOn( aShapeType ))
3298 // Create a cylinder surface
3299 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
3300 if ( aCylinder.IsNull() )
3304 TCollection_AsciiString anAsciiList;
3305 Handle(TColStd_HSequenceOfTransient) aSeq;
3306 aSeq = getShapesOnSurface( aCylinder, theShape, aShapeType, theState, anAsciiList );
3307 if ( aSeq.IsNull() || aSeq->Length() == 0 )
3310 // Make a Python command
3312 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
3313 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
3315 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
3316 << "] = geompy.GetShapesOnCylinder(" << theShape << ", " << aShapeType
3317 << ", " << theAxis << ", " << theRadius << ", " << theState << ")";
3323 //=============================================================================
3325 * GetShapesOnCylinderWithLocation
3327 //=============================================================================
3328 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnCylinderWithLocation
3329 (const Handle(GEOM_Object)& theShape,
3330 const Standard_Integer theShapeType,
3331 const Handle(GEOM_Object)& theAxis,
3332 const Handle(GEOM_Object)& thePnt,
3333 const Standard_Real theRadius,
3334 const GEOMAlgo_State theState)
3338 if (theShape.IsNull() || theAxis.IsNull() || thePnt.IsNull()) return NULL;
3340 TopoDS_Shape aShape = theShape->GetValue();
3341 TopoDS_Shape anAxis = theAxis->GetValue();
3342 TopoDS_Shape aPnt = thePnt->GetValue();
3344 if (aShape.IsNull() || anAxis.IsNull() || aPnt.IsNull()) return NULL;
3346 if (aPnt.ShapeType() != TopAbs_VERTEX )
3348 SetErrorCode("Bottom location point must be vertex");
3352 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3353 if ( !checkTypeShapesOn( aShapeType ))
3356 // Create a cylinder surface
3357 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
3358 if ( aCylinder.IsNull() )
3361 // translate the surface
3362 Handle(Geom_CylindricalSurface) aCylSurface =
3363 Handle(Geom_CylindricalSurface)::DownCast( aCylinder );
3364 if ( aCylSurface.IsNull() )
3366 SetErrorCode("Unexpected surface type instead of Geom_CylindricalSurface");
3369 gp_Pnt fromLoc = aCylSurface->Cylinder().Location();
3370 gp_Pnt toLoc = BRep_Tool::Pnt( TopoDS::Vertex( aPnt ));
3371 aCylinder->Translate( fromLoc, toLoc );
3374 TCollection_AsciiString anAsciiList;
3375 Handle(TColStd_HSequenceOfTransient) aSeq;
3376 aSeq = getShapesOnSurface( aCylinder, theShape, aShapeType, theState, anAsciiList );
3377 if ( aSeq.IsNull() || aSeq->Length() == 0 )
3380 // Make a Python command
3382 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
3383 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
3385 GEOM::TPythonDump(aFunction)
3386 << "[" << anAsciiList.ToCString()
3387 << "] = geompy.GetShapesOnCylinderWithLocation(" << theShape << ", " << aShapeType << ", "
3388 << theAxis << ", " << thePnt << ", " << theRadius << ", " << theState << ")";
3394 //=============================================================================
3398 //=============================================================================
3399 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnSphere
3400 (const Handle(GEOM_Object)& theShape,
3401 const Standard_Integer theShapeType,
3402 const Handle(GEOM_Object)& theCenter,
3403 const Standard_Real theRadius,
3404 const GEOMAlgo_State theState)
3408 if (theShape.IsNull() || theCenter.IsNull()) return NULL;
3410 TopoDS_Shape aShape = theShape->GetValue();
3411 TopoDS_Shape aCenter = theCenter->GetValue();
3413 if (aShape.IsNull() || aCenter.IsNull()) return NULL;
3415 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3416 if ( !checkTypeShapesOn( aShapeType ))
3419 // Center of the sphere
3420 if (aCenter.ShapeType() != TopAbs_VERTEX) return NULL;
3421 gp_Pnt aLoc = BRep_Tool::Pnt(TopoDS::Vertex(aCenter));
3423 gp_Ax3 anAx3 (aLoc, gp::DZ());
3424 Handle(Geom_SphericalSurface) aSphere =
3425 new Geom_SphericalSurface(anAx3, theRadius);
3428 TCollection_AsciiString anAsciiList;
3429 Handle(TColStd_HSequenceOfTransient) aSeq;
3430 aSeq = getShapesOnSurface( aSphere, theShape, aShapeType, theState, anAsciiList );
3431 if ( aSeq.IsNull() || aSeq->Length() == 0 )
3434 // Make a Python command
3436 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
3437 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
3439 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
3440 << "] = geompy.GetShapesOnSphere(" << theShape << ", " << aShapeType
3441 << ", " << theCenter << ", " << theRadius << ", " << theState << ")";
3447 //=============================================================================
3449 * GetShapesOnPlaneIDs
3451 //=============================================================================
3452 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnPlaneIDs
3453 (const Handle(GEOM_Object)& theShape,
3454 const Standard_Integer theShapeType,
3455 const Handle(GEOM_Object)& theAx1,
3456 const GEOMAlgo_State theState)
3460 if (theShape.IsNull() || theAx1.IsNull()) return NULL;
3462 TopoDS_Shape aShape = theShape->GetValue();
3463 TopoDS_Shape anAx1 = theAx1->GetValue();
3465 if (aShape.IsNull() || anAx1.IsNull()) return NULL;
3467 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3468 if ( !checkTypeShapesOn( aShapeType ))
3472 Handle(Geom_Surface) aPlane = makePlane( anAx1 );
3473 if ( aPlane.IsNull() )
3477 Handle(TColStd_HSequenceOfInteger) aSeq;
3478 aSeq = getShapesOnSurfaceIDs( aPlane, aShape, aShapeType, theState );
3480 // The GetShapesOnPlaneIDs() doesn't change object so no new function is required.
3481 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAx1)->GetLastFunction();
3483 // Make a Python command
3484 GEOM::TPythonDump(aFunction, /*append=*/true)
3485 << "listShapesOnPlane = geompy.GetShapesOnPlaneIDs"
3486 << "(" << theShape << "," << aShapeType << "," << theAx1 << "," << theState << ")";
3492 //=============================================================================
3494 * GetShapesOnPlaneWithLocationIDs
3496 //=============================================================================
3497 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnPlaneWithLocationIDs
3498 (const Handle(GEOM_Object)& theShape,
3499 const Standard_Integer theShapeType,
3500 const Handle(GEOM_Object)& theAx1,
3501 const Handle(GEOM_Object)& thePnt,
3502 const GEOMAlgo_State theState)
3506 if (theShape.IsNull() || theAx1.IsNull() || thePnt.IsNull()) return NULL;
3508 TopoDS_Shape aShape = theShape->GetValue();
3509 TopoDS_Shape anAx1 = theAx1->GetValue();
3510 TopoDS_Shape anPnt = thePnt->GetValue();
3512 if (aShape.IsNull() || anAx1.IsNull() || anPnt.IsNull()) return NULL;
3514 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3515 if ( !checkTypeShapesOn( aShapeType ))
3519 if (anAx1.ShapeType() != TopAbs_EDGE || anPnt.ShapeType() != TopAbs_VERTEX) return NULL;
3520 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
3521 TopoDS_Vertex V1, V2, V3;
3522 TopExp::Vertices(anEdge, V1, V2, Standard_True);
3523 if (V1.IsNull() || V2.IsNull()) {
3524 SetErrorCode("Bad edge given for the plane normal vector");
3527 V3 = TopoDS::Vertex(anPnt);
3529 SetErrorCode("Bad vertex given for the plane location");
3532 gp_Pnt aLoc = BRep_Tool::Pnt(V3);
3533 gp_Vec aVec(BRep_Tool::Pnt(V1),BRep_Tool::Pnt(V2));
3534 if (aVec.Magnitude() < Precision::Confusion()) {
3535 SetErrorCode("Vector with null magnitude given");
3539 Handle(Geom_Surface) aPlane = new Geom_Plane(aLoc, aVec);
3540 if ( aPlane.IsNull() )
3544 Handle(TColStd_HSequenceOfInteger) aSeq;
3545 aSeq = getShapesOnSurfaceIDs( aPlane, aShape, aShapeType, theState );
3547 // The GetShapesOnPlaneIDs() doesn't change object so no new function is required.
3548 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAx1)->GetLastFunction();
3550 // Make a Python command
3551 GEOM::TPythonDump(aFunction, /*append=*/true)
3552 << "listShapesOnPlane = geompy.GetShapesOnPlaneWithLocationIDs"
3553 << "(" << theShape << ", " << aShapeType << ", " << theAx1 << ", "<< thePnt << ", " << theState << ")";
3559 //=============================================================================
3561 * GetShapesOnCylinderIDs
3563 //=============================================================================
3564 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnCylinderIDs
3565 (const Handle(GEOM_Object)& theShape,
3566 const Standard_Integer theShapeType,
3567 const Handle(GEOM_Object)& theAxis,
3568 const Standard_Real theRadius,
3569 const GEOMAlgo_State theState)
3573 if (theShape.IsNull() || theAxis.IsNull()) return NULL;
3575 TopoDS_Shape aShape = theShape->GetValue();
3576 TopoDS_Shape anAxis = theAxis->GetValue();
3578 if (aShape.IsNull() || anAxis.IsNull()) return NULL;
3580 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3581 if ( !checkTypeShapesOn( aShapeType ))
3584 // Create a cylinder surface
3585 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
3586 if ( aCylinder.IsNull() )
3590 Handle(TColStd_HSequenceOfInteger) aSeq;
3591 aSeq = getShapesOnSurfaceIDs( aCylinder, aShape, aShapeType, theState );
3593 // The GetShapesOnCylinder() doesn't change object so no new function is required.
3594 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAxis)->GetLastFunction();
3596 // Make a Python command
3597 GEOM::TPythonDump(aFunction, /*append=*/true)
3598 << "listShapesOnCylinder = geompy.GetShapesOnCylinderIDs"
3599 << "(" << theShape << ", " << aShapeType << ", " << theAxis << ", "
3600 << theRadius << ", " << theState << ")";
3606 //=============================================================================
3608 * GetShapesOnCylinderWithLocationIDs
3610 //=============================================================================
3611 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnCylinderWithLocationIDs
3612 (const Handle(GEOM_Object)& theShape,
3613 const Standard_Integer theShapeType,
3614 const Handle(GEOM_Object)& theAxis,
3615 const Handle(GEOM_Object)& thePnt,
3616 const Standard_Real theRadius,
3617 const GEOMAlgo_State theState)
3621 if (theShape.IsNull() || theAxis.IsNull() || thePnt.IsNull()) return NULL;
3623 TopoDS_Shape aShape = theShape->GetValue();
3624 TopoDS_Shape anAxis = theAxis->GetValue();
3625 TopoDS_Shape aPnt = thePnt->GetValue();
3627 if (aShape.IsNull() || anAxis.IsNull() || aPnt.IsNull()) return NULL;
3629 if (aPnt.ShapeType() != TopAbs_VERTEX )
3631 SetErrorCode("Bottom location point must be vertex");
3635 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3636 if ( !checkTypeShapesOn( aShapeType ))
3639 // Create a cylinder surface
3640 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
3641 if ( aCylinder.IsNull() )
3644 // translate the surface
3645 Handle(Geom_CylindricalSurface) aCylSurface =
3646 Handle(Geom_CylindricalSurface)::DownCast( aCylinder );
3647 if ( aCylSurface.IsNull() )
3649 SetErrorCode("Unexpected surface type instead of Geom_CylindricalSurface");
3652 gp_Pnt fromLoc = aCylSurface->Cylinder().Location();
3653 gp_Pnt toLoc = BRep_Tool::Pnt( TopoDS::Vertex( aPnt ));
3654 aCylinder->Translate( fromLoc, toLoc );
3657 Handle(TColStd_HSequenceOfInteger) aSeq;
3658 aSeq = getShapesOnSurfaceIDs( aCylinder, aShape, aShapeType, theState );
3660 // The GetShapesOnCylinder() doesn't change object so no new function is required.
3661 Handle(GEOM_Function) aFunction =
3662 GEOM::GetCreatedLast(theShape, GEOM::GetCreatedLast(thePnt,theAxis))->GetLastFunction();
3664 // Make a Python command
3665 GEOM::TPythonDump(aFunction, /*append=*/true)
3666 << "listShapesOnCylinder = geompy.GetShapesOnCylinderWithLocationIDs"
3667 << "(" << theShape << ", " << aShapeType << ", " << theAxis << ", "
3668 << thePnt << ", " << theRadius << ", " << theState << ")";
3674 //=============================================================================
3676 * GetShapesOnSphereIDs
3678 //=============================================================================
3679 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnSphereIDs
3680 (const Handle(GEOM_Object)& theShape,
3681 const Standard_Integer theShapeType,
3682 const Handle(GEOM_Object)& theCenter,
3683 const Standard_Real theRadius,
3684 const GEOMAlgo_State theState)
3688 if (theShape.IsNull() || theCenter.IsNull()) return NULL;
3690 TopoDS_Shape aShape = theShape->GetValue();
3691 TopoDS_Shape aCenter = theCenter->GetValue();
3693 if (aShape.IsNull() || aCenter.IsNull()) return NULL;
3695 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3696 if ( !checkTypeShapesOn( aShapeType ))
3699 // Center of the sphere
3700 if (aCenter.ShapeType() != TopAbs_VERTEX) return NULL;
3701 gp_Pnt aLoc = BRep_Tool::Pnt(TopoDS::Vertex(aCenter));
3703 gp_Ax3 anAx3 (aLoc, gp::DZ());
3704 Handle(Geom_SphericalSurface) aSphere =
3705 new Geom_SphericalSurface(anAx3, theRadius);
3708 Handle(TColStd_HSequenceOfInteger) aSeq;
3709 aSeq = getShapesOnSurfaceIDs( aSphere, aShape, aShapeType, theState );
3711 // The GetShapesOnSphere() doesn't change object so no new function is required.
3712 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theCenter)->GetLastFunction();
3714 // Make a Python command
3715 GEOM::TPythonDump(aFunction, /*append=*/true)
3716 << "listShapesOnCylinder = geompy.GetShapesOnSphereIDs"
3717 << "(" << theShape << ", " << aShapeType << ", " << theCenter << ", "
3718 << theRadius << ", " << theState << ")";
3724 //=======================================================================
3725 //function : getShapesOnQuadrangleIDs
3727 * \brief Find IDs of sub-shapes complying with given status about quadrangle
3728 * \param theShape - the shape to explore
3729 * \param theShapeType - type of sub-shape of theShape
3730 * \param theTopLeftPoint - top left quadrangle corner
3731 * \param theTopRigthPoint - top right quadrangle corner
3732 * \param theBottomLeftPoint - bottom left quadrangle corner
3733 * \param theBottomRigthPoint - bottom right quadrangle corner
3734 * \param theState - required state
3735 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
3737 //=======================================================================
3738 Handle(TColStd_HSequenceOfInteger)
3739 GEOMImpl_IShapesOperations::getShapesOnQuadrangleIDs (const Handle(GEOM_Object)& theShape,
3740 const Standard_Integer theShapeType,
3741 const Handle(GEOM_Object)& theTopLeftPoint,
3742 const Handle(GEOM_Object)& theTopRigthPoint,
3743 const Handle(GEOM_Object)& theBottomLeftPoint,
3744 const Handle(GEOM_Object)& theBottomRigthPoint,
3745 const GEOMAlgo_State theState)
3749 if ( theShape.IsNull() ||
3750 theTopLeftPoint.IsNull() ||
3751 theTopRigthPoint.IsNull() ||
3752 theBottomLeftPoint.IsNull() ||
3753 theBottomRigthPoint.IsNull() )
3756 TopoDS_Shape aShape = theShape->GetValue();
3757 TopoDS_Shape aTL = theTopLeftPoint->GetValue();
3758 TopoDS_Shape aTR = theTopRigthPoint->GetValue();
3759 TopoDS_Shape aBL = theBottomLeftPoint->GetValue();
3760 TopoDS_Shape aBR = theBottomRigthPoint->GetValue();
3762 if (aShape.IsNull() ||
3767 aTL.ShapeType() != TopAbs_VERTEX ||
3768 aTR.ShapeType() != TopAbs_VERTEX ||
3769 aBL.ShapeType() != TopAbs_VERTEX ||
3770 aBR.ShapeType() != TopAbs_VERTEX )
3773 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3774 if ( !checkTypeShapesOn( aShapeType ))
3777 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
3779 // Check presence of triangulation, build if need
3780 if (!GEOMUtils::CheckTriangulation(aShape)) {
3781 SetErrorCode("Cannot build triangulation on the shape");
3786 gp_Pnt aPntTL = BRep_Tool::Pnt(TopoDS::Vertex(aTL));
3787 gp_Pnt aPntTR = BRep_Tool::Pnt(TopoDS::Vertex(aTR));
3788 gp_Pnt aPntBL = BRep_Tool::Pnt(TopoDS::Vertex(aBL));
3789 gp_Pnt aPntBR = BRep_Tool::Pnt(TopoDS::Vertex(aBR));
3791 GEOMAlgo_FinderShapeOnQuad aFinder( aPntTL, aPntTR, aPntBL, aPntBR );
3792 Standard_Real aTol = 0.0001; // default value
3794 aFinder.SetShape(aShape);
3795 aFinder.SetTolerance(aTol);
3796 //aFinder.SetSurface(theSurface);
3797 aFinder.SetShapeType(aShapeType);
3798 aFinder.SetState(theState);
3800 // Sets the minimal number of inner points for the faces that do not have own
3801 // inner points at all (for e.g. rectangular planar faces have just 2 triangles).
3803 aFinder.SetNbPntsMin(3);
3804 // Sets the maximal number of inner points for edges or faces.
3805 // It is usefull for the cases when this number is very big (e.g =2000) to improve
3806 // the performance. If this value =0, all inner points will be taken into account.
3808 aFinder.SetNbPntsMax(100);
3812 // Interprete results
3813 Standard_Integer iErr = aFinder.ErrorStatus();
3814 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
3816 MESSAGE(" iErr : " << iErr);
3817 TCollection_AsciiString aMsg (" iErr : ");
3818 aMsg += TCollection_AsciiString(iErr);
3822 Standard_Integer iWrn = aFinder.WarningStatus();
3823 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
3825 MESSAGE(" *** iWrn : " << iWrn);
3828 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
3830 if (listSS.Extent() < 1) {
3831 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
3832 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
3836 // Fill sequence of object IDs
3837 aSeqOfIDs = new TColStd_HSequenceOfInteger;
3839 TopTools_IndexedMapOfShape anIndices;
3840 TopExp::MapShapes(aShape, anIndices);
3842 TopTools_ListIteratorOfListOfShape itSub (listSS);
3843 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
3844 int id = anIndices.FindIndex(itSub.Value());
3845 aSeqOfIDs->Append(id);
3850 //=======================================================================
3851 //function : GetShapesOnQuadrangle
3853 * \brief Find sub-shapes complying with given status about quadrangle
3854 * \param theShape - the shape to explore
3855 * \param theShapeType - type of sub-shape of theShape
3856 * \param theTopLeftPoint - top left quadrangle corner
3857 * \param theTopRigthPoint - top right quadrangle corner
3858 * \param theBottomLeftPoint - bottom left quadrangle corner
3859 * \param theBottomRigthPoint - bottom right quadrangle corner
3860 * \param theState - required state
3861 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
3863 //=======================================================================
3864 Handle(TColStd_HSequenceOfTransient)
3865 GEOMImpl_IShapesOperations::GetShapesOnQuadrangle (const Handle(GEOM_Object)& theShape,
3866 const Standard_Integer theShapeType,
3867 const Handle(GEOM_Object)& theTopLeftPoint,
3868 const Handle(GEOM_Object)& theTopRigthPoint,
3869 const Handle(GEOM_Object)& theBottomLeftPoint,
3870 const Handle(GEOM_Object)& theBottomRigthPoint,
3871 const GEOMAlgo_State theState)
3874 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
3875 getShapesOnQuadrangleIDs( theShape,
3880 theBottomRigthPoint,
3882 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->IsEmpty() )
3885 // Find objects by indices
3886 TCollection_AsciiString anAsciiList;
3887 Handle(TColStd_HSequenceOfTransient) aSeq;
3888 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
3889 if ( aSeq.IsNull() || aSeq->IsEmpty() )
3892 // Make a Python command
3894 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
3895 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
3897 GEOM::TPythonDump(aFunction)
3898 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnQuadrangle("
3900 << TopAbs_ShapeEnum(theShapeType) << ", "
3901 << theTopLeftPoint << ", "
3902 << theTopRigthPoint << ", "
3903 << theBottomLeftPoint << ", "
3904 << theBottomRigthPoint << ", "
3911 //=======================================================================
3912 //function : GetShapesOnQuadrangleIDs
3914 * \brief Find IDs of sub-shapes complying with given status about quadrangle
3915 * \param theShape - the shape to explore
3916 * \param theShapeType - type of sub-shape of theShape
3917 * \param theTopLeftPoint - top left quadrangle corner
3918 * \param theTopRigthPoint - top right quadrangle corner
3919 * \param theBottomLeftPoint - bottom left quadrangle corner
3920 * \param theBottomRigthPoint - bottom right quadrangle corner
3921 * \param theState - required state
3922 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
3924 //=======================================================================
3925 Handle(TColStd_HSequenceOfInteger)
3926 GEOMImpl_IShapesOperations::GetShapesOnQuadrangleIDs (const Handle(GEOM_Object)& theShape,
3927 const Standard_Integer theShapeType,
3928 const Handle(GEOM_Object)& theTopLeftPoint,
3929 const Handle(GEOM_Object)& theTopRigthPoint,
3930 const Handle(GEOM_Object)& theBottomLeftPoint,
3931 const Handle(GEOM_Object)& theBottomRigthPoint,
3932 const GEOMAlgo_State theState)
3935 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
3936 getShapesOnQuadrangleIDs( theShape,
3941 theBottomRigthPoint,
3943 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->IsEmpty() )
3946 // Make a Python command
3948 // The GetShapesOnCylinder() doesn't change object so no new function is required.
3949 Handle(GEOM_Object) lastObj = GEOM::GetCreatedLast(theShape,theTopLeftPoint);
3950 lastObj = GEOM::GetCreatedLast(lastObj,theTopRigthPoint);
3951 lastObj = GEOM::GetCreatedLast(lastObj,theBottomRigthPoint);
3952 lastObj = GEOM::GetCreatedLast(lastObj,theBottomLeftPoint);
3953 Handle(GEOM_Function) aFunction = lastObj->GetLastFunction();
3955 GEOM::TPythonDump(aFunction, /*append=*/true)
3956 << "listShapesOnQuadrangle = geompy.GetShapesOnQuadrangleIDs("
3958 << TopAbs_ShapeEnum(theShapeType) << ", "
3959 << theTopLeftPoint << ", "
3960 << theTopRigthPoint << ", "
3961 << theBottomLeftPoint << ", "
3962 << theBottomRigthPoint << ", "
3969 //=============================================================================
3973 //=============================================================================
3974 static bool GetInPlaceOfShape (const Handle(GEOM_Function)& theWhereFunction,
3975 const TopTools_IndexedMapOfShape& theWhereIndices,
3976 const TopoDS_Shape& theWhat,
3977 TColStd_ListOfInteger& theModifiedList)
3979 if (theWhereFunction.IsNull() || theWhat.IsNull()) return false;
3981 if (theWhereIndices.Contains(theWhat)) {
3982 // entity was not changed by the operation
3983 Standard_Integer aWhatIndex = theWhereIndices.FindIndex(theWhat);
3984 theModifiedList.Append(aWhatIndex);
3988 // try to find in history
3989 TDF_Label aHistoryLabel = theWhereFunction->GetHistoryEntry(Standard_False);
3991 // search in history for all argument shapes
3992 Standard_Boolean isFound = Standard_False;
3993 Standard_Boolean isGood = Standard_False;
3995 TDF_LabelSequence aLabelSeq;
3996 theWhereFunction->GetDependency(aLabelSeq);
3997 Standard_Integer nbArg = aLabelSeq.Length();
3999 for (Standard_Integer iarg = 1; iarg <= nbArg && !isFound; iarg++) {
4001 TDF_Label anArgumentRefLabel = aLabelSeq.Value(iarg);
4003 Handle(GEOM_Object) anArgumentObject = GEOM_Object::GetReferencedObject(anArgumentRefLabel);
4004 TopoDS_Shape anArgumentShape = anArgumentObject->GetValue();
4006 TopTools_IndexedMapOfShape anArgumentIndices;
4007 TopExp::MapShapes(anArgumentShape, anArgumentIndices);
4009 if (anArgumentIndices.Contains(theWhat)) {
4010 isFound = Standard_True;
4011 Standard_Integer aWhatIndex = anArgumentIndices.FindIndex(theWhat);
4013 // Find corresponding label in history
4014 TDF_Label anArgumentHistoryLabel =
4015 theWhereFunction->GetArgumentHistoryEntry(anArgumentRefLabel, Standard_False);
4016 if (anArgumentHistoryLabel.IsNull()) {
4017 // Lost History of operation argument. Possibly, all its entities was removed.
4018 isGood = Standard_True;
4021 TDF_Label aWhatHistoryLabel = anArgumentHistoryLabel.FindChild(aWhatIndex, Standard_False);
4023 if (aWhatHistoryLabel.IsNull()) {
4024 // Removed entity ? Compound ? Compsolid ? Shell ? Wire
4025 isGood = Standard_False;
4027 Handle(TDataStd_IntegerArray) anIntegerArray;
4028 if (!aWhatHistoryLabel.FindAttribute(TDataStd_IntegerArray::GetID(), anIntegerArray)) {
4029 //Error: Empty modifications history for the sought shape.
4030 isGood = Standard_False;
4033 isGood = Standard_True;
4034 Standard_Integer imod, aModifLen = anIntegerArray->Array()->Length();
4035 for (imod = 1; imod <= aModifLen; imod++) {
4036 theModifiedList.Append(anIntegerArray->Array()->Value(imod));
4047 // try compound/compsolid/shell/wire element by element
4048 bool isFoundAny = false;
4049 TopTools_MapOfShape mapShape;
4051 if (theWhat.ShapeType() == TopAbs_COMPOUND ||
4052 theWhat.ShapeType() == TopAbs_COMPSOLID) {
4053 // recursive processing of compound/compsolid
4054 TopoDS_Iterator anIt (theWhat, Standard_True, Standard_True);
4055 for (; anIt.More(); anIt.Next()) {
4056 if (mapShape.Add(anIt.Value())) {
4057 TopoDS_Shape curWhat = anIt.Value();
4058 isFoundAny = GetInPlaceOfShape(theWhereFunction, theWhereIndices, curWhat, theModifiedList);
4059 if (isFoundAny) isFound = Standard_True;
4063 else if (theWhat.ShapeType() == TopAbs_SHELL) {
4064 // try to replace a shell by its faces images
4065 TopExp_Explorer anExp (theWhat, TopAbs_FACE);
4066 for (; anExp.More(); anExp.Next()) {
4067 if (mapShape.Add(anExp.Current())) {
4068 TopoDS_Shape curWhat = anExp.Current();
4069 isFoundAny = GetInPlaceOfShape(theWhereFunction, theWhereIndices, curWhat, theModifiedList);
4070 if (isFoundAny) isFound = Standard_True;
4074 else if (theWhat.ShapeType() == TopAbs_WIRE) {
4075 // try to replace a wire by its edges images
4076 TopExp_Explorer anExp (theWhat, TopAbs_EDGE);
4077 for (; anExp.More(); anExp.Next()) {
4078 if (mapShape.Add(anExp.Current())) {
4079 TopoDS_Shape curWhat = anExp.Current();
4080 isFoundAny = GetInPlaceOfShape(theWhereFunction, theWhereIndices, curWhat, theModifiedList);
4081 if (isFoundAny) isFound = Standard_True;
4093 //=============================================================================
4095 * GetShapeProperties
4097 //=============================================================================
4098 void GEOMImpl_IShapesOperations::GetShapeProperties( const TopoDS_Shape aShape, Standard_Real tab[],
4101 GProp_GProps theProps;
4103 //TopoDS_Shape aPntShape;
4104 Standard_Real aShapeSize;
4106 if (aShape.ShapeType() == TopAbs_VERTEX) aCenterMass = BRep_Tool::Pnt( TopoDS::Vertex( aShape ) );
4107 else if (aShape.ShapeType() == TopAbs_EDGE) BRepGProp::LinearProperties(aShape, theProps);
4108 else if (aShape.ShapeType() == TopAbs_FACE) BRepGProp::SurfaceProperties(aShape, theProps);
4109 else BRepGProp::VolumeProperties(aShape, theProps);
4111 if (aShape.ShapeType() == TopAbs_VERTEX)
4114 aCenterMass = theProps.CentreOfMass();
4115 aShapeSize = theProps.Mass();
4118 // aPntShape = BRepBuilderAPI_MakeVertex(aCenterMass).Shape();
4119 // aVertex = BRep_Tool::Pnt( TopoDS::Vertex( aPntShape ) );
4120 aVertex = aCenterMass;
4121 tab[0] = aVertex.X();
4122 tab[1] = aVertex.Y();
4123 tab[2] = aVertex.Z();
4124 tab[3] = aShapeSize;
4128 //=============================================================================
4133 //=============================================================================
4134 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlace (Handle(GEOM_Object) theShapeWhere,
4135 Handle(GEOM_Object) theShapeWhat)
4139 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
4141 TopoDS_Shape aWhere = theShapeWhere->GetValue();
4142 TopoDS_Shape aWhat = theShapeWhat->GetValue();
4144 if (aWhere.IsNull() || aWhat.IsNull()) {
4145 SetErrorCode("Error: aWhere and aWhat TopoDS_Shape are Null.");
4149 // Compute confusion tolerance.
4150 Standard_Real aTolConf = Precision::Confusion();
4153 for (i = 0; i < 2; ++i) {
4154 TopExp_Explorer anExp(i == 0 ? aWhere : aWhat, TopAbs_VERTEX);
4156 for (; anExp.More(); anExp.Next()) {
4157 const TopoDS_Vertex aVtx = TopoDS::Vertex(anExp.Current());
4158 const Standard_Real aTolVtx = BRep_Tool::Tolerance(aVtx);
4160 if (aTolVtx > aTolConf) {
4166 // Compute mass tolerance.
4167 Bnd_Box aBoundingBox;
4168 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
4169 Standard_Real aMassTol;
4171 BRepBndLib::Add(aWhere, aBoundingBox);
4172 BRepBndLib::Add(aWhat, aBoundingBox);
4173 aBoundingBox.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
4174 aMassTol = Max(aXmax - aXmin, aYmax - aYmin);
4175 aMassTol = Max(aMassTol, aZmax - aZmin);
4176 aMassTol *= aTolConf;
4178 // Searching for the sub-shapes inside the ShapeWhere shape
4179 GEOMAlgo_GetInPlace aGIP;
4180 aGIP.SetTolerance(aTolConf);
4181 aGIP.SetTolMass(aMassTol);
4182 aGIP.SetTolCG(aTolConf);
4184 aGIP.SetArgument(aWhat);
4185 aGIP.SetShapeWhere(aWhere);
4188 int iErr = aGIP.ErrorStatus();
4190 SetErrorCode("Error in GEOMAlgo_GetInPlace");
4194 // Add direct result.
4195 TopTools_ListOfShape aLSA;
4196 const TopoDS_Shape &aShapeResult = aGIP.Result();
4197 TopTools_MapOfShape aMFence;
4198 TopTools_IndexedMapOfShape aWhereIndices;
4200 TopExp::MapShapes(aWhere, aWhereIndices);
4202 if (aShapeResult.IsNull() == Standard_False) {
4203 TopoDS_Iterator anIt(aShapeResult);
4205 for (; anIt.More(); anIt.Next()) {
4206 const TopoDS_Shape &aPart = anIt.Value();
4208 if(aWhereIndices.Contains(aPart) && aMFence.Add(aPart)) {
4214 if (aLSA.Extent() == 0) {
4215 SetErrorCode(NOT_FOUND_ANY); // Not found any Results
4219 Handle(TColStd_HArray1OfInteger) aModifiedArray = new TColStd_HArray1OfInteger (1, aLSA.Extent());
4220 TopTools_ListIteratorOfListOfShape anIterModif (aLSA);
4221 for (Standard_Integer imod = 1; anIterModif.More(); anIterModif.Next(), imod++) {
4222 if (aWhereIndices.Contains(anIterModif.Value())) {
4223 aModifiedArray->SetValue(imod, aWhereIndices.FindIndex(anIterModif.Value()));
4226 SetErrorCode("Error: wrong sub-shape returned");
4232 Handle(GEOM_Object) aResult = GetEngine()->AddSubShape(theShapeWhere, aModifiedArray);
4233 if (aResult.IsNull()) {
4234 SetErrorCode("Error in algorithm: result found, but cannot be returned.");
4238 if (aModifiedArray->Length() > 1 || theShapeWhat->GetType() == GEOM_GROUP) {
4240 aResult->SetType(GEOM_GROUP);
4242 //Set a sub-shape type
4243 TopoDS_Shape aFirstFound = aLSA.First();
4244 TopAbs_ShapeEnum aShapeType = aFirstFound.ShapeType();
4246 TDF_Label aFreeLabel = aResult->GetFreeLabel();
4247 TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aShapeType);
4250 //Make a Python command
4251 Handle(GEOM_Function) aFunction = aResult->GetFunction(1);
4253 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetInPlace("
4254 << theShapeWhere << ", " << theShapeWhat << ", True)";
4260 //=============================================================================
4262 * case GetInPlaceOld:
4265 //=============================================================================
4266 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlaceOld (Handle(GEOM_Object) theShapeWhere,
4267 Handle(GEOM_Object) theShapeWhat)
4271 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
4273 TopoDS_Shape aWhere = theShapeWhere->GetValue();
4274 TopoDS_Shape aWhat = theShapeWhat->GetValue();
4275 TopoDS_Shape aPntShape;
4276 TopoDS_Vertex aVertex;
4278 if (aWhere.IsNull() || aWhat.IsNull()) {
4279 SetErrorCode("Error: aWhere and aWhat TopoDS_Shape are Null.");
4283 Handle(GEOM_Function) aWhereFunction = theShapeWhere->GetLastFunction();
4284 if (aWhereFunction.IsNull()) {
4285 SetErrorCode("Error: aWhereFunction is Null.");
4289 TopTools_IndexedMapOfShape aWhereIndices;
4290 TopExp::MapShapes(aWhere, aWhereIndices);
4292 TColStd_ListOfInteger aModifiedList;
4293 Standard_Integer aWhereIndex;
4294 Handle(TColStd_HArray1OfInteger) aModifiedArray;
4295 Handle(GEOM_Object) aResult;
4297 bool isFound = false;
4298 TopAbs_ShapeEnum iType = TopAbs_SOLID;
4299 //Standard_Real aWhat_Mass = 0., aWhere_Mass = 0.;
4300 Standard_Real tab_aWhat[4], tab_aWhere[4];
4301 Standard_Real dl_l = 1e-3;
4302 Standard_Real min_l, Tol_0D, Tol_1D, Tol_2D, Tol_3D, Tol_Mass;
4303 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
4304 Bnd_Box BoundingBox;
4305 gp_Pnt aPnt, aPnt_aWhat, tab_Pnt[2];
4306 GProp_GProps aProps;
4308 // Find the iType of the aWhat shape
4310 if ( aWhat.ShapeType() == TopAbs_VERTEX ) iType = TopAbs_VERTEX;
4311 else if ( aWhat.ShapeType() == TopAbs_EDGE || aWhat.ShapeType() == TopAbs_WIRE ) iType = TopAbs_EDGE;
4312 else if ( aWhat.ShapeType() == TopAbs_FACE || aWhat.ShapeType() == TopAbs_SHELL ) iType = TopAbs_FACE;
4313 else if ( aWhat.ShapeType() == TopAbs_SOLID || aWhat.ShapeType() == TopAbs_COMPSOLID ) iType = TopAbs_SOLID;
4314 else if ( aWhat.ShapeType() == TopAbs_COMPOUND ) {
4315 // Only the iType of the first shape in the compound is taken into account
4316 TopoDS_Iterator It (aWhat, Standard_False, Standard_False);
4318 SetErrorCode("Error: theShapeWhat is an empty COMPOUND.");
4321 TopAbs_ShapeEnum compType = It.Value().ShapeType();
4322 if ( compType == TopAbs_VERTEX ) iType = TopAbs_VERTEX;
4323 else if ( compType == TopAbs_EDGE || compType == TopAbs_WIRE ) iType = TopAbs_EDGE;
4324 else if ( compType == TopAbs_FACE || compType == TopAbs_SHELL) iType = TopAbs_FACE;
4325 else if ( compType == TopAbs_SOLID || compType == TopAbs_COMPSOLID) iType = TopAbs_SOLID;
4328 SetErrorCode("Error: An attempt to extract a shape of not supported type.");
4332 iType = GEOMUtils::GetTypeOfSimplePart(aWhat);
4333 if (iType == TopAbs_SHAPE) {
4334 SetErrorCode("Error: An attempt to extract a shape of not supported type.");
4338 TopExp_Explorer Exp_aWhat ( aWhat, iType );
4339 TopExp_Explorer Exp_aWhere ( aWhere, iType );
4340 TopExp_Explorer Exp_Edge ( aWhere, TopAbs_EDGE );
4342 // Find the shortest edge in theShapeWhere shape
4343 BRepBndLib::Add(aWhere, BoundingBox);
4344 BoundingBox.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
4345 min_l = fabs(aXmax - aXmin);
4346 if( min_l < fabs(aYmax - aYmin) ) min_l = fabs(aYmax - aYmin);
4347 if( min_l < fabs(aZmax - aZmin) ) min_l = fabs(aZmax - aZmin);
4349 // Mantis issue 0020908 BEGIN
4350 if (!Exp_Edge.More()) {
4351 min_l = Precision::Confusion();
4353 // Mantis issue 0020908 END
4354 for ( Standard_Integer nbEdge = 0; Exp_Edge.More(); Exp_Edge.Next(), nbEdge++ ) {
4355 TopExp_Explorer Exp_Vertex( Exp_Edge.Current(), TopAbs_VERTEX);
4356 for ( Standard_Integer nbVertex = 0; Exp_Vertex.More(); Exp_Vertex.Next(), nbVertex++ ) {
4357 aPnt = BRep_Tool::Pnt( TopoDS::Vertex( Exp_Vertex.Current() ) );
4358 tab_Pnt[nbVertex] = aPnt;
4360 if ( ! tab_Pnt[0].IsEqual(tab_Pnt[1], dl_l) ) {
4361 BRepGProp::LinearProperties(Exp_Edge.Current(), aProps);
4362 if ( aProps.Mass() < min_l ) min_l = aProps.Mass();
4366 // Compute tolerances
4368 Tol_1D = dl_l * min_l;
4369 Tol_2D = dl_l * ( min_l * min_l) * ( 2. + dl_l);
4370 Tol_3D = dl_l * ( min_l * min_l * min_l ) * ( 3. + (3 * dl_l) + (dl_l * dl_l) );
4372 if (Tol_0D < Precision::Confusion()) Tol_0D = Precision::Confusion();
4373 if (Tol_1D < Precision::Confusion()) Tol_1D = Precision::Confusion();
4374 if (Tol_2D < Precision::Confusion()) Tol_2D = Precision::Confusion();
4375 if (Tol_3D < Precision::Confusion()) Tol_3D = Precision::Confusion();
4377 //if (Tol_1D > 1.0) Tol_1D = 1.0;
4378 //if (Tol_2D > 1.0) Tol_2D = 1.0;
4379 //if (Tol_3D > 1.0) Tol_3D = 1.0;
4382 if ( iType == TopAbs_VERTEX ) Tol_Mass = Tol_0D;
4383 else if ( iType == TopAbs_EDGE ) Tol_Mass = Tol_1D;
4384 else if ( iType == TopAbs_FACE ) Tol_Mass = Tol_2D;
4386 // Compute the ShapeWhat Mass
4388 for ( ; Exp_aWhat.More(); Exp_aWhat.Next() ) {
4389 if ( iType == TopAbs_VERTEX ) {
4393 else if ( iType == TopAbs_EDGE ) BRepGProp::LinearProperties(Exp_aWhat.Current(), aProps);
4394 else if ( iType == TopAbs_FACE ) BRepGProp::SurfaceProperties(Exp_aWhat.Current(), aProps);
4395 else BRepGProp::VolumeProperties(Exp_aWhat.Current(), aProps);
4396 aWhat_Mass += aProps.Mass();
4400 // Searching for the sub-shapes inside the ShapeWhere shape
4401 TopTools_MapOfShape map_aWhere;
4402 for ( Exp_aWhere.ReInit(); Exp_aWhere.More(); Exp_aWhere.Next() ) {
4403 if (!map_aWhere.Add(Exp_aWhere.Current()))
4404 continue; // skip repeated shape to avoid mass addition
4405 GetShapeProperties( Exp_aWhere.Current(), tab_aWhere, aPnt );
4406 for ( Exp_aWhat.ReInit(); Exp_aWhat.More(); Exp_aWhat.Next() ) {
4407 GetShapeProperties( Exp_aWhat.Current(), tab_aWhat, aPnt_aWhat );
4408 if ( fabs(tab_aWhat[3] - tab_aWhere[3]) <= Tol_Mass && aPnt_aWhat.Distance(aPnt) <= Tol_1D )
4411 if ( (tab_aWhat[3] - tab_aWhere[3]) > Tol_Mass ) {
4412 aPntShape = BRepBuilderAPI_MakeVertex( aPnt ).Shape();
4413 aVertex = TopoDS::Vertex( aPntShape );
4414 BRepExtrema_DistShapeShape aWhereDistance ( aVertex, Exp_aWhere.Current() );
4415 BRepExtrema_DistShapeShape aWhatDistance ( aVertex, Exp_aWhat.Current() );
4416 if ( aWhereDistance.IsDone() && aWhatDistance.IsDone() &&
4417 fabs(aWhereDistance.Value() - aWhatDistance.Value()) <= Tol_1D )
4419 // 0020162: "EDF 961 GEOM : Getinplace is getting additionnal orthogonal faces"
4420 // aVertex must be projected to the same point on Where and on What
4421 gp_Pnt pOnWhat = aWhatDistance.PointOnShape2(1);
4422 gp_Pnt pOnWhere = aWhereDistance.PointOnShape2(1);
4423 isFound = ( pOnWhat.Distance(pOnWhere) <= Tol_1D );
4424 if ( isFound && iType == TopAbs_FACE )
4426 // check normals at pOnWhat and pOnWhere
4427 const double angleTol = M_PI/180.;
4428 gp_Vec normToWhat = GetNormal( TopoDS::Face(Exp_aWhat.Current()), aWhatDistance);
4429 gp_Vec normToWhere = GetNormal( TopoDS::Face(Exp_aWhere.Current()), aWhereDistance);
4430 if ( normToWhat * normToWhere < 0 )
4431 normToWhat.Reverse();
4432 isFound = ( normToWhat.Angle( normToWhere ) < angleTol );
4438 aWhereIndex = aWhereIndices.FindIndex(Exp_aWhere.Current());
4439 aModifiedList.Append(aWhereIndex);
4440 //aWhere_Mass += tab_aWhere[3];
4445 //if ( fabs( aWhat_Mass - aWhere_Mass ) <= Tol_Mass )
4449 if (aModifiedList.Extent() == 0) { // Not found any Results
4450 SetErrorCode(NOT_FOUND_ANY);
4454 aModifiedArray = new TColStd_HArray1OfInteger (1, aModifiedList.Extent());
4455 TColStd_ListIteratorOfListOfInteger anIterModif (aModifiedList);
4456 for (Standard_Integer imod = 1; anIterModif.More(); anIterModif.Next(), imod++)
4457 aModifiedArray->SetValue(imod, anIterModif.Value());
4460 aResult = GetEngine()->AddSubShape(theShapeWhere, aModifiedArray);
4461 if (aResult.IsNull()) {
4462 SetErrorCode("Error in algorithm: result found, but cannot be returned.");
4466 if (aModifiedArray->Length() > 1 || theShapeWhat->GetType() == GEOM_GROUP) {
4468 aResult->SetType(GEOM_GROUP);
4470 //Set a sub-shape type
4471 TopoDS_Shape aFirstFound = aWhereIndices.FindKey(aModifiedArray->Value(1));
4472 TopAbs_ShapeEnum aShapeType = aFirstFound.ShapeType();
4474 TDF_Label aFreeLabel = aResult->GetFreeLabel();
4475 TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aShapeType);
4478 //Make a Python command
4479 Handle(GEOM_Function) aFunction = aResult->GetFunction(1);
4481 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetInPlace("
4482 << theShapeWhere << ", " << theShapeWhat << ", False)";
4488 //=======================================================================
4489 //function : GetInPlaceByHistory
4491 //=======================================================================
4492 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlaceByHistory
4493 (Handle(GEOM_Object) theShapeWhere,
4494 Handle(GEOM_Object) theShapeWhat)
4498 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
4500 TopoDS_Shape aWhere = theShapeWhere->GetValue();
4501 TopoDS_Shape aWhat = theShapeWhat->GetValue();
4503 if (aWhere.IsNull() || aWhat.IsNull()) return NULL;
4505 Handle(GEOM_Function) aWhereFunction = theShapeWhere->GetLastFunction();
4506 if (aWhereFunction.IsNull()) return NULL;
4508 //Fill array of indices
4509 TopTools_IndexedMapOfShape aWhereIndices;
4510 TopExp::MapShapes(aWhere, aWhereIndices);
4513 TColStd_ListOfInteger aModifiedList;
4514 bool isFound = GetInPlaceOfShape(aWhereFunction, aWhereIndices, aWhat, aModifiedList);
4516 if (!isFound || aModifiedList.Extent() < 1) {
4517 SetErrorCode("Error: No history found for the sought shape or its sub-shapes.");
4521 Standard_Integer nbFound = aModifiedList.Extent();
4522 TColStd_ListIteratorOfListOfInteger anIterModif (aModifiedList);
4525 // remove sub-shapes inappropriate for group creation
4526 TopAbs_ShapeEnum subType = TopAbs_SHAPE;
4527 while ( anIterModif.More() ) {
4528 TopAbs_ShapeEnum type = aWhereIndices( anIterModif.Value() ).ShapeType();
4529 bool okForGroup = ( type == TopAbs_VERTEX || type == TopAbs_EDGE ||
4530 type == TopAbs_FACE || type == TopAbs_SOLID );
4532 if ( subType == TopAbs_SHAPE )
4535 okForGroup = ( subType == type );
4540 aModifiedList.Remove( anIterModif );
4541 nbFound -= ( !okForGroup );
4543 if ( nbFound == 0 ) {
4544 SetErrorCode("Error: result found but it's type is inappropriate for group creation.");
4549 Handle(TColStd_HArray1OfInteger) aModifiedArray =
4550 new TColStd_HArray1OfInteger( 1, nbFound );
4551 anIterModif.Initialize(aModifiedList);
4552 for (Standard_Integer imod = 1; anIterModif.More(); anIterModif.Next(), imod++)
4553 aModifiedArray->SetValue(imod, anIterModif.Value());
4556 Handle(GEOM_Object) aResult = GetEngine()->AddSubShape(theShapeWhere, aModifiedArray);
4557 if (aResult.IsNull()) {
4558 SetErrorCode("Error in algorithm: result found, but cannot be returned.");
4562 if (aModifiedArray->Length() > 1) {
4564 aResult->SetType(GEOM_GROUP);
4566 //Set a sub-shape type
4567 TopoDS_Shape aFirstFound = aWhereIndices.FindKey(aModifiedArray->Value(1));
4568 TopAbs_ShapeEnum aShapeType = aFirstFound.ShapeType();
4570 TDF_Label aFreeLabel = aResult->GetFreeLabel();
4571 TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aShapeType);
4574 //Make a Python command
4575 Handle(GEOM_Function) aFunction = aResult->GetFunction(1);
4577 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetInPlaceByHistory("
4578 << theShapeWhere << ", " << theShapeWhat << ")";
4584 #define MAX_TOLERANCE 1.e-7
4586 //=======================================================================
4587 //function : isSameEdge
4588 //purpose : Returns True if two edges coincide
4589 //=======================================================================
4590 static bool isSameEdge(const TopoDS_Edge& theEdge1, const TopoDS_Edge& theEdge2)
4592 TopoDS_Vertex V11, V12, V21, V22;
4593 TopExp::Vertices(theEdge1, V11, V12);
4594 TopExp::Vertices(theEdge2, V21, V22);
4595 gp_Pnt P11 = BRep_Tool::Pnt(V11);
4596 gp_Pnt P12 = BRep_Tool::Pnt(V12);
4597 gp_Pnt P21 = BRep_Tool::Pnt(V21);
4598 gp_Pnt P22 = BRep_Tool::Pnt(V22);
4599 bool coincide = false;
4601 //Check that ends of edges coincide
4602 if(P11.Distance(P21) <= MAX_TOLERANCE) {
4603 if(P12.Distance(P22) <= MAX_TOLERANCE) coincide = true;
4605 else if(P11.Distance(P22) <= MAX_TOLERANCE) {
4606 if(P12.Distance(P21) <= MAX_TOLERANCE) coincide = true;
4609 if(!coincide) return false;
4611 if (BRep_Tool::Degenerated(theEdge1))
4612 if (BRep_Tool::Degenerated(theEdge2)) return true;
4615 if (BRep_Tool::Degenerated(theEdge2)) return false;
4617 double U11, U12, U21, U22;
4618 Handle(Geom_Curve) C1 = BRep_Tool::Curve(theEdge1, U11, U12);
4619 Handle(Geom_Curve) C2 = BRep_Tool::Curve(theEdge2, U21, U22);
4620 if(C1->DynamicType() == C2->DynamicType()) return true;
4622 //Check that both edges has the same geometry
4623 double range = U12-U11;
4624 double U = U11+ range/3.0;
4625 gp_Pnt P1 = C1->Value(U); //Compute a point on one third of the edge's length
4626 U = U11+range*2.0/3.0;
4627 gp_Pnt P2 = C1->Value(U); //Compute a point on two thirds of the edge's length
4629 if(!GeomLib_Tool::Parameter(C2, P1, MAX_TOLERANCE, U) || U < U21 || U > U22)
4632 if(P1.Distance(C2->Value(U)) > MAX_TOLERANCE) return false;
4634 if(!GeomLib_Tool::Parameter(C2, P2, MAX_TOLERANCE, U) || U < U21 || U > U22)
4637 if(P2.Distance(C2->Value(U)) > MAX_TOLERANCE) return false;
4642 #include <TopoDS_TShape.hxx>
4643 //=======================================================================
4644 //function : isSameFace
4645 //purpose : Returns True if two faces coincide
4646 //=======================================================================
4647 static bool isSameFace(const TopoDS_Face& theFace1, const TopoDS_Face& theFace2)
4649 TopExp_Explorer E(theFace1, TopAbs_EDGE);
4650 TopTools_ListOfShape LS1, LS2;
4651 for(; E.More(); E.Next()) LS1.Append(E.Current());
4653 E.Init(theFace2, TopAbs_EDGE);
4654 for(; E.More(); E.Next()) LS2.Append(E.Current());
4656 //Compare the number of edges in the faces
4657 if(LS1.Extent() != LS2.Extent()) return false;
4659 double aMin = RealFirst(), aMax = RealLast();
4660 double xminB1=aMax, yminB1=aMax, zminB1=aMax, xminB2=aMax, yminB2=aMax, zminB2=aMax;
4661 double xmaxB1=aMin, ymaxB1=aMin, zmaxB1=aMin, xmaxB2=aMin, ymaxB2=aMin, zmaxB2=aMin;
4663 for(E.Init(theFace1, TopAbs_VERTEX); E.More(); E.Next()) {
4664 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4665 if(P.X() < xminB1) xminB1 = P.X();
4666 if(P.Y() < yminB1) yminB1 = P.Y();
4667 if(P.Z() < zminB1) zminB1 = P.Z();
4668 if(P.X() > xmaxB1) xmaxB1 = P.X();
4669 if(P.Y() > ymaxB1) ymaxB1 = P.Y();
4670 if(P.Z() > zmaxB1) zmaxB1 = P.Z();
4673 for(E.Init(theFace2, TopAbs_VERTEX); E.More(); E.Next()) {
4674 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4675 if(P.X() < xminB2) xminB2 = P.X();
4676 if(P.Y() < yminB2) yminB2 = P.Y();
4677 if(P.Z() < zminB2) zminB2 = P.Z();
4678 if(P.X() > xmaxB2) xmaxB2 = P.X();
4679 if(P.Y() > ymaxB2) ymaxB2 = P.Y();
4680 if(P.Z() > zmaxB2) zmaxB2 = P.Z();
4683 //Compare the bounding boxes of both faces
4684 if(gp_Pnt(xminB1, yminB1, zminB1).Distance(gp_Pnt(xminB2, yminB2, zminB2)) > MAX_TOLERANCE)
4687 if(gp_Pnt(xmaxB1, ymaxB1, zmaxB1).Distance(gp_Pnt(xmaxB2, ymaxB2, zmaxB2)) > MAX_TOLERANCE)
4690 Handle(Geom_Surface) S1 = BRep_Tool::Surface(theFace1);
4691 Handle(Geom_Surface) S2 = BRep_Tool::Surface(theFace2);
4693 //Check if there a coincidence of two surfaces at least in two points
4694 double U11, U12, V11, V12, U21, U22, V21, V22;
4695 BRepTools::UVBounds(theFace1, U11, U12, V11, V12);
4696 BRepTools::UVBounds(theFace2, U21, U22, V21, V22);
4698 double rangeU = U12-U11;
4699 double rangeV = V12-V11;
4700 double U = U11 + rangeU/3.0;
4701 double V = V11 + rangeV/3.0;
4702 gp_Pnt P1 = S1->Value(U, V);
4703 U = U11+rangeU*2.0/3.0;
4704 V = V11+rangeV*2.0/3.0;
4705 gp_Pnt P2 = S1->Value(U, V);
4707 if (!GeomLib_Tool::Parameters(S2, P1, MAX_TOLERANCE, U, V) || U < U21 || U > U22 || V < V21 || V > V22)
4710 if (P1.Distance(S2->Value(U,V)) > MAX_TOLERANCE) return false;
4712 if (!GeomLib_Tool::Parameters(S2, P2, MAX_TOLERANCE, U, V) || U < U21 || U > U22 || V < V21 || V > V22)
4715 if (P2.Distance(S2->Value(U, V)) > MAX_TOLERANCE) return false;
4717 //Check that each edge of the Face1 has a counterpart in the Face2
4718 TopTools_MapOfOrientedShape aMap;
4719 TopTools_ListIteratorOfListOfShape LSI1(LS1);
4720 for(; LSI1.More(); LSI1.Next()) {
4721 TopoDS_Edge E = TopoDS::Edge(LSI1.Value());
4722 bool isFound = false;
4723 TopTools_ListIteratorOfListOfShape LSI2(LS2);
4724 for(; LSI2.More(); LSI2.Next()) {
4725 TopoDS_Shape aValue = LSI2.Value();
4726 if(aMap.Contains(aValue)) continue; //To avoid checking already found edge several times
4727 if(isSameEdge(E, TopoDS::Edge(aValue))) {
4733 if(!isFound) return false;
4739 //=======================================================================
4740 //function : isSameSolid
4741 //purpose : Returns True if two solids coincide
4742 //=======================================================================
4743 bool isSameSolid(const TopoDS_Solid& theSolid1, const TopoDS_Solid& theSolid2)
4745 TopExp_Explorer E(theSolid1, TopAbs_FACE);
4746 TopTools_ListOfShape LS1, LS2;
4747 for(; E.More(); E.Next()) LS1.Append(E.Current());
4748 E.Init(theSolid2, TopAbs_FACE);
4749 for(; E.More(); E.Next()) LS2.Append(E.Current());
4751 if(LS1.Extent() != LS2.Extent()) return false;
4753 double aMin = RealFirst(), aMax = RealLast();
4754 double xminB1=aMax, yminB1=aMax, zminB1=aMax, xminB2=aMax, yminB2=aMax, zminB2=aMax;
4755 double xmaxB1=aMin, ymaxB1=aMin, zmaxB1=aMin, xmaxB2=aMin, ymaxB2=aMin, zmaxB2=aMin;
4757 for(E.Init(theSolid1, TopAbs_VERTEX); E.More(); E.Next()) {
4758 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4759 if(P.X() < xminB1) xminB1 = P.X();
4760 if(P.Y() < yminB1) yminB1 = P.Y();
4761 if(P.Z() < zminB1) zminB1 = P.Z();
4762 if(P.X() > xmaxB1) xmaxB1 = P.X();
4763 if(P.Y() > ymaxB1) ymaxB1 = P.Y();
4764 if(P.Z() > zmaxB1) zmaxB1 = P.Z();
4767 for(E.Init(theSolid2, TopAbs_VERTEX); E.More(); E.Next()) {
4768 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4769 if(P.X() < xminB2) xminB2 = P.X();
4770 if(P.Y() < yminB2) yminB2 = P.Y();
4771 if(P.Z() < zminB2) zminB2 = P.Z();
4772 if(P.X() > xmaxB2) xmaxB2 = P.X();
4773 if(P.Y() > ymaxB2) ymaxB2 = P.Y();
4774 if(P.Z() > zmaxB2) zmaxB2 = P.Z();
4777 //Compare the bounding boxes of both solids
4778 if(gp_Pnt(xminB1, yminB1, zminB1).Distance(gp_Pnt(xminB2, yminB2, zminB2)) > MAX_TOLERANCE)
4781 if(gp_Pnt(xmaxB1, ymaxB1, zmaxB1).Distance(gp_Pnt(xmaxB2, ymaxB2, zmaxB2)) > MAX_TOLERANCE)
4784 //Check that each face of the Solid1 has a counterpart in the Solid2
4785 TopTools_MapOfOrientedShape aMap;
4786 TopTools_ListIteratorOfListOfShape LSI1(LS1);
4787 for(; LSI1.More(); LSI1.Next()) {
4788 TopoDS_Face F = TopoDS::Face(LSI1.Value());
4789 bool isFound = false;
4790 TopTools_ListIteratorOfListOfShape LSI2(LS2);
4791 for(; LSI2.More(); LSI2.Next()) {
4792 if(aMap.Contains(LSI2.Value())) continue; //To avoid checking already found faces several times
4793 if(isSameFace(F, TopoDS::Face(LSI2.Value()))) {
4794 aMap.Add(LSI2.Value());
4799 if(!isFound) return false;
4805 //=======================================================================
4806 //function : GetSame
4808 //=======================================================================
4809 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetSame(const Handle(GEOM_Object)& theShapeWhere,
4810 const Handle(GEOM_Object)& theShapeWhat)
4813 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
4815 TopoDS_Shape aWhere = theShapeWhere->GetValue();
4816 TopoDS_Shape aWhat = theShapeWhat->GetValue();
4818 if (aWhere.IsNull() || aWhat.IsNull()) return NULL;
4821 bool isFound = false;
4822 TopoDS_Shape aSubShape;
4823 TopTools_MapOfShape aMap;
4825 if (aWhat.ShapeType() == TopAbs_COMPOUND || aWhat.ShapeType() == TopAbs_COMPSOLID) {
4826 TopoDS_Iterator It (aWhat, Standard_True, Standard_True);
4827 if (It.More()) aWhat = It.Value();
4830 SetErrorCode("Compounds of two or more shapes are not allowed for aWhat argument");
4835 switch (aWhat.ShapeType()) {
4836 case TopAbs_VERTEX: {
4837 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(aWhat));
4838 TopExp_Explorer E(aWhere, TopAbs_VERTEX);
4839 for(; E.More(); E.Next()) {
4840 if(!aMap.Add(E.Current())) continue;
4841 gp_Pnt P2 = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4842 if(P.Distance(P2) <= MAX_TOLERANCE) {
4844 aSubShape = E.Current();
4851 TopoDS_Edge anEdge = TopoDS::Edge(aWhat);
4852 TopExp_Explorer E(aWhere, TopAbs_EDGE);
4853 for(; E.More(); E.Next()) {
4854 if(!aMap.Add(E.Current())) continue;
4855 if(isSameEdge(anEdge, TopoDS::Edge(E.Current()))) {
4856 aSubShape = E.Current();
4864 TopoDS_Face aFace = TopoDS::Face(aWhat);
4865 TopExp_Explorer E(aWhere, TopAbs_FACE);
4866 for(; E.More(); E.Next()) {
4867 if(!aMap.Add(E.Current())) continue;
4868 if(isSameFace(aFace, TopoDS::Face(E.Current()))) {
4869 aSubShape = E.Current();
4876 case TopAbs_SOLID: {
4877 TopoDS_Solid aSolid = TopoDS::Solid(aWhat);
4878 TopExp_Explorer E(aWhere, TopAbs_SOLID);
4879 for(; E.More(); E.Next()) {
4880 if(!aMap.Add(E.Current())) continue;
4881 if(isSameSolid(aSolid, TopoDS::Solid(E.Current()))) {
4882 aSubShape = E.Current();
4894 TopTools_IndexedMapOfShape anIndices;
4895 TopExp::MapShapes(aWhere, anIndices);
4896 if (anIndices.Contains(aSubShape))
4897 anIndex = anIndices.FindIndex(aSubShape);
4900 if (anIndex < 0) return NULL;
4902 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
4904 anArray->SetValue(1, anIndex);
4906 Handle(GEOM_Object) aResult = GetEngine()->AddSubShape(theShapeWhere, anArray);
4907 Handle(GEOM_Function) aFunction = aResult->GetLastFunction();
4909 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetSame("
4910 << theShapeWhere << ", " << theShapeWhat << ")";
4918 //=======================================================================
4919 //function : GetSameIDs
4921 //=======================================================================
4922 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetSameIDs
4923 (const Handle(GEOM_Object)& theShapeWhere,
4924 const Handle(GEOM_Object)& theShapeWhat)
4927 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
4929 TopoDS_Shape aWhere = theShapeWhere->GetValue();
4930 TopoDS_Shape aWhat = theShapeWhat->GetValue();
4932 if (aWhere.IsNull() || aWhat.IsNull()) return NULL;
4934 TopTools_ListOfShape listShape;
4935 TopTools_MapOfShape aMap;
4937 if (aWhat.ShapeType() == TopAbs_COMPOUND || aWhat.ShapeType() == TopAbs_COMPSOLID) {
4938 TopoDS_Iterator It (aWhat, Standard_True, Standard_True);
4939 if (It.More()) aWhat = It.Value();
4942 SetErrorCode("Compounds of two or more shapes are not allowed for aWhat argument");
4947 switch (aWhat.ShapeType()) {
4948 case TopAbs_VERTEX: {
4949 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(aWhat));
4950 TopExp_Explorer E(aWhere, TopAbs_VERTEX);
4951 for(; E.More(); E.Next()) {
4952 if(!aMap.Add(E.Current())) continue;
4953 gp_Pnt P2 = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4954 if(P.Distance(P2) <= MAX_TOLERANCE) {
4955 listShape.Append(E.Current());
4961 TopoDS_Edge anEdge = TopoDS::Edge(aWhat);
4962 TopExp_Explorer E(aWhere, TopAbs_EDGE);
4963 for(; E.More(); E.Next()) {
4964 if(!aMap.Add(E.Current())) continue;
4965 if(isSameEdge(anEdge, TopoDS::Edge(E.Current()))) {
4966 listShape.Append(E.Current());
4972 TopoDS_Face aFace = TopoDS::Face(aWhat);
4973 TopExp_Explorer E(aWhere, TopAbs_FACE);
4974 for(; E.More(); E.Next()) {
4975 if(!aMap.Add(E.Current())) continue;
4976 if(isSameFace(aFace, TopoDS::Face(E.Current()))) {
4977 listShape.Append(E.Current());
4982 case TopAbs_SOLID: {
4983 TopoDS_Solid aSolid = TopoDS::Solid(aWhat);
4984 TopExp_Explorer E(aWhere, TopAbs_SOLID);
4985 for(; E.More(); E.Next()) {
4986 if(!aMap.Add(E.Current())) continue;
4987 if(isSameSolid(aSolid, TopoDS::Solid(E.Current()))) {
4988 listShape.Append(E.Current());
4997 if ( !listShape.IsEmpty() ) {
4998 TopTools_IndexedMapOfShape anIndices;
4999 TopExp::MapShapes(aWhere, anIndices);
5000 TopTools_ListIteratorOfListOfShape itSub (listShape);
5001 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
5002 for (; itSub.More(); itSub.Next()) {
5003 if (anIndices.Contains(itSub.Value()))
5004 aSeq->Append(anIndices.FindIndex(itSub.Value()));
5007 // The GetSameIDs() doesn't change object so no new function is required.
5008 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShapeWhere,theShapeWhat)->GetLastFunction();
5010 // Make a Python command
5011 GEOM::TPythonDump(aFunction, /*append=*/true)
5012 << "listSameIDs = geompy.GetSameIDs("
5013 << theShapeWhere << ", "
5014 << theShapeWhat << ")";
5017 SetErrorCode(NOT_FOUND_ANY);
5022 //=======================================================================
5023 //function : ExtendEdge
5025 //=======================================================================
5026 Handle(GEOM_Object) GEOMImpl_IShapesOperations::ExtendEdge
5027 (const Handle(GEOM_Object) &theEdge,
5028 const Standard_Real theMin,
5029 const Standard_Real theMax)
5033 if (theEdge.IsNull()) {
5037 //Add a new Edge object
5038 Handle(GEOM_Object) aResEdge = GetEngine()->AddObject(GetDocID(), GEOM_EDGE);
5040 //Add a new Vector function
5041 Handle(GEOM_Function) aFunction =
5042 aResEdge->AddFunction(GEOMImpl_ShapeDriver::GetID(), EDGE_UV);
5044 //Check if the function is set correctly
5045 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) {
5049 GEOMImpl_IShapeExtend aCI (aFunction);
5051 Handle(GEOM_Function) anEdge = theEdge->GetLastFunction();
5053 if (anEdge.IsNull()) {
5057 aCI.SetShape(anEdge);
5058 aCI.SetUMin(theMin);
5059 aCI.SetUMax(theMax);
5061 //Compute the Edge value
5064 if (!GetSolver()->ComputeFunction(aFunction)) {
5065 SetErrorCode("Shape driver failed");
5070 catch (Standard_Failure) {
5071 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
5072 SetErrorCode(aFail->GetMessageString());
5077 //Make a Python command
5078 GEOM::TPythonDump(aFunction)
5079 << aResEdge << " = geompy.ExtendEdge("
5080 << theEdge << ", " << theMin << ", " << theMax << ")";
5087 //=======================================================================
5088 //function : ExtendFace
5090 //=======================================================================
5091 Handle(GEOM_Object) GEOMImpl_IShapesOperations::ExtendFace
5092 (const Handle(GEOM_Object) &theFace,
5093 const Standard_Real theUMin,
5094 const Standard_Real theUMax,
5095 const Standard_Real theVMin,
5096 const Standard_Real theVMax)
5100 if (theFace.IsNull()) {
5104 //Add a new Face object
5105 Handle(GEOM_Object) aResFace = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
5107 //Add a new Vector function
5108 Handle(GEOM_Function) aFunction =
5109 aResFace->AddFunction(GEOMImpl_ShapeDriver::GetID(), FACE_UV);
5111 //Check if the function is set correctly
5112 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) {
5116 GEOMImpl_IShapeExtend aCI (aFunction);
5118 Handle(GEOM_Function) aFace = theFace->GetLastFunction();
5120 if (aFace.IsNull()) {
5124 aCI.SetShape(aFace);
5125 aCI.SetUMin(theUMin);
5126 aCI.SetUMax(theUMax);
5127 aCI.SetVMin(theVMin);
5128 aCI.SetVMax(theVMax);
5130 //Compute the Face value
5133 if (!GetSolver()->ComputeFunction(aFunction)) {
5134 SetErrorCode("Shape driver failed");
5139 catch (Standard_Failure) {
5140 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
5141 SetErrorCode(aFail->GetMessageString());
5146 //Make a Python command
5147 GEOM::TPythonDump(aFunction)
5148 << aResFace << " = geompy.ExtendFace("
5149 << theFace << ", " << theUMin << ", " << theUMax << ", "
5150 << theVMin << ", " << theVMax << ")";
5157 //=======================================================================
5158 //function : MakeSurfaceFromFace
5160 //=======================================================================
5161 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeSurfaceFromFace
5162 (const Handle(GEOM_Object) &theFace)
5166 if (theFace.IsNull()) {
5170 //Add a new Face object
5171 Handle(GEOM_Object) aResFace = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
5173 //Add a new Vector function
5174 Handle(GEOM_Function) aFunction =
5175 aResFace->AddFunction(GEOMImpl_ShapeDriver::GetID(), SURFACE_FROM_FACE);
5177 //Check if the function is set correctly
5178 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) {
5182 GEOMImpl_IShapeExtend aCI (aFunction);
5184 Handle(GEOM_Function) aFace = theFace->GetLastFunction();
5186 if (aFace.IsNull()) {
5190 aCI.SetShape(aFace);
5192 //Compute the Face value
5195 if (!GetSolver()->ComputeFunction(aFunction)) {
5196 SetErrorCode("Shape driver failed");
5201 catch (Standard_Failure) {
5202 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
5203 SetErrorCode(aFail->GetMessageString());
5208 //Make a Python command
5209 GEOM::TPythonDump(aFunction)
5210 << aResFace << " = geompy.MakeSurfaceFromFace("