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/
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 <BRepBndLib.hxx>
60 #include <BRepBuilderAPI_MakeFace.hxx>
61 #include <BRepMesh_IncrementalMesh.hxx>
66 #include <TopoDS_Shape.hxx>
67 #include <TopoDS_Face.hxx>
68 #include <TopoDS_Edge.hxx>
69 #include <TopoDS_Vertex.hxx>
70 #include <TopoDS_Iterator.hxx>
71 #include <TopExp_Explorer.hxx>
72 #include <TopLoc_Location.hxx>
73 #include <TopTools_MapOfShape.hxx>
74 #include <TopTools_Array1OfShape.hxx>
75 #include <TopTools_ListIteratorOfListOfShape.hxx>
76 #include <TopTools_IndexedMapOfShape.hxx>
78 #include <Geom_Surface.hxx>
79 #include <Geom_Plane.hxx>
80 #include <Geom_SphericalSurface.hxx>
81 #include <Geom_CylindricalSurface.hxx>
82 #include <GeomAdaptor_Surface.hxx>
84 #include <Geom2d_Curve.hxx>
86 #include <Bnd_Box.hxx>
87 #include <GProp_GProps.hxx>
90 #include <TColStd_ListOfInteger.hxx>
91 #include <TColStd_ListIteratorOfListOfInteger.hxx>
92 #include <TColStd_Array1OfReal.hxx>
93 #include <TColStd_HArray1OfInteger.hxx>
98 //#include <OSD_Timer.hxx>
100 #include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
102 //=============================================================================
106 //=============================================================================
107 GEOMImpl_IShapesOperations::GEOMImpl_IShapesOperations (GEOM_Engine* theEngine, int theDocID)
108 : GEOM_IOperations(theEngine, theDocID)
110 MESSAGE("GEOMImpl_IShapesOperations::GEOMImpl_IShapesOperations");
113 //=============================================================================
117 //=============================================================================
118 GEOMImpl_IShapesOperations::~GEOMImpl_IShapesOperations()
120 MESSAGE("GEOMImpl_IShapesOperations::~GEOMImpl_IShapesOperations");
124 //=============================================================================
128 //=============================================================================
129 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeEdge
130 (Handle(GEOM_Object) thePnt1, Handle(GEOM_Object) thePnt2)
134 if (thePnt1.IsNull() || thePnt2.IsNull()) return NULL;
136 //Add a new Edge object
137 Handle(GEOM_Object) anEdge = GetEngine()->AddObject(GetDocID(), GEOM_EDGE);
139 //Add a new Vector function
140 Handle(GEOM_Function) aFunction =
141 anEdge->AddFunction(GEOMImpl_VectorDriver::GetID(), VECTOR_TWO_PNT);
143 //Check if the function is set correctly
144 if (aFunction->GetDriverGUID() != GEOMImpl_VectorDriver::GetID()) return NULL;
146 GEOMImpl_IVector aPI (aFunction);
148 Handle(GEOM_Function) aRef1 = thePnt1->GetLastFunction();
149 Handle(GEOM_Function) aRef2 = thePnt2->GetLastFunction();
150 if (aRef1.IsNull() || aRef2.IsNull()) return NULL;
152 aPI.SetPoint1(aRef1);
153 aPI.SetPoint2(aRef2);
155 //Compute the Edge value
157 if (!GetSolver()->ComputeFunction(aFunction)) {
158 SetErrorCode("Vector driver failed");
162 catch (Standard_Failure) {
163 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
164 SetErrorCode(aFail->GetMessageString());
168 //Make a Python command
169 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdge("
170 << thePnt1 << ", " << thePnt2 << ")";
176 //=============================================================================
180 //=============================================================================
181 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeWire
182 (list<Handle(GEOM_Object)> theShapes)
184 return MakeShape(theShapes, GEOM_WIRE, WIRE_EDGES, "MakeWire");
187 //=============================================================================
191 //=============================================================================
192 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFace (Handle(GEOM_Object) theWire,
193 const bool isPlanarWanted)
197 if (theWire.IsNull()) return NULL;
199 //Add a new Face object
200 Handle(GEOM_Object) aFace = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
202 //Add a new Shape function for creation of a face from a wire
203 Handle(GEOM_Function) aFunction =
204 aFace->AddFunction(GEOMImpl_ShapeDriver::GetID(), FACE_WIRE);
205 if (aFunction.IsNull()) return NULL;
207 //Check if the function is set correctly
208 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
210 GEOMImpl_IShapes aCI (aFunction);
212 Handle(GEOM_Function) aRefWire = theWire->GetLastFunction();
214 if (aRefWire.IsNull()) return NULL;
216 aCI.SetBase(aRefWire);
217 aCI.SetIsPlanar(isPlanarWanted);
219 //Compute the Face value
221 if (!GetSolver()->ComputeFunction(aFunction)) {
222 SetErrorCode("Shape driver failed to compute a face");
226 catch (Standard_Failure) {
227 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
228 SetErrorCode(aFail->GetMessageString());
232 //Make a Python command
233 GEOM::TPythonDump(aFunction) << aFace << " = geompy.MakeFace("
234 << theWire << ", " << (int)isPlanarWanted << ")";
240 //=============================================================================
244 //=============================================================================
245 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFaceWires
246 (list<Handle(GEOM_Object)> theShapes,
247 const bool isPlanarWanted)
252 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
255 Handle(GEOM_Function) aFunction =
256 aShape->AddFunction(GEOMImpl_ShapeDriver::GetID(), FACE_WIRES);
257 if (aFunction.IsNull()) return NULL;
259 //Check if the function is set correctly
260 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
262 GEOMImpl_IShapes aCI (aFunction);
264 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
267 list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
268 for (; it != theShapes.end(); it++) {
269 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
270 if (aRefSh.IsNull()) {
271 SetErrorCode("NULL argument shape for the face construction");
274 aShapesSeq->Append(aRefSh);
276 aCI.SetShapes(aShapesSeq);
278 aCI.SetIsPlanar(isPlanarWanted);
282 if (!GetSolver()->ComputeFunction(aFunction)) {
283 SetErrorCode("Shape driver failed");
287 catch (Standard_Failure) {
288 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
289 SetErrorCode(aFail->GetMessageString());
293 //Make a Python command
294 GEOM::TPythonDump pd (aFunction);
295 pd << aShape << " = geompy.MakeFaceWires([";
298 it = theShapes.begin();
299 if (it != theShapes.end()) {
301 while (it != theShapes.end()) {
302 pd << ", " << (*it++);
305 pd << "], " << (int)isPlanarWanted << ")";
311 //=============================================================================
315 //=============================================================================
316 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeShell
317 (list<Handle(GEOM_Object)> theShapes)
319 return MakeShape(theShapes, GEOM_SHELL, SHELL_FACES, "MakeShell");
322 //=============================================================================
326 //=============================================================================
327 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeSolidShells
328 (list<Handle(GEOM_Object)> theShapes)
330 return MakeShape(theShapes, GEOM_SOLID, SOLID_SHELLS, "MakeSolid");
333 //=============================================================================
337 //=============================================================================
338 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeSolidShell (Handle(GEOM_Object) theShell)
342 if (theShell.IsNull()) return NULL;
344 //Add a new Solid object
345 Handle(GEOM_Object) aSolid = GetEngine()->AddObject(GetDocID(), GEOM_SOLID);
347 //Add a new Solid function for creation of a solid from a shell
348 Handle(GEOM_Function) aFunction =
349 aSolid->AddFunction(GEOMImpl_ShapeDriver::GetID(), SOLID_SHELL);
350 if (aFunction.IsNull()) return NULL;
352 //Check if the function is set correctly
353 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
355 GEOMImpl_IShapes aCI (aFunction);
357 Handle(GEOM_Function) aRefShell = theShell->GetLastFunction();
359 if (aRefShell.IsNull()) return NULL;
361 aCI.SetBase(aRefShell);
363 //Compute the Solid value
365 if (!GetSolver()->ComputeFunction(aFunction)) {
366 SetErrorCode("Solid driver failed");
370 catch (Standard_Failure) {
371 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
372 SetErrorCode(aFail->GetMessageString());
376 //Make a Python command
377 GEOM::TPythonDump(aFunction) << aSolid
378 << " = geompy.MakeSolid(" << theShell << ")";
384 //=============================================================================
388 //=============================================================================
389 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeCompound
390 (list<Handle(GEOM_Object)> theShapes)
392 return MakeShape(theShapes, GEOM_COMPOUND, COMPOUND_SHAPES, "MakeCompound");
395 //=============================================================================
399 //=============================================================================
400 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeShape
401 (list<Handle(GEOM_Object)> theShapes,
402 const Standard_Integer theObjectType,
403 const Standard_Integer theFunctionType,
404 const TCollection_AsciiString& theMethodName)
409 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), theObjectType);
412 Handle(GEOM_Function) aFunction =
413 aShape->AddFunction(GEOMImpl_ShapeDriver::GetID(), theFunctionType);
414 if (aFunction.IsNull()) return NULL;
416 //Check if the function is set correctly
417 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
419 GEOMImpl_IShapes aCI (aFunction);
421 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
424 list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
425 for (; it != theShapes.end(); it++) {
426 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
427 if (aRefSh.IsNull()) {
428 SetErrorCode("NULL argument shape for the shape construction");
431 aShapesSeq->Append(aRefSh);
433 aCI.SetShapes(aShapesSeq);
437 if (!GetSolver()->ComputeFunction(aFunction)) {
438 SetErrorCode("Shape driver failed");
442 catch (Standard_Failure) {
443 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
444 SetErrorCode(aFail->GetMessageString());
448 //Make a Python command
449 GEOM::TPythonDump pd (aFunction);
450 pd << aShape << " = geompy." << theMethodName.ToCString() << "([";
453 it = theShapes.begin();
454 if (it != theShapes.end()) {
456 while (it != theShapes.end()) {
457 pd << ", " << (*it++);
466 //=============================================================================
470 //=============================================================================
471 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeGlueFaces
472 (Handle(GEOM_Object) theShape,
473 const Standard_Real theTolerance)
477 if (theShape.IsNull()) return NULL;
479 //Add a new Glued object
480 Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
482 //Add a new Glue function
483 Handle(GEOM_Function) aFunction;
484 aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_FACES);
485 if (aFunction.IsNull()) return NULL;
487 //Check if the function is set correctly
488 if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
490 GEOMImpl_IGlue aCI (aFunction);
492 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
493 if (aRefShape.IsNull()) return NULL;
495 aCI.SetBase(aRefShape);
496 aCI.SetTolerance(theTolerance);
498 //Compute the sub-shape value
499 Standard_Boolean isWarning = Standard_False;
501 if (!GetSolver()->ComputeFunction(aFunction)) {
502 SetErrorCode("Shape driver failed to glue faces");
506 catch (Standard_Failure) {
507 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
508 SetErrorCode(aFail->GetMessageString());
509 // to provide warning
510 if (!aFunction->GetValue().IsNull()) {
511 isWarning = Standard_True;
517 //Make a Python command
518 GEOM::TPythonDump(aFunction) << aGlued << " = geompy.MakeGlueFaces("
519 << theShape << ", " << theTolerance << ")";
521 // to provide warning
522 if (!isWarning) SetErrorCode(OK);
526 //=============================================================================
530 //=============================================================================
531 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::MakeExplode
532 (Handle(GEOM_Object) theShape,
533 const Standard_Integer theShapeType,
534 const Standard_Boolean isSorted)
536 // OSD_Timer timer1, timer2, timer3, timer4;
541 if (theShape.IsNull()) return NULL;
542 TopoDS_Shape aShape = theShape->GetValue();
543 if (aShape.IsNull()) return NULL;
545 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
546 Handle(GEOM_Object) anObj;
547 Handle(GEOM_Function) aFunction;
548 TopTools_MapOfShape mapShape;
549 TopTools_ListOfShape listShape;
551 if (aShape.ShapeType() == TopAbs_COMPOUND &&
552 (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
553 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPSOLID ||
554 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPOUND)) {
555 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
556 for (; It.More(); It.Next()) {
557 if (mapShape.Add(It.Value())) {
558 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
559 TopAbs_ShapeEnum(theShapeType) == It.Value().ShapeType()) {
560 listShape.Append(It.Value());
565 TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
566 for (; exp.More(); exp.Next())
567 if (mapShape.Add(exp.Current()))
568 listShape.Append(exp.Current());
571 if (listShape.IsEmpty()) {
572 SetErrorCode("The given shape has no sub-shapes of the requested type");
580 SortShapes(listShape);
585 TopTools_IndexedMapOfShape anIndices;
586 TopExp::MapShapes(aShape, anIndices);
587 Handle(TColStd_HArray1OfInteger) anArray;
589 TopTools_ListIteratorOfListOfShape itSub (listShape);
590 TCollection_AsciiString anAsciiList, anEntry;
591 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
592 TopoDS_Shape aValue = itSub.Value();
593 anArray = new TColStd_HArray1OfInteger(1,1);
594 anArray->SetValue(1, anIndices.FindIndex(aValue));
595 anObj = GetEngine()->AddSubShape(theShape, anArray);
598 // for python command
599 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
600 anAsciiList += anEntry;
604 //Make a Python command
605 anAsciiList.Trunc(anAsciiList.Length() - 1);
607 aFunction = theShape->GetLastFunction();
608 TCollection_AsciiString anOldDescr = aFunction->GetDescription();
610 GEOM::TPythonDump pd (aFunction);
611 pd << anOldDescr.ToCString() << "\n\t[" << anAsciiList.ToCString();
612 pd << "] = geompy.SubShapeAll" << (isSorted ? "Sorted(" : "(");
613 pd << theShape << ", " << theShapeType << ")";
619 // cout << "Explosure takes:" << endl;
621 // cout << "Sorting takes:" << endl;
623 // cout << "Sub-shapes addition takes:" << endl;
625 // cout << "Update Description takes:" << endl;
631 //=============================================================================
635 //=============================================================================
636 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::SubShapeAllIDs
637 (Handle(GEOM_Object) theShape,
638 const Standard_Integer theShapeType,
639 const Standard_Boolean isSorted)
643 if (theShape.IsNull()) return NULL;
644 TopoDS_Shape aShape = theShape->GetValue();
645 if (aShape.IsNull()) return NULL;
647 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
648 TopTools_MapOfShape mapShape;
649 TopTools_ListOfShape listShape;
651 if (aShape.ShapeType() == TopAbs_COMPOUND &&
652 (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
653 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPSOLID ||
654 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPOUND)) {
655 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
656 for (; It.More(); It.Next()) {
657 if (mapShape.Add(It.Value())) {
658 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
659 TopAbs_ShapeEnum(theShapeType) == It.Value().ShapeType()) {
660 listShape.Append(It.Value());
665 TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
666 for (; exp.More(); exp.Next())
667 if (mapShape.Add(exp.Current()))
668 listShape.Append(exp.Current());
671 if (listShape.IsEmpty()) {
672 SetErrorCode("The given shape has no sub-shapes of the requested type");
677 SortShapes(listShape);
679 TopTools_IndexedMapOfShape anIndices;
680 TopExp::MapShapes(aShape, anIndices);
681 Handle(TColStd_HArray1OfInteger) anArray;
683 TopTools_ListIteratorOfListOfShape itSub (listShape);
684 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
685 TopoDS_Shape aValue = itSub.Value();
686 aSeq->Append(anIndices.FindIndex(aValue));
689 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
690 TCollection_AsciiString anOldDescr = aFunction->GetDescription();
692 //Make a Python command
693 GEOM::TPythonDump pd (aFunction);
694 pd << anOldDescr.ToCString() << "\n\tlistSubShapeIDs = geompy.SubShapeAll";
695 pd << (isSorted ? "SortedIDs(" : "IDs(");
696 pd << theShape << ", " << theShapeType << ")";
702 //=============================================================================
706 //=============================================================================
707 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetSubShape
708 (Handle(GEOM_Object) theMainShape,
709 const Standard_Integer theID)
713 if (theMainShape.IsNull()) return NULL;
715 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
716 anArray->SetValue(1, theID);
717 Handle(GEOM_Object) anObj = GetEngine()->AddSubShape(theMainShape, anArray,true);
718 if (anObj.IsNull()) {
719 SetErrorCode("Can not get a sub-shape with the given ID");
723 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
725 //Make a Python command
726 GEOM::TPythonDump(aFunction) << anObj << " = geompy.GetSubShape("
727 << theMainShape << ", [" << theID << "])";
734 //=============================================================================
738 //=============================================================================
739 Standard_Integer GEOMImpl_IShapesOperations::NumberOfFaces (Handle(GEOM_Object) theShape)
743 Standard_Integer nb = 0;
745 if (theShape.IsNull()) return -1;
746 TopoDS_Shape aShape = theShape->GetValue();
747 if (aShape.IsNull()) return -1;
749 TopTools_MapOfShape mapShape;
751 TopExp_Explorer exp (aShape, TopAbs_FACE);
752 for (; exp.More(); exp.Next())
753 if (mapShape.Add(exp.Current()))
760 //=============================================================================
764 //=============================================================================
765 Standard_Integer GEOMImpl_IShapesOperations::NumberOfEdges (Handle(GEOM_Object) theShape)
769 Standard_Integer nb = 0;
771 if (theShape.IsNull()) return -1;
772 TopoDS_Shape aShape = theShape->GetValue();
773 if (aShape.IsNull()) return -1;
775 TopTools_MapOfShape mapShape;
777 TopExp_Explorer exp (aShape, TopAbs_EDGE);
778 for (; exp.More(); exp.Next())
779 if (mapShape.Add(exp.Current()))
786 //=============================================================================
790 //=============================================================================
791 Handle(GEOM_Object) GEOMImpl_IShapesOperations::ReverseShape(Handle(GEOM_Object) theShape)
795 if (theShape.IsNull()) return NULL;
797 //Add a new reversed object
798 Handle(GEOM_Object) aReversed = GetEngine()->AddObject(GetDocID(), theShape->GetType());
800 //Add a new Revese function
801 Handle(GEOM_Function) aFunction;
802 aFunction = aReversed->AddFunction(GEOMImpl_ShapeDriver::GetID(), REVERSE_ORIENTATION);
803 if (aFunction.IsNull()) return NULL;
805 //Check if the function is set correctly
806 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
808 GEOMImpl_IShapes aSI (aFunction);
810 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
811 if (aRefShape.IsNull()) return NULL;
813 aSI.SetBase(aRefShape);
815 //Compute the sub-shape value
817 if (!GetSolver()->ComputeFunction(aFunction)) {
818 SetErrorCode("Shape driver failed to reverse shape");
822 catch (Standard_Failure) {
823 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
824 SetErrorCode(aFail->GetMessageString());
828 //Make a Python command
829 GEOM::TPythonDump(aFunction) << aReversed
830 << " = geompy.ChangeOrientation(" << theShape << ")";
836 //=============================================================================
840 //=============================================================================
841 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetFreeFacesIDs
842 (Handle(GEOM_Object) theShape)
846 if (theShape.IsNull()) return NULL;
847 TopoDS_Shape aShape = theShape->GetValue();
848 if (aShape.IsNull()) return NULL;
850 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
852 TopTools_IndexedDataMapOfShapeListOfShape mapFaceBlocks;
853 GEOMImpl_Block6Explorer::MapShapesAndAncestors
854 (aShape, TopAbs_FACE, TopAbs_SOLID, mapFaceBlocks);
856 Standard_Integer ind = 1, nbFaces = mapFaceBlocks.Extent();
859 SetErrorCode("The given shape has no faces");
863 TopTools_IndexedMapOfShape anIndices;
864 TopExp::MapShapes(aShape, anIndices);
867 for (; ind <= nbFaces; ind++) {
868 if (mapFaceBlocks.FindFromIndex(ind).Extent() != 2) {
869 id = anIndices.FindIndex(mapFaceBlocks.FindKey(ind));
874 //The explode doesn't change object so no new function is required.
875 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
876 TCollection_AsciiString anOldDescr = aFunction->GetDescription();
878 //Make a Python command
879 GEOM::TPythonDump(aFunction) << anOldDescr.ToCString()
880 << "\n\tlistFreeFacesIDs = geompy.GetFreeFacesIDs(" << theShape << ")";
886 //=======================================================================
887 //function : GetSharedShapes
889 //=======================================================================
891 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetSharedShapes
892 (Handle(GEOM_Object) theShape1,
893 Handle(GEOM_Object) theShape2,
894 const Standard_Integer theShapeType)
898 if (theShape1.IsNull() || theShape2.IsNull()) return NULL;
900 TopoDS_Shape aShape1 = theShape1->GetValue();
901 TopoDS_Shape aShape2 = theShape2->GetValue();
903 if (aShape1.IsNull() || aShape2.IsNull()) return NULL;
905 TopTools_IndexedMapOfShape anIndices;
906 TopExp::MapShapes(aShape1, anIndices);
907 Handle(TColStd_HArray1OfInteger) anArray;
909 TopTools_IndexedMapOfShape mapShape1;
910 TopExp::MapShapes(aShape1, TopAbs_ShapeEnum(theShapeType), mapShape1);
912 Handle(GEOM_Object) anObj;
913 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
914 TCollection_AsciiString anAsciiList, anEntry;
916 TopTools_MapOfShape mapShape2;
917 TopExp_Explorer exp (aShape2, TopAbs_ShapeEnum(theShapeType));
918 for (; exp.More(); exp.Next()) {
919 TopoDS_Shape aSS = exp.Current();
920 if (mapShape2.Add(aSS) && mapShape1.Contains(aSS)) {
921 anArray = new TColStd_HArray1OfInteger(1,1);
922 anArray->SetValue(1, anIndices.FindIndex(aSS));
923 anObj = GetEngine()->AddSubShape(theShape1, anArray);
926 // for python command
927 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
928 anAsciiList += anEntry;
933 if (aSeq->IsEmpty()) {
934 SetErrorCode("The given shapes have no shared sub-shapes of the requested type");
938 //Make a Python command
939 anAsciiList.Trunc(anAsciiList.Length() - 1);
941 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
943 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
944 << "] = geompy.GetSharedShapes(" << theShape1 << ", "
945 << theShape2 << ", " << theShapeType << ")";
951 //=============================================================================
955 //=============================================================================
956 static GEOM::TPythonDump& operator<< (GEOM::TPythonDump& theDump,
957 const GEOMAlgo_State theState)
961 theDump << "geompy.GEOM.ST_IN";
963 case GEOMAlgo_ST_OUT:
964 theDump << "geompy.GEOM.ST_OUT";
967 theDump << "geompy.GEOM.ST_ON";
969 case GEOMAlgo_ST_ONIN:
970 theDump << "geompy.GEOM.ST_ONIN";
972 case GEOMAlgo_ST_ONOUT:
973 theDump << "geompy.GEOM.ST_ONOUT";
976 theDump << "geompy.GEOM.ST_UNKNOWN";
982 //=======================================================================
983 //function : checkTypeShapesOn
985 * \brief Checks if theShapeType parameter of GetShapesOnXXX() is OK
986 * \param theShapeType - the shape type to check
987 * \retval bool - result of the check
989 //=======================================================================
991 bool GEOMImpl_IShapesOperations::checkTypeShapesOn(const Standard_Integer theShapeType)
993 if (theShapeType != TopAbs_VERTEX &&
994 theShapeType != TopAbs_EDGE &&
995 theShapeType != TopAbs_FACE &&
996 theShapeType != TopAbs_SOLID) {
997 SetErrorCode("Only solids, vertices, edges or faces can be found by this method");
1003 //=======================================================================
1004 //function : makePlane
1006 * \brief Creates Geom_Plane
1007 * \param theAx1 - shape object defining plane parameters
1008 * \retval Handle(Geom_Surface) - resulting surface
1010 //=======================================================================
1012 Handle(Geom_Surface) GEOMImpl_IShapesOperations::makePlane(const TopoDS_Shape& anAx1)
1014 if (anAx1.ShapeType() != TopAbs_EDGE) return NULL;
1015 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
1016 TopoDS_Vertex V1, V2;
1017 TopExp::Vertices(anEdge, V1, V2, Standard_True);
1018 if (V1.IsNull() || V2.IsNull()) {
1019 SetErrorCode("Bad edge given for the plane normal vector");
1022 gp_Pnt aLoc = BRep_Tool::Pnt(V1);
1023 gp_Vec aVec (aLoc, BRep_Tool::Pnt(V2));
1024 if (aVec.Magnitude() < Precision::Confusion()) {
1025 SetErrorCode("Vector with null magnitude given");
1028 return new Geom_Plane(aLoc, aVec);
1031 //=======================================================================
1032 //function : makeCylinder
1034 * \brief Creates Geom_CylindricalSurface
1035 * \param theAx1 - edge defining cylinder axis
1036 * \param theRadius - cylinder radius
1037 * \retval Handle(Geom_Surface) - resulting surface
1039 //=======================================================================
1041 Handle(Geom_Surface) GEOMImpl_IShapesOperations::makeCylinder(const TopoDS_Shape& anAxis,
1042 const Standard_Real theRadius)
1044 //Axis of the cylinder
1045 if (anAxis.ShapeType() != TopAbs_EDGE) {
1046 SetErrorCode("Not an edge given for the axis");
1049 TopoDS_Edge anEdge = TopoDS::Edge(anAxis);
1050 TopoDS_Vertex V1, V2;
1051 TopExp::Vertices(anEdge, V1, V2, Standard_True);
1052 if (V1.IsNull() || V2.IsNull()) {
1053 SetErrorCode("Bad edge given for the axis");
1056 gp_Pnt aLoc = BRep_Tool::Pnt(V1);
1057 gp_Vec aVec (aLoc, BRep_Tool::Pnt(V2));
1058 if (aVec.Magnitude() < Precision::Confusion()) {
1059 SetErrorCode("Vector with null magnitude given");
1063 gp_Ax3 anAx3 (aLoc, aVec);
1064 return new Geom_CylindricalSurface(anAx3, theRadius);
1068 //=======================================================================
1069 //function : getShapesOnSurfaceIDs
1071 * \brief Find IDs of subshapes complying with given status about surface
1072 * \param theSurface - the surface to check state of subshapes against
1073 * \param theShape - the shape to explore
1074 * \param theShapeType - type of subshape of theShape
1075 * \param theState - required state
1076 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1078 //=======================================================================
1080 Handle(TColStd_HSequenceOfInteger)
1081 GEOMImpl_IShapesOperations::getShapesOnSurfaceIDs(const Handle(Geom_Surface)& theSurface,
1082 const TopoDS_Shape& theShape,
1083 TopAbs_ShapeEnum theShapeType,
1084 GEOMAlgo_State theState)
1086 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
1087 // MESSAGE("--------------------------- GetShapesOnPlane phase 1 takes:");
1088 // OSD_Timer timer1;
1091 // Check presence of triangulation, build if need
1092 if (!CheckTriangulation(theShape))
1096 GEOMAlgo_FinderShapeOn1 aFinder;
1097 Standard_Real aTol = 0.0001; // default value
1099 aFinder.SetShape(theShape);
1100 aFinder.SetTolerance(aTol);
1101 aFinder.SetSurface(theSurface);
1102 aFinder.SetShapeType(theShapeType);
1103 aFinder.SetState(theState);
1105 // Sets the minimal number of inner points for the faces that do not have own
1106 // inner points at all (for e.g. rectangular planar faces have just 2 triangles).
1108 aFinder.SetNbPntsMin(3);
1109 // Sets the maximal number of inner points for edges or faces.
1110 // It is usefull for the cases when this number is very big (e.g =2000) to improve
1111 // the performance. If this value =0, all inner points will be taken into account.
1113 aFinder.SetNbPntsMax(100);
1118 // MESSAGE("--------------------------- Perform on Plane takes:");
1125 // MESSAGE("--------------------------- GetShapesOnPlane phase 3 takes:");
1129 // Interprete results
1130 Standard_Integer iErr = aFinder.ErrorStatus();
1131 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
1133 MESSAGE(" iErr : " << iErr);
1134 TCollection_AsciiString aMsg (" iErr : ");
1135 aMsg += TCollection_AsciiString(iErr);
1139 Standard_Integer iWrn = aFinder.WarningStatus();
1140 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
1142 MESSAGE(" *** iWrn : " << iWrn);
1145 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
1147 if (listSS.Extent() < 1) {
1148 SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
1155 // MESSAGE("--------------------------- GetShapesOnPlane phase 4 takes:");
1159 // Fill sequence of object IDs
1160 aSeqOfIDs = new TColStd_HSequenceOfInteger;
1162 TopTools_IndexedMapOfShape anIndices;
1163 TopExp::MapShapes(theShape, anIndices);
1165 TopTools_ListIteratorOfListOfShape itSub (listSS);
1166 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
1167 int id = anIndices.FindIndex(itSub.Value());
1168 aSeqOfIDs->Append(id);
1175 //=======================================================================
1176 //function : getObjectsShapesOn
1178 * \brief Find shape objects and their entries by their ids
1179 * \param theShapeIDs - incoming shape ids
1180 * \param theShapeEntries - outgoing entries like "entry1, entry2, ..."
1181 * \retval Handle(TColStd_HSequenceOfTransient) - found shape objects
1183 //=======================================================================
1185 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::
1186 getObjectsShapesOn(const Handle(GEOM_Object)& theShape,
1187 const Handle(TColStd_HSequenceOfInteger)& theShapeIDs,
1188 TCollection_AsciiString & theShapeEntries)
1190 Handle(TColStd_HSequenceOfTransient) aSeq;
1192 if ( !theShapeIDs.IsNull() && theShapeIDs->Length() > 0 )
1194 aSeq = new TColStd_HSequenceOfTransient;
1195 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
1196 TCollection_AsciiString anEntry;
1197 for ( int i = 1; i <= theShapeIDs->Length(); ++i )
1199 anArray->SetValue(1, theShapeIDs->Value( i ));
1200 Handle(GEOM_Object) anObj = GetEngine()->AddSubShape(theShape, anArray);
1201 aSeq->Append( anObj );
1203 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
1204 if ( i != 1 ) theShapeEntries += ",";
1205 theShapeEntries += anEntry;
1211 //=======================================================================
1212 //function : getShapesOnSurface
1214 * \brief Find subshapes complying with given status about surface
1215 * \param theSurface - the surface to check state of subshapes against
1216 * \param theShape - the shape to explore
1217 * \param theShapeType - type of subshape of theShape
1218 * \param theState - required state
1219 * \param theShapeEntries - outgoing entries like "entry1, entry2, ..."
1220 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1222 //=======================================================================
1224 Handle(TColStd_HSequenceOfTransient)
1225 GEOMImpl_IShapesOperations::getShapesOnSurface(const Handle(Geom_Surface)& theSurface,
1226 const Handle(GEOM_Object)& theShape,
1227 TopAbs_ShapeEnum theShapeType,
1228 GEOMAlgo_State theState,
1229 TCollection_AsciiString & theShapeEntries)
1231 // Find subshapes ids
1232 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
1233 getShapesOnSurfaceIDs (theSurface, theShape->GetValue(), theShapeType, theState);
1234 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
1237 return getObjectsShapesOn( theShape, aSeqOfIDs, theShapeEntries );
1240 //=============================================================================
1244 //=============================================================================
1245 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnPlane
1246 (const Handle(GEOM_Object)& theShape,
1247 const Standard_Integer theShapeType,
1248 const Handle(GEOM_Object)& theAx1,
1249 const GEOMAlgo_State theState)
1253 // MESSAGE("--------------------------- GetShapesOnPlane phase 1 takes:");
1254 // OSD_Timer timer1;
1257 if (theShape.IsNull() || theAx1.IsNull()) return NULL;
1259 TopoDS_Shape aShape = theShape->GetValue();
1260 TopoDS_Shape anAx1 = theAx1->GetValue();
1262 if (aShape.IsNull() || anAx1.IsNull()) return NULL;
1264 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
1265 if ( !checkTypeShapesOn( theShapeType ))
1269 Handle(Geom_Surface) aPlane = makePlane( anAx1 );
1270 if ( aPlane.IsNull() )
1274 TCollection_AsciiString anAsciiList;
1275 Handle(TColStd_HSequenceOfTransient) aSeq;
1276 aSeq = getShapesOnSurface( aPlane, theShape, aShapeType, theState, anAsciiList );
1277 if ( aSeq.IsNull() || aSeq->Length() == 0 )
1283 // MESSAGE("--------------------------- GetShapesOnPlane phase 5 takes:");
1287 // Make a Python command
1289 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
1290 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1292 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
1293 << "] = geompy.GetShapesOnPlane(" << theShape << ", "
1294 << theShapeType << ", " << theAx1 << ", " << theState << ")";
1300 //=============================================================================
1302 * GetShapesOnCylinder
1304 //=============================================================================
1305 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnCylinder
1306 (const Handle(GEOM_Object)& theShape,
1307 const Standard_Integer theShapeType,
1308 const Handle(GEOM_Object)& theAxis,
1309 const Standard_Real theRadius,
1310 const GEOMAlgo_State theState)
1314 if (theShape.IsNull() || theAxis.IsNull()) return NULL;
1316 TopoDS_Shape aShape = theShape->GetValue();
1317 TopoDS_Shape anAxis = theAxis->GetValue();
1319 if (aShape.IsNull() || anAxis.IsNull()) return NULL;
1321 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
1322 if ( !checkTypeShapesOn( aShapeType ))
1325 // Create a cylinder surface
1326 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
1327 if ( aCylinder.IsNull() )
1331 TCollection_AsciiString anAsciiList;
1332 Handle(TColStd_HSequenceOfTransient) aSeq;
1333 aSeq = getShapesOnSurface( aCylinder, theShape, aShapeType, theState, anAsciiList );
1334 if ( aSeq.IsNull() || aSeq->Length() == 0 )
1337 // Make a Python command
1339 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
1340 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1342 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
1343 << "] = geompy.GetShapesOnCylinder(" << theShape << ", " << theShapeType
1344 << ", " << theAxis << ", " << theRadius << ", " << theState << ")";
1350 //=============================================================================
1354 //=============================================================================
1355 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnSphere
1356 (const Handle(GEOM_Object)& theShape,
1357 const Standard_Integer theShapeType,
1358 const Handle(GEOM_Object)& theCenter,
1359 const Standard_Real theRadius,
1360 const GEOMAlgo_State theState)
1364 if (theShape.IsNull() || theCenter.IsNull()) return NULL;
1366 TopoDS_Shape aShape = theShape->GetValue();
1367 TopoDS_Shape aCenter = theCenter->GetValue();
1369 if (aShape.IsNull() || aCenter.IsNull()) return NULL;
1371 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
1372 if ( !checkTypeShapesOn( aShapeType ))
1375 // Center of the sphere
1376 if (aCenter.ShapeType() != TopAbs_VERTEX) return NULL;
1377 gp_Pnt aLoc = BRep_Tool::Pnt(TopoDS::Vertex(aCenter));
1379 gp_Ax3 anAx3 (aLoc, gp::DZ());
1380 Handle(Geom_SphericalSurface) aSphere =
1381 new Geom_SphericalSurface(anAx3, theRadius);
1384 TCollection_AsciiString anAsciiList;
1385 Handle(TColStd_HSequenceOfTransient) aSeq;
1386 aSeq = getShapesOnSurface( aSphere, theShape, aShapeType, theState, anAsciiList );
1387 if ( aSeq.IsNull() || aSeq->Length() == 0 )
1390 // Make a Python command
1392 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
1393 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1395 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
1396 << "] = geompy.GetShapesOnSphere(" << theShape << ", " << theShapeType
1397 << ", " << theCenter << ", " << theRadius << ", " << theState << ")";
1403 //=======================================================================
1404 //function : getCreatedLast
1406 * \brief Select the object created last
1407 * \param theObj1 - Object 1
1408 * \param theObj2 - Object 2
1409 * \retval Handle(GEOM_Object) - selected object
1411 //=======================================================================
1413 Handle(GEOM_Object) GEOMImpl_IShapesOperations::getCreatedLast(const Handle(GEOM_Object)& theObj1,
1414 const Handle(GEOM_Object)& theObj2)
1416 if ( theObj1.IsNull() ) return theObj2;
1417 if ( theObj2.IsNull() ) return theObj1;
1418 return ( theObj1->GetEntry().Tag() > theObj2->GetEntry().Tag() ) ? theObj1 : theObj2;
1421 //=============================================================================
1423 * GetShapesOnPlaneIDs
1425 //=============================================================================
1426 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnPlaneIDs
1427 (const Handle(GEOM_Object)& theShape,
1428 const Standard_Integer theShapeType,
1429 const Handle(GEOM_Object)& theAx1,
1430 const GEOMAlgo_State theState)
1434 if (theShape.IsNull() || theAx1.IsNull()) return NULL;
1436 TopoDS_Shape aShape = theShape->GetValue();
1437 TopoDS_Shape anAx1 = theAx1->GetValue();
1439 if (aShape.IsNull() || anAx1.IsNull()) return NULL;
1441 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
1442 if ( !checkTypeShapesOn( aShapeType ))
1446 Handle(Geom_Surface) aPlane = makePlane( anAx1 );
1447 if ( aPlane.IsNull() )
1451 Handle(TColStd_HSequenceOfInteger) aSeq;
1452 aSeq = getShapesOnSurfaceIDs( aPlane, aShape, aShapeType, theState );
1454 // The GetShapesOnPlaneIDs() doesn't change object so no new function is required.
1455 Handle(GEOM_Function) aFunction = getCreatedLast(theShape,theAx1)->GetLastFunction();
1457 // Make a Python command
1458 const bool append = true;
1459 GEOM::TPythonDump(aFunction,append)
1460 << "listShapesOnPlane = geompy.GetShapesOnPlaneIDs"
1461 << "(" << theShape << "," << theShapeType << "," << theAx1 << "," << theState << ")";
1467 //=============================================================================
1469 * GetShapesOnCylinderIDs
1471 //=============================================================================
1472 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnCylinderIDs
1473 (const Handle(GEOM_Object)& theShape,
1474 const Standard_Integer theShapeType,
1475 const Handle(GEOM_Object)& theAxis,
1476 const Standard_Real theRadius,
1477 const GEOMAlgo_State theState)
1481 if (theShape.IsNull() || theAxis.IsNull()) return NULL;
1483 TopoDS_Shape aShape = theShape->GetValue();
1484 TopoDS_Shape anAxis = theAxis->GetValue();
1486 if (aShape.IsNull() || anAxis.IsNull()) return NULL;
1488 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
1489 if ( !checkTypeShapesOn( aShapeType ))
1492 // Create a cylinder surface
1493 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
1494 if ( aCylinder.IsNull() )
1498 Handle(TColStd_HSequenceOfInteger) aSeq;
1499 aSeq = getShapesOnSurfaceIDs( aCylinder, aShape, aShapeType, theState );
1501 // The GetShapesOnCylinder() doesn't change object so no new function is required.
1502 Handle(GEOM_Function) aFunction = getCreatedLast(theShape,theAxis)->GetLastFunction();
1504 // Make a Python command
1505 const bool append = true;
1506 GEOM::TPythonDump(aFunction,append)
1507 << "listShapesOnCylinder = geompy.GetShapesOnCylinderIDs"
1508 << "(" << theShape << ", " << theShapeType << ", " << theAxis << ", "
1509 << theRadius << ", " << theState << ")";
1515 //=============================================================================
1517 * GetShapesOnSphereIDs
1519 //=============================================================================
1520 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnSphereIDs
1521 (const Handle(GEOM_Object)& theShape,
1522 const Standard_Integer theShapeType,
1523 const Handle(GEOM_Object)& theCenter,
1524 const Standard_Real theRadius,
1525 const GEOMAlgo_State theState)
1529 if (theShape.IsNull() || theCenter.IsNull()) return NULL;
1531 TopoDS_Shape aShape = theShape->GetValue();
1532 TopoDS_Shape aCenter = theCenter->GetValue();
1534 if (aShape.IsNull() || aCenter.IsNull()) return NULL;
1536 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
1537 if ( !checkTypeShapesOn( aShapeType ))
1540 // Center of the sphere
1541 if (aCenter.ShapeType() != TopAbs_VERTEX) return NULL;
1542 gp_Pnt aLoc = BRep_Tool::Pnt(TopoDS::Vertex(aCenter));
1544 gp_Ax3 anAx3 (aLoc, gp::DZ());
1545 Handle(Geom_SphericalSurface) aSphere =
1546 new Geom_SphericalSurface(anAx3, theRadius);
1549 Handle(TColStd_HSequenceOfInteger) aSeq;
1550 aSeq = getShapesOnSurfaceIDs( aSphere, aShape, aShapeType, theState );
1552 // The GetShapesOnSphere() doesn't change object so no new function is required.
1553 Handle(GEOM_Function) aFunction = getCreatedLast(theShape,theCenter)->GetLastFunction();
1555 // Make a Python command
1556 const bool append = true;
1557 GEOM::TPythonDump(aFunction,append)
1558 << "listShapesOnCylinder = geompy.GetShapesOnCylinderIDs"
1559 << "(" << theShape << ", " << theShapeType << ", " << theCenter << ", "
1560 << theRadius << ", " << theState << ")";
1566 //=======================================================================
1567 //function : getShapesOnQuadrangleIDs
1569 * \brief Find IDs of subshapes complying with given status about quadrangle
1570 * \param theShape - the shape to explore
1571 * \param theShapeType - type of subshape of theShape
1572 * \param theTopLeftPoint - top left quadrangle corner
1573 * \param theTopRigthPoint - top right quadrangle corner
1574 * \param theBottomLeftPoint - bottom left quadrangle corner
1575 * \param theBottomRigthPoint - bottom right quadrangle corner
1576 * \param theState - required state
1577 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1579 //=======================================================================
1581 Handle(TColStd_HSequenceOfInteger)
1582 GEOMImpl_IShapesOperations::getShapesOnQuadrangleIDs (const Handle(GEOM_Object)& theShape,
1583 const Standard_Integer theShapeType,
1584 const Handle(GEOM_Object)& theTopLeftPoint,
1585 const Handle(GEOM_Object)& theTopRigthPoint,
1586 const Handle(GEOM_Object)& theBottomLeftPoint,
1587 const Handle(GEOM_Object)& theBottomRigthPoint,
1588 const GEOMAlgo_State theState)
1592 if ( theShape.IsNull() ||
1593 theTopLeftPoint.IsNull() ||
1594 theTopRigthPoint.IsNull() ||
1595 theBottomLeftPoint.IsNull() ||
1596 theBottomRigthPoint.IsNull() )
1599 TopoDS_Shape aShape = theShape->GetValue();
1600 TopoDS_Shape aTL = theTopLeftPoint->GetValue();
1601 TopoDS_Shape aTR = theTopRigthPoint->GetValue();
1602 TopoDS_Shape aBL = theBottomLeftPoint->GetValue();
1603 TopoDS_Shape aBR = theBottomRigthPoint->GetValue();
1605 if (aShape.IsNull() ||
1610 aTL.ShapeType() != TopAbs_VERTEX ||
1611 aTR.ShapeType() != TopAbs_VERTEX ||
1612 aBL.ShapeType() != TopAbs_VERTEX ||
1613 aBR.ShapeType() != TopAbs_VERTEX )
1616 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
1617 if ( !checkTypeShapesOn( aShapeType ))
1620 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
1622 // Check presence of triangulation, build if need
1623 if (!CheckTriangulation(aShape))
1627 gp_Pnt aPntTL = BRep_Tool::Pnt(TopoDS::Vertex(aTL));
1628 gp_Pnt aPntTR = BRep_Tool::Pnt(TopoDS::Vertex(aTR));
1629 gp_Pnt aPntBL = BRep_Tool::Pnt(TopoDS::Vertex(aBL));
1630 gp_Pnt aPntBR = BRep_Tool::Pnt(TopoDS::Vertex(aBR));
1632 GEOMAlgo_FinderShapeOnQuad aFinder( aPntTL, aPntTR, aPntBL, aPntBR );
1633 Standard_Real aTol = 0.0001; // default value
1635 aFinder.SetShape(aShape);
1636 aFinder.SetTolerance(aTol);
1637 //aFinder.SetSurface(theSurface);
1638 aFinder.SetShapeType(aShapeType);
1639 aFinder.SetState(theState);
1641 // Sets the minimal number of inner points for the faces that do not have own
1642 // inner points at all (for e.g. rectangular planar faces have just 2 triangles).
1644 aFinder.SetNbPntsMin(3);
1645 // Sets the maximal number of inner points for edges or faces.
1646 // It is usefull for the cases when this number is very big (e.g =2000) to improve
1647 // the performance. If this value =0, all inner points will be taken into account.
1649 aFinder.SetNbPntsMax(100);
1653 // Interprete results
1654 Standard_Integer iErr = aFinder.ErrorStatus();
1655 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
1657 MESSAGE(" iErr : " << iErr);
1658 TCollection_AsciiString aMsg (" iErr : ");
1659 aMsg += TCollection_AsciiString(iErr);
1663 Standard_Integer iWrn = aFinder.WarningStatus();
1664 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
1666 MESSAGE(" *** iWrn : " << iWrn);
1669 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
1671 if (listSS.Extent() < 1) {
1672 SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
1676 // Fill sequence of object IDs
1677 aSeqOfIDs = new TColStd_HSequenceOfInteger;
1679 TopTools_IndexedMapOfShape anIndices;
1680 TopExp::MapShapes(aShape, anIndices);
1682 TopTools_ListIteratorOfListOfShape itSub (listSS);
1683 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
1684 int id = anIndices.FindIndex(itSub.Value());
1685 aSeqOfIDs->Append(id);
1690 //=======================================================================
1691 //function : GetShapesOnQuadrangle
1693 * \brief Find subshapes complying with given status about quadrangle
1694 * \param theShape - the shape to explore
1695 * \param theShapeType - type of subshape of theShape
1696 * \param theTopLeftPoint - top left quadrangle corner
1697 * \param theTopRigthPoint - top right quadrangle corner
1698 * \param theBottomLeftPoint - bottom left quadrangle corner
1699 * \param theBottomRigthPoint - bottom right quadrangle corner
1700 * \param theState - required state
1701 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1703 //=======================================================================
1705 Handle(TColStd_HSequenceOfTransient)
1706 GEOMImpl_IShapesOperations::GetShapesOnQuadrangle (const Handle(GEOM_Object)& theShape,
1707 const Standard_Integer theShapeType,
1708 const Handle(GEOM_Object)& theTopLeftPoint,
1709 const Handle(GEOM_Object)& theTopRigthPoint,
1710 const Handle(GEOM_Object)& theBottomLeftPoint,
1711 const Handle(GEOM_Object)& theBottomRigthPoint,
1712 const GEOMAlgo_State theState)
1715 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
1716 getShapesOnQuadrangleIDs( theShape,
1721 theBottomRigthPoint,
1723 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->IsEmpty() )
1726 // Find objects by indices
1727 TCollection_AsciiString anAsciiList;
1728 Handle(TColStd_HSequenceOfTransient) aSeq;
1729 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
1730 if ( aSeq.IsNull() || aSeq->IsEmpty() )
1733 // Make a Python command
1735 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
1736 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1738 GEOM::TPythonDump(aFunction)
1739 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnQuadrangle("
1741 << theShapeType << ", "
1742 << theTopLeftPoint << ", "
1743 << theTopRigthPoint << ", "
1744 << theBottomLeftPoint << ", "
1745 << theBottomRigthPoint << ", "
1752 //=======================================================================
1753 //function : GetShapesOnQuadrangleIDs
1755 * \brief Find IDs of subshapes complying with given status about quadrangle
1756 * \param theShape - the shape to explore
1757 * \param theShapeType - type of subshape of theShape
1758 * \param theTopLeftPoint - top left quadrangle corner
1759 * \param theTopRigthPoint - top right quadrangle corner
1760 * \param theBottomLeftPoint - bottom left quadrangle corner
1761 * \param theBottomRigthPoint - bottom right quadrangle corner
1762 * \param theState - required state
1763 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1765 //=======================================================================
1767 Handle(TColStd_HSequenceOfInteger)
1768 GEOMImpl_IShapesOperations::GetShapesOnQuadrangleIDs (const Handle(GEOM_Object)& theShape,
1769 const Standard_Integer theShapeType,
1770 const Handle(GEOM_Object)& theTopLeftPoint,
1771 const Handle(GEOM_Object)& theTopRigthPoint,
1772 const Handle(GEOM_Object)& theBottomLeftPoint,
1773 const Handle(GEOM_Object)& theBottomRigthPoint,
1774 const GEOMAlgo_State theState)
1777 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
1778 getShapesOnQuadrangleIDs( theShape,
1783 theBottomRigthPoint,
1785 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->IsEmpty() )
1788 // Make a Python command
1790 // The GetShapesOnCylinder() doesn't change object so no new function is required.
1791 Handle(GEOM_Object) lastObj = getCreatedLast(theShape,theTopLeftPoint);
1792 lastObj = getCreatedLast(lastObj,theTopRigthPoint);
1793 lastObj = getCreatedLast(lastObj,theBottomRigthPoint);
1794 lastObj = getCreatedLast(lastObj,theBottomLeftPoint);
1795 Handle(GEOM_Function) aFunction = lastObj->GetLastFunction();
1797 const bool append = true;
1798 GEOM::TPythonDump(aFunction,append)
1799 << "listShapesOnQuadrangle = geompy.GetShapesOnQuadrangleIDs("
1801 << theShapeType << ", "
1802 << theTopLeftPoint << ", "
1803 << theTopRigthPoint << ", "
1804 << theBottomLeftPoint << ", "
1805 << theBottomRigthPoint << ", "
1813 //=============================================================================
1817 //=============================================================================
1818 static void SimplifyWhat (TopoDS_Shape& theWhat,
1819 TopTools_IndexedMapOfShape& theArgumentIndices,
1820 TColStd_ListOfInteger& theSimpleSubWhat)
1822 TopTools_MapOfShape mapShape;
1823 TopoDS_Iterator It (theWhat, Standard_True, Standard_True);
1824 for (; It.More(); It.Next()) {
1825 if (mapShape.Add(It.Value())) {
1826 TopoDS_Shape curSh = It.Value();
1827 if (curSh.ShapeType() == TopAbs_COMPOUND ||
1828 curSh.ShapeType() == TopAbs_COMPSOLID) {
1829 SimplifyWhat(curSh, theArgumentIndices, theSimpleSubWhat);
1831 theSimpleSubWhat.Append(theArgumentIndices.FindIndex(curSh));
1837 static bool GetInPlaceOfCompound (Handle(GEOM_Function)& theWhereFunction,
1838 TopoDS_Shape& theWhat,
1839 TColStd_ListOfInteger& theModifiedArray)
1841 bool isFoundAny = false;
1842 TopTools_MapOfShape mapShape;
1843 TopoDS_Iterator It (theWhat, Standard_True, Standard_True);
1844 for (; It.More(); It.Next()) {
1845 if (mapShape.Add(It.Value())) {
1846 TopoDS_Shape curWhat = It.Value();
1847 if (curWhat.ShapeType() == TopAbs_COMPOUND ||
1848 curWhat.ShapeType() == TopAbs_COMPSOLID) {
1849 // Recursive call for compound or compsolid
1850 if (GetInPlaceOfCompound(theWhereFunction, curWhat, theModifiedArray))
1853 // Try to find for "simple" shape
1854 bool isFound = false;
1856 TDF_LabelSequence aLabelSeq;
1857 theWhereFunction->GetDependency(aLabelSeq);
1858 Standard_Integer nbArg = aLabelSeq.Length();
1860 for (Standard_Integer iarg = 1; iarg <= nbArg && !isFound; iarg++) {
1862 TDF_Label anArgumentRefLabel = aLabelSeq.Value(iarg);
1864 Handle(GEOM_Object) anArgumentObject = GEOM_Object::GetReferencedObject(anArgumentRefLabel);
1865 TopoDS_Shape anArgumentShape = anArgumentObject->GetValue();
1867 TopTools_IndexedMapOfShape anArgumentIndices;
1868 TopExp::MapShapes(anArgumentShape, anArgumentIndices);
1870 if (anArgumentIndices.Contains(curWhat)) {
1871 isFound = Standard_True;
1872 Standard_Integer aWhatIndex = anArgumentIndices.FindIndex(curWhat);
1874 // Find corresponding label in history
1875 TDF_Label anArgumentHistoryLabel =
1876 theWhereFunction->GetArgumentHistoryEntry(anArgumentRefLabel, Standard_False);
1877 if (!anArgumentHistoryLabel.IsNull()) {
1878 TDF_Label aWhatHistoryLabel = anArgumentHistoryLabel.FindChild(aWhatIndex, Standard_False);
1879 if (!aWhatHistoryLabel.IsNull()) {
1880 Handle(TDataStd_IntegerArray) anIntegerArray;
1881 if (aWhatHistoryLabel.FindAttribute(TDataStd_IntegerArray::GetID(), anIntegerArray)) {
1882 Standard_Integer imod, aModifLen = anIntegerArray->Array()->Length();
1883 for (imod = 1; imod <= aModifLen; imod++) {
1884 theModifiedArray.Append(anIntegerArray->Array()->Value(imod));
1899 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlace
1900 (Handle(GEOM_Object) theShapeWhere,
1901 Handle(GEOM_Object) theShapeWhat)
1905 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
1907 TopoDS_Shape aWhere = theShapeWhere->GetValue();
1908 TopoDS_Shape aWhat = theShapeWhat->GetValue();
1910 if (aWhere.IsNull() || aWhat.IsNull()) return NULL;
1912 //Fill array of indices
1913 Handle(TColStd_HArray1OfInteger) aModifiedArray;
1915 Handle(GEOM_Function) aWhereFunction = theShapeWhere->GetLastFunction();
1917 TopTools_IndexedMapOfShape aWhereIndices;
1918 TopExp::MapShapes(aWhere, aWhereIndices);
1920 if (aWhereIndices.Contains(aWhat)) {
1922 // entity was not changed by the operation
1923 Standard_Integer aWhatIndex = aWhereIndices.FindIndex(aWhat);
1924 aModifiedArray = new TColStd_HArray1OfInteger(1,1);
1925 aModifiedArray->SetValue(1, aWhatIndex);
1929 TDF_Label aHistoryLabel = aWhereFunction->GetHistoryEntry(Standard_False);
1930 if (aHistoryLabel.IsNull()) {
1931 SetErrorCode("Modifications history does not exist for the shape under consideration.");
1935 // search in history for all argument shapes
1936 Standard_Boolean isFound = Standard_False;
1938 TDF_LabelSequence aLabelSeq;
1939 aWhereFunction->GetDependency(aLabelSeq);
1940 Standard_Integer nbArg = aLabelSeq.Length();
1942 for (Standard_Integer iarg = 1; iarg <= nbArg && !isFound; iarg++) {
1944 TDF_Label anArgumentRefLabel = aLabelSeq.Value(iarg);
1946 Handle(GEOM_Object) anArgumentObject = GEOM_Object::GetReferencedObject(anArgumentRefLabel);
1947 TopoDS_Shape anArgumentShape = anArgumentObject->GetValue();
1949 TopTools_IndexedMapOfShape anArgumentIndices;
1950 TopExp::MapShapes(anArgumentShape, anArgumentIndices);
1952 if (anArgumentIndices.Contains(aWhat)) {
1953 isFound = Standard_True;
1954 Standard_Integer aWhatIndex = anArgumentIndices.FindIndex(aWhat);
1956 // Find corresponding label in history
1957 TDF_Label anArgumentHistoryLabel =
1958 aWhereFunction->GetArgumentHistoryEntry(anArgumentRefLabel, Standard_False);
1959 if (anArgumentHistoryLabel.IsNull()) {
1960 // Lost History of operation argument. Possibly, all its entities was removed.
1965 TDF_Label aWhatHistoryLabel = anArgumentHistoryLabel.FindChild(aWhatIndex, Standard_False);
1966 if (aWhatHistoryLabel.IsNull()) {
1967 // Check, if the sought shape is Compound or Compsolid.
1968 // In that case we will try to find history for its sub-shapes
1969 if (aWhat.ShapeType() == TopAbs_COMPOUND ||
1970 aWhat.ShapeType() == TopAbs_COMPSOLID) {
1971 TColStd_ListOfInteger aSimpleSubWhat, aModifiedList;
1972 SimplifyWhat(aWhat, anArgumentIndices, aSimpleSubWhat);
1973 TColStd_ListIteratorOfListOfInteger anIterSub (aSimpleSubWhat);
1974 for (; anIterSub.More(); anIterSub.Next()) {
1975 Standard_Integer aSubWhatIndex = anIterSub.Value();
1976 TDF_Label aSubWhatHistoryLabel =
1977 anArgumentHistoryLabel.FindChild(aSubWhatIndex, Standard_False);
1978 if (!aSubWhatHistoryLabel.IsNull()) {
1979 Handle(TDataStd_IntegerArray) anIntegerArray;
1980 if (aSubWhatHistoryLabel.FindAttribute(TDataStd_IntegerArray::GetID(), anIntegerArray)) {
1981 for (Standard_Integer isub = 1; isub <= anIntegerArray->Length(); isub++) {
1982 aModifiedList.Append(anIntegerArray->Value(isub));
1987 if (aModifiedList.Extent() > 0) {
1988 Handle(TColStd_HArray1OfInteger) aModifiedArraySub =
1989 new TColStd_HArray1OfInteger (1, aModifiedList.Extent());
1990 TColStd_ListIteratorOfListOfInteger anIterModif (aModifiedList);
1991 for (Standard_Integer imod = 1; anIterModif.More(); anIterModif.Next(), imod++) {
1992 aModifiedArraySub->SetValue(imod, anIterModif.Value());
1994 aModifiedArray = aModifiedArraySub;
2006 Handle(TDataStd_IntegerArray) anIntegerArray;
2007 if (!aWhatHistoryLabel.FindAttribute(TDataStd_IntegerArray::GetID(), anIntegerArray)) {
2008 SetErrorCode("Error: Empty modifications history for the sought shape.");
2012 aModifiedArray = anIntegerArray->Array();
2013 if (aModifiedArray->Length() == 0) {
2014 SetErrorCode("Error: Empty modifications history for the sought shape.");
2022 // try compound element by element
2023 if (aWhat.ShapeType() == TopAbs_COMPOUND ||
2024 aWhat.ShapeType() == TopAbs_COMPSOLID) {
2025 TColStd_ListOfInteger aModifiedList;
2026 isFound = GetInPlaceOfCompound(aWhereFunction, aWhat, aModifiedList);
2028 aModifiedArray = new TColStd_HArray1OfInteger (1, aModifiedList.Extent());
2029 TColStd_ListIteratorOfListOfInteger anIterModif (aModifiedList);
2030 for (Standard_Integer imod = 1; anIterModif.More(); anIterModif.Next(), imod++) {
2031 aModifiedArray->SetValue(imod, anIterModif.Value());
2036 SetErrorCode("The sought shape does not belong to any operation argument.");
2043 Handle(GEOM_Object) aResult = GetEngine()->AddSubShape(theShapeWhere, aModifiedArray);
2045 if (aModifiedArray->Length() > 1) {
2047 aResult->SetType(GEOM_GROUP);
2049 //Set a sub shape type
2050 TDF_Label aFreeLabel = aResult->GetFreeLabel();
2051 TopAbs_ShapeEnum aShapeType = aWhat.ShapeType();
2052 TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aShapeType);
2055 //Make a Python command
2056 Handle(GEOM_Function) aFunction = aResult->GetFunction(1);
2058 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetInPlace("
2059 << theShapeWhere << ", " << theShapeWhat << ")";
2065 //=======================================================================
2066 //function : SortShapes
2068 //=======================================================================
2069 void GEOMImpl_IShapesOperations::SortShapes(TopTools_ListOfShape& SL)
2071 Standard_Integer MaxShapes = SL.Extent();
2072 TopTools_Array1OfShape aShapes (1,MaxShapes);
2073 TColStd_Array1OfInteger OrderInd(1,MaxShapes);
2074 TColStd_Array1OfReal MidXYZ (1,MaxShapes); //X,Y,Z;
2075 TColStd_Array1OfReal Length (1,MaxShapes); //X,Y,Z;
2077 // Computing of CentreOfMass
2078 Standard_Integer Index;
2081 TopTools_ListIteratorOfListOfShape it(SL);
2082 for (Index=1; it.More(); Index++)
2084 TopoDS_Shape S = it.Value();
2085 SL.Remove( it ); // == it.Next()
2087 OrderInd.SetValue (Index, Index);
2088 if (S.ShapeType() == TopAbs_VERTEX)
2090 GPoint = BRep_Tool::Pnt( TopoDS::Vertex( S ));
2091 Length.SetValue( Index, (Standard_Real) S.Orientation());
2095 BRepGProp::LinearProperties (S, GPr);
2096 GPoint = GPr.CentreOfMass();
2097 Length.SetValue( Index, GPr.Mass() );
2099 MidXYZ.SetValue(Index,
2100 GPoint.X()*999 + GPoint.Y()*99 + GPoint.Z()*0.9);
2103 Standard_Integer aTemp;
2104 Standard_Boolean exchange, Sort = Standard_True;
2107 Sort = Standard_False;
2108 for (Index=1; Index < MaxShapes; Index++)
2110 if (MidXYZ(OrderInd(Index)) > MidXYZ(OrderInd(Index+1)))
2111 exchange = Standard_True;
2112 else if (MidXYZ(OrderInd(Index)) == MidXYZ(OrderInd(Index+1)) &&
2113 Length(OrderInd(Index)) > Length(OrderInd(Index+1)) )
2114 exchange = Standard_True;
2116 exchange = Standard_False;
2119 aTemp = OrderInd(Index);
2120 OrderInd(Index) = OrderInd(Index+1);
2121 OrderInd(Index+1) = aTemp;
2122 Sort = Standard_True;
2126 for (Index=1; Index <= MaxShapes; Index++)
2127 SL.Append( aShapes( OrderInd(Index) ));
2130 //=======================================================================
2131 //function : CheckTriangulation
2133 //=======================================================================
2134 bool GEOMImpl_IShapesOperations::CheckTriangulation (const TopoDS_Shape& aShape)
2136 // MESSAGE("CheckTriangulation");
2138 // OSD_Timer timer1;
2141 TopExp_Explorer exp (aShape, TopAbs_FACE);
2143 SetErrorCode("Shape without faces given");
2147 TopLoc_Location aTopLoc;
2148 Handle(Poly_Triangulation) aTRF;
2149 aTRF = BRep_Tool::Triangulation(TopoDS::Face(exp.Current()), aTopLoc);
2150 if (aTRF.IsNull()) {
2151 // calculate deflection
2152 Standard_Real aDeviationCoefficient = 0.001;
2155 BRepBndLib::Add(aShape, B);
2156 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
2157 B.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
2159 Standard_Real dx = aXmax - aXmin, dy = aYmax - aYmin, dz = aZmax - aZmin;
2160 Standard_Real aDeflection = Max(Max(dx, dy), dz) * aDeviationCoefficient * 4;
2162 // MESSAGE("Deflection = " << aDeflection);
2164 Standard_Real aHLRAngle = 0.349066;
2166 BRepMesh_IncrementalMesh Inc (aShape, aDeflection, Standard_False, aHLRAngle);