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_FinderShapeOn1.hxx"
59 #include "GEOMAlgo_FinderShapeOnQuad.hxx"
60 #include "GEOMAlgo_FinderShapeOn2.hxx"
61 #include "GEOMAlgo_GetInPlace.hxx"
62 #include "GEOMAlgo_GetInPlaceAPI.hxx"
63 #include "GEOMAlgo_GlueDetector.hxx"
65 #include <utilities.h>
67 #include <BRepAdaptor_Curve.hxx>
68 #include <BRepAdaptor_Surface.hxx>
69 #include <BRepTools.hxx>
70 #include <BRep_Builder.hxx>
71 #include <BRep_Tool.hxx>
72 #include <GeomLib_Tool.hxx>
73 #include <Geom_CylindricalSurface.hxx>
74 #include <Geom_Plane.hxx>
75 #include <Geom_SphericalSurface.hxx>
76 #include <Geom_Surface.hxx>
77 #include <Precision.hxx>
78 #include <TColStd_HArray1OfInteger.hxx>
79 #include <TDF_Tool.hxx>
80 #include <TDataStd_Integer.hxx>
81 #include <TDataStd_ListIteratorOfListOfExtendedString.hxx>
83 #include <TopExp_Explorer.hxx>
84 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
85 #include <TopTools_IndexedMapOfShape.hxx>
86 #include <TopTools_ListIteratorOfListOfShape.hxx>
87 #include <TopTools_MapOfOrientedShape.hxx>
88 #include <TopTools_MapOfShape.hxx>
89 #include <TopTools_SequenceOfShape.hxx>
91 #include <TopoDS_Compound.hxx>
92 #include <TopoDS_Edge.hxx>
93 #include <TopoDS_Face.hxx>
94 #include <TopoDS_Iterator.hxx>
95 #include <TopoDS_Shape.hxx>
96 #include <TopoDS_Solid.hxx>
97 #include <TopoDS_Vertex.hxx>
98 #include <gp_Cylinder.hxx>
103 #include <Standard_Failure.hxx>
104 #include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
108 void AddFlatSubShapes(const TopoDS_Shape& S, TopTools_ListOfShape& L, TopTools_MapOfShape& M)
110 if (S.ShapeType() != TopAbs_COMPOUND) {
114 TopoDS_Iterator It(S, Standard_True, Standard_True);
115 for (; It.More(); It.Next()) {
116 TopoDS_Shape SS = It.Value();
118 AddFlatSubShapes(SS, L, M);
124 //=============================================================================
128 //=============================================================================
129 GEOMImpl_IShapesOperations::GEOMImpl_IShapesOperations (GEOM_Engine* theEngine, int theDocID)
130 : GEOM_IOperations(theEngine, theDocID)
132 MESSAGE("GEOMImpl_IShapesOperations::GEOMImpl_IShapesOperations");
135 //=============================================================================
139 //=============================================================================
140 GEOMImpl_IShapesOperations::~GEOMImpl_IShapesOperations()
142 MESSAGE("GEOMImpl_IShapesOperations::~GEOMImpl_IShapesOperations");
145 //=============================================================================
149 //=============================================================================
150 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeEdge
151 (Handle(GEOM_Object) thePnt1, Handle(GEOM_Object) thePnt2)
155 if (thePnt1.IsNull() || thePnt2.IsNull()) return NULL;
157 //Add a new Edge object
158 Handle(GEOM_Object) anEdge = GetEngine()->AddObject(GetDocID(), GEOM_EDGE);
160 //Add a new Vector function
161 Handle(GEOM_Function) aFunction =
162 anEdge->AddFunction(GEOMImpl_VectorDriver::GetID(), VECTOR_TWO_PNT);
164 //Check if the function is set correctly
165 if (aFunction->GetDriverGUID() != GEOMImpl_VectorDriver::GetID()) return NULL;
167 GEOMImpl_IVector aPI (aFunction);
169 Handle(GEOM_Function) aRef1 = thePnt1->GetLastFunction();
170 Handle(GEOM_Function) aRef2 = thePnt2->GetLastFunction();
171 if (aRef1.IsNull() || aRef2.IsNull()) return NULL;
173 aPI.SetPoint1(aRef1);
174 aPI.SetPoint2(aRef2);
176 //Compute the Edge value
179 if (!GetSolver()->ComputeFunction(aFunction)) {
180 SetErrorCode("Vector driver failed");
184 catch (Standard_Failure) {
185 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
186 SetErrorCode(aFail->GetMessageString());
190 //Make a Python command
191 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdge("
192 << thePnt1 << ", " << thePnt2 << ")";
198 //=============================================================================
200 * MakeEdgeOnCurveByLength
202 //=============================================================================
203 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeEdgeOnCurveByLength
204 (Handle(GEOM_Object) theRefCurve,
205 const Standard_Real theLength,
206 Handle(GEOM_Object) theStartPoint)
210 if (theRefCurve.IsNull()) return NULL;
212 //Add a new Edge object
213 Handle(GEOM_Object) anEdge = GetEngine()->AddObject(GetDocID(), GEOM_EDGE);
215 //Add a new Vector function
216 Handle(GEOM_Function) aFunction =
217 anEdge->AddFunction(GEOMImpl_ShapeDriver::GetID(), EDGE_CURVE_LENGTH);
219 //Check if the function is set correctly
220 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
222 GEOMImpl_IVector aPI (aFunction);
224 Handle(GEOM_Function) aRef1 = theRefCurve->GetLastFunction();
225 if (aRef1.IsNull()) return NULL;
226 aPI.SetPoint1(aRef1);
228 if (!theStartPoint.IsNull()) {
229 Handle(GEOM_Function) aRef2 = theStartPoint->GetLastFunction();
230 aPI.SetPoint2(aRef2);
233 aPI.SetParameter(theLength);
235 //Compute the Edge value
238 if (!GetSolver()->ComputeFunction(aFunction)) {
239 SetErrorCode("Vector driver failed");
243 catch (Standard_Failure) {
244 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
245 SetErrorCode(aFail->GetMessageString());
249 //Make a Python command
250 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdgeOnCurveByLength("
251 << theRefCurve << ", " << theLength << ", " << theStartPoint << ")";
257 //=============================================================================
261 //=============================================================================
262 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeEdgeWire
263 (Handle(GEOM_Object) theWire,
264 const Standard_Real theLinearTolerance,
265 const Standard_Real theAngularTolerance)
269 if (theWire.IsNull()) return NULL;
271 //Add a new Edge object
272 Handle(GEOM_Object) anEdge = GetEngine()->AddObject(GetDocID(), GEOM_EDGE);
274 //Add a new Vector function
275 Handle(GEOM_Function) aFunction =
276 anEdge->AddFunction(GEOMImpl_ShapeDriver::GetID(), EDGE_WIRE);
278 //Check if the function is set correctly
279 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
281 GEOMImpl_IShapes aCI (aFunction);
283 Handle(GEOM_Function) aWire = theWire->GetLastFunction();
285 if (aWire.IsNull()) return NULL;
288 aCI.SetTolerance(theLinearTolerance);
289 aCI.SetAngularTolerance(theAngularTolerance);
291 //Compute the Edge value
294 if (!GetSolver()->ComputeFunction(aFunction)) {
295 SetErrorCode("Shape driver failed");
299 catch (Standard_Failure) {
300 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
301 SetErrorCode(aFail->GetMessageString());
305 const double DEF_LIN_TOL = Precision::Confusion();
306 const double DEF_ANG_TOL = Precision::Angular();
307 //Make a Python command
308 if ( theAngularTolerance == DEF_ANG_TOL ) {
309 if ( theLinearTolerance == DEF_LIN_TOL )
310 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdgeWire("
313 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdgeWire("
314 << theWire << ", " << theLinearTolerance << ")";
317 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdgeWire("
318 << theWire << ", " << theLinearTolerance << ", "
319 << theAngularTolerance << ")";
326 //=============================================================================
330 //=============================================================================
331 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeWire
332 (std::list<Handle(GEOM_Object)> theShapes,
333 const Standard_Real theTolerance)
338 Handle(GEOM_Object) aWire = GetEngine()->AddObject(GetDocID(), GEOM_WIRE);
341 Handle(GEOM_Function) aFunction =
342 aWire->AddFunction(GEOMImpl_ShapeDriver::GetID(), WIRE_EDGES);
343 if (aFunction.IsNull()) return NULL;
345 //Check if the function is set correctly
346 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
348 GEOMImpl_IShapes aCI (aFunction);
349 aCI.SetTolerance(theTolerance);
351 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
354 std::list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
355 for (; it != theShapes.end(); it++) {
356 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
357 if (aRefSh.IsNull()) {
358 SetErrorCode("NULL argument shape for the shape construction");
361 aShapesSeq->Append(aRefSh);
363 aCI.SetShapes(aShapesSeq);
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 //Make a Python command
380 GEOM::TPythonDump pd (aFunction);
381 pd << aWire << " = geompy.MakeWire([";
384 it = theShapes.begin();
385 if (it != theShapes.end()) {
387 while (it != theShapes.end()) {
388 pd << ", " << (*it++);
391 pd << "], " << theTolerance << ")";
397 //=============================================================================
401 //=============================================================================
402 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFace (Handle(GEOM_Object) theWire,
403 const bool isPlanarWanted)
407 if (theWire.IsNull()) return NULL;
409 //Add a new Face object
410 Handle(GEOM_Object) aFace = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
412 //Add a new Shape function for creation of a face from a wire
413 Handle(GEOM_Function) aFunction =
414 aFace->AddFunction(GEOMImpl_ShapeDriver::GetID(), FACE_WIRE);
415 if (aFunction.IsNull()) return NULL;
417 //Check if the function is set correctly
418 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
420 GEOMImpl_IShapes aCI (aFunction);
422 Handle(GEOM_Function) aRefWire = theWire->GetLastFunction();
424 if (aRefWire.IsNull()) return NULL;
426 aCI.SetBase(aRefWire);
427 aCI.SetIsPlanar(isPlanarWanted);
429 //Compute the Face value
430 Standard_Boolean isWarning = Standard_False;
433 if (!GetSolver()->ComputeFunction(aFunction)) {
434 SetErrorCode("Shape driver failed to compute a face");
438 catch (Standard_Failure) {
439 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
440 SetErrorCode(aFail->GetMessageString());
441 // to provide warning
442 if (!aFunction->GetValue().IsNull()) {
443 isWarning = Standard_True;
449 //Make a Python command
450 GEOM::TPythonDump(aFunction) << aFace << " = geompy.MakeFace("
451 << theWire << ", " << (int)isPlanarWanted << ")";
453 // to provide warning
454 if (!isWarning) SetErrorCode(OK);
458 //=============================================================================
462 //=============================================================================
463 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFaceWires
464 (std::list<Handle(GEOM_Object)> theShapes,
465 const bool isPlanarWanted)
470 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
473 Handle(GEOM_Function) aFunction =
474 aShape->AddFunction(GEOMImpl_ShapeDriver::GetID(), FACE_WIRES);
475 if (aFunction.IsNull()) return NULL;
477 //Check if the function is set correctly
478 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
480 GEOMImpl_IShapes aCI (aFunction);
482 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
485 std::list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
486 for (; it != theShapes.end(); it++) {
487 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
488 if (aRefSh.IsNull()) {
489 SetErrorCode("NULL argument shape for the face construction");
492 aShapesSeq->Append(aRefSh);
494 aCI.SetShapes(aShapesSeq);
496 aCI.SetIsPlanar(isPlanarWanted);
499 Standard_Boolean isWarning = Standard_False;
502 if (!GetSolver()->ComputeFunction(aFunction)) {
503 SetErrorCode("Shape driver failed");
507 catch (Standard_Failure) {
508 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
509 SetErrorCode(aFail->GetMessageString());
510 // to provide warning
511 if (!aFunction->GetValue().IsNull()) {
512 isWarning = Standard_True;
518 //Make a Python command
519 GEOM::TPythonDump pd (aFunction);
520 pd << aShape << " = geompy.MakeFaceWires([";
523 it = theShapes.begin();
524 if (it != theShapes.end()) {
526 while (it != theShapes.end()) {
527 pd << ", " << (*it++);
530 pd << "], " << (int)isPlanarWanted << ")";
532 // to provide warning
533 if (!isWarning) SetErrorCode(OK);
537 //=============================================================================
539 * MakeFaceFromSurface
541 //=============================================================================
542 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFaceFromSurface
543 (Handle(GEOM_Object) theFace,
544 Handle(GEOM_Object) theWire)
549 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
552 Handle(GEOM_Function) aFunction =
553 aShape->AddFunction(GEOMImpl_ShapeDriver::GetID(), FACE_FROM_SURFACE);
555 if (aFunction.IsNull()) {
559 //Check if the function is set correctly
560 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) {
564 GEOMImpl_IShapes aCI (aFunction);
565 Handle(TColStd_HSequenceOfTransient) aShapesSeq =
566 new TColStd_HSequenceOfTransient;
567 Handle(GEOM_Function) aRefFace = theFace->GetLastFunction();
568 Handle(GEOM_Function) aRefWire = theWire->GetLastFunction();
570 if (aRefFace.IsNull()) {
571 SetErrorCode("NULL argument face for the face construction");
575 if (aRefWire.IsNull()) {
576 SetErrorCode("NULL argument wire for the face construction");
580 aShapesSeq->Append(aRefFace);
581 aShapesSeq->Append(aRefWire);
583 aCI.SetShapes(aShapesSeq);
588 if (!GetSolver()->ComputeFunction(aFunction)) {
589 SetErrorCode("Shape driver failed");
593 catch (Standard_Failure) {
594 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
595 SetErrorCode(aFail->GetMessageString());
599 //Make a Python command
600 GEOM::TPythonDump (aFunction) << aShape
601 << " = geompy.MakeFaceFromSurface(" << theFace << ", " << theWire << ")";
608 //=============================================================================
610 * MakeFaceWithConstraints
612 //=============================================================================
613 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFaceWithConstraints
614 (std::list<Handle(GEOM_Object)> theConstraints)
619 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_FILLING);
622 Handle(GEOM_Function) aFunction =
623 aShape->AddFunction(GEOMImpl_FillingDriver::GetID(), FILLING_ON_CONSTRAINTS);
624 if (aFunction.IsNull()) return NULL;
626 //Check if the function is set correctly
627 if (aFunction->GetDriverGUID() != GEOMImpl_FillingDriver::GetID()) return NULL;
629 GEOMImpl_IFilling aCI (aFunction);
630 Handle(TColStd_HSequenceOfTransient) aConstraints = new TColStd_HSequenceOfTransient;
633 std::list<Handle(GEOM_Object)>::iterator it = theConstraints.begin();
634 while (it != theConstraints.end()) {
635 Handle(GEOM_Object) anObject = (*it);
636 if ( anObject.IsNull() || anObject->GetValue().ShapeType() != TopAbs_EDGE ) {
637 SetErrorCode("NULL argument edge for the face construction");
640 Handle(GEOM_Function) aRefSh = anObject->GetLastFunction();
641 aConstraints->Append(aRefSh);
643 if ( it != theConstraints.end() ) {
644 Handle(GEOM_Object) aFace = (*it);
645 if ( aFace.IsNull() ) {
646 // null constraint face - it is a valid case
650 if ( aFace->GetValue().ShapeType() != TopAbs_FACE )
651 // constraint face can be omitted - it is a valid case
653 if ( IsSubShapeBelongsTo( anObject, 0, aFace, 0 ) ) {
655 aRefSh = aFace->GetLastFunction();
656 aConstraints->Append(aRefSh);
661 SetErrorCode("Face is NULL or not connected to the Edge");
666 aCI.SetShapes( aConstraints );
669 Standard_Boolean isWarning = Standard_False;
672 if (!GetSolver()->ComputeFunction(aFunction)) {
673 SetErrorCode("Shape driver failed");
677 catch (Standard_Failure) {
678 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
679 SetErrorCode(aFail->GetMessageString());
680 // to provide warning
681 if (!aFunction->GetValue().IsNull()) {
682 isWarning = Standard_True;
688 //Make a Python command
689 GEOM::TPythonDump pd (aFunction);
690 pd << aShape << " = geompy.MakeFaceWithConstraints([";
693 it = theConstraints.begin();
694 if (it != theConstraints.end() ) {
696 while (it != theConstraints.end()) {
697 Handle(GEOM_Object) anObject = (*it++);
698 if( !anObject.IsNull() )
699 pd << ", " << anObject;
704 // to provide warning
705 if (!isWarning) SetErrorCode(OK);
709 //=============================================================================
713 //=============================================================================
714 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeShell
715 (std::list<Handle(GEOM_Object)> theShapes)
717 return MakeShape(theShapes, GEOM_SHELL, SHELL_FACES, "MakeShell");
720 //=============================================================================
724 //=============================================================================
725 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeSolidShells
726 (std::list<Handle(GEOM_Object)> theShapes)
728 return MakeShape(theShapes, GEOM_SOLID, SOLID_SHELLS, "MakeSolid");
731 //=============================================================================
735 //=============================================================================
736 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeCompound
737 (std::list<Handle(GEOM_Object)> theShapes)
739 return MakeShape(theShapes, GEOM_COMPOUND, COMPOUND_SHAPES, "MakeCompound");
742 //=============================================================================
746 //=============================================================================
747 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeShape
748 (std::list<Handle(GEOM_Object)> theShapes,
749 const Standard_Integer theObjectType,
750 const Standard_Integer theFunctionType,
751 const TCollection_AsciiString& theMethodName)
756 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), theObjectType);
759 Handle(GEOM_Function) aFunction =
760 aShape->AddFunction(GEOMImpl_ShapeDriver::GetID(), theFunctionType);
761 if (aFunction.IsNull()) return NULL;
763 //Check if the function is set correctly
764 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
766 GEOMImpl_IShapes aCI (aFunction);
768 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
771 std::list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
772 for (; it != theShapes.end(); it++) {
773 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
774 if (aRefSh.IsNull()) {
775 SetErrorCode("NULL argument shape for the shape construction");
778 aShapesSeq->Append(aRefSh);
780 aCI.SetShapes(aShapesSeq);
785 if (!GetSolver()->ComputeFunction(aFunction)) {
786 SetErrorCode("Shape driver failed");
790 catch (Standard_Failure) {
791 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
792 SetErrorCode(aFail->GetMessageString());
796 //Make a Python command
797 GEOM::TPythonDump pd (aFunction);
798 pd << aShape << " = geompy." << theMethodName.ToCString() << "([";
801 it = theShapes.begin();
802 if (it != theShapes.end()) {
804 while (it != theShapes.end()) {
805 pd << ", " << (*it++);
814 //=============================================================================
816 * MakeSolidFromConnectedFaces
818 //=============================================================================
819 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeSolidFromConnectedFaces
820 (std::list<Handle(GEOM_Object)> theFacesOrShells,
821 const Standard_Boolean isIntersect)
826 Handle(GEOM_Object) aSolid = GetEngine()->AddObject(GetDocID(), GEOM_SOLID);
829 Handle(GEOM_Function) aFunction =
830 aSolid->AddFunction(GEOMImpl_ShapeDriver::GetID(), SOLID_FACES);
831 if (aFunction.IsNull()) return NULL;
833 //Check if the function is set correctly
834 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
836 GEOMImpl_IShapes aCI (aFunction);
838 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
841 std::list<Handle(GEOM_Object)>::iterator it = theFacesOrShells.begin();
842 for (; it != theFacesOrShells.end(); it++) {
843 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
844 if (aRefSh.IsNull()) {
845 SetErrorCode("NULL argument shape for the shape construction");
848 aShapesSeq->Append(aRefSh);
850 aCI.SetShapes(aShapesSeq);
851 aCI.SetIsIntersect(isIntersect);
856 if (!GetSolver()->ComputeFunction(aFunction)) {
857 SetErrorCode("Shape driver failed");
861 catch (Standard_Failure) {
862 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
863 SetErrorCode(aFail->GetMessageString());
867 //Make a Python command
868 GEOM::TPythonDump pd (aFunction);
869 pd << aSolid << " = geompy.MakeSolidFromConnectedFaces([";
872 it = theFacesOrShells.begin();
873 if (it != theFacesOrShells.end()) {
875 while (it != theFacesOrShells.end()) {
876 pd << ", " << (*it++);
879 pd << "]," << (isIntersect ? "True" : "False") << ")";
885 //=============================================================================
889 //=============================================================================
891 GEOMImpl_IShapesOperations::MakeGlueFaces (std::list< Handle(GEOM_Object) >& theShapes,
892 const Standard_Real theTolerance,
893 const Standard_Boolean doKeepNonSolids)
897 Handle(TColStd_HSequenceOfTransient) objects = GEOM_Object::GetLastFunctions( theShapes );
898 if ( objects.IsNull() || objects->IsEmpty() ) {
899 SetErrorCode("NULL argument shape");
903 //Add a new Glued object
904 Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
906 //Add a new Glue function
907 Handle(GEOM_Function) aFunction;
908 aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_FACES);
909 if (aFunction.IsNull()) return NULL;
911 //Check if the function is set correctly
912 if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
914 GEOMImpl_IGlue aCI (aFunction);
916 aCI.SetBase( objects );
917 aCI.SetTolerance(theTolerance);
918 aCI.SetKeepNonSolids(doKeepNonSolids);
920 //Compute the sub-shape value
921 Standard_Boolean isWarning = Standard_False;
924 if (!GetSolver()->ComputeFunction(aFunction)) {
925 SetErrorCode("Shape driver failed to glue faces");
929 catch (Standard_Failure) {
930 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
931 SetErrorCode(aFail->GetMessageString());
932 // to provide warning
933 if (!aFunction->GetValue().IsNull()) {
934 isWarning = Standard_True;
940 //Make a Python command
941 GEOM::TPythonDump(aFunction) << aGlued << " = geompy.MakeGlueFaces("
942 << theShapes << ", " << theTolerance << ")";
944 // to provide warning
945 if (!isWarning) SetErrorCode(OK);
949 //=============================================================================
953 //=============================================================================
955 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetGlueFaces
956 (Handle(GEOM_Object) theShape,
957 const Standard_Real theTolerance)
961 if (theShape.IsNull()) return NULL;
962 TopoDS_Shape aShape = theShape->GetValue();
963 if (aShape.IsNull()) return NULL;
965 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
967 Standard_Integer iErr;
969 GEOMAlgo_Gluer1 aGluer;
970 GEOMAlgo_ListIteratorOfListOfCoupleOfShapes aItCS;
971 GEOMAlgo_CoupleOfShapes aCS;
972 GEOMAlgo_ListOfCoupleOfShapes aLCS;
974 //aGluer = new GEOMAlgo_Gluer1;
975 aGluer.SetShape(aShape);
976 aGluer.SetTolerance(theTolerance);
978 iErr = aGluer.ErrorStatus();
979 if (iErr) return NULL;
981 TopTools_ListOfShape listShape;
982 const GEOMAlgo_ListOfCoupleOfShapes& aLCSG = aGluer.GluedFaces();
984 aItCS.Initialize(aLCSG);
985 for (; aItCS.More(); aItCS.Next()) {
986 const GEOMAlgo_CoupleOfShapes& aCSG = aItCS.Value();
987 listShape.Append(aCSG.Shape1());
990 TopTools_ListIteratorOfListOfShape itSub (listShape);
991 TCollection_AsciiString anAsciiList, anEntry;
992 TopTools_IndexedMapOfShape anIndices;
993 TopExp::MapShapes(aShape, anIndices);
994 Handle(TColStd_HArray1OfInteger) anArray;
995 Handle(GEOM_Object) anObj;
996 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
997 TopoDS_Shape aValue = itSub.Value();
998 anArray = new TColStd_HArray1OfInteger(1,1);
999 anArray->SetValue(1, anIndices.FindIndex(aValue));
1000 anObj = GetEngine()->AddSubShape(theShape, anArray);
1001 if (!anObj.IsNull()) {
1002 aSeq->Append(anObj);
1004 // for python command
1005 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
1006 anAsciiList += anEntry;
1011 //Make a Python command
1012 if( anAsciiList.Length() > 0 ) {
1013 anAsciiList.Trunc(anAsciiList.Length() - 1);
1014 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
1015 GEOM::TPythonDump pd (aFunction, true);
1016 pd << "[" << anAsciiList.ToCString();
1017 pd << "] = geompy.GetGlueFaces(" << theShape << ", " << theTolerance << ")";
1026 //=============================================================================
1028 * MakeGlueFacesByList
1030 //=============================================================================
1032 GEOMImpl_IShapesOperations::MakeGlueFacesByList(std::list< Handle(GEOM_Object) >& theShapes,
1033 const Standard_Real theTolerance,
1034 std::list<Handle(GEOM_Object)> & theFaces,
1035 const Standard_Boolean doKeepNonSolids,
1036 const Standard_Boolean doGlueAllEdges)
1040 Handle(TColStd_HSequenceOfTransient) objects = GEOM_Object::GetLastFunctions( theShapes );
1041 if ( objects.IsNull() || objects->IsEmpty() ) {
1042 SetErrorCode("NULL argument shape");
1045 Handle(TColStd_HSequenceOfTransient) aFaces = GEOM_Object::GetLastFunctions( theFaces );
1046 if ( aFaces.IsNull() ) {
1047 SetErrorCode("NULL argument shape for the shape construction");
1051 //Add a new Glued object
1052 Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
1054 //Add a new Glue function
1055 Handle(GEOM_Function) aFunction;
1056 aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_FACES_BY_LIST);
1057 if (aFunction.IsNull()) return NULL;
1059 //Check if the function is set correctly
1060 if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
1062 GEOMImpl_IGlue aCI (aFunction);
1064 aCI.SetBase( objects );
1065 aCI.SetTolerance(theTolerance);
1066 aCI.SetKeepNonSolids(doKeepNonSolids);
1067 aCI.SetGlueAllEdges(doGlueAllEdges);
1068 aCI.SetFaces(aFaces);
1070 //Compute the sub-shape value
1071 Standard_Boolean isWarning = Standard_False;
1074 if (!GetSolver()->ComputeFunction(aFunction)) {
1075 SetErrorCode("Shape driver failed to glue faces");
1079 catch (Standard_Failure) {
1080 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1081 SetErrorCode(aFail->GetMessageString());
1082 // to provide warning
1083 if (!aFunction->GetValue().IsNull()) {
1084 isWarning = Standard_True;
1090 //Make a Python command
1092 GEOM::TPythonDump pd(aFunction);
1093 pd << aGlued << " = geompy.MakeGlueFacesByList("
1094 << theShapes << ", " << theTolerance << ", " << theFaces << ", "
1095 << (bool)doKeepNonSolids << ", " << (bool)doGlueAllEdges << ")";
1097 // to provide warning
1098 if (!isWarning) SetErrorCode(OK);
1102 //=============================================================================
1106 //=============================================================================
1108 GEOMImpl_IShapesOperations::MakeGlueEdges (std::list< Handle(GEOM_Object) >& theShapes,
1109 const Standard_Real theTolerance)
1113 Handle(TColStd_HSequenceOfTransient) objects = GEOM_Object::GetLastFunctions( theShapes );
1114 if ( objects.IsNull() || objects->IsEmpty() ) {
1115 SetErrorCode("NULL argument shape");
1119 //Add a new Glued object
1120 Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
1122 //Add a new Glue function
1123 Handle(GEOM_Function) aFunction;
1124 aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_EDGES);
1125 if (aFunction.IsNull()) return NULL;
1127 //Check if the function is set correctly
1128 if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
1130 GEOMImpl_IGlue aCI (aFunction);
1132 aCI.SetBase( objects );
1133 aCI.SetTolerance(theTolerance);
1134 aCI.SetKeepNonSolids(true);
1136 //Compute the sub-shape value
1137 Standard_Boolean isWarning = Standard_False;
1140 if (!GetSolver()->ComputeFunction(aFunction)) {
1141 SetErrorCode("Shape driver failed to glue edges");
1145 catch (Standard_Failure) {
1146 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1147 SetErrorCode(aFail->GetMessageString());
1148 // to provide warning
1149 if (!aFunction->GetValue().IsNull()) {
1150 isWarning = Standard_True;
1156 //Make a Python command
1157 GEOM::TPythonDump(aFunction) << aGlued << " = geompy.MakeGlueEdges("
1158 << theShapes << ", " << theTolerance << ")";
1160 // to provide warning
1161 if (!isWarning) SetErrorCode(OK);
1165 //=============================================================================
1169 //=============================================================================
1170 Handle(TColStd_HSequenceOfTransient)
1171 GEOMImpl_IShapesOperations::GetGlueShapes (std::list< Handle(GEOM_Object) >& theShapes,
1172 const Standard_Real theTolerance,
1173 const TopAbs_ShapeEnum theType)
1177 TopoDS_Shape aShape;
1178 TopTools_SequenceOfShape shapes;
1179 std::list< Handle(GEOM_Object) >::iterator s = theShapes.begin();
1180 Handle(GEOM_Object) lastCreatedGO;
1181 for ( ; s != theShapes.end(); ++s )
1183 Handle(GEOM_Object) go = *s;
1184 if ( go.IsNull() ) return NULL;
1185 aShape = go->GetValue();
1186 if ( aShape.IsNull() ) return NULL;
1187 shapes.Append( aShape );
1188 lastCreatedGO = GEOM::GetCreatedLast( lastCreatedGO, go );
1190 if ( shapes.Length() > 1 )
1192 TopoDS_Compound compound;
1193 BRep_Builder builder;
1194 builder.MakeCompound( compound );
1195 for ( int i = 1; i <= shapes.Length(); ++i )
1196 builder.Add( compound, shapes( i ) );
1201 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1203 GEOMAlgo_GlueDetector aGluer;
1204 aGluer.SetArgument(aShape);
1205 aGluer.SetTolerance(theTolerance);
1207 Standard_Integer iErr = aGluer.ErrorStatus();
1208 if (iErr) return NULL;
1210 std::vector< TopTools_IndexedMapOfShape* > anIndices( shapes.Length(), NULL );
1211 Handle(TColStd_HArray1OfInteger) anArray;
1212 Handle(GEOM_Object) anObj;
1214 TopTools_ListOfShape listOnePerSet;
1216 const TopTools_DataMapOfShapeListOfShape& aImages = aGluer.Images();
1217 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape aItDMSLS (aImages);
1218 for (int index = 1; aItDMSLS.More(); aItDMSLS.Next(), ++index) {
1220 //const TopoDS_Shape& aSkey = aItDMSLS.Key();
1222 // list of shapes of the argument that can be glued
1223 const TopTools_ListOfShape& aLSD = aItDMSLS.Value();
1225 //listShape.Append(aLSD.First());
1226 TopoDS_Shape aValue = aLSD.First();
1228 if (aValue.ShapeType() == theType) {
1229 listOnePerSet.Append(aValue);
1233 // for stable order of returned entities
1234 GEOMUtils::SortShapes(listOnePerSet, Standard_False);
1236 TopTools_ListIteratorOfListOfShape aListIt (listOnePerSet);
1237 for (; aListIt.More(); aListIt.Next())
1239 TopoDS_Shape aValue = aListIt.Value();
1240 // find a shape to add aValue as a sub-shape
1242 s = theShapes.begin();
1243 for ( int i = 0; i < shapes.Length(); ++i, ++s )
1245 Handle(GEOM_Object) object = *s;
1246 if ( !anIndices[i] ) {
1247 anIndices[i] = new TopTools_IndexedMapOfShape;
1248 TopExp::MapShapes( object->GetValue(), *anIndices[i]);
1250 if (int index = anIndices[i]->FindIndex( aValue )) {
1251 anArray = new TColStd_HArray1OfInteger(1,1);
1252 anArray->SetValue(1, index);
1253 anObj = GetEngine()->AddSubShape( object, anArray);
1257 if (!anObj.IsNull())
1258 aSeq->Append(anObj);
1260 for ( size_t i = 0 ; i < anIndices.size(); ++i )
1261 delete anIndices[i];
1263 // Make a Python command
1264 if ( aSeq->Length() > 0)
1266 Handle(GEOM_Function) aFunction = lastCreatedGO->GetLastFunction();
1267 GEOM::TPythonDump pd (aFunction, /*append=*/true);
1269 << " = geompy." << (theType == TopAbs_FACE ? "GetGlueFaces" : "GetGlueEdges" )
1270 << "( " << theShapes << ", " << theTolerance << ")";
1278 //=============================================================================
1280 * MakeGlueEdgesByList
1282 //=============================================================================
1284 GEOMImpl_IShapesOperations::MakeGlueEdgesByList (std::list< Handle(GEOM_Object) >& theShapes,
1285 const Standard_Real theTolerance,
1286 std::list<Handle(GEOM_Object)>& theEdges)
1290 Handle(TColStd_HSequenceOfTransient) objects = GEOM_Object::GetLastFunctions( theShapes );
1291 if ( objects.IsNull() || objects->IsEmpty() ) {
1292 SetErrorCode("NULL argument shape");
1295 Handle(TColStd_HSequenceOfTransient) anEdges = GEOM_Object::GetLastFunctions( theEdges );
1296 if ( anEdges.IsNull() ) {
1297 SetErrorCode("NULL argument shape for the shape construction");
1300 //Add a new Glued object
1301 Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
1303 //Add a new Glue function
1304 Handle(GEOM_Function) aFunction;
1305 aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_EDGES_BY_LIST);
1306 if (aFunction.IsNull()) return NULL;
1308 //Check if the function is set correctly
1309 if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
1311 GEOMImpl_IGlue aCI (aFunction);
1313 aCI.SetBase( objects );
1314 aCI.SetTolerance(theTolerance);
1315 aCI.SetKeepNonSolids(true);
1316 aCI.SetFaces(anEdges);
1318 //Compute the sub-shape value
1319 Standard_Boolean isWarning = Standard_False;
1322 if (!GetSolver()->ComputeFunction(aFunction)) {
1323 SetErrorCode("Shape driver failed to glue edges");
1327 catch (Standard_Failure) {
1328 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1329 SetErrorCode(aFail->GetMessageString());
1330 // to provide warning
1331 if (!aFunction->GetValue().IsNull()) {
1332 isWarning = Standard_True;
1338 //Make a Python command
1340 GEOM::TPythonDump pd (aFunction);
1341 pd << aGlued << " = geompy.MakeGlueEdgesByList("
1342 << theShapes << ", " << theTolerance << ", " << theEdges << " )";
1344 // to provide warning
1345 if (!isWarning) SetErrorCode(OK);
1349 //=============================================================================
1351 * GetExistingSubObjects
1353 //=============================================================================
1354 Handle(TColStd_HSequenceOfTransient)
1355 GEOMImpl_IShapesOperations::GetExistingSubObjects(Handle(GEOM_Object) theShape,
1356 const Standard_Boolean theGroupsOnly)
1358 // note: this method does not return fields
1360 Standard_Integer types = theGroupsOnly ? Groups : Groups|SubShapes;
1361 Handle(TColStd_HSequenceOfTransient) results = GetExistingSubObjects(theShape, types);
1363 if (results->Length() > 0) {
1364 //Make a Python command
1365 TCollection_AsciiString anAsciiList;
1366 for (int i = 1; i <= results->Length(); i++)
1368 Handle(GEOM_BaseObject) obj = Handle(GEOM_BaseObject)::DownCast( results->Value(i));
1369 obj->GetEntryString();
1370 if ( i < results->Length() )
1374 GEOM::TPythonDump pd (theShape->GetLastFunction(), /*append=*/true);
1375 pd << "[" << anAsciiList.ToCString();
1376 pd << "] = geompy.GetExistingSubObjects(";
1377 pd << theShape << ", " << (bool)theGroupsOnly << ")";
1383 Handle(TColStd_HSequenceOfTransient)
1384 GEOMImpl_IShapesOperations::GetExistingSubObjects(Handle(GEOM_Object) theShape,
1385 const Standard_Integer theTypes)
1389 if (theShape.IsNull()) return NULL;
1391 Handle(GEOM_Function) aMainShape = theShape->GetLastFunction();
1392 if (aMainShape.IsNull()) return NULL;
1394 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1395 SetErrorCode(NOT_FOUND_ANY);
1397 if (!aMainShape->HasSubShapeReferences()) return aSeq;
1398 const TDataStd_ListOfExtendedString& aListEntries = aMainShape->GetSubShapeReferences();
1399 if (aListEntries.IsEmpty()) return aSeq;
1403 TDataStd_ListIteratorOfListOfExtendedString anIt (aListEntries);
1404 for (; anIt.More(); anIt.Next()) {
1405 TCollection_ExtendedString anEntry = anIt.Value();
1406 Standard_Integer aStrLen = anEntry.LengthOfCString();
1407 char* anEntryStr = new char[aStrLen+1];
1408 anEntry.ToUTF8CString(anEntryStr);
1409 Handle(GEOM_BaseObject) anObj = GetEngine()->GetObject(GetDocID(), anEntryStr, false);
1410 if (!anObj.IsNull() ) {
1411 bool isGroup = anObj->IsKind(STANDARD_TYPE(GEOM_Object)) && anObj->GetType() == GEOM_GROUP;
1412 bool isSubShape = anObj->IsKind(STANDARD_TYPE(GEOM_Object)) && anObj->GetType() != GEOM_GROUP;
1413 bool isField = anObj->IsKind(STANDARD_TYPE(GEOM_Field));
1414 if (theTypes & Groups && isGroup ||
1415 theTypes & SubShapes && isSubShape ||
1416 theTypes & Fields && isField) {
1417 aSeq->Append(anObj);
1420 delete [] anEntryStr;
1423 if (aSeq->Length() == 0) {
1424 SetErrorCode(NOT_FOUND_ANY);
1433 //=============================================================================
1437 //=============================================================================
1438 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::MakeExplode
1439 (Handle(GEOM_Object) theShape,
1440 const Standard_Integer theShapeType,
1441 const Standard_Boolean isSorted,
1442 const ExplodeType theExplodeType)
1446 if (theShape.IsNull()) return NULL;
1447 TopoDS_Shape aShape = theShape->GetValue();
1448 if (aShape.IsNull()) return NULL;
1450 Handle(GEOM_Function) aMainShape = theShape->GetLastFunction();
1452 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1453 Handle(GEOM_Object) anObj;
1454 TopTools_MapOfShape mapShape;
1455 TopTools_ListOfShape listShape;
1457 if (aShape.ShapeType() == TopAbs_COMPOUND &&
1458 (theShapeType == TopAbs_SHAPE || theShapeType == TopAbs_FLAT || theShapeType == TopAbs_COMPOUND))
1460 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
1461 for (; It.More(); It.Next()) {
1462 TopoDS_Shape SS = It.Value();
1463 if (mapShape.Add(SS)) {
1464 if (theShapeType == TopAbs_FLAT) {
1465 AddFlatSubShapes(SS, listShape, mapShape);
1467 else if (theShapeType == TopAbs_SHAPE || theShapeType == SS.ShapeType()) {
1468 listShape.Append(SS);
1470 // VSR: for EXPLODE_NEW_INCLUDE_MAIN and EXPLODE_OLD_INCLUDE_MAIN:
1471 // it seems it is necessary to add top-level shape if theShapeType == TopAbs_COMPOUND
1475 else if (theExplodeType != EXPLODE_NEW_EXCLUDE_MAIN || aShape.ShapeType() != theShapeType) // issue 0021079
1477 TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
1478 for (; exp.More(); exp.Next())
1479 if (mapShape.Add(exp.Current()))
1480 listShape.Append(exp.Current());
1483 if (listShape.IsEmpty()){
1484 //SetErrorCode("The given shape has no sub-shapes of the requested type");
1485 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
1490 bool isOldSorting = false;
1491 if (theExplodeType == EXPLODE_OLD_INCLUDE_MAIN)
1492 isOldSorting = true;
1493 GEOMUtils::SortShapes(listShape, isOldSorting);
1496 TopTools_IndexedMapOfShape anIndices;
1497 TopExp::MapShapes(aShape, anIndices);
1498 Handle(TColStd_HArray1OfInteger) anArray;
1500 TopTools_ListIteratorOfListOfShape itSub (listShape);
1501 TCollection_AsciiString anAsciiList, anEntry;
1502 for (int index = 1; itSub.More(); itSub.Next(), ++index)
1504 TopoDS_Shape aValue = itSub.Value();
1505 anArray = new TColStd_HArray1OfInteger(1,1);
1506 anArray->SetValue(1, anIndices.FindIndex(aValue));
1508 //anObj = GetEngine()->AddSubShape(theShape, anArray);
1510 anObj = GetEngine()->AddObject(GetDocID(), GEOM_SUBSHAPE);
1511 Handle(GEOM_Function) aFunction = anObj->AddFunction(GEOM_Object::GetSubShapeID(), 1);
1512 if (aFunction.IsNull()) return aSeq;
1514 GEOM_ISubShape aSSI (aFunction);
1515 aSSI.SetMainShape(aMainShape);
1516 aSSI.SetIndices(anArray);
1518 // Set function value directly, as we know it.
1519 // Usage of Solver here would lead to significant loss of time,
1520 // because GEOM_SubShapeDriver will build TopTools_IndexedMapOfShape
1521 // on the main shape for each being calculated sub-shape separately.
1522 aFunction->SetValue(aValue);
1524 // Put this subshape in the list of sub-shapes of theMainShape
1525 aMainShape->AddSubShapeReference(aFunction);
1527 if (!anObj.IsNull()) {
1528 aSeq->Append(anObj);
1530 // for python command
1531 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
1532 anAsciiList += anEntry;
1537 //Make a Python command
1538 anAsciiList.Trunc(anAsciiList.Length() - 1);
1540 GEOM::TPythonDump pd (aMainShape, /*append=*/true);
1541 pd << "[" << anAsciiList.ToCString() << "] = geompy.";
1542 switch (theExplodeType) {
1543 case EXPLODE_NEW_EXCLUDE_MAIN:
1544 pd << "ExtractShapes(" << theShape << ", "
1545 << TopAbs_ShapeEnum(theShapeType) << ", " << (isSorted ? "True" : "False") << ")";
1547 case EXPLODE_NEW_INCLUDE_MAIN:
1548 pd << "SubShapeAll" << (isSorted ? "SortedCentres(" : "(")
1549 << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
1551 case EXPLODE_OLD_INCLUDE_MAIN:
1552 pd << "SubShapeAll" << (isSorted ? "Sorted(" : "(")
1553 << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
1562 //=============================================================================
1566 //=============================================================================
1567 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::SubShapeAllIDs
1568 (Handle(GEOM_Object) theShape,
1569 const Standard_Integer theShapeType,
1570 const Standard_Boolean isSorted,
1571 const ExplodeType theExplodeType)
1575 if (theShape.IsNull()) return NULL;
1576 TopoDS_Shape aShape = theShape->GetValue();
1577 if (aShape.IsNull()) return NULL;
1579 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
1580 TopTools_MapOfShape mapShape;
1581 TopTools_ListOfShape listShape;
1583 if (aShape.ShapeType() == TopAbs_COMPOUND &&
1584 (theShapeType == TopAbs_SHAPE || theShapeType == TopAbs_FLAT || theShapeType == TopAbs_COMPOUND))
1586 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
1587 for (; It.More(); It.Next()) {
1588 TopoDS_Shape SS = It.Value();
1589 if (mapShape.Add(SS)) {
1590 if (theShapeType == TopAbs_FLAT) {
1591 AddFlatSubShapes(SS, listShape, mapShape);
1593 else if (theShapeType == TopAbs_SHAPE || theShapeType == SS.ShapeType()) {
1594 listShape.Append(SS);
1599 else if (theExplodeType != EXPLODE_NEW_EXCLUDE_MAIN || aShape.ShapeType() != theShapeType) // issue 0021079
1601 TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
1602 for (; exp.More(); exp.Next())
1603 if (mapShape.Add(exp.Current()))
1604 listShape.Append(exp.Current());
1607 if (listShape.IsEmpty()) {
1608 //SetErrorCode("The given shape has no sub-shapes of the requested type");
1609 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
1614 bool isOldSorting = false;
1615 if (theExplodeType == EXPLODE_OLD_INCLUDE_MAIN)
1616 isOldSorting = true;
1617 GEOMUtils::SortShapes(listShape, isOldSorting);
1620 TopTools_IndexedMapOfShape anIndices;
1621 TopExp::MapShapes(aShape, anIndices);
1622 Handle(TColStd_HArray1OfInteger) anArray;
1624 TopTools_ListIteratorOfListOfShape itSub (listShape);
1625 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
1626 TopoDS_Shape aValue = itSub.Value();
1627 aSeq->Append(anIndices.FindIndex(aValue));
1630 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
1632 //Make a Python command
1633 GEOM::TPythonDump pd (aFunction, /*append=*/true);
1634 pd << "listSubShapeIDs = geompy.SubShapeAll";
1635 switch (theExplodeType) {
1636 case EXPLODE_NEW_EXCLUDE_MAIN:
1638 case EXPLODE_NEW_INCLUDE_MAIN:
1639 pd << (isSorted ? "SortedCentresIDs(" : "IDs(")
1640 << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
1642 case EXPLODE_OLD_INCLUDE_MAIN:
1643 pd << (isSorted ? "SortedIDs(" : "IDs(")
1644 << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
1653 //=============================================================================
1657 //=============================================================================
1658 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetSubShape
1659 (Handle(GEOM_Object) theMainShape,
1660 const Standard_Integer theID)
1664 if (theMainShape.IsNull()) return NULL;
1666 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
1667 anArray->SetValue(1, theID);
1668 Handle(GEOM_Object) anObj = GetEngine()->AddSubShape(theMainShape, anArray,true);
1669 if (anObj.IsNull()) {
1670 SetErrorCode("Can not get a sub-shape with the given ID");
1674 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1676 //Make a Python command
1677 GEOM::TPythonDump(aFunction) << anObj << " = geompy.GetSubShape("
1678 << theMainShape << ", [" << theID << "])";
1684 //=============================================================================
1688 //=============================================================================
1689 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::MakeSubShapes
1690 (Handle(GEOM_Object) theMainShape,
1691 Handle(TColStd_HArray1OfInteger) theIndices)
1695 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1697 if (!theIndices->Length()) {
1698 SetErrorCode(NOT_FOUND_ANY);
1702 if (theMainShape.IsNull()) return NULL;
1703 TopoDS_Shape aShape = theMainShape->GetValue();
1704 if (aShape.IsNull()) return NULL;
1706 Handle(GEOM_Function) aMainShape = theMainShape->GetLastFunction();
1708 TopTools_IndexedMapOfShape anIndices;
1709 TopExp::MapShapes(aShape, anIndices);
1711 Handle(TColStd_HArray1OfInteger) anArray;
1712 Handle(GEOM_Object) anObj;
1714 TCollection_AsciiString anAsciiList, anEntry;
1715 Standard_Integer i, low = theIndices->Lower(), up = theIndices->Upper();
1716 for (i = low; i <= up; i++) {
1717 int id = theIndices->Value(i);
1718 if (1 <= id && id <= anIndices.Extent()) {
1719 TopoDS_Shape aValue = anIndices.FindKey(id);
1720 anArray = new TColStd_HArray1OfInteger(1,1);
1721 anArray->SetValue(1, id);
1723 anObj = GetEngine()->AddObject(GetDocID(), GEOM_SUBSHAPE);
1724 if (!anObj.IsNull()) {
1725 Handle(GEOM_Function) aFunction = anObj->AddFunction(GEOM_Object::GetSubShapeID(), 1);
1726 if (aFunction.IsNull()) return aSeq;
1728 GEOM_ISubShape aSSI (aFunction);
1729 aSSI.SetMainShape(aMainShape);
1730 aSSI.SetIndices(anArray);
1732 // Set function value directly, as we know it.
1733 // Usage of Solver here would lead to significant loss of time,
1734 // because GEOM_SubShapeDriver will build TopTools_IndexedMapOfShape
1735 // on the main shape for each being calculated sub-shape separately.
1736 aFunction->SetValue(aValue);
1738 // Put this sub-shape in the list of sub-shapes of theMainShape
1739 aMainShape->AddSubShapeReference(aFunction);
1741 aSeq->Append(anObj);
1743 // for python command
1744 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
1745 anAsciiList += anEntry;
1751 //Make a Python command
1752 anAsciiList.Trunc(anAsciiList.Length() - 1);
1754 GEOM::TPythonDump pd (aMainShape, /*append=*/true);
1755 pd << "[" << anAsciiList.ToCString() << "] = geompy.SubShapes("
1756 << theMainShape << ", [" ;
1757 for (i = low; i <= up - 1; i++) {
1758 pd << theIndices->Value(i) << ", ";
1760 pd << theIndices->Value(up) << "])";
1767 //=============================================================================
1771 //=============================================================================
1772 Standard_Integer GEOMImpl_IShapesOperations::GetSubShapeIndex (Handle(GEOM_Object) theMainShape,
1773 Handle(GEOM_Object) theSubShape)
1777 TopoDS_Shape aMainShape = theMainShape->GetValue();
1778 TopoDS_Shape aSubShape = theSubShape->GetValue();
1780 if (aMainShape.IsNull() || aSubShape.IsNull()) return -1;
1782 TopTools_IndexedMapOfShape anIndices;
1783 TopExp::MapShapes(aMainShape, anIndices);
1784 // if (anIndices.Contains(aSubShape)) {
1785 // SetErrorCode(OK);
1786 // return anIndices.FindIndex(aSubShape);
1788 int id = anIndices.FindIndex(aSubShape);
1799 //=============================================================================
1801 * GetSubShapeIndices
1803 //=============================================================================
1804 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetSubShapesIndices (Handle(GEOM_Object) theMainShape,
1805 std::list<Handle(GEOM_Object)> theSubShapes)
1807 MESSAGE("GEOMImpl_IShapesOperations::GetSubShapesIndices")
1810 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
1812 TopoDS_Shape aMainShape = theMainShape->GetValue();
1813 if (aMainShape.IsNull())
1815 MESSAGE("NULL main shape")
1819 TopTools_IndexedMapOfShape anIndices;
1820 TopExp::MapShapes(aMainShape, anIndices);
1822 std::list<Handle(GEOM_Object)>::iterator it;
1823 for (it=theSubShapes.begin(); it != theSubShapes.end(); ++it)
1825 TopoDS_Shape aSubShape = (*it)->GetValue();
1826 if (aSubShape.IsNull())
1828 MESSAGE("NULL subshape")
1831 int id = anIndices.FindIndex(aSubShape);
1840 //=============================================================================
1844 //=============================================================================
1845 Standard_Integer GEOMImpl_IShapesOperations::GetTopologyIndex (Handle(GEOM_Object) theMainShape,
1846 Handle(GEOM_Object) theSubShape)
1850 TopoDS_Shape aMainShape = theMainShape->GetValue();
1851 TopoDS_Shape aSubShape = theSubShape->GetValue();
1853 if (aMainShape.IsNull() || aSubShape.IsNull()) {
1854 SetErrorCode("Null argument shape given");
1859 if (aSubShape.ShapeType() == TopAbs_COMPOUND) {
1861 TopTools_ListOfShape CL;
1862 CL.Append(aMainShape);
1863 TopTools_ListIteratorOfListOfShape itC;
1864 for (itC.Initialize(CL); itC.More(); itC.Next()) {
1865 for (it.Initialize(itC.Value()); it.More(); it.Next()) {
1866 if (it.Value().ShapeType() == TopAbs_COMPOUND) {
1867 if (it.Value().IsSame(aSubShape))
1871 CL.Append(it.Value());
1876 TopExp_Explorer anExp (aMainShape, aSubShape.ShapeType());
1877 TopTools_MapOfShape M;
1878 for (; anExp.More(); anExp.Next()) {
1879 if (M.Add(anExp.Current())) {
1880 if (anExp.Current().IsSame(aSubShape))
1887 SetErrorCode("The sub-shape does not belong to the main shape");
1891 //=============================================================================
1893 * GetShapeTypeString
1895 //=============================================================================
1896 TCollection_AsciiString GEOMImpl_IShapesOperations::GetShapeTypeString (Handle(GEOM_Object) theShape)
1900 TCollection_AsciiString aTypeName ("Null Shape");
1902 TopoDS_Shape aShape = theShape->GetValue();
1903 if (aShape.IsNull())
1906 switch (aShape.ShapeType() )
1908 case TopAbs_COMPOUND:
1909 aTypeName = "Compound";
1911 case TopAbs_COMPSOLID:
1912 aTypeName = "Compound Solid";
1915 aTypeName = "Solid";
1918 aTypeName = "Shell";
1922 BRepAdaptor_Surface surf (TopoDS::Face(aShape));
1923 if (surf.GetType() == GeomAbs_Plane)
1924 aTypeName = "Plane";
1925 else if (surf.GetType() == GeomAbs_Cylinder)
1926 aTypeName = "Cylindrical Face";
1927 else if (surf.GetType() == GeomAbs_Sphere)
1928 aTypeName = "Spherical Face";
1929 else if (surf.GetType() == GeomAbs_Torus)
1930 aTypeName = "Toroidal Face";
1931 else if (surf.GetType() == GeomAbs_Cone)
1932 aTypeName = "Conical Face";
1934 aTypeName = "GEOM::FACE";
1942 BRepAdaptor_Curve curv (TopoDS::Edge(aShape));
1943 if (curv.GetType() == GeomAbs_Line) {
1944 if ((Abs(curv.FirstParameter()) >= 1E6) ||
1945 (Abs(curv.LastParameter()) >= 1E6))
1949 } else if (curv.GetType() == GeomAbs_Circle) {
1950 if (curv.IsClosed())
1951 aTypeName = "Circle";
1960 aTypeName = "Vertex";
1963 aTypeName = "Shape";
1966 aTypeName = "Shape of unknown type";
1972 //=============================================================================
1974 * IsSubShapeBelongsTo
1976 //=============================================================================
1977 Standard_Boolean GEOMImpl_IShapesOperations::IsSubShapeBelongsTo( Handle(GEOM_Object) theSubObject,
1978 const Standard_Integer theSubObjectIndex,
1979 Handle(GEOM_Object) theObject,
1980 const Standard_Integer theObjectIndex)
1982 if ( theObject.IsNull() || theSubObject.IsNull() )
1985 TopoDS_Shape shape = theObject->GetValue();
1986 TopoDS_Shape subShape = theSubObject->GetValue();
1988 if ( shape.IsNull() || subShape.IsNull() )
1991 TopTools_IndexedMapOfShape anIndices;
1992 if ( theObjectIndex > 0 ) {
1993 TopExp::MapShapes( shape, anIndices );
1994 shape = anIndices.FindKey(theObjectIndex);
1996 if ( theSubObjectIndex > 0 ) {
1997 TopExp::MapShapes( subShape, anIndices );
1998 subShape = anIndices.FindKey(theSubObjectIndex);
2001 TopExp::MapShapes( shape, anIndices );
2002 return anIndices.Contains( subShape );
2005 //=============================================================================
2009 //=============================================================================
2010 Standard_Integer GEOMImpl_IShapesOperations::NumberOfSubShapes
2011 (Handle(GEOM_Object) theShape,
2012 const Standard_Integer theShapeType)
2015 Standard_Integer nbShapes = 0;
2017 if (theShape.IsNull()) return -1;
2018 TopoDS_Shape aShape = theShape->GetValue();
2019 if (aShape.IsNull()) return -1;
2022 TopTools_MapOfShape mapShape;
2024 if (aShape.ShapeType() == TopAbs_COMPOUND &&
2025 (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
2026 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPSOLID ||
2027 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPOUND)) {
2028 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
2029 for (; It.More(); It.Next()) {
2030 if (mapShape.Add(It.Value())) {
2031 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
2032 TopAbs_ShapeEnum(theShapeType) == It.Value().ShapeType()) {
2038 TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
2039 for (; exp.More(); exp.Next())
2040 if (mapShape.Add(exp.Current()))
2046 if (theShapeType == TopAbs_FLAT) {
2047 TopTools_MapOfShape aMapOfShape;
2048 TopTools_ListOfShape aListOfShape;
2049 AddFlatSubShapes(aShape, aListOfShape, aMapOfShape);
2050 nbShapes = aListOfShape.Extent();
2054 int iType, nbTypes [TopAbs_SHAPE];
2055 for (iType = 0; iType < TopAbs_SHAPE; ++iType)
2057 nbTypes[aShape.ShapeType()]++;
2059 TopTools_MapOfShape aMapOfShape;
2060 aMapOfShape.Add(aShape);
2061 TopTools_ListOfShape aListOfShape;
2062 aListOfShape.Append(aShape);
2064 TopTools_ListIteratorOfListOfShape itL (aListOfShape);
2065 for (; itL.More(); itL.Next()) {
2066 TopoDS_Iterator it (itL.Value());
2067 for (; it.More(); it.Next()) {
2068 TopoDS_Shape s = it.Value();
2069 if (aMapOfShape.Add(s)) {
2070 aListOfShape.Append(s);
2071 nbTypes[s.ShapeType()]++;
2076 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE)
2077 nbShapes = aMapOfShape.Extent();
2079 nbShapes = nbTypes[theShapeType];
2082 catch (Standard_Failure) {
2083 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2084 SetErrorCode(aFail->GetMessageString());
2092 //=============================================================================
2096 //=============================================================================
2097 Handle(GEOM_Object) GEOMImpl_IShapesOperations::ReverseShape(Handle(GEOM_Object) theShape)
2101 if (theShape.IsNull()) return NULL;
2104 //Add a new reversed object
2105 Handle(GEOM_Object) aReversed = GetEngine()->AddObject(GetDocID(), theShape->GetType());
2107 //Add a new Revese function
2108 Handle(GEOM_Function) aFunction;
2109 aFunction = aReversed->AddFunction(GEOMImpl_ShapeDriver::GetID(), REVERSE_ORIENTATION);
2110 if (aFunction.IsNull()) return NULL;
2112 //Check if the function is set correctly
2113 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
2115 GEOMImpl_IShapes aSI (aFunction);
2117 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
2118 if (aRefShape.IsNull()) return NULL;
2120 aSI.SetBase(aRefShape);
2122 //Compute the sub-shape value
2125 if (!GetSolver()->ComputeFunction(aFunction)) {
2126 SetErrorCode("Shape driver failed to reverse shape");
2130 catch (Standard_Failure) {
2131 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2132 SetErrorCode(aFail->GetMessageString());
2136 //Make a Python command
2137 GEOM::TPythonDump(aFunction) << aReversed
2138 << " = geompy.ChangeOrientation(" << theShape << ")";
2143 Handle(GEOM_Object) aReversed;
2145 GEOM_Engine* anEngine = GetEngine();
2146 //GEOMImpl_Gen* aGen = dynamic_cast<GEOMImpl_Gen*>(anEngine);
2147 GEOMImpl_Gen* aGen = (GEOMImpl_Gen*)anEngine;
2150 GEOMImpl_IHealingOperations* anIHealingOperations =
2151 aGen->GetIHealingOperations(GetDocID());
2152 aReversed = anIHealingOperations->ChangeOrientationCopy(theShape);
2153 SetErrorCode(anIHealingOperations->GetErrorCode());
2159 //=============================================================================
2163 //=============================================================================
2164 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetFreeFacesIDs
2165 (Handle(GEOM_Object) theShape)
2169 if (theShape.IsNull()) return NULL;
2170 TopoDS_Shape aShape = theShape->GetValue();
2171 if (aShape.IsNull()) return NULL;
2173 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
2175 TopTools_IndexedDataMapOfShapeListOfShape mapFaceBlocks;
2176 GEOMImpl_Block6Explorer::MapShapesAndAncestors
2177 (aShape, TopAbs_FACE, TopAbs_SOLID, mapFaceBlocks);
2179 Standard_Integer ind = 1, nbFaces = mapFaceBlocks.Extent();
2182 SetErrorCode("The given shape has no faces");
2186 TopTools_IndexedMapOfShape anIndices;
2187 TopExp::MapShapes(aShape, anIndices);
2189 Standard_Integer id;
2190 for (; ind <= nbFaces; ind++) {
2191 if (mapFaceBlocks.FindFromIndex(ind).Extent() != 2) {
2192 id = anIndices.FindIndex(mapFaceBlocks.FindKey(ind));
2197 //The explode doesn't change object so no new function is required.
2198 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
2200 //Make a Python command
2201 GEOM::TPythonDump(aFunction, /*append=*/true)
2202 << "listFreeFacesIDs = geompy.GetFreeFacesIDs(" << theShape << ")";
2208 //=======================================================================
2209 //function : GetSharedShapes
2211 //=======================================================================
2212 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetSharedShapes
2213 (Handle(GEOM_Object) theShape1,
2214 Handle(GEOM_Object) theShape2,
2215 const Standard_Integer theShapeType)
2219 if (theShape1.IsNull() || theShape2.IsNull()) return NULL;
2221 TopoDS_Shape aShape1 = theShape1->GetValue();
2222 TopoDS_Shape aShape2 = theShape2->GetValue();
2224 if (aShape1.IsNull() || aShape2.IsNull()) return NULL;
2226 TopTools_IndexedMapOfShape anIndices;
2227 TopExp::MapShapes(aShape1, anIndices);
2228 Handle(TColStd_HArray1OfInteger) anArray;
2230 TopTools_IndexedMapOfShape mapShape1;
2231 TopExp::MapShapes(aShape1, TopAbs_ShapeEnum(theShapeType), mapShape1);
2233 Handle(GEOM_Object) anObj;
2234 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
2235 TCollection_AsciiString anAsciiList, anEntry;
2237 TopTools_MapOfShape mapShape2;
2238 TopExp_Explorer exp (aShape2, TopAbs_ShapeEnum(theShapeType));
2239 for (; exp.More(); exp.Next()) {
2240 TopoDS_Shape aSS = exp.Current();
2241 if (mapShape2.Add(aSS) && mapShape1.Contains(aSS)) {
2242 anArray = new TColStd_HArray1OfInteger(1,1);
2243 anArray->SetValue(1, anIndices.FindIndex(aSS));
2244 anObj = GetEngine()->AddSubShape(theShape1, anArray);
2245 aSeq->Append(anObj);
2247 // for python command
2248 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
2249 anAsciiList += anEntry;
2254 if (aSeq->IsEmpty()) {
2255 SetErrorCode("The given shapes have no shared sub-shapes of the requested type");
2259 //Make a Python command
2260 anAsciiList.Trunc(anAsciiList.Length() - 1);
2262 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2264 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
2265 << "] = geompy.GetSharedShapes(" << theShape1 << ", "
2266 << theShape2 << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
2272 //=======================================================================
2273 //function : GetSharedShapes
2275 //=======================================================================
2276 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetSharedShapes
2277 (std::list<Handle(GEOM_Object)> & theShapes,
2278 const Standard_Integer theShapeType)
2282 int aLen = theShapes.size();
2283 if (aLen < 1) return NULL;
2286 std::list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
2288 Handle(GEOM_Object) aMainObj = *it;
2289 Handle(GEOM_Function) aMainShape = aMainObj->GetLastFunction();
2291 TopTools_SequenceOfShape shapeSeq;
2292 for (; it != theShapes.end(); it++, ind++) {
2293 Handle(GEOM_Function) aRefShape = (*it)->GetLastFunction();
2294 if (aRefShape.IsNull()) {
2295 SetErrorCode("NULL shape for GetSharedShapes");
2298 TopoDS_Shape aShape2 = aRefShape->GetValue();
2299 if (aShape2.IsNull()) return NULL;
2300 shapeSeq.Append( aShape2 );
2303 TopoDS_Shape aShape1 = shapeSeq.First();
2305 if ( shapeSeq.Length() == 1 )
2308 for ( TopoDS_Iterator it( aShape1); it.More(); it.Next() )
2309 shapeSeq.Append( it.Value() );
2310 aShape1 = shapeSeq.First();
2313 TopTools_IndexedMapOfShape anIndices;
2314 TopExp::MapShapes(aMainShape->GetValue(), anIndices);
2316 TopTools_IndexedMapOfShape mapSelected;
2317 TopExp::MapShapes(aShape1, TopAbs_ShapeEnum(theShapeType), mapSelected);
2319 // Find shared shapes
2321 TopoDS_Compound aCurrSelection;
2323 for ( ind = 2; ind <= shapeSeq.Length(); ind++) {
2325 TopoDS_Compound aCompound;
2326 B.MakeCompound(aCompound);
2328 const TopoDS_Shape& aShape2 = shapeSeq.Value( ind );
2330 TopTools_MapOfShape mapShape2;
2331 TopExp_Explorer exp (aShape2, TopAbs_ShapeEnum(theShapeType));
2332 for (; exp.More(); exp.Next()) {
2333 const TopoDS_Shape& aSS = exp.Current();
2334 if (mapShape2.Add(aSS) && mapSelected.Contains(aSS)) {
2335 B.Add(aCompound, aSS);
2339 mapSelected.Clear();
2340 TopExp::MapShapes(aCompound, TopAbs_ShapeEnum(theShapeType), mapSelected);
2341 aCurrSelection = aCompound;
2344 // Create GEOM_Object for each found shared shape (collected in aCurrSelection)
2345 Handle(GEOM_Object) anObj, aLastCreated;
2346 Handle(TColStd_HArray1OfInteger) anArray;
2347 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
2348 TCollection_AsciiString anAsciiList, anEntry;
2350 TopoDS_Iterator itSel (aCurrSelection, Standard_True, Standard_True);
2351 for (; itSel.More(); itSel.Next()) {
2352 anArray = new TColStd_HArray1OfInteger(1,1);
2353 anArray->SetValue(1, anIndices.FindIndex(itSel.Value()));
2354 anObj = GetEngine()->AddSubShape(aMainObj, anArray);
2355 aSeq->Append(anObj);
2357 aLastCreated = GEOM::GetCreatedLast( aLastCreated, anObj );
2359 // for python command
2360 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
2361 anAsciiList += anEntry;
2365 if (aSeq->IsEmpty()) {
2366 SetErrorCode("The given shapes have no shared sub-shapes of the requested type");
2370 // Make a Python command
2371 anAsciiList.Trunc(anAsciiList.Length() - 1);
2373 // IPAL22904: TC6.5.0: order of python commands is wrong after dump study
2374 // Get the function of the latest published object
2375 Handle(GEOM_Function) aFunction = aLastCreated->GetLastFunction();
2376 if( aFunction.IsNull() ) // just in case
2377 aFunction = aMainShape;
2379 GEOM::TPythonDump pd (aFunction, /*append=*/true);
2380 pd << "[" << anAsciiList.ToCString()
2381 << "] = geompy.GetSharedShapesMulti([";
2383 it = theShapes.begin();
2385 while (it != theShapes.end()) {
2386 pd << ", " << (*it++);
2389 pd << "], " << TopAbs_ShapeEnum(theShapeType) << ")";
2395 //=============================================================================
2399 //=============================================================================
2400 static GEOM::TPythonDump& operator<< (GEOM::TPythonDump& theDump,
2401 const GEOMAlgo_State theState)
2404 case GEOMAlgo_ST_IN:
2405 theDump << "GEOM.ST_IN";
2407 case GEOMAlgo_ST_OUT:
2408 theDump << "GEOM.ST_OUT";
2410 case GEOMAlgo_ST_ON:
2411 theDump << "GEOM.ST_ON";
2413 case GEOMAlgo_ST_ONIN:
2414 theDump << "GEOM.ST_ONIN";
2416 case GEOMAlgo_ST_ONOUT:
2417 theDump << "GEOM.ST_ONOUT";
2420 theDump << "GEOM.ST_UNKNOWN";
2426 //=======================================================================
2427 //function : checkTypeShapesOn
2429 * \brief Checks if theShapeType parameter of GetShapesOnXXX() is OK
2430 * \param theShapeType - the shape type to check
2431 * \retval bool - result of the check
2433 //=======================================================================
2434 bool GEOMImpl_IShapesOperations::checkTypeShapesOn(const Standard_Integer theShapeType)
2436 if (theShapeType != TopAbs_VERTEX &&
2437 theShapeType != TopAbs_EDGE &&
2438 theShapeType != TopAbs_FACE &&
2439 theShapeType != TopAbs_SOLID) {
2440 SetErrorCode("Only solids, vertices, edges or faces can be found by this method");
2446 //=======================================================================
2447 //function : makePlane
2449 * \brief Creates Geom_Plane
2450 * \param theAx1 - shape object defining plane parameters
2451 * \retval Handle(Geom_Surface) - resulting surface
2453 //=======================================================================
2454 Handle(Geom_Surface) GEOMImpl_IShapesOperations::makePlane(const TopoDS_Shape& anAx1)
2456 if (anAx1.ShapeType() != TopAbs_EDGE) return NULL;
2457 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
2458 TopoDS_Vertex V1, V2;
2459 TopExp::Vertices(anEdge, V1, V2, Standard_True);
2460 if (V1.IsNull() || V2.IsNull()) {
2461 SetErrorCode("Bad edge given for the plane normal vector");
2464 gp_Pnt aLoc = BRep_Tool::Pnt(V1);
2465 gp_Vec aVec (aLoc, BRep_Tool::Pnt(V2));
2466 if (aVec.Magnitude() < Precision::Confusion()) {
2467 SetErrorCode("Vector with null magnitude given");
2470 return new Geom_Plane(aLoc, aVec);
2473 //=======================================================================
2474 //function : makeCylinder
2476 * \brief Creates Geom_CylindricalSurface
2477 * \param theAx1 - edge defining cylinder axis
2478 * \param theRadius - cylinder radius
2479 * \retval Handle(Geom_Surface) - resulting surface
2481 //=======================================================================
2482 Handle(Geom_Surface) GEOMImpl_IShapesOperations::makeCylinder(const TopoDS_Shape& anAxis,
2483 const Standard_Real theRadius)
2485 //Axis of the cylinder
2486 if (anAxis.ShapeType() != TopAbs_EDGE) {
2487 SetErrorCode("Not an edge given for the axis");
2490 TopoDS_Edge anEdge = TopoDS::Edge(anAxis);
2491 TopoDS_Vertex V1, V2;
2492 TopExp::Vertices(anEdge, V1, V2, Standard_True);
2493 if (V1.IsNull() || V2.IsNull()) {
2494 SetErrorCode("Bad edge given for the axis");
2497 gp_Pnt aLoc = BRep_Tool::Pnt(V1);
2498 gp_Vec aVec (aLoc, BRep_Tool::Pnt(V2));
2499 if (aVec.Magnitude() < Precision::Confusion()) {
2500 SetErrorCode("Vector with null magnitude given");
2504 gp_Ax3 anAx3 (aLoc, aVec);
2505 return new Geom_CylindricalSurface(anAx3, theRadius);
2508 //=======================================================================
2509 //function : getShapesOnBoxIDs
2511 * \brief Find IDs of sub-shapes complying with given status about surface
2512 * \param theBox - the box to check state of sub-shapes against
2513 * \param theShape - the shape to explore
2514 * \param theShapeType - type of sub-shape of theShape
2515 * \param theState - required state
2516 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
2518 //=======================================================================
2519 Handle(TColStd_HSequenceOfInteger)
2520 GEOMImpl_IShapesOperations::getShapesOnBoxIDs(const Handle(GEOM_Object)& theBox,
2521 const Handle(GEOM_Object)& theShape,
2522 const Standard_Integer theShapeType,
2523 GEOMAlgo_State theState)
2525 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
2527 TopoDS_Shape aBox = theBox->GetValue();
2528 TopoDS_Shape aShape = theShape->GetValue();
2530 // Check presence of triangulation, build if need
2531 if (!GEOMUtils::CheckTriangulation(aShape)) {
2532 SetErrorCode("Cannot build triangulation on the shape");
2537 GEOMAlgo_FinderShapeOn2 aFinder;
2538 Standard_Real aTol = 0.0001; // default value
2540 Handle(GEOMAlgo_ClsfBox) aClsfBox = new GEOMAlgo_ClsfBox;
2541 aClsfBox->SetBox(aBox);
2543 aFinder.SetShape(aShape);
2544 aFinder.SetTolerance(aTol);
2545 aFinder.SetClsf(aClsfBox);
2546 aFinder.SetShapeType( (TopAbs_ShapeEnum)theShapeType );
2547 aFinder.SetState(theState);
2550 // Interprete results
2551 Standard_Integer iErr = aFinder.ErrorStatus();
2552 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
2554 MESSAGE(" iErr : " << iErr);
2555 TCollection_AsciiString aMsg (" iErr : ");
2556 aMsg += TCollection_AsciiString(iErr);
2560 Standard_Integer iWrn = aFinder.WarningStatus();
2561 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
2563 MESSAGE(" *** iWrn : " << iWrn);
2566 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
2568 if (listSS.Extent() < 1) {
2569 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
2570 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
2574 // Fill sequence of object IDs
2575 aSeqOfIDs = new TColStd_HSequenceOfInteger;
2577 TopTools_IndexedMapOfShape anIndices;
2578 TopExp::MapShapes(aShape, anIndices);
2580 TopTools_ListIteratorOfListOfShape itSub (listSS);
2581 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
2582 int id = anIndices.FindIndex(itSub.Value());
2583 aSeqOfIDs->Append(id);
2589 //=======================================================================
2590 //function : GetShapesOnBoxIDs
2592 * \brief Find sub-shapes complying with given status about surface
2593 * \param theBox - the box to check state of sub-shapes against
2594 * \param theShape - the shape to explore
2595 * \param theShapeType - type of sub-shape of theShape
2596 * \param theState - required state
2597 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
2599 //=======================================================================
2600 Handle(TColStd_HSequenceOfInteger)
2601 GEOMImpl_IShapesOperations::GetShapesOnBoxIDs(const Handle(GEOM_Object)& theBox,
2602 const Handle(GEOM_Object)& theShape,
2603 const Standard_Integer theShapeType,
2604 GEOMAlgo_State theState)
2606 // Find sub-shapes ids
2607 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2608 getShapesOnBoxIDs (theBox, theShape, theShapeType, theState);
2609 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2612 // The GetShapesOnBox() doesn't change object so no new function is required.
2613 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theBox)->GetLastFunction();
2615 // Make a Python command
2616 GEOM::TPythonDump(aFunction, /*append=*/true)
2617 << "listShapesOnBoxIDs = geompy.GetShapesOnBoxIDs("
2620 << TopAbs_ShapeEnum(theShapeType) << ", "
2627 //=======================================================================
2628 //function : GetShapesOnBox
2630 * \brief Find sub-shapes complying with given status about surface
2631 * \param theBox - the box to check state of sub-shapes against
2632 * \param theShape - the shape to explore
2633 * \param theShapeType - type of sub-shape of theShape
2634 * \param theState - required state
2635 * \retval Handle(TColStd_HSequenceOfTransient) - found sub-shapes
2637 //=======================================================================
2638 Handle(TColStd_HSequenceOfTransient)
2639 GEOMImpl_IShapesOperations::GetShapesOnBox(const Handle(GEOM_Object)& theBox,
2640 const Handle(GEOM_Object)& theShape,
2641 const Standard_Integer theShapeType,
2642 GEOMAlgo_State theState)
2644 // Find sub-shapes ids
2645 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2646 getShapesOnBoxIDs (theBox, theShape, theShapeType, theState);
2647 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2650 // Find objects by indices
2651 TCollection_AsciiString anAsciiList;
2652 Handle(TColStd_HSequenceOfTransient) aSeq;
2653 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
2654 if ( aSeq.IsNull() || aSeq->IsEmpty() )
2657 // Make a Python command
2659 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2660 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2662 GEOM::TPythonDump(aFunction)
2663 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnBox("
2666 << TopAbs_ShapeEnum(theShapeType) << ", "
2673 //=======================================================================
2674 //function : getShapesOnShapeIDs
2676 * \brief Find IDs of sub-shapes complying with given status about surface
2677 * \param theCheckShape - the shape to check state of sub-shapes against
2678 * \param theShape - the shape to explore
2679 * \param theShapeType - type of sub-shape of theShape
2680 * \param theState - required state
2681 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
2683 //=======================================================================
2684 Handle(TColStd_HSequenceOfInteger)
2685 GEOMImpl_IShapesOperations::getShapesOnShapeIDs
2686 (const Handle(GEOM_Object)& theCheckShape,
2687 const Handle(GEOM_Object)& theShape,
2688 const Standard_Integer theShapeType,
2689 GEOMAlgo_State theState)
2691 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
2693 TopoDS_Shape aCheckShape = theCheckShape->GetValue();
2694 TopoDS_Shape aShape = theShape->GetValue();
2695 TopTools_ListOfShape res;
2697 // Check presence of triangulation, build if need
2698 if (!GEOMUtils::CheckTriangulation(aShape)) {
2699 SetErrorCode("Cannot build triangulation on the shape");
2704 GEOMAlgo_FinderShapeOn2 aFinder;
2705 Standard_Real aTol = 0.0001; // default value
2707 Handle(GEOMAlgo_ClsfSolid) aClsfSolid = new GEOMAlgo_ClsfSolid;
2708 aClsfSolid->SetShape(aCheckShape);
2710 aFinder.SetShape(aShape);
2711 aFinder.SetTolerance(aTol);
2712 aFinder.SetClsf(aClsfSolid);
2713 aFinder.SetShapeType( (TopAbs_ShapeEnum)theShapeType );
2714 aFinder.SetState(theState);
2717 // Interprete results
2718 Standard_Integer iErr = aFinder.ErrorStatus();
2719 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
2722 SetErrorCode("theCheckShape must be a solid");
2725 MESSAGE(" iErr : " << iErr);
2726 TCollection_AsciiString aMsg (" iErr : ");
2727 aMsg += TCollection_AsciiString(iErr);
2732 Standard_Integer iWrn = aFinder.WarningStatus();
2733 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
2735 MESSAGE(" *** iWrn : " << iWrn);
2738 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
2740 if (listSS.Extent() < 1) {
2741 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
2742 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
2745 // Fill sequence of object IDs
2746 aSeqOfIDs = new TColStd_HSequenceOfInteger;
2748 TopTools_IndexedMapOfShape anIndices;
2749 TopExp::MapShapes(aShape, anIndices);
2751 TopTools_ListIteratorOfListOfShape itSub (listSS);
2752 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
2753 int id = anIndices.FindIndex(itSub.Value());
2754 aSeqOfIDs->Append(id);
2760 //=======================================================================
2761 //function : GetShapesOnShapeIDs
2763 * \brief Find sub-shapes complying with given status about surface
2764 * \param theCheckShape - the shape to check state of sub-shapes against
2765 * \param theShape - the shape to explore
2766 * \param theShapeType - type of sub-shape of theShape
2767 * \param theState - required state
2768 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
2770 //=======================================================================
2771 Handle(TColStd_HSequenceOfInteger)
2772 GEOMImpl_IShapesOperations::GetShapesOnShapeIDs
2773 (const Handle(GEOM_Object)& theCheckShape,
2774 const Handle(GEOM_Object)& theShape,
2775 const Standard_Integer theShapeType,
2776 GEOMAlgo_State theState)
2778 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2779 getShapesOnShapeIDs (theCheckShape, theShape, theShapeType, theState);
2781 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2784 // The GetShapesOnShape() doesn't change object so no new function is required.
2785 Handle(GEOM_Function) aFunction =
2786 GEOM::GetCreatedLast(theShape,theCheckShape)->GetLastFunction();
2788 // Make a Python command
2789 GEOM::TPythonDump(aFunction, /*append=*/true)
2790 << "listShapesOnBoxIDs = geompy.GetShapesOnShapeIDs("
2791 << theCheckShape << ", "
2793 << TopAbs_ShapeEnum(theShapeType) << ", "
2800 //=======================================================================
2801 //function : GetShapesOnShape
2803 * \brief Find sub-shapes complying with given status about surface
2804 * \param theCheckShape - the shape to check state of sub-shapes against
2805 * \param theShape - the shape to explore
2806 * \param theShapeType - type of sub-shape of theShape
2807 * \param theState - required state
2808 * \retval Handle(TColStd_HSequenceOfTransient) - found sub-shapes
2810 //=======================================================================
2811 Handle(TColStd_HSequenceOfTransient)
2812 GEOMImpl_IShapesOperations::GetShapesOnShape
2813 (const Handle(GEOM_Object)& theCheckShape,
2814 const Handle(GEOM_Object)& theShape,
2815 const Standard_Integer theShapeType,
2816 GEOMAlgo_State theState)
2818 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2819 getShapesOnShapeIDs (theCheckShape, theShape, theShapeType, theState);
2820 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2823 // Find objects by indices
2824 TCollection_AsciiString anAsciiList;
2825 Handle(TColStd_HSequenceOfTransient) aSeq;
2826 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
2828 if ( aSeq.IsNull() || aSeq->IsEmpty() )
2831 // Make a Python command
2833 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2834 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2836 GEOM::TPythonDump(aFunction)
2837 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnShape("
2838 << theCheckShape << ", "
2840 << TopAbs_ShapeEnum(theShapeType) << ", "
2847 //=======================================================================
2848 //function : GetShapesOnShapeAsCompound
2849 //=======================================================================
2850 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetShapesOnShapeAsCompound
2851 (const Handle(GEOM_Object)& theCheckShape,
2852 const Handle(GEOM_Object)& theShape,
2853 const Standard_Integer theShapeType,
2854 GEOMAlgo_State theState)
2856 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2857 getShapesOnShapeIDs (theCheckShape, theShape, theShapeType, theState);
2859 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2862 // Find objects by indices
2863 TCollection_AsciiString anAsciiList;
2864 Handle(TColStd_HSequenceOfTransient) aSeq;
2865 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
2867 if ( aSeq.IsNull() || aSeq->IsEmpty() )
2870 TopoDS_Compound aCompound;
2872 B.MakeCompound(aCompound);
2874 for(; i<=aSeq->Length(); i++) {
2875 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(aSeq->Value(i));
2876 TopoDS_Shape aShape_i = anObj->GetValue();
2877 B.Add(aCompound,aShape_i);
2880 //Add a new result object
2881 Handle(GEOM_Object) aRes = GetEngine()->AddObject(GetDocID(), GEOM_SHAPES_ON_SHAPE);
2882 Handle(GEOM_Function) aFunction =
2883 aRes->AddFunction(GEOMImpl_ShapeDriver::GetID(), SHAPES_ON_SHAPE);
2884 aFunction->SetValue(aCompound);
2887 aSeq->Append( theCheckShape->GetLastFunction() );
2888 aSeq->Append( theShape->GetLastFunction() );
2890 GEOMImpl_IShapes aCI( aFunction );
2891 aCI.SetShapes( aSeq );
2892 aCI.SetSubShapeType( theShapeType );
2893 aCI.SetTolerance( theState );
2895 GEOM::TPythonDump(aFunction)
2896 << aRes << " = geompy.GetShapesOnShapeAsCompound("
2897 << theCheckShape << ", "
2899 << TopAbs_ShapeEnum(theShapeType) << ", "
2907 //=======================================================================
2908 //function : getShapesOnSurfaceIDs
2910 * \brief Find IDs of sub-shapes complying with given status about surface
2911 * \param theSurface - the surface to check state of sub-shapes against
2912 * \param theShape - the shape to explore
2913 * \param theShapeType - type of sub-shape of theShape
2914 * \param theState - required state
2915 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
2917 //=======================================================================
2918 Handle(TColStd_HSequenceOfInteger)
2919 GEOMImpl_IShapesOperations::getShapesOnSurfaceIDs(const Handle(Geom_Surface)& theSurface,
2920 const TopoDS_Shape& theShape,
2921 TopAbs_ShapeEnum theShapeType,
2922 GEOMAlgo_State theState)
2924 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
2926 // Check presence of triangulation, build if need
2927 if (!GEOMUtils::CheckTriangulation(theShape)) {
2928 SetErrorCode("Cannot build triangulation on the shape");
2932 // BEGIN: Mantis issue 0020961: Error on a pipe T-Shape
2933 // Compute tolerance
2934 Standard_Real T, VertMax = -RealLast();
2937 for (TopExp_Explorer ExV (theShape, TopAbs_VERTEX); ExV.More(); ExV.Next()) {
2938 TopoDS_Vertex Vertex = TopoDS::Vertex(ExV.Current());
2939 T = BRep_Tool::Tolerance(Vertex);
2944 catch (Standard_Failure) {
2945 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2946 SetErrorCode(aFail->GetMessageString());
2949 // END: Mantis issue 0020961
2952 GEOMAlgo_FinderShapeOn1 aFinder;
2953 //Standard_Real aTol = 0.0001; // default value
2954 Standard_Real aTol = VertMax; // Mantis issue 0020961
2956 aFinder.SetShape(theShape);
2957 aFinder.SetTolerance(aTol);
2958 aFinder.SetSurface(theSurface);
2959 aFinder.SetShapeType(theShapeType);
2960 aFinder.SetState(theState);
2962 // Sets the minimal number of inner points for the faces that do not have own
2963 // inner points at all (for e.g. rectangular planar faces have just 2 triangles).
2965 aFinder.SetNbPntsMin(3);
2966 // Sets the maximal number of inner points for edges or faces.
2967 // It is usefull for the cases when this number is very big (e.g =2000) to improve
2968 // the performance. If this value =0, all inner points will be taken into account.
2970 aFinder.SetNbPntsMax(100);
2974 // Interprete results
2975 Standard_Integer iErr = aFinder.ErrorStatus();
2976 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
2978 MESSAGE(" iErr : " << iErr);
2979 TCollection_AsciiString aMsg (" iErr : ");
2980 aMsg += TCollection_AsciiString(iErr);
2984 Standard_Integer iWrn = aFinder.WarningStatus();
2985 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
2987 MESSAGE(" *** iWrn : " << iWrn);
2990 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
2992 if (listSS.Extent() < 1) {
2993 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
2994 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
2998 // Fill sequence of object IDs
2999 aSeqOfIDs = new TColStd_HSequenceOfInteger;
3001 TopTools_IndexedMapOfShape anIndices;
3002 TopExp::MapShapes(theShape, anIndices);
3004 TopTools_ListIteratorOfListOfShape itSub (listSS);
3005 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
3006 int id = anIndices.FindIndex(itSub.Value());
3007 aSeqOfIDs->Append(id);
3013 //=======================================================================
3014 //function : getObjectsShapesOn
3016 * \brief Find shape objects and their entries by their ids
3017 * \param theShapeIDs - incoming shape ids
3018 * \param theShapeEntries - outgoing entries like "entry1, entry2, ..."
3019 * \retval Handle(TColStd_HSequenceOfTransient) - found shape objects
3021 //=======================================================================
3022 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::
3023 getObjectsShapesOn(const Handle(GEOM_Object)& theShape,
3024 const Handle(TColStd_HSequenceOfInteger)& theShapeIDs,
3025 TCollection_AsciiString & theShapeEntries)
3027 Handle(TColStd_HSequenceOfTransient) aSeq;
3029 if ( !theShapeIDs.IsNull() && theShapeIDs->Length() > 0 )
3031 aSeq = new TColStd_HSequenceOfTransient;
3032 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
3033 TCollection_AsciiString anEntry;
3034 for ( int i = 1; i <= theShapeIDs->Length(); ++i )
3036 anArray->SetValue(1, theShapeIDs->Value( i ));
3037 Handle(GEOM_Object) anObj = GetEngine()->AddSubShape(theShape, anArray);
3038 aSeq->Append( anObj );
3040 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
3041 if ( i != 1 ) theShapeEntries += ",";
3042 theShapeEntries += anEntry;
3048 //=======================================================================
3049 //function : getShapesOnSurface
3051 * \brief Find sub-shapes complying with given status about surface
3052 * \param theSurface - the surface to check state of sub-shapes against
3053 * \param theShape - the shape to explore
3054 * \param theShapeType - type of sub-shape of theShape
3055 * \param theState - required state
3056 * \param theShapeEntries - outgoing entries like "entry1, entry2, ..."
3057 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
3059 //=======================================================================
3060 Handle(TColStd_HSequenceOfTransient)
3061 GEOMImpl_IShapesOperations::getShapesOnSurface(const Handle(Geom_Surface)& theSurface,
3062 const Handle(GEOM_Object)& theShape,
3063 TopAbs_ShapeEnum theShapeType,
3064 GEOMAlgo_State theState,
3065 TCollection_AsciiString & theShapeEntries)
3067 // Find sub-shapes ids
3068 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
3069 getShapesOnSurfaceIDs (theSurface, theShape->GetValue(), theShapeType, theState);
3070 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
3073 return getObjectsShapesOn( theShape, aSeqOfIDs, theShapeEntries );
3076 //=============================================================================
3080 //=============================================================================
3081 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnPlane
3082 (const Handle(GEOM_Object)& theShape,
3083 const Standard_Integer theShapeType,
3084 const Handle(GEOM_Object)& theAx1,
3085 const GEOMAlgo_State theState)
3089 if (theShape.IsNull() || theAx1.IsNull()) return NULL;
3091 TopoDS_Shape aShape = theShape->GetValue();
3092 TopoDS_Shape anAx1 = theAx1->GetValue();
3094 if (aShape.IsNull() || anAx1.IsNull()) return NULL;
3096 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3097 if ( !checkTypeShapesOn( theShapeType ))
3101 Handle(Geom_Surface) aPlane = makePlane( anAx1 );
3102 if ( aPlane.IsNull() )
3106 TCollection_AsciiString anAsciiList;
3107 Handle(TColStd_HSequenceOfTransient) aSeq;
3108 aSeq = getShapesOnSurface( aPlane, theShape, aShapeType, theState, anAsciiList );
3109 if ( aSeq.IsNull() || aSeq->Length() == 0 )
3112 // Make a Python command
3114 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
3115 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
3117 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
3118 << "] = geompy.GetShapesOnPlane(" << theShape << ", "
3119 << aShapeType << ", " << theAx1 << ", " << theState << ")";
3125 //=============================================================================
3127 * GetShapesOnPlaneWithLocation
3129 //=============================================================================
3130 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnPlaneWithLocation
3131 (const Handle(GEOM_Object)& theShape,
3132 const Standard_Integer theShapeType,
3133 const Handle(GEOM_Object)& theAx1,
3134 const Handle(GEOM_Object)& thePnt,
3135 const GEOMAlgo_State theState)
3139 if (theShape.IsNull() || theAx1.IsNull() || thePnt.IsNull()) return NULL;
3141 TopoDS_Shape aShape = theShape->GetValue();
3142 TopoDS_Shape anAx1 = theAx1->GetValue();
3143 TopoDS_Shape anPnt = thePnt->GetValue();
3145 if (aShape.IsNull() || anAx1.IsNull() || anPnt.IsNull()) return NULL;
3147 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3148 if ( !checkTypeShapesOn( theShapeType ))
3152 if ( anAx1.ShapeType() != TopAbs_EDGE || anPnt.ShapeType() != TopAbs_VERTEX ) return NULL;
3153 TopoDS_Vertex V1, V2, V3;
3154 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
3155 TopExp::Vertices(anEdge, V1, V2, Standard_True);
3157 if (V1.IsNull() || V2.IsNull()) {
3158 SetErrorCode("Bad edge given for the plane normal vector");
3161 V3 = TopoDS::Vertex(anPnt);
3164 SetErrorCode("Bad vertex given for the plane location");
3167 gp_Pnt aLoc = BRep_Tool::Pnt(V3);
3168 gp_Vec aVec(BRep_Tool::Pnt(V1),BRep_Tool::Pnt(V2));
3170 if (aVec.Magnitude() < Precision::Confusion()) {
3171 SetErrorCode("Vector with null magnitude given");
3174 Handle(Geom_Surface) aPlane = new Geom_Plane(aLoc, aVec);
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.GetShapesOnPlaneWithLocation(" << theShape << ", "
3193 << aShapeType << ", " << theAx1 << ", "<< thePnt <<", " << theState << ")";
3199 //=============================================================================
3201 * GetShapesOnCylinder
3203 //=============================================================================
3204 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnCylinder
3205 (const Handle(GEOM_Object)& theShape,
3206 const Standard_Integer theShapeType,
3207 const Handle(GEOM_Object)& theAxis,
3208 const Standard_Real theRadius,
3209 const GEOMAlgo_State theState)
3213 if (theShape.IsNull() || theAxis.IsNull()) return NULL;
3215 TopoDS_Shape aShape = theShape->GetValue();
3216 TopoDS_Shape anAxis = theAxis->GetValue();
3218 if (aShape.IsNull() || anAxis.IsNull()) return NULL;
3220 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3221 if ( !checkTypeShapesOn( aShapeType ))
3224 // Create a cylinder surface
3225 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
3226 if ( aCylinder.IsNull() )
3230 TCollection_AsciiString anAsciiList;
3231 Handle(TColStd_HSequenceOfTransient) aSeq;
3232 aSeq = getShapesOnSurface( aCylinder, theShape, aShapeType, theState, anAsciiList );
3233 if ( aSeq.IsNull() || aSeq->Length() == 0 )
3236 // Make a Python command
3238 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
3239 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
3241 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
3242 << "] = geompy.GetShapesOnCylinder(" << theShape << ", " << aShapeType
3243 << ", " << theAxis << ", " << theRadius << ", " << theState << ")";
3249 //=============================================================================
3251 * GetShapesOnCylinderWithLocation
3253 //=============================================================================
3254 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnCylinderWithLocation
3255 (const Handle(GEOM_Object)& theShape,
3256 const Standard_Integer theShapeType,
3257 const Handle(GEOM_Object)& theAxis,
3258 const Handle(GEOM_Object)& thePnt,
3259 const Standard_Real theRadius,
3260 const GEOMAlgo_State theState)
3264 if (theShape.IsNull() || theAxis.IsNull() || thePnt.IsNull()) return NULL;
3266 TopoDS_Shape aShape = theShape->GetValue();
3267 TopoDS_Shape anAxis = theAxis->GetValue();
3268 TopoDS_Shape aPnt = thePnt->GetValue();
3270 if (aShape.IsNull() || anAxis.IsNull() || aPnt.IsNull()) return NULL;
3272 if (aPnt.ShapeType() != TopAbs_VERTEX )
3274 SetErrorCode("Bottom location point must be vertex");
3278 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3279 if ( !checkTypeShapesOn( aShapeType ))
3282 // Create a cylinder surface
3283 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
3284 if ( aCylinder.IsNull() )
3287 // translate the surface
3288 Handle(Geom_CylindricalSurface) aCylSurface =
3289 Handle(Geom_CylindricalSurface)::DownCast( aCylinder );
3290 if ( aCylSurface.IsNull() )
3292 SetErrorCode("Unexpected surface type instead of Geom_CylindricalSurface");
3295 gp_Pnt fromLoc = aCylSurface->Cylinder().Location();
3296 gp_Pnt toLoc = BRep_Tool::Pnt( TopoDS::Vertex( aPnt ));
3297 aCylinder->Translate( fromLoc, toLoc );
3300 TCollection_AsciiString anAsciiList;
3301 Handle(TColStd_HSequenceOfTransient) aSeq;
3302 aSeq = getShapesOnSurface( aCylinder, theShape, aShapeType, theState, anAsciiList );
3303 if ( aSeq.IsNull() || aSeq->Length() == 0 )
3306 // Make a Python command
3308 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
3309 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
3311 GEOM::TPythonDump(aFunction)
3312 << "[" << anAsciiList.ToCString()
3313 << "] = geompy.GetShapesOnCylinderWithLocation(" << theShape << ", " << aShapeType << ", "
3314 << theAxis << ", " << thePnt << ", " << theRadius << ", " << theState << ")";
3320 //=============================================================================
3324 //=============================================================================
3325 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnSphere
3326 (const Handle(GEOM_Object)& theShape,
3327 const Standard_Integer theShapeType,
3328 const Handle(GEOM_Object)& theCenter,
3329 const Standard_Real theRadius,
3330 const GEOMAlgo_State theState)
3334 if (theShape.IsNull() || theCenter.IsNull()) return NULL;
3336 TopoDS_Shape aShape = theShape->GetValue();
3337 TopoDS_Shape aCenter = theCenter->GetValue();
3339 if (aShape.IsNull() || aCenter.IsNull()) return NULL;
3341 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3342 if ( !checkTypeShapesOn( aShapeType ))
3345 // Center of the sphere
3346 if (aCenter.ShapeType() != TopAbs_VERTEX) return NULL;
3347 gp_Pnt aLoc = BRep_Tool::Pnt(TopoDS::Vertex(aCenter));
3349 gp_Ax3 anAx3 (aLoc, gp::DZ());
3350 Handle(Geom_SphericalSurface) aSphere =
3351 new Geom_SphericalSurface(anAx3, theRadius);
3354 TCollection_AsciiString anAsciiList;
3355 Handle(TColStd_HSequenceOfTransient) aSeq;
3356 aSeq = getShapesOnSurface( aSphere, theShape, aShapeType, theState, anAsciiList );
3357 if ( aSeq.IsNull() || aSeq->Length() == 0 )
3360 // Make a Python command
3362 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
3363 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
3365 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
3366 << "] = geompy.GetShapesOnSphere(" << theShape << ", " << aShapeType
3367 << ", " << theCenter << ", " << theRadius << ", " << theState << ")";
3373 //=============================================================================
3375 * GetShapesOnPlaneIDs
3377 //=============================================================================
3378 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnPlaneIDs
3379 (const Handle(GEOM_Object)& theShape,
3380 const Standard_Integer theShapeType,
3381 const Handle(GEOM_Object)& theAx1,
3382 const GEOMAlgo_State theState)
3386 if (theShape.IsNull() || theAx1.IsNull()) return NULL;
3388 TopoDS_Shape aShape = theShape->GetValue();
3389 TopoDS_Shape anAx1 = theAx1->GetValue();
3391 if (aShape.IsNull() || anAx1.IsNull()) return NULL;
3393 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3394 if ( !checkTypeShapesOn( aShapeType ))
3398 Handle(Geom_Surface) aPlane = makePlane( anAx1 );
3399 if ( aPlane.IsNull() )
3403 Handle(TColStd_HSequenceOfInteger) aSeq;
3404 aSeq = getShapesOnSurfaceIDs( aPlane, aShape, aShapeType, theState );
3406 // The GetShapesOnPlaneIDs() doesn't change object so no new function is required.
3407 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAx1)->GetLastFunction();
3409 // Make a Python command
3410 GEOM::TPythonDump(aFunction, /*append=*/true)
3411 << "listShapesOnPlane = geompy.GetShapesOnPlaneIDs"
3412 << "(" << theShape << "," << aShapeType << "," << theAx1 << "," << theState << ")";
3418 //=============================================================================
3420 * GetShapesOnPlaneWithLocationIDs
3422 //=============================================================================
3423 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnPlaneWithLocationIDs
3424 (const Handle(GEOM_Object)& theShape,
3425 const Standard_Integer theShapeType,
3426 const Handle(GEOM_Object)& theAx1,
3427 const Handle(GEOM_Object)& thePnt,
3428 const GEOMAlgo_State theState)
3432 if (theShape.IsNull() || theAx1.IsNull() || thePnt.IsNull()) return NULL;
3434 TopoDS_Shape aShape = theShape->GetValue();
3435 TopoDS_Shape anAx1 = theAx1->GetValue();
3436 TopoDS_Shape anPnt = thePnt->GetValue();
3438 if (aShape.IsNull() || anAx1.IsNull() || anPnt.IsNull()) return NULL;
3440 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3441 if ( !checkTypeShapesOn( aShapeType ))
3445 if (anAx1.ShapeType() != TopAbs_EDGE || anPnt.ShapeType() != TopAbs_VERTEX) return NULL;
3446 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
3447 TopoDS_Vertex V1, V2, V3;
3448 TopExp::Vertices(anEdge, V1, V2, Standard_True);
3449 if (V1.IsNull() || V2.IsNull()) {
3450 SetErrorCode("Bad edge given for the plane normal vector");
3453 V3 = TopoDS::Vertex(anPnt);
3455 SetErrorCode("Bad vertex given for the plane location");
3458 gp_Pnt aLoc = BRep_Tool::Pnt(V3);
3459 gp_Vec aVec(BRep_Tool::Pnt(V1),BRep_Tool::Pnt(V2));
3460 if (aVec.Magnitude() < Precision::Confusion()) {
3461 SetErrorCode("Vector with null magnitude given");
3465 Handle(Geom_Surface) aPlane = new Geom_Plane(aLoc, aVec);
3466 if ( aPlane.IsNull() )
3470 Handle(TColStd_HSequenceOfInteger) aSeq;
3471 aSeq = getShapesOnSurfaceIDs( aPlane, aShape, aShapeType, theState );
3473 // The GetShapesOnPlaneIDs() doesn't change object so no new function is required.
3474 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAx1)->GetLastFunction();
3476 // Make a Python command
3477 GEOM::TPythonDump(aFunction, /*append=*/true)
3478 << "listShapesOnPlane = geompy.GetShapesOnPlaneWithLocationIDs"
3479 << "(" << theShape << ", " << aShapeType << ", " << theAx1 << ", "<< thePnt << ", " << theState << ")";
3485 //=============================================================================
3487 * GetShapesOnCylinderIDs
3489 //=============================================================================
3490 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnCylinderIDs
3491 (const Handle(GEOM_Object)& theShape,
3492 const Standard_Integer theShapeType,
3493 const Handle(GEOM_Object)& theAxis,
3494 const Standard_Real theRadius,
3495 const GEOMAlgo_State theState)
3499 if (theShape.IsNull() || theAxis.IsNull()) return NULL;
3501 TopoDS_Shape aShape = theShape->GetValue();
3502 TopoDS_Shape anAxis = theAxis->GetValue();
3504 if (aShape.IsNull() || anAxis.IsNull()) return NULL;
3506 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3507 if ( !checkTypeShapesOn( aShapeType ))
3510 // Create a cylinder surface
3511 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
3512 if ( aCylinder.IsNull() )
3516 Handle(TColStd_HSequenceOfInteger) aSeq;
3517 aSeq = getShapesOnSurfaceIDs( aCylinder, aShape, aShapeType, theState );
3519 // The GetShapesOnCylinder() doesn't change object so no new function is required.
3520 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAxis)->GetLastFunction();
3522 // Make a Python command
3523 GEOM::TPythonDump(aFunction, /*append=*/true)
3524 << "listShapesOnCylinder = geompy.GetShapesOnCylinderIDs"
3525 << "(" << theShape << ", " << aShapeType << ", " << theAxis << ", "
3526 << theRadius << ", " << theState << ")";
3532 //=============================================================================
3534 * GetShapesOnCylinderWithLocationIDs
3536 //=============================================================================
3537 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnCylinderWithLocationIDs
3538 (const Handle(GEOM_Object)& theShape,
3539 const Standard_Integer theShapeType,
3540 const Handle(GEOM_Object)& theAxis,
3541 const Handle(GEOM_Object)& thePnt,
3542 const Standard_Real theRadius,
3543 const GEOMAlgo_State theState)
3547 if (theShape.IsNull() || theAxis.IsNull() || thePnt.IsNull()) return NULL;
3549 TopoDS_Shape aShape = theShape->GetValue();
3550 TopoDS_Shape anAxis = theAxis->GetValue();
3551 TopoDS_Shape aPnt = thePnt->GetValue();
3553 if (aShape.IsNull() || anAxis.IsNull() || aPnt.IsNull()) return NULL;
3555 if (aPnt.ShapeType() != TopAbs_VERTEX )
3557 SetErrorCode("Bottom location point must be vertex");
3561 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3562 if ( !checkTypeShapesOn( aShapeType ))
3565 // Create a cylinder surface
3566 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
3567 if ( aCylinder.IsNull() )
3570 // translate the surface
3571 Handle(Geom_CylindricalSurface) aCylSurface =
3572 Handle(Geom_CylindricalSurface)::DownCast( aCylinder );
3573 if ( aCylSurface.IsNull() )
3575 SetErrorCode("Unexpected surface type instead of Geom_CylindricalSurface");
3578 gp_Pnt fromLoc = aCylSurface->Cylinder().Location();
3579 gp_Pnt toLoc = BRep_Tool::Pnt( TopoDS::Vertex( aPnt ));
3580 aCylinder->Translate( fromLoc, toLoc );
3583 Handle(TColStd_HSequenceOfInteger) aSeq;
3584 aSeq = getShapesOnSurfaceIDs( aCylinder, aShape, aShapeType, theState );
3586 // The GetShapesOnCylinder() doesn't change object so no new function is required.
3587 Handle(GEOM_Function) aFunction =
3588 GEOM::GetCreatedLast(theShape, GEOM::GetCreatedLast(thePnt,theAxis))->GetLastFunction();
3590 // Make a Python command
3591 GEOM::TPythonDump(aFunction, /*append=*/true)
3592 << "listShapesOnCylinder = geompy.GetShapesOnCylinderWithLocationIDs"
3593 << "(" << theShape << ", " << aShapeType << ", " << theAxis << ", "
3594 << thePnt << ", " << theRadius << ", " << theState << ")";
3600 //=============================================================================
3602 * GetShapesOnSphereIDs
3604 //=============================================================================
3605 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnSphereIDs
3606 (const Handle(GEOM_Object)& theShape,
3607 const Standard_Integer theShapeType,
3608 const Handle(GEOM_Object)& theCenter,
3609 const Standard_Real theRadius,
3610 const GEOMAlgo_State theState)
3614 if (theShape.IsNull() || theCenter.IsNull()) return NULL;
3616 TopoDS_Shape aShape = theShape->GetValue();
3617 TopoDS_Shape aCenter = theCenter->GetValue();
3619 if (aShape.IsNull() || aCenter.IsNull()) return NULL;
3621 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3622 if ( !checkTypeShapesOn( aShapeType ))
3625 // Center of the sphere
3626 if (aCenter.ShapeType() != TopAbs_VERTEX) return NULL;
3627 gp_Pnt aLoc = BRep_Tool::Pnt(TopoDS::Vertex(aCenter));
3629 gp_Ax3 anAx3 (aLoc, gp::DZ());
3630 Handle(Geom_SphericalSurface) aSphere =
3631 new Geom_SphericalSurface(anAx3, theRadius);
3634 Handle(TColStd_HSequenceOfInteger) aSeq;
3635 aSeq = getShapesOnSurfaceIDs( aSphere, aShape, aShapeType, theState );
3637 // The GetShapesOnSphere() doesn't change object so no new function is required.
3638 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theCenter)->GetLastFunction();
3640 // Make a Python command
3641 GEOM::TPythonDump(aFunction, /*append=*/true)
3642 << "listShapesOnCylinder = geompy.GetShapesOnSphereIDs"
3643 << "(" << theShape << ", " << aShapeType << ", " << theCenter << ", "
3644 << theRadius << ", " << theState << ")";
3650 //=======================================================================
3651 //function : getShapesOnQuadrangleIDs
3653 * \brief Find IDs of sub-shapes complying with given status about quadrangle
3654 * \param theShape - the shape to explore
3655 * \param theShapeType - type of sub-shape of theShape
3656 * \param theTopLeftPoint - top left quadrangle corner
3657 * \param theTopRigthPoint - top right quadrangle corner
3658 * \param theBottomLeftPoint - bottom left quadrangle corner
3659 * \param theBottomRigthPoint - bottom right quadrangle corner
3660 * \param theState - required state
3661 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
3663 //=======================================================================
3664 Handle(TColStd_HSequenceOfInteger)
3665 GEOMImpl_IShapesOperations::getShapesOnQuadrangleIDs (const Handle(GEOM_Object)& theShape,
3666 const Standard_Integer theShapeType,
3667 const Handle(GEOM_Object)& theTopLeftPoint,
3668 const Handle(GEOM_Object)& theTopRigthPoint,
3669 const Handle(GEOM_Object)& theBottomLeftPoint,
3670 const Handle(GEOM_Object)& theBottomRigthPoint,
3671 const GEOMAlgo_State theState)
3675 if ( theShape.IsNull() ||
3676 theTopLeftPoint.IsNull() ||
3677 theTopRigthPoint.IsNull() ||
3678 theBottomLeftPoint.IsNull() ||
3679 theBottomRigthPoint.IsNull() )
3682 TopoDS_Shape aShape = theShape->GetValue();
3683 TopoDS_Shape aTL = theTopLeftPoint->GetValue();
3684 TopoDS_Shape aTR = theTopRigthPoint->GetValue();
3685 TopoDS_Shape aBL = theBottomLeftPoint->GetValue();
3686 TopoDS_Shape aBR = theBottomRigthPoint->GetValue();
3688 if (aShape.IsNull() ||
3693 aTL.ShapeType() != TopAbs_VERTEX ||
3694 aTR.ShapeType() != TopAbs_VERTEX ||
3695 aBL.ShapeType() != TopAbs_VERTEX ||
3696 aBR.ShapeType() != TopAbs_VERTEX )
3699 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3700 if ( !checkTypeShapesOn( aShapeType ))
3703 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
3705 // Check presence of triangulation, build if need
3706 if (!GEOMUtils::CheckTriangulation(aShape)) {
3707 SetErrorCode("Cannot build triangulation on the shape");
3712 gp_Pnt aPntTL = BRep_Tool::Pnt(TopoDS::Vertex(aTL));
3713 gp_Pnt aPntTR = BRep_Tool::Pnt(TopoDS::Vertex(aTR));
3714 gp_Pnt aPntBL = BRep_Tool::Pnt(TopoDS::Vertex(aBL));
3715 gp_Pnt aPntBR = BRep_Tool::Pnt(TopoDS::Vertex(aBR));
3717 GEOMAlgo_FinderShapeOnQuad aFinder( aPntTL, aPntTR, aPntBL, aPntBR );
3718 Standard_Real aTol = 0.0001; // default value
3720 aFinder.SetShape(aShape);
3721 aFinder.SetTolerance(aTol);
3722 //aFinder.SetSurface(theSurface);
3723 aFinder.SetShapeType(aShapeType);
3724 aFinder.SetState(theState);
3726 // Sets the minimal number of inner points for the faces that do not have own
3727 // inner points at all (for e.g. rectangular planar faces have just 2 triangles).
3729 aFinder.SetNbPntsMin(3);
3730 // Sets the maximal number of inner points for edges or faces.
3731 // It is usefull for the cases when this number is very big (e.g =2000) to improve
3732 // the performance. If this value =0, all inner points will be taken into account.
3734 aFinder.SetNbPntsMax(100);
3738 // Interprete results
3739 Standard_Integer iErr = aFinder.ErrorStatus();
3740 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
3742 MESSAGE(" iErr : " << iErr);
3743 TCollection_AsciiString aMsg (" iErr : ");
3744 aMsg += TCollection_AsciiString(iErr);
3748 Standard_Integer iWrn = aFinder.WarningStatus();
3749 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
3751 MESSAGE(" *** iWrn : " << iWrn);
3754 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
3756 if (listSS.Extent() < 1) {
3757 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
3758 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
3762 // Fill sequence of object IDs
3763 aSeqOfIDs = new TColStd_HSequenceOfInteger;
3765 TopTools_IndexedMapOfShape anIndices;
3766 TopExp::MapShapes(aShape, anIndices);
3768 TopTools_ListIteratorOfListOfShape itSub (listSS);
3769 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
3770 int id = anIndices.FindIndex(itSub.Value());
3771 aSeqOfIDs->Append(id);
3776 //=======================================================================
3777 //function : GetShapesOnQuadrangle
3779 * \brief Find sub-shapes complying with given status about quadrangle
3780 * \param theShape - the shape to explore
3781 * \param theShapeType - type of sub-shape of theShape
3782 * \param theTopLeftPoint - top left quadrangle corner
3783 * \param theTopRigthPoint - top right quadrangle corner
3784 * \param theBottomLeftPoint - bottom left quadrangle corner
3785 * \param theBottomRigthPoint - bottom right quadrangle corner
3786 * \param theState - required state
3787 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
3789 //=======================================================================
3790 Handle(TColStd_HSequenceOfTransient)
3791 GEOMImpl_IShapesOperations::GetShapesOnQuadrangle (const Handle(GEOM_Object)& theShape,
3792 const Standard_Integer theShapeType,
3793 const Handle(GEOM_Object)& theTopLeftPoint,
3794 const Handle(GEOM_Object)& theTopRigthPoint,
3795 const Handle(GEOM_Object)& theBottomLeftPoint,
3796 const Handle(GEOM_Object)& theBottomRigthPoint,
3797 const GEOMAlgo_State theState)
3800 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
3801 getShapesOnQuadrangleIDs( theShape,
3806 theBottomRigthPoint,
3808 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->IsEmpty() )
3811 // Find objects by indices
3812 TCollection_AsciiString anAsciiList;
3813 Handle(TColStd_HSequenceOfTransient) aSeq;
3814 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
3815 if ( aSeq.IsNull() || aSeq->IsEmpty() )
3818 // Make a Python command
3820 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
3821 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
3823 GEOM::TPythonDump(aFunction)
3824 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnQuadrangle("
3826 << TopAbs_ShapeEnum(theShapeType) << ", "
3827 << theTopLeftPoint << ", "
3828 << theTopRigthPoint << ", "
3829 << theBottomLeftPoint << ", "
3830 << theBottomRigthPoint << ", "
3837 //=======================================================================
3838 //function : GetShapesOnQuadrangleIDs
3840 * \brief Find IDs of sub-shapes complying with given status about quadrangle
3841 * \param theShape - the shape to explore
3842 * \param theShapeType - type of sub-shape of theShape
3843 * \param theTopLeftPoint - top left quadrangle corner
3844 * \param theTopRigthPoint - top right quadrangle corner
3845 * \param theBottomLeftPoint - bottom left quadrangle corner
3846 * \param theBottomRigthPoint - bottom right quadrangle corner
3847 * \param theState - required state
3848 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found sub-shapes
3850 //=======================================================================
3851 Handle(TColStd_HSequenceOfInteger)
3852 GEOMImpl_IShapesOperations::GetShapesOnQuadrangleIDs (const Handle(GEOM_Object)& theShape,
3853 const Standard_Integer theShapeType,
3854 const Handle(GEOM_Object)& theTopLeftPoint,
3855 const Handle(GEOM_Object)& theTopRigthPoint,
3856 const Handle(GEOM_Object)& theBottomLeftPoint,
3857 const Handle(GEOM_Object)& theBottomRigthPoint,
3858 const GEOMAlgo_State theState)
3861 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
3862 getShapesOnQuadrangleIDs( theShape,
3867 theBottomRigthPoint,
3869 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->IsEmpty() )
3872 // Make a Python command
3874 // The GetShapesOnCylinder() doesn't change object so no new function is required.
3875 Handle(GEOM_Object) lastObj = GEOM::GetCreatedLast(theShape,theTopLeftPoint);
3876 lastObj = GEOM::GetCreatedLast(lastObj,theTopRigthPoint);
3877 lastObj = GEOM::GetCreatedLast(lastObj,theBottomRigthPoint);
3878 lastObj = GEOM::GetCreatedLast(lastObj,theBottomLeftPoint);
3879 Handle(GEOM_Function) aFunction = lastObj->GetLastFunction();
3881 GEOM::TPythonDump(aFunction, /*append=*/true)
3882 << "listShapesOnQuadrangle = geompy.GetShapesOnQuadrangleIDs("
3884 << TopAbs_ShapeEnum(theShapeType) << ", "
3885 << theTopLeftPoint << ", "
3886 << theTopRigthPoint << ", "
3887 << theBottomLeftPoint << ", "
3888 << theBottomRigthPoint << ", "
3895 //=============================================================================
3900 //=============================================================================
3901 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlace (Handle(GEOM_Object) theShapeWhere,
3902 Handle(GEOM_Object) theShapeWhat)
3906 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
3908 TopoDS_Shape aWhere = theShapeWhere->GetValue();
3909 TopoDS_Shape aWhat = theShapeWhat->GetValue();
3911 if (aWhere.IsNull() || aWhat.IsNull()) {
3912 SetErrorCode("Error: aWhere and aWhat TopoDS_Shape are Null.");
3916 // Searching for the sub-shapes inside the ShapeWhere shape
3917 GEOMAlgo_GetInPlace aGIP;
3919 if (!GEOMAlgo_GetInPlaceAPI::GetInPlace(aWhere, aWhat, aGIP)) {
3920 SetErrorCode("Error in GEOMAlgo_GetInPlace");
3924 // Add direct result.
3925 TopTools_ListOfShape aLSA;
3926 const TopoDS_Shape &aShapeResult = aGIP.Result();
3927 TopTools_MapOfShape aMFence;
3928 TopTools_IndexedMapOfShape aWhereIndices;
3930 TopExp::MapShapes(aWhere, aWhereIndices);
3932 if (aShapeResult.IsNull() == Standard_False) {
3933 TopoDS_Iterator anIt(aShapeResult);
3935 for (; anIt.More(); anIt.Next()) {
3936 const TopoDS_Shape &aPart = anIt.Value();
3938 if(aWhereIndices.Contains(aPart) && aMFence.Add(aPart)) {
3944 if (aLSA.Extent() == 0) {
3945 SetErrorCode(NOT_FOUND_ANY); // Not found any Results
3949 Handle(TColStd_HArray1OfInteger) aModifiedArray = new TColStd_HArray1OfInteger (1, aLSA.Extent());
3950 TopTools_ListIteratorOfListOfShape anIterModif (aLSA);
3951 for (Standard_Integer imod = 1; anIterModif.More(); anIterModif.Next(), imod++) {
3952 if (aWhereIndices.Contains(anIterModif.Value())) {
3953 aModifiedArray->SetValue(imod, aWhereIndices.FindIndex(anIterModif.Value()));
3956 SetErrorCode("Error: wrong sub-shape returned");
3962 Handle(GEOM_Object) aResult = GetEngine()->AddSubShape(theShapeWhere, aModifiedArray);
3963 if (aResult.IsNull()) {
3964 SetErrorCode("Error in algorithm: result found, but cannot be returned.");
3968 if (aModifiedArray->Length() > 1 || theShapeWhat->GetType() == GEOM_GROUP) {
3970 aResult->SetType(GEOM_GROUP);
3972 //Set a sub-shape type
3973 TopoDS_Shape aFirstFound = aLSA.First();
3974 TopAbs_ShapeEnum aShapeType = aFirstFound.ShapeType();
3976 TDF_Label aFreeLabel = aResult->GetFreeLabel();
3977 TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aShapeType);
3980 //Make a Python command
3981 Handle(GEOM_Function) aFunction = aResult->GetFunction(1);
3983 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetInPlace("
3984 << theShapeWhere << ", " << theShapeWhat << ", True)";
3990 //=============================================================================
3992 * case GetInPlaceOld:
3995 //=============================================================================
3996 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlaceOld
3997 (Handle(GEOM_Object) theShapeWhere,
3998 Handle(GEOM_Object) theShapeWhat)
4002 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
4004 TopoDS_Shape aWhere = theShapeWhere->GetValue();
4005 TopoDS_Shape aWhat = theShapeWhat->GetValue();
4006 TopTools_ListOfShape aModifiedList;
4007 const Standard_Integer iErr =
4008 GEOMAlgo_GetInPlaceAPI::GetInPlaceOld(aWhere, aWhat, aModifiedList);
4013 SetErrorCode("Error: aWhere and aWhat TopoDS_Shape are Null.");
4017 ("Error: An attempt to extract a shape of not supported type.");
4020 SetErrorCode(NOT_FOUND_ANY);
4023 SetErrorCode("Shape driver failed");
4030 TopTools_IndexedMapOfShape aWhereIndices;
4031 TopExp::MapShapes(aWhere, aWhereIndices);
4033 Handle(TColStd_HArray1OfInteger) aModifiedArray =
4034 new TColStd_HArray1OfInteger (1, aModifiedList.Extent());
4035 TopTools_ListIteratorOfListOfShape anIterModif (aModifiedList);
4036 Standard_Integer imod;
4038 for (imod = 1; anIterModif.More(); anIterModif.Next(), imod++) {
4039 const Standard_Integer anIndex =
4040 aWhereIndices.FindIndex(anIterModif.Value());
4042 aModifiedArray->SetValue(imod, anIndex);
4046 Handle(GEOM_Object) aResult =
4047 GetEngine()->AddSubShape(theShapeWhere, aModifiedArray);
4049 if (aResult.IsNull()) {
4050 SetErrorCode("Error in algorithm: result found, but cannot be returned.");
4054 if (aModifiedArray->Length() > 1 || theShapeWhat->GetType() == GEOM_GROUP) {
4056 aResult->SetType(GEOM_GROUP);
4058 //Set a sub-shape type
4059 TopoDS_Shape aFirstFound = aWhereIndices.FindKey(aModifiedArray->Value(1));
4060 TopAbs_ShapeEnum aShapeType = aFirstFound.ShapeType();
4062 TDF_Label aFreeLabel = aResult->GetFreeLabel();
4063 TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aShapeType);
4066 //Make a Python command
4067 Handle(GEOM_Function) aFunction = aResult->GetFunction(1);
4069 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetInPlace("
4070 << theShapeWhere << ", " << theShapeWhat << ", False)";
4077 //=======================================================================
4078 //function : GetInPlaceByHistory
4080 //=======================================================================
4081 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlaceByHistory
4082 (Handle(GEOM_Object) theShapeWhere,
4083 Handle(GEOM_Object) theShapeWhat)
4087 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
4089 TopoDS_Shape aWhere = theShapeWhere->GetValue();
4090 TopoDS_Shape aWhat = theShapeWhat->GetValue();
4092 if (aWhere.IsNull() || aWhat.IsNull()) return NULL;
4094 Handle(GEOM_Function) aWhereFunction = theShapeWhere->GetLastFunction();
4095 if (aWhereFunction.IsNull()) return NULL;
4097 //Fill array of indices
4098 TopTools_IndexedMapOfShape aWhereIndices;
4100 TopExp::MapShapes(aWhere, aWhereIndices);
4103 TopTools_ListOfShape aModifiedList;
4104 bool isFound = GEOMAlgo_GetInPlaceAPI::GetInPlaceByHistory
4105 (aWhereFunction, aWhereIndices, aWhat, aModifiedList);
4107 if (!isFound || aModifiedList.Extent() < 1) {
4108 SetErrorCode("Error: No history found for the sought shape or its sub-shapes.");
4112 Standard_Integer nbFound = aModifiedList.Extent();
4113 TopTools_ListIteratorOfListOfShape anIterModif (aModifiedList);
4116 // remove sub-shapes inappropriate for group creation
4117 TopAbs_ShapeEnum subType = TopAbs_SHAPE;
4118 while ( anIterModif.More() ) {
4119 TopAbs_ShapeEnum type = anIterModif.Value().ShapeType();
4120 bool okForGroup = ( type == TopAbs_VERTEX || type == TopAbs_EDGE ||
4121 type == TopAbs_FACE || type == TopAbs_SOLID );
4123 if ( subType == TopAbs_SHAPE )
4126 okForGroup = ( subType == type );
4131 aModifiedList.Remove( anIterModif );
4132 nbFound -= ( !okForGroup );
4134 if ( nbFound == 0 ) {
4135 SetErrorCode("Error: result found but it's type is inappropriate for group creation.");
4140 Handle(TColStd_HArray1OfInteger) aModifiedArray =
4141 new TColStd_HArray1OfInteger( 1, nbFound );
4142 anIterModif.Initialize(aModifiedList);
4143 for (Standard_Integer imod = 1; anIterModif.More(); anIterModif.Next(), imod++)
4144 aModifiedArray->SetValue
4145 (imod, aWhereIndices.FindIndex(anIterModif.Value()));
4148 Handle(GEOM_Object) aResult = GetEngine()->AddSubShape(theShapeWhere, aModifiedArray);
4149 if (aResult.IsNull()) {
4150 SetErrorCode("Error in algorithm: result found, but cannot be returned.");
4154 if (aModifiedArray->Length() > 1) {
4156 aResult->SetType(GEOM_GROUP);
4158 //Set a sub-shape type
4159 TopoDS_Shape aFirstFound = aWhereIndices.FindKey(aModifiedArray->Value(1));
4160 TopAbs_ShapeEnum aShapeType = aFirstFound.ShapeType();
4162 TDF_Label aFreeLabel = aResult->GetFreeLabel();
4163 TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aShapeType);
4166 //Make a Python command
4167 Handle(GEOM_Function) aFunction = aResult->GetFunction(1);
4169 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetInPlaceByHistory("
4170 << theShapeWhere << ", " << theShapeWhat << ")";
4176 #define MAX_TOLERANCE 1.e-7
4178 //=======================================================================
4179 //function : isSameEdge
4180 //purpose : Returns True if two edges coincide
4181 //=======================================================================
4182 static bool isSameEdge(const TopoDS_Edge& theEdge1, const TopoDS_Edge& theEdge2)
4184 TopoDS_Vertex V11, V12, V21, V22;
4185 TopExp::Vertices(theEdge1, V11, V12);
4186 TopExp::Vertices(theEdge2, V21, V22);
4187 gp_Pnt P11 = BRep_Tool::Pnt(V11);
4188 gp_Pnt P12 = BRep_Tool::Pnt(V12);
4189 gp_Pnt P21 = BRep_Tool::Pnt(V21);
4190 gp_Pnt P22 = BRep_Tool::Pnt(V22);
4191 bool coincide = false;
4193 //Check that ends of edges coincide
4194 if(P11.Distance(P21) <= MAX_TOLERANCE) {
4195 if(P12.Distance(P22) <= MAX_TOLERANCE) coincide = true;
4197 else if(P11.Distance(P22) <= MAX_TOLERANCE) {
4198 if(P12.Distance(P21) <= MAX_TOLERANCE) coincide = true;
4201 if(!coincide) return false;
4203 if (BRep_Tool::Degenerated(theEdge1))
4204 if (BRep_Tool::Degenerated(theEdge2)) return true;
4207 if (BRep_Tool::Degenerated(theEdge2)) return false;
4209 double U11, U12, U21, U22;
4210 Handle(Geom_Curve) C1 = BRep_Tool::Curve(theEdge1, U11, U12);
4211 Handle(Geom_Curve) C2 = BRep_Tool::Curve(theEdge2, U21, U22);
4212 if(C1->DynamicType() == C2->DynamicType()) return true;
4214 //Check that both edges has the same geometry
4215 double range = U12-U11;
4216 double U = U11+ range/3.0;
4217 gp_Pnt P1 = C1->Value(U); //Compute a point on one third of the edge's length
4218 U = U11+range*2.0/3.0;
4219 gp_Pnt P2 = C1->Value(U); //Compute a point on two thirds of the edge's length
4221 if(!GeomLib_Tool::Parameter(C2, P1, MAX_TOLERANCE, U) || U < U21 || U > U22)
4224 if(P1.Distance(C2->Value(U)) > MAX_TOLERANCE) return false;
4226 if(!GeomLib_Tool::Parameter(C2, P2, MAX_TOLERANCE, U) || U < U21 || U > U22)
4229 if(P2.Distance(C2->Value(U)) > MAX_TOLERANCE) return false;
4234 #include <TopoDS_TShape.hxx>
4235 //=======================================================================
4236 //function : isSameFace
4237 //purpose : Returns True if two faces coincide
4238 //=======================================================================
4239 static bool isSameFace(const TopoDS_Face& theFace1, const TopoDS_Face& theFace2)
4241 TopExp_Explorer E(theFace1, TopAbs_EDGE);
4242 TopTools_ListOfShape LS1, LS2;
4243 for(; E.More(); E.Next()) LS1.Append(E.Current());
4245 E.Init(theFace2, TopAbs_EDGE);
4246 for(; E.More(); E.Next()) LS2.Append(E.Current());
4248 //Compare the number of edges in the faces
4249 if(LS1.Extent() != LS2.Extent()) return false;
4251 double aMin = RealFirst(), aMax = RealLast();
4252 double xminB1=aMax, yminB1=aMax, zminB1=aMax, xminB2=aMax, yminB2=aMax, zminB2=aMax;
4253 double xmaxB1=aMin, ymaxB1=aMin, zmaxB1=aMin, xmaxB2=aMin, ymaxB2=aMin, zmaxB2=aMin;
4255 for(E.Init(theFace1, TopAbs_VERTEX); E.More(); E.Next()) {
4256 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4257 if(P.X() < xminB1) xminB1 = P.X();
4258 if(P.Y() < yminB1) yminB1 = P.Y();
4259 if(P.Z() < zminB1) zminB1 = P.Z();
4260 if(P.X() > xmaxB1) xmaxB1 = P.X();
4261 if(P.Y() > ymaxB1) ymaxB1 = P.Y();
4262 if(P.Z() > zmaxB1) zmaxB1 = P.Z();
4265 for(E.Init(theFace2, TopAbs_VERTEX); E.More(); E.Next()) {
4266 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4267 if(P.X() < xminB2) xminB2 = P.X();
4268 if(P.Y() < yminB2) yminB2 = P.Y();
4269 if(P.Z() < zminB2) zminB2 = P.Z();
4270 if(P.X() > xmaxB2) xmaxB2 = P.X();
4271 if(P.Y() > ymaxB2) ymaxB2 = P.Y();
4272 if(P.Z() > zmaxB2) zmaxB2 = P.Z();
4275 //Compare the bounding boxes of both faces
4276 if(gp_Pnt(xminB1, yminB1, zminB1).Distance(gp_Pnt(xminB2, yminB2, zminB2)) > MAX_TOLERANCE)
4279 if(gp_Pnt(xmaxB1, ymaxB1, zmaxB1).Distance(gp_Pnt(xmaxB2, ymaxB2, zmaxB2)) > MAX_TOLERANCE)
4282 Handle(Geom_Surface) S1 = BRep_Tool::Surface(theFace1);
4283 Handle(Geom_Surface) S2 = BRep_Tool::Surface(theFace2);
4285 //Check if there a coincidence of two surfaces at least in two points
4286 double U11, U12, V11, V12, U21, U22, V21, V22;
4287 BRepTools::UVBounds(theFace1, U11, U12, V11, V12);
4288 BRepTools::UVBounds(theFace2, U21, U22, V21, V22);
4290 double rangeU = U12-U11;
4291 double rangeV = V12-V11;
4292 double U = U11 + rangeU/3.0;
4293 double V = V11 + rangeV/3.0;
4294 gp_Pnt P1 = S1->Value(U, V);
4295 U = U11+rangeU*2.0/3.0;
4296 V = V11+rangeV*2.0/3.0;
4297 gp_Pnt P2 = S1->Value(U, V);
4299 if (!GeomLib_Tool::Parameters(S2, P1, MAX_TOLERANCE, U, V) || U < U21 || U > U22 || V < V21 || V > V22)
4302 if (P1.Distance(S2->Value(U,V)) > MAX_TOLERANCE) return false;
4304 if (!GeomLib_Tool::Parameters(S2, P2, MAX_TOLERANCE, U, V) || U < U21 || U > U22 || V < V21 || V > V22)
4307 if (P2.Distance(S2->Value(U, V)) > MAX_TOLERANCE) return false;
4309 //Check that each edge of the Face1 has a counterpart in the Face2
4310 TopTools_MapOfOrientedShape aMap;
4311 TopTools_ListIteratorOfListOfShape LSI1(LS1);
4312 for(; LSI1.More(); LSI1.Next()) {
4313 TopoDS_Edge E = TopoDS::Edge(LSI1.Value());
4314 bool isFound = false;
4315 TopTools_ListIteratorOfListOfShape LSI2(LS2);
4316 for(; LSI2.More(); LSI2.Next()) {
4317 TopoDS_Shape aValue = LSI2.Value();
4318 if(aMap.Contains(aValue)) continue; //To avoid checking already found edge several times
4319 if(isSameEdge(E, TopoDS::Edge(aValue))) {
4325 if(!isFound) return false;
4331 //=======================================================================
4332 //function : isSameSolid
4333 //purpose : Returns True if two solids coincide
4334 //=======================================================================
4335 bool isSameSolid(const TopoDS_Solid& theSolid1, const TopoDS_Solid& theSolid2)
4337 TopExp_Explorer E(theSolid1, TopAbs_FACE);
4338 TopTools_ListOfShape LS1, LS2;
4339 for(; E.More(); E.Next()) LS1.Append(E.Current());
4340 E.Init(theSolid2, TopAbs_FACE);
4341 for(; E.More(); E.Next()) LS2.Append(E.Current());
4343 if(LS1.Extent() != LS2.Extent()) return false;
4345 double aMin = RealFirst(), aMax = RealLast();
4346 double xminB1=aMax, yminB1=aMax, zminB1=aMax, xminB2=aMax, yminB2=aMax, zminB2=aMax;
4347 double xmaxB1=aMin, ymaxB1=aMin, zmaxB1=aMin, xmaxB2=aMin, ymaxB2=aMin, zmaxB2=aMin;
4349 for(E.Init(theSolid1, TopAbs_VERTEX); E.More(); E.Next()) {
4350 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4351 if(P.X() < xminB1) xminB1 = P.X();
4352 if(P.Y() < yminB1) yminB1 = P.Y();
4353 if(P.Z() < zminB1) zminB1 = P.Z();
4354 if(P.X() > xmaxB1) xmaxB1 = P.X();
4355 if(P.Y() > ymaxB1) ymaxB1 = P.Y();
4356 if(P.Z() > zmaxB1) zmaxB1 = P.Z();
4359 for(E.Init(theSolid2, TopAbs_VERTEX); E.More(); E.Next()) {
4360 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4361 if(P.X() < xminB2) xminB2 = P.X();
4362 if(P.Y() < yminB2) yminB2 = P.Y();
4363 if(P.Z() < zminB2) zminB2 = P.Z();
4364 if(P.X() > xmaxB2) xmaxB2 = P.X();
4365 if(P.Y() > ymaxB2) ymaxB2 = P.Y();
4366 if(P.Z() > zmaxB2) zmaxB2 = P.Z();
4369 //Compare the bounding boxes of both solids
4370 if(gp_Pnt(xminB1, yminB1, zminB1).Distance(gp_Pnt(xminB2, yminB2, zminB2)) > MAX_TOLERANCE)
4373 if(gp_Pnt(xmaxB1, ymaxB1, zmaxB1).Distance(gp_Pnt(xmaxB2, ymaxB2, zmaxB2)) > MAX_TOLERANCE)
4376 //Check that each face of the Solid1 has a counterpart in the Solid2
4377 TopTools_MapOfOrientedShape aMap;
4378 TopTools_ListIteratorOfListOfShape LSI1(LS1);
4379 for(; LSI1.More(); LSI1.Next()) {
4380 TopoDS_Face F = TopoDS::Face(LSI1.Value());
4381 bool isFound = false;
4382 TopTools_ListIteratorOfListOfShape LSI2(LS2);
4383 for(; LSI2.More(); LSI2.Next()) {
4384 if(aMap.Contains(LSI2.Value())) continue; //To avoid checking already found faces several times
4385 if(isSameFace(F, TopoDS::Face(LSI2.Value()))) {
4386 aMap.Add(LSI2.Value());
4391 if(!isFound) return false;
4397 //=======================================================================
4398 //function : GetSame
4400 //=======================================================================
4401 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetSame(const Handle(GEOM_Object)& theShapeWhere,
4402 const Handle(GEOM_Object)& theShapeWhat)
4405 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
4407 TopoDS_Shape aWhere = theShapeWhere->GetValue();
4408 TopoDS_Shape aWhat = theShapeWhat->GetValue();
4410 if (aWhere.IsNull() || aWhat.IsNull()) return NULL;
4413 bool isFound = false;
4414 TopoDS_Shape aSubShape;
4415 TopTools_MapOfShape aMap;
4417 if (aWhat.ShapeType() == TopAbs_COMPOUND || aWhat.ShapeType() == TopAbs_COMPSOLID) {
4418 TopoDS_Iterator It (aWhat, Standard_True, Standard_True);
4419 if (It.More()) aWhat = It.Value();
4422 SetErrorCode("Compounds of two or more shapes are not allowed for aWhat argument");
4427 switch (aWhat.ShapeType()) {
4428 case TopAbs_VERTEX: {
4429 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(aWhat));
4430 TopExp_Explorer E(aWhere, TopAbs_VERTEX);
4431 for(; E.More(); E.Next()) {
4432 if(!aMap.Add(E.Current())) continue;
4433 gp_Pnt P2 = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4434 if(P.Distance(P2) <= MAX_TOLERANCE) {
4436 aSubShape = E.Current();
4443 TopoDS_Edge anEdge = TopoDS::Edge(aWhat);
4444 TopExp_Explorer E(aWhere, TopAbs_EDGE);
4445 for(; E.More(); E.Next()) {
4446 if(!aMap.Add(E.Current())) continue;
4447 if(isSameEdge(anEdge, TopoDS::Edge(E.Current()))) {
4448 aSubShape = E.Current();
4456 TopoDS_Face aFace = TopoDS::Face(aWhat);
4457 TopExp_Explorer E(aWhere, TopAbs_FACE);
4458 for(; E.More(); E.Next()) {
4459 if(!aMap.Add(E.Current())) continue;
4460 if(isSameFace(aFace, TopoDS::Face(E.Current()))) {
4461 aSubShape = E.Current();
4468 case TopAbs_SOLID: {
4469 TopoDS_Solid aSolid = TopoDS::Solid(aWhat);
4470 TopExp_Explorer E(aWhere, TopAbs_SOLID);
4471 for(; E.More(); E.Next()) {
4472 if(!aMap.Add(E.Current())) continue;
4473 if(isSameSolid(aSolid, TopoDS::Solid(E.Current()))) {
4474 aSubShape = E.Current();
4486 TopTools_IndexedMapOfShape anIndices;
4487 TopExp::MapShapes(aWhere, anIndices);
4488 if (anIndices.Contains(aSubShape))
4489 anIndex = anIndices.FindIndex(aSubShape);
4492 if (anIndex < 0) return NULL;
4494 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
4496 anArray->SetValue(1, anIndex);
4498 Handle(GEOM_Object) aResult = GetEngine()->AddSubShape(theShapeWhere, anArray);
4499 Handle(GEOM_Function) aFunction = aResult->GetLastFunction();
4501 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetSame("
4502 << theShapeWhere << ", " << theShapeWhat << ")";
4510 //=======================================================================
4511 //function : GetSameIDs
4513 //=======================================================================
4514 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetSameIDs
4515 (const Handle(GEOM_Object)& theShapeWhere,
4516 const Handle(GEOM_Object)& theShapeWhat)
4519 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
4521 TopoDS_Shape aWhere = theShapeWhere->GetValue();
4522 TopoDS_Shape aWhat = theShapeWhat->GetValue();
4524 if (aWhere.IsNull() || aWhat.IsNull()) return NULL;
4526 TopTools_ListOfShape listShape;
4527 TopTools_MapOfShape aMap;
4529 if (aWhat.ShapeType() == TopAbs_COMPOUND || aWhat.ShapeType() == TopAbs_COMPSOLID) {
4530 TopoDS_Iterator It (aWhat, Standard_True, Standard_True);
4531 if (It.More()) aWhat = It.Value();
4534 SetErrorCode("Compounds of two or more shapes are not allowed for aWhat argument");
4539 switch (aWhat.ShapeType()) {
4540 case TopAbs_VERTEX: {
4541 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(aWhat));
4542 TopExp_Explorer E(aWhere, TopAbs_VERTEX);
4543 for(; E.More(); E.Next()) {
4544 if(!aMap.Add(E.Current())) continue;
4545 gp_Pnt P2 = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4546 if(P.Distance(P2) <= MAX_TOLERANCE) {
4547 listShape.Append(E.Current());
4553 TopoDS_Edge anEdge = TopoDS::Edge(aWhat);
4554 TopExp_Explorer E(aWhere, TopAbs_EDGE);
4555 for(; E.More(); E.Next()) {
4556 if(!aMap.Add(E.Current())) continue;
4557 if(isSameEdge(anEdge, TopoDS::Edge(E.Current()))) {
4558 listShape.Append(E.Current());
4564 TopoDS_Face aFace = TopoDS::Face(aWhat);
4565 TopExp_Explorer E(aWhere, TopAbs_FACE);
4566 for(; E.More(); E.Next()) {
4567 if(!aMap.Add(E.Current())) continue;
4568 if(isSameFace(aFace, TopoDS::Face(E.Current()))) {
4569 listShape.Append(E.Current());
4574 case TopAbs_SOLID: {
4575 TopoDS_Solid aSolid = TopoDS::Solid(aWhat);
4576 TopExp_Explorer E(aWhere, TopAbs_SOLID);
4577 for(; E.More(); E.Next()) {
4578 if(!aMap.Add(E.Current())) continue;
4579 if(isSameSolid(aSolid, TopoDS::Solid(E.Current()))) {
4580 listShape.Append(E.Current());
4589 if ( !listShape.IsEmpty() ) {
4590 TopTools_IndexedMapOfShape anIndices;
4591 TopExp::MapShapes(aWhere, anIndices);
4592 TopTools_ListIteratorOfListOfShape itSub (listShape);
4593 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
4594 for (; itSub.More(); itSub.Next()) {
4595 if (anIndices.Contains(itSub.Value()))
4596 aSeq->Append(anIndices.FindIndex(itSub.Value()));
4599 // The GetSameIDs() doesn't change object so no new function is required.
4600 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShapeWhere,theShapeWhat)->GetLastFunction();
4602 // Make a Python command
4603 GEOM::TPythonDump(aFunction, /*append=*/true)
4604 << "listSameIDs = geompy.GetSameIDs("
4605 << theShapeWhere << ", "
4606 << theShapeWhat << ")";
4609 SetErrorCode(NOT_FOUND_ANY);
4614 //=======================================================================
4615 //function : ExtendEdge
4617 //=======================================================================
4618 Handle(GEOM_Object) GEOMImpl_IShapesOperations::ExtendEdge
4619 (const Handle(GEOM_Object) &theEdge,
4620 const Standard_Real theMin,
4621 const Standard_Real theMax)
4625 if (theEdge.IsNull()) {
4629 //Add a new Edge object
4630 Handle(GEOM_Object) aResEdge = GetEngine()->AddObject(GetDocID(), GEOM_EDGE);
4632 //Add a new Vector function
4633 Handle(GEOM_Function) aFunction =
4634 aResEdge->AddFunction(GEOMImpl_ShapeDriver::GetID(), EDGE_UV);
4636 //Check if the function is set correctly
4637 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) {
4641 GEOMImpl_IShapeExtend aCI (aFunction);
4643 Handle(GEOM_Function) anEdge = theEdge->GetLastFunction();
4645 if (anEdge.IsNull()) {
4649 aCI.SetShape(anEdge);
4650 aCI.SetUMin(theMin);
4651 aCI.SetUMax(theMax);
4653 //Compute the Edge value
4656 if (!GetSolver()->ComputeFunction(aFunction)) {
4657 SetErrorCode("Shape driver failed");
4662 catch (Standard_Failure) {
4663 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
4664 SetErrorCode(aFail->GetMessageString());
4669 //Make a Python command
4670 GEOM::TPythonDump(aFunction)
4671 << aResEdge << " = geompy.ExtendEdge("
4672 << theEdge << ", " << theMin << ", " << theMax << ")";
4679 //=======================================================================
4680 //function : ExtendFace
4682 //=======================================================================
4683 Handle(GEOM_Object) GEOMImpl_IShapesOperations::ExtendFace
4684 (const Handle(GEOM_Object) &theFace,
4685 const Standard_Real theUMin,
4686 const Standard_Real theUMax,
4687 const Standard_Real theVMin,
4688 const Standard_Real theVMax)
4692 if (theFace.IsNull()) {
4696 //Add a new Face object
4697 Handle(GEOM_Object) aResFace = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
4699 //Add a new Vector function
4700 Handle(GEOM_Function) aFunction =
4701 aResFace->AddFunction(GEOMImpl_ShapeDriver::GetID(), FACE_UV);
4703 //Check if the function is set correctly
4704 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) {
4708 GEOMImpl_IShapeExtend aCI (aFunction);
4710 Handle(GEOM_Function) aFace = theFace->GetLastFunction();
4712 if (aFace.IsNull()) {
4716 aCI.SetShape(aFace);
4717 aCI.SetUMin(theUMin);
4718 aCI.SetUMax(theUMax);
4719 aCI.SetVMin(theVMin);
4720 aCI.SetVMax(theVMax);
4722 //Compute the Face value
4725 if (!GetSolver()->ComputeFunction(aFunction)) {
4726 SetErrorCode("Shape driver failed");
4731 catch (Standard_Failure) {
4732 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
4733 SetErrorCode(aFail->GetMessageString());
4738 //Make a Python command
4739 GEOM::TPythonDump(aFunction)
4740 << aResFace << " = geompy.ExtendFace("
4741 << theFace << ", " << theUMin << ", " << theUMax << ", "
4742 << theVMin << ", " << theVMax << ")";
4749 //=======================================================================
4750 //function : MakeSurfaceFromFace
4752 //=======================================================================
4753 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeSurfaceFromFace
4754 (const Handle(GEOM_Object) &theFace)
4758 if (theFace.IsNull()) {
4762 //Add a new Face object
4763 Handle(GEOM_Object) aResFace = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
4765 //Add a new Vector function
4766 Handle(GEOM_Function) aFunction =
4767 aResFace->AddFunction(GEOMImpl_ShapeDriver::GetID(), SURFACE_FROM_FACE);
4769 //Check if the function is set correctly
4770 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) {
4774 GEOMImpl_IShapeExtend aCI (aFunction);
4776 Handle(GEOM_Function) aFace = theFace->GetLastFunction();
4778 if (aFace.IsNull()) {
4782 aCI.SetShape(aFace);
4784 //Compute the Face value
4787 if (!GetSolver()->ComputeFunction(aFunction)) {
4788 SetErrorCode("Shape driver failed");
4793 catch (Standard_Failure) {
4794 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
4795 SetErrorCode(aFail->GetMessageString());
4800 //Make a Python command
4801 GEOM::TPythonDump(aFunction)
4802 << aResFace << " = geompy.MakeSurfaceFromFace("