3 #include "GEOMImpl_IShapesOperations.hxx"
5 #include "GEOMImpl_Types.hxx"
7 #include "GEOMImpl_VectorDriver.hxx"
8 #include "GEOMImpl_ShapeDriver.hxx"
9 #include "GEOMImpl_CopyDriver.hxx"
10 #include "GEOMImpl_GlueDriver.hxx"
12 #include "GEOMImpl_IVector.hxx"
13 #include "GEOMImpl_IShapes.hxx"
14 #include "GEOMImpl_IGlue.hxx"
16 #include "GEOMImpl_Block6Explorer.hxx"
18 #include "GEOM_Function.hxx"
19 #include "GEOM_PythonDump.hxx"
21 #include "GEOMAlgo_FinderShapeOn1.hxx"
23 #include "utilities.h"
25 #include "Utils_ExceptHandlers.hxx"
27 #include <TFunction_DriverTable.hxx>
28 #include <TFunction_Driver.hxx>
29 #include <TFunction_Logbook.hxx>
30 #include <TDataStd_Integer.hxx>
31 #include <TDataStd_IntegerArray.hxx>
32 #include <TDF_Tool.hxx>
34 #include <BRepExtrema_ExtCF.hxx>
36 #include <BRep_Tool.hxx>
37 #include <BRepGProp.hxx>
38 #include <BRepAdaptor_Curve.hxx>
39 #include <BRepBndLib.hxx>
40 #include <BRepBuilderAPI_MakeFace.hxx>
41 #include <BRepMesh_IncrementalMesh.hxx>
46 #include <TopoDS_Shape.hxx>
47 #include <TopoDS_Face.hxx>
48 #include <TopoDS_Edge.hxx>
49 #include <TopoDS_Vertex.hxx>
50 #include <TopoDS_Iterator.hxx>
51 #include <TopExp_Explorer.hxx>
52 #include <TopLoc_Location.hxx>
53 #include <TopTools_MapOfShape.hxx>
54 #include <TopTools_Array1OfShape.hxx>
55 #include <TopTools_ListIteratorOfListOfShape.hxx>
56 #include <TopTools_IndexedMapOfShape.hxx>
58 #include <Geom_Surface.hxx>
59 #include <Geom_Plane.hxx>
60 #include <Geom_SphericalSurface.hxx>
61 #include <Geom_CylindricalSurface.hxx>
62 #include <GeomAdaptor_Surface.hxx>
64 #include <Geom2d_Curve.hxx>
66 #include <Bnd_Box.hxx>
67 #include <GProp_GProps.hxx>
70 #include <TColStd_Array1OfReal.hxx>
71 #include <TColStd_HArray1OfInteger.hxx>
72 #include <TColStd_ListOfInteger.hxx>
73 #include <TColStd_ListIteratorOfListOfInteger.hxx>
75 //#include <OSD_Timer.hxx>
77 #include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
79 //=============================================================================
83 //=============================================================================
84 GEOMImpl_IShapesOperations::GEOMImpl_IShapesOperations (GEOM_Engine* theEngine, int theDocID)
85 : GEOM_IOperations(theEngine, theDocID)
87 MESSAGE("GEOMImpl_IShapesOperations::GEOMImpl_IShapesOperations");
90 //=============================================================================
94 //=============================================================================
95 GEOMImpl_IShapesOperations::~GEOMImpl_IShapesOperations()
97 MESSAGE("GEOMImpl_IShapesOperations::~GEOMImpl_IShapesOperations");
101 //=============================================================================
105 //=============================================================================
106 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeEdge
107 (Handle(GEOM_Object) thePnt1, Handle(GEOM_Object) thePnt2)
111 if (thePnt1.IsNull() || thePnt2.IsNull()) return NULL;
113 //Add a new Edge object
114 Handle(GEOM_Object) anEdge = GetEngine()->AddObject(GetDocID(), GEOM_EDGE);
116 //Add a new Vector function
117 Handle(GEOM_Function) aFunction =
118 anEdge->AddFunction(GEOMImpl_VectorDriver::GetID(), VECTOR_TWO_PNT);
120 //Check if the function is set correctly
121 if (aFunction->GetDriverGUID() != GEOMImpl_VectorDriver::GetID()) return NULL;
123 GEOMImpl_IVector aPI (aFunction);
125 Handle(GEOM_Function) aRef1 = thePnt1->GetLastFunction();
126 Handle(GEOM_Function) aRef2 = thePnt2->GetLastFunction();
127 if (aRef1.IsNull() || aRef2.IsNull()) return NULL;
129 aPI.SetPoint1(aRef1);
130 aPI.SetPoint2(aRef2);
132 //Compute the Edge value
134 if (!GetSolver()->ComputeFunction(aFunction)) {
135 SetErrorCode("Vector driver failed");
139 catch (Standard_Failure) {
140 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
141 SetErrorCode(aFail->GetMessageString());
145 //Make a Python command
146 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdge("
147 << thePnt1 << ", " << thePnt2 << ")";
153 //=============================================================================
157 //=============================================================================
158 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeWire
159 (list<Handle(GEOM_Object)> theShapes)
161 return MakeShape(theShapes, GEOM_WIRE, WIRE_EDGES, "MakeWire");
164 //=============================================================================
168 //=============================================================================
169 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFace (Handle(GEOM_Object) theWire,
170 const bool isPlanarWanted)
174 if (theWire.IsNull()) return NULL;
176 //Add a new Face object
177 Handle(GEOM_Object) aFace = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
179 //Add a new Shape function for creation of a face from a wire
180 Handle(GEOM_Function) aFunction =
181 aFace->AddFunction(GEOMImpl_ShapeDriver::GetID(), FACE_WIRE);
182 if (aFunction.IsNull()) return NULL;
184 //Check if the function is set correctly
185 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
187 GEOMImpl_IShapes aCI (aFunction);
189 Handle(GEOM_Function) aRefWire = theWire->GetLastFunction();
191 if (aRefWire.IsNull()) return NULL;
193 aCI.SetBase(aRefWire);
194 aCI.SetIsPlanar(isPlanarWanted);
196 //Compute the Face value
198 if (!GetSolver()->ComputeFunction(aFunction)) {
199 SetErrorCode("Shape driver failed to compute a face");
203 catch (Standard_Failure) {
204 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
205 SetErrorCode(aFail->GetMessageString());
209 //Make a Python command
210 GEOM::TPythonDump(aFunction) << aFace << " = geompy.MakeFace("
211 << theWire << ", " << (int)isPlanarWanted << ")";
217 //=============================================================================
221 //=============================================================================
222 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFaceWires
223 (list<Handle(GEOM_Object)> theShapes,
224 const bool isPlanarWanted)
229 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
232 Handle(GEOM_Function) aFunction =
233 aShape->AddFunction(GEOMImpl_ShapeDriver::GetID(), FACE_WIRES);
234 if (aFunction.IsNull()) return NULL;
236 //Check if the function is set correctly
237 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
239 GEOMImpl_IShapes aCI (aFunction);
241 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
244 list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
245 for (; it != theShapes.end(); it++) {
246 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
247 if (aRefSh.IsNull()) {
248 SetErrorCode("NULL argument shape for the face construction");
251 aShapesSeq->Append(aRefSh);
253 aCI.SetShapes(aShapesSeq);
255 aCI.SetIsPlanar(isPlanarWanted);
259 if (!GetSolver()->ComputeFunction(aFunction)) {
260 SetErrorCode("Shape driver failed");
264 catch (Standard_Failure) {
265 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
266 SetErrorCode(aFail->GetMessageString());
270 //Make a Python command
271 GEOM::TPythonDump pd (aFunction);
272 pd << aShape << " = geompy.MakeFaceWires([";
275 it = theShapes.begin();
276 if (it != theShapes.end()) {
278 while (it != theShapes.end()) {
279 pd << ", " << (*it++);
282 pd << "], " << (int)isPlanarWanted << ")";
288 //=============================================================================
292 //=============================================================================
293 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeShell
294 (list<Handle(GEOM_Object)> theShapes)
296 return MakeShape(theShapes, GEOM_SHELL, SHELL_FACES, "MakeShell");
299 //=============================================================================
303 //=============================================================================
304 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeSolidShells
305 (list<Handle(GEOM_Object)> theShapes)
307 return MakeShape(theShapes, GEOM_SOLID, SOLID_SHELLS, "MakeSolidShells");
310 //=============================================================================
314 //=============================================================================
315 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeSolidShell (Handle(GEOM_Object) theShell)
319 if (theShell.IsNull()) return NULL;
321 //Add a new Solid object
322 Handle(GEOM_Object) aSolid = GetEngine()->AddObject(GetDocID(), GEOM_SOLID);
324 //Add a new Solid function for creation of a solid from a shell
325 Handle(GEOM_Function) aFunction =
326 aSolid->AddFunction(GEOMImpl_ShapeDriver::GetID(), SOLID_SHELL);
327 if (aFunction.IsNull()) return NULL;
329 //Check if the function is set correctly
330 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
332 GEOMImpl_IShapes aCI (aFunction);
334 Handle(GEOM_Function) aRefShell = theShell->GetLastFunction();
336 if (aRefShell.IsNull()) return NULL;
338 aCI.SetBase(aRefShell);
340 //Compute the Solid value
342 if (!GetSolver()->ComputeFunction(aFunction)) {
343 SetErrorCode("Solid driver failed");
347 catch (Standard_Failure) {
348 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
349 SetErrorCode(aFail->GetMessageString());
353 //Make a Python command
354 GEOM::TPythonDump(aFunction) << aSolid
355 << " = geompy.MakeSolid(" << theShell << ")";
361 //=============================================================================
365 //=============================================================================
366 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeCompound
367 (list<Handle(GEOM_Object)> theShapes)
369 return MakeShape(theShapes, GEOM_COMPOUND, COMPOUND_SHAPES, "MakeCompound");
372 //=============================================================================
376 //=============================================================================
377 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeShape
378 (list<Handle(GEOM_Object)> theShapes,
379 const Standard_Integer theObjectType,
380 const Standard_Integer theFunctionType,
381 const TCollection_AsciiString theMethodName)
386 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), theObjectType);
389 Handle(GEOM_Function) aFunction =
390 aShape->AddFunction(GEOMImpl_ShapeDriver::GetID(), theFunctionType);
391 if (aFunction.IsNull()) return NULL;
393 //Check if the function is set correctly
394 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
396 GEOMImpl_IShapes aCI (aFunction);
398 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
401 list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
402 for (; it != theShapes.end(); it++) {
403 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
404 if (aRefSh.IsNull()) {
405 SetErrorCode("NULL argument shape for the shape construction");
408 aShapesSeq->Append(aRefSh);
410 aCI.SetShapes(aShapesSeq);
414 if (!GetSolver()->ComputeFunction(aFunction)) {
415 SetErrorCode("Shape driver failed");
419 catch (Standard_Failure) {
420 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
421 SetErrorCode(aFail->GetMessageString());
425 //Make a Python command
426 GEOM::TPythonDump pd (aFunction);
427 pd << aShape << " = geompy." << theMethodName.ToCString() << "([";
430 it = theShapes.begin();
431 if (it != theShapes.end()) {
433 while (it != theShapes.end()) {
434 pd << ", " << (*it++);
443 //=============================================================================
447 //=============================================================================
448 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeGlueFaces
449 (Handle(GEOM_Object) theShape,
450 const Standard_Real theTolerance)
454 if (theShape.IsNull()) return NULL;
456 //Add a new Glued object
457 Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
459 //Add a new Glue function
460 Handle(GEOM_Function) aFunction;
461 aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_FACES);
462 if (aFunction.IsNull()) return NULL;
464 //Check if the function is set correctly
465 if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
467 GEOMImpl_IGlue aCI (aFunction);
469 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
470 if (aRefShape.IsNull()) return NULL;
472 aCI.SetBase(aRefShape);
473 aCI.SetTolerance(theTolerance);
475 //Compute the sub-shape value
476 Standard_Boolean isWarning = Standard_False;
478 if (!GetSolver()->ComputeFunction(aFunction)) {
479 SetErrorCode("Shape driver failed to glue faces");
483 catch (Standard_Failure) {
484 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
485 SetErrorCode(aFail->GetMessageString());
486 // to provide warning
487 if (!aFunction->GetValue().IsNull()) {
488 isWarning = Standard_True;
494 //Make a Python command
495 GEOM::TPythonDump(aFunction) << aGlued << " = geompy.MakeGlueFaces("
496 << theShape << ", " << theTolerance << ")";
498 // to provide warning
499 if (!isWarning) SetErrorCode(OK);
503 //=============================================================================
507 //=============================================================================
508 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::MakeExplode
509 (Handle(GEOM_Object) theShape,
510 const Standard_Integer theShapeType,
511 const Standard_Boolean isSorted)
513 // OSD_Timer timer1, timer2, timer3, timer4;
518 if (theShape.IsNull()) return NULL;
519 TopoDS_Shape aShape = theShape->GetValue();
520 if (aShape.IsNull()) return NULL;
522 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
523 Handle(GEOM_Object) anObj;
524 Handle(GEOM_Function) aFunction;
525 TopTools_MapOfShape mapShape;
526 TopTools_ListOfShape listShape;
528 if (aShape.ShapeType() == TopAbs_COMPOUND &&
529 (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
530 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPSOLID ||
531 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPOUND)) {
532 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
533 for (; It.More(); It.Next()) {
534 if (mapShape.Add(It.Value())) {
535 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
536 TopAbs_ShapeEnum(theShapeType) == It.Value().ShapeType()) {
537 listShape.Append(It.Value());
542 TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
543 for (; exp.More(); exp.Next())
544 if (mapShape.Add(exp.Current()))
545 listShape.Append(exp.Current());
548 if (listShape.IsEmpty()) {
549 SetErrorCode("The given shape has no sub-shapes of the requested type");
557 SortShapes(listShape);
562 TopTools_IndexedMapOfShape anIndices;
563 TopExp::MapShapes(aShape, anIndices);
564 Handle(TColStd_HArray1OfInteger) anArray;
566 TopTools_ListIteratorOfListOfShape itSub (listShape);
567 TCollection_AsciiString anAsciiList, anEntry;
568 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
569 TopoDS_Shape aValue = itSub.Value();
570 anArray = new TColStd_HArray1OfInteger(1,1);
571 anArray->SetValue(1, anIndices.FindIndex(aValue));
572 anObj = GetEngine()->AddSubShape(theShape, anArray);
575 // for python command
576 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
577 anAsciiList += anEntry;
581 //Make a Python command
582 anAsciiList.Trunc(anAsciiList.Length() - 1);
584 aFunction = theShape->GetLastFunction();
585 TCollection_AsciiString anOldDescr = aFunction->GetDescription();
587 GEOM::TPythonDump pd (aFunction);
588 pd << anOldDescr.ToCString() << "\n\t[" << anAsciiList.ToCString();
589 pd << "] = geompy.SubShapeAll" << (isSorted ? "Sorted(" : "(");
590 pd << theShape << ", " << theShapeType << ")";
596 // cout << "Explosure takes:" << endl;
598 // cout << "Sorting takes:" << endl;
600 // cout << "Sub-shapes addition takes:" << endl;
602 // cout << "Update Description takes:" << endl;
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();
667 TCollection_AsciiString anOldDescr = aFunction->GetDescription();
669 //Make a Python command
670 GEOM::TPythonDump pd (aFunction);
671 pd << anOldDescr.ToCString() << "\n\tlistSubShapeIDs = geompy.SubShapeAll";
672 pd << (isSorted ? "SortedIDs(" : "IDs(");
673 pd << theShape << ", " << theShapeType << ")";
679 //=============================================================================
683 //=============================================================================
684 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetSubShape
685 (Handle(GEOM_Object) theMainShape,
686 const Standard_Integer theID)
690 if (theMainShape.IsNull()) return NULL;
692 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
693 anArray->SetValue(1, theID);
694 Handle(GEOM_Object) anObj = GetEngine()->AddSubShape(theMainShape, anArray,true);
695 if (anObj.IsNull()) {
696 SetErrorCode("Can not get a sub-shape with the given ID");
700 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
702 //Make a Python command
703 GEOM::TPythonDump(aFunction) << anObj << " = geompy.GetSubShape("
704 << theMainShape << ", [" << theID << "])";
711 //=============================================================================
715 //=============================================================================
716 Standard_Integer GEOMImpl_IShapesOperations::NumberOfFaces (Handle(GEOM_Object) theShape)
720 Standard_Integer nb = 0;
722 if (theShape.IsNull()) return -1;
723 TopoDS_Shape aShape = theShape->GetValue();
724 if (aShape.IsNull()) return -1;
726 TopTools_MapOfShape mapShape;
728 TopExp_Explorer exp (aShape, TopAbs_FACE);
729 for (; exp.More(); exp.Next())
730 if (mapShape.Add(exp.Current()))
737 //=============================================================================
741 //=============================================================================
742 Standard_Integer GEOMImpl_IShapesOperations::NumberOfEdges (Handle(GEOM_Object) theShape)
746 Standard_Integer nb = 0;
748 if (theShape.IsNull()) return -1;
749 TopoDS_Shape aShape = theShape->GetValue();
750 if (aShape.IsNull()) return -1;
752 TopTools_MapOfShape mapShape;
754 TopExp_Explorer exp (aShape, TopAbs_EDGE);
755 for (; exp.More(); exp.Next())
756 if (mapShape.Add(exp.Current()))
763 //=============================================================================
767 //=============================================================================
768 Handle(GEOM_Object) GEOMImpl_IShapesOperations::ReverseShape(Handle(GEOM_Object) theShape)
772 if (theShape.IsNull()) return NULL;
774 //Add a new reversed object
775 Handle(GEOM_Object) aReversed = GetEngine()->AddObject(GetDocID(), theShape->GetType());
777 //Add a new Revese function
778 Handle(GEOM_Function) aFunction;
779 aFunction = aReversed->AddFunction(GEOMImpl_ShapeDriver::GetID(), REVERSE_ORIENTATION);
780 if (aFunction.IsNull()) return NULL;
782 //Check if the function is set correctly
783 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
785 GEOMImpl_IShapes aSI (aFunction);
787 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
788 if (aRefShape.IsNull()) return NULL;
790 aSI.SetBase(aRefShape);
792 //Compute the sub-shape value
794 if (!GetSolver()->ComputeFunction(aFunction)) {
795 SetErrorCode("Shape driver failed to reverse shape");
799 catch (Standard_Failure) {
800 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
801 SetErrorCode(aFail->GetMessageString());
805 //Make a Python command
806 GEOM::TPythonDump(aFunction) << aReversed
807 << " = geompy.ChangeOrientation(" << theShape << ")";
813 //=============================================================================
817 //=============================================================================
818 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetFreeFacesIDs
819 (Handle(GEOM_Object) theShape)
823 if (theShape.IsNull()) return NULL;
824 TopoDS_Shape aShape = theShape->GetValue();
825 if (aShape.IsNull()) return NULL;
827 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
829 TopTools_IndexedDataMapOfShapeListOfShape mapFaceBlocks;
830 GEOMImpl_Block6Explorer::MapShapesAndAncestors
831 (aShape, TopAbs_FACE, TopAbs_SOLID, mapFaceBlocks);
833 Standard_Integer ind = 1, nbFaces = mapFaceBlocks.Extent();
836 SetErrorCode("The given shape has no faces");
840 TopTools_IndexedMapOfShape anIndices;
841 TopExp::MapShapes(aShape, anIndices);
844 for (; ind <= nbFaces; ind++) {
845 if (mapFaceBlocks.FindFromIndex(ind).Extent() != 2) {
846 id = anIndices.FindIndex(mapFaceBlocks.FindKey(ind));
851 //The explode doesn't change object so no new function is required.
852 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
853 TCollection_AsciiString anOldDescr = aFunction->GetDescription();
855 //Make a Python command
856 GEOM::TPythonDump(aFunction) << anOldDescr.ToCString()
857 << "\n\tlistFreeFacesIDs = geompy.GetFreeFacesIDs(" << theShape << ")";
863 //=============================================================================
867 //=============================================================================
868 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetSharedShapes
869 (Handle(GEOM_Object) theShape1,
870 Handle(GEOM_Object) theShape2,
871 const Standard_Integer theShapeType)
875 if (theShape1.IsNull() || theShape2.IsNull()) return NULL;
877 TopoDS_Shape aShape1 = theShape1->GetValue();
878 TopoDS_Shape aShape2 = theShape2->GetValue();
880 if (aShape1.IsNull() || aShape2.IsNull()) return NULL;
882 TopTools_IndexedMapOfShape anIndices;
883 TopExp::MapShapes(aShape1, anIndices);
884 Handle(TColStd_HArray1OfInteger) anArray;
886 TopTools_IndexedMapOfShape mapShape1;
887 TopExp::MapShapes(aShape1, TopAbs_ShapeEnum(theShapeType), mapShape1);
889 Handle(GEOM_Object) anObj;
890 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
891 TCollection_AsciiString anAsciiList, anEntry;
893 TopTools_MapOfShape mapShape2;
894 TopExp_Explorer exp (aShape2, TopAbs_ShapeEnum(theShapeType));
895 for (; exp.More(); exp.Next()) {
896 TopoDS_Shape aSS = exp.Current();
897 if (mapShape2.Add(aSS) && mapShape1.Contains(aSS)) {
898 anArray = new TColStd_HArray1OfInteger(1,1);
899 anArray->SetValue(1, anIndices.FindIndex(aSS));
900 anObj = GetEngine()->AddSubShape(theShape1, anArray);
903 // for python command
904 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
905 anAsciiList += anEntry;
910 if (aSeq->IsEmpty()) {
911 SetErrorCode("The given shapes have no shared sub-shapes of the requested type");
915 //Make a Python command
916 anAsciiList.Trunc(anAsciiList.Length() - 1);
918 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
920 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
921 << "] = geompy.GetSharedShapes(" << theShape1 << ", "
922 << theShape2 << ", " << theShapeType << ")";
928 //=============================================================================
932 //=============================================================================
933 static GEOM::TPythonDump& operator<< (GEOM::TPythonDump& theDump,
934 const GEOMAlgo_State theState)
938 theDump << "geompy.GEOM.ST_IN";
940 case GEOMAlgo_ST_OUT:
941 theDump << "geompy.GEOM.ST_OUT";
944 theDump << "geompy.GEOM.ST_ON";
946 case GEOMAlgo_ST_ONIN:
947 theDump << "geompy.GEOM.ST_ONIN";
949 case GEOMAlgo_ST_ONOUT:
950 theDump << "geompy.GEOM.ST_ONOUT";
953 theDump << "geompy.GEOM.ST_UNKNOWN";
959 //=============================================================================
963 //=============================================================================
964 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnPlane
965 (const Handle(GEOM_Object)& theShape,
966 const Standard_Integer theShapeType,
967 const Handle(GEOM_Object)& theAx1,
968 const GEOMAlgo_State theState)
972 // MESSAGE("--------------------------- GetShapesOnPlane phase 1 takes:");
976 if (theShape.IsNull() || theAx1.IsNull()) return NULL;
978 TopoDS_Shape aShape = theShape->GetValue();
979 TopoDS_Shape anAx1 = theAx1->GetValue();
981 if (aShape.IsNull() || anAx1.IsNull()) return NULL;
983 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
984 if (aShapeType != TopAbs_VERTEX &&
985 aShapeType != TopAbs_EDGE &&
986 aShapeType != TopAbs_FACE &&
987 aShapeType != TopAbs_SOLID) {
988 SetErrorCode("Only solids, vertices, edges or faces can be found by this method");
993 if (anAx1.ShapeType() != TopAbs_EDGE) return NULL;
994 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
995 TopoDS_Vertex V1, V2;
996 TopExp::Vertices(anEdge, V1, V2, Standard_True);
997 if (V1.IsNull() || V2.IsNull()) {
998 SetErrorCode("Bad edge given for the plane normal vector");
1001 gp_Pnt aLoc = BRep_Tool::Pnt(V1);
1002 gp_Vec aVec (aLoc, BRep_Tool::Pnt(V2));
1003 if (aVec.Magnitude() < Precision::Confusion()) {
1004 SetErrorCode("Vector with null magnitude given");
1008 Handle(Geom_Plane) aPlane = new Geom_Plane(aLoc, aVec);
1010 // Check presence of triangulation, build if need
1011 if (!CheckTriangulation(aShape))
1015 GEOMAlgo_FinderShapeOn1 aFinder;
1016 Standard_Real aTol = 0.0001; // default value
1018 aFinder.SetShape(aShape);
1019 aFinder.SetTolerance(aTol);
1020 aFinder.SetSurface(aPlane);
1021 aFinder.SetShapeType(aShapeType);
1022 aFinder.SetState(theState);
1024 // Sets the minimal number of inner points for the faces that do not have own
1025 // inner points at all (for e.g. rectangular planar faces have just 2 triangles).
1027 aFinder.SetNbPntsMin(3);
1028 // Sets the maximal number of inner points for edges or faces.
1029 // It is usefull for the cases when this number is very big (e.g =2000) to improve
1030 // the performance. If this value =0, all inner points will be taken into account.
1032 aFinder.SetNbPntsMax(100);
1037 // MESSAGE("--------------------------- Perform on Plane takes:");
1044 // MESSAGE("--------------------------- GetShapesOnPlane phase 3 takes:");
1048 // Interprete results
1049 Standard_Integer iErr = aFinder.ErrorStatus();
1050 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
1052 MESSAGE(" iErr : " << iErr);
1053 TCollection_AsciiString aMsg (" iErr : ");
1054 aMsg += TCollection_AsciiString(iErr);
1058 Standard_Integer iWrn = aFinder.WarningStatus();
1059 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
1061 MESSAGE(" *** iWrn : " << iWrn);
1064 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
1066 if (listSS.Extent() < 1) {
1067 SetErrorCode("Not a single sub-shape of the requested type found on the given plane");
1074 // MESSAGE("--------------------------- GetShapesOnPlane phase 4 takes:");
1078 // Fill sequence of objects
1079 TopTools_IndexedMapOfShape anIndices;
1080 TopExp::MapShapes(aShape, anIndices);
1082 Handle(GEOM_Object) anObj;
1083 Handle(TColStd_HArray1OfInteger) anArray;
1084 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1085 TCollection_AsciiString anAsciiList, anEntry;
1087 TopTools_ListIteratorOfListOfShape itSub (listSS);
1088 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
1089 int id = anIndices.FindIndex(itSub.Value());
1090 anArray = new TColStd_HArray1OfInteger(1,1);
1091 anArray->SetValue(1, id);
1092 anObj = GetEngine()->AddSubShape(theShape, anArray);
1093 aSeq->Append(anObj);
1095 // for python command
1096 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
1097 anAsciiList += anEntry;
1104 // MESSAGE("--------------------------- GetShapesOnPlane phase 5 takes:");
1108 // Make a Python command
1109 anAsciiList.Trunc(anAsciiList.Length() - 1);
1111 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1113 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
1114 << "] = geompy.GetShapesOnPlane(" << theShape << ", "
1115 << theShapeType << ", " << theAx1 << ", " << theState << ")";
1121 //=============================================================================
1123 * GetShapesOnCylinder
1125 //=============================================================================
1126 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnCylinder
1127 (const Handle(GEOM_Object)& theShape,
1128 const Standard_Integer theShapeType,
1129 const Handle(GEOM_Object)& theAxis,
1130 const Standard_Real theRadius,
1131 const GEOMAlgo_State theState)
1135 if (theShape.IsNull() || theAxis.IsNull()) return NULL;
1137 TopoDS_Shape aShape = theShape->GetValue();
1138 TopoDS_Shape anAxis = theAxis->GetValue();
1140 if (aShape.IsNull() || anAxis.IsNull()) return NULL;
1142 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
1143 if (aShapeType != TopAbs_VERTEX &&
1144 aShapeType != TopAbs_EDGE &&
1145 aShapeType != TopAbs_FACE &&
1146 aShapeType != TopAbs_SOLID) {
1147 SetErrorCode("Only solids, vertices, edges or faces can be found by this method");
1151 //Axis of the cylinder
1152 if (anAxis.ShapeType() != TopAbs_EDGE) {
1153 SetErrorCode("Not an edge given for the axis");
1156 TopoDS_Edge anEdge = TopoDS::Edge(anAxis);
1157 TopoDS_Vertex V1, V2;
1158 TopExp::Vertices(anEdge, V1, V2, Standard_True);
1159 if (V1.IsNull() || V2.IsNull()) {
1160 SetErrorCode("Bad edge given for the axis");
1163 gp_Pnt aLoc = BRep_Tool::Pnt(V1);
1164 gp_Vec aVec (aLoc, BRep_Tool::Pnt(V2));
1165 if (aVec.Magnitude() < Precision::Confusion()) {
1166 SetErrorCode("Vector with null magnitude given");
1170 gp_Ax3 anAx3 (aLoc, aVec);
1171 Handle(Geom_CylindricalSurface) aCylinder =
1172 new Geom_CylindricalSurface(anAx3, theRadius);
1174 // Check presence of triangulation, build if need
1175 if (!CheckTriangulation(aShape))
1179 GEOMAlgo_FinderShapeOn1 aFinder;
1180 Standard_Real aTol = 0.0001; // default value
1182 aFinder.SetShape(aShape);
1183 aFinder.SetTolerance(aTol);
1184 aFinder.SetSurface(aCylinder);
1185 aFinder.SetShapeType(aShapeType);
1186 aFinder.SetState(theState);
1188 aFinder.SetNbPntsMin(3);
1189 aFinder.SetNbPntsMax(100);
1193 // Interprete results
1194 Standard_Integer iErr = aFinder.ErrorStatus();
1195 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
1197 MESSAGE(" iErr : " << iErr);
1198 TCollection_AsciiString aMsg (" iErr : ");
1199 aMsg += TCollection_AsciiString(iErr);
1203 Standard_Integer iWrn = aFinder.WarningStatus();
1204 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
1206 MESSAGE(" *** iWrn : " << iWrn);
1209 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
1211 if (listSS.Extent() < 1) {
1212 SetErrorCode("Not a single sub-shape of the requested type found on the given cylinder");
1216 // Fill sequence of objects
1217 TopTools_IndexedMapOfShape anIndices;
1218 TopExp::MapShapes(aShape, anIndices);
1220 Handle(GEOM_Object) anObj;
1221 Handle(TColStd_HArray1OfInteger) anArray;
1222 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1223 TCollection_AsciiString anAsciiList, anEntry;
1225 TopTools_ListIteratorOfListOfShape itSub (listSS);
1226 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
1227 int id = anIndices.FindIndex(itSub.Value());
1228 anArray = new TColStd_HArray1OfInteger(1,1);
1229 anArray->SetValue(1, id);
1230 anObj = GetEngine()->AddSubShape(theShape, anArray);
1231 aSeq->Append(anObj);
1233 // for python command
1234 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
1235 anAsciiList += anEntry;
1239 // Make a Python command
1240 anAsciiList.Trunc(anAsciiList.Length() - 1);
1242 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1244 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
1245 << "] = geompy.GetShapesOnCylinder(" << theShape << ", " << theShapeType
1246 << ", " << theAxis << ", " << theRadius << ", " << theState << ")";
1252 //=============================================================================
1256 //=============================================================================
1257 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnSphere
1258 (const Handle(GEOM_Object)& theShape,
1259 const Standard_Integer theShapeType,
1260 const Handle(GEOM_Object)& theCenter,
1261 const Standard_Real theRadius,
1262 const GEOMAlgo_State theState)
1266 if (theShape.IsNull() || theCenter.IsNull()) return NULL;
1268 TopoDS_Shape aShape = theShape->GetValue();
1269 TopoDS_Shape aCenter = theCenter->GetValue();
1271 if (aShape.IsNull() || aCenter.IsNull()) return NULL;
1273 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
1274 if (aShapeType != TopAbs_VERTEX &&
1275 aShapeType != TopAbs_EDGE &&
1276 aShapeType != TopAbs_FACE &&
1277 aShapeType != TopAbs_SOLID) {
1278 SetErrorCode("Only solids, vertices, edges or faces can be found by this method");
1282 // Center of the sphere
1283 if (aCenter.ShapeType() != TopAbs_VERTEX) return NULL;
1284 gp_Pnt aLoc = BRep_Tool::Pnt(TopoDS::Vertex(aCenter));
1286 gp_Ax3 anAx3 (aLoc, gp::DZ());
1287 Handle(Geom_SphericalSurface) aSphere =
1288 new Geom_SphericalSurface(anAx3, theRadius);
1290 // Check presence of triangulation, build if need
1291 if (!CheckTriangulation(aShape))
1295 GEOMAlgo_FinderShapeOn1 aFinder;
1296 Standard_Real aTol = 0.0001; // default value
1298 aFinder.SetShape(aShape);
1299 aFinder.SetTolerance(aTol);
1300 aFinder.SetSurface(aSphere);
1301 aFinder.SetShapeType(aShapeType);
1302 aFinder.SetState(theState);
1304 aFinder.SetNbPntsMin(3);
1305 aFinder.SetNbPntsMax(100);
1309 // Interprete results
1310 Standard_Integer iErr = aFinder.ErrorStatus();
1311 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
1313 MESSAGE(" iErr : " << iErr);
1314 TCollection_AsciiString aMsg (" iErr : ");
1315 aMsg += TCollection_AsciiString(iErr);
1319 Standard_Integer iWrn = aFinder.WarningStatus();
1320 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
1322 MESSAGE(" *** iWrn : " << iWrn);
1325 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
1327 if (listSS.Extent() < 1) {
1328 SetErrorCode("Not a single sub-shape of the requested type found on the given sphere");
1332 // Fill sequence of objects
1333 TopTools_IndexedMapOfShape anIndices;
1334 TopExp::MapShapes(aShape, anIndices);
1336 Handle(GEOM_Object) anObj;
1337 Handle(TColStd_HArray1OfInteger) anArray;
1338 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1339 TCollection_AsciiString anAsciiList, anEntry;
1341 TopTools_ListIteratorOfListOfShape itSub (listSS);
1342 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
1343 int id = anIndices.FindIndex(itSub.Value());
1344 anArray = new TColStd_HArray1OfInteger(1,1);
1345 anArray->SetValue(1, id);
1346 anObj = GetEngine()->AddSubShape(theShape, anArray);
1347 aSeq->Append(anObj);
1349 // for python command
1350 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
1351 anAsciiList += anEntry;
1355 // Make a Python command
1356 anAsciiList.Trunc(anAsciiList.Length() - 1);
1358 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1360 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
1361 << "] = geompy.GetShapesOnSphere(" << theShape << ", " << theShapeType
1362 << ", " << theCenter << ", " << theRadius << ", " << theState << ")";
1367 //=============================================================================
1369 * GetShapesOnPlaneIDs
1371 //=============================================================================
1372 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnPlaneIDs
1373 (const Handle(GEOM_Object)& theShape,
1374 const Standard_Integer theShapeType,
1375 const Handle(GEOM_Object)& theAx1,
1376 const GEOMAlgo_State theState)
1380 if (theShape.IsNull() || theAx1.IsNull()) return NULL;
1382 TopoDS_Shape aShape = theShape->GetValue();
1383 TopoDS_Shape anAx1 = theAx1->GetValue();
1385 if (aShape.IsNull() || anAx1.IsNull()) return NULL;
1387 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
1388 if (aShapeType != TopAbs_VERTEX &&
1389 aShapeType != TopAbs_EDGE &&
1390 aShapeType != TopAbs_FACE &&
1391 aShapeType != TopAbs_SOLID) {
1392 SetErrorCode("Only solids, vertices, edges or faces can be found by this method");
1397 if (anAx1.ShapeType() != TopAbs_EDGE) return NULL;
1398 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
1399 TopoDS_Vertex V1, V2;
1400 TopExp::Vertices(anEdge, V1, V2, Standard_True);
1401 if (V1.IsNull() || V2.IsNull()) {
1402 SetErrorCode("Bad edge given for the plane normal vector");
1405 gp_Pnt aLoc = BRep_Tool::Pnt(V1);
1406 gp_Vec aVec (aLoc, BRep_Tool::Pnt(V2));
1407 if (aVec.Magnitude() < Precision::Confusion()) {
1408 SetErrorCode("Vector with null magnitude given");
1412 Handle(Geom_Plane) aPlane = new Geom_Plane(aLoc, aVec);
1414 // Check presence of triangulation, build if need
1415 if (!CheckTriangulation(aShape))
1419 GEOMAlgo_FinderShapeOn1 aFinder;
1420 Standard_Real aTol = 0.0001; // default value
1422 aFinder.SetShape(aShape);
1423 aFinder.SetTolerance(aTol);
1424 aFinder.SetSurface(aPlane);
1425 aFinder.SetShapeType(aShapeType);
1426 aFinder.SetState(theState);
1428 aFinder.SetNbPntsMin(3);
1429 aFinder.SetNbPntsMax(100);
1433 // Interprete results
1434 Standard_Integer iErr = aFinder.ErrorStatus();
1435 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
1437 MESSAGE(" iErr : " << iErr);
1438 TCollection_AsciiString aMsg (" iErr : ");
1439 aMsg += TCollection_AsciiString(iErr);
1443 Standard_Integer iWrn = aFinder.WarningStatus();
1444 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
1446 MESSAGE(" *** iWrn : " << iWrn);
1449 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
1451 if (listSS.Extent() < 1) {
1452 SetErrorCode("Not a single sub-shape of the requested type found on the given plane");
1456 // Fill sequence of objects
1457 TopTools_IndexedMapOfShape anIndices;
1458 TopExp::MapShapes(aShape, anIndices);
1460 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
1462 TopTools_ListIteratorOfListOfShape itSub (listSS);
1463 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
1464 int id = anIndices.FindIndex(itSub.Value());
1468 // The GetShapesOnPlane() doesn't change object so no new function is required.
1469 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
1471 // Make a Python command
1472 TCollection_AsciiString anEntry, aDescr
1473 ("\nlistShapesOnPlane = IShapesOperations.GetShapesOnPlaneIDs(");
1474 TDF_Tool::Entry(theShape->GetEntry(), anEntry);
1475 aDescr += anEntry + TCollection_AsciiString(theShapeType) + ",";
1476 TDF_Tool::Entry(theAx1->GetEntry(), anEntry);
1477 aDescr += anEntry + ",";
1478 aDescr += TCollection_AsciiString(theState) + ")";
1480 TCollection_AsciiString anOldDescr = aFunction->GetDescription();
1481 anOldDescr += aDescr;
1482 aFunction->SetDescription(anOldDescr);
1488 //=============================================================================
1490 * GetShapesOnCylinderIDs
1492 //=============================================================================
1493 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnCylinderIDs
1494 (const Handle(GEOM_Object)& theShape,
1495 const Standard_Integer theShapeType,
1496 const Handle(GEOM_Object)& theAxis,
1497 const Standard_Real theRadius,
1498 const GEOMAlgo_State theState)
1502 if (theShape.IsNull() || theAxis.IsNull()) return NULL;
1504 TopoDS_Shape aShape = theShape->GetValue();
1505 TopoDS_Shape anAxis = theAxis->GetValue();
1507 if (aShape.IsNull() || anAxis.IsNull()) return NULL;
1509 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
1510 if (aShapeType != TopAbs_VERTEX &&
1511 aShapeType != TopAbs_EDGE &&
1512 aShapeType != TopAbs_FACE &&
1513 aShapeType != TopAbs_SOLID) {
1514 SetErrorCode("Only solids, vertices, edges or faces can be found by this method");
1518 //Axis of the cylinder
1519 if (anAxis.ShapeType() != TopAbs_EDGE) {
1520 SetErrorCode("Not an edge given for the axis");
1523 TopoDS_Edge anEdge = TopoDS::Edge(anAxis);
1524 TopoDS_Vertex V1, V2;
1525 TopExp::Vertices(anEdge, V1, V2, Standard_True);
1526 if (V1.IsNull() || V2.IsNull()) {
1527 SetErrorCode("Bad edge given for the axis");
1530 gp_Pnt aLoc = BRep_Tool::Pnt(V1);
1531 gp_Vec aVec (aLoc, BRep_Tool::Pnt(V2));
1532 if (aVec.Magnitude() < Precision::Confusion()) {
1533 SetErrorCode("Vector with null magnitude given");
1537 gp_Ax3 anAx3 (aLoc, aVec);
1538 Handle(Geom_CylindricalSurface) aCylinder =
1539 new Geom_CylindricalSurface(anAx3, theRadius);
1541 // Check presence of triangulation, build if need
1542 if (!CheckTriangulation(aShape))
1546 GEOMAlgo_FinderShapeOn1 aFinder;
1547 Standard_Real aTol = 0.0001; // default value
1549 aFinder.SetShape(aShape);
1550 aFinder.SetTolerance(aTol);
1551 aFinder.SetSurface(aCylinder);
1552 aFinder.SetShapeType(aShapeType);
1553 aFinder.SetState(theState);
1555 aFinder.SetNbPntsMin(3);
1556 aFinder.SetNbPntsMax(100);
1560 // Interprete results
1561 Standard_Integer iErr = aFinder.ErrorStatus();
1562 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
1564 MESSAGE(" iErr : " << iErr);
1565 TCollection_AsciiString aMsg (" iErr : ");
1566 aMsg += TCollection_AsciiString(iErr);
1570 Standard_Integer iWrn = aFinder.WarningStatus();
1571 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
1573 MESSAGE(" *** iWrn : " << iWrn);
1576 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
1578 if (listSS.Extent() < 1) {
1579 SetErrorCode("Not a single sub-shape of the requested type found on the given cylinder");
1583 // Fill sequence of objects
1584 TopTools_IndexedMapOfShape anIndices;
1585 TopExp::MapShapes(aShape, anIndices);
1587 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
1589 TopTools_ListIteratorOfListOfShape itSub (listSS);
1590 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
1591 int id = anIndices.FindIndex(itSub.Value());
1595 // The GetShapesOnCylinder() doesn't change object so no new function is required.
1596 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
1598 // Make a Python command
1599 TCollection_AsciiString anEntry, aDescr
1600 ("\nlistShapesOnCylinder = IShapesOperations.GetShapesOnCylinderIDs(");
1601 TDF_Tool::Entry(theShape->GetEntry(), anEntry);
1602 aDescr += anEntry + TCollection_AsciiString(theShapeType) + ",";
1603 TDF_Tool::Entry(theAxis->GetEntry(), anEntry);
1604 aDescr += anEntry + ",";
1605 aDescr += TCollection_AsciiString(theRadius) + ",";
1606 aDescr += TCollection_AsciiString(theState) + ")";
1608 TCollection_AsciiString anOldDescr = aFunction->GetDescription();
1609 anOldDescr += aDescr;
1610 aFunction->SetDescription(anOldDescr);
1616 //=============================================================================
1618 * GetShapesOnSphereIDs
1620 //=============================================================================
1621 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnSphereIDs
1622 (const Handle(GEOM_Object)& theShape,
1623 const Standard_Integer theShapeType,
1624 const Handle(GEOM_Object)& theCenter,
1625 const Standard_Real theRadius,
1626 const GEOMAlgo_State theState)
1630 if (theShape.IsNull() || theCenter.IsNull()) return NULL;
1632 TopoDS_Shape aShape = theShape->GetValue();
1633 TopoDS_Shape aCenter = theCenter->GetValue();
1635 if (aShape.IsNull() || aCenter.IsNull()) return NULL;
1637 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
1638 if (aShapeType != TopAbs_VERTEX &&
1639 aShapeType != TopAbs_EDGE &&
1640 aShapeType != TopAbs_FACE &&
1641 aShapeType != TopAbs_SOLID) {
1642 SetErrorCode("Only solids, vertices, edges or faces can be found by this method");
1646 // Center of the sphere
1647 if (aCenter.ShapeType() != TopAbs_VERTEX) return NULL;
1648 gp_Pnt aLoc = BRep_Tool::Pnt(TopoDS::Vertex(aCenter));
1650 gp_Ax3 anAx3 (aLoc, gp::DZ());
1651 Handle(Geom_SphericalSurface) aSphere =
1652 new Geom_SphericalSurface(anAx3, theRadius);
1654 // Check presence of triangulation, build if need
1655 if (!CheckTriangulation(aShape))
1659 GEOMAlgo_FinderShapeOn1 aFinder;
1660 Standard_Real aTol = 0.0001; // default value
1662 aFinder.SetShape(aShape);
1663 aFinder.SetTolerance(aTol);
1664 aFinder.SetSurface(aSphere);
1665 aFinder.SetShapeType(aShapeType);
1666 aFinder.SetState(theState);
1668 aFinder.SetNbPntsMin(3);
1669 aFinder.SetNbPntsMax(100);
1673 // Interprete results
1674 Standard_Integer iErr = aFinder.ErrorStatus();
1675 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
1677 MESSAGE(" iErr : " << iErr);
1678 TCollection_AsciiString aMsg (" iErr : ");
1679 aMsg += TCollection_AsciiString(iErr);
1683 Standard_Integer iWrn = aFinder.WarningStatus();
1684 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
1686 MESSAGE(" *** iWrn : " << iWrn);
1689 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
1691 if (listSS.Extent() < 1) {
1692 SetErrorCode("Not a single sub-shape of the requested type found on the given sphere");
1696 // Fill sequence of objects
1697 TopTools_IndexedMapOfShape anIndices;
1698 TopExp::MapShapes(aShape, anIndices);
1700 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
1702 TopTools_ListIteratorOfListOfShape itSub (listSS);
1703 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
1704 int id = anIndices.FindIndex(itSub.Value());
1708 // The GetShapesOnSphere() doesn't change object so no new function is required.
1709 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
1711 // Make a Python command
1712 TCollection_AsciiString anEntry, aDescr
1713 ("\nlistShapesOnSphere = IShapesOperations.GetShapesOnSphereIDs(");
1714 TDF_Tool::Entry(theShape->GetEntry(), anEntry);
1715 aDescr += anEntry + TCollection_AsciiString(theShapeType) + ",";
1716 TDF_Tool::Entry(theCenter->GetEntry(), anEntry);
1717 aDescr += anEntry + ",";
1718 aDescr += TCollection_AsciiString(theRadius) + ",";
1719 aDescr += TCollection_AsciiString(theState) + ")";
1721 TCollection_AsciiString anOldDescr = aFunction->GetDescription();
1722 anOldDescr += aDescr;
1723 aFunction->SetDescription(anOldDescr);
1729 //=============================================================================
1733 //=============================================================================
1734 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlace
1735 (Handle(GEOM_Object) theShapeWhere,
1736 Handle(GEOM_Object) theShapeWhat)
1740 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
1742 TopoDS_Shape aWhere = theShapeWhere->GetValue();
1743 TopoDS_Shape aWhat = theShapeWhat->GetValue();
1745 if (aWhere.IsNull() || aWhat.IsNull()) return NULL;
1747 //Fill array of indices
1748 Handle(TColStd_HArray1OfInteger) aModifiedArray;
1750 Handle(GEOM_Function) aWhereFunction = theShapeWhere->GetLastFunction();
1752 TopTools_IndexedMapOfShape aWhereIndices;
1753 TopExp::MapShapes(aWhere, aWhereIndices);
1755 if (aWhereIndices.Contains(aWhat)) {
1757 // entity was not changed by the operation
1758 Standard_Integer aWhatIndex = aWhereIndices.FindIndex(aWhat);
1759 aModifiedArray = new TColStd_HArray1OfInteger(1,1);
1760 aModifiedArray->SetValue(1, aWhatIndex);
1764 TDF_Label aHistoryLabel = aWhereFunction->GetHistoryEntry(Standard_False);
1765 if (aHistoryLabel.IsNull()) {
1766 SetErrorCode("Modifications history does not exist for the shape under consideration.");
1770 // search in history for all argument shapes
1771 Standard_Boolean isFound = Standard_False;
1773 TDF_LabelSequence aLabelSeq;
1774 aWhereFunction->GetDependency(aLabelSeq);
1775 Standard_Integer nbArg = aLabelSeq.Length();
1777 for (Standard_Integer iarg = 1; iarg <= nbArg && !isFound; iarg++) {
1779 TDF_Label anArgumentRefLabel = aLabelSeq.Value(iarg);
1781 Handle(GEOM_Object) anArgumentObject = GEOM_Object::GetReferencedObject(anArgumentRefLabel);
1782 TopoDS_Shape anArgumentShape = anArgumentObject->GetValue();
1784 TopTools_IndexedMapOfShape anArgumentIndices;
1785 TopExp::MapShapes(anArgumentShape, anArgumentIndices);
1787 if (anArgumentIndices.Contains(aWhat)) {
1788 isFound = Standard_True;
1789 Standard_Integer aWhatIndex = anArgumentIndices.FindIndex(aWhat);
1791 // Find corresponding label in history
1792 TDF_Label anArgumentHistoryLabel =
1793 aWhereFunction->GetArgumentHistoryEntry(anArgumentRefLabel, Standard_False);
1794 if (anArgumentHistoryLabel.IsNull()) {
1795 // Lost History of operation argument. Possibly, all its entities was removed.
1800 TDF_Label aWhatHistoryLabel = anArgumentHistoryLabel.FindChild(aWhatIndex, Standard_False);
1801 if (aWhatHistoryLabel.IsNull()) {
1807 Handle(TDataStd_IntegerArray) anIntegerArray;
1808 if (!aWhatHistoryLabel.FindAttribute(TDataStd_IntegerArray::GetID(), anIntegerArray)) {
1809 SetErrorCode("Error: Empty modifications history for the sought shape.");
1813 aModifiedArray = anIntegerArray->Array();
1814 if (aModifiedArray->Length() == 0) {
1815 SetErrorCode("Error: Empty modifications history for the sought shape.");
1822 SetErrorCode("The sought shape does not belong to any operation argument.");
1828 Handle(GEOM_Object) aResult = GetEngine()->AddSubShape(theShapeWhere, aModifiedArray);
1830 if (aModifiedArray->Length() > 1) {
1832 aResult->SetType(GEOM_GROUP);
1834 //Set a sub shape type
1835 TDF_Label aFreeLabel = aResult->GetFreeLabel();
1836 TopAbs_ShapeEnum aShapeType = aWhat.ShapeType();
1837 TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aShapeType);
1840 //Make a Python command
1841 Handle(GEOM_Function) aFunction = aResult->GetFunction(1);
1843 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetInPlace("
1844 << theShapeWhere << ", " << theShapeWhat << ")";
1850 //=======================================================================
1851 //function : SortShapes
1853 //=======================================================================
1854 void GEOMImpl_IShapesOperations::SortShapes(TopTools_ListOfShape& SL)
1856 Standard_Integer MaxShapes = SL.Extent();
1857 TopTools_Array1OfShape aShapes (1,MaxShapes);
1858 TColStd_Array1OfInteger OrderInd(1,MaxShapes);
1859 TColStd_Array1OfReal MidXYZ (1,MaxShapes); //X,Y,Z;
1860 TColStd_Array1OfReal Length (1,MaxShapes); //X,Y,Z;
1862 // Computing of CentreOfMass
1863 Standard_Integer Index;
1866 TopTools_ListIteratorOfListOfShape it(SL);
1867 for (Index=1; it.More(); Index++)
1869 TopoDS_Shape S = it.Value();
1870 SL.Remove( it ); // == it.Next()
1872 OrderInd.SetValue (Index, Index);
1873 if (S.ShapeType() == TopAbs_VERTEX)
1875 GPoint = BRep_Tool::Pnt( TopoDS::Vertex( S ));
1876 Length.SetValue( Index, (Standard_Real) S.Orientation());
1880 BRepGProp::LinearProperties (S, GPr);
1881 GPoint = GPr.CentreOfMass();
1882 Length.SetValue( Index, GPr.Mass() );
1884 MidXYZ.SetValue(Index,
1885 GPoint.X()*999 + GPoint.Y()*99 + GPoint.Z()*0.9);
1888 Standard_Integer aTemp;
1889 Standard_Boolean exchange, Sort = Standard_True;
1892 Sort = Standard_False;
1893 for (Index=1; Index < MaxShapes; Index++)
1895 if (MidXYZ(OrderInd(Index)) > MidXYZ(OrderInd(Index+1)))
1896 exchange = Standard_True;
1897 else if (MidXYZ(OrderInd(Index)) == MidXYZ(OrderInd(Index+1)) &&
1898 Length(OrderInd(Index)) > Length(OrderInd(Index+1)) )
1899 exchange = Standard_True;
1901 exchange = Standard_False;
1904 aTemp = OrderInd(Index);
1905 OrderInd(Index) = OrderInd(Index+1);
1906 OrderInd(Index+1) = aTemp;
1907 Sort = Standard_True;
1911 for (Index=1; Index <= MaxShapes; Index++)
1912 SL.Append( aShapes( OrderInd(Index) ));
1915 //=======================================================================
1916 //function : CheckTriangulation
1918 //=======================================================================
1919 bool GEOMImpl_IShapesOperations::CheckTriangulation (const TopoDS_Shape& aShape)
1921 // MESSAGE("CheckTriangulation");
1923 // OSD_Timer timer1;
1926 TopExp_Explorer exp (aShape, TopAbs_FACE);
1928 SetErrorCode("Shape without faces given");
1932 TopLoc_Location aTopLoc;
1933 Handle(Poly_Triangulation) aTRF;
1934 aTRF = BRep_Tool::Triangulation(TopoDS::Face(exp.Current()), aTopLoc);
1935 if (aTRF.IsNull()) {
1936 // calculate deflection
1937 Standard_Real aDeviationCoefficient = 0.001;
1940 BRepBndLib::Add(aShape, B);
1941 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
1942 B.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
1944 Standard_Real dx = aXmax - aXmin, dy = aYmax - aYmin, dz = aZmax - aZmin;
1945 Standard_Real aDeflection = Max(Max(dx, dy), dz) * aDeviationCoefficient * 4;
1947 // MESSAGE("Deflection = " << aDeflection);
1949 Standard_Real aHLRAngle = 0.349066;
1951 BRepMesh_IncrementalMesh Inc (aShape, aDeflection, Standard_False, aHLRAngle);