1 #include <Standard_Stream.hxx>
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"
22 #include "GEOMAlgo_FinderShapeOnQuad.hxx"
24 #include "utilities.h"
26 #include "Utils_ExceptHandlers.hxx"
28 #include <TFunction_DriverTable.hxx>
29 #include <TFunction_Driver.hxx>
30 #include <TFunction_Logbook.hxx>
31 #include <TDataStd_Integer.hxx>
32 #include <TDataStd_IntegerArray.hxx>
33 #include <TDF_Tool.hxx>
35 #include <BRepExtrema_ExtCF.hxx>
37 #include <BRep_Tool.hxx>
38 #include <BRepGProp.hxx>
39 #include <BRepAdaptor_Curve.hxx>
40 #include <BRepBndLib.hxx>
41 #include <BRepBuilderAPI_MakeFace.hxx>
42 #include <BRepMesh_IncrementalMesh.hxx>
47 #include <TopoDS_Shape.hxx>
48 #include <TopoDS_Face.hxx>
49 #include <TopoDS_Edge.hxx>
50 #include <TopoDS_Vertex.hxx>
51 #include <TopoDS_Iterator.hxx>
52 #include <TopExp_Explorer.hxx>
53 #include <TopLoc_Location.hxx>
54 #include <TopTools_MapOfShape.hxx>
55 #include <TopTools_Array1OfShape.hxx>
56 #include <TopTools_ListIteratorOfListOfShape.hxx>
57 #include <TopTools_IndexedMapOfShape.hxx>
59 #include <Geom_Surface.hxx>
60 #include <Geom_Plane.hxx>
61 #include <Geom_SphericalSurface.hxx>
62 #include <Geom_CylindricalSurface.hxx>
63 #include <GeomAdaptor_Surface.hxx>
65 #include <Geom2d_Curve.hxx>
67 #include <Bnd_Box.hxx>
68 #include <GProp_GProps.hxx>
71 #include <TColStd_Array1OfReal.hxx>
72 #include <TColStd_HArray1OfInteger.hxx>
77 //#include <OSD_Timer.hxx>
79 #include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
81 //=============================================================================
85 //=============================================================================
86 GEOMImpl_IShapesOperations::GEOMImpl_IShapesOperations (GEOM_Engine* theEngine, int theDocID)
87 : GEOM_IOperations(theEngine, theDocID)
89 MESSAGE("GEOMImpl_IShapesOperations::GEOMImpl_IShapesOperations");
92 //=============================================================================
96 //=============================================================================
97 GEOMImpl_IShapesOperations::~GEOMImpl_IShapesOperations()
99 MESSAGE("GEOMImpl_IShapesOperations::~GEOMImpl_IShapesOperations");
103 //=============================================================================
107 //=============================================================================
108 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeEdge
109 (Handle(GEOM_Object) thePnt1, Handle(GEOM_Object) thePnt2)
113 if (thePnt1.IsNull() || thePnt2.IsNull()) return NULL;
115 //Add a new Edge object
116 Handle(GEOM_Object) anEdge = GetEngine()->AddObject(GetDocID(), GEOM_EDGE);
118 //Add a new Vector function
119 Handle(GEOM_Function) aFunction =
120 anEdge->AddFunction(GEOMImpl_VectorDriver::GetID(), VECTOR_TWO_PNT);
122 //Check if the function is set correctly
123 if (aFunction->GetDriverGUID() != GEOMImpl_VectorDriver::GetID()) return NULL;
125 GEOMImpl_IVector aPI (aFunction);
127 Handle(GEOM_Function) aRef1 = thePnt1->GetLastFunction();
128 Handle(GEOM_Function) aRef2 = thePnt2->GetLastFunction();
129 if (aRef1.IsNull() || aRef2.IsNull()) return NULL;
131 aPI.SetPoint1(aRef1);
132 aPI.SetPoint2(aRef2);
134 //Compute the Edge value
136 if (!GetSolver()->ComputeFunction(aFunction)) {
137 SetErrorCode("Vector driver failed");
141 catch (Standard_Failure) {
142 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
143 SetErrorCode(aFail->GetMessageString());
147 //Make a Python command
148 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdge("
149 << thePnt1 << ", " << thePnt2 << ")";
155 //=============================================================================
159 //=============================================================================
160 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeWire
161 (list<Handle(GEOM_Object)> theShapes)
163 return MakeShape(theShapes, GEOM_WIRE, WIRE_EDGES, "MakeWire");
166 //=============================================================================
170 //=============================================================================
171 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFace (Handle(GEOM_Object) theWire,
172 const bool isPlanarWanted)
176 if (theWire.IsNull()) return NULL;
178 //Add a new Face object
179 Handle(GEOM_Object) aFace = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
181 //Add a new Shape function for creation of a face from a wire
182 Handle(GEOM_Function) aFunction =
183 aFace->AddFunction(GEOMImpl_ShapeDriver::GetID(), FACE_WIRE);
184 if (aFunction.IsNull()) return NULL;
186 //Check if the function is set correctly
187 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
189 GEOMImpl_IShapes aCI (aFunction);
191 Handle(GEOM_Function) aRefWire = theWire->GetLastFunction();
193 if (aRefWire.IsNull()) return NULL;
195 aCI.SetBase(aRefWire);
196 aCI.SetIsPlanar(isPlanarWanted);
198 //Compute the Face value
200 if (!GetSolver()->ComputeFunction(aFunction)) {
201 SetErrorCode("Shape driver failed to compute a face");
205 catch (Standard_Failure) {
206 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
207 SetErrorCode(aFail->GetMessageString());
211 //Make a Python command
212 GEOM::TPythonDump(aFunction) << aFace << " = geompy.MakeFace("
213 << theWire << ", " << (int)isPlanarWanted << ")";
219 //=============================================================================
223 //=============================================================================
224 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFaceWires
225 (list<Handle(GEOM_Object)> theShapes,
226 const bool isPlanarWanted)
231 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
234 Handle(GEOM_Function) aFunction =
235 aShape->AddFunction(GEOMImpl_ShapeDriver::GetID(), FACE_WIRES);
236 if (aFunction.IsNull()) return NULL;
238 //Check if the function is set correctly
239 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
241 GEOMImpl_IShapes aCI (aFunction);
243 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
246 list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
247 for (; it != theShapes.end(); it++) {
248 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
249 if (aRefSh.IsNull()) {
250 SetErrorCode("NULL argument shape for the face construction");
253 aShapesSeq->Append(aRefSh);
255 aCI.SetShapes(aShapesSeq);
257 aCI.SetIsPlanar(isPlanarWanted);
261 if (!GetSolver()->ComputeFunction(aFunction)) {
262 SetErrorCode("Shape driver failed");
266 catch (Standard_Failure) {
267 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
268 SetErrorCode(aFail->GetMessageString());
272 //Make a Python command
273 GEOM::TPythonDump pd (aFunction);
274 pd << aShape << " = geompy.MakeFaceWires([";
277 it = theShapes.begin();
278 if (it != theShapes.end()) {
280 while (it != theShapes.end()) {
281 pd << ", " << (*it++);
284 pd << "], " << (int)isPlanarWanted << ")";
290 //=============================================================================
294 //=============================================================================
295 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeShell
296 (list<Handle(GEOM_Object)> theShapes)
298 return MakeShape(theShapes, GEOM_SHELL, SHELL_FACES, "MakeShell");
301 //=============================================================================
305 //=============================================================================
306 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeSolidShells
307 (list<Handle(GEOM_Object)> theShapes)
309 return MakeShape(theShapes, GEOM_SOLID, SOLID_SHELLS, "MakeSolidShells");
312 //=============================================================================
316 //=============================================================================
317 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeSolidShell (Handle(GEOM_Object) theShell)
321 if (theShell.IsNull()) return NULL;
323 //Add a new Solid object
324 Handle(GEOM_Object) aSolid = GetEngine()->AddObject(GetDocID(), GEOM_SOLID);
326 //Add a new Solid function for creation of a solid from a shell
327 Handle(GEOM_Function) aFunction =
328 aSolid->AddFunction(GEOMImpl_ShapeDriver::GetID(), SOLID_SHELL);
329 if (aFunction.IsNull()) return NULL;
331 //Check if the function is set correctly
332 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
334 GEOMImpl_IShapes aCI (aFunction);
336 Handle(GEOM_Function) aRefShell = theShell->GetLastFunction();
338 if (aRefShell.IsNull()) return NULL;
340 aCI.SetBase(aRefShell);
342 //Compute the Solid value
344 if (!GetSolver()->ComputeFunction(aFunction)) {
345 SetErrorCode("Solid driver failed");
349 catch (Standard_Failure) {
350 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
351 SetErrorCode(aFail->GetMessageString());
355 //Make a Python command
356 GEOM::TPythonDump(aFunction) << aSolid
357 << " = geompy.MakeSolid(" << theShell << ")";
363 //=============================================================================
367 //=============================================================================
368 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeCompound
369 (list<Handle(GEOM_Object)> theShapes)
371 return MakeShape(theShapes, GEOM_COMPOUND, COMPOUND_SHAPES, "MakeCompound");
374 //=============================================================================
378 //=============================================================================
379 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeShape
380 (list<Handle(GEOM_Object)> theShapes,
381 const Standard_Integer theObjectType,
382 const Standard_Integer theFunctionType,
383 const TCollection_AsciiString& theMethodName)
388 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), theObjectType);
391 Handle(GEOM_Function) aFunction =
392 aShape->AddFunction(GEOMImpl_ShapeDriver::GetID(), theFunctionType);
393 if (aFunction.IsNull()) return NULL;
395 //Check if the function is set correctly
396 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
398 GEOMImpl_IShapes aCI (aFunction);
400 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
403 list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
404 for (; it != theShapes.end(); it++) {
405 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
406 if (aRefSh.IsNull()) {
407 SetErrorCode("NULL argument shape for the shape construction");
410 aShapesSeq->Append(aRefSh);
412 aCI.SetShapes(aShapesSeq);
416 if (!GetSolver()->ComputeFunction(aFunction)) {
417 SetErrorCode("Shape driver failed");
421 catch (Standard_Failure) {
422 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
423 SetErrorCode(aFail->GetMessageString());
427 //Make a Python command
428 GEOM::TPythonDump pd (aFunction);
429 pd << aShape << " = geompy." << theMethodName.ToCString() << "([";
432 it = theShapes.begin();
433 if (it != theShapes.end()) {
435 while (it != theShapes.end()) {
436 pd << ", " << (*it++);
445 //=============================================================================
449 //=============================================================================
450 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeGlueFaces
451 (Handle(GEOM_Object) theShape,
452 const Standard_Real theTolerance)
456 if (theShape.IsNull()) return NULL;
458 //Add a new Glued object
459 Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
461 //Add a new Glue function
462 Handle(GEOM_Function) aFunction;
463 aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_FACES);
464 if (aFunction.IsNull()) return NULL;
466 //Check if the function is set correctly
467 if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
469 GEOMImpl_IGlue aCI (aFunction);
471 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
472 if (aRefShape.IsNull()) return NULL;
474 aCI.SetBase(aRefShape);
475 aCI.SetTolerance(theTolerance);
477 //Compute the sub-shape value
478 Standard_Boolean isWarning = Standard_False;
480 if (!GetSolver()->ComputeFunction(aFunction)) {
481 SetErrorCode("Shape driver failed to glue faces");
485 catch (Standard_Failure) {
486 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
487 SetErrorCode(aFail->GetMessageString());
488 // to provide warning
489 if (!aFunction->GetValue().IsNull()) {
490 isWarning = Standard_True;
496 //Make a Python command
497 GEOM::TPythonDump(aFunction) << aGlued << " = geompy.MakeGlueFaces("
498 << theShape << ", " << theTolerance << ")";
500 // to provide warning
501 if (!isWarning) SetErrorCode(OK);
505 //=============================================================================
509 //=============================================================================
510 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::MakeExplode
511 (Handle(GEOM_Object) theShape,
512 const Standard_Integer theShapeType,
513 const Standard_Boolean isSorted)
515 // OSD_Timer timer1, timer2, timer3, timer4;
520 if (theShape.IsNull()) return NULL;
521 TopoDS_Shape aShape = theShape->GetValue();
522 if (aShape.IsNull()) return NULL;
524 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
525 Handle(GEOM_Object) anObj;
526 Handle(GEOM_Function) aFunction;
527 TopTools_MapOfShape mapShape;
528 TopTools_ListOfShape listShape;
530 if (aShape.ShapeType() == TopAbs_COMPOUND &&
531 (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
532 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPSOLID ||
533 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPOUND)) {
534 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
535 for (; It.More(); It.Next()) {
536 if (mapShape.Add(It.Value())) {
537 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
538 TopAbs_ShapeEnum(theShapeType) == It.Value().ShapeType()) {
539 listShape.Append(It.Value());
544 TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
545 for (; exp.More(); exp.Next())
546 if (mapShape.Add(exp.Current()))
547 listShape.Append(exp.Current());
550 if (listShape.IsEmpty()) {
551 SetErrorCode("The given shape has no sub-shapes of the requested type");
559 SortShapes(listShape);
564 TopTools_IndexedMapOfShape anIndices;
565 TopExp::MapShapes(aShape, anIndices);
566 Handle(TColStd_HArray1OfInteger) anArray;
568 TopTools_ListIteratorOfListOfShape itSub (listShape);
569 TCollection_AsciiString anAsciiList, anEntry;
570 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
571 TopoDS_Shape aValue = itSub.Value();
572 anArray = new TColStd_HArray1OfInteger(1,1);
573 anArray->SetValue(1, anIndices.FindIndex(aValue));
574 anObj = GetEngine()->AddSubShape(theShape, anArray);
577 // for python command
578 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
579 anAsciiList += anEntry;
583 //Make a Python command
584 anAsciiList.Trunc(anAsciiList.Length() - 1);
586 aFunction = theShape->GetLastFunction();
587 TCollection_AsciiString anOldDescr = aFunction->GetDescription();
589 GEOM::TPythonDump pd (aFunction);
590 pd << anOldDescr.ToCString() << "\n\t[" << anAsciiList.ToCString();
591 pd << "] = geompy.SubShapeAll" << (isSorted ? "Sorted(" : "(");
592 pd << theShape << ", " << theShapeType << ")";
598 // cout << "Explosure takes:" << endl;
600 // cout << "Sorting takes:" << endl;
602 // cout << "Sub-shapes addition takes:" << endl;
604 // cout << "Update Description takes:" << endl;
610 //=============================================================================
614 //=============================================================================
615 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::SubShapeAllIDs
616 (Handle(GEOM_Object) theShape,
617 const Standard_Integer theShapeType,
618 const Standard_Boolean isSorted)
622 if (theShape.IsNull()) return NULL;
623 TopoDS_Shape aShape = theShape->GetValue();
624 if (aShape.IsNull()) return NULL;
626 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
627 TopTools_MapOfShape mapShape;
628 TopTools_ListOfShape listShape;
630 if (aShape.ShapeType() == TopAbs_COMPOUND &&
631 (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
632 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPSOLID ||
633 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPOUND)) {
634 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
635 for (; It.More(); It.Next()) {
636 if (mapShape.Add(It.Value())) {
637 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
638 TopAbs_ShapeEnum(theShapeType) == It.Value().ShapeType()) {
639 listShape.Append(It.Value());
644 TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
645 for (; exp.More(); exp.Next())
646 if (mapShape.Add(exp.Current()))
647 listShape.Append(exp.Current());
650 if (listShape.IsEmpty()) {
651 SetErrorCode("The given shape has no sub-shapes of the requested type");
656 SortShapes(listShape);
658 TopTools_IndexedMapOfShape anIndices;
659 TopExp::MapShapes(aShape, anIndices);
660 Handle(TColStd_HArray1OfInteger) anArray;
662 TopTools_ListIteratorOfListOfShape itSub (listShape);
663 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
664 TopoDS_Shape aValue = itSub.Value();
665 aSeq->Append(anIndices.FindIndex(aValue));
668 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
669 TCollection_AsciiString anOldDescr = aFunction->GetDescription();
671 //Make a Python command
672 GEOM::TPythonDump pd (aFunction);
673 pd << anOldDescr.ToCString() << "\n\tlistSubShapeIDs = geompy.SubShapeAll";
674 pd << (isSorted ? "SortedIDs(" : "IDs(");
675 pd << theShape << ", " << theShapeType << ")";
681 //=============================================================================
685 //=============================================================================
686 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetSubShape
687 (Handle(GEOM_Object) theMainShape,
688 const Standard_Integer theID)
692 if (theMainShape.IsNull()) return NULL;
694 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
695 anArray->SetValue(1, theID);
696 Handle(GEOM_Object) anObj = GetEngine()->AddSubShape(theMainShape, anArray,true);
697 if (anObj.IsNull()) {
698 SetErrorCode("Can not get a sub-shape with the given ID");
702 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
704 //Make a Python command
705 GEOM::TPythonDump(aFunction) << anObj << " = geompy.GetSubShape("
706 << theMainShape << ", [" << theID << "])";
713 //=============================================================================
717 //=============================================================================
718 Standard_Integer GEOMImpl_IShapesOperations::NumberOfFaces (Handle(GEOM_Object) theShape)
722 Standard_Integer nb = 0;
724 if (theShape.IsNull()) return -1;
725 TopoDS_Shape aShape = theShape->GetValue();
726 if (aShape.IsNull()) return -1;
728 TopTools_MapOfShape mapShape;
730 TopExp_Explorer exp (aShape, TopAbs_FACE);
731 for (; exp.More(); exp.Next())
732 if (mapShape.Add(exp.Current()))
739 //=============================================================================
743 //=============================================================================
744 Standard_Integer GEOMImpl_IShapesOperations::NumberOfEdges (Handle(GEOM_Object) theShape)
748 Standard_Integer nb = 0;
750 if (theShape.IsNull()) return -1;
751 TopoDS_Shape aShape = theShape->GetValue();
752 if (aShape.IsNull()) return -1;
754 TopTools_MapOfShape mapShape;
756 TopExp_Explorer exp (aShape, TopAbs_EDGE);
757 for (; exp.More(); exp.Next())
758 if (mapShape.Add(exp.Current()))
765 //=============================================================================
769 //=============================================================================
770 Handle(GEOM_Object) GEOMImpl_IShapesOperations::ReverseShape(Handle(GEOM_Object) theShape)
774 if (theShape.IsNull()) return NULL;
776 //Add a new reversed object
777 Handle(GEOM_Object) aReversed = GetEngine()->AddObject(GetDocID(), theShape->GetType());
779 //Add a new Revese function
780 Handle(GEOM_Function) aFunction;
781 aFunction = aReversed->AddFunction(GEOMImpl_ShapeDriver::GetID(), REVERSE_ORIENTATION);
782 if (aFunction.IsNull()) return NULL;
784 //Check if the function is set correctly
785 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
787 GEOMImpl_IShapes aSI (aFunction);
789 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
790 if (aRefShape.IsNull()) return NULL;
792 aSI.SetBase(aRefShape);
794 //Compute the sub-shape value
796 if (!GetSolver()->ComputeFunction(aFunction)) {
797 SetErrorCode("Shape driver failed to reverse shape");
801 catch (Standard_Failure) {
802 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
803 SetErrorCode(aFail->GetMessageString());
807 //Make a Python command
808 GEOM::TPythonDump(aFunction) << aReversed
809 << " = geompy.ChangeOrientation(" << theShape << ")";
815 //=============================================================================
819 //=============================================================================
820 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetFreeFacesIDs
821 (Handle(GEOM_Object) theShape)
825 if (theShape.IsNull()) return NULL;
826 TopoDS_Shape aShape = theShape->GetValue();
827 if (aShape.IsNull()) return NULL;
829 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
831 TopTools_IndexedDataMapOfShapeListOfShape mapFaceBlocks;
832 GEOMImpl_Block6Explorer::MapShapesAndAncestors
833 (aShape, TopAbs_FACE, TopAbs_SOLID, mapFaceBlocks);
835 Standard_Integer ind = 1, nbFaces = mapFaceBlocks.Extent();
838 SetErrorCode("The given shape has no faces");
842 TopTools_IndexedMapOfShape anIndices;
843 TopExp::MapShapes(aShape, anIndices);
846 for (; ind <= nbFaces; ind++) {
847 if (mapFaceBlocks.FindFromIndex(ind).Extent() != 2) {
848 id = anIndices.FindIndex(mapFaceBlocks.FindKey(ind));
853 //The explode doesn't change object so no new function is required.
854 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
855 TCollection_AsciiString anOldDescr = aFunction->GetDescription();
857 //Make a Python command
858 GEOM::TPythonDump(aFunction) << anOldDescr.ToCString()
859 << "\n\tlistFreeFacesIDs = geompy.GetFreeFacesIDs(" << theShape << ")";
865 //=======================================================================
866 //function : GetSharedShapes
868 //=======================================================================
870 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetSharedShapes
871 (Handle(GEOM_Object) theShape1,
872 Handle(GEOM_Object) theShape2,
873 const Standard_Integer theShapeType)
877 if (theShape1.IsNull() || theShape2.IsNull()) return NULL;
879 TopoDS_Shape aShape1 = theShape1->GetValue();
880 TopoDS_Shape aShape2 = theShape2->GetValue();
882 if (aShape1.IsNull() || aShape2.IsNull()) return NULL;
884 TopTools_IndexedMapOfShape anIndices;
885 TopExp::MapShapes(aShape1, anIndices);
886 Handle(TColStd_HArray1OfInteger) anArray;
888 TopTools_IndexedMapOfShape mapShape1;
889 TopExp::MapShapes(aShape1, TopAbs_ShapeEnum(theShapeType), mapShape1);
891 Handle(GEOM_Object) anObj;
892 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
893 TCollection_AsciiString anAsciiList, anEntry;
895 TopTools_MapOfShape mapShape2;
896 TopExp_Explorer exp (aShape2, TopAbs_ShapeEnum(theShapeType));
897 for (; exp.More(); exp.Next()) {
898 TopoDS_Shape aSS = exp.Current();
899 if (mapShape2.Add(aSS) && mapShape1.Contains(aSS)) {
900 anArray = new TColStd_HArray1OfInteger(1,1);
901 anArray->SetValue(1, anIndices.FindIndex(aSS));
902 anObj = GetEngine()->AddSubShape(theShape1, anArray);
905 // for python command
906 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
907 anAsciiList += anEntry;
912 if (aSeq->IsEmpty()) {
913 SetErrorCode("The given shapes have no shared sub-shapes of the requested type");
917 //Make a Python command
918 anAsciiList.Trunc(anAsciiList.Length() - 1);
920 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
922 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
923 << "] = geompy.GetSharedShapes(" << theShape1 << ", "
924 << theShape2 << ", " << theShapeType << ")";
930 //=============================================================================
934 //=============================================================================
935 static GEOM::TPythonDump& operator<< (GEOM::TPythonDump& theDump,
936 const GEOMAlgo_State theState)
940 theDump << "geompy.GEOM.ST_IN";
942 case GEOMAlgo_ST_OUT:
943 theDump << "geompy.GEOM.ST_OUT";
946 theDump << "geompy.GEOM.ST_ON";
948 case GEOMAlgo_ST_ONIN:
949 theDump << "geompy.GEOM.ST_ONIN";
951 case GEOMAlgo_ST_ONOUT:
952 theDump << "geompy.GEOM.ST_ONOUT";
955 theDump << "geompy.GEOM.ST_UNKNOWN";
961 //=======================================================================
962 //function : checkTypeShapesOn
964 * \brief Checks if theShapeType parameter of GetShapesOnXXX() is OK
965 * \param theShapeType - the shape type to check
966 * \retval bool - result of the check
968 //=======================================================================
970 bool GEOMImpl_IShapesOperations::checkTypeShapesOn(const Standard_Integer theShapeType)
972 if (theShapeType != TopAbs_VERTEX &&
973 theShapeType != TopAbs_EDGE &&
974 theShapeType != TopAbs_FACE &&
975 theShapeType != TopAbs_SOLID) {
976 SetErrorCode("Only solids, vertices, edges or faces can be found by this method");
982 //=======================================================================
983 //function : makePlane
985 * \brief Creates Geom_Plane
986 * \param theAx1 - shape object defining plane parameters
987 * \retval Handle(Geom_Surface) - resulting surface
989 //=======================================================================
991 Handle(Geom_Surface) GEOMImpl_IShapesOperations::makePlane(const TopoDS_Shape& anAx1)
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");
1007 return new Geom_Plane(aLoc, aVec);
1010 //=======================================================================
1011 //function : makeCylinder
1013 * \brief Creates Geom_CylindricalSurface
1014 * \param theAx1 - edge defining cylinder axis
1015 * \param theRadius - cylinder radius
1016 * \retval Handle(Geom_Surface) - resulting surface
1018 //=======================================================================
1020 Handle(Geom_Surface) GEOMImpl_IShapesOperations::makeCylinder(const TopoDS_Shape& anAxis,
1021 const Standard_Real theRadius)
1023 //Axis of the cylinder
1024 if (anAxis.ShapeType() != TopAbs_EDGE) {
1025 SetErrorCode("Not an edge given for the axis");
1028 TopoDS_Edge anEdge = TopoDS::Edge(anAxis);
1029 TopoDS_Vertex V1, V2;
1030 TopExp::Vertices(anEdge, V1, V2, Standard_True);
1031 if (V1.IsNull() || V2.IsNull()) {
1032 SetErrorCode("Bad edge given for the axis");
1035 gp_Pnt aLoc = BRep_Tool::Pnt(V1);
1036 gp_Vec aVec (aLoc, BRep_Tool::Pnt(V2));
1037 if (aVec.Magnitude() < Precision::Confusion()) {
1038 SetErrorCode("Vector with null magnitude given");
1042 gp_Ax3 anAx3 (aLoc, aVec);
1043 return new Geom_CylindricalSurface(anAx3, theRadius);
1047 //=======================================================================
1048 //function : getShapesOnSurfaceIDs
1050 * \brief Find IDs of subshapes complying with given status about surface
1051 * \param theSurface - the surface to check state of subshapes against
1052 * \param theShape - the shape to explore
1053 * \param theShapeType - type of subshape of theShape
1054 * \param theState - required state
1055 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1057 //=======================================================================
1059 Handle(TColStd_HSequenceOfInteger)
1060 GEOMImpl_IShapesOperations::getShapesOnSurfaceIDs(const Handle(Geom_Surface)& theSurface,
1061 const TopoDS_Shape& theShape,
1062 TopAbs_ShapeEnum theShapeType,
1063 GEOMAlgo_State theState)
1065 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
1066 // MESSAGE("--------------------------- GetShapesOnPlane phase 1 takes:");
1067 // OSD_Timer timer1;
1070 // Check presence of triangulation, build if need
1071 if (!CheckTriangulation(theShape))
1075 GEOMAlgo_FinderShapeOn1 aFinder;
1076 Standard_Real aTol = 0.0001; // default value
1078 aFinder.SetShape(theShape);
1079 aFinder.SetTolerance(aTol);
1080 aFinder.SetSurface(theSurface);
1081 aFinder.SetShapeType(theShapeType);
1082 aFinder.SetState(theState);
1084 // Sets the minimal number of inner points for the faces that do not have own
1085 // inner points at all (for e.g. rectangular planar faces have just 2 triangles).
1087 aFinder.SetNbPntsMin(3);
1088 // Sets the maximal number of inner points for edges or faces.
1089 // It is usefull for the cases when this number is very big (e.g =2000) to improve
1090 // the performance. If this value =0, all inner points will be taken into account.
1092 aFinder.SetNbPntsMax(100);
1097 // MESSAGE("--------------------------- Perform on Plane takes:");
1104 // MESSAGE("--------------------------- GetShapesOnPlane phase 3 takes:");
1108 // Interprete results
1109 Standard_Integer iErr = aFinder.ErrorStatus();
1110 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
1112 MESSAGE(" iErr : " << iErr);
1113 TCollection_AsciiString aMsg (" iErr : ");
1114 aMsg += TCollection_AsciiString(iErr);
1118 Standard_Integer iWrn = aFinder.WarningStatus();
1119 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
1121 MESSAGE(" *** iWrn : " << iWrn);
1124 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
1126 if (listSS.Extent() < 1) {
1127 SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
1134 // MESSAGE("--------------------------- GetShapesOnPlane phase 4 takes:");
1138 // Fill sequence of object IDs
1139 aSeqOfIDs = new TColStd_HSequenceOfInteger;
1141 TopTools_IndexedMapOfShape anIndices;
1142 TopExp::MapShapes(theShape, anIndices);
1144 TopTools_ListIteratorOfListOfShape itSub (listSS);
1145 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
1146 int id = anIndices.FindIndex(itSub.Value());
1147 aSeqOfIDs->Append(id);
1154 //=======================================================================
1155 //function : getObjectsShapesOn
1157 * \brief Find shape objects and their entries by their ids
1158 * \param theShapeIDs - incoming shape ids
1159 * \param theShapeEntries - outgoing entries like "entry1, entry2, ..."
1160 * \retval Handle(TColStd_HSequenceOfTransient) - found shape objects
1162 //=======================================================================
1164 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::
1165 getObjectsShapesOn(const Handle(GEOM_Object)& theShape,
1166 const Handle(TColStd_HSequenceOfInteger)& theShapeIDs,
1167 TCollection_AsciiString & theShapeEntries)
1169 Handle(TColStd_HSequenceOfTransient) aSeq;
1171 if ( !theShapeIDs.IsNull() && theShapeIDs->Length() > 0 )
1173 aSeq = new TColStd_HSequenceOfTransient;
1174 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
1175 TCollection_AsciiString anEntry;
1176 for ( int i = 1; i <= theShapeIDs->Length(); ++i )
1178 anArray->SetValue(1, theShapeIDs->Value( i ));
1179 Handle(GEOM_Object) anObj = GetEngine()->AddSubShape(theShape, anArray);
1180 aSeq->Append( anObj );
1182 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
1183 if ( i != 1 ) theShapeEntries += ",";
1184 theShapeEntries += anEntry;
1190 //=======================================================================
1191 //function : getShapesOnSurface
1193 * \brief Find subshapes complying with given status about surface
1194 * \param theSurface - the surface to check state of subshapes against
1195 * \param theShape - the shape to explore
1196 * \param theShapeType - type of subshape of theShape
1197 * \param theState - required state
1198 * \param theShapeEntries - outgoing entries like "entry1, entry2, ..."
1199 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1201 //=======================================================================
1203 Handle(TColStd_HSequenceOfTransient)
1204 GEOMImpl_IShapesOperations::getShapesOnSurface(const Handle(Geom_Surface)& theSurface,
1205 const Handle(GEOM_Object)& theShape,
1206 TopAbs_ShapeEnum theShapeType,
1207 GEOMAlgo_State theState,
1208 TCollection_AsciiString & theShapeEntries)
1210 // Find subshapes ids
1211 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
1212 getShapesOnSurfaceIDs (theSurface, theShape->GetValue(), theShapeType, theState);
1213 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
1216 return getObjectsShapesOn( theShape, aSeqOfIDs, theShapeEntries );
1219 //=============================================================================
1223 //=============================================================================
1224 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnPlane
1225 (const Handle(GEOM_Object)& theShape,
1226 const Standard_Integer theShapeType,
1227 const Handle(GEOM_Object)& theAx1,
1228 const GEOMAlgo_State theState)
1232 // MESSAGE("--------------------------- GetShapesOnPlane phase 1 takes:");
1233 // OSD_Timer timer1;
1236 if (theShape.IsNull() || theAx1.IsNull()) return NULL;
1238 TopoDS_Shape aShape = theShape->GetValue();
1239 TopoDS_Shape anAx1 = theAx1->GetValue();
1241 if (aShape.IsNull() || anAx1.IsNull()) return NULL;
1243 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
1244 if ( !checkTypeShapesOn( theShapeType ))
1248 Handle(Geom_Surface) aPlane = makePlane( anAx1 );
1249 if ( aPlane.IsNull() )
1253 TCollection_AsciiString anAsciiList;
1254 Handle(TColStd_HSequenceOfTransient) aSeq;
1255 aSeq = getShapesOnSurface( aPlane, theShape, aShapeType, theState, anAsciiList );
1256 if ( aSeq.IsNull() || aSeq->Length() == 0 )
1262 // MESSAGE("--------------------------- GetShapesOnPlane phase 5 takes:");
1266 // Make a Python command
1268 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
1269 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1271 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
1272 << "] = geompy.GetShapesOnPlane(" << theShape << ", "
1273 << theShapeType << ", " << theAx1 << ", " << theState << ")";
1279 //=============================================================================
1281 * GetShapesOnCylinder
1283 //=============================================================================
1284 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnCylinder
1285 (const Handle(GEOM_Object)& theShape,
1286 const Standard_Integer theShapeType,
1287 const Handle(GEOM_Object)& theAxis,
1288 const Standard_Real theRadius,
1289 const GEOMAlgo_State theState)
1293 if (theShape.IsNull() || theAxis.IsNull()) return NULL;
1295 TopoDS_Shape aShape = theShape->GetValue();
1296 TopoDS_Shape anAxis = theAxis->GetValue();
1298 if (aShape.IsNull() || anAxis.IsNull()) return NULL;
1300 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
1301 if ( !checkTypeShapesOn( aShapeType ))
1304 // Create a cylinder surface
1305 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
1306 if ( aCylinder.IsNull() )
1310 TCollection_AsciiString anAsciiList;
1311 Handle(TColStd_HSequenceOfTransient) aSeq;
1312 aSeq = getShapesOnSurface( aCylinder, theShape, aShapeType, theState, anAsciiList );
1313 if ( aSeq.IsNull() || aSeq->Length() == 0 )
1316 // Make a Python command
1318 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
1319 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1321 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
1322 << "] = geompy.GetShapesOnCylinder(" << theShape << ", " << theShapeType
1323 << ", " << theAxis << ", " << theRadius << ", " << theState << ")";
1329 //=============================================================================
1333 //=============================================================================
1334 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnSphere
1335 (const Handle(GEOM_Object)& theShape,
1336 const Standard_Integer theShapeType,
1337 const Handle(GEOM_Object)& theCenter,
1338 const Standard_Real theRadius,
1339 const GEOMAlgo_State theState)
1343 if (theShape.IsNull() || theCenter.IsNull()) return NULL;
1345 TopoDS_Shape aShape = theShape->GetValue();
1346 TopoDS_Shape aCenter = theCenter->GetValue();
1348 if (aShape.IsNull() || aCenter.IsNull()) return NULL;
1350 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
1351 if ( !checkTypeShapesOn( aShapeType ))
1354 // Center of the sphere
1355 if (aCenter.ShapeType() != TopAbs_VERTEX) return NULL;
1356 gp_Pnt aLoc = BRep_Tool::Pnt(TopoDS::Vertex(aCenter));
1358 gp_Ax3 anAx3 (aLoc, gp::DZ());
1359 Handle(Geom_SphericalSurface) aSphere =
1360 new Geom_SphericalSurface(anAx3, theRadius);
1363 TCollection_AsciiString anAsciiList;
1364 Handle(TColStd_HSequenceOfTransient) aSeq;
1365 aSeq = getShapesOnSurface( aSphere, theShape, aShapeType, theState, anAsciiList );
1366 if ( aSeq.IsNull() || aSeq->Length() == 0 )
1369 // Make a Python command
1371 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
1372 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1374 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
1375 << "] = geompy.GetShapesOnSphere(" << theShape << ", " << theShapeType
1376 << ", " << theCenter << ", " << theRadius << ", " << theState << ")";
1382 //=======================================================================
1383 //function : getCreatedLast
1385 * \brief Select the object created last
1386 * \param theObj1 - Object 1
1387 * \param theObj2 - Object 2
1388 * \retval Handle(GEOM_Object) - selected object
1390 //=======================================================================
1392 Handle(GEOM_Object) GEOMImpl_IShapesOperations::getCreatedLast(const Handle(GEOM_Object)& theObj1,
1393 const Handle(GEOM_Object)& theObj2)
1395 if ( theObj1.IsNull() ) return theObj2;
1396 if ( theObj2.IsNull() ) return theObj1;
1397 return ( theObj1->GetEntry().Tag() > theObj2->GetEntry().Tag() ) ? theObj1 : theObj2;
1400 //=============================================================================
1402 * GetShapesOnPlaneIDs
1404 //=============================================================================
1405 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnPlaneIDs
1406 (const Handle(GEOM_Object)& theShape,
1407 const Standard_Integer theShapeType,
1408 const Handle(GEOM_Object)& theAx1,
1409 const GEOMAlgo_State theState)
1413 if (theShape.IsNull() || theAx1.IsNull()) return NULL;
1415 TopoDS_Shape aShape = theShape->GetValue();
1416 TopoDS_Shape anAx1 = theAx1->GetValue();
1418 if (aShape.IsNull() || anAx1.IsNull()) return NULL;
1420 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
1421 if ( !checkTypeShapesOn( aShapeType ))
1425 Handle(Geom_Surface) aPlane = makePlane( anAx1 );
1426 if ( aPlane.IsNull() )
1430 Handle(TColStd_HSequenceOfInteger) aSeq;
1431 aSeq = getShapesOnSurfaceIDs( aPlane, aShape, aShapeType, theState );
1433 // The GetShapesOnPlaneIDs() doesn't change object so no new function is required.
1434 Handle(GEOM_Function) aFunction = getCreatedLast(theShape,theAx1)->GetLastFunction();
1436 // Make a Python command
1437 const bool append = true;
1438 GEOM::TPythonDump(aFunction,append)
1439 << "listShapesOnPlane = geompy.GetShapesOnPlaneIDs"
1440 << "(" << theShape << "," << theShapeType << "," << theAx1 << "," << theState << ")";
1446 //=============================================================================
1448 * GetShapesOnCylinderIDs
1450 //=============================================================================
1451 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnCylinderIDs
1452 (const Handle(GEOM_Object)& theShape,
1453 const Standard_Integer theShapeType,
1454 const Handle(GEOM_Object)& theAxis,
1455 const Standard_Real theRadius,
1456 const GEOMAlgo_State theState)
1460 if (theShape.IsNull() || theAxis.IsNull()) return NULL;
1462 TopoDS_Shape aShape = theShape->GetValue();
1463 TopoDS_Shape anAxis = theAxis->GetValue();
1465 if (aShape.IsNull() || anAxis.IsNull()) return NULL;
1467 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
1468 if ( !checkTypeShapesOn( aShapeType ))
1471 // Create a cylinder surface
1472 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
1473 if ( aCylinder.IsNull() )
1477 Handle(TColStd_HSequenceOfInteger) aSeq;
1478 aSeq = getShapesOnSurfaceIDs( aCylinder, aShape, aShapeType, theState );
1480 // The GetShapesOnCylinder() doesn't change object so no new function is required.
1481 Handle(GEOM_Function) aFunction = getCreatedLast(theShape,theAxis)->GetLastFunction();
1483 // Make a Python command
1484 const bool append = true;
1485 GEOM::TPythonDump(aFunction,append)
1486 << "listShapesOnCylinder = geompy.GetShapesOnCylinderIDs"
1487 << "(" << theShape << ", " << theShapeType << ", " << theAxis << ", "
1488 << theRadius << ", " << theState << ")";
1494 //=============================================================================
1496 * GetShapesOnSphereIDs
1498 //=============================================================================
1499 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnSphereIDs
1500 (const Handle(GEOM_Object)& theShape,
1501 const Standard_Integer theShapeType,
1502 const Handle(GEOM_Object)& theCenter,
1503 const Standard_Real theRadius,
1504 const GEOMAlgo_State theState)
1508 if (theShape.IsNull() || theCenter.IsNull()) return NULL;
1510 TopoDS_Shape aShape = theShape->GetValue();
1511 TopoDS_Shape aCenter = theCenter->GetValue();
1513 if (aShape.IsNull() || aCenter.IsNull()) return NULL;
1515 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
1516 if ( !checkTypeShapesOn( aShapeType ))
1519 // Center of the sphere
1520 if (aCenter.ShapeType() != TopAbs_VERTEX) return NULL;
1521 gp_Pnt aLoc = BRep_Tool::Pnt(TopoDS::Vertex(aCenter));
1523 gp_Ax3 anAx3 (aLoc, gp::DZ());
1524 Handle(Geom_SphericalSurface) aSphere =
1525 new Geom_SphericalSurface(anAx3, theRadius);
1528 Handle(TColStd_HSequenceOfInteger) aSeq;
1529 aSeq = getShapesOnSurfaceIDs( aSphere, aShape, aShapeType, theState );
1531 // The GetShapesOnSphere() doesn't change object so no new function is required.
1532 Handle(GEOM_Function) aFunction = getCreatedLast(theShape,theCenter)->GetLastFunction();
1534 // Make a Python command
1535 const bool append = true;
1536 GEOM::TPythonDump(aFunction,append)
1537 << "listShapesOnCylinder = geompy.GetShapesOnCylinderIDs"
1538 << "(" << theShape << ", " << theShapeType << ", " << theCenter << ", "
1539 << theRadius << ", " << theState << ")";
1545 //=======================================================================
1546 //function : getShapesOnQuadrangleIDs
1548 * \brief Find IDs of subshapes complying with given status about quadrangle
1549 * \param theShape - the shape to explore
1550 * \param theShapeType - type of subshape of theShape
1551 * \param theTopLeftPoint - top left quadrangle corner
1552 * \param theTopRigthPoint - top right quadrangle corner
1553 * \param theBottomLeftPoint - bottom left quadrangle corner
1554 * \param theBottomRigthPoint - bottom right quadrangle corner
1555 * \param theState - required state
1556 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1558 //=======================================================================
1560 Handle(TColStd_HSequenceOfInteger)
1561 GEOMImpl_IShapesOperations::getShapesOnQuadrangleIDs (const Handle(GEOM_Object)& theShape,
1562 const Standard_Integer theShapeType,
1563 const Handle(GEOM_Object)& theTopLeftPoint,
1564 const Handle(GEOM_Object)& theTopRigthPoint,
1565 const Handle(GEOM_Object)& theBottomLeftPoint,
1566 const Handle(GEOM_Object)& theBottomRigthPoint,
1567 const GEOMAlgo_State theState)
1571 if ( theShape.IsNull() ||
1572 theTopLeftPoint.IsNull() ||
1573 theTopRigthPoint.IsNull() ||
1574 theBottomLeftPoint.IsNull() ||
1575 theBottomRigthPoint.IsNull() )
1578 TopoDS_Shape aShape = theShape->GetValue();
1579 TopoDS_Shape aTL = theTopLeftPoint->GetValue();
1580 TopoDS_Shape aTR = theTopRigthPoint->GetValue();
1581 TopoDS_Shape aBL = theBottomLeftPoint->GetValue();
1582 TopoDS_Shape aBR = theBottomRigthPoint->GetValue();
1584 if (aShape.IsNull() ||
1589 aTL.ShapeType() != TopAbs_VERTEX ||
1590 aTR.ShapeType() != TopAbs_VERTEX ||
1591 aBL.ShapeType() != TopAbs_VERTEX ||
1592 aBR.ShapeType() != TopAbs_VERTEX )
1595 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
1596 if ( !checkTypeShapesOn( aShapeType ))
1599 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
1601 // Check presence of triangulation, build if need
1602 if (!CheckTriangulation(aShape))
1606 gp_Pnt aPntTL = BRep_Tool::Pnt(TopoDS::Vertex(aTL));
1607 gp_Pnt aPntTR = BRep_Tool::Pnt(TopoDS::Vertex(aTR));
1608 gp_Pnt aPntBL = BRep_Tool::Pnt(TopoDS::Vertex(aBL));
1609 gp_Pnt aPntBR = BRep_Tool::Pnt(TopoDS::Vertex(aBR));
1611 GEOMAlgo_FinderShapeOnQuad aFinder( aPntTL, aPntTR, aPntBL, aPntBR );
1612 Standard_Real aTol = 0.0001; // default value
1614 aFinder.SetShape(aShape);
1615 aFinder.SetTolerance(aTol);
1616 //aFinder.SetSurface(theSurface);
1617 aFinder.SetShapeType(aShapeType);
1618 aFinder.SetState(theState);
1620 // Sets the minimal number of inner points for the faces that do not have own
1621 // inner points at all (for e.g. rectangular planar faces have just 2 triangles).
1623 aFinder.SetNbPntsMin(3);
1624 // Sets the maximal number of inner points for edges or faces.
1625 // It is usefull for the cases when this number is very big (e.g =2000) to improve
1626 // the performance. If this value =0, all inner points will be taken into account.
1628 aFinder.SetNbPntsMax(100);
1632 // Interprete results
1633 Standard_Integer iErr = aFinder.ErrorStatus();
1634 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
1636 MESSAGE(" iErr : " << iErr);
1637 TCollection_AsciiString aMsg (" iErr : ");
1638 aMsg += TCollection_AsciiString(iErr);
1642 Standard_Integer iWrn = aFinder.WarningStatus();
1643 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
1645 MESSAGE(" *** iWrn : " << iWrn);
1648 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
1650 if (listSS.Extent() < 1) {
1651 SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
1655 // Fill sequence of object IDs
1656 aSeqOfIDs = new TColStd_HSequenceOfInteger;
1658 TopTools_IndexedMapOfShape anIndices;
1659 TopExp::MapShapes(aShape, anIndices);
1661 TopTools_ListIteratorOfListOfShape itSub (listSS);
1662 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
1663 int id = anIndices.FindIndex(itSub.Value());
1664 aSeqOfIDs->Append(id);
1669 //=======================================================================
1670 //function : GetShapesOnQuadrangle
1672 * \brief Find subshapes complying with given status about quadrangle
1673 * \param theShape - the shape to explore
1674 * \param theShapeType - type of subshape of theShape
1675 * \param theTopLeftPoint - top left quadrangle corner
1676 * \param theTopRigthPoint - top right quadrangle corner
1677 * \param theBottomLeftPoint - bottom left quadrangle corner
1678 * \param theBottomRigthPoint - bottom right quadrangle corner
1679 * \param theState - required state
1680 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1682 //=======================================================================
1684 Handle(TColStd_HSequenceOfTransient)
1685 GEOMImpl_IShapesOperations::GetShapesOnQuadrangle (const Handle(GEOM_Object)& theShape,
1686 const Standard_Integer theShapeType,
1687 const Handle(GEOM_Object)& theTopLeftPoint,
1688 const Handle(GEOM_Object)& theTopRigthPoint,
1689 const Handle(GEOM_Object)& theBottomLeftPoint,
1690 const Handle(GEOM_Object)& theBottomRigthPoint,
1691 const GEOMAlgo_State theState)
1694 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
1695 getShapesOnQuadrangleIDs( theShape,
1700 theBottomRigthPoint,
1702 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->IsEmpty() )
1705 // Find objects by indices
1706 TCollection_AsciiString anAsciiList;
1707 Handle(TColStd_HSequenceOfTransient) aSeq;
1708 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
1709 if ( aSeq.IsNull() || aSeq->IsEmpty() )
1712 // Make a Python command
1714 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
1715 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1717 GEOM::TPythonDump(aFunction)
1718 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnQuadrangle("
1720 << theShapeType << ", "
1721 << theTopLeftPoint << ", "
1722 << theTopRigthPoint << ", "
1723 << theBottomLeftPoint << ", "
1724 << theBottomRigthPoint << ", "
1731 //=======================================================================
1732 //function : GetShapesOnQuadrangleIDs
1734 * \brief Find IDs of subshapes complying with given status about quadrangle
1735 * \param theShape - the shape to explore
1736 * \param theShapeType - type of subshape of theShape
1737 * \param theTopLeftPoint - top left quadrangle corner
1738 * \param theTopRigthPoint - top right quadrangle corner
1739 * \param theBottomLeftPoint - bottom left quadrangle corner
1740 * \param theBottomRigthPoint - bottom right quadrangle corner
1741 * \param theState - required state
1742 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1744 //=======================================================================
1746 Handle(TColStd_HSequenceOfInteger)
1747 GEOMImpl_IShapesOperations::GetShapesOnQuadrangleIDs (const Handle(GEOM_Object)& theShape,
1748 const Standard_Integer theShapeType,
1749 const Handle(GEOM_Object)& theTopLeftPoint,
1750 const Handle(GEOM_Object)& theTopRigthPoint,
1751 const Handle(GEOM_Object)& theBottomLeftPoint,
1752 const Handle(GEOM_Object)& theBottomRigthPoint,
1753 const GEOMAlgo_State theState)
1756 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
1757 getShapesOnQuadrangleIDs( theShape,
1762 theBottomRigthPoint,
1764 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->IsEmpty() )
1767 // Make a Python command
1769 // The GetShapesOnCylinder() doesn't change object so no new function is required.
1770 Handle(GEOM_Object) lastObj = getCreatedLast(theShape,theTopLeftPoint);
1771 lastObj = getCreatedLast(lastObj,theTopRigthPoint);
1772 lastObj = getCreatedLast(lastObj,theBottomRigthPoint);
1773 lastObj = getCreatedLast(lastObj,theBottomLeftPoint);
1774 Handle(GEOM_Function) aFunction = lastObj->GetLastFunction();
1776 const bool append = true;
1777 GEOM::TPythonDump(aFunction,append)
1778 << "listShapesOnQuadrangle = geompy.GetShapesOnQuadrangleIDs("
1780 << theShapeType << ", "
1781 << theTopLeftPoint << ", "
1782 << theTopRigthPoint << ", "
1783 << theBottomLeftPoint << ", "
1784 << theBottomRigthPoint << ", "
1792 //=============================================================================
1796 //=============================================================================
1797 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlace
1798 (Handle(GEOM_Object) theShapeWhere,
1799 Handle(GEOM_Object) theShapeWhat)
1803 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
1805 TopoDS_Shape aWhere = theShapeWhere->GetValue();
1806 TopoDS_Shape aWhat = theShapeWhat->GetValue();
1808 if (aWhere.IsNull() || aWhat.IsNull()) return NULL;
1810 //Fill array of indices
1811 Handle(TColStd_HArray1OfInteger) aModifiedArray;
1813 Handle(GEOM_Function) aWhereFunction = theShapeWhere->GetLastFunction();
1815 TopTools_IndexedMapOfShape aWhereIndices;
1816 TopExp::MapShapes(aWhere, aWhereIndices);
1818 if (aWhereIndices.Contains(aWhat)) {
1820 // entity was not changed by the operation
1821 Standard_Integer aWhatIndex = aWhereIndices.FindIndex(aWhat);
1822 aModifiedArray = new TColStd_HArray1OfInteger(1,1);
1823 aModifiedArray->SetValue(1, aWhatIndex);
1827 TDF_Label aHistoryLabel = aWhereFunction->GetHistoryEntry(Standard_False);
1828 if (aHistoryLabel.IsNull()) {
1829 SetErrorCode("Modifications history does not exist for the shape under consideration.");
1833 // search in history for all argument shapes
1834 Standard_Boolean isFound = Standard_False;
1836 TDF_LabelSequence aLabelSeq;
1837 aWhereFunction->GetDependency(aLabelSeq);
1838 Standard_Integer nbArg = aLabelSeq.Length();
1840 for (Standard_Integer iarg = 1; iarg <= nbArg && !isFound; iarg++) {
1842 TDF_Label anArgumentRefLabel = aLabelSeq.Value(iarg);
1844 Handle(GEOM_Object) anArgumentObject = GEOM_Object::GetReferencedObject(anArgumentRefLabel);
1845 TopoDS_Shape anArgumentShape = anArgumentObject->GetValue();
1847 TopTools_IndexedMapOfShape anArgumentIndices;
1848 TopExp::MapShapes(anArgumentShape, anArgumentIndices);
1850 if (anArgumentIndices.Contains(aWhat)) {
1851 isFound = Standard_True;
1852 Standard_Integer aWhatIndex = anArgumentIndices.FindIndex(aWhat);
1854 // Find corresponding label in history
1855 TDF_Label anArgumentHistoryLabel =
1856 aWhereFunction->GetArgumentHistoryEntry(anArgumentRefLabel, Standard_False);
1857 if (anArgumentHistoryLabel.IsNull()) {
1858 // Lost History of operation argument. Possibly, all its entities was removed.
1863 TDF_Label aWhatHistoryLabel = anArgumentHistoryLabel.FindChild(aWhatIndex, Standard_False);
1864 if (aWhatHistoryLabel.IsNull()) {
1870 Handle(TDataStd_IntegerArray) anIntegerArray;
1871 if (!aWhatHistoryLabel.FindAttribute(TDataStd_IntegerArray::GetID(), anIntegerArray)) {
1872 SetErrorCode("Error: Empty modifications history for the sought shape.");
1876 aModifiedArray = anIntegerArray->Array();
1877 if (aModifiedArray->Length() == 0) {
1878 SetErrorCode("Error: Empty modifications history for the sought shape.");
1885 SetErrorCode("The sought shape does not belong to any operation argument.");
1891 Handle(GEOM_Object) aResult = GetEngine()->AddSubShape(theShapeWhere, aModifiedArray);
1893 if (aModifiedArray->Length() > 1) {
1895 aResult->SetType(GEOM_GROUP);
1897 //Set a sub shape type
1898 TDF_Label aFreeLabel = aResult->GetFreeLabel();
1899 TopAbs_ShapeEnum aShapeType = aWhat.ShapeType();
1900 TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aShapeType);
1903 //Make a Python command
1904 Handle(GEOM_Function) aFunction = aResult->GetFunction(1);
1906 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetInPlace("
1907 << theShapeWhere << ", " << theShapeWhat << ")";
1913 //=======================================================================
1914 //function : SortShapes
1916 //=======================================================================
1917 void GEOMImpl_IShapesOperations::SortShapes(TopTools_ListOfShape& SL)
1919 Standard_Integer MaxShapes = SL.Extent();
1920 TopTools_Array1OfShape aShapes (1,MaxShapes);
1921 TColStd_Array1OfInteger OrderInd(1,MaxShapes);
1922 TColStd_Array1OfReal MidXYZ (1,MaxShapes); //X,Y,Z;
1923 TColStd_Array1OfReal Length (1,MaxShapes); //X,Y,Z;
1925 // Computing of CentreOfMass
1926 Standard_Integer Index;
1929 TopTools_ListIteratorOfListOfShape it(SL);
1930 for (Index=1; it.More(); Index++)
1932 TopoDS_Shape S = it.Value();
1933 SL.Remove( it ); // == it.Next()
1935 OrderInd.SetValue (Index, Index);
1936 if (S.ShapeType() == TopAbs_VERTEX)
1938 GPoint = BRep_Tool::Pnt( TopoDS::Vertex( S ));
1939 Length.SetValue( Index, (Standard_Real) S.Orientation());
1943 BRepGProp::LinearProperties (S, GPr);
1944 GPoint = GPr.CentreOfMass();
1945 Length.SetValue( Index, GPr.Mass() );
1947 MidXYZ.SetValue(Index,
1948 GPoint.X()*999 + GPoint.Y()*99 + GPoint.Z()*0.9);
1951 Standard_Integer aTemp;
1952 Standard_Boolean exchange, Sort = Standard_True;
1955 Sort = Standard_False;
1956 for (Index=1; Index < MaxShapes; Index++)
1958 if (MidXYZ(OrderInd(Index)) > MidXYZ(OrderInd(Index+1)))
1959 exchange = Standard_True;
1960 else if (MidXYZ(OrderInd(Index)) == MidXYZ(OrderInd(Index+1)) &&
1961 Length(OrderInd(Index)) > Length(OrderInd(Index+1)) )
1962 exchange = Standard_True;
1964 exchange = Standard_False;
1967 aTemp = OrderInd(Index);
1968 OrderInd(Index) = OrderInd(Index+1);
1969 OrderInd(Index+1) = aTemp;
1970 Sort = Standard_True;
1974 for (Index=1; Index <= MaxShapes; Index++)
1975 SL.Append( aShapes( OrderInd(Index) ));
1978 //=======================================================================
1979 //function : CheckTriangulation
1981 //=======================================================================
1982 bool GEOMImpl_IShapesOperations::CheckTriangulation (const TopoDS_Shape& aShape)
1984 // MESSAGE("CheckTriangulation");
1986 // OSD_Timer timer1;
1989 TopExp_Explorer exp (aShape, TopAbs_FACE);
1991 SetErrorCode("Shape without faces given");
1995 TopLoc_Location aTopLoc;
1996 Handle(Poly_Triangulation) aTRF;
1997 aTRF = BRep_Tool::Triangulation(TopoDS::Face(exp.Current()), aTopLoc);
1998 if (aTRF.IsNull()) {
1999 // calculate deflection
2000 Standard_Real aDeviationCoefficient = 0.001;
2003 BRepBndLib::Add(aShape, B);
2004 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
2005 B.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
2007 Standard_Real dx = aXmax - aXmin, dy = aYmax - aYmin, dz = aZmax - aZmin;
2008 Standard_Real aDeflection = Max(Max(dx, dy), dz) * aDeviationCoefficient * 4;
2010 // MESSAGE("Deflection = " << aDeflection);
2012 Standard_Real aHLRAngle = 0.349066;
2014 BRepMesh_IncrementalMesh Inc (aShape, aDeflection, Standard_False, aHLRAngle);