1 // Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 // File : GEOMImpl_IShapesOperations.cxx
24 // Author : modified by Lioka RAZAFINDRAZAKA (CEA) 22/06/2007
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_CopyDriver.hxx"
37 #include "GEOMImpl_GlueDriver.hxx"
39 #include "GEOMImpl_IVector.hxx"
40 #include "GEOMImpl_IShapes.hxx"
41 #include "GEOMImpl_IGlue.hxx"
43 #include "GEOMImpl_Block6Explorer.hxx"
45 #include "GEOM_Function.hxx"
46 #include "GEOM_ISubShape.hxx"
47 #include "GEOM_PythonDump.hxx"
49 #include "GEOMAlgo_FinderShapeOn1.hxx"
50 #include "GEOMAlgo_FinderShapeOnQuad.hxx"
51 #include "GEOMAlgo_FinderShapeOn2.hxx"
52 #include "GEOMAlgo_ClsfBox.hxx"
53 #include "GEOMAlgo_ClsfSolid.hxx"
54 #include "GEOMAlgo_Gluer1.hxx"
55 #include "GEOMAlgo_ListIteratorOfListOfCoupleOfShapes.hxx"
56 #include "GEOMAlgo_CoupleOfShapes.hxx"
57 #include "GEOMAlgo_ListOfCoupleOfShapes.hxx"
59 #include "utilities.h"
61 #include "Utils_ExceptHandlers.hxx"
63 #include <TFunction_DriverTable.hxx>
64 #include <TFunction_Driver.hxx>
65 #include <TFunction_Logbook.hxx>
66 #include <TDataStd_Integer.hxx>
67 #include <TDataStd_IntegerArray.hxx>
68 #include <TDF_Tool.hxx>
70 #include <BRepExtrema_ExtCF.hxx>
71 #include <BRepExtrema_DistShapeShape.hxx>
73 #include <BRep_Tool.hxx>
74 #include <BRep_Builder.hxx>
75 #include <BRepTools.hxx>
76 #include <BRepGProp.hxx>
77 #include <BRepAdaptor_Curve.hxx>
78 #include <BRepAdaptor_Surface.hxx>
79 #include <BRepBndLib.hxx>
80 #include <BRepBuilderAPI_MakeFace.hxx>
81 #include <BRepMesh_IncrementalMesh.hxx>
86 #include <TopoDS_Shape.hxx>
87 #include <TopoDS_Solid.hxx>
88 #include <TopoDS_Face.hxx>
89 #include <TopoDS_Edge.hxx>
90 #include <TopoDS_Vertex.hxx>
91 #include <TopoDS_Compound.hxx>
92 #include <TopoDS_Iterator.hxx>
93 #include <TopExp_Explorer.hxx>
94 #include <TopLoc_Location.hxx>
95 #include <TopTools_MapOfShape.hxx>
96 #include <TopTools_MapOfOrientedShape.hxx>
97 #include <TopTools_Array1OfShape.hxx>
98 #include <TopTools_ListIteratorOfListOfShape.hxx>
99 #include <TopTools_IndexedMapOfShape.hxx>
101 #include <Geom_Surface.hxx>
102 #include <Geom_Plane.hxx>
103 #include <Geom_SphericalSurface.hxx>
104 #include <Geom_CylindricalSurface.hxx>
105 #include <GeomAdaptor_Surface.hxx>
107 #include <GeomLib_Tool.hxx>
108 #include <Geom2d_Curve.hxx>
110 #include <Bnd_Box.hxx>
111 #include <GProp_GProps.hxx>
112 #include <TColStd_Array1OfReal.hxx>
113 #include <TColStd_HArray1OfInteger.hxx>
114 #include <TColStd_ListIteratorOfListOfInteger.hxx>
115 #include <TColStd_ListOfInteger.hxx>
116 #include <gp_Cylinder.hxx>
117 #include <gp_Lin.hxx>
118 #include <gp_Pnt.hxx>
122 #include <Standard_NullObject.hxx>
123 #include <Standard_Failure.hxx>
124 #include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
126 // Includes added for GetInPlace algorithm improvement
128 #include <GEOMImpl_MeasureDriver.hxx>
129 #include <GEOMImpl_IMeasure.hxx>
130 #include <BRepBuilderAPI_MakeVertex.hxx>
132 #include <BRepClass_FaceClassifier.hxx>
133 #include <BRepClass3d_SolidClassifier.hxx>
134 #include <Precision.hxx>
136 //=============================================================================
140 //=============================================================================
141 GEOMImpl_IShapesOperations::GEOMImpl_IShapesOperations (GEOM_Engine* theEngine, int theDocID)
142 : GEOM_IOperations(theEngine, theDocID)
144 MESSAGE("GEOMImpl_IShapesOperations::GEOMImpl_IShapesOperations");
147 //=============================================================================
151 //=============================================================================
152 GEOMImpl_IShapesOperations::~GEOMImpl_IShapesOperations()
154 MESSAGE("GEOMImpl_IShapesOperations::~GEOMImpl_IShapesOperations");
157 //=============================================================================
161 //=============================================================================
162 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeEdge
163 (Handle(GEOM_Object) thePnt1, Handle(GEOM_Object) thePnt2)
167 if (thePnt1.IsNull() || thePnt2.IsNull()) return NULL;
169 //Add a new Edge object
170 Handle(GEOM_Object) anEdge = GetEngine()->AddObject(GetDocID(), GEOM_EDGE);
172 //Add a new Vector function
173 Handle(GEOM_Function) aFunction =
174 anEdge->AddFunction(GEOMImpl_VectorDriver::GetID(), VECTOR_TWO_PNT);
176 //Check if the function is set correctly
177 if (aFunction->GetDriverGUID() != GEOMImpl_VectorDriver::GetID()) return NULL;
179 GEOMImpl_IVector aPI (aFunction);
181 Handle(GEOM_Function) aRef1 = thePnt1->GetLastFunction();
182 Handle(GEOM_Function) aRef2 = thePnt2->GetLastFunction();
183 if (aRef1.IsNull() || aRef2.IsNull()) return NULL;
185 aPI.SetPoint1(aRef1);
186 aPI.SetPoint2(aRef2);
188 //Compute the Edge value
190 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
193 if (!GetSolver()->ComputeFunction(aFunction)) {
194 SetErrorCode("Vector driver failed");
198 catch (Standard_Failure) {
199 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
200 SetErrorCode(aFail->GetMessageString());
204 //Make a Python command
205 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdge("
206 << thePnt1 << ", " << thePnt2 << ")";
212 //=============================================================================
216 //=============================================================================
217 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeWire
218 (std::list<Handle(GEOM_Object)> theShapes,
219 const Standard_Real theTolerance)
224 Handle(GEOM_Object) aWire = GetEngine()->AddObject(GetDocID(), GEOM_WIRE);
227 Handle(GEOM_Function) aFunction =
228 aWire->AddFunction(GEOMImpl_ShapeDriver::GetID(), WIRE_EDGES);
229 if (aFunction.IsNull()) return NULL;
231 //Check if the function is set correctly
232 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
234 GEOMImpl_IShapes aCI (aFunction);
235 aCI.SetTolerance(theTolerance);
237 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
240 std::list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
241 for (; it != theShapes.end(); it++) {
242 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
243 if (aRefSh.IsNull()) {
244 SetErrorCode("NULL argument shape for the shape construction");
247 aShapesSeq->Append(aRefSh);
249 aCI.SetShapes(aShapesSeq);
253 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
256 if (!GetSolver()->ComputeFunction(aFunction)) {
257 SetErrorCode("Shape driver failed");
261 catch (Standard_Failure) {
262 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
263 SetErrorCode(aFail->GetMessageString());
267 //Make a Python command
268 GEOM::TPythonDump pd (aFunction);
269 pd << aWire << " = geompy.MakeWire([";
272 it = theShapes.begin();
273 if (it != theShapes.end()) {
275 while (it != theShapes.end()) {
276 pd << ", " << (*it++);
279 pd << "], " << theTolerance << ")";
285 //=============================================================================
289 //=============================================================================
290 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFace (Handle(GEOM_Object) theWire,
291 const bool isPlanarWanted)
295 if (theWire.IsNull()) return NULL;
297 //Add a new Face object
298 Handle(GEOM_Object) aFace = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
300 //Add a new Shape function for creation of a face from a wire
301 Handle(GEOM_Function) aFunction =
302 aFace->AddFunction(GEOMImpl_ShapeDriver::GetID(), FACE_WIRE);
303 if (aFunction.IsNull()) return NULL;
305 //Check if the function is set correctly
306 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
308 GEOMImpl_IShapes aCI (aFunction);
310 Handle(GEOM_Function) aRefWire = theWire->GetLastFunction();
312 if (aRefWire.IsNull()) return NULL;
314 aCI.SetBase(aRefWire);
315 aCI.SetIsPlanar(isPlanarWanted);
317 //Compute the Face value
319 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
322 if (!GetSolver()->ComputeFunction(aFunction)) {
323 SetErrorCode("Shape driver failed to compute a face");
327 catch (Standard_Failure) {
328 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
329 SetErrorCode(aFail->GetMessageString());
333 //Make a Python command
334 GEOM::TPythonDump(aFunction) << aFace << " = geompy.MakeFace("
335 << theWire << ", " << (int)isPlanarWanted << ")";
341 //=============================================================================
345 //=============================================================================
346 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFaceWires
347 (std::list<Handle(GEOM_Object)> theShapes,
348 const bool isPlanarWanted)
353 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
356 Handle(GEOM_Function) aFunction =
357 aShape->AddFunction(GEOMImpl_ShapeDriver::GetID(), FACE_WIRES);
358 if (aFunction.IsNull()) return NULL;
360 //Check if the function is set correctly
361 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
363 GEOMImpl_IShapes aCI (aFunction);
365 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
368 std::list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
369 for (; it != theShapes.end(); it++) {
370 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
371 if (aRefSh.IsNull()) {
372 SetErrorCode("NULL argument shape for the face construction");
375 aShapesSeq->Append(aRefSh);
377 aCI.SetShapes(aShapesSeq);
379 aCI.SetIsPlanar(isPlanarWanted);
383 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
386 if (!GetSolver()->ComputeFunction(aFunction)) {
387 SetErrorCode("Shape driver failed");
391 catch (Standard_Failure) {
392 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
393 SetErrorCode(aFail->GetMessageString());
397 //Make a Python command
398 GEOM::TPythonDump pd (aFunction);
399 pd << aShape << " = geompy.MakeFaceWires([";
402 it = theShapes.begin();
403 if (it != theShapes.end()) {
405 while (it != theShapes.end()) {
406 pd << ", " << (*it++);
409 pd << "], " << (int)isPlanarWanted << ")";
415 //=============================================================================
419 //=============================================================================
420 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeShell
421 (std::list<Handle(GEOM_Object)> theShapes)
423 return MakeShape(theShapes, GEOM_SHELL, SHELL_FACES, "MakeShell");
426 //=============================================================================
430 //=============================================================================
431 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeSolidShells
432 (std::list<Handle(GEOM_Object)> theShapes)
434 return MakeShape(theShapes, GEOM_SOLID, SOLID_SHELLS, "MakeSolid");
437 //=============================================================================
441 //=============================================================================
442 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeSolidShell (Handle(GEOM_Object) theShell)
446 if (theShell.IsNull()) return NULL;
448 //Add a new Solid object
449 Handle(GEOM_Object) aSolid = GetEngine()->AddObject(GetDocID(), GEOM_SOLID);
451 //Add a new Solid function for creation of a solid from a shell
452 Handle(GEOM_Function) aFunction =
453 aSolid->AddFunction(GEOMImpl_ShapeDriver::GetID(), SOLID_SHELL);
454 if (aFunction.IsNull()) return NULL;
456 //Check if the function is set correctly
457 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
459 GEOMImpl_IShapes aCI (aFunction);
461 Handle(GEOM_Function) aRefShell = theShell->GetLastFunction();
463 if (aRefShell.IsNull()) return NULL;
465 aCI.SetBase(aRefShell);
467 //Compute the Solid value
469 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
472 if (!GetSolver()->ComputeFunction(aFunction)) {
473 SetErrorCode("Solid driver failed");
477 catch (Standard_Failure) {
478 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
479 SetErrorCode(aFail->GetMessageString());
483 //Make a Python command
484 GEOM::TPythonDump(aFunction) << aSolid
485 << " = geompy.MakeSolid(" << theShell << ")";
491 //=============================================================================
495 //=============================================================================
496 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeCompound
497 (std::list<Handle(GEOM_Object)> theShapes)
499 return MakeShape(theShapes, GEOM_COMPOUND, COMPOUND_SHAPES, "MakeCompound");
502 //=============================================================================
506 //=============================================================================
507 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeShape
508 (std::list<Handle(GEOM_Object)> theShapes,
509 const Standard_Integer theObjectType,
510 const Standard_Integer theFunctionType,
511 const TCollection_AsciiString& theMethodName)
516 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), theObjectType);
519 Handle(GEOM_Function) aFunction =
520 aShape->AddFunction(GEOMImpl_ShapeDriver::GetID(), theFunctionType);
521 if (aFunction.IsNull()) return NULL;
523 //Check if the function is set correctly
524 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
526 GEOMImpl_IShapes aCI (aFunction);
528 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
531 std::list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
532 for (; it != theShapes.end(); it++) {
533 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
534 if (aRefSh.IsNull()) {
535 SetErrorCode("NULL argument shape for the shape construction");
538 aShapesSeq->Append(aRefSh);
540 aCI.SetShapes(aShapesSeq);
544 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
547 if (!GetSolver()->ComputeFunction(aFunction)) {
548 SetErrorCode("Shape driver failed");
552 catch (Standard_Failure) {
553 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
554 SetErrorCode(aFail->GetMessageString());
558 //Make a Python command
559 GEOM::TPythonDump pd (aFunction);
560 pd << aShape << " = geompy." << theMethodName.ToCString() << "([";
563 it = theShapes.begin();
564 if (it != theShapes.end()) {
566 while (it != theShapes.end()) {
567 pd << ", " << (*it++);
576 //=============================================================================
580 //=============================================================================
581 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeGlueFaces
582 (Handle(GEOM_Object) theShape,
583 const Standard_Real theTolerance,
584 const Standard_Boolean doKeepNonSolids)
588 if (theShape.IsNull()) return NULL;
590 //Add a new Glued object
591 Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
593 //Add a new Glue function
594 Handle(GEOM_Function) aFunction;
595 aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_FACES);
596 if (aFunction.IsNull()) return NULL;
598 //Check if the function is set correctly
599 if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
601 GEOMImpl_IGlue aCI (aFunction);
603 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
604 if (aRefShape.IsNull()) return NULL;
606 aCI.SetBase(aRefShape);
607 aCI.SetTolerance(theTolerance);
608 aCI.SetKeepNonSolids(doKeepNonSolids);
610 //Compute the sub-shape value
611 Standard_Boolean isWarning = Standard_False;
613 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
616 if (!GetSolver()->ComputeFunction(aFunction)) {
617 SetErrorCode("Shape driver failed to glue faces");
621 catch (Standard_Failure) {
622 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
623 SetErrorCode(aFail->GetMessageString());
624 // to provide warning
625 if (!aFunction->GetValue().IsNull()) {
626 isWarning = Standard_True;
632 //Make a Python command
633 GEOM::TPythonDump(aFunction) << aGlued << " = geompy.MakeGlueFaces("
634 << theShape << ", " << theTolerance << ")";
636 // to provide warning
637 if (!isWarning) SetErrorCode(OK);
641 //=============================================================================
645 //=============================================================================
646 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetGlueFaces
647 (Handle(GEOM_Object) theShape,
648 const Standard_Real theTolerance)
652 if (theShape.IsNull()) return NULL;
653 TopoDS_Shape aShape = theShape->GetValue();
654 if (aShape.IsNull()) return NULL;
656 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
658 Standard_Integer iErr;
660 GEOMAlgo_Gluer1 aGluer;
661 GEOMAlgo_ListIteratorOfListOfCoupleOfShapes aItCS;
662 GEOMAlgo_CoupleOfShapes aCS;
663 GEOMAlgo_ListOfCoupleOfShapes aLCS;
665 //aGluer = new GEOMAlgo_Gluer1;
666 aGluer.SetShape(aShape);
667 aGluer.SetTolerance(theTolerance);
669 iErr = aGluer.ErrorStatus();
670 if (iErr) return NULL;
672 TopTools_ListOfShape listShape;
673 const GEOMAlgo_ListOfCoupleOfShapes& aLCSG = aGluer.GluedFaces();
675 aItCS.Initialize(aLCSG);
676 for (; aItCS.More(); aItCS.Next()) {
677 const GEOMAlgo_CoupleOfShapes& aCSG = aItCS.Value();
678 listShape.Append(aCSG.Shape1());
681 TopTools_ListIteratorOfListOfShape itSub (listShape);
682 TCollection_AsciiString anAsciiList, anEntry;
683 TopTools_IndexedMapOfShape anIndices;
684 TopExp::MapShapes(aShape, anIndices);
685 Handle(TColStd_HArray1OfInteger) anArray;
686 Handle(GEOM_Object) anObj;
687 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
688 TopoDS_Shape aValue = itSub.Value();
689 anArray = new TColStd_HArray1OfInteger(1,1);
690 anArray->SetValue(1, anIndices.FindIndex(aValue));
691 anObj = GetEngine()->AddSubShape(theShape, anArray);
692 if (!anObj.IsNull()) {
695 // for python command
696 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
697 anAsciiList += anEntry;
702 //Make a Python command
703 if( anAsciiList.Length() > 0 ) {
704 anAsciiList.Trunc(anAsciiList.Length() - 1);
705 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
706 GEOM::TPythonDump pd (aFunction, /*append=*/true);
707 pd << "[" << anAsciiList.ToCString();
708 pd << "] = geompy.GetGlueFaces(" << theShape << ", " << theTolerance << ")";
716 //=============================================================================
718 * MakeGlueFacesByList
720 //=============================================================================
721 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeGlueFacesByList
722 (Handle(GEOM_Object) theShape,
723 const Standard_Real theTolerance,
724 std::list<Handle(GEOM_Object)> theFaces,
725 const Standard_Boolean doKeepNonSolids)
729 if (theShape.IsNull()) return NULL;
731 //Add a new Glued object
732 Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
734 //Add a new Glue function
735 Handle(GEOM_Function) aFunction;
736 aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_FACES_BY_LIST);
737 if (aFunction.IsNull()) return NULL;
739 //Check if the function is set correctly
740 if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
742 GEOMImpl_IGlue aCI (aFunction);
744 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
745 if (aRefShape.IsNull()) return NULL;
747 aCI.SetBase(aRefShape);
748 aCI.SetTolerance(theTolerance);
749 aCI.SetKeepNonSolids(doKeepNonSolids);
751 Handle(TColStd_HSequenceOfTransient) aFaces = new TColStd_HSequenceOfTransient;
752 std::list<Handle(GEOM_Object)>::iterator it = theFaces.begin();
753 for (; it != theFaces.end(); it++) {
754 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
755 if (aRefSh.IsNull()) {
756 SetErrorCode("NULL argument shape for the shape construction");
759 aFaces->Append(aRefSh);
761 aCI.SetFaces(aFaces);
763 //Compute the sub-shape value
764 Standard_Boolean isWarning = Standard_False;
766 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
769 if (!GetSolver()->ComputeFunction(aFunction)) {
770 SetErrorCode("Shape driver failed to glue faces");
774 catch (Standard_Failure) {
775 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
776 SetErrorCode(aFail->GetMessageString());
777 // to provide warning
778 if (!aFunction->GetValue().IsNull()) {
779 isWarning = Standard_True;
785 //Make a Python command
787 GEOM::TPythonDump pd(aFunction);
788 pd << aGlued << " = geompy.MakeGlueFacesByList("
789 << theShape << ", " << theTolerance << ", [";
791 it = theFaces.begin();
792 if (it != theFaces.end()) {
794 while (it != theFaces.end()) {
795 pd << ", " << (*it++);
800 // to provide warning
801 if (!isWarning) SetErrorCode(OK);
805 //=============================================================================
809 //=============================================================================
810 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::MakeExplode
811 (Handle(GEOM_Object) theShape,
812 const Standard_Integer theShapeType,
813 const Standard_Boolean isSorted)
817 if (theShape.IsNull()) return NULL;
818 TopoDS_Shape aShape = theShape->GetValue();
819 if (aShape.IsNull()) return NULL;
821 Handle(GEOM_Function) aMainShape = theShape->GetLastFunction();
823 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
824 Handle(GEOM_Object) anObj;
825 TopTools_MapOfShape mapShape;
826 TopTools_ListOfShape listShape;
828 if (aShape.ShapeType() == TopAbs_COMPOUND &&
829 (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
830 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPSOLID ||
831 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPOUND)) {
832 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
833 for (; It.More(); It.Next()) {
834 if (mapShape.Add(It.Value())) {
835 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
836 TopAbs_ShapeEnum(theShapeType) == It.Value().ShapeType()) {
837 listShape.Append(It.Value());
842 TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
843 for (; exp.More(); exp.Next())
844 if (mapShape.Add(exp.Current()))
845 listShape.Append(exp.Current());
848 if (listShape.IsEmpty()) {
849 //SetErrorCode("The given shape has no sub-shapes of the requested type");
850 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
855 SortShapes(listShape);
857 TopTools_IndexedMapOfShape anIndices;
858 TopExp::MapShapes(aShape, anIndices);
859 Handle(TColStd_HArray1OfInteger) anArray;
861 TopTools_ListIteratorOfListOfShape itSub (listShape);
862 TCollection_AsciiString anAsciiList, anEntry;
863 for (int index = 1; itSub.More(); itSub.Next(), ++index)
865 TopoDS_Shape aValue = itSub.Value();
866 anArray = new TColStd_HArray1OfInteger(1,1);
867 anArray->SetValue(1, anIndices.FindIndex(aValue));
869 //anObj = GetEngine()->AddSubShape(theShape, anArray);
871 anObj = GetEngine()->AddObject(GetDocID(), GEOM_SUBSHAPE);
872 Handle(GEOM_Function) aFunction = anObj->AddFunction(GEOM_Object::GetSubShapeID(), 1);
873 if (aFunction.IsNull()) return aSeq;
875 GEOM_ISubShape aSSI (aFunction);
876 aSSI.SetMainShape(aMainShape);
877 aSSI.SetIndices(anArray);
879 // Set function value directly, as we know it.
880 // Usage of Solver here would lead to significant loss of time,
881 // because GEOM_SubShapeDriver will build TopTools_IndexedMapOfShape
882 // on the main shape for each being calculated sub-shape separately.
883 aFunction->SetValue(aValue);
886 if (!anObj.IsNull()) {
889 // for python command
890 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
891 anAsciiList += anEntry;
896 //Make a Python command
897 anAsciiList.Trunc(anAsciiList.Length() - 1);
899 GEOM::TPythonDump pd (aMainShape, /*append=*/true);
900 pd << "[" << anAsciiList.ToCString();
901 pd << "] = geompy.SubShapeAll" << (isSorted ? "Sorted(" : "(");
902 pd << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
909 //=============================================================================
913 //=============================================================================
914 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::SubShapeAllIDs
915 (Handle(GEOM_Object) theShape,
916 const Standard_Integer theShapeType,
917 const Standard_Boolean isSorted)
921 if (theShape.IsNull()) return NULL;
922 TopoDS_Shape aShape = theShape->GetValue();
923 if (aShape.IsNull()) return NULL;
925 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
926 TopTools_MapOfShape mapShape;
927 TopTools_ListOfShape listShape;
929 if (aShape.ShapeType() == TopAbs_COMPOUND &&
930 (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
931 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPSOLID ||
932 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPOUND)) {
933 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
934 for (; It.More(); It.Next()) {
935 if (mapShape.Add(It.Value())) {
936 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
937 TopAbs_ShapeEnum(theShapeType) == It.Value().ShapeType()) {
938 listShape.Append(It.Value());
943 TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
944 for (; exp.More(); exp.Next())
945 if (mapShape.Add(exp.Current()))
946 listShape.Append(exp.Current());
949 if (listShape.IsEmpty()) {
950 //SetErrorCode("The given shape has no sub-shapes of the requested type");
951 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
956 SortShapes(listShape);
958 TopTools_IndexedMapOfShape anIndices;
959 TopExp::MapShapes(aShape, anIndices);
960 Handle(TColStd_HArray1OfInteger) anArray;
962 TopTools_ListIteratorOfListOfShape itSub (listShape);
963 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
964 TopoDS_Shape aValue = itSub.Value();
965 aSeq->Append(anIndices.FindIndex(aValue));
968 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
970 //Make a Python command
971 GEOM::TPythonDump pd (aFunction, /*append=*/true);
972 pd << "listSubShapeIDs = geompy.SubShapeAll";
973 pd << (isSorted ? "SortedIDs(" : "IDs(");
974 pd << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
980 //=============================================================================
984 //=============================================================================
985 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetSubShape
986 (Handle(GEOM_Object) theMainShape,
987 const Standard_Integer theID)
991 if (theMainShape.IsNull()) return NULL;
993 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
994 anArray->SetValue(1, theID);
995 Handle(GEOM_Object) anObj = GetEngine()->AddSubShape(theMainShape, anArray,true);
996 if (anObj.IsNull()) {
997 SetErrorCode("Can not get a sub-shape with the given ID");
1001 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1003 //Make a Python command
1004 GEOM::TPythonDump(aFunction) << anObj << " = geompy.GetSubShape("
1005 << theMainShape << ", [" << theID << "])";
1011 //=============================================================================
1015 //=============================================================================
1016 Standard_Integer GEOMImpl_IShapesOperations::GetSubShapeIndex (Handle(GEOM_Object) theMainShape,
1017 Handle(GEOM_Object) theSubShape)
1021 TopoDS_Shape aMainShape = theMainShape->GetValue();
1022 TopoDS_Shape aSubShape = theSubShape->GetValue();
1024 if (aMainShape.IsNull() || aSubShape.IsNull()) return -1;
1026 TopTools_IndexedMapOfShape anIndices;
1027 TopExp::MapShapes(aMainShape, anIndices);
1028 if (anIndices.Contains(aSubShape)) {
1030 return anIndices.FindIndex(aSubShape);
1036 //=============================================================================
1040 //=============================================================================
1041 Standard_Integer GEOMImpl_IShapesOperations::GetTopologyIndex (Handle(GEOM_Object) theMainShape,
1042 Handle(GEOM_Object) theSubShape)
1046 TopoDS_Shape aMainShape = theMainShape->GetValue();
1047 TopoDS_Shape aSubShape = theSubShape->GetValue();
1049 if (aMainShape.IsNull() || aSubShape.IsNull()) {
1050 SetErrorCode("Null argument shape given");
1055 if (aSubShape.ShapeType() == TopAbs_COMPOUND) {
1057 TopTools_ListOfShape CL;
1058 CL.Append(aMainShape);
1059 TopTools_ListIteratorOfListOfShape itC;
1060 for (itC.Initialize(CL); itC.More(); itC.Next()) {
1061 for (it.Initialize(itC.Value()); it.More(); it.Next()) {
1062 if (it.Value().ShapeType() == TopAbs_COMPOUND) {
1063 if (it.Value().IsSame(aSubShape))
1067 CL.Append(it.Value());
1072 TopExp_Explorer anExp (aMainShape, aSubShape.ShapeType());
1073 TopTools_MapOfShape M;
1074 for (; anExp.More(); anExp.Next()) {
1075 if (M.Add(anExp.Current())) {
1076 if (anExp.Current().IsSame(aSubShape))
1083 SetErrorCode("The sub-shape does not belong to the main shape");
1087 //=============================================================================
1089 * GetShapeTypeString
1091 //=============================================================================
1092 TCollection_AsciiString GEOMImpl_IShapesOperations::GetShapeTypeString (Handle(GEOM_Object) theShape)
1096 TCollection_AsciiString aTypeName ("Null Shape");
1098 TopoDS_Shape aShape = theShape->GetValue();
1099 if (aShape.IsNull())
1102 switch (aShape.ShapeType() )
1104 case TopAbs_COMPOUND:
1105 aTypeName = "Compound";
1107 case TopAbs_COMPSOLID:
1108 aTypeName = "Compound Solid";
1111 aTypeName = "Solid";
1114 aTypeName = "Shell";
1118 BRepAdaptor_Surface surf (TopoDS::Face(aShape));
1119 if (surf.GetType() == GeomAbs_Plane)
1120 aTypeName = "Plane";
1121 else if (surf.GetType() == GeomAbs_Cylinder)
1122 aTypeName = "Cylindrical Face";
1123 else if (surf.GetType() == GeomAbs_Sphere)
1124 aTypeName = "Spherical Face";
1125 else if (surf.GetType() == GeomAbs_Torus)
1126 aTypeName = "Toroidal Face";
1127 else if (surf.GetType() == GeomAbs_Cone)
1128 aTypeName = "Conical Face";
1130 aTypeName = "GEOM::FACE";
1138 BRepAdaptor_Curve curv (TopoDS::Edge(aShape));
1139 if (curv.GetType() == GeomAbs_Line) {
1140 if ((Abs(curv.FirstParameter()) >= 1E6) ||
1141 (Abs(curv.LastParameter()) >= 1E6))
1145 } else if (curv.GetType() == GeomAbs_Circle) {
1146 if (curv.IsClosed())
1147 aTypeName = "Circle";
1156 aTypeName = "Vertex";
1159 aTypeName = "Shape";
1162 aTypeName = "Shape of unknown type";
1168 //=============================================================================
1172 //=============================================================================
1173 Standard_Integer GEOMImpl_IShapesOperations::NumberOfSubShapes
1174 (Handle(GEOM_Object) theShape,
1175 const Standard_Integer theShapeType)
1178 Standard_Integer nbShapes = 0;
1180 if (theShape.IsNull()) return -1;
1181 TopoDS_Shape aShape = theShape->GetValue();
1182 if (aShape.IsNull()) return -1;
1185 TopTools_MapOfShape mapShape;
1187 if (aShape.ShapeType() == TopAbs_COMPOUND &&
1188 (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
1189 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPSOLID ||
1190 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPOUND)) {
1191 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
1192 for (; It.More(); It.Next()) {
1193 if (mapShape.Add(It.Value())) {
1194 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
1195 TopAbs_ShapeEnum(theShapeType) == It.Value().ShapeType()) {
1201 TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
1202 for (; exp.More(); exp.Next())
1203 if (mapShape.Add(exp.Current()))
1209 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
1212 int iType, nbTypes [TopAbs_SHAPE];
1213 for (iType = 0; iType < TopAbs_SHAPE; ++iType)
1215 nbTypes[aShape.ShapeType()]++;
1217 TopTools_MapOfShape aMapOfShape;
1218 aMapOfShape.Add(aShape);
1219 TopTools_ListOfShape aListOfShape;
1220 aListOfShape.Append(aShape);
1222 TopTools_ListIteratorOfListOfShape itL (aListOfShape);
1223 for (; itL.More(); itL.Next()) {
1224 TopoDS_Iterator it (itL.Value());
1225 for (; it.More(); it.Next()) {
1226 TopoDS_Shape s = it.Value();
1227 if (aMapOfShape.Add(s)) {
1228 aListOfShape.Append(s);
1229 nbTypes[s.ShapeType()]++;
1234 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE)
1235 nbShapes = aMapOfShape.Extent();
1237 nbShapes = nbTypes[theShapeType];
1239 catch (Standard_Failure) {
1240 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1241 SetErrorCode(aFail->GetMessageString());
1249 //=============================================================================
1253 //=============================================================================
1254 Handle(GEOM_Object) GEOMImpl_IShapesOperations::ReverseShape(Handle(GEOM_Object) theShape)
1258 if (theShape.IsNull()) return NULL;
1260 //Add a new reversed object
1261 Handle(GEOM_Object) aReversed = GetEngine()->AddObject(GetDocID(), theShape->GetType());
1263 //Add a new Revese function
1264 Handle(GEOM_Function) aFunction;
1265 aFunction = aReversed->AddFunction(GEOMImpl_ShapeDriver::GetID(), REVERSE_ORIENTATION);
1266 if (aFunction.IsNull()) return NULL;
1268 //Check if the function is set correctly
1269 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
1271 GEOMImpl_IShapes aSI (aFunction);
1273 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
1274 if (aRefShape.IsNull()) return NULL;
1276 aSI.SetBase(aRefShape);
1278 //Compute the sub-shape value
1280 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
1283 if (!GetSolver()->ComputeFunction(aFunction)) {
1284 SetErrorCode("Shape driver failed to reverse shape");
1288 catch (Standard_Failure) {
1289 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1290 SetErrorCode(aFail->GetMessageString());
1294 //Make a Python command
1295 GEOM::TPythonDump(aFunction) << aReversed
1296 << " = geompy.ChangeOrientation(" << theShape << ")";
1302 //=============================================================================
1306 //=============================================================================
1307 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetFreeFacesIDs
1308 (Handle(GEOM_Object) theShape)
1312 if (theShape.IsNull()) return NULL;
1313 TopoDS_Shape aShape = theShape->GetValue();
1314 if (aShape.IsNull()) return NULL;
1316 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
1318 TopTools_IndexedDataMapOfShapeListOfShape mapFaceBlocks;
1319 GEOMImpl_Block6Explorer::MapShapesAndAncestors
1320 (aShape, TopAbs_FACE, TopAbs_SOLID, mapFaceBlocks);
1322 Standard_Integer ind = 1, nbFaces = mapFaceBlocks.Extent();
1325 SetErrorCode("The given shape has no faces");
1329 TopTools_IndexedMapOfShape anIndices;
1330 TopExp::MapShapes(aShape, anIndices);
1332 Standard_Integer id;
1333 for (; ind <= nbFaces; ind++) {
1334 if (mapFaceBlocks.FindFromIndex(ind).Extent() != 2) {
1335 id = anIndices.FindIndex(mapFaceBlocks.FindKey(ind));
1340 //The explode doesn't change object so no new function is required.
1341 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
1343 //Make a Python command
1344 GEOM::TPythonDump(aFunction, /*append=*/true)
1345 << "listFreeFacesIDs = geompy.GetFreeFacesIDs(" << theShape << ")";
1351 //=======================================================================
1352 //function : GetSharedShapes
1354 //=======================================================================
1355 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetSharedShapes
1356 (Handle(GEOM_Object) theShape1,
1357 Handle(GEOM_Object) theShape2,
1358 const Standard_Integer theShapeType)
1362 if (theShape1.IsNull() || theShape2.IsNull()) return NULL;
1364 TopoDS_Shape aShape1 = theShape1->GetValue();
1365 TopoDS_Shape aShape2 = theShape2->GetValue();
1367 if (aShape1.IsNull() || aShape2.IsNull()) return NULL;
1369 TopTools_IndexedMapOfShape anIndices;
1370 TopExp::MapShapes(aShape1, anIndices);
1371 Handle(TColStd_HArray1OfInteger) anArray;
1373 TopTools_IndexedMapOfShape mapShape1;
1374 TopExp::MapShapes(aShape1, TopAbs_ShapeEnum(theShapeType), mapShape1);
1376 Handle(GEOM_Object) anObj;
1377 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1378 TCollection_AsciiString anAsciiList, anEntry;
1380 TopTools_MapOfShape mapShape2;
1381 TopExp_Explorer exp (aShape2, TopAbs_ShapeEnum(theShapeType));
1382 for (; exp.More(); exp.Next()) {
1383 TopoDS_Shape aSS = exp.Current();
1384 if (mapShape2.Add(aSS) && mapShape1.Contains(aSS)) {
1385 anArray = new TColStd_HArray1OfInteger(1,1);
1386 anArray->SetValue(1, anIndices.FindIndex(aSS));
1387 anObj = GetEngine()->AddSubShape(theShape1, anArray);
1388 aSeq->Append(anObj);
1390 // for python command
1391 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
1392 anAsciiList += anEntry;
1397 if (aSeq->IsEmpty()) {
1398 SetErrorCode("The given shapes have no shared sub-shapes of the requested type");
1402 //Make a Python command
1403 anAsciiList.Trunc(anAsciiList.Length() - 1);
1405 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1407 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
1408 << "] = geompy.GetSharedShapes(" << theShape1 << ", "
1409 << theShape2 << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
1415 //=============================================================================
1419 //=============================================================================
1420 static GEOM::TPythonDump& operator<< (GEOM::TPythonDump& theDump,
1421 const GEOMAlgo_State theState)
1424 case GEOMAlgo_ST_IN:
1425 theDump << "geompy.GEOM.ST_IN";
1427 case GEOMAlgo_ST_OUT:
1428 theDump << "geompy.GEOM.ST_OUT";
1430 case GEOMAlgo_ST_ON:
1431 theDump << "geompy.GEOM.ST_ON";
1433 case GEOMAlgo_ST_ONIN:
1434 theDump << "geompy.GEOM.ST_ONIN";
1436 case GEOMAlgo_ST_ONOUT:
1437 theDump << "geompy.GEOM.ST_ONOUT";
1440 theDump << "geompy.GEOM.ST_UNKNOWN";
1446 //=======================================================================
1447 //function : checkTypeShapesOn
1449 * \brief Checks if theShapeType parameter of GetShapesOnXXX() is OK
1450 * \param theShapeType - the shape type to check
1451 * \retval bool - result of the check
1453 //=======================================================================
1454 bool GEOMImpl_IShapesOperations::checkTypeShapesOn(const Standard_Integer theShapeType)
1456 if (theShapeType != TopAbs_VERTEX &&
1457 theShapeType != TopAbs_EDGE &&
1458 theShapeType != TopAbs_FACE &&
1459 theShapeType != TopAbs_SOLID) {
1460 SetErrorCode("Only solids, vertices, edges or faces can be found by this method");
1466 //=======================================================================
1467 //function : makePlane
1469 * \brief Creates Geom_Plane
1470 * \param theAx1 - shape object defining plane parameters
1471 * \retval Handle(Geom_Surface) - resulting surface
1473 //=======================================================================
1474 Handle(Geom_Surface) GEOMImpl_IShapesOperations::makePlane(const TopoDS_Shape& anAx1)
1476 if (anAx1.ShapeType() != TopAbs_EDGE) return NULL;
1477 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
1478 TopoDS_Vertex V1, V2;
1479 TopExp::Vertices(anEdge, V1, V2, Standard_True);
1480 if (V1.IsNull() || V2.IsNull()) {
1481 SetErrorCode("Bad edge given for the plane normal vector");
1484 gp_Pnt aLoc = BRep_Tool::Pnt(V1);
1485 gp_Vec aVec (aLoc, BRep_Tool::Pnt(V2));
1486 if (aVec.Magnitude() < Precision::Confusion()) {
1487 SetErrorCode("Vector with null magnitude given");
1490 return new Geom_Plane(aLoc, aVec);
1493 //=======================================================================
1494 //function : makeCylinder
1496 * \brief Creates Geom_CylindricalSurface
1497 * \param theAx1 - edge defining cylinder axis
1498 * \param theRadius - cylinder radius
1499 * \retval Handle(Geom_Surface) - resulting surface
1501 //=======================================================================
1502 Handle(Geom_Surface) GEOMImpl_IShapesOperations::makeCylinder(const TopoDS_Shape& anAxis,
1503 const Standard_Real theRadius)
1505 //Axis of the cylinder
1506 if (anAxis.ShapeType() != TopAbs_EDGE) {
1507 SetErrorCode("Not an edge given for the axis");
1510 TopoDS_Edge anEdge = TopoDS::Edge(anAxis);
1511 TopoDS_Vertex V1, V2;
1512 TopExp::Vertices(anEdge, V1, V2, Standard_True);
1513 if (V1.IsNull() || V2.IsNull()) {
1514 SetErrorCode("Bad edge given for the axis");
1517 gp_Pnt aLoc = BRep_Tool::Pnt(V1);
1518 gp_Vec aVec (aLoc, BRep_Tool::Pnt(V2));
1519 if (aVec.Magnitude() < Precision::Confusion()) {
1520 SetErrorCode("Vector with null magnitude given");
1524 gp_Ax3 anAx3 (aLoc, aVec);
1525 return new Geom_CylindricalSurface(anAx3, theRadius);
1528 //=======================================================================
1529 //function : getShapesOnBoxIDs
1531 * \brief Find IDs of subshapes complying with given status about surface
1532 * \param theBox - the box to check state of subshapes against
1533 * \param theShape - the shape to explore
1534 * \param theShapeType - type of subshape of theShape
1535 * \param theState - required state
1536 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1538 //=======================================================================
1539 Handle(TColStd_HSequenceOfInteger)
1540 GEOMImpl_IShapesOperations::getShapesOnBoxIDs(const Handle(GEOM_Object)& theBox,
1541 const Handle(GEOM_Object)& theShape,
1542 const Standard_Integer theShapeType,
1543 GEOMAlgo_State theState)
1545 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
1547 TopoDS_Shape aBox = theBox->GetValue();
1548 TopoDS_Shape aShape = theShape->GetValue();
1550 // Check presence of triangulation, build if need
1551 if (!CheckTriangulation(aShape)) {
1552 SetErrorCode("Cannot build triangulation on the shape");
1557 GEOMAlgo_FinderShapeOn2 aFinder;
1558 Standard_Real aTol = 0.0001; // default value
1560 Handle(GEOMAlgo_ClsfBox) aClsfBox = new GEOMAlgo_ClsfBox;
1561 aClsfBox->SetBox(aBox);
1563 aFinder.SetShape(aShape);
1564 aFinder.SetTolerance(aTol);
1565 aFinder.SetClsf(aClsfBox);
1566 aFinder.SetShapeType( (TopAbs_ShapeEnum)theShapeType );
1567 aFinder.SetState(theState);
1570 // Interprete results
1571 Standard_Integer iErr = aFinder.ErrorStatus();
1572 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
1574 MESSAGE(" iErr : " << iErr);
1575 TCollection_AsciiString aMsg (" iErr : ");
1576 aMsg += TCollection_AsciiString(iErr);
1580 Standard_Integer iWrn = aFinder.WarningStatus();
1581 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
1583 MESSAGE(" *** iWrn : " << iWrn);
1586 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
1588 if (listSS.Extent() < 1) {
1589 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
1590 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
1594 // Fill sequence of object IDs
1595 aSeqOfIDs = new TColStd_HSequenceOfInteger;
1597 TopTools_IndexedMapOfShape anIndices;
1598 TopExp::MapShapes(aShape, anIndices);
1600 TopTools_ListIteratorOfListOfShape itSub (listSS);
1601 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
1602 int id = anIndices.FindIndex(itSub.Value());
1603 aSeqOfIDs->Append(id);
1609 //=======================================================================
1610 //function : GetShapesOnBoxIDs
1612 * \brief Find subshapes complying with given status about surface
1613 * \param theBox - the box to check state of subshapes against
1614 * \param theShape - the shape to explore
1615 * \param theShapeType - type of subshape of theShape
1616 * \param theState - required state
1617 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1619 //=======================================================================
1620 Handle(TColStd_HSequenceOfInteger)
1621 GEOMImpl_IShapesOperations::GetShapesOnBoxIDs(const Handle(GEOM_Object)& theBox,
1622 const Handle(GEOM_Object)& theShape,
1623 const Standard_Integer theShapeType,
1624 GEOMAlgo_State theState)
1626 // Find subshapes ids
1627 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
1628 getShapesOnBoxIDs (theBox, theShape, theShapeType, theState);
1629 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
1632 // The GetShapesOnBox() doesn't change object so no new function is required.
1633 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theBox)->GetLastFunction();
1635 // Make a Python command
1636 GEOM::TPythonDump(aFunction)
1637 << "listShapesOnBoxIDs = geompy.GetShapesOnBoxIDs("
1640 << TopAbs_ShapeEnum(theShapeType) << ", "
1647 //=======================================================================
1648 //function : GetShapesOnBox
1650 * \brief Find subshapes complying with given status about surface
1651 * \param theBox - the box to check state of subshapes against
1652 * \param theShape - the shape to explore
1653 * \param theShapeType - type of subshape of theShape
1654 * \param theState - required state
1655 * \retval Handle(TColStd_HSequenceOfTransient) - found subshapes
1657 //=======================================================================
1658 Handle(TColStd_HSequenceOfTransient)
1659 GEOMImpl_IShapesOperations::GetShapesOnBox(const Handle(GEOM_Object)& theBox,
1660 const Handle(GEOM_Object)& theShape,
1661 const Standard_Integer theShapeType,
1662 GEOMAlgo_State theState)
1664 // Find subshapes ids
1665 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
1666 getShapesOnBoxIDs (theBox, theShape, theShapeType, theState);
1667 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
1670 // Find objects by indices
1671 TCollection_AsciiString anAsciiList;
1672 Handle(TColStd_HSequenceOfTransient) aSeq;
1673 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
1674 if ( aSeq.IsNull() || aSeq->IsEmpty() )
1677 // Make a Python command
1679 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
1680 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1682 GEOM::TPythonDump(aFunction)
1683 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnBox("
1686 << TopAbs_ShapeEnum(theShapeType) << ", "
1693 //=======================================================================
1694 //function : getShapesOnShapeIDs
1696 * \brief Find IDs of subshapes complying with given status about surface
1697 * \param theCheckShape - the shape to check state of subshapes against
1698 * \param theShape - the shape to explore
1699 * \param theShapeType - type of subshape of theShape
1700 * \param theState - required state
1701 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1703 //=======================================================================
1704 Handle(TColStd_HSequenceOfInteger)
1705 GEOMImpl_IShapesOperations::getShapesOnShapeIDs
1706 (const Handle(GEOM_Object)& theCheckShape,
1707 const Handle(GEOM_Object)& theShape,
1708 const Standard_Integer theShapeType,
1709 GEOMAlgo_State theState)
1711 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
1713 TopoDS_Shape aCheckShape = theCheckShape->GetValue();
1714 TopoDS_Shape aShape = theShape->GetValue();
1715 TopTools_ListOfShape res;
1717 // Check presence of triangulation, build if need
1718 if (!CheckTriangulation(aShape)) {
1719 SetErrorCode("Cannot build triangulation on the shape");
1724 GEOMAlgo_FinderShapeOn2 aFinder;
1725 Standard_Real aTol = 0.0001; // default value
1727 Handle(GEOMAlgo_ClsfSolid) aClsfSolid = new GEOMAlgo_ClsfSolid;
1728 aClsfSolid->SetShape(aCheckShape);
1730 aFinder.SetShape(aShape);
1731 aFinder.SetTolerance(aTol);
1732 aFinder.SetClsf(aClsfSolid);
1733 aFinder.SetShapeType( (TopAbs_ShapeEnum)theShapeType );
1734 aFinder.SetState(theState);
1737 // Interprete results
1738 Standard_Integer iErr = aFinder.ErrorStatus();
1739 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
1742 SetErrorCode("theCheckShape must be a solid");
1745 MESSAGE(" iErr : " << iErr);
1746 TCollection_AsciiString aMsg (" iErr : ");
1747 aMsg += TCollection_AsciiString(iErr);
1752 Standard_Integer iWrn = aFinder.WarningStatus();
1753 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
1755 MESSAGE(" *** iWrn : " << iWrn);
1758 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
1760 if (listSS.Extent() < 1) {
1761 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
1762 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
1765 // Fill sequence of object IDs
1766 aSeqOfIDs = new TColStd_HSequenceOfInteger;
1768 TopTools_IndexedMapOfShape anIndices;
1769 TopExp::MapShapes(aShape, anIndices);
1771 TopTools_ListIteratorOfListOfShape itSub (listSS);
1772 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
1773 int id = anIndices.FindIndex(itSub.Value());
1774 aSeqOfIDs->Append(id);
1780 //=======================================================================
1781 //function : GetShapesOnShapeIDs
1783 * \brief Find subshapes complying with given status about surface
1784 * \param theCheckShape - the shape to check state of subshapes against
1785 * \param theShape - the shape to explore
1786 * \param theShapeType - type of subshape of theShape
1787 * \param theState - required state
1788 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1790 //=======================================================================
1791 Handle(TColStd_HSequenceOfInteger)
1792 GEOMImpl_IShapesOperations::GetShapesOnShapeIDs
1793 (const Handle(GEOM_Object)& theCheckShape,
1794 const Handle(GEOM_Object)& theShape,
1795 const Standard_Integer theShapeType,
1796 GEOMAlgo_State theState)
1798 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
1799 getShapesOnShapeIDs (theCheckShape, theShape, theShapeType, theState);
1801 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
1804 // The GetShapesOnShape() doesn't change object so no new function is required.
1805 Handle(GEOM_Function) aFunction =
1806 GEOM::GetCreatedLast(theShape,theCheckShape)->GetLastFunction();
1808 // Make a Python command
1809 GEOM::TPythonDump(aFunction)
1810 << "listShapesOnBoxIDs = geompy.GetShapesOnShapeIDs("
1811 << theCheckShape << ", "
1813 << TopAbs_ShapeEnum(theShapeType) << ", "
1820 //=======================================================================
1821 //function : GetShapesOnShape
1823 * \brief Find subshapes complying with given status about surface
1824 * \param theCheckShape - the shape to check state of subshapes against
1825 * \param theShape - the shape to explore
1826 * \param theShapeType - type of subshape of theShape
1827 * \param theState - required state
1828 * \retval Handle(TColStd_HSequenceOfTransient) - found subshapes
1830 //=======================================================================
1831 Handle(TColStd_HSequenceOfTransient)
1832 GEOMImpl_IShapesOperations::GetShapesOnShape
1833 (const Handle(GEOM_Object)& theCheckShape,
1834 const Handle(GEOM_Object)& theShape,
1835 const Standard_Integer theShapeType,
1836 GEOMAlgo_State theState)
1838 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
1839 getShapesOnShapeIDs (theCheckShape, theShape, theShapeType, theState);
1840 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
1843 // Find objects by indices
1844 TCollection_AsciiString anAsciiList;
1845 Handle(TColStd_HSequenceOfTransient) aSeq;
1846 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
1848 if ( aSeq.IsNull() || aSeq->IsEmpty() )
1851 // Make a Python command
1853 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
1854 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1856 GEOM::TPythonDump(aFunction)
1857 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnShape("
1858 << theCheckShape << ", "
1860 << TopAbs_ShapeEnum(theShapeType) << ", "
1867 //=======================================================================
1868 //function : GetShapesOnShapeAsCompound
1869 //=======================================================================
1870 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetShapesOnShapeAsCompound
1871 (const Handle(GEOM_Object)& theCheckShape,
1872 const Handle(GEOM_Object)& theShape,
1873 const Standard_Integer theShapeType,
1874 GEOMAlgo_State theState)
1876 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
1877 getShapesOnShapeIDs (theCheckShape, theShape, theShapeType, theState);
1879 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
1882 // Find objects by indices
1883 TCollection_AsciiString anAsciiList;
1884 Handle(TColStd_HSequenceOfTransient) aSeq;
1885 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
1887 if ( aSeq.IsNull() || aSeq->IsEmpty() )
1890 TopoDS_Compound aCompound;
1892 B.MakeCompound(aCompound);
1894 for(; i<=aSeq->Length(); i++) {
1895 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(aSeq->Value(i));
1896 TopoDS_Shape aShape_i = anObj->GetValue();
1897 B.Add(aCompound,aShape_i);
1900 //Add a new result object
1901 Handle(GEOM_Object) aRes = GetEngine()->AddObject(GetDocID(), GEOM_SHAPES_ON_SHAPE);
1902 Handle(GEOM_Function) aFunction =
1903 aRes->AddFunction(GEOMImpl_ShapeDriver::GetID(), SHAPES_ON_SHAPE);
1904 aFunction->SetValue(aCompound);
1906 GEOM::TPythonDump(aFunction)
1907 << aRes << " = geompy.GetShapesOnShapeAsCompound("
1908 << theCheckShape << ", "
1910 << TopAbs_ShapeEnum(theShapeType) << ", "
1918 //=======================================================================
1919 //function : getShapesOnSurfaceIDs
1921 * \brief Find IDs of subshapes complying with given status about surface
1922 * \param theSurface - the surface to check state of subshapes against
1923 * \param theShape - the shape to explore
1924 * \param theShapeType - type of subshape of theShape
1925 * \param theState - required state
1926 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1928 //=======================================================================
1929 Handle(TColStd_HSequenceOfInteger)
1930 GEOMImpl_IShapesOperations::getShapesOnSurfaceIDs(const Handle(Geom_Surface)& theSurface,
1931 const TopoDS_Shape& theShape,
1932 TopAbs_ShapeEnum theShapeType,
1933 GEOMAlgo_State theState)
1935 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
1937 // Check presence of triangulation, build if need
1938 if (!CheckTriangulation(theShape)) {
1939 SetErrorCode("Cannot build triangulation on the shape");
1944 GEOMAlgo_FinderShapeOn1 aFinder;
1945 Standard_Real aTol = 0.0001; // default value
1947 aFinder.SetShape(theShape);
1948 aFinder.SetTolerance(aTol);
1949 aFinder.SetSurface(theSurface);
1950 aFinder.SetShapeType(theShapeType);
1951 aFinder.SetState(theState);
1953 // Sets the minimal number of inner points for the faces that do not have own
1954 // inner points at all (for e.g. rectangular planar faces have just 2 triangles).
1956 aFinder.SetNbPntsMin(3);
1957 // Sets the maximal number of inner points for edges or faces.
1958 // It is usefull for the cases when this number is very big (e.g =2000) to improve
1959 // the performance. If this value =0, all inner points will be taken into account.
1961 aFinder.SetNbPntsMax(100);
1965 // Interprete results
1966 Standard_Integer iErr = aFinder.ErrorStatus();
1967 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
1969 MESSAGE(" iErr : " << iErr);
1970 TCollection_AsciiString aMsg (" iErr : ");
1971 aMsg += TCollection_AsciiString(iErr);
1975 Standard_Integer iWrn = aFinder.WarningStatus();
1976 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
1978 MESSAGE(" *** iWrn : " << iWrn);
1981 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
1983 if (listSS.Extent() < 1) {
1984 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
1985 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
1989 // Fill sequence of object IDs
1990 aSeqOfIDs = new TColStd_HSequenceOfInteger;
1992 TopTools_IndexedMapOfShape anIndices;
1993 TopExp::MapShapes(theShape, anIndices);
1995 TopTools_ListIteratorOfListOfShape itSub (listSS);
1996 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
1997 int id = anIndices.FindIndex(itSub.Value());
1998 aSeqOfIDs->Append(id);
2004 //=======================================================================
2005 //function : getObjectsShapesOn
2007 * \brief Find shape objects and their entries by their ids
2008 * \param theShapeIDs - incoming shape ids
2009 * \param theShapeEntries - outgoing entries like "entry1, entry2, ..."
2010 * \retval Handle(TColStd_HSequenceOfTransient) - found shape objects
2012 //=======================================================================
2013 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::
2014 getObjectsShapesOn(const Handle(GEOM_Object)& theShape,
2015 const Handle(TColStd_HSequenceOfInteger)& theShapeIDs,
2016 TCollection_AsciiString & theShapeEntries)
2018 Handle(TColStd_HSequenceOfTransient) aSeq;
2020 if ( !theShapeIDs.IsNull() && theShapeIDs->Length() > 0 )
2022 aSeq = new TColStd_HSequenceOfTransient;
2023 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
2024 TCollection_AsciiString anEntry;
2025 for ( int i = 1; i <= theShapeIDs->Length(); ++i )
2027 anArray->SetValue(1, theShapeIDs->Value( i ));
2028 Handle(GEOM_Object) anObj = GetEngine()->AddSubShape(theShape, anArray);
2029 aSeq->Append( anObj );
2031 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
2032 if ( i != 1 ) theShapeEntries += ",";
2033 theShapeEntries += anEntry;
2039 //=======================================================================
2040 //function : getShapesOnSurface
2042 * \brief Find subshapes complying with given status about surface
2043 * \param theSurface - the surface to check state of subshapes against
2044 * \param theShape - the shape to explore
2045 * \param theShapeType - type of subshape of theShape
2046 * \param theState - required state
2047 * \param theShapeEntries - outgoing entries like "entry1, entry2, ..."
2048 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
2050 //=======================================================================
2051 Handle(TColStd_HSequenceOfTransient)
2052 GEOMImpl_IShapesOperations::getShapesOnSurface(const Handle(Geom_Surface)& theSurface,
2053 const Handle(GEOM_Object)& theShape,
2054 TopAbs_ShapeEnum theShapeType,
2055 GEOMAlgo_State theState,
2056 TCollection_AsciiString & theShapeEntries)
2058 // Find subshapes ids
2059 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2060 getShapesOnSurfaceIDs (theSurface, theShape->GetValue(), theShapeType, theState);
2061 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2064 return getObjectsShapesOn( theShape, aSeqOfIDs, theShapeEntries );
2067 //=============================================================================
2071 //=============================================================================
2072 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnPlane
2073 (const Handle(GEOM_Object)& theShape,
2074 const Standard_Integer theShapeType,
2075 const Handle(GEOM_Object)& theAx1,
2076 const GEOMAlgo_State theState)
2080 if (theShape.IsNull() || theAx1.IsNull()) return NULL;
2082 TopoDS_Shape aShape = theShape->GetValue();
2083 TopoDS_Shape anAx1 = theAx1->GetValue();
2085 if (aShape.IsNull() || anAx1.IsNull()) return NULL;
2087 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2088 if ( !checkTypeShapesOn( theShapeType ))
2092 Handle(Geom_Surface) aPlane = makePlane( anAx1 );
2093 if ( aPlane.IsNull() )
2097 TCollection_AsciiString anAsciiList;
2098 Handle(TColStd_HSequenceOfTransient) aSeq;
2099 aSeq = getShapesOnSurface( aPlane, theShape, aShapeType, theState, anAsciiList );
2100 if ( aSeq.IsNull() || aSeq->Length() == 0 )
2103 // Make a Python command
2105 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2106 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2108 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
2109 << "] = geompy.GetShapesOnPlane(" << theShape << ", "
2110 << aShapeType << ", " << theAx1 << ", " << theState << ")";
2116 //=============================================================================
2118 * GetShapesOnPlaneWithLocation
2120 //=============================================================================
2121 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnPlaneWithLocation
2122 (const Handle(GEOM_Object)& theShape,
2123 const Standard_Integer theShapeType,
2124 const Handle(GEOM_Object)& theAx1,
2125 const Handle(GEOM_Object)& thePnt,
2126 const GEOMAlgo_State theState)
2130 if (theShape.IsNull() || theAx1.IsNull() || thePnt.IsNull()) return NULL;
2132 TopoDS_Shape aShape = theShape->GetValue();
2133 TopoDS_Shape anAx1 = theAx1->GetValue();
2134 TopoDS_Shape anPnt = thePnt->GetValue();
2136 if (aShape.IsNull() || anAx1.IsNull() || anPnt.IsNull()) return NULL;
2138 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2139 if ( !checkTypeShapesOn( theShapeType ))
2143 if ( anAx1.ShapeType() != TopAbs_EDGE || anPnt.ShapeType() != TopAbs_VERTEX ) return NULL;
2144 TopoDS_Vertex V1, V2, V3;
2145 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
2146 TopExp::Vertices(anEdge, V1, V2, Standard_True);
2148 if (V1.IsNull() || V2.IsNull()) {
2149 SetErrorCode("Bad edge given for the plane normal vector");
2152 V3 = TopoDS::Vertex(anPnt);
2155 SetErrorCode("Bad vertex given for the plane location");
2158 gp_Pnt aLoc = BRep_Tool::Pnt(V3);
2159 gp_Vec aVec(BRep_Tool::Pnt(V1),BRep_Tool::Pnt(V2));
2161 if (aVec.Magnitude() < Precision::Confusion()) {
2162 SetErrorCode("Vector with null magnitude given");
2165 Handle(Geom_Surface) aPlane = new Geom_Plane(aLoc, aVec);
2167 if ( aPlane.IsNull() )
2171 TCollection_AsciiString anAsciiList;
2172 Handle(TColStd_HSequenceOfTransient) aSeq;
2173 aSeq = getShapesOnSurface( aPlane, theShape, aShapeType, theState, anAsciiList );
2174 if ( aSeq.IsNull() || aSeq->Length() == 0 )
2177 // Make a Python command
2179 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2180 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2182 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
2183 << "] = geompy.GetShapesOnPlaneWithLocation(" << theShape << ", "
2184 << aShapeType << ", " << theAx1 << ", "<< thePnt <<", " << theState << ")";
2190 //=============================================================================
2192 * GetShapesOnCylinder
2194 //=============================================================================
2195 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnCylinder
2196 (const Handle(GEOM_Object)& theShape,
2197 const Standard_Integer theShapeType,
2198 const Handle(GEOM_Object)& theAxis,
2199 const Standard_Real theRadius,
2200 const GEOMAlgo_State theState)
2204 if (theShape.IsNull() || theAxis.IsNull()) return NULL;
2206 TopoDS_Shape aShape = theShape->GetValue();
2207 TopoDS_Shape anAxis = theAxis->GetValue();
2209 if (aShape.IsNull() || anAxis.IsNull()) return NULL;
2211 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2212 if ( !checkTypeShapesOn( aShapeType ))
2215 // Create a cylinder surface
2216 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
2217 if ( aCylinder.IsNull() )
2221 TCollection_AsciiString anAsciiList;
2222 Handle(TColStd_HSequenceOfTransient) aSeq;
2223 aSeq = getShapesOnSurface( aCylinder, theShape, aShapeType, theState, anAsciiList );
2224 if ( aSeq.IsNull() || aSeq->Length() == 0 )
2227 // Make a Python command
2229 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2230 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2232 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
2233 << "] = geompy.GetShapesOnCylinder(" << theShape << ", " << aShapeType
2234 << ", " << theAxis << ", " << theRadius << ", " << theState << ")";
2240 //=============================================================================
2242 * GetShapesOnCylinderWithLocation
2244 //=============================================================================
2245 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnCylinderWithLocation
2246 (const Handle(GEOM_Object)& theShape,
2247 const Standard_Integer theShapeType,
2248 const Handle(GEOM_Object)& theAxis,
2249 const Handle(GEOM_Object)& thePnt,
2250 const Standard_Real theRadius,
2251 const GEOMAlgo_State theState)
2255 if (theShape.IsNull() || theAxis.IsNull() || thePnt.IsNull()) return NULL;
2257 TopoDS_Shape aShape = theShape->GetValue();
2258 TopoDS_Shape anAxis = theAxis->GetValue();
2259 TopoDS_Shape aPnt = thePnt->GetValue();
2261 if (aShape.IsNull() || anAxis.IsNull() || aPnt.IsNull()) return NULL;
2263 if (aPnt.ShapeType() != TopAbs_VERTEX )
2265 SetErrorCode("Bottom location point must be vertex");
2269 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2270 if ( !checkTypeShapesOn( aShapeType ))
2273 // Create a cylinder surface
2274 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
2275 if ( aCylinder.IsNull() )
2278 // translate the surface
2279 Handle(Geom_CylindricalSurface) aCylSurface =
2280 Handle(Geom_CylindricalSurface)::DownCast( aCylinder );
2281 if ( aCylSurface.IsNull() )
2283 SetErrorCode("Unexpected surface type instead of Geom_CylindricalSurface");
2286 gp_Pnt fromLoc = aCylSurface->Cylinder().Location();
2287 gp_Pnt toLoc = BRep_Tool::Pnt( TopoDS::Vertex( aPnt ));
2288 aCylinder->Translate( fromLoc, toLoc );
2291 TCollection_AsciiString anAsciiList;
2292 Handle(TColStd_HSequenceOfTransient) aSeq;
2293 aSeq = getShapesOnSurface( aCylinder, theShape, aShapeType, theState, anAsciiList );
2294 if ( aSeq.IsNull() || aSeq->Length() == 0 )
2297 // Make a Python command
2299 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2300 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2302 GEOM::TPythonDump(aFunction)
2303 << "[" << anAsciiList.ToCString()
2304 << "] = geompy.GetShapesOnCylinderWithLocation(" << theShape << ", " << aShapeType << ", "
2305 << theAxis << ", " << thePnt << ", " << theRadius << ", " << theState << ")";
2311 //=============================================================================
2315 //=============================================================================
2316 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnSphere
2317 (const Handle(GEOM_Object)& theShape,
2318 const Standard_Integer theShapeType,
2319 const Handle(GEOM_Object)& theCenter,
2320 const Standard_Real theRadius,
2321 const GEOMAlgo_State theState)
2325 if (theShape.IsNull() || theCenter.IsNull()) return NULL;
2327 TopoDS_Shape aShape = theShape->GetValue();
2328 TopoDS_Shape aCenter = theCenter->GetValue();
2330 if (aShape.IsNull() || aCenter.IsNull()) return NULL;
2332 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2333 if ( !checkTypeShapesOn( aShapeType ))
2336 // Center of the sphere
2337 if (aCenter.ShapeType() != TopAbs_VERTEX) return NULL;
2338 gp_Pnt aLoc = BRep_Tool::Pnt(TopoDS::Vertex(aCenter));
2340 gp_Ax3 anAx3 (aLoc, gp::DZ());
2341 Handle(Geom_SphericalSurface) aSphere =
2342 new Geom_SphericalSurface(anAx3, theRadius);
2345 TCollection_AsciiString anAsciiList;
2346 Handle(TColStd_HSequenceOfTransient) aSeq;
2347 aSeq = getShapesOnSurface( aSphere, theShape, aShapeType, theState, anAsciiList );
2348 if ( aSeq.IsNull() || aSeq->Length() == 0 )
2351 // Make a Python command
2353 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2354 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2356 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
2357 << "] = geompy.GetShapesOnSphere(" << theShape << ", " << aShapeType
2358 << ", " << theCenter << ", " << theRadius << ", " << theState << ")";
2364 //=============================================================================
2366 * GetShapesOnPlaneIDs
2368 //=============================================================================
2369 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnPlaneIDs
2370 (const Handle(GEOM_Object)& theShape,
2371 const Standard_Integer theShapeType,
2372 const Handle(GEOM_Object)& theAx1,
2373 const GEOMAlgo_State theState)
2377 if (theShape.IsNull() || theAx1.IsNull()) return NULL;
2379 TopoDS_Shape aShape = theShape->GetValue();
2380 TopoDS_Shape anAx1 = theAx1->GetValue();
2382 if (aShape.IsNull() || anAx1.IsNull()) return NULL;
2384 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2385 if ( !checkTypeShapesOn( aShapeType ))
2389 Handle(Geom_Surface) aPlane = makePlane( anAx1 );
2390 if ( aPlane.IsNull() )
2394 Handle(TColStd_HSequenceOfInteger) aSeq;
2395 aSeq = getShapesOnSurfaceIDs( aPlane, aShape, aShapeType, theState );
2397 // The GetShapesOnPlaneIDs() doesn't change object so no new function is required.
2398 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAx1)->GetLastFunction();
2400 // Make a Python command
2401 GEOM::TPythonDump(aFunction, /*append=*/true)
2402 << "listShapesOnPlane = geompy.GetShapesOnPlaneIDs"
2403 << "(" << theShape << "," << aShapeType << "," << theAx1 << "," << theState << ")";
2409 //=============================================================================
2411 * GetShapesOnPlaneWithLocationIDs
2413 //=============================================================================
2414 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnPlaneWithLocationIDs
2415 (const Handle(GEOM_Object)& theShape,
2416 const Standard_Integer theShapeType,
2417 const Handle(GEOM_Object)& theAx1,
2418 const Handle(GEOM_Object)& thePnt,
2419 const GEOMAlgo_State theState)
2423 if (theShape.IsNull() || theAx1.IsNull() || thePnt.IsNull()) return NULL;
2425 TopoDS_Shape aShape = theShape->GetValue();
2426 TopoDS_Shape anAx1 = theAx1->GetValue();
2427 TopoDS_Shape anPnt = thePnt->GetValue();
2429 if (aShape.IsNull() || anAx1.IsNull() || anPnt.IsNull()) return NULL;
2431 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2432 if ( !checkTypeShapesOn( aShapeType ))
2436 if (anAx1.ShapeType() != TopAbs_EDGE || anPnt.ShapeType() != TopAbs_VERTEX) return NULL;
2437 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
2438 TopoDS_Vertex V1, V2, V3;
2439 TopExp::Vertices(anEdge, V1, V2, Standard_True);
2440 if (V1.IsNull() || V2.IsNull()) {
2441 SetErrorCode("Bad edge given for the plane normal vector");
2444 V3 = TopoDS::Vertex(anPnt);
2446 SetErrorCode("Bad vertex given for the plane location");
2449 gp_Pnt aLoc = BRep_Tool::Pnt(V3);
2450 gp_Vec aVec(BRep_Tool::Pnt(V1),BRep_Tool::Pnt(V2));
2451 if (aVec.Magnitude() < Precision::Confusion()) {
2452 SetErrorCode("Vector with null magnitude given");
2456 Handle(Geom_Surface) aPlane = new Geom_Plane(aLoc, aVec);
2457 if ( aPlane.IsNull() )
2461 Handle(TColStd_HSequenceOfInteger) aSeq;
2462 aSeq = getShapesOnSurfaceIDs( aPlane, aShape, aShapeType, theState );
2464 // The GetShapesOnPlaneIDs() doesn't change object so no new function is required.
2465 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAx1)->GetLastFunction();
2467 // Make a Python command
2468 GEOM::TPythonDump(aFunction, /*append=*/true)
2469 << "listShapesOnPlane = geompy.GetShapesOnPlaneWithLocationIDs"
2470 << "(" << theShape << ", " << aShapeType << ", " << theAx1 << ", "<< thePnt << ", " << theState << ")";
2476 //=============================================================================
2478 * GetShapesOnCylinderIDs
2480 //=============================================================================
2481 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnCylinderIDs
2482 (const Handle(GEOM_Object)& theShape,
2483 const Standard_Integer theShapeType,
2484 const Handle(GEOM_Object)& theAxis,
2485 const Standard_Real theRadius,
2486 const GEOMAlgo_State theState)
2490 if (theShape.IsNull() || theAxis.IsNull()) return NULL;
2492 TopoDS_Shape aShape = theShape->GetValue();
2493 TopoDS_Shape anAxis = theAxis->GetValue();
2495 if (aShape.IsNull() || anAxis.IsNull()) return NULL;
2497 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2498 if ( !checkTypeShapesOn( aShapeType ))
2501 // Create a cylinder surface
2502 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
2503 if ( aCylinder.IsNull() )
2507 Handle(TColStd_HSequenceOfInteger) aSeq;
2508 aSeq = getShapesOnSurfaceIDs( aCylinder, aShape, aShapeType, theState );
2510 // The GetShapesOnCylinder() doesn't change object so no new function is required.
2511 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAxis)->GetLastFunction();
2513 // Make a Python command
2514 GEOM::TPythonDump(aFunction, /*append=*/true)
2515 << "listShapesOnCylinder = geompy.GetShapesOnCylinderIDs"
2516 << "(" << theShape << ", " << aShapeType << ", " << theAxis << ", "
2517 << theRadius << ", " << theState << ")";
2523 //=============================================================================
2525 * GetShapesOnCylinderWithLocationIDs
2527 //=============================================================================
2528 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnCylinderWithLocationIDs
2529 (const Handle(GEOM_Object)& theShape,
2530 const Standard_Integer theShapeType,
2531 const Handle(GEOM_Object)& theAxis,
2532 const Handle(GEOM_Object)& thePnt,
2533 const Standard_Real theRadius,
2534 const GEOMAlgo_State theState)
2538 if (theShape.IsNull() || theAxis.IsNull() || thePnt.IsNull()) return NULL;
2540 TopoDS_Shape aShape = theShape->GetValue();
2541 TopoDS_Shape anAxis = theAxis->GetValue();
2542 TopoDS_Shape aPnt = thePnt->GetValue();
2544 if (aShape.IsNull() || anAxis.IsNull() || aPnt.IsNull()) return NULL;
2546 if (aPnt.ShapeType() != TopAbs_VERTEX )
2548 SetErrorCode("Bottom location point must be vertex");
2552 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2553 if ( !checkTypeShapesOn( aShapeType ))
2556 // Create a cylinder surface
2557 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
2558 if ( aCylinder.IsNull() )
2561 // translate the surface
2562 Handle(Geom_CylindricalSurface) aCylSurface =
2563 Handle(Geom_CylindricalSurface)::DownCast( aCylinder );
2564 if ( aCylSurface.IsNull() )
2566 SetErrorCode("Unexpected surface type instead of Geom_CylindricalSurface");
2569 gp_Pnt fromLoc = aCylSurface->Cylinder().Location();
2570 gp_Pnt toLoc = BRep_Tool::Pnt( TopoDS::Vertex( aPnt ));
2571 aCylinder->Translate( fromLoc, toLoc );
2574 Handle(TColStd_HSequenceOfInteger) aSeq;
2575 aSeq = getShapesOnSurfaceIDs( aCylinder, aShape, aShapeType, theState );
2577 // The GetShapesOnCylinder() doesn't change object so no new function is required.
2578 Handle(GEOM_Function) aFunction =
2579 GEOM::GetCreatedLast(theShape, GEOM::GetCreatedLast(thePnt,theAxis))->GetLastFunction();
2581 // Make a Python command
2582 GEOM::TPythonDump(aFunction, /*append=*/true)
2583 << "listShapesOnCylinder = geompy.GetShapesOnCylinderWithLocationIDs"
2584 << "(" << theShape << ", " << aShapeType << ", " << theAxis << ", "
2585 << thePnt << ", " << theRadius << ", " << theState << ")";
2591 //=============================================================================
2593 * GetShapesOnSphereIDs
2595 //=============================================================================
2596 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnSphereIDs
2597 (const Handle(GEOM_Object)& theShape,
2598 const Standard_Integer theShapeType,
2599 const Handle(GEOM_Object)& theCenter,
2600 const Standard_Real theRadius,
2601 const GEOMAlgo_State theState)
2605 if (theShape.IsNull() || theCenter.IsNull()) return NULL;
2607 TopoDS_Shape aShape = theShape->GetValue();
2608 TopoDS_Shape aCenter = theCenter->GetValue();
2610 if (aShape.IsNull() || aCenter.IsNull()) return NULL;
2612 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2613 if ( !checkTypeShapesOn( aShapeType ))
2616 // Center of the sphere
2617 if (aCenter.ShapeType() != TopAbs_VERTEX) return NULL;
2618 gp_Pnt aLoc = BRep_Tool::Pnt(TopoDS::Vertex(aCenter));
2620 gp_Ax3 anAx3 (aLoc, gp::DZ());
2621 Handle(Geom_SphericalSurface) aSphere =
2622 new Geom_SphericalSurface(anAx3, theRadius);
2625 Handle(TColStd_HSequenceOfInteger) aSeq;
2626 aSeq = getShapesOnSurfaceIDs( aSphere, aShape, aShapeType, theState );
2628 // The GetShapesOnSphere() doesn't change object so no new function is required.
2629 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theCenter)->GetLastFunction();
2631 // Make a Python command
2632 GEOM::TPythonDump(aFunction, /*append=*/true)
2633 << "listShapesOnCylinder = geompy.GetShapesOnCylinderIDs"
2634 << "(" << theShape << ", " << aShapeType << ", " << theCenter << ", "
2635 << theRadius << ", " << theState << ")";
2641 //=======================================================================
2642 //function : getShapesOnQuadrangleIDs
2644 * \brief Find IDs of subshapes complying with given status about quadrangle
2645 * \param theShape - the shape to explore
2646 * \param theShapeType - type of subshape of theShape
2647 * \param theTopLeftPoint - top left quadrangle corner
2648 * \param theTopRigthPoint - top right quadrangle corner
2649 * \param theBottomLeftPoint - bottom left quadrangle corner
2650 * \param theBottomRigthPoint - bottom right quadrangle corner
2651 * \param theState - required state
2652 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
2654 //=======================================================================
2655 Handle(TColStd_HSequenceOfInteger)
2656 GEOMImpl_IShapesOperations::getShapesOnQuadrangleIDs (const Handle(GEOM_Object)& theShape,
2657 const Standard_Integer theShapeType,
2658 const Handle(GEOM_Object)& theTopLeftPoint,
2659 const Handle(GEOM_Object)& theTopRigthPoint,
2660 const Handle(GEOM_Object)& theBottomLeftPoint,
2661 const Handle(GEOM_Object)& theBottomRigthPoint,
2662 const GEOMAlgo_State theState)
2666 if ( theShape.IsNull() ||
2667 theTopLeftPoint.IsNull() ||
2668 theTopRigthPoint.IsNull() ||
2669 theBottomLeftPoint.IsNull() ||
2670 theBottomRigthPoint.IsNull() )
2673 TopoDS_Shape aShape = theShape->GetValue();
2674 TopoDS_Shape aTL = theTopLeftPoint->GetValue();
2675 TopoDS_Shape aTR = theTopRigthPoint->GetValue();
2676 TopoDS_Shape aBL = theBottomLeftPoint->GetValue();
2677 TopoDS_Shape aBR = theBottomRigthPoint->GetValue();
2679 if (aShape.IsNull() ||
2684 aTL.ShapeType() != TopAbs_VERTEX ||
2685 aTR.ShapeType() != TopAbs_VERTEX ||
2686 aBL.ShapeType() != TopAbs_VERTEX ||
2687 aBR.ShapeType() != TopAbs_VERTEX )
2690 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2691 if ( !checkTypeShapesOn( aShapeType ))
2694 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
2696 // Check presence of triangulation, build if need
2697 if (!CheckTriangulation(aShape)) {
2698 SetErrorCode("Cannot build triangulation on the shape");
2703 gp_Pnt aPntTL = BRep_Tool::Pnt(TopoDS::Vertex(aTL));
2704 gp_Pnt aPntTR = BRep_Tool::Pnt(TopoDS::Vertex(aTR));
2705 gp_Pnt aPntBL = BRep_Tool::Pnt(TopoDS::Vertex(aBL));
2706 gp_Pnt aPntBR = BRep_Tool::Pnt(TopoDS::Vertex(aBR));
2708 GEOMAlgo_FinderShapeOnQuad aFinder( aPntTL, aPntTR, aPntBL, aPntBR );
2709 Standard_Real aTol = 0.0001; // default value
2711 aFinder.SetShape(aShape);
2712 aFinder.SetTolerance(aTol);
2713 //aFinder.SetSurface(theSurface);
2714 aFinder.SetShapeType(aShapeType);
2715 aFinder.SetState(theState);
2717 // Sets the minimal number of inner points for the faces that do not have own
2718 // inner points at all (for e.g. rectangular planar faces have just 2 triangles).
2720 aFinder.SetNbPntsMin(3);
2721 // Sets the maximal number of inner points for edges or faces.
2722 // It is usefull for the cases when this number is very big (e.g =2000) to improve
2723 // the performance. If this value =0, all inner points will be taken into account.
2725 aFinder.SetNbPntsMax(100);
2729 // Interprete results
2730 Standard_Integer iErr = aFinder.ErrorStatus();
2731 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
2733 MESSAGE(" iErr : " << iErr);
2734 TCollection_AsciiString aMsg (" iErr : ");
2735 aMsg += TCollection_AsciiString(iErr);
2739 Standard_Integer iWrn = aFinder.WarningStatus();
2740 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
2742 MESSAGE(" *** iWrn : " << iWrn);
2745 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
2747 if (listSS.Extent() < 1) {
2748 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
2749 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
2753 // Fill sequence of object IDs
2754 aSeqOfIDs = new TColStd_HSequenceOfInteger;
2756 TopTools_IndexedMapOfShape anIndices;
2757 TopExp::MapShapes(aShape, anIndices);
2759 TopTools_ListIteratorOfListOfShape itSub (listSS);
2760 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
2761 int id = anIndices.FindIndex(itSub.Value());
2762 aSeqOfIDs->Append(id);
2767 //=======================================================================
2768 //function : GetShapesOnQuadrangle
2770 * \brief Find subshapes complying with given status about quadrangle
2771 * \param theShape - the shape to explore
2772 * \param theShapeType - type of subshape of theShape
2773 * \param theTopLeftPoint - top left quadrangle corner
2774 * \param theTopRigthPoint - top right quadrangle corner
2775 * \param theBottomLeftPoint - bottom left quadrangle corner
2776 * \param theBottomRigthPoint - bottom right quadrangle corner
2777 * \param theState - required state
2778 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
2780 //=======================================================================
2781 Handle(TColStd_HSequenceOfTransient)
2782 GEOMImpl_IShapesOperations::GetShapesOnQuadrangle (const Handle(GEOM_Object)& theShape,
2783 const Standard_Integer theShapeType,
2784 const Handle(GEOM_Object)& theTopLeftPoint,
2785 const Handle(GEOM_Object)& theTopRigthPoint,
2786 const Handle(GEOM_Object)& theBottomLeftPoint,
2787 const Handle(GEOM_Object)& theBottomRigthPoint,
2788 const GEOMAlgo_State theState)
2791 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2792 getShapesOnQuadrangleIDs( theShape,
2797 theBottomRigthPoint,
2799 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->IsEmpty() )
2802 // Find objects by indices
2803 TCollection_AsciiString anAsciiList;
2804 Handle(TColStd_HSequenceOfTransient) aSeq;
2805 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
2806 if ( aSeq.IsNull() || aSeq->IsEmpty() )
2809 // Make a Python command
2811 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2812 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2814 GEOM::TPythonDump(aFunction)
2815 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnQuadrangle("
2817 << TopAbs_ShapeEnum(theShapeType) << ", "
2818 << theTopLeftPoint << ", "
2819 << theTopRigthPoint << ", "
2820 << theBottomLeftPoint << ", "
2821 << theBottomRigthPoint << ", "
2828 //=======================================================================
2829 //function : GetShapesOnQuadrangleIDs
2831 * \brief Find IDs of subshapes complying with given status about quadrangle
2832 * \param theShape - the shape to explore
2833 * \param theShapeType - type of subshape of theShape
2834 * \param theTopLeftPoint - top left quadrangle corner
2835 * \param theTopRigthPoint - top right quadrangle corner
2836 * \param theBottomLeftPoint - bottom left quadrangle corner
2837 * \param theBottomRigthPoint - bottom right quadrangle corner
2838 * \param theState - required state
2839 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
2841 //=======================================================================
2842 Handle(TColStd_HSequenceOfInteger)
2843 GEOMImpl_IShapesOperations::GetShapesOnQuadrangleIDs (const Handle(GEOM_Object)& theShape,
2844 const Standard_Integer theShapeType,
2845 const Handle(GEOM_Object)& theTopLeftPoint,
2846 const Handle(GEOM_Object)& theTopRigthPoint,
2847 const Handle(GEOM_Object)& theBottomLeftPoint,
2848 const Handle(GEOM_Object)& theBottomRigthPoint,
2849 const GEOMAlgo_State theState)
2852 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2853 getShapesOnQuadrangleIDs( theShape,
2858 theBottomRigthPoint,
2860 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->IsEmpty() )
2863 // Make a Python command
2865 // The GetShapesOnCylinder() doesn't change object so no new function is required.
2866 Handle(GEOM_Object) lastObj = GEOM::GetCreatedLast(theShape,theTopLeftPoint);
2867 lastObj = GEOM::GetCreatedLast(lastObj,theTopRigthPoint);
2868 lastObj = GEOM::GetCreatedLast(lastObj,theBottomRigthPoint);
2869 lastObj = GEOM::GetCreatedLast(lastObj,theBottomLeftPoint);
2870 Handle(GEOM_Function) aFunction = lastObj->GetLastFunction();
2872 GEOM::TPythonDump(aFunction, /*append=*/true)
2873 << "listShapesOnQuadrangle = geompy.GetShapesOnQuadrangleIDs("
2875 << TopAbs_ShapeEnum(theShapeType) << ", "
2876 << theTopLeftPoint << ", "
2877 << theTopRigthPoint << ", "
2878 << theBottomLeftPoint << ", "
2879 << theBottomRigthPoint << ", "
2886 //=============================================================================
2890 //=============================================================================
2891 static bool GetInPlaceOfShape (const Handle(GEOM_Function)& theWhereFunction,
2892 const TopTools_IndexedMapOfShape& theWhereIndices,
2893 const TopoDS_Shape& theWhat,
2894 TColStd_ListOfInteger& theModifiedList)
2896 if (theWhereFunction.IsNull() || theWhat.IsNull()) return false;
2898 if (theWhereIndices.Contains(theWhat)) {
2899 // entity was not changed by the operation
2900 Standard_Integer aWhatIndex = theWhereIndices.FindIndex(theWhat);
2901 theModifiedList.Append(aWhatIndex);
2905 // try to find in history
2906 TDF_Label aHistoryLabel = theWhereFunction->GetHistoryEntry(Standard_False);
2908 // search in history for all argument shapes
2909 Standard_Boolean isFound = Standard_False;
2910 Standard_Boolean isGood = Standard_False;
2912 TDF_LabelSequence aLabelSeq;
2913 theWhereFunction->GetDependency(aLabelSeq);
2914 Standard_Integer nbArg = aLabelSeq.Length();
2916 for (Standard_Integer iarg = 1; iarg <= nbArg && !isFound; iarg++) {
2918 TDF_Label anArgumentRefLabel = aLabelSeq.Value(iarg);
2920 Handle(GEOM_Object) anArgumentObject = GEOM_Object::GetReferencedObject(anArgumentRefLabel);
2921 TopoDS_Shape anArgumentShape = anArgumentObject->GetValue();
2923 TopTools_IndexedMapOfShape anArgumentIndices;
2924 TopExp::MapShapes(anArgumentShape, anArgumentIndices);
2926 if (anArgumentIndices.Contains(theWhat)) {
2927 isFound = Standard_True;
2928 Standard_Integer aWhatIndex = anArgumentIndices.FindIndex(theWhat);
2930 // Find corresponding label in history
2931 TDF_Label anArgumentHistoryLabel =
2932 theWhereFunction->GetArgumentHistoryEntry(anArgumentRefLabel, Standard_False);
2933 if (anArgumentHistoryLabel.IsNull()) {
2934 // Lost History of operation argument. Possibly, all its entities was removed.
2935 isGood = Standard_True;
2938 TDF_Label aWhatHistoryLabel = anArgumentHistoryLabel.FindChild(aWhatIndex, Standard_False);
2940 if (aWhatHistoryLabel.IsNull()) {
2941 // Removed entity ? Compound ? Compsolid ? Shell ? Wire
2942 isGood = Standard_False;
2944 Handle(TDataStd_IntegerArray) anIntegerArray;
2945 if (!aWhatHistoryLabel.FindAttribute(TDataStd_IntegerArray::GetID(), anIntegerArray)) {
2946 //Error: Empty modifications history for the sought shape.
2947 isGood = Standard_False;
2950 isGood = Standard_True;
2951 Standard_Integer imod, aModifLen = anIntegerArray->Array()->Length();
2952 for (imod = 1; imod <= aModifLen; imod++) {
2953 theModifiedList.Append(anIntegerArray->Array()->Value(imod));
2964 // try compound/compsolid/shell/wire element by element
2965 bool isFoundAny = false;
2966 TopTools_MapOfShape mapShape;
2968 if (theWhat.ShapeType() == TopAbs_COMPOUND ||
2969 theWhat.ShapeType() == TopAbs_COMPSOLID) {
2970 // recursive processing of compound/compsolid
2971 TopoDS_Iterator anIt (theWhat, Standard_True, Standard_True);
2972 for (; anIt.More(); anIt.Next()) {
2973 if (mapShape.Add(anIt.Value())) {
2974 TopoDS_Shape curWhat = anIt.Value();
2975 isFoundAny = GetInPlaceOfShape(theWhereFunction, theWhereIndices, curWhat, theModifiedList);
2976 if (isFoundAny) isFound = Standard_True;
2980 else if (theWhat.ShapeType() == TopAbs_SHELL) {
2981 // try to replace a shell by its faces images
2982 TopExp_Explorer anExp (theWhat, TopAbs_FACE);
2983 for (; anExp.More(); anExp.Next()) {
2984 if (mapShape.Add(anExp.Current())) {
2985 TopoDS_Shape curWhat = anExp.Current();
2986 isFoundAny = GetInPlaceOfShape(theWhereFunction, theWhereIndices, curWhat, theModifiedList);
2987 if (isFoundAny) isFound = Standard_True;
2991 else if (theWhat.ShapeType() == TopAbs_WIRE) {
2992 // try to replace a wire by its edges images
2993 TopExp_Explorer anExp (theWhat, TopAbs_EDGE);
2994 for (; anExp.More(); anExp.Next()) {
2995 if (mapShape.Add(anExp.Current())) {
2996 TopoDS_Shape curWhat = anExp.Current();
2997 isFoundAny = GetInPlaceOfShape(theWhereFunction, theWhereIndices, curWhat, theModifiedList);
2998 if (isFoundAny) isFound = Standard_True;
3010 //=============================================================================
3012 * GetShapeProperties
3014 //=============================================================================
3015 void GEOMImpl_IShapesOperations::GetShapeProperties( const TopoDS_Shape aShape, Standard_Real tab[],
3018 GProp_GProps theProps;
3020 //TopoDS_Shape aPntShape;
3021 Standard_Real aShapeSize;
3023 if (aShape.ShapeType() == TopAbs_EDGE) BRepGProp::LinearProperties(aShape, theProps);
3024 else if (aShape.ShapeType() == TopAbs_FACE) BRepGProp::SurfaceProperties(aShape, theProps);
3025 else BRepGProp::VolumeProperties(aShape, theProps);
3027 aCenterMass = theProps.CentreOfMass();
3028 aShapeSize = theProps.Mass();
3030 // aPntShape = BRepBuilderAPI_MakeVertex(aCenterMass).Shape();
3031 // aVertex = BRep_Tool::Pnt( TopoDS::Vertex( aPntShape ) );
3032 aVertex = aCenterMass;
3033 tab[0] = aVertex.X();
3034 tab[1] = aVertex.Y();
3035 tab[2] = aVertex.Z();
3036 tab[3] = aShapeSize;
3042 //================================================================================
3044 * \brief Return normal to face at extrema point
3046 //================================================================================
3048 gp_Vec GetNormal(const TopoDS_Face& face, const BRepExtrema_DistShapeShape& extrema)
3050 gp_Vec defaultNorm(1,0,0); // to have same normals on different faces
3052 // get UV at extrema point
3053 Standard_Real u,v, f,l;
3054 switch ( extrema.SupportTypeShape2(1) ) {
3055 case BRepExtrema_IsInFace: {
3056 extrema.ParOnFaceS2(1, u, v );
3059 case BRepExtrema_IsOnEdge: {
3060 TopoDS_Edge edge = TopoDS::Edge( extrema.SupportOnShape2(1));
3061 Handle(Geom2d_Curve) pcurve = BRep_Tool::CurveOnSurface( edge, face, f,l );
3062 extrema.ParOnEdgeS2( 1, u );
3063 gp_Pnt2d uv = pcurve->Value( u );
3068 case BRepExtrema_IsVertex: return defaultNorm;
3071 BRepAdaptor_Surface surface( face, false );
3072 gp_Vec du, dv; gp_Pnt p;
3073 surface.D1( u, v, p, du, dv );
3077 } catch (Standard_Failure ) {
3083 //=============================================================================
3088 //=============================================================================
3089 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlace (Handle(GEOM_Object) theShapeWhere,
3090 Handle(GEOM_Object) theShapeWhat)
3094 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
3096 TopoDS_Shape aWhere = theShapeWhere->GetValue();
3097 TopoDS_Shape aWhat = theShapeWhat->GetValue();
3098 TopoDS_Shape aPntShape;
3099 TopoDS_Vertex aVertex;
3101 if (aWhere.IsNull() || aWhat.IsNull()) {
3102 SetErrorCode("Error: aWhere and aWhat TopoDS_Shape are Null.");
3106 Handle(GEOM_Function) aWhereFunction = theShapeWhere->GetLastFunction();
3107 if (aWhereFunction.IsNull()) {
3108 SetErrorCode("Error: aWhereFunction is Null.");
3112 TopTools_IndexedMapOfShape aWhereIndices;
3113 TopExp::MapShapes(aWhere, aWhereIndices);
3115 TColStd_ListOfInteger aModifiedList;
3116 Standard_Integer aWhereIndex;
3117 Handle(TColStd_HArray1OfInteger) aModifiedArray;
3118 Handle(GEOM_Object) aResult;
3120 bool isFound = false;
3121 Standard_Integer iType = TopAbs_SOLID;
3122 Standard_Integer compType = TopAbs_SOLID;
3123 Standard_Real aWhat_Mass = 0., aWhere_Mass = 0.;
3124 Standard_Real tab_aWhat[4], tab_aWhere[4];
3125 Standard_Real dl_l = 1e-3;
3126 Standard_Real min_l, Tol_1D, Tol_2D, Tol_3D, Tol_Mass;
3127 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
3128 Bnd_Box BoundingBox;
3129 gp_Pnt aPnt, aPnt_aWhat, tab_Pnt[2];
3130 GProp_GProps aProps;
3132 // Find the iType of the aWhat shape
3133 if ( aWhat.ShapeType() == TopAbs_EDGE || aWhat.ShapeType() == TopAbs_WIRE ) iType = TopAbs_EDGE;
3134 else if ( aWhat.ShapeType() == TopAbs_FACE || aWhat.ShapeType() == TopAbs_SHELL ) iType = TopAbs_FACE;
3135 else if ( aWhat.ShapeType() == TopAbs_SOLID || aWhat.ShapeType() == TopAbs_COMPSOLID ) iType = TopAbs_SOLID;
3136 else if ( aWhat.ShapeType() == TopAbs_COMPOUND ) {
3137 // Only the iType of the first shape in the compound is taken into account
3138 TopoDS_Iterator It (aWhat, Standard_False, Standard_False);
3140 SetErrorCode("Error: theShapeWhat is an empty COMPOUND.");
3143 compType = It.Value().ShapeType();
3144 if ( compType == TopAbs_EDGE || compType == TopAbs_WIRE ) iType = TopAbs_EDGE;
3145 else if ( compType == TopAbs_FACE || compType == TopAbs_SHELL) iType = TopAbs_FACE;
3146 else if ( compType == TopAbs_SOLID || compType == TopAbs_COMPSOLID) iType = TopAbs_SOLID;
3149 SetErrorCode("Error: An attempt to extract a shape of not supported type.");
3153 TopExp_Explorer Exp_aWhat( aWhat, TopAbs_ShapeEnum( iType ) );
3154 TopExp_Explorer Exp_aWhere( aWhere, TopAbs_ShapeEnum( iType ) );
3155 TopExp_Explorer Exp_Edge( aWhere, TopAbs_EDGE );
3157 // Find the shortest edge in theShapeWhere shape
3158 BRepBndLib::Add(aWhere, BoundingBox);
3159 BoundingBox.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
3160 min_l = fabs(aXmax - aXmin);
3161 if( min_l < fabs(aYmax - aYmin) ) min_l = fabs(aYmax - aYmin);
3162 if( min_l < fabs(aZmax - aZmin) ) min_l = fabs(aZmax - aZmin);
3164 for ( Standard_Integer nbEdge = 0; Exp_Edge.More(); Exp_Edge.Next(), nbEdge++ ) {
3165 TopExp_Explorer Exp_Vertex( Exp_Edge.Current(), TopAbs_VERTEX);
3166 for ( Standard_Integer nbVertex = 0; Exp_Vertex.More(); Exp_Vertex.Next(), nbVertex++ ) {
3167 aPnt = BRep_Tool::Pnt( TopoDS::Vertex( Exp_Vertex.Current() ) );
3168 tab_Pnt[nbVertex] = aPnt;
3170 if ( ! tab_Pnt[0].IsEqual(tab_Pnt[1], dl_l) ) {
3171 BRepGProp::LinearProperties(Exp_Edge.Current(), aProps);
3172 if ( aProps.Mass() < min_l ) min_l = aProps.Mass();
3176 // Compute tolerances
3177 Tol_1D = dl_l * min_l;
3178 Tol_2D = dl_l * ( min_l * min_l) * ( 2. + dl_l);
3179 Tol_3D = dl_l * ( min_l * min_l * min_l ) * ( 3. + (3 * dl_l) + (dl_l * dl_l) );
3181 if (Tol_1D < Precision::Confusion()) Tol_1D = Precision::Confusion();
3182 if (Tol_2D < Precision::Confusion()) Tol_2D = Precision::Confusion();
3183 if (Tol_3D < Precision::Confusion()) Tol_3D = Precision::Confusion();
3185 //if (Tol_1D > 1.0) Tol_1D = 1.0;
3186 //if (Tol_2D > 1.0) Tol_2D = 1.0;
3187 //if (Tol_3D > 1.0) Tol_3D = 1.0;
3190 if ( iType == TopAbs_EDGE ) Tol_Mass = Tol_1D;
3191 else if ( iType == TopAbs_FACE ) Tol_Mass = Tol_2D;
3193 // Compute the ShapeWhat Mass
3194 for ( ; Exp_aWhat.More(); Exp_aWhat.Next() ) {
3195 if ( iType == TopAbs_EDGE ) BRepGProp::LinearProperties(Exp_aWhat.Current(), aProps);
3196 else if ( iType == TopAbs_FACE ) BRepGProp::SurfaceProperties(Exp_aWhat.Current(), aProps);
3197 else BRepGProp::VolumeProperties(Exp_aWhat.Current(), aProps);
3198 aWhat_Mass += aProps.Mass();
3201 // Searching for the sub-shapes inside the ShapeWhere shape
3202 TopTools_MapOfShape map_aWhere;
3203 for ( Exp_aWhere.ReInit(); Exp_aWhere.More(); Exp_aWhere.Next() ) {
3204 if (!map_aWhere.Add(Exp_aWhere.Current()))
3205 continue; // skip repeated shape to avoid mass addition
3206 GetShapeProperties( Exp_aWhere.Current(), tab_aWhere, aPnt );
3207 for ( Exp_aWhat.ReInit(); Exp_aWhat.More(); Exp_aWhat.Next() ) {
3208 GetShapeProperties( Exp_aWhat.Current(), tab_aWhat, aPnt_aWhat );
3209 if ( fabs(tab_aWhat[3] - tab_aWhere[3]) <= Tol_Mass && aPnt_aWhat.Distance(aPnt) <= Tol_1D )
3212 if ( (tab_aWhat[3] - tab_aWhere[3]) > Tol_Mass ) {
3213 aPntShape = BRepBuilderAPI_MakeVertex( aPnt ).Shape();
3214 aVertex = TopoDS::Vertex( aPntShape );
3215 BRepExtrema_DistShapeShape aWhereDistance ( aVertex, Exp_aWhere.Current() );
3216 BRepExtrema_DistShapeShape aWhatDistance ( aVertex, Exp_aWhat.Current() );
3217 if ( aWhereDistance.IsDone() && aWhatDistance.IsDone() &&
3218 fabs(aWhereDistance.Value() - aWhatDistance.Value()) <= Tol_1D )
3220 // 0020162: "EDF 961 GEOM : Getinplace is getting additionnal orthogonal faces"
3221 // aVertex must be projected to the same point on Where and on What
3222 gp_Pnt pOnWhat = aWhatDistance.PointOnShape2(1);
3223 gp_Pnt pOnWhere = aWhereDistance.PointOnShape2(1);
3224 isFound = ( pOnWhat.Distance(pOnWhere) <= Tol_1D );
3225 if ( isFound && iType == TopAbs_FACE )
3227 // check normals at pOnWhat and pOnWhere
3228 const double angleTol = PI/180.;
3229 gp_Vec normToWhat = GetNormal( TopoDS::Face(Exp_aWhat.Current()), aWhatDistance);
3230 gp_Vec normToWhere = GetNormal( TopoDS::Face(Exp_aWhere.Current()), aWhereDistance);
3231 if ( normToWhat * normToWhere < 0 )
3232 normToWhat.Reverse();
3233 isFound = ( normToWhat.Angle( normToWhere ) < angleTol );
3239 aWhereIndex = aWhereIndices.FindIndex(Exp_aWhere.Current());
3240 aModifiedList.Append(aWhereIndex);
3241 aWhere_Mass += tab_aWhere[3];
3246 if ( fabs( aWhat_Mass - aWhere_Mass ) <= Tol_Mass ) break;
3249 if (aModifiedList.Extent() == 0) { // Not found any Results
3250 SetErrorCode(NOT_FOUND_ANY);
3254 aModifiedArray = new TColStd_HArray1OfInteger (1, aModifiedList.Extent());
3255 TColStd_ListIteratorOfListOfInteger anIterModif (aModifiedList);
3256 for (Standard_Integer imod = 1; anIterModif.More(); anIterModif.Next(), imod++)
3257 aModifiedArray->SetValue(imod, anIterModif.Value());
3260 aResult = GetEngine()->AddSubShape(theShapeWhere, aModifiedArray);
3261 if (aResult.IsNull()) {
3262 SetErrorCode("Error in algorithm: result found, but cannot be returned.");
3266 if (aModifiedArray->Length() > 1) {
3268 aResult->SetType(GEOM_GROUP);
3270 //Set a sub shape type
3271 TopoDS_Shape aFirstFound = aWhereIndices.FindKey(aModifiedArray->Value(1));
3272 TopAbs_ShapeEnum aShapeType = aFirstFound.ShapeType();
3274 TDF_Label aFreeLabel = aResult->GetFreeLabel();
3275 TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aShapeType);
3278 //Make a Python command
3279 Handle(GEOM_Function) aFunction = aResult->GetFunction(1);
3281 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetInPlace("
3282 << theShapeWhere << ", " << theShapeWhat << ")";
3288 //=======================================================================
3289 //function : GetInPlaceByHistory
3291 //=======================================================================
3292 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlaceByHistory
3293 (Handle(GEOM_Object) theShapeWhere,
3294 Handle(GEOM_Object) theShapeWhat)
3298 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
3300 TopoDS_Shape aWhere = theShapeWhere->GetValue();
3301 TopoDS_Shape aWhat = theShapeWhat->GetValue();
3303 if (aWhere.IsNull() || aWhat.IsNull()) return NULL;
3305 Handle(GEOM_Function) aWhereFunction = theShapeWhere->GetLastFunction();
3306 if (aWhereFunction.IsNull()) return NULL;
3308 //Fill array of indices
3309 TopTools_IndexedMapOfShape aWhereIndices;
3310 TopExp::MapShapes(aWhere, aWhereIndices);
3313 TColStd_ListOfInteger aModifiedList;
3314 bool isFound = GetInPlaceOfShape(aWhereFunction, aWhereIndices, aWhat, aModifiedList);
3316 if (!isFound || aModifiedList.Extent() < 1) {
3317 SetErrorCode("Error: No history found for the sought shape or its sub-shapes.");
3321 Handle(TColStd_HArray1OfInteger) aModifiedArray =
3322 new TColStd_HArray1OfInteger (1, aModifiedList.Extent());
3323 TColStd_ListIteratorOfListOfInteger anIterModif (aModifiedList);
3324 for (Standard_Integer imod = 1; anIterModif.More(); anIterModif.Next(), imod++) {
3325 aModifiedArray->SetValue(imod, anIterModif.Value());
3329 Handle(GEOM_Object) aResult = GetEngine()->AddSubShape(theShapeWhere, aModifiedArray);
3330 if (aResult.IsNull()) {
3331 SetErrorCode("Error in algorithm: result found, but cannot be returned.");
3335 if (aModifiedArray->Length() > 1) {
3337 aResult->SetType(GEOM_GROUP);
3339 //Set a sub shape type
3340 TopoDS_Shape aFirstFound = aWhereIndices.FindKey(aModifiedArray->Value(1));
3341 TopAbs_ShapeEnum aShapeType = aFirstFound.ShapeType();
3343 TDF_Label aFreeLabel = aResult->GetFreeLabel();
3344 TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aShapeType);
3347 //Make a Python command
3348 Handle(GEOM_Function) aFunction = aResult->GetFunction(1);
3350 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetInPlaceByHistory("
3351 << theShapeWhere << ", " << theShapeWhat << ")";
3357 //=======================================================================
3358 //function : SortShapes
3360 //=======================================================================
3361 void GEOMImpl_IShapesOperations::SortShapes(TopTools_ListOfShape& SL)
3363 Standard_Integer MaxShapes = SL.Extent();
3364 TopTools_Array1OfShape aShapes (1,MaxShapes);
3365 TColStd_Array1OfInteger OrderInd(1,MaxShapes);
3366 TColStd_Array1OfReal MidXYZ (1,MaxShapes); //X,Y,Z;
3367 TColStd_Array1OfReal Length (1,MaxShapes); //X,Y,Z;
3369 // Computing of CentreOfMass
3370 Standard_Integer Index;
3373 TopTools_ListIteratorOfListOfShape it(SL);
3374 for (Index=1; it.More(); Index++)
3376 TopoDS_Shape S = it.Value();
3377 SL.Remove( it ); // == it.Next()
3379 OrderInd.SetValue (Index, Index);
3380 if (S.ShapeType() == TopAbs_VERTEX)
3382 GPoint = BRep_Tool::Pnt( TopoDS::Vertex( S ));
3383 Length.SetValue( Index, (Standard_Real) S.Orientation());
3387 BRepGProp::LinearProperties (S, GPr);
3388 GPoint = GPr.CentreOfMass();
3389 Length.SetValue( Index, GPr.Mass() );
3391 MidXYZ.SetValue(Index,
3392 GPoint.X()*999 + GPoint.Y()*99 + GPoint.Z()*0.9);
3393 //cout << Index << " L: " << Length(Index) << "CG: " << MidXYZ(Index) << endl;
3397 Standard_Integer aTemp;
3398 Standard_Boolean exchange, Sort = Standard_True;
3399 Standard_Real tol = Precision::Confusion();
3402 Sort = Standard_False;
3403 for (Index=1; Index < MaxShapes; Index++)
3405 exchange = Standard_False;
3406 Standard_Real dMidXYZ = MidXYZ(OrderInd(Index)) - MidXYZ(OrderInd(Index+1));
3407 Standard_Real dLength = Length(OrderInd(Index)) - Length(OrderInd(Index+1));
3408 if ( dMidXYZ >= tol ) {
3409 // cout << "MidXYZ: " << MidXYZ(OrderInd(Index))<< " > " <<MidXYZ(OrderInd(Index+1))
3410 // << " d: " << dMidXYZ << endl;
3411 exchange = Standard_True;
3413 else if ( Abs(dMidXYZ) < tol && dLength >= tol ) {
3414 // cout << "Length: " << Length(OrderInd(Index))<< " > " <<Length(OrderInd(Index+1))
3415 // << " d: " << dLength << endl;
3416 exchange = Standard_True;
3418 else if ( Abs(dMidXYZ) < tol && Abs(dLength) < tol &&
3419 aShapes(OrderInd(Index)).ShapeType() <= TopAbs_FACE) {
3421 // equal values possible on shapes such as two halves of a sphere and
3422 // a membrane inside the sphere
3424 BRepBndLib::Add( aShapes( OrderInd(Index) ), box1 );
3425 if ( box1.IsVoid() ) continue;
3426 BRepBndLib::Add( aShapes( OrderInd(Index+1) ), box2 );
3427 Standard_Real dSquareExtent = box1.SquareExtent() - box2.SquareExtent();
3428 if ( dSquareExtent >= tol ) {
3429 // cout << "SquareExtent: " << box1.SquareExtent()<<" > "<<box2.SquareExtent() << endl;
3430 exchange = Standard_True;
3432 else if ( Abs(dSquareExtent) < tol ) {
3433 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax, val1, val2;
3434 box1.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
3435 val1 = (aXmin+aXmax)*999 + (aYmin+aYmax)*99 + (aZmin+aZmax)*0.9;
3436 box2.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
3437 val2 = (aXmin+aXmax)*999 + (aYmin+aYmax)*99 + (aZmin+aZmax)*0.9;
3438 //exchange = val1 > val2;
3439 if ((val1 - val2) >= tol) {
3440 exchange = Standard_True;
3442 //cout << "box: " << val1<<" > "<<val2 << endl;
3448 // cout << "exchange " << Index << " & " << Index+1 << endl;
3449 aTemp = OrderInd(Index);
3450 OrderInd(Index) = OrderInd(Index+1);
3451 OrderInd(Index+1) = aTemp;
3452 Sort = Standard_True;
3457 for (Index=1; Index <= MaxShapes; Index++)
3458 SL.Append( aShapes( OrderInd(Index) ));
3461 //=======================================================================
3462 //function : CompsolidToCompound
3464 //=======================================================================
3465 TopoDS_Shape GEOMImpl_IShapesOperations::CompsolidToCompound (const TopoDS_Shape& theCompsolid)
3467 if (theCompsolid.ShapeType() != TopAbs_COMPSOLID) {
3468 return theCompsolid;
3471 TopoDS_Compound aCompound;
3473 B.MakeCompound(aCompound);
3475 TopTools_MapOfShape mapShape;
3476 TopoDS_Iterator It (theCompsolid, Standard_True, Standard_True);
3478 for (; It.More(); It.Next()) {
3479 TopoDS_Shape aShape_i = It.Value();
3480 if (mapShape.Add(aShape_i)) {
3481 B.Add(aCompound, aShape_i);
3488 //=======================================================================
3489 //function : CheckTriangulation
3491 //=======================================================================
3492 bool GEOMImpl_IShapesOperations::CheckTriangulation (const TopoDS_Shape& aShape)
3494 bool isTriangulation = true;
3496 TopExp_Explorer exp (aShape, TopAbs_FACE);
3499 TopLoc_Location aTopLoc;
3500 Handle(Poly_Triangulation) aTRF;
3501 aTRF = BRep_Tool::Triangulation(TopoDS::Face(exp.Current()), aTopLoc);
3502 if (aTRF.IsNull()) {
3503 isTriangulation = false;
3506 else // no faces, try edges
3508 TopExp_Explorer expe (aShape, TopAbs_EDGE);
3512 TopLoc_Location aLoc;
3513 Handle(Poly_Polygon3D) aPE = BRep_Tool::Polygon3D(TopoDS::Edge(expe.Current()), aLoc);
3515 isTriangulation = false;
3519 if (!isTriangulation) {
3520 // calculate deflection
3521 Standard_Real aDeviationCoefficient = 0.001;
3524 BRepBndLib::Add(aShape, B);
3525 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
3526 B.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
3528 Standard_Real dx = aXmax - aXmin, dy = aYmax - aYmin, dz = aZmax - aZmin;
3529 Standard_Real aDeflection = Max(Max(dx, dy), dz) * aDeviationCoefficient * 4;
3530 Standard_Real aHLRAngle = 0.349066;
3532 BRepMesh_IncrementalMesh Inc (aShape, aDeflection, Standard_False, aHLRAngle);
3538 #define MAX_TOLERANCE 1.e-7
3540 //=======================================================================
3541 //function : isSameEdge
3542 //purpose : Returns True if two edges coincide
3543 //=======================================================================
3544 static bool isSameEdge(const TopoDS_Edge& theEdge1, const TopoDS_Edge& theEdge2)
3546 TopoDS_Vertex V11, V12, V21, V22;
3547 TopExp::Vertices(theEdge1, V11, V12);
3548 TopExp::Vertices(theEdge2, V21, V22);
3549 gp_Pnt P11 = BRep_Tool::Pnt(V11);
3550 gp_Pnt P12 = BRep_Tool::Pnt(V12);
3551 gp_Pnt P21 = BRep_Tool::Pnt(V21);
3552 gp_Pnt P22 = BRep_Tool::Pnt(V22);
3553 bool coincide = false;
3555 //Check that ends of edges coincide
3556 if(P11.Distance(P21) <= MAX_TOLERANCE) {
3557 if(P12.Distance(P22) <= MAX_TOLERANCE) coincide = true;
3559 else if(P11.Distance(P22) <= MAX_TOLERANCE) {
3560 if(P12.Distance(P21) <= MAX_TOLERANCE) coincide = true;
3563 if(!coincide) return false;
3565 if (BRep_Tool::Degenerated(theEdge1))
3566 if (BRep_Tool::Degenerated(theEdge2)) return true;
3569 if (BRep_Tool::Degenerated(theEdge2)) return false;
3571 double U11, U12, U21, U22;
3572 Handle(Geom_Curve) C1 = BRep_Tool::Curve(theEdge1, U11, U12);
3573 Handle(Geom_Curve) C2 = BRep_Tool::Curve(theEdge2, U21, U22);
3574 if(C1->DynamicType() == C2->DynamicType()) return true;
3576 //Check that both edges has the same geometry
3577 double range = U12-U11;
3578 double U = U11+ range/3.0;
3579 gp_Pnt P1 = C1->Value(U); //Compute a point on one third of the edge's length
3580 U = U11+range*2.0/3.0;
3581 gp_Pnt P2 = C1->Value(U); //Compute a point on two thirds of the edge's length
3583 if(!GeomLib_Tool::Parameter(C2, P1, MAX_TOLERANCE, U) || U < U21 || U > U22)
3586 if(P1.Distance(C2->Value(U)) > MAX_TOLERANCE) return false;
3588 if(!GeomLib_Tool::Parameter(C2, P2, MAX_TOLERANCE, U) || U < U21 || U > U22)
3591 if(P2.Distance(C2->Value(U)) > MAX_TOLERANCE) return false;
3596 #include <TopoDS_TShape.hxx>
3597 //=======================================================================
3598 //function : isSameFace
3599 //purpose : Returns True if two faces coincide
3600 //=======================================================================
3601 static bool isSameFace(const TopoDS_Face& theFace1, const TopoDS_Face& theFace2)
3603 TopExp_Explorer E(theFace1, TopAbs_EDGE);
3604 TopTools_ListOfShape LS1, LS2;
3605 for(; E.More(); E.Next()) LS1.Append(E.Current());
3607 E.Init(theFace2, TopAbs_EDGE);
3608 for(; E.More(); E.Next()) LS2.Append(E.Current());
3610 //Compare the number of edges in the faces
3611 if(LS1.Extent() != LS2.Extent()) return false;
3613 double aMin = RealFirst(), aMax = RealLast();
3614 double xminB1=aMax, yminB1=aMax, zminB1=aMax, xminB2=aMax, yminB2=aMax, zminB2=aMax;
3615 double xmaxB1=aMin, ymaxB1=aMin, zmaxB1=aMin, xmaxB2=aMin, ymaxB2=aMin, zmaxB2=aMin;
3617 for(E.Init(theFace1, TopAbs_VERTEX); E.More(); E.Next()) {
3618 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
3619 if(P.X() < xminB1) xminB1 = P.X();
3620 if(P.Y() < yminB1) yminB1 = P.Y();
3621 if(P.Z() < zminB1) zminB1 = P.Z();
3622 if(P.X() > xmaxB1) xmaxB1 = P.X();
3623 if(P.Y() > ymaxB1) ymaxB1 = P.Y();
3624 if(P.Z() > zmaxB1) zmaxB1 = P.Z();
3627 for(E.Init(theFace2, TopAbs_VERTEX); E.More(); E.Next()) {
3628 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
3629 if(P.X() < xminB2) xminB2 = P.X();
3630 if(P.Y() < yminB2) yminB2 = P.Y();
3631 if(P.Z() < zminB2) zminB2 = P.Z();
3632 if(P.X() > xmaxB2) xmaxB2 = P.X();
3633 if(P.Y() > ymaxB2) ymaxB2 = P.Y();
3634 if(P.Z() > zmaxB2) zmaxB2 = P.Z();
3637 //Compare the bounding boxes of both faces
3638 if(gp_Pnt(xminB1, yminB1, zminB1).Distance(gp_Pnt(xminB2, yminB2, zminB2)) > MAX_TOLERANCE)
3641 if(gp_Pnt(xmaxB1, ymaxB1, zmaxB1).Distance(gp_Pnt(xmaxB2, ymaxB2, zmaxB2)) > MAX_TOLERANCE)
3644 Handle(Geom_Surface) S1 = BRep_Tool::Surface(theFace1);
3645 Handle(Geom_Surface) S2 = BRep_Tool::Surface(theFace2);
3647 //Check if there a coincidence of two surfaces at least in two points
3648 double U11, U12, V11, V12, U21, U22, V21, V22;
3649 BRepTools::UVBounds(theFace1, U11, U12, V11, V12);
3650 BRepTools::UVBounds(theFace2, U21, U22, V21, V22);
3652 double rangeU = U12-U11;
3653 double rangeV = V12-V11;
3654 double U = U11 + rangeU/3.0;
3655 double V = V11 + rangeV/3.0;
3656 gp_Pnt P1 = S1->Value(U, V);
3657 U = U11+rangeU*2.0/3.0;
3658 V = V11+rangeV*2.0/3.0;
3659 gp_Pnt P2 = S1->Value(U, V);
3661 if (!GeomLib_Tool::Parameters(S2, P1, MAX_TOLERANCE, U, V) || U < U21 || U > U22 || V < V21 || V > V22)
3664 if (P1.Distance(S2->Value(U,V)) > MAX_TOLERANCE) return false;
3666 if (!GeomLib_Tool::Parameters(S2, P2, MAX_TOLERANCE, U, V) || U < U21 || U > U22 || V < V21 || V > V22)
3669 if (P2.Distance(S2->Value(U, V)) > MAX_TOLERANCE) return false;
3671 //Check that each edge of the Face1 has a counterpart in the Face2
3672 TopTools_MapOfOrientedShape aMap;
3673 TopTools_ListIteratorOfListOfShape LSI1(LS1);
3674 for(; LSI1.More(); LSI1.Next()) {
3675 TopoDS_Edge E = TopoDS::Edge(LSI1.Value());
3676 bool isFound = false;
3677 TopTools_ListIteratorOfListOfShape LSI2(LS2);
3678 for(; LSI2.More(); LSI2.Next()) {
3679 TopoDS_Shape aValue = LSI2.Value();
3680 if(aMap.Contains(aValue)) continue; //To avoid checking already found edge several times
3681 if(isSameEdge(E, TopoDS::Edge(aValue))) {
3687 if(!isFound) return false;
3693 //=======================================================================
3694 //function : isSameSolid
3695 //purpose : Returns True if two solids coincide
3696 //=======================================================================
3697 bool isSameSolid(const TopoDS_Solid& theSolid1, const TopoDS_Solid& theSolid2)
3699 TopExp_Explorer E(theSolid1, TopAbs_FACE);
3700 TopTools_ListOfShape LS1, LS2;
3701 for(; E.More(); E.Next()) LS1.Append(E.Current());
3702 E.Init(theSolid2, TopAbs_FACE);
3703 for(; E.More(); E.Next()) LS2.Append(E.Current());
3705 if(LS1.Extent() != LS2.Extent()) return false;
3707 double aMin = RealFirst(), aMax = RealLast();
3708 double xminB1=aMax, yminB1=aMax, zminB1=aMax, xminB2=aMax, yminB2=aMax, zminB2=aMax;
3709 double xmaxB1=aMin, ymaxB1=aMin, zmaxB1=aMin, xmaxB2=aMin, ymaxB2=aMin, zmaxB2=aMin;
3711 for(E.Init(theSolid1, TopAbs_VERTEX); E.More(); E.Next()) {
3712 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
3713 if(P.X() < xminB1) xminB1 = P.X();
3714 if(P.Y() < yminB1) yminB1 = P.Y();
3715 if(P.Z() < zminB1) zminB1 = P.Z();
3716 if(P.X() > xmaxB1) xmaxB1 = P.X();
3717 if(P.Y() > ymaxB1) ymaxB1 = P.Y();
3718 if(P.Z() > zmaxB1) zmaxB1 = P.Z();
3721 for(E.Init(theSolid2, TopAbs_VERTEX); E.More(); E.Next()) {
3722 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
3723 if(P.X() < xminB2) xminB2 = P.X();
3724 if(P.Y() < yminB2) yminB2 = P.Y();
3725 if(P.Z() < zminB2) zminB2 = P.Z();
3726 if(P.X() > xmaxB2) xmaxB2 = P.X();
3727 if(P.Y() > ymaxB2) ymaxB2 = P.Y();
3728 if(P.Z() > zmaxB2) zmaxB2 = P.Z();
3731 //Compare the bounding boxes of both solids
3732 if(gp_Pnt(xminB1, yminB1, zminB1).Distance(gp_Pnt(xminB2, yminB2, zminB2)) > MAX_TOLERANCE)
3735 if(gp_Pnt(xmaxB1, ymaxB1, zmaxB1).Distance(gp_Pnt(xmaxB2, ymaxB2, zmaxB2)) > MAX_TOLERANCE)
3738 //Check that each face of the Solid1 has a counterpart in the Solid2
3739 TopTools_MapOfOrientedShape aMap;
3740 TopTools_ListIteratorOfListOfShape LSI1(LS1);
3741 for(; LSI1.More(); LSI1.Next()) {
3742 TopoDS_Face F = TopoDS::Face(LSI1.Value());
3743 bool isFound = false;
3744 TopTools_ListIteratorOfListOfShape LSI2(LS2);
3745 for(; LSI2.More(); LSI2.Next()) {
3746 if(aMap.Contains(LSI2.Value())) continue; //To avoid checking already found faces several times
3747 if(isSameFace(F, TopoDS::Face(LSI2.Value()))) {
3748 aMap.Add(LSI2.Value());
3753 if(!isFound) return false;
3759 //=======================================================================
3760 //function : GetSame
3762 //=======================================================================
3763 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetSame(const Handle(GEOM_Object)& theShapeWhere,
3764 const Handle(GEOM_Object)& theShapeWhat)
3767 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
3769 TopoDS_Shape aWhere = theShapeWhere->GetValue();
3770 TopoDS_Shape aWhat = theShapeWhat->GetValue();
3772 if (aWhere.IsNull() || aWhat.IsNull()) return NULL;
3775 bool isFound = false;
3776 TopoDS_Shape aSubShape;
3777 TopTools_MapOfShape aMap;
3779 switch(aWhat.ShapeType()) {
3780 case TopAbs_VERTEX: {
3781 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(aWhat));
3782 TopExp_Explorer E(aWhere, TopAbs_VERTEX);
3783 for(; E.More(); E.Next()) {
3784 if(!aMap.Add(E.Current())) continue;
3785 gp_Pnt P2 = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
3786 if(P.Distance(P2) <= MAX_TOLERANCE) {
3788 aSubShape = E.Current();
3795 TopoDS_Face aFace = TopoDS::Face(aWhat);
3796 TopExp_Explorer E(aWhere, TopAbs_FACE);
3797 for(; E.More(); E.Next()) {
3798 if(!aMap.Add(E.Current())) continue;
3799 if(isSameFace(aFace, TopoDS::Face(E.Current()))) {
3800 aSubShape = E.Current();
3808 TopoDS_Edge anEdge = TopoDS::Edge(aWhat);
3809 TopExp_Explorer E(aWhere, TopAbs_EDGE);
3810 for(; E.More(); E.Next()) {
3811 if(!aMap.Add(E.Current())) continue;
3812 if(isSameEdge(anEdge, TopoDS::Edge(E.Current()))) {
3813 aSubShape = E.Current();
3820 case TopAbs_SOLID: {
3821 TopoDS_Solid aSolid = TopoDS::Solid(aWhat);
3822 TopExp_Explorer E(aWhere, TopAbs_SOLID);
3823 for(; E.More(); E.Next()) {
3824 if(!aMap.Add(E.Current())) continue;
3825 if(isSameSolid(aSolid, TopoDS::Solid(E.Current()))) {
3826 aSubShape = E.Current();
3838 TopTools_IndexedMapOfShape anIndices;
3839 TopExp::MapShapes(aWhere, anIndices);
3840 if (anIndices.Contains(aSubShape))
3841 anIndex = anIndices.FindIndex(aSubShape);
3844 if(anIndex < 0) return NULL;
3846 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
3848 anArray->SetValue(1, anIndex);
3850 Handle(GEOM_Object) aResult = GetEngine()->AddSubShape(theShapeWhere, anArray);
3851 Handle(GEOM_Function) aFunction = aResult->GetLastFunction();
3853 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetSame("
3854 << theShapeWhere << ", " << theShapeWhat << ")";