1 // Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
2 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License.
9 // This library is distributed in the hope that it will be useful
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // Lesser General Public License for more details.
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 #include <Standard_Stream.hxx>
22 #include "GEOMImpl_IShapesOperations.hxx"
24 #include "GEOMImpl_Types.hxx"
26 #include "GEOMImpl_VectorDriver.hxx"
27 #include "GEOMImpl_ShapeDriver.hxx"
28 #include "GEOMImpl_CopyDriver.hxx"
29 #include "GEOMImpl_GlueDriver.hxx"
31 #include "GEOMImpl_IVector.hxx"
32 #include "GEOMImpl_IShapes.hxx"
33 #include "GEOMImpl_IGlue.hxx"
35 #include "GEOMImpl_Block6Explorer.hxx"
37 #include "GEOM_Function.hxx"
38 #include "GEOM_PythonDump.hxx"
40 #include "GEOMAlgo_FinderShapeOn1.hxx"
41 #include "GEOMAlgo_FinderShapeOnQuad.hxx"
43 #include "utilities.h"
45 #include "Utils_ExceptHandlers.hxx"
47 #include <TFunction_DriverTable.hxx>
48 #include <TFunction_Driver.hxx>
49 #include <TFunction_Logbook.hxx>
50 #include <TDataStd_Integer.hxx>
51 #include <TDataStd_IntegerArray.hxx>
52 #include <TDF_Tool.hxx>
54 #include <BRepExtrema_ExtCF.hxx>
56 #include <BRep_Tool.hxx>
57 #include <BRepGProp.hxx>
58 #include <BRepAdaptor_Curve.hxx>
59 #include <BRepAdaptor_Surface.hxx>
60 #include <BRepBndLib.hxx>
61 #include <BRepBuilderAPI_MakeFace.hxx>
62 #include <BRepMesh_IncrementalMesh.hxx>
67 #include <TopoDS_Shape.hxx>
68 #include <TopoDS_Face.hxx>
69 #include <TopoDS_Edge.hxx>
70 #include <TopoDS_Vertex.hxx>
71 #include <TopoDS_Iterator.hxx>
72 #include <TopExp_Explorer.hxx>
73 #include <TopLoc_Location.hxx>
74 #include <TopTools_MapOfShape.hxx>
75 #include <TopTools_Array1OfShape.hxx>
76 #include <TopTools_ListIteratorOfListOfShape.hxx>
77 #include <TopTools_IndexedMapOfShape.hxx>
79 #include <Geom_Surface.hxx>
80 #include <Geom_Plane.hxx>
81 #include <Geom_SphericalSurface.hxx>
82 #include <Geom_CylindricalSurface.hxx>
83 #include <GeomAdaptor_Surface.hxx>
85 #include <Geom2d_Curve.hxx>
87 #include <Bnd_Box.hxx>
88 #include <GProp_GProps.hxx>
91 #include <TColStd_ListOfInteger.hxx>
92 #include <TColStd_ListIteratorOfListOfInteger.hxx>
93 #include <TColStd_Array1OfReal.hxx>
94 #include <TColStd_HArray1OfInteger.hxx>
98 #include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
100 //=============================================================================
104 //=============================================================================
105 GEOMImpl_IShapesOperations::GEOMImpl_IShapesOperations (GEOM_Engine* theEngine, int theDocID)
106 : GEOM_IOperations(theEngine, theDocID)
108 MESSAGE("GEOMImpl_IShapesOperations::GEOMImpl_IShapesOperations");
111 //=============================================================================
115 //=============================================================================
116 GEOMImpl_IShapesOperations::~GEOMImpl_IShapesOperations()
118 MESSAGE("GEOMImpl_IShapesOperations::~GEOMImpl_IShapesOperations");
122 //=============================================================================
126 //=============================================================================
127 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeEdge
128 (Handle(GEOM_Object) thePnt1, Handle(GEOM_Object) thePnt2)
132 if (thePnt1.IsNull() || thePnt2.IsNull()) return NULL;
134 //Add a new Edge object
135 Handle(GEOM_Object) anEdge = GetEngine()->AddObject(GetDocID(), GEOM_EDGE);
137 //Add a new Vector function
138 Handle(GEOM_Function) aFunction =
139 anEdge->AddFunction(GEOMImpl_VectorDriver::GetID(), VECTOR_TWO_PNT);
141 //Check if the function is set correctly
142 if (aFunction->GetDriverGUID() != GEOMImpl_VectorDriver::GetID()) return NULL;
144 GEOMImpl_IVector aPI (aFunction);
146 Handle(GEOM_Function) aRef1 = thePnt1->GetLastFunction();
147 Handle(GEOM_Function) aRef2 = thePnt2->GetLastFunction();
148 if (aRef1.IsNull() || aRef2.IsNull()) return NULL;
150 aPI.SetPoint1(aRef1);
151 aPI.SetPoint2(aRef2);
153 //Compute the Edge value
155 if (!GetSolver()->ComputeFunction(aFunction)) {
156 SetErrorCode("Vector driver failed");
160 catch (Standard_Failure) {
161 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
162 SetErrorCode(aFail->GetMessageString());
166 //Make a Python command
167 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdge("
168 << thePnt1 << ", " << thePnt2 << ")";
174 //=============================================================================
178 //=============================================================================
179 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeWire
180 (list<Handle(GEOM_Object)> theShapes)
182 return MakeShape(theShapes, GEOM_WIRE, WIRE_EDGES, "MakeWire");
185 //=============================================================================
189 //=============================================================================
190 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFace (Handle(GEOM_Object) theWire,
191 const bool isPlanarWanted)
195 if (theWire.IsNull()) return NULL;
197 //Add a new Face object
198 Handle(GEOM_Object) aFace = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
200 //Add a new Shape function for creation of a face from a wire
201 Handle(GEOM_Function) aFunction =
202 aFace->AddFunction(GEOMImpl_ShapeDriver::GetID(), FACE_WIRE);
203 if (aFunction.IsNull()) return NULL;
205 //Check if the function is set correctly
206 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
208 GEOMImpl_IShapes aCI (aFunction);
210 Handle(GEOM_Function) aRefWire = theWire->GetLastFunction();
212 if (aRefWire.IsNull()) return NULL;
214 aCI.SetBase(aRefWire);
215 aCI.SetIsPlanar(isPlanarWanted);
217 //Compute the Face value
219 if (!GetSolver()->ComputeFunction(aFunction)) {
220 SetErrorCode("Shape driver failed to compute a face");
224 catch (Standard_Failure) {
225 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
226 SetErrorCode(aFail->GetMessageString());
230 //Make a Python command
231 GEOM::TPythonDump(aFunction) << aFace << " = geompy.MakeFace("
232 << theWire << ", " << (int)isPlanarWanted << ")";
238 //=============================================================================
242 //=============================================================================
243 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFaceWires
244 (list<Handle(GEOM_Object)> theShapes,
245 const bool isPlanarWanted)
250 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
253 Handle(GEOM_Function) aFunction =
254 aShape->AddFunction(GEOMImpl_ShapeDriver::GetID(), FACE_WIRES);
255 if (aFunction.IsNull()) return NULL;
257 //Check if the function is set correctly
258 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
260 GEOMImpl_IShapes aCI (aFunction);
262 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
265 list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
266 for (; it != theShapes.end(); it++) {
267 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
268 if (aRefSh.IsNull()) {
269 SetErrorCode("NULL argument shape for the face construction");
272 aShapesSeq->Append(aRefSh);
274 aCI.SetShapes(aShapesSeq);
276 aCI.SetIsPlanar(isPlanarWanted);
280 if (!GetSolver()->ComputeFunction(aFunction)) {
281 SetErrorCode("Shape driver failed");
285 catch (Standard_Failure) {
286 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
287 SetErrorCode(aFail->GetMessageString());
291 //Make a Python command
292 GEOM::TPythonDump pd (aFunction);
293 pd << aShape << " = geompy.MakeFaceWires([";
296 it = theShapes.begin();
297 if (it != theShapes.end()) {
299 while (it != theShapes.end()) {
300 pd << ", " << (*it++);
303 pd << "], " << (int)isPlanarWanted << ")";
309 //=============================================================================
313 //=============================================================================
314 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeShell
315 (list<Handle(GEOM_Object)> theShapes)
317 return MakeShape(theShapes, GEOM_SHELL, SHELL_FACES, "MakeShell");
320 //=============================================================================
324 //=============================================================================
325 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeSolidShells
326 (list<Handle(GEOM_Object)> theShapes)
328 return MakeShape(theShapes, GEOM_SOLID, SOLID_SHELLS, "MakeSolid");
331 //=============================================================================
335 //=============================================================================
336 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeSolidShell (Handle(GEOM_Object) theShell)
340 if (theShell.IsNull()) return NULL;
342 //Add a new Solid object
343 Handle(GEOM_Object) aSolid = GetEngine()->AddObject(GetDocID(), GEOM_SOLID);
345 //Add a new Solid function for creation of a solid from a shell
346 Handle(GEOM_Function) aFunction =
347 aSolid->AddFunction(GEOMImpl_ShapeDriver::GetID(), SOLID_SHELL);
348 if (aFunction.IsNull()) return NULL;
350 //Check if the function is set correctly
351 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
353 GEOMImpl_IShapes aCI (aFunction);
355 Handle(GEOM_Function) aRefShell = theShell->GetLastFunction();
357 if (aRefShell.IsNull()) return NULL;
359 aCI.SetBase(aRefShell);
361 //Compute the Solid value
363 if (!GetSolver()->ComputeFunction(aFunction)) {
364 SetErrorCode("Solid driver failed");
368 catch (Standard_Failure) {
369 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
370 SetErrorCode(aFail->GetMessageString());
374 //Make a Python command
375 GEOM::TPythonDump(aFunction) << aSolid
376 << " = geompy.MakeSolid(" << theShell << ")";
382 //=============================================================================
386 //=============================================================================
387 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeCompound
388 (list<Handle(GEOM_Object)> theShapes)
390 return MakeShape(theShapes, GEOM_COMPOUND, COMPOUND_SHAPES, "MakeCompound");
393 //=============================================================================
397 //=============================================================================
398 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeShape
399 (list<Handle(GEOM_Object)> theShapes,
400 const Standard_Integer theObjectType,
401 const Standard_Integer theFunctionType,
402 const TCollection_AsciiString& theMethodName)
407 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), theObjectType);
410 Handle(GEOM_Function) aFunction =
411 aShape->AddFunction(GEOMImpl_ShapeDriver::GetID(), theFunctionType);
412 if (aFunction.IsNull()) return NULL;
414 //Check if the function is set correctly
415 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
417 GEOMImpl_IShapes aCI (aFunction);
419 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
422 list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
423 for (; it != theShapes.end(); it++) {
424 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
425 if (aRefSh.IsNull()) {
426 SetErrorCode("NULL argument shape for the shape construction");
429 aShapesSeq->Append(aRefSh);
431 aCI.SetShapes(aShapesSeq);
435 if (!GetSolver()->ComputeFunction(aFunction)) {
436 SetErrorCode("Shape driver failed");
440 catch (Standard_Failure) {
441 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
442 SetErrorCode(aFail->GetMessageString());
446 //Make a Python command
447 GEOM::TPythonDump pd (aFunction);
448 pd << aShape << " = geompy." << theMethodName.ToCString() << "([";
451 it = theShapes.begin();
452 if (it != theShapes.end()) {
454 while (it != theShapes.end()) {
455 pd << ", " << (*it++);
464 //=============================================================================
468 //=============================================================================
469 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeGlueFaces
470 (Handle(GEOM_Object) theShape,
471 const Standard_Real theTolerance)
475 if (theShape.IsNull()) return NULL;
477 //Add a new Glued object
478 Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
480 //Add a new Glue function
481 Handle(GEOM_Function) aFunction;
482 aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_FACES);
483 if (aFunction.IsNull()) return NULL;
485 //Check if the function is set correctly
486 if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
488 GEOMImpl_IGlue aCI (aFunction);
490 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
491 if (aRefShape.IsNull()) return NULL;
493 aCI.SetBase(aRefShape);
494 aCI.SetTolerance(theTolerance);
496 //Compute the sub-shape value
497 Standard_Boolean isWarning = Standard_False;
499 if (!GetSolver()->ComputeFunction(aFunction)) {
500 SetErrorCode("Shape driver failed to glue faces");
504 catch (Standard_Failure) {
505 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
506 SetErrorCode(aFail->GetMessageString());
507 // to provide warning
508 if (!aFunction->GetValue().IsNull()) {
509 isWarning = Standard_True;
515 //Make a Python command
516 GEOM::TPythonDump(aFunction) << aGlued << " = geompy.MakeGlueFaces("
517 << theShape << ", " << theTolerance << ")";
519 // to provide warning
520 if (!isWarning) SetErrorCode(OK);
524 //=============================================================================
528 //=============================================================================
529 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::MakeExplode
530 (Handle(GEOM_Object) theShape,
531 const Standard_Integer theShapeType,
532 const Standard_Boolean isSorted)
536 if (theShape.IsNull()) return NULL;
537 TopoDS_Shape aShape = theShape->GetValue();
538 if (aShape.IsNull()) return NULL;
540 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
541 Handle(GEOM_Object) anObj;
542 Handle(GEOM_Function) aFunction;
543 TopTools_MapOfShape mapShape;
544 TopTools_ListOfShape listShape;
546 if (aShape.ShapeType() == TopAbs_COMPOUND &&
547 (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
548 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPSOLID ||
549 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPOUND)) {
550 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
551 for (; It.More(); It.Next()) {
552 if (mapShape.Add(It.Value())) {
553 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
554 TopAbs_ShapeEnum(theShapeType) == It.Value().ShapeType()) {
555 listShape.Append(It.Value());
560 TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
561 for (; exp.More(); exp.Next())
562 if (mapShape.Add(exp.Current()))
563 listShape.Append(exp.Current());
566 if (listShape.IsEmpty()) {
567 SetErrorCode("The given shape has no sub-shapes of the requested type");
572 SortShapes(listShape);
574 TopTools_IndexedMapOfShape anIndices;
575 TopExp::MapShapes(aShape, anIndices);
576 Handle(TColStd_HArray1OfInteger) anArray;
578 TopTools_ListIteratorOfListOfShape itSub (listShape);
579 TCollection_AsciiString anAsciiList, anEntry;
580 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
581 TopoDS_Shape aValue = itSub.Value();
582 anArray = new TColStd_HArray1OfInteger(1,1);
583 anArray->SetValue(1, anIndices.FindIndex(aValue));
584 anObj = GetEngine()->AddSubShape(theShape, anArray);
587 // for python command
588 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
589 anAsciiList += anEntry;
593 //Make a Python command
594 anAsciiList.Trunc(anAsciiList.Length() - 1);
596 aFunction = theShape->GetLastFunction();
598 GEOM::TPythonDump pd (aFunction, /*append=*/true);
599 pd << "[" << anAsciiList.ToCString();
600 pd << "] = geompy.SubShapeAll" << (isSorted ? "Sorted(" : "(");
601 pd << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
608 //=============================================================================
612 //=============================================================================
613 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::SubShapeAllIDs
614 (Handle(GEOM_Object) theShape,
615 const Standard_Integer theShapeType,
616 const Standard_Boolean isSorted)
620 if (theShape.IsNull()) return NULL;
621 TopoDS_Shape aShape = theShape->GetValue();
622 if (aShape.IsNull()) return NULL;
624 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
625 TopTools_MapOfShape mapShape;
626 TopTools_ListOfShape listShape;
628 if (aShape.ShapeType() == TopAbs_COMPOUND &&
629 (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
630 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPSOLID ||
631 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPOUND)) {
632 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
633 for (; It.More(); It.Next()) {
634 if (mapShape.Add(It.Value())) {
635 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
636 TopAbs_ShapeEnum(theShapeType) == It.Value().ShapeType()) {
637 listShape.Append(It.Value());
642 TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
643 for (; exp.More(); exp.Next())
644 if (mapShape.Add(exp.Current()))
645 listShape.Append(exp.Current());
648 if (listShape.IsEmpty()) {
649 SetErrorCode("The given shape has no sub-shapes of the requested type");
654 SortShapes(listShape);
656 TopTools_IndexedMapOfShape anIndices;
657 TopExp::MapShapes(aShape, anIndices);
658 Handle(TColStd_HArray1OfInteger) anArray;
660 TopTools_ListIteratorOfListOfShape itSub (listShape);
661 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
662 TopoDS_Shape aValue = itSub.Value();
663 aSeq->Append(anIndices.FindIndex(aValue));
666 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
668 //Make a Python command
669 GEOM::TPythonDump pd (aFunction, /*append=*/true);
670 pd << "listSubShapeIDs = geompy.SubShapeAll";
671 pd << (isSorted ? "SortedIDs(" : "IDs(");
672 pd << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
678 //=============================================================================
682 //=============================================================================
683 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetSubShape
684 (Handle(GEOM_Object) theMainShape,
685 const Standard_Integer theID)
689 if (theMainShape.IsNull()) return NULL;
691 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
692 anArray->SetValue(1, theID);
693 Handle(GEOM_Object) anObj = GetEngine()->AddSubShape(theMainShape, anArray,true);
694 if (anObj.IsNull()) {
695 SetErrorCode("Can not get a sub-shape with the given ID");
699 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
701 //Make a Python command
702 GEOM::TPythonDump(aFunction) << anObj << " = geompy.GetSubShape("
703 << theMainShape << ", [" << theID << "])";
709 //=============================================================================
713 //=============================================================================
714 Standard_Integer GEOMImpl_IShapesOperations::GetSubShapeIndex (Handle(GEOM_Object) theMainShape,
715 Handle(GEOM_Object) theSubShape)
719 TopoDS_Shape aMainShape = theMainShape->GetValue();
720 TopoDS_Shape aSubShape = theSubShape->GetValue();
722 if (aMainShape.IsNull() || aSubShape.IsNull()) return -1;
724 TopTools_IndexedMapOfShape anIndices;
725 TopExp::MapShapes(aMainShape, anIndices);
726 if (anIndices.Contains(aSubShape)) {
728 return anIndices.FindIndex(aSubShape);
734 //=============================================================================
738 //=============================================================================
739 Standard_Integer GEOMImpl_IShapesOperations::GetTopologyIndex (Handle(GEOM_Object) theMainShape,
740 Handle(GEOM_Object) theSubShape)
744 TopoDS_Shape aMainShape = theMainShape->GetValue();
745 TopoDS_Shape aSubShape = theSubShape->GetValue();
747 if (aMainShape.IsNull() || aSubShape.IsNull()) {
748 SetErrorCode("Null argument shape given");
753 if (aSubShape.ShapeType() == TopAbs_COMPOUND) {
755 TopTools_ListOfShape CL;
756 CL.Append(aMainShape);
757 TopTools_ListIteratorOfListOfShape itC;
758 for (itC.Initialize(CL); itC.More(); itC.Next()) {
759 for (it.Initialize(itC.Value()); it.More(); it.Next()) {
760 if (it.Value().ShapeType() == TopAbs_COMPOUND) {
761 if (it.Value().IsSame(aSubShape))
765 CL.Append(it.Value());
770 TopExp_Explorer anExp (aMainShape, aSubShape.ShapeType());
771 TopTools_MapOfShape M;
772 for (; anExp.More(); anExp.Next()) {
773 if (M.Add(anExp.Current())) {
774 if (anExp.Current().IsSame(aSubShape))
781 SetErrorCode("The sub-shape does not belong to the main shape");
785 //=============================================================================
789 //=============================================================================
790 TCollection_AsciiString GEOMImpl_IShapesOperations::GetShapeTypeString (Handle(GEOM_Object) theShape)
794 TCollection_AsciiString aTypeName ("Null Shape");
796 TopoDS_Shape aShape = theShape->GetValue();
800 switch (aShape.ShapeType() )
802 case TopAbs_COMPOUND:
803 aTypeName = "Compound";
805 case TopAbs_COMPSOLID:
806 aTypeName = "Compound Solid";
816 BRepAdaptor_Surface surf (TopoDS::Face(aShape));
817 if (surf.GetType() == GeomAbs_Plane)
819 else if (surf.GetType() == GeomAbs_Cylinder)
820 aTypeName = "Cylindrical Face";
821 else if (surf.GetType() == GeomAbs_Sphere)
822 aTypeName = "Spherical Face";
823 else if (surf.GetType() == GeomAbs_Torus)
824 aTypeName = "Toroidal Face";
825 else if (surf.GetType() == GeomAbs_Cone)
826 aTypeName = "Conical Face";
828 aTypeName = "GEOM::FACE";
836 BRepAdaptor_Curve curv (TopoDS::Edge(aShape));
837 if (curv.GetType() == GeomAbs_Line) {
838 if ((Abs(curv.FirstParameter()) >= 1E6) ||
839 (Abs(curv.LastParameter()) >= 1E6))
843 } else if (curv.GetType() == GeomAbs_Circle) {
845 aTypeName = "Circle";
854 aTypeName = "Vertex";
860 aTypeName = "Shape of unknown type";
867 //=============================================================================
871 //=============================================================================
872 Standard_Integer GEOMImpl_IShapesOperations::NumberOfFaces (Handle(GEOM_Object) theShape)
876 Standard_Integer nb = 0;
878 if (theShape.IsNull()) return -1;
879 TopoDS_Shape aShape = theShape->GetValue();
880 if (aShape.IsNull()) return -1;
882 TopTools_MapOfShape mapShape;
884 TopExp_Explorer exp (aShape, TopAbs_FACE);
885 for (; exp.More(); exp.Next())
886 if (mapShape.Add(exp.Current()))
893 //=============================================================================
897 //=============================================================================
898 Standard_Integer GEOMImpl_IShapesOperations::NumberOfEdges (Handle(GEOM_Object) theShape)
902 Standard_Integer nb = 0;
904 if (theShape.IsNull()) return -1;
905 TopoDS_Shape aShape = theShape->GetValue();
906 if (aShape.IsNull()) return -1;
908 TopTools_MapOfShape mapShape;
910 TopExp_Explorer exp (aShape, TopAbs_EDGE);
911 for (; exp.More(); exp.Next())
912 if (mapShape.Add(exp.Current()))
919 //=============================================================================
923 //=============================================================================
924 Handle(GEOM_Object) GEOMImpl_IShapesOperations::ReverseShape(Handle(GEOM_Object) theShape)
928 if (theShape.IsNull()) return NULL;
930 //Add a new reversed object
931 Handle(GEOM_Object) aReversed = GetEngine()->AddObject(GetDocID(), theShape->GetType());
933 //Add a new Revese function
934 Handle(GEOM_Function) aFunction;
935 aFunction = aReversed->AddFunction(GEOMImpl_ShapeDriver::GetID(), REVERSE_ORIENTATION);
936 if (aFunction.IsNull()) return NULL;
938 //Check if the function is set correctly
939 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
941 GEOMImpl_IShapes aSI (aFunction);
943 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
944 if (aRefShape.IsNull()) return NULL;
946 aSI.SetBase(aRefShape);
948 //Compute the sub-shape value
950 if (!GetSolver()->ComputeFunction(aFunction)) {
951 SetErrorCode("Shape driver failed to reverse shape");
955 catch (Standard_Failure) {
956 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
957 SetErrorCode(aFail->GetMessageString());
961 //Make a Python command
962 GEOM::TPythonDump(aFunction) << aReversed
963 << " = geompy.ChangeOrientation(" << theShape << ")";
969 //=============================================================================
973 //=============================================================================
974 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetFreeFacesIDs
975 (Handle(GEOM_Object) theShape)
979 if (theShape.IsNull()) return NULL;
980 TopoDS_Shape aShape = theShape->GetValue();
981 if (aShape.IsNull()) return NULL;
983 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
985 TopTools_IndexedDataMapOfShapeListOfShape mapFaceBlocks;
986 GEOMImpl_Block6Explorer::MapShapesAndAncestors
987 (aShape, TopAbs_FACE, TopAbs_SOLID, mapFaceBlocks);
989 Standard_Integer ind = 1, nbFaces = mapFaceBlocks.Extent();
992 SetErrorCode("The given shape has no faces");
996 TopTools_IndexedMapOfShape anIndices;
997 TopExp::MapShapes(aShape, anIndices);
1000 for (; ind <= nbFaces; ind++) {
1001 if (mapFaceBlocks.FindFromIndex(ind).Extent() != 2) {
1002 id = anIndices.FindIndex(mapFaceBlocks.FindKey(ind));
1007 //The explode doesn't change object so no new function is required.
1008 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
1010 //Make a Python command
1011 GEOM::TPythonDump(aFunction, /*append=*/true)
1012 << "listFreeFacesIDs = geompy.GetFreeFacesIDs(" << theShape << ")";
1018 //=======================================================================
1019 //function : GetSharedShapes
1021 //=======================================================================
1023 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetSharedShapes
1024 (Handle(GEOM_Object) theShape1,
1025 Handle(GEOM_Object) theShape2,
1026 const Standard_Integer theShapeType)
1030 if (theShape1.IsNull() || theShape2.IsNull()) return NULL;
1032 TopoDS_Shape aShape1 = theShape1->GetValue();
1033 TopoDS_Shape aShape2 = theShape2->GetValue();
1035 if (aShape1.IsNull() || aShape2.IsNull()) return NULL;
1037 TopTools_IndexedMapOfShape anIndices;
1038 TopExp::MapShapes(aShape1, anIndices);
1039 Handle(TColStd_HArray1OfInteger) anArray;
1041 TopTools_IndexedMapOfShape mapShape1;
1042 TopExp::MapShapes(aShape1, TopAbs_ShapeEnum(theShapeType), mapShape1);
1044 Handle(GEOM_Object) anObj;
1045 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1046 TCollection_AsciiString anAsciiList, anEntry;
1048 TopTools_MapOfShape mapShape2;
1049 TopExp_Explorer exp (aShape2, TopAbs_ShapeEnum(theShapeType));
1050 for (; exp.More(); exp.Next()) {
1051 TopoDS_Shape aSS = exp.Current();
1052 if (mapShape2.Add(aSS) && mapShape1.Contains(aSS)) {
1053 anArray = new TColStd_HArray1OfInteger(1,1);
1054 anArray->SetValue(1, anIndices.FindIndex(aSS));
1055 anObj = GetEngine()->AddSubShape(theShape1, anArray);
1056 aSeq->Append(anObj);
1058 // for python command
1059 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
1060 anAsciiList += anEntry;
1065 if (aSeq->IsEmpty()) {
1066 SetErrorCode("The given shapes have no shared sub-shapes of the requested type");
1070 //Make a Python command
1071 anAsciiList.Trunc(anAsciiList.Length() - 1);
1073 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1075 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
1076 << "] = geompy.GetSharedShapes(" << theShape1 << ", "
1077 << theShape2 << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
1083 //=============================================================================
1087 //=============================================================================
1088 static GEOM::TPythonDump& operator<< (GEOM::TPythonDump& theDump,
1089 const GEOMAlgo_State theState)
1092 case GEOMAlgo_ST_IN:
1093 theDump << "geompy.GEOM.ST_IN";
1095 case GEOMAlgo_ST_OUT:
1096 theDump << "geompy.GEOM.ST_OUT";
1098 case GEOMAlgo_ST_ON:
1099 theDump << "geompy.GEOM.ST_ON";
1101 case GEOMAlgo_ST_ONIN:
1102 theDump << "geompy.GEOM.ST_ONIN";
1104 case GEOMAlgo_ST_ONOUT:
1105 theDump << "geompy.GEOM.ST_ONOUT";
1108 theDump << "geompy.GEOM.ST_UNKNOWN";
1114 //=======================================================================
1115 //function : checkTypeShapesOn
1117 * \brief Checks if theShapeType parameter of GetShapesOnXXX() is OK
1118 * \param theShapeType - the shape type to check
1119 * \retval bool - result of the check
1121 //=======================================================================
1123 bool GEOMImpl_IShapesOperations::checkTypeShapesOn(const Standard_Integer theShapeType)
1125 if (theShapeType != TopAbs_VERTEX &&
1126 theShapeType != TopAbs_EDGE &&
1127 theShapeType != TopAbs_FACE &&
1128 theShapeType != TopAbs_SOLID) {
1129 SetErrorCode("Only solids, vertices, edges or faces can be found by this method");
1135 //=======================================================================
1136 //function : makePlane
1138 * \brief Creates Geom_Plane
1139 * \param theAx1 - shape object defining plane parameters
1140 * \retval Handle(Geom_Surface) - resulting surface
1142 //=======================================================================
1144 Handle(Geom_Surface) GEOMImpl_IShapesOperations::makePlane(const TopoDS_Shape& anAx1)
1146 if (anAx1.ShapeType() != TopAbs_EDGE) return NULL;
1147 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
1148 TopoDS_Vertex V1, V2;
1149 TopExp::Vertices(anEdge, V1, V2, Standard_True);
1150 if (V1.IsNull() || V2.IsNull()) {
1151 SetErrorCode("Bad edge given for the plane normal vector");
1154 gp_Pnt aLoc = BRep_Tool::Pnt(V1);
1155 gp_Vec aVec (aLoc, BRep_Tool::Pnt(V2));
1156 if (aVec.Magnitude() < Precision::Confusion()) {
1157 SetErrorCode("Vector with null magnitude given");
1160 return new Geom_Plane(aLoc, aVec);
1163 //=======================================================================
1164 //function : makeCylinder
1166 * \brief Creates Geom_CylindricalSurface
1167 * \param theAx1 - edge defining cylinder axis
1168 * \param theRadius - cylinder radius
1169 * \retval Handle(Geom_Surface) - resulting surface
1171 //=======================================================================
1173 Handle(Geom_Surface) GEOMImpl_IShapesOperations::makeCylinder(const TopoDS_Shape& anAxis,
1174 const Standard_Real theRadius)
1176 //Axis of the cylinder
1177 if (anAxis.ShapeType() != TopAbs_EDGE) {
1178 SetErrorCode("Not an edge given for the axis");
1181 TopoDS_Edge anEdge = TopoDS::Edge(anAxis);
1182 TopoDS_Vertex V1, V2;
1183 TopExp::Vertices(anEdge, V1, V2, Standard_True);
1184 if (V1.IsNull() || V2.IsNull()) {
1185 SetErrorCode("Bad edge given for the axis");
1188 gp_Pnt aLoc = BRep_Tool::Pnt(V1);
1189 gp_Vec aVec (aLoc, BRep_Tool::Pnt(V2));
1190 if (aVec.Magnitude() < Precision::Confusion()) {
1191 SetErrorCode("Vector with null magnitude given");
1195 gp_Ax3 anAx3 (aLoc, aVec);
1196 return new Geom_CylindricalSurface(anAx3, theRadius);
1200 //=======================================================================
1201 //function : getShapesOnSurfaceIDs
1203 * \brief Find IDs of subshapes complying with given status about surface
1204 * \param theSurface - the surface to check state of subshapes against
1205 * \param theShape - the shape to explore
1206 * \param theShapeType - type of subshape of theShape
1207 * \param theState - required state
1208 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1210 //=======================================================================
1212 Handle(TColStd_HSequenceOfInteger)
1213 GEOMImpl_IShapesOperations::getShapesOnSurfaceIDs(const Handle(Geom_Surface)& theSurface,
1214 const TopoDS_Shape& theShape,
1215 TopAbs_ShapeEnum theShapeType,
1216 GEOMAlgo_State theState)
1218 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
1220 // Check presence of triangulation, build if need
1221 if (!CheckTriangulation(theShape))
1225 GEOMAlgo_FinderShapeOn1 aFinder;
1226 Standard_Real aTol = 0.0001; // default value
1228 aFinder.SetShape(theShape);
1229 aFinder.SetTolerance(aTol);
1230 aFinder.SetSurface(theSurface);
1231 aFinder.SetShapeType(theShapeType);
1232 aFinder.SetState(theState);
1234 // Sets the minimal number of inner points for the faces that do not have own
1235 // inner points at all (for e.g. rectangular planar faces have just 2 triangles).
1237 aFinder.SetNbPntsMin(3);
1238 // Sets the maximal number of inner points for edges or faces.
1239 // It is usefull for the cases when this number is very big (e.g =2000) to improve
1240 // the performance. If this value =0, all inner points will be taken into account.
1242 aFinder.SetNbPntsMax(100);
1246 // Interprete results
1247 Standard_Integer iErr = aFinder.ErrorStatus();
1248 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
1250 MESSAGE(" iErr : " << iErr);
1251 TCollection_AsciiString aMsg (" iErr : ");
1252 aMsg += TCollection_AsciiString(iErr);
1256 Standard_Integer iWrn = aFinder.WarningStatus();
1257 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
1259 MESSAGE(" *** iWrn : " << iWrn);
1262 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
1264 if (listSS.Extent() < 1) {
1265 SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
1269 // Fill sequence of object IDs
1270 aSeqOfIDs = new TColStd_HSequenceOfInteger;
1272 TopTools_IndexedMapOfShape anIndices;
1273 TopExp::MapShapes(theShape, anIndices);
1275 TopTools_ListIteratorOfListOfShape itSub (listSS);
1276 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
1277 int id = anIndices.FindIndex(itSub.Value());
1278 aSeqOfIDs->Append(id);
1284 //=======================================================================
1285 //function : getObjectsShapesOn
1287 * \brief Find shape objects and their entries by their ids
1288 * \param theShapeIDs - incoming shape ids
1289 * \param theShapeEntries - outgoing entries like "entry1, entry2, ..."
1290 * \retval Handle(TColStd_HSequenceOfTransient) - found shape objects
1292 //=======================================================================
1294 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::
1295 getObjectsShapesOn(const Handle(GEOM_Object)& theShape,
1296 const Handle(TColStd_HSequenceOfInteger)& theShapeIDs,
1297 TCollection_AsciiString & theShapeEntries)
1299 Handle(TColStd_HSequenceOfTransient) aSeq;
1301 if ( !theShapeIDs.IsNull() && theShapeIDs->Length() > 0 )
1303 aSeq = new TColStd_HSequenceOfTransient;
1304 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
1305 TCollection_AsciiString anEntry;
1306 for ( int i = 1; i <= theShapeIDs->Length(); ++i )
1308 anArray->SetValue(1, theShapeIDs->Value( i ));
1309 Handle(GEOM_Object) anObj = GetEngine()->AddSubShape(theShape, anArray);
1310 aSeq->Append( anObj );
1312 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
1313 if ( i != 1 ) theShapeEntries += ",";
1314 theShapeEntries += anEntry;
1320 //=======================================================================
1321 //function : getShapesOnSurface
1323 * \brief Find subshapes complying with given status about surface
1324 * \param theSurface - the surface to check state of subshapes against
1325 * \param theShape - the shape to explore
1326 * \param theShapeType - type of subshape of theShape
1327 * \param theState - required state
1328 * \param theShapeEntries - outgoing entries like "entry1, entry2, ..."
1329 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1331 //=======================================================================
1333 Handle(TColStd_HSequenceOfTransient)
1334 GEOMImpl_IShapesOperations::getShapesOnSurface(const Handle(Geom_Surface)& theSurface,
1335 const Handle(GEOM_Object)& theShape,
1336 TopAbs_ShapeEnum theShapeType,
1337 GEOMAlgo_State theState,
1338 TCollection_AsciiString & theShapeEntries)
1340 // Find subshapes ids
1341 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
1342 getShapesOnSurfaceIDs (theSurface, theShape->GetValue(), theShapeType, theState);
1343 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
1346 return getObjectsShapesOn( theShape, aSeqOfIDs, theShapeEntries );
1349 //=============================================================================
1353 //=============================================================================
1354 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnPlane
1355 (const Handle(GEOM_Object)& theShape,
1356 const Standard_Integer theShapeType,
1357 const Handle(GEOM_Object)& theAx1,
1358 const GEOMAlgo_State theState)
1362 if (theShape.IsNull() || theAx1.IsNull()) return NULL;
1364 TopoDS_Shape aShape = theShape->GetValue();
1365 TopoDS_Shape anAx1 = theAx1->GetValue();
1367 if (aShape.IsNull() || anAx1.IsNull()) return NULL;
1369 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
1370 if ( !checkTypeShapesOn( theShapeType ))
1374 Handle(Geom_Surface) aPlane = makePlane( anAx1 );
1375 if ( aPlane.IsNull() )
1379 TCollection_AsciiString anAsciiList;
1380 Handle(TColStd_HSequenceOfTransient) aSeq;
1381 aSeq = getShapesOnSurface( aPlane, theShape, aShapeType, theState, anAsciiList );
1382 if ( aSeq.IsNull() || aSeq->Length() == 0 )
1385 // Make a Python command
1387 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
1388 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1390 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
1391 << "] = geompy.GetShapesOnPlane(" << theShape << ", "
1392 << aShapeType << ", " << theAx1 << ", " << theState << ")";
1398 //=============================================================================
1400 * GetShapesOnCylinder
1402 //=============================================================================
1403 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnCylinder
1404 (const Handle(GEOM_Object)& theShape,
1405 const Standard_Integer theShapeType,
1406 const Handle(GEOM_Object)& theAxis,
1407 const Standard_Real theRadius,
1408 const GEOMAlgo_State theState)
1412 if (theShape.IsNull() || theAxis.IsNull()) return NULL;
1414 TopoDS_Shape aShape = theShape->GetValue();
1415 TopoDS_Shape anAxis = theAxis->GetValue();
1417 if (aShape.IsNull() || anAxis.IsNull()) return NULL;
1419 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
1420 if ( !checkTypeShapesOn( aShapeType ))
1423 // Create a cylinder surface
1424 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
1425 if ( aCylinder.IsNull() )
1429 TCollection_AsciiString anAsciiList;
1430 Handle(TColStd_HSequenceOfTransient) aSeq;
1431 aSeq = getShapesOnSurface( aCylinder, theShape, aShapeType, theState, anAsciiList );
1432 if ( aSeq.IsNull() || aSeq->Length() == 0 )
1435 // Make a Python command
1437 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
1438 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1440 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
1441 << "] = geompy.GetShapesOnCylinder(" << theShape << ", " << aShapeType
1442 << ", " << theAxis << ", " << theRadius << ", " << theState << ")";
1448 //=============================================================================
1452 //=============================================================================
1453 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnSphere
1454 (const Handle(GEOM_Object)& theShape,
1455 const Standard_Integer theShapeType,
1456 const Handle(GEOM_Object)& theCenter,
1457 const Standard_Real theRadius,
1458 const GEOMAlgo_State theState)
1462 if (theShape.IsNull() || theCenter.IsNull()) return NULL;
1464 TopoDS_Shape aShape = theShape->GetValue();
1465 TopoDS_Shape aCenter = theCenter->GetValue();
1467 if (aShape.IsNull() || aCenter.IsNull()) return NULL;
1469 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
1470 if ( !checkTypeShapesOn( aShapeType ))
1473 // Center of the sphere
1474 if (aCenter.ShapeType() != TopAbs_VERTEX) return NULL;
1475 gp_Pnt aLoc = BRep_Tool::Pnt(TopoDS::Vertex(aCenter));
1477 gp_Ax3 anAx3 (aLoc, gp::DZ());
1478 Handle(Geom_SphericalSurface) aSphere =
1479 new Geom_SphericalSurface(anAx3, theRadius);
1482 TCollection_AsciiString anAsciiList;
1483 Handle(TColStd_HSequenceOfTransient) aSeq;
1484 aSeq = getShapesOnSurface( aSphere, theShape, aShapeType, theState, anAsciiList );
1485 if ( aSeq.IsNull() || aSeq->Length() == 0 )
1488 // Make a Python command
1490 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
1491 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1493 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
1494 << "] = geompy.GetShapesOnSphere(" << theShape << ", " << aShapeType
1495 << ", " << theCenter << ", " << theRadius << ", " << theState << ")";
1501 //=============================================================================
1503 * GetShapesOnPlaneIDs
1505 //=============================================================================
1506 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnPlaneIDs
1507 (const Handle(GEOM_Object)& theShape,
1508 const Standard_Integer theShapeType,
1509 const Handle(GEOM_Object)& theAx1,
1510 const GEOMAlgo_State theState)
1514 if (theShape.IsNull() || theAx1.IsNull()) return NULL;
1516 TopoDS_Shape aShape = theShape->GetValue();
1517 TopoDS_Shape anAx1 = theAx1->GetValue();
1519 if (aShape.IsNull() || anAx1.IsNull()) return NULL;
1521 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
1522 if ( !checkTypeShapesOn( aShapeType ))
1526 Handle(Geom_Surface) aPlane = makePlane( anAx1 );
1527 if ( aPlane.IsNull() )
1531 Handle(TColStd_HSequenceOfInteger) aSeq;
1532 aSeq = getShapesOnSurfaceIDs( aPlane, aShape, aShapeType, theState );
1534 // The GetShapesOnPlaneIDs() doesn't change object so no new function is required.
1535 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAx1)->GetLastFunction();
1537 // Make a Python command
1538 GEOM::TPythonDump(aFunction, /*append=*/true)
1539 << "listShapesOnPlane = geompy.GetShapesOnPlaneIDs"
1540 << "(" << theShape << "," << aShapeType << "," << theAx1 << "," << theState << ")";
1546 //=============================================================================
1548 * GetShapesOnCylinderIDs
1550 //=============================================================================
1551 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnCylinderIDs
1552 (const Handle(GEOM_Object)& theShape,
1553 const Standard_Integer theShapeType,
1554 const Handle(GEOM_Object)& theAxis,
1555 const Standard_Real theRadius,
1556 const GEOMAlgo_State theState)
1560 if (theShape.IsNull() || theAxis.IsNull()) return NULL;
1562 TopoDS_Shape aShape = theShape->GetValue();
1563 TopoDS_Shape anAxis = theAxis->GetValue();
1565 if (aShape.IsNull() || anAxis.IsNull()) return NULL;
1567 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
1568 if ( !checkTypeShapesOn( aShapeType ))
1571 // Create a cylinder surface
1572 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
1573 if ( aCylinder.IsNull() )
1577 Handle(TColStd_HSequenceOfInteger) aSeq;
1578 aSeq = getShapesOnSurfaceIDs( aCylinder, aShape, aShapeType, theState );
1580 // The GetShapesOnCylinder() doesn't change object so no new function is required.
1581 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAxis)->GetLastFunction();
1583 // Make a Python command
1584 GEOM::TPythonDump(aFunction, /*append=*/true)
1585 << "listShapesOnCylinder = geompy.GetShapesOnCylinderIDs"
1586 << "(" << theShape << ", " << aShapeType << ", " << theAxis << ", "
1587 << theRadius << ", " << theState << ")";
1593 //=============================================================================
1595 * GetShapesOnSphereIDs
1597 //=============================================================================
1598 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnSphereIDs
1599 (const Handle(GEOM_Object)& theShape,
1600 const Standard_Integer theShapeType,
1601 const Handle(GEOM_Object)& theCenter,
1602 const Standard_Real theRadius,
1603 const GEOMAlgo_State theState)
1607 if (theShape.IsNull() || theCenter.IsNull()) return NULL;
1609 TopoDS_Shape aShape = theShape->GetValue();
1610 TopoDS_Shape aCenter = theCenter->GetValue();
1612 if (aShape.IsNull() || aCenter.IsNull()) return NULL;
1614 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
1615 if ( !checkTypeShapesOn( aShapeType ))
1618 // Center of the sphere
1619 if (aCenter.ShapeType() != TopAbs_VERTEX) return NULL;
1620 gp_Pnt aLoc = BRep_Tool::Pnt(TopoDS::Vertex(aCenter));
1622 gp_Ax3 anAx3 (aLoc, gp::DZ());
1623 Handle(Geom_SphericalSurface) aSphere =
1624 new Geom_SphericalSurface(anAx3, theRadius);
1627 Handle(TColStd_HSequenceOfInteger) aSeq;
1628 aSeq = getShapesOnSurfaceIDs( aSphere, aShape, aShapeType, theState );
1630 // The GetShapesOnSphere() doesn't change object so no new function is required.
1631 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theCenter)->GetLastFunction();
1633 // Make a Python command
1634 GEOM::TPythonDump(aFunction, /*append=*/true)
1635 << "listShapesOnCylinder = geompy.GetShapesOnCylinderIDs"
1636 << "(" << theShape << ", " << aShapeType << ", " << theCenter << ", "
1637 << theRadius << ", " << theState << ")";
1643 //=======================================================================
1644 //function : getShapesOnQuadrangleIDs
1646 * \brief Find IDs of subshapes complying with given status about quadrangle
1647 * \param theShape - the shape to explore
1648 * \param theShapeType - type of subshape of theShape
1649 * \param theTopLeftPoint - top left quadrangle corner
1650 * \param theTopRigthPoint - top right quadrangle corner
1651 * \param theBottomLeftPoint - bottom left quadrangle corner
1652 * \param theBottomRigthPoint - bottom right quadrangle corner
1653 * \param theState - required state
1654 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1656 //=======================================================================
1658 Handle(TColStd_HSequenceOfInteger)
1659 GEOMImpl_IShapesOperations::getShapesOnQuadrangleIDs (const Handle(GEOM_Object)& theShape,
1660 const Standard_Integer theShapeType,
1661 const Handle(GEOM_Object)& theTopLeftPoint,
1662 const Handle(GEOM_Object)& theTopRigthPoint,
1663 const Handle(GEOM_Object)& theBottomLeftPoint,
1664 const Handle(GEOM_Object)& theBottomRigthPoint,
1665 const GEOMAlgo_State theState)
1669 if ( theShape.IsNull() ||
1670 theTopLeftPoint.IsNull() ||
1671 theTopRigthPoint.IsNull() ||
1672 theBottomLeftPoint.IsNull() ||
1673 theBottomRigthPoint.IsNull() )
1676 TopoDS_Shape aShape = theShape->GetValue();
1677 TopoDS_Shape aTL = theTopLeftPoint->GetValue();
1678 TopoDS_Shape aTR = theTopRigthPoint->GetValue();
1679 TopoDS_Shape aBL = theBottomLeftPoint->GetValue();
1680 TopoDS_Shape aBR = theBottomRigthPoint->GetValue();
1682 if (aShape.IsNull() ||
1687 aTL.ShapeType() != TopAbs_VERTEX ||
1688 aTR.ShapeType() != TopAbs_VERTEX ||
1689 aBL.ShapeType() != TopAbs_VERTEX ||
1690 aBR.ShapeType() != TopAbs_VERTEX )
1693 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
1694 if ( !checkTypeShapesOn( aShapeType ))
1697 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
1699 // Check presence of triangulation, build if need
1700 if (!CheckTriangulation(aShape))
1704 gp_Pnt aPntTL = BRep_Tool::Pnt(TopoDS::Vertex(aTL));
1705 gp_Pnt aPntTR = BRep_Tool::Pnt(TopoDS::Vertex(aTR));
1706 gp_Pnt aPntBL = BRep_Tool::Pnt(TopoDS::Vertex(aBL));
1707 gp_Pnt aPntBR = BRep_Tool::Pnt(TopoDS::Vertex(aBR));
1709 GEOMAlgo_FinderShapeOnQuad aFinder( aPntTL, aPntTR, aPntBL, aPntBR );
1710 Standard_Real aTol = 0.0001; // default value
1712 aFinder.SetShape(aShape);
1713 aFinder.SetTolerance(aTol);
1714 //aFinder.SetSurface(theSurface);
1715 aFinder.SetShapeType(aShapeType);
1716 aFinder.SetState(theState);
1718 // Sets the minimal number of inner points for the faces that do not have own
1719 // inner points at all (for e.g. rectangular planar faces have just 2 triangles).
1721 aFinder.SetNbPntsMin(3);
1722 // Sets the maximal number of inner points for edges or faces.
1723 // It is usefull for the cases when this number is very big (e.g =2000) to improve
1724 // the performance. If this value =0, all inner points will be taken into account.
1726 aFinder.SetNbPntsMax(100);
1730 // Interprete results
1731 Standard_Integer iErr = aFinder.ErrorStatus();
1732 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
1734 MESSAGE(" iErr : " << iErr);
1735 TCollection_AsciiString aMsg (" iErr : ");
1736 aMsg += TCollection_AsciiString(iErr);
1740 Standard_Integer iWrn = aFinder.WarningStatus();
1741 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
1743 MESSAGE(" *** iWrn : " << iWrn);
1746 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
1748 if (listSS.Extent() < 1) {
1749 SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
1753 // Fill sequence of object IDs
1754 aSeqOfIDs = new TColStd_HSequenceOfInteger;
1756 TopTools_IndexedMapOfShape anIndices;
1757 TopExp::MapShapes(aShape, anIndices);
1759 TopTools_ListIteratorOfListOfShape itSub (listSS);
1760 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
1761 int id = anIndices.FindIndex(itSub.Value());
1762 aSeqOfIDs->Append(id);
1767 //=======================================================================
1768 //function : GetShapesOnQuadrangle
1770 * \brief Find subshapes complying with given status about quadrangle
1771 * \param theShape - the shape to explore
1772 * \param theShapeType - type of subshape of theShape
1773 * \param theTopLeftPoint - top left quadrangle corner
1774 * \param theTopRigthPoint - top right quadrangle corner
1775 * \param theBottomLeftPoint - bottom left quadrangle corner
1776 * \param theBottomRigthPoint - bottom right quadrangle corner
1777 * \param theState - required state
1778 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1780 //=======================================================================
1782 Handle(TColStd_HSequenceOfTransient)
1783 GEOMImpl_IShapesOperations::GetShapesOnQuadrangle (const Handle(GEOM_Object)& theShape,
1784 const Standard_Integer theShapeType,
1785 const Handle(GEOM_Object)& theTopLeftPoint,
1786 const Handle(GEOM_Object)& theTopRigthPoint,
1787 const Handle(GEOM_Object)& theBottomLeftPoint,
1788 const Handle(GEOM_Object)& theBottomRigthPoint,
1789 const GEOMAlgo_State theState)
1792 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
1793 getShapesOnQuadrangleIDs( theShape,
1798 theBottomRigthPoint,
1800 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->IsEmpty() )
1803 // Find objects by indices
1804 TCollection_AsciiString anAsciiList;
1805 Handle(TColStd_HSequenceOfTransient) aSeq;
1806 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
1807 if ( aSeq.IsNull() || aSeq->IsEmpty() )
1810 // Make a Python command
1812 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
1813 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1815 GEOM::TPythonDump(aFunction)
1816 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnQuadrangle("
1818 << TopAbs_ShapeEnum(theShapeType) << ", "
1819 << theTopLeftPoint << ", "
1820 << theTopRigthPoint << ", "
1821 << theBottomLeftPoint << ", "
1822 << theBottomRigthPoint << ", "
1829 //=======================================================================
1830 //function : GetShapesOnQuadrangleIDs
1832 * \brief Find IDs of subshapes complying with given status about quadrangle
1833 * \param theShape - the shape to explore
1834 * \param theShapeType - type of subshape of theShape
1835 * \param theTopLeftPoint - top left quadrangle corner
1836 * \param theTopRigthPoint - top right quadrangle corner
1837 * \param theBottomLeftPoint - bottom left quadrangle corner
1838 * \param theBottomRigthPoint - bottom right quadrangle corner
1839 * \param theState - required state
1840 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1842 //=======================================================================
1844 Handle(TColStd_HSequenceOfInteger)
1845 GEOMImpl_IShapesOperations::GetShapesOnQuadrangleIDs (const Handle(GEOM_Object)& theShape,
1846 const Standard_Integer theShapeType,
1847 const Handle(GEOM_Object)& theTopLeftPoint,
1848 const Handle(GEOM_Object)& theTopRigthPoint,
1849 const Handle(GEOM_Object)& theBottomLeftPoint,
1850 const Handle(GEOM_Object)& theBottomRigthPoint,
1851 const GEOMAlgo_State theState)
1854 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
1855 getShapesOnQuadrangleIDs( theShape,
1860 theBottomRigthPoint,
1862 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->IsEmpty() )
1865 // Make a Python command
1867 // The GetShapesOnCylinder() doesn't change object so no new function is required.
1868 Handle(GEOM_Object) lastObj = GEOM::GetCreatedLast(theShape,theTopLeftPoint);
1869 lastObj = GEOM::GetCreatedLast(lastObj,theTopRigthPoint);
1870 lastObj = GEOM::GetCreatedLast(lastObj,theBottomRigthPoint);
1871 lastObj = GEOM::GetCreatedLast(lastObj,theBottomLeftPoint);
1872 Handle(GEOM_Function) aFunction = lastObj->GetLastFunction();
1874 GEOM::TPythonDump(aFunction, /*append=*/true)
1875 << "listShapesOnQuadrangle = geompy.GetShapesOnQuadrangleIDs("
1877 << TopAbs_ShapeEnum(theShapeType) << ", "
1878 << theTopLeftPoint << ", "
1879 << theTopRigthPoint << ", "
1880 << theBottomLeftPoint << ", "
1881 << theBottomRigthPoint << ", "
1889 //=============================================================================
1893 //=============================================================================
1894 static void SimplifyWhat (TopoDS_Shape& theWhat,
1895 TopTools_IndexedMapOfShape& theArgumentIndices,
1896 TColStd_ListOfInteger& theSimpleSubWhat)
1898 TopTools_MapOfShape mapShape;
1899 TopoDS_Iterator It (theWhat, Standard_True, Standard_True);
1900 for (; It.More(); It.Next()) {
1901 if (mapShape.Add(It.Value())) {
1902 TopoDS_Shape curSh = It.Value();
1903 if (curSh.ShapeType() == TopAbs_COMPOUND ||
1904 curSh.ShapeType() == TopAbs_COMPSOLID) {
1905 SimplifyWhat(curSh, theArgumentIndices, theSimpleSubWhat);
1907 theSimpleSubWhat.Append(theArgumentIndices.FindIndex(curSh));
1913 static bool GetInPlaceOfCompound (Handle(GEOM_Function)& theWhereFunction,
1914 TopoDS_Shape& theWhat,
1915 TColStd_ListOfInteger& theModifiedArray)
1917 bool isFoundAny = false;
1918 TopTools_MapOfShape mapShape;
1919 TopoDS_Iterator It (theWhat, Standard_True, Standard_True);
1920 for (; It.More(); It.Next()) {
1921 if (mapShape.Add(It.Value())) {
1922 TopoDS_Shape curWhat = It.Value();
1923 if (curWhat.ShapeType() == TopAbs_COMPOUND ||
1924 curWhat.ShapeType() == TopAbs_COMPSOLID) {
1925 // Recursive call for compound or compsolid
1926 if (GetInPlaceOfCompound(theWhereFunction, curWhat, theModifiedArray))
1929 // Try to find for "simple" shape
1930 bool isFound = false;
1932 TDF_LabelSequence aLabelSeq;
1933 theWhereFunction->GetDependency(aLabelSeq);
1934 Standard_Integer nbArg = aLabelSeq.Length();
1936 for (Standard_Integer iarg = 1; iarg <= nbArg && !isFound; iarg++) {
1938 TDF_Label anArgumentRefLabel = aLabelSeq.Value(iarg);
1940 Handle(GEOM_Object) anArgumentObject = GEOM_Object::GetReferencedObject(anArgumentRefLabel);
1941 TopoDS_Shape anArgumentShape = anArgumentObject->GetValue();
1943 TopTools_IndexedMapOfShape anArgumentIndices;
1944 TopExp::MapShapes(anArgumentShape, anArgumentIndices);
1946 if (anArgumentIndices.Contains(curWhat)) {
1947 isFound = Standard_True;
1948 Standard_Integer aWhatIndex = anArgumentIndices.FindIndex(curWhat);
1950 // Find corresponding label in history
1951 TDF_Label anArgumentHistoryLabel =
1952 theWhereFunction->GetArgumentHistoryEntry(anArgumentRefLabel, Standard_False);
1953 if (!anArgumentHistoryLabel.IsNull()) {
1954 TDF_Label aWhatHistoryLabel = anArgumentHistoryLabel.FindChild(aWhatIndex, Standard_False);
1955 if (!aWhatHistoryLabel.IsNull()) {
1956 Handle(TDataStd_IntegerArray) anIntegerArray;
1957 if (aWhatHistoryLabel.FindAttribute(TDataStd_IntegerArray::GetID(), anIntegerArray)) {
1958 Standard_Integer imod, aModifLen = anIntegerArray->Array()->Length();
1959 for (imod = 1; imod <= aModifLen; imod++) {
1960 theModifiedArray.Append(anIntegerArray->Array()->Value(imod));
1975 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlace
1976 (Handle(GEOM_Object) theShapeWhere,
1977 Handle(GEOM_Object) theShapeWhat)
1981 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
1983 TopoDS_Shape aWhere = theShapeWhere->GetValue();
1984 TopoDS_Shape aWhat = theShapeWhat->GetValue();
1986 if (aWhere.IsNull() || aWhat.IsNull()) return NULL;
1988 //Fill array of indices
1989 Handle(TColStd_HArray1OfInteger) aModifiedArray;
1991 Handle(GEOM_Function) aWhereFunction = theShapeWhere->GetLastFunction();
1993 TopTools_IndexedMapOfShape aWhereIndices;
1994 TopExp::MapShapes(aWhere, aWhereIndices);
1996 if (aWhereIndices.Contains(aWhat)) {
1998 // entity was not changed by the operation
1999 Standard_Integer aWhatIndex = aWhereIndices.FindIndex(aWhat);
2000 aModifiedArray = new TColStd_HArray1OfInteger(1,1);
2001 aModifiedArray->SetValue(1, aWhatIndex);
2005 TDF_Label aHistoryLabel = aWhereFunction->GetHistoryEntry(Standard_False);
2006 if (aHistoryLabel.IsNull()) {
2007 SetErrorCode("Modifications history does not exist for the shape under consideration.");
2011 // search in history for all argument shapes
2012 Standard_Boolean isFound = Standard_False;
2014 TDF_LabelSequence aLabelSeq;
2015 aWhereFunction->GetDependency(aLabelSeq);
2016 Standard_Integer nbArg = aLabelSeq.Length();
2018 for (Standard_Integer iarg = 1; iarg <= nbArg && !isFound; iarg++) {
2020 TDF_Label anArgumentRefLabel = aLabelSeq.Value(iarg);
2022 Handle(GEOM_Object) anArgumentObject = GEOM_Object::GetReferencedObject(anArgumentRefLabel);
2023 TopoDS_Shape anArgumentShape = anArgumentObject->GetValue();
2025 TopTools_IndexedMapOfShape anArgumentIndices;
2026 TopExp::MapShapes(anArgumentShape, anArgumentIndices);
2028 if (anArgumentIndices.Contains(aWhat)) {
2029 isFound = Standard_True;
2030 Standard_Integer aWhatIndex = anArgumentIndices.FindIndex(aWhat);
2032 // Find corresponding label in history
2033 TDF_Label anArgumentHistoryLabel =
2034 aWhereFunction->GetArgumentHistoryEntry(anArgumentRefLabel, Standard_False);
2035 if (anArgumentHistoryLabel.IsNull()) {
2036 // Lost History of operation argument. Possibly, all its entities was removed.
2041 TDF_Label aWhatHistoryLabel = anArgumentHistoryLabel.FindChild(aWhatIndex, Standard_False);
2042 if (aWhatHistoryLabel.IsNull()) {
2043 // Check, if the sought shape is Compound or Compsolid.
2044 // In that case we will try to find history for its sub-shapes
2045 if (aWhat.ShapeType() == TopAbs_COMPOUND ||
2046 aWhat.ShapeType() == TopAbs_COMPSOLID) {
2047 TColStd_ListOfInteger aSimpleSubWhat, aModifiedList;
2048 SimplifyWhat(aWhat, anArgumentIndices, aSimpleSubWhat);
2049 TColStd_ListIteratorOfListOfInteger anIterSub (aSimpleSubWhat);
2050 for (; anIterSub.More(); anIterSub.Next()) {
2051 Standard_Integer aSubWhatIndex = anIterSub.Value();
2052 TDF_Label aSubWhatHistoryLabel =
2053 anArgumentHistoryLabel.FindChild(aSubWhatIndex, Standard_False);
2054 if (!aSubWhatHistoryLabel.IsNull()) {
2055 Handle(TDataStd_IntegerArray) anIntegerArray;
2056 if (aSubWhatHistoryLabel.FindAttribute(TDataStd_IntegerArray::GetID(), anIntegerArray)) {
2057 for (Standard_Integer isub = 1; isub <= anIntegerArray->Length(); isub++) {
2058 aModifiedList.Append(anIntegerArray->Value(isub));
2063 if (aModifiedList.Extent() > 0) {
2064 Handle(TColStd_HArray1OfInteger) aModifiedArraySub =
2065 new TColStd_HArray1OfInteger (1, aModifiedList.Extent());
2066 TColStd_ListIteratorOfListOfInteger anIterModif (aModifiedList);
2067 for (Standard_Integer imod = 1; anIterModif.More(); anIterModif.Next(), imod++) {
2068 aModifiedArraySub->SetValue(imod, anIterModif.Value());
2070 aModifiedArray = aModifiedArraySub;
2082 Handle(TDataStd_IntegerArray) anIntegerArray;
2083 if (!aWhatHistoryLabel.FindAttribute(TDataStd_IntegerArray::GetID(), anIntegerArray)) {
2084 SetErrorCode("Error: Empty modifications history for the sought shape.");
2088 aModifiedArray = anIntegerArray->Array();
2089 if (aModifiedArray->Length() == 0) {
2090 SetErrorCode("Error: Empty modifications history for the sought shape.");
2098 // try compound element by element
2099 if (aWhat.ShapeType() == TopAbs_COMPOUND ||
2100 aWhat.ShapeType() == TopAbs_COMPSOLID) {
2101 TColStd_ListOfInteger aModifiedList;
2102 isFound = GetInPlaceOfCompound(aWhereFunction, aWhat, aModifiedList);
2104 aModifiedArray = new TColStd_HArray1OfInteger (1, aModifiedList.Extent());
2105 TColStd_ListIteratorOfListOfInteger anIterModif (aModifiedList);
2106 for (Standard_Integer imod = 1; anIterModif.More(); anIterModif.Next(), imod++) {
2107 aModifiedArray->SetValue(imod, anIterModif.Value());
2112 SetErrorCode("The sought shape does not belong to any operation argument.");
2119 Handle(GEOM_Object) aResult = GetEngine()->AddSubShape(theShapeWhere, aModifiedArray);
2121 if (aModifiedArray->Length() > 1) {
2123 aResult->SetType(GEOM_GROUP);
2125 //Set a sub shape type
2126 TDF_Label aFreeLabel = aResult->GetFreeLabel();
2127 TopAbs_ShapeEnum aShapeType = aWhat.ShapeType();
2128 TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aShapeType);
2131 //Make a Python command
2132 Handle(GEOM_Function) aFunction = aResult->GetFunction(1);
2134 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetInPlace("
2135 << theShapeWhere << ", " << theShapeWhat << ")";
2141 //=======================================================================
2142 //function : SortShapes
2144 //=======================================================================
2145 void GEOMImpl_IShapesOperations::SortShapes(TopTools_ListOfShape& SL)
2147 Standard_Integer MaxShapes = SL.Extent();
2148 TopTools_Array1OfShape aShapes (1,MaxShapes);
2149 TColStd_Array1OfInteger OrderInd(1,MaxShapes);
2150 TColStd_Array1OfReal MidXYZ (1,MaxShapes); //X,Y,Z;
2151 TColStd_Array1OfReal Length (1,MaxShapes); //X,Y,Z;
2153 // Computing of CentreOfMass
2154 Standard_Integer Index;
2157 TopTools_ListIteratorOfListOfShape it(SL);
2158 for (Index=1; it.More(); Index++)
2160 TopoDS_Shape S = it.Value();
2161 SL.Remove( it ); // == it.Next()
2163 OrderInd.SetValue (Index, Index);
2164 if (S.ShapeType() == TopAbs_VERTEX)
2166 GPoint = BRep_Tool::Pnt( TopoDS::Vertex( S ));
2167 Length.SetValue( Index, (Standard_Real) S.Orientation());
2171 BRepGProp::LinearProperties (S, GPr);
2172 GPoint = GPr.CentreOfMass();
2173 Length.SetValue( Index, GPr.Mass() );
2175 MidXYZ.SetValue(Index,
2176 GPoint.X()*999 + GPoint.Y()*99 + GPoint.Z()*0.9);
2180 Standard_Integer aTemp;
2181 Standard_Boolean exchange, Sort = Standard_True;
2184 Sort = Standard_False;
2185 for (Index=1; Index < MaxShapes; Index++)
2187 if (MidXYZ(OrderInd(Index)) > MidXYZ(OrderInd(Index+1)))
2188 exchange = Standard_True;
2189 else if (MidXYZ(OrderInd(Index)) == MidXYZ(OrderInd(Index+1)) &&
2190 Length(OrderInd(Index)) > Length(OrderInd(Index+1)) )
2191 exchange = Standard_True;
2193 exchange = Standard_False;
2196 aTemp = OrderInd(Index);
2197 OrderInd(Index) = OrderInd(Index+1);
2198 OrderInd(Index+1) = aTemp;
2199 Sort = Standard_True;
2203 for (Index=1; Index <= MaxShapes; Index++)
2204 SL.Append( aShapes( OrderInd(Index) ));
2207 //=======================================================================
2208 //function : CheckTriangulation
2210 //=======================================================================
2211 bool GEOMImpl_IShapesOperations::CheckTriangulation (const TopoDS_Shape& aShape)
2213 TopExp_Explorer exp (aShape, TopAbs_FACE);
2215 SetErrorCode("Shape without faces given");
2219 TopLoc_Location aTopLoc;
2220 Handle(Poly_Triangulation) aTRF;
2221 aTRF = BRep_Tool::Triangulation(TopoDS::Face(exp.Current()), aTopLoc);
2222 if (aTRF.IsNull()) {
2223 // calculate deflection
2224 Standard_Real aDeviationCoefficient = 0.001;
2227 BRepBndLib::Add(aShape, B);
2228 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
2229 B.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
2231 Standard_Real dx = aXmax - aXmin, dy = aYmax - aYmin, dz = aZmax - aZmin;
2232 Standard_Real aDeflection = Max(Max(dx, dy), dz) * aDeviationCoefficient * 4;
2233 Standard_Real aHLRAngle = 0.349066;
2235 BRepMesh_IncrementalMesh Inc (aShape, aDeflection, Standard_False, aHLRAngle);