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>
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>
74 #include <TColStd_DataMapOfIntegerInteger.hxx>
75 #include <TColStd_DataMapIteratorOfDataMapOfIntegerInteger.hxx>
80 //#include <OSD_Timer.hxx>
82 #include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
84 //=============================================================================
88 //=============================================================================
89 GEOMImpl_IShapesOperations::GEOMImpl_IShapesOperations (GEOM_Engine* theEngine, int theDocID)
90 : GEOM_IOperations(theEngine, theDocID)
92 MESSAGE("GEOMImpl_IShapesOperations::GEOMImpl_IShapesOperations");
95 //=============================================================================
99 //=============================================================================
100 GEOMImpl_IShapesOperations::~GEOMImpl_IShapesOperations()
102 MESSAGE("GEOMImpl_IShapesOperations::~GEOMImpl_IShapesOperations");
106 //=============================================================================
110 //=============================================================================
111 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeEdge
112 (Handle(GEOM_Object) thePnt1, Handle(GEOM_Object) thePnt2)
116 if (thePnt1.IsNull() || thePnt2.IsNull()) return NULL;
118 //Add a new Edge object
119 Handle(GEOM_Object) anEdge = GetEngine()->AddObject(GetDocID(), GEOM_EDGE);
121 //Add a new Vector function
122 Handle(GEOM_Function) aFunction =
123 anEdge->AddFunction(GEOMImpl_VectorDriver::GetID(), VECTOR_TWO_PNT);
125 //Check if the function is set correctly
126 if (aFunction->GetDriverGUID() != GEOMImpl_VectorDriver::GetID()) return NULL;
128 GEOMImpl_IVector aPI (aFunction);
130 Handle(GEOM_Function) aRef1 = thePnt1->GetLastFunction();
131 Handle(GEOM_Function) aRef2 = thePnt2->GetLastFunction();
132 if (aRef1.IsNull() || aRef2.IsNull()) return NULL;
134 aPI.SetPoint1(aRef1);
135 aPI.SetPoint2(aRef2);
137 //Compute the Edge value
139 if (!GetSolver()->ComputeFunction(aFunction)) {
140 SetErrorCode("Vector driver failed");
144 catch (Standard_Failure) {
145 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
146 SetErrorCode(aFail->GetMessageString());
150 //Make a Python command
151 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdge("
152 << thePnt1 << ", " << thePnt2 << ")";
158 //=============================================================================
162 //=============================================================================
163 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeWire
164 (list<Handle(GEOM_Object)> theShapes)
166 return MakeShape(theShapes, GEOM_WIRE, WIRE_EDGES, "MakeWire");
169 //=============================================================================
173 //=============================================================================
174 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFace (Handle(GEOM_Object) theWire,
175 const bool isPlanarWanted)
179 if (theWire.IsNull()) return NULL;
181 //Add a new Face object
182 Handle(GEOM_Object) aFace = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
184 //Add a new Shape function for creation of a face from a wire
185 Handle(GEOM_Function) aFunction =
186 aFace->AddFunction(GEOMImpl_ShapeDriver::GetID(), FACE_WIRE);
187 if (aFunction.IsNull()) return NULL;
189 //Check if the function is set correctly
190 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
192 GEOMImpl_IShapes aCI (aFunction);
194 Handle(GEOM_Function) aRefWire = theWire->GetLastFunction();
196 if (aRefWire.IsNull()) return NULL;
198 aCI.SetBase(aRefWire);
199 aCI.SetIsPlanar(isPlanarWanted);
201 //Compute the Face value
203 if (!GetSolver()->ComputeFunction(aFunction)) {
204 SetErrorCode("Shape driver failed to compute a face");
208 catch (Standard_Failure) {
209 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
210 SetErrorCode(aFail->GetMessageString());
214 //Make a Python command
215 GEOM::TPythonDump(aFunction) << aFace << " = geompy.MakeFace("
216 << theWire << ", " << (int)isPlanarWanted << ")";
222 //=============================================================================
226 //=============================================================================
227 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFaceWires
228 (list<Handle(GEOM_Object)> theShapes,
229 const bool isPlanarWanted)
234 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
237 Handle(GEOM_Function) aFunction =
238 aShape->AddFunction(GEOMImpl_ShapeDriver::GetID(), FACE_WIRES);
239 if (aFunction.IsNull()) return NULL;
241 //Check if the function is set correctly
242 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
244 GEOMImpl_IShapes aCI (aFunction);
246 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
249 list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
250 for (; it != theShapes.end(); it++) {
251 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
252 if (aRefSh.IsNull()) {
253 SetErrorCode("NULL argument shape for the face construction");
256 aShapesSeq->Append(aRefSh);
258 aCI.SetShapes(aShapesSeq);
260 aCI.SetIsPlanar(isPlanarWanted);
264 if (!GetSolver()->ComputeFunction(aFunction)) {
265 SetErrorCode("Shape driver failed");
269 catch (Standard_Failure) {
270 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
271 SetErrorCode(aFail->GetMessageString());
275 //Make a Python command
276 GEOM::TPythonDump pd (aFunction);
277 pd << aShape << " = geompy.MakeFaceWires([";
280 it = theShapes.begin();
281 if (it != theShapes.end()) {
283 while (it != theShapes.end()) {
284 pd << ", " << (*it++);
287 pd << "], " << (int)isPlanarWanted << ")";
293 //=============================================================================
297 //=============================================================================
298 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeShell
299 (list<Handle(GEOM_Object)> theShapes)
301 return MakeShape(theShapes, GEOM_SHELL, SHELL_FACES, "MakeShell");
304 //=============================================================================
308 //=============================================================================
309 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeSolidShells
310 (list<Handle(GEOM_Object)> theShapes)
312 return MakeShape(theShapes, GEOM_SOLID, SOLID_SHELLS, "MakeSolidShells");
315 //=============================================================================
319 //=============================================================================
320 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeSolidShell (Handle(GEOM_Object) theShell)
324 if (theShell.IsNull()) return NULL;
326 //Add a new Solid object
327 Handle(GEOM_Object) aSolid = GetEngine()->AddObject(GetDocID(), GEOM_SOLID);
329 //Add a new Solid function for creation of a solid from a shell
330 Handle(GEOM_Function) aFunction =
331 aSolid->AddFunction(GEOMImpl_ShapeDriver::GetID(), SOLID_SHELL);
332 if (aFunction.IsNull()) return NULL;
334 //Check if the function is set correctly
335 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
337 GEOMImpl_IShapes aCI (aFunction);
339 Handle(GEOM_Function) aRefShell = theShell->GetLastFunction();
341 if (aRefShell.IsNull()) return NULL;
343 aCI.SetBase(aRefShell);
345 //Compute the Solid value
347 if (!GetSolver()->ComputeFunction(aFunction)) {
348 SetErrorCode("Solid driver failed");
352 catch (Standard_Failure) {
353 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
354 SetErrorCode(aFail->GetMessageString());
358 //Make a Python command
359 GEOM::TPythonDump(aFunction) << aSolid
360 << " = geompy.MakeSolid(" << theShell << ")";
366 //=============================================================================
370 //=============================================================================
371 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeCompound
372 (list<Handle(GEOM_Object)> theShapes)
374 return MakeShape(theShapes, GEOM_COMPOUND, COMPOUND_SHAPES, "MakeCompound");
377 //=============================================================================
381 //=============================================================================
382 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeShape
383 (list<Handle(GEOM_Object)> theShapes,
384 const Standard_Integer theObjectType,
385 const Standard_Integer theFunctionType,
386 const TCollection_AsciiString& theMethodName)
391 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), theObjectType);
394 Handle(GEOM_Function) aFunction =
395 aShape->AddFunction(GEOMImpl_ShapeDriver::GetID(), theFunctionType);
396 if (aFunction.IsNull()) return NULL;
398 //Check if the function is set correctly
399 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
401 GEOMImpl_IShapes aCI (aFunction);
403 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
406 list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
407 for (; it != theShapes.end(); it++) {
408 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
409 if (aRefSh.IsNull()) {
410 SetErrorCode("NULL argument shape for the shape construction");
413 aShapesSeq->Append(aRefSh);
415 aCI.SetShapes(aShapesSeq);
419 if (!GetSolver()->ComputeFunction(aFunction)) {
420 SetErrorCode("Shape driver failed");
424 catch (Standard_Failure) {
425 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
426 SetErrorCode(aFail->GetMessageString());
430 //Make a Python command
431 GEOM::TPythonDump pd (aFunction);
432 pd << aShape << " = geompy." << theMethodName.ToCString() << "([";
435 it = theShapes.begin();
436 if (it != theShapes.end()) {
438 while (it != theShapes.end()) {
439 pd << ", " << (*it++);
448 //=============================================================================
452 //=============================================================================
453 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeGlueFaces
454 (Handle(GEOM_Object) theShape,
455 const Standard_Real theTolerance)
459 if (theShape.IsNull()) return NULL;
461 //Add a new Glued object
462 Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
464 //Add a new Glue function
465 Handle(GEOM_Function) aFunction;
466 aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_FACES);
467 if (aFunction.IsNull()) return NULL;
469 //Check if the function is set correctly
470 if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
472 GEOMImpl_IGlue aCI (aFunction);
474 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
475 if (aRefShape.IsNull()) return NULL;
477 aCI.SetBase(aRefShape);
478 aCI.SetTolerance(theTolerance);
480 //Compute the sub-shape value
481 Standard_Boolean isWarning = Standard_False;
483 if (!GetSolver()->ComputeFunction(aFunction)) {
484 SetErrorCode("Shape driver failed to glue faces");
488 catch (Standard_Failure) {
489 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
490 SetErrorCode(aFail->GetMessageString());
491 // to provide warning
492 if (!aFunction->GetValue().IsNull()) {
493 isWarning = Standard_True;
499 //Make a Python command
500 GEOM::TPythonDump(aFunction) << aGlued << " = geompy.MakeGlueFaces("
501 << theShape << ", " << theTolerance << ")";
503 // to provide warning
504 if (!isWarning) SetErrorCode(OK);
508 //=============================================================================
512 //=============================================================================
513 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::MakeExplode
514 (Handle(GEOM_Object) theShape,
515 const Standard_Integer theShapeType,
516 const Standard_Boolean isSorted)
518 // OSD_Timer timer1, timer2, timer3, timer4;
523 if (theShape.IsNull()) return NULL;
524 TopoDS_Shape aShape = theShape->GetValue();
525 if (aShape.IsNull()) return NULL;
527 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
528 Handle(GEOM_Object) anObj;
529 Handle(GEOM_Function) aFunction;
530 TopTools_MapOfShape mapShape;
531 TopTools_ListOfShape listShape;
533 if (aShape.ShapeType() == TopAbs_COMPOUND &&
534 (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
535 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPSOLID ||
536 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPOUND)) {
537 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
538 for (; It.More(); It.Next()) {
539 if (mapShape.Add(It.Value())) {
540 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
541 TopAbs_ShapeEnum(theShapeType) == It.Value().ShapeType()) {
542 listShape.Append(It.Value());
547 TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
548 for (; exp.More(); exp.Next())
549 if (mapShape.Add(exp.Current()))
550 listShape.Append(exp.Current());
553 if (listShape.IsEmpty()) {
554 SetErrorCode("The given shape has no sub-shapes of the requested type");
562 SortShapes(listShape);
567 TopTools_IndexedMapOfShape anIndices;
568 TopExp::MapShapes(aShape, anIndices);
569 Handle(TColStd_HArray1OfInteger) anArray;
571 TopTools_ListIteratorOfListOfShape itSub (listShape);
572 TCollection_AsciiString anAsciiList, anEntry;
573 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
574 TopoDS_Shape aValue = itSub.Value();
575 anArray = new TColStd_HArray1OfInteger(1,1);
576 anArray->SetValue(1, anIndices.FindIndex(aValue));
577 anObj = GetEngine()->AddSubShape(theShape, anArray);
580 // for python command
581 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
582 anAsciiList += anEntry;
586 //Make a Python command
587 anAsciiList.Trunc(anAsciiList.Length() - 1);
589 aFunction = theShape->GetLastFunction();
590 TCollection_AsciiString anOldDescr = aFunction->GetDescription();
592 GEOM::TPythonDump pd (aFunction);
593 pd << anOldDescr.ToCString() << "\n\t[" << anAsciiList.ToCString();
594 pd << "] = geompy.SubShapeAll" << (isSorted ? "Sorted(" : "(");
595 pd << theShape << ", " << theShapeType << ")";
601 // cout << "Explosure takes:" << endl;
603 // cout << "Sorting takes:" << endl;
605 // cout << "Sub-shapes addition takes:" << endl;
607 // cout << "Update Description takes:" << endl;
613 //=============================================================================
617 //=============================================================================
618 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::SubShapeAllIDs
619 (Handle(GEOM_Object) theShape,
620 const Standard_Integer theShapeType,
621 const Standard_Boolean isSorted)
625 if (theShape.IsNull()) return NULL;
626 TopoDS_Shape aShape = theShape->GetValue();
627 if (aShape.IsNull()) return NULL;
629 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
630 TopTools_MapOfShape mapShape;
631 TopTools_ListOfShape listShape;
633 if (aShape.ShapeType() == TopAbs_COMPOUND &&
634 (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
635 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPSOLID ||
636 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPOUND)) {
637 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
638 for (; It.More(); It.Next()) {
639 if (mapShape.Add(It.Value())) {
640 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
641 TopAbs_ShapeEnum(theShapeType) == It.Value().ShapeType()) {
642 listShape.Append(It.Value());
647 TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
648 for (; exp.More(); exp.Next())
649 if (mapShape.Add(exp.Current()))
650 listShape.Append(exp.Current());
653 if (listShape.IsEmpty()) {
654 SetErrorCode("The given shape has no sub-shapes of the requested type");
659 SortShapes(listShape);
661 TopTools_IndexedMapOfShape anIndices;
662 TopExp::MapShapes(aShape, anIndices);
663 Handle(TColStd_HArray1OfInteger) anArray;
665 TopTools_ListIteratorOfListOfShape itSub (listShape);
666 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
667 TopoDS_Shape aValue = itSub.Value();
668 aSeq->Append(anIndices.FindIndex(aValue));
671 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
672 TCollection_AsciiString anOldDescr = aFunction->GetDescription();
674 //Make a Python command
675 GEOM::TPythonDump pd (aFunction);
676 pd << anOldDescr.ToCString() << "\n\tlistSubShapeIDs = geompy.SubShapeAll";
677 pd << (isSorted ? "SortedIDs(" : "IDs(");
678 pd << theShape << ", " << theShapeType << ")";
684 //=============================================================================
688 //=============================================================================
689 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetSubShape
690 (Handle(GEOM_Object) theMainShape,
691 const Standard_Integer theID)
695 if (theMainShape.IsNull()) return NULL;
697 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
698 anArray->SetValue(1, theID);
699 Handle(GEOM_Object) anObj = GetEngine()->AddSubShape(theMainShape, anArray,true);
700 if (anObj.IsNull()) {
701 SetErrorCode("Can not get a sub-shape with the given ID");
705 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
707 //Make a Python command
708 GEOM::TPythonDump(aFunction) << anObj << " = geompy.GetSubShape("
709 << theMainShape << ", [" << theID << "])";
716 //=============================================================================
720 //=============================================================================
721 Standard_Integer GEOMImpl_IShapesOperations::NumberOfFaces (Handle(GEOM_Object) theShape)
725 Standard_Integer nb = 0;
727 if (theShape.IsNull()) return -1;
728 TopoDS_Shape aShape = theShape->GetValue();
729 if (aShape.IsNull()) return -1;
731 TopTools_MapOfShape mapShape;
733 TopExp_Explorer exp (aShape, TopAbs_FACE);
734 for (; exp.More(); exp.Next())
735 if (mapShape.Add(exp.Current()))
742 //=============================================================================
746 //=============================================================================
747 Standard_Integer GEOMImpl_IShapesOperations::NumberOfEdges (Handle(GEOM_Object) theShape)
751 Standard_Integer nb = 0;
753 if (theShape.IsNull()) return -1;
754 TopoDS_Shape aShape = theShape->GetValue();
755 if (aShape.IsNull()) return -1;
757 TopTools_MapOfShape mapShape;
759 TopExp_Explorer exp (aShape, TopAbs_EDGE);
760 for (; exp.More(); exp.Next())
761 if (mapShape.Add(exp.Current()))
768 //=============================================================================
772 //=============================================================================
773 Handle(GEOM_Object) GEOMImpl_IShapesOperations::ReverseShape(Handle(GEOM_Object) theShape)
777 if (theShape.IsNull()) return NULL;
779 //Add a new reversed object
780 Handle(GEOM_Object) aReversed = GetEngine()->AddObject(GetDocID(), theShape->GetType());
782 //Add a new Revese function
783 Handle(GEOM_Function) aFunction;
784 aFunction = aReversed->AddFunction(GEOMImpl_ShapeDriver::GetID(), REVERSE_ORIENTATION);
785 if (aFunction.IsNull()) return NULL;
787 //Check if the function is set correctly
788 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
790 GEOMImpl_IShapes aSI (aFunction);
792 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
793 if (aRefShape.IsNull()) return NULL;
795 aSI.SetBase(aRefShape);
797 //Compute the sub-shape value
799 if (!GetSolver()->ComputeFunction(aFunction)) {
800 SetErrorCode("Shape driver failed to reverse shape");
804 catch (Standard_Failure) {
805 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
806 SetErrorCode(aFail->GetMessageString());
810 //Make a Python command
811 GEOM::TPythonDump(aFunction) << aReversed
812 << " = geompy.ChangeOrientation(" << theShape << ")";
818 //=============================================================================
822 //=============================================================================
823 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetFreeFacesIDs
824 (Handle(GEOM_Object) theShape)
828 if (theShape.IsNull()) return NULL;
829 TopoDS_Shape aShape = theShape->GetValue();
830 if (aShape.IsNull()) return NULL;
832 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
834 TopTools_IndexedDataMapOfShapeListOfShape mapFaceBlocks;
835 GEOMImpl_Block6Explorer::MapShapesAndAncestors
836 (aShape, TopAbs_FACE, TopAbs_SOLID, mapFaceBlocks);
838 Standard_Integer ind = 1, nbFaces = mapFaceBlocks.Extent();
841 SetErrorCode("The given shape has no faces");
845 TopTools_IndexedMapOfShape anIndices;
846 TopExp::MapShapes(aShape, anIndices);
849 for (; ind <= nbFaces; ind++) {
850 if (mapFaceBlocks.FindFromIndex(ind).Extent() != 2) {
851 id = anIndices.FindIndex(mapFaceBlocks.FindKey(ind));
856 //The explode doesn't change object so no new function is required.
857 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
858 TCollection_AsciiString anOldDescr = aFunction->GetDescription();
860 //Make a Python command
861 GEOM::TPythonDump(aFunction) << anOldDescr.ToCString()
862 << "\n\tlistFreeFacesIDs = geompy.GetFreeFacesIDs(" << theShape << ")";
868 //=======================================================================
869 //function : GetSharedShapes
871 //=======================================================================
873 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetSharedShapes
874 (Handle(GEOM_Object) theShape1,
875 Handle(GEOM_Object) theShape2,
876 const Standard_Integer theShapeType)
880 if (theShape1.IsNull() || theShape2.IsNull()) return NULL;
882 TopoDS_Shape aShape1 = theShape1->GetValue();
883 TopoDS_Shape aShape2 = theShape2->GetValue();
885 if (aShape1.IsNull() || aShape2.IsNull()) return NULL;
887 TopTools_IndexedMapOfShape anIndices;
888 TopExp::MapShapes(aShape1, anIndices);
889 Handle(TColStd_HArray1OfInteger) anArray;
891 TopTools_IndexedMapOfShape mapShape1;
892 TopExp::MapShapes(aShape1, TopAbs_ShapeEnum(theShapeType), mapShape1);
894 Handle(GEOM_Object) anObj;
895 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
896 TCollection_AsciiString anAsciiList, anEntry;
898 TopTools_MapOfShape mapShape2;
899 TopExp_Explorer exp (aShape2, TopAbs_ShapeEnum(theShapeType));
900 for (; exp.More(); exp.Next()) {
901 TopoDS_Shape aSS = exp.Current();
902 if (mapShape2.Add(aSS) && mapShape1.Contains(aSS)) {
903 anArray = new TColStd_HArray1OfInteger(1,1);
904 anArray->SetValue(1, anIndices.FindIndex(aSS));
905 anObj = GetEngine()->AddSubShape(theShape1, anArray);
908 // for python command
909 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
910 anAsciiList += anEntry;
915 if (aSeq->IsEmpty()) {
916 SetErrorCode("The given shapes have no shared sub-shapes of the requested type");
920 //Make a Python command
921 anAsciiList.Trunc(anAsciiList.Length() - 1);
923 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
925 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
926 << "] = geompy.GetSharedShapes(" << theShape1 << ", "
927 << theShape2 << ", " << theShapeType << ")";
933 //=============================================================================
937 //=============================================================================
938 static GEOM::TPythonDump& operator<< (GEOM::TPythonDump& theDump,
939 const GEOMAlgo_State theState)
943 theDump << "geompy.GEOM.ST_IN";
945 case GEOMAlgo_ST_OUT:
946 theDump << "geompy.GEOM.ST_OUT";
949 theDump << "geompy.GEOM.ST_ON";
951 case GEOMAlgo_ST_ONIN:
952 theDump << "geompy.GEOM.ST_ONIN";
954 case GEOMAlgo_ST_ONOUT:
955 theDump << "geompy.GEOM.ST_ONOUT";
958 theDump << "geompy.GEOM.ST_UNKNOWN";
964 //=======================================================================
965 //function : checkTypeShapesOn
967 * \brief Checks if theShapeType parameter of GetShapesOnXXX() is OK
968 * \param theShapeType - the shape type to check
969 * \retval bool - result of the check
971 //=======================================================================
973 bool GEOMImpl_IShapesOperations::checkTypeShapesOn(const Standard_Integer theShapeType)
975 if (theShapeType != TopAbs_VERTEX &&
976 theShapeType != TopAbs_EDGE &&
977 theShapeType != TopAbs_FACE &&
978 theShapeType != TopAbs_SOLID) {
979 SetErrorCode("Only solids, vertices, edges or faces can be found by this method");
985 //=======================================================================
986 //function : makePlane
988 * \brief Creates Geom_Plane
989 * \param theAx1 - shape object defining plane parameters
990 * \retval Handle(Geom_Surface) - resulting surface
992 //=======================================================================
994 Handle(Geom_Surface) GEOMImpl_IShapesOperations::makePlane(const TopoDS_Shape& anAx1)
996 if (anAx1.ShapeType() != TopAbs_EDGE) return NULL;
997 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
998 TopoDS_Vertex V1, V2;
999 TopExp::Vertices(anEdge, V1, V2, Standard_True);
1000 if (V1.IsNull() || V2.IsNull()) {
1001 SetErrorCode("Bad edge given for the plane normal vector");
1004 gp_Pnt aLoc = BRep_Tool::Pnt(V1);
1005 gp_Vec aVec (aLoc, BRep_Tool::Pnt(V2));
1006 if (aVec.Magnitude() < Precision::Confusion()) {
1007 SetErrorCode("Vector with null magnitude given");
1010 return new Geom_Plane(aLoc, aVec);
1013 //=======================================================================
1014 //function : makeCylinder
1016 * \brief Creates Geom_CylindricalSurface
1017 * \param theAx1 - edge defining cylinder axis
1018 * \param theRadius - cylinder radius
1019 * \retval Handle(Geom_Surface) - resulting surface
1021 //=======================================================================
1023 Handle(Geom_Surface) GEOMImpl_IShapesOperations::makeCylinder(const TopoDS_Shape& anAxis,
1024 const Standard_Real theRadius)
1026 //Axis of the cylinder
1027 if (anAxis.ShapeType() != TopAbs_EDGE) {
1028 SetErrorCode("Not an edge given for the axis");
1031 TopoDS_Edge anEdge = TopoDS::Edge(anAxis);
1032 TopoDS_Vertex V1, V2;
1033 TopExp::Vertices(anEdge, V1, V2, Standard_True);
1034 if (V1.IsNull() || V2.IsNull()) {
1035 SetErrorCode("Bad edge given for the axis");
1038 gp_Pnt aLoc = BRep_Tool::Pnt(V1);
1039 gp_Vec aVec (aLoc, BRep_Tool::Pnt(V2));
1040 if (aVec.Magnitude() < Precision::Confusion()) {
1041 SetErrorCode("Vector with null magnitude given");
1045 gp_Ax3 anAx3 (aLoc, aVec);
1046 return new Geom_CylindricalSurface(anAx3, theRadius);
1050 //=======================================================================
1051 //function : getShapesOnSurfaceIDs
1053 * \brief Find IDs of subshapes complying with given status about surface
1054 * \param theSurface - the surface to check state of subshapes against
1055 * \param theShape - the shape to explore
1056 * \param theShapeType - type of subshape of theShape
1057 * \param theState - required state
1058 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1060 //=======================================================================
1062 Handle(TColStd_HSequenceOfInteger)
1063 GEOMImpl_IShapesOperations::getShapesOnSurfaceIDs(const Handle(Geom_Surface)& theSurface,
1064 const TopoDS_Shape& theShape,
1065 TopAbs_ShapeEnum theShapeType,
1066 GEOMAlgo_State theState)
1068 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
1069 // MESSAGE("--------------------------- GetShapesOnPlane phase 1 takes:");
1070 // OSD_Timer timer1;
1073 // Check presence of triangulation, build if need
1074 if (!CheckTriangulation(theShape))
1078 GEOMAlgo_FinderShapeOn1 aFinder;
1079 Standard_Real aTol = 0.0001; // default value
1081 aFinder.SetShape(theShape);
1082 aFinder.SetTolerance(aTol);
1083 aFinder.SetSurface(theSurface);
1084 aFinder.SetShapeType(theShapeType);
1085 aFinder.SetState(theState);
1087 // Sets the minimal number of inner points for the faces that do not have own
1088 // inner points at all (for e.g. rectangular planar faces have just 2 triangles).
1090 aFinder.SetNbPntsMin(3);
1091 // Sets the maximal number of inner points for edges or faces.
1092 // It is usefull for the cases when this number is very big (e.g =2000) to improve
1093 // the performance. If this value =0, all inner points will be taken into account.
1095 aFinder.SetNbPntsMax(100);
1100 // MESSAGE("--------------------------- Perform on Plane takes:");
1107 // MESSAGE("--------------------------- GetShapesOnPlane phase 3 takes:");
1111 // Interprete results
1112 Standard_Integer iErr = aFinder.ErrorStatus();
1113 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
1115 MESSAGE(" iErr : " << iErr);
1116 TCollection_AsciiString aMsg (" iErr : ");
1117 aMsg += TCollection_AsciiString(iErr);
1121 Standard_Integer iWrn = aFinder.WarningStatus();
1122 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
1124 MESSAGE(" *** iWrn : " << iWrn);
1127 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
1129 if (listSS.Extent() < 1) {
1130 SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
1137 // MESSAGE("--------------------------- GetShapesOnPlane phase 4 takes:");
1141 // Fill sequence of object IDs
1142 aSeqOfIDs = new TColStd_HSequenceOfInteger;
1144 TopTools_IndexedMapOfShape anIndices;
1145 TopExp::MapShapes(theShape, anIndices);
1147 TopTools_ListIteratorOfListOfShape itSub (listSS);
1148 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
1149 int id = anIndices.FindIndex(itSub.Value());
1150 aSeqOfIDs->Append(id);
1157 //=======================================================================
1158 //function : getObjectsShapesOn
1160 * \brief Find shape objects and their entries by their ids
1161 * \param theShapeIDs - incoming shape ids
1162 * \param theShapeEntries - outgoing entries like "entry1, entry2, ..."
1163 * \retval Handle(TColStd_HSequenceOfTransient) - found shape objects
1165 //=======================================================================
1167 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::
1168 getObjectsShapesOn(const Handle(GEOM_Object)& theShape,
1169 const Handle(TColStd_HSequenceOfInteger)& theShapeIDs,
1170 TCollection_AsciiString & theShapeEntries)
1172 Handle(TColStd_HSequenceOfTransient) aSeq;
1174 if ( !theShapeIDs.IsNull() && theShapeIDs->Length() > 0 )
1176 aSeq = new TColStd_HSequenceOfTransient;
1177 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
1178 TCollection_AsciiString anEntry;
1179 for ( int i = 1; i <= theShapeIDs->Length(); ++i )
1181 anArray->SetValue(1, theShapeIDs->Value( i ));
1182 Handle(GEOM_Object) anObj = GetEngine()->AddSubShape(theShape, anArray);
1183 aSeq->Append( anObj );
1185 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
1186 if ( i != 1 ) theShapeEntries += ",";
1187 theShapeEntries += anEntry;
1193 //=======================================================================
1194 //function : getShapesOnSurface
1196 * \brief Find subshapes complying with given status about surface
1197 * \param theSurface - the surface to check state of subshapes against
1198 * \param theShape - the shape to explore
1199 * \param theShapeType - type of subshape of theShape
1200 * \param theState - required state
1201 * \param theShapeEntries - outgoing entries like "entry1, entry2, ..."
1202 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1204 //=======================================================================
1206 Handle(TColStd_HSequenceOfTransient)
1207 GEOMImpl_IShapesOperations::getShapesOnSurface(const Handle(Geom_Surface)& theSurface,
1208 const Handle(GEOM_Object)& theShape,
1209 TopAbs_ShapeEnum theShapeType,
1210 GEOMAlgo_State theState,
1211 TCollection_AsciiString & theShapeEntries)
1213 // Find subshapes ids
1214 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
1215 getShapesOnSurfaceIDs (theSurface, theShape->GetValue(), theShapeType, theState);
1216 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
1219 return getObjectsShapesOn( theShape, aSeqOfIDs, theShapeEntries );
1222 //=============================================================================
1226 //=============================================================================
1227 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnPlane
1228 (const Handle(GEOM_Object)& theShape,
1229 const Standard_Integer theShapeType,
1230 const Handle(GEOM_Object)& theAx1,
1231 const GEOMAlgo_State theState)
1235 // MESSAGE("--------------------------- GetShapesOnPlane phase 1 takes:");
1236 // OSD_Timer timer1;
1239 if (theShape.IsNull() || theAx1.IsNull()) return NULL;
1241 TopoDS_Shape aShape = theShape->GetValue();
1242 TopoDS_Shape anAx1 = theAx1->GetValue();
1244 if (aShape.IsNull() || anAx1.IsNull()) return NULL;
1246 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
1247 if ( !checkTypeShapesOn( theShapeType ))
1251 Handle(Geom_Surface) aPlane = makePlane( anAx1 );
1252 if ( aPlane.IsNull() )
1256 TCollection_AsciiString anAsciiList;
1257 Handle(TColStd_HSequenceOfTransient) aSeq;
1258 aSeq = getShapesOnSurface( aPlane, theShape, aShapeType, theState, anAsciiList );
1259 if ( aSeq.IsNull() || aSeq->Length() == 0 )
1265 // MESSAGE("--------------------------- GetShapesOnPlane phase 5 takes:");
1269 // Make a Python command
1271 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
1272 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1274 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
1275 << "] = geompy.GetShapesOnPlane(" << theShape << ", "
1276 << theShapeType << ", " << theAx1 << ", " << theState << ")";
1282 //=============================================================================
1284 * GetShapesOnCylinder
1286 //=============================================================================
1287 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnCylinder
1288 (const Handle(GEOM_Object)& theShape,
1289 const Standard_Integer theShapeType,
1290 const Handle(GEOM_Object)& theAxis,
1291 const Standard_Real theRadius,
1292 const GEOMAlgo_State theState)
1296 if (theShape.IsNull() || theAxis.IsNull()) return NULL;
1298 TopoDS_Shape aShape = theShape->GetValue();
1299 TopoDS_Shape anAxis = theAxis->GetValue();
1301 if (aShape.IsNull() || anAxis.IsNull()) return NULL;
1303 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
1304 if ( !checkTypeShapesOn( aShapeType ))
1307 // Create a cylinder surface
1308 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
1309 if ( aCylinder.IsNull() )
1313 TCollection_AsciiString anAsciiList;
1314 Handle(TColStd_HSequenceOfTransient) aSeq;
1315 aSeq = getShapesOnSurface( aCylinder, theShape, aShapeType, theState, anAsciiList );
1316 if ( aSeq.IsNull() || aSeq->Length() == 0 )
1319 // Make a Python command
1321 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
1322 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1324 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
1325 << "] = geompy.GetShapesOnCylinder(" << theShape << ", " << theShapeType
1326 << ", " << theAxis << ", " << theRadius << ", " << theState << ")";
1332 //=============================================================================
1336 //=============================================================================
1337 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnSphere
1338 (const Handle(GEOM_Object)& theShape,
1339 const Standard_Integer theShapeType,
1340 const Handle(GEOM_Object)& theCenter,
1341 const Standard_Real theRadius,
1342 const GEOMAlgo_State theState)
1346 if (theShape.IsNull() || theCenter.IsNull()) return NULL;
1348 TopoDS_Shape aShape = theShape->GetValue();
1349 TopoDS_Shape aCenter = theCenter->GetValue();
1351 if (aShape.IsNull() || aCenter.IsNull()) return NULL;
1353 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
1354 if ( !checkTypeShapesOn( aShapeType ))
1357 // Center of the sphere
1358 if (aCenter.ShapeType() != TopAbs_VERTEX) return NULL;
1359 gp_Pnt aLoc = BRep_Tool::Pnt(TopoDS::Vertex(aCenter));
1361 gp_Ax3 anAx3 (aLoc, gp::DZ());
1362 Handle(Geom_SphericalSurface) aSphere =
1363 new Geom_SphericalSurface(anAx3, theRadius);
1366 TCollection_AsciiString anAsciiList;
1367 Handle(TColStd_HSequenceOfTransient) aSeq;
1368 aSeq = getShapesOnSurface( aSphere, theShape, aShapeType, theState, anAsciiList );
1369 if ( aSeq.IsNull() || aSeq->Length() == 0 )
1372 // Make a Python command
1374 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
1375 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1377 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
1378 << "] = geompy.GetShapesOnSphere(" << theShape << ", " << theShapeType
1379 << ", " << theCenter << ", " << theRadius << ", " << theState << ")";
1384 //=============================================================================
1386 * GetShapesOnPlaneIDs
1388 //=============================================================================
1389 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnPlaneIDs
1390 (const Handle(GEOM_Object)& theShape,
1391 const Standard_Integer theShapeType,
1392 const Handle(GEOM_Object)& theAx1,
1393 const GEOMAlgo_State theState)
1397 if (theShape.IsNull() || theAx1.IsNull()) return NULL;
1399 TopoDS_Shape aShape = theShape->GetValue();
1400 TopoDS_Shape anAx1 = theAx1->GetValue();
1402 if (aShape.IsNull() || anAx1.IsNull()) return NULL;
1404 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
1405 if ( !checkTypeShapesOn( aShapeType ))
1409 Handle(Geom_Surface) aPlane = makePlane( anAx1 );
1410 if ( aPlane.IsNull() )
1414 Handle(TColStd_HSequenceOfInteger) aSeq;
1415 aSeq = getShapesOnSurfaceIDs( aPlane, aShape, aShapeType, theState );
1417 // The GetShapesOnPlaneIDs() doesn't change object so no new function is required.
1418 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
1420 // Make a Python command
1421 const bool append = true;
1422 GEOM::TPythonDump(aFunction,append)
1423 << "listShapesOnPlane = IShapesOperations.GetShapesOnPlaneIDs"
1424 << "(" << theShape << "," << theShapeType << "," << theAx1 << "," << theState << ")";
1430 //=============================================================================
1432 * GetShapesOnCylinderIDs
1434 //=============================================================================
1435 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnCylinderIDs
1436 (const Handle(GEOM_Object)& theShape,
1437 const Standard_Integer theShapeType,
1438 const Handle(GEOM_Object)& theAxis,
1439 const Standard_Real theRadius,
1440 const GEOMAlgo_State theState)
1444 if (theShape.IsNull() || theAxis.IsNull()) return NULL;
1446 TopoDS_Shape aShape = theShape->GetValue();
1447 TopoDS_Shape anAxis = theAxis->GetValue();
1449 if (aShape.IsNull() || anAxis.IsNull()) return NULL;
1451 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
1452 if ( !checkTypeShapesOn( aShapeType ))
1455 // Create a cylinder surface
1456 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
1457 if ( aCylinder.IsNull() )
1461 Handle(TColStd_HSequenceOfInteger) aSeq;
1462 aSeq = getShapesOnSurfaceIDs( aCylinder, aShape, aShapeType, theState );
1464 // The GetShapesOnCylinder() doesn't change object so no new function is required.
1465 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
1467 // Make a Python command
1468 const bool append = true;
1469 GEOM::TPythonDump(aFunction,append)
1470 << "listShapesOnCylinder = IShapesOperations.GetShapesOnCylinderIDs"
1471 << "(" << theShape << ", " << theShapeType << ", " << theAxis << ", "
1472 << theRadius << ", " << theState << ")";
1478 //=============================================================================
1480 * GetShapesOnSphereIDs
1482 //=============================================================================
1483 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnSphereIDs
1484 (const Handle(GEOM_Object)& theShape,
1485 const Standard_Integer theShapeType,
1486 const Handle(GEOM_Object)& theCenter,
1487 const Standard_Real theRadius,
1488 const GEOMAlgo_State theState)
1492 if (theShape.IsNull() || theCenter.IsNull()) return NULL;
1494 TopoDS_Shape aShape = theShape->GetValue();
1495 TopoDS_Shape aCenter = theCenter->GetValue();
1497 if (aShape.IsNull() || aCenter.IsNull()) return NULL;
1499 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
1500 if ( !checkTypeShapesOn( aShapeType ))
1503 // Center of the sphere
1504 if (aCenter.ShapeType() != TopAbs_VERTEX) return NULL;
1505 gp_Pnt aLoc = BRep_Tool::Pnt(TopoDS::Vertex(aCenter));
1507 gp_Ax3 anAx3 (aLoc, gp::DZ());
1508 Handle(Geom_SphericalSurface) aSphere =
1509 new Geom_SphericalSurface(anAx3, theRadius);
1512 Handle(TColStd_HSequenceOfInteger) aSeq;
1513 aSeq = getShapesOnSurfaceIDs( aSphere, aShape, aShapeType, theState );
1515 // The GetShapesOnSphere() doesn't change object so no new function is required.
1516 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
1518 // Make a Python command
1519 const bool append = true;
1520 GEOM::TPythonDump(aFunction,append)
1521 << "listShapesOnCylinder = IShapesOperations.GetShapesOnCylinderIDs"
1522 << "(" << theShape << ", " << theShapeType << ", " << theCenter << ", "
1523 << theRadius << ", " << theState << ")";
1529 //=======================================================================
1530 //function : getShapesOnQuadrangleIDs
1532 * \brief Find IDs of subshapes complying with given status about quadrangle
1533 * \param theShape - the shape to explore
1534 * \param theShapeType - type of subshape of theShape
1535 * \param theTopLeftPoint - top left quadrangle corner
1536 * \param theTopRigthPoint - top right quadrangle corner
1537 * \param theBottomLeftPoint - bottom left quadrangle corner
1538 * \param theBottomRigthPoint - bottom right quadrangle corner
1539 * \param theState - required state
1540 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1542 //=======================================================================
1544 Handle(TColStd_HSequenceOfInteger)
1545 GEOMImpl_IShapesOperations::getShapesOnQuadrangleIDs (const Handle(GEOM_Object)& theShape,
1546 const Standard_Integer theShapeType,
1547 const Handle(GEOM_Object)& theTopLeftPoint,
1548 const Handle(GEOM_Object)& theTopRigthPoint,
1549 const Handle(GEOM_Object)& theBottomLeftPoint,
1550 const Handle(GEOM_Object)& theBottomRigthPoint,
1551 const GEOMAlgo_State theState)
1555 if ( theShape.IsNull() ||
1556 theTopLeftPoint.IsNull() ||
1557 theTopRigthPoint.IsNull() ||
1558 theBottomLeftPoint.IsNull() ||
1559 theBottomRigthPoint.IsNull() )
1562 TopoDS_Shape aShape = theShape->GetValue();
1563 TopoDS_Shape aTL = theTopLeftPoint->GetValue();
1564 TopoDS_Shape aTR = theTopRigthPoint->GetValue();
1565 TopoDS_Shape aBL = theBottomLeftPoint->GetValue();
1566 TopoDS_Shape aBR = theBottomRigthPoint->GetValue();
1568 if (aShape.IsNull() ||
1573 aTL.ShapeType() != TopAbs_VERTEX ||
1574 aTR.ShapeType() != TopAbs_VERTEX ||
1575 aBL.ShapeType() != TopAbs_VERTEX ||
1576 aBR.ShapeType() != TopAbs_VERTEX )
1579 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
1580 if ( !checkTypeShapesOn( aShapeType ))
1583 vector< gp_Pnt > points(4);
1584 points[0] = BRep_Tool::Pnt(TopoDS::Vertex(aTL));
1585 points[1] = BRep_Tool::Pnt(TopoDS::Vertex(aTR));
1586 points[2] = BRep_Tool::Pnt(TopoDS::Vertex(aBR));
1587 points[3] = BRep_Tool::Pnt(TopoDS::Vertex(aBL));
1589 // Algo: for each pair of neighboring point of a quadrangle, make a plane
1590 // and find subshape indices having theState. Then
1591 // - for IN state, find indices common for all pairs.
1592 // - else, keep IDs that are OK for any plane
1593 const bool keepOkOnAllPlanes = ( theState == GEOMAlgo_ST_IN ||
1594 theState == GEOMAlgo_ST_ONIN ||
1595 theState == GEOMAlgo_ST_INOUT );
1597 // Find plane normal defined by corner points, it will be used to define a plane
1598 // for each pair of points. For that, find non coincident corner points
1599 vector< gp_Pnt > farPoints;
1600 farPoints.reserve( 5 );
1601 farPoints.push_back( points[0] );
1602 for ( int i = 1; i < 4; ++i )
1604 // check if i-th point is far from all farPoints
1605 bool tooClose = false;
1606 vector< gp_Pnt >::iterator p = farPoints.begin();
1607 for ( ; p != farPoints.end(); ++p )
1608 if ( p->SquareDistance( points[ i ]) <= DBL_MIN )
1611 farPoints.push_back( points[ i ]);
1613 if ( farPoints.size() < 3 ) {
1614 SetErrorCode("Coincident input points");
1618 gp_Vec( farPoints[0], farPoints[1] ) ^ gp_Vec( farPoints[0], farPoints[2] );
1619 //std::cout << " X Vec : " << aVecX.X() << " " <<aVecX.Y() << " " <<aVecX.Z() << " " << endl;
1621 // Use datamap to find IDs which have good state with all planes:
1622 // count nb of OK states for each ID
1623 TColStd_DataMapOfIntegerInteger nbOkStatesOfID;
1625 // loop on point pairs
1627 farPoints[ farPoints.size() ] = farPoints[ 0 ];
1628 for ( int i = 0; i < farPoints.size(); ++i )
1630 // point1 -> point2 vector
1631 gp_Vec aVecY( farPoints[ i ], farPoints[ i + 1 ]);
1632 //std::cout << " Y Vec : " << aVecY.X() << " " <<aVecY.Y() << " " <<aVecY.Z() << " " << endl;
1635 gp_Vec aVecZ = aVecX ^ aVecY;
1636 //std::cout << " Z Vec : " << aVecZ.X() << " " <<aVecZ.Y() << " " <<aVecZ.Z() << " " << endl;
1637 if ( aVecZ.SquareMagnitude() <= DBL_MIN )
1640 // Check that normal direction is outside a quadrangle
1641 // (Suppose there are no concave corners in a quadrangle)
1642 int iPrev = i ? i - 1 : farPoints.size() - 1;
1643 if ( aVecZ * gp_Vec( farPoints[ i ], farPoints[ iPrev ]) >= 0. )
1647 Handle(Geom_Plane) aPlane = new Geom_Plane( farPoints[ i ], aVecZ );
1649 // Find subshape indices
1650 Handle(TColStd_HSequenceOfInteger) aSeq;
1651 aSeq = getShapesOnSurfaceIDs( aPlane, aShape, aShapeType, theState );
1653 if ( aSeq.IsNull() || aSeq->Length() == 0 )
1655 if ( keepOkOnAllPlanes )
1660 // put IDs to the datamap
1661 //std::cout << " IDS in plane " << nbPlanes << " : ";
1662 for ( int iID = 1; iID <= aSeq->Length(); ++iID )
1664 int id = aSeq->Value( iID );
1665 //std::cout << id << " ";
1666 if ( nbOkStatesOfID.IsBound( id ))
1667 nbOkStatesOfID( id )++;
1669 nbOkStatesOfID.Bind( id, 1 );
1671 //std::cout << endl;
1675 // select IDs that are OK with all planes
1676 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
1677 TColStd_DataMapIteratorOfDataMapOfIntegerInteger id_nb;
1678 for ( id_nb.Initialize( nbOkStatesOfID ); id_nb.More(); id_nb.Next() )
1680 //std::cout << id_nb.Key() << " in " << id_nb.Value() << " planes " << endl;
1681 if ( !keepOkOnAllPlanes || id_nb.Value() == nbPlanes )
1682 aSeq->Append( id_nb.Key() );
1687 //=======================================================================
1688 //function : GetShapesOnQuadrangle
1690 * \brief Find subshapes complying with given status about quadrangle
1691 * \param theShape - the shape to explore
1692 * \param theShapeType - type of subshape of theShape
1693 * \param theTopLeftPoint - top left quadrangle corner
1694 * \param theTopRigthPoint - top right quadrangle corner
1695 * \param theBottomLeftPoint - bottom left quadrangle corner
1696 * \param theBottomRigthPoint - bottom right quadrangle corner
1697 * \param theState - required state
1698 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1700 //=======================================================================
1702 Handle(TColStd_HSequenceOfTransient)
1703 GEOMImpl_IShapesOperations::GetShapesOnQuadrangle (const Handle(GEOM_Object)& theShape,
1704 const Standard_Integer theShapeType,
1705 const Handle(GEOM_Object)& theTopLeftPoint,
1706 const Handle(GEOM_Object)& theTopRigthPoint,
1707 const Handle(GEOM_Object)& theBottomLeftPoint,
1708 const Handle(GEOM_Object)& theBottomRigthPoint,
1709 const GEOMAlgo_State theState)
1712 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
1713 getShapesOnQuadrangleIDs( theShape,
1718 theBottomRigthPoint,
1720 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->IsEmpty() )
1723 // Find objects by indices
1724 TCollection_AsciiString anAsciiList;
1725 Handle(TColStd_HSequenceOfTransient) aSeq;
1726 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
1727 if ( aSeq.IsNull() || aSeq->IsEmpty() )
1730 // Make a Python command
1732 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
1733 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1735 GEOM::TPythonDump(aFunction)
1736 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnQuadrangle("
1738 << theShapeType << ", "
1739 << theTopLeftPoint << ", "
1740 << theTopRigthPoint << ", "
1741 << theBottomLeftPoint << ", "
1742 << theBottomRigthPoint << ", "
1749 //=======================================================================
1750 //function : GetShapesOnQuadrangleIDs
1752 * \brief Find IDs of subshapes complying with given status about quadrangle
1753 * \param theShape - the shape to explore
1754 * \param theShapeType - type of subshape of theShape
1755 * \param theTopLeftPoint - top left quadrangle corner
1756 * \param theTopRigthPoint - top right quadrangle corner
1757 * \param theBottomLeftPoint - bottom left quadrangle corner
1758 * \param theBottomRigthPoint - bottom right quadrangle corner
1759 * \param theState - required state
1760 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1762 //=======================================================================
1764 Handle(TColStd_HSequenceOfInteger)
1765 GEOMImpl_IShapesOperations::GetShapesOnQuadrangleIDs (const Handle(GEOM_Object)& theShape,
1766 const Standard_Integer theShapeType,
1767 const Handle(GEOM_Object)& theTopLeftPoint,
1768 const Handle(GEOM_Object)& theTopRigthPoint,
1769 const Handle(GEOM_Object)& theBottomLeftPoint,
1770 const Handle(GEOM_Object)& theBottomRigthPoint,
1771 const GEOMAlgo_State theState)
1774 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
1775 getShapesOnQuadrangleIDs( theShape,
1780 theBottomRigthPoint,
1782 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->IsEmpty() )
1785 // Make a Python command
1787 // The GetShapesOnCylinder() doesn't change object so no new function is required.
1788 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
1790 const bool append = true;
1791 GEOM::TPythonDump(aFunction,append)
1792 << "listShapesOnQuadrangle = geompy.GetShapesOnQuadrangleIDs("
1794 << theShapeType << ", "
1795 << theTopLeftPoint << ", "
1796 << theTopRigthPoint << ", "
1797 << theBottomLeftPoint << ", "
1798 << theBottomRigthPoint << ", "
1806 //=============================================================================
1810 //=============================================================================
1811 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlace
1812 (Handle(GEOM_Object) theShapeWhere,
1813 Handle(GEOM_Object) theShapeWhat)
1817 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
1819 TopoDS_Shape aWhere = theShapeWhere->GetValue();
1820 TopoDS_Shape aWhat = theShapeWhat->GetValue();
1822 if (aWhere.IsNull() || aWhat.IsNull()) return NULL;
1824 //Fill array of indices
1825 Handle(TColStd_HArray1OfInteger) aModifiedArray;
1827 Handle(GEOM_Function) aWhereFunction = theShapeWhere->GetLastFunction();
1829 TopTools_IndexedMapOfShape aWhereIndices;
1830 TopExp::MapShapes(aWhere, aWhereIndices);
1832 if (aWhereIndices.Contains(aWhat)) {
1834 // entity was not changed by the operation
1835 Standard_Integer aWhatIndex = aWhereIndices.FindIndex(aWhat);
1836 aModifiedArray = new TColStd_HArray1OfInteger(1,1);
1837 aModifiedArray->SetValue(1, aWhatIndex);
1841 TDF_Label aHistoryLabel = aWhereFunction->GetHistoryEntry(Standard_False);
1842 if (aHistoryLabel.IsNull()) {
1843 SetErrorCode("Modifications history does not exist for the shape under consideration.");
1847 // search in history for all argument shapes
1848 Standard_Boolean isFound = Standard_False;
1850 TDF_LabelSequence aLabelSeq;
1851 aWhereFunction->GetDependency(aLabelSeq);
1852 Standard_Integer nbArg = aLabelSeq.Length();
1854 for (Standard_Integer iarg = 1; iarg <= nbArg && !isFound; iarg++) {
1856 TDF_Label anArgumentRefLabel = aLabelSeq.Value(iarg);
1858 Handle(GEOM_Object) anArgumentObject = GEOM_Object::GetReferencedObject(anArgumentRefLabel);
1859 TopoDS_Shape anArgumentShape = anArgumentObject->GetValue();
1861 TopTools_IndexedMapOfShape anArgumentIndices;
1862 TopExp::MapShapes(anArgumentShape, anArgumentIndices);
1864 if (anArgumentIndices.Contains(aWhat)) {
1865 isFound = Standard_True;
1866 Standard_Integer aWhatIndex = anArgumentIndices.FindIndex(aWhat);
1868 // Find corresponding label in history
1869 TDF_Label anArgumentHistoryLabel =
1870 aWhereFunction->GetArgumentHistoryEntry(anArgumentRefLabel, Standard_False);
1871 if (anArgumentHistoryLabel.IsNull()) {
1872 // Lost History of operation argument. Possibly, all its entities was removed.
1877 TDF_Label aWhatHistoryLabel = anArgumentHistoryLabel.FindChild(aWhatIndex, Standard_False);
1878 if (aWhatHistoryLabel.IsNull()) {
1884 Handle(TDataStd_IntegerArray) anIntegerArray;
1885 if (!aWhatHistoryLabel.FindAttribute(TDataStd_IntegerArray::GetID(), anIntegerArray)) {
1886 SetErrorCode("Error: Empty modifications history for the sought shape.");
1890 aModifiedArray = anIntegerArray->Array();
1891 if (aModifiedArray->Length() == 0) {
1892 SetErrorCode("Error: Empty modifications history for the sought shape.");
1899 SetErrorCode("The sought shape does not belong to any operation argument.");
1905 Handle(GEOM_Object) aResult = GetEngine()->AddSubShape(theShapeWhere, aModifiedArray);
1907 if (aModifiedArray->Length() > 1) {
1909 aResult->SetType(GEOM_GROUP);
1911 //Set a sub shape type
1912 TDF_Label aFreeLabel = aResult->GetFreeLabel();
1913 TopAbs_ShapeEnum aShapeType = aWhat.ShapeType();
1914 TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aShapeType);
1917 //Make a Python command
1918 Handle(GEOM_Function) aFunction = aResult->GetFunction(1);
1920 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetInPlace("
1921 << theShapeWhere << ", " << theShapeWhat << ")";
1927 //=======================================================================
1928 //function : SortShapes
1930 //=======================================================================
1931 void GEOMImpl_IShapesOperations::SortShapes(TopTools_ListOfShape& SL)
1933 Standard_Integer MaxShapes = SL.Extent();
1934 TopTools_Array1OfShape aShapes (1,MaxShapes);
1935 TColStd_Array1OfInteger OrderInd(1,MaxShapes);
1936 TColStd_Array1OfReal MidXYZ (1,MaxShapes); //X,Y,Z;
1937 TColStd_Array1OfReal Length (1,MaxShapes); //X,Y,Z;
1939 // Computing of CentreOfMass
1940 Standard_Integer Index;
1943 TopTools_ListIteratorOfListOfShape it(SL);
1944 for (Index=1; it.More(); Index++)
1946 TopoDS_Shape S = it.Value();
1947 SL.Remove( it ); // == it.Next()
1949 OrderInd.SetValue (Index, Index);
1950 if (S.ShapeType() == TopAbs_VERTEX)
1952 GPoint = BRep_Tool::Pnt( TopoDS::Vertex( S ));
1953 Length.SetValue( Index, (Standard_Real) S.Orientation());
1957 BRepGProp::LinearProperties (S, GPr);
1958 GPoint = GPr.CentreOfMass();
1959 Length.SetValue( Index, GPr.Mass() );
1961 MidXYZ.SetValue(Index,
1962 GPoint.X()*999 + GPoint.Y()*99 + GPoint.Z()*0.9);
1965 Standard_Integer aTemp;
1966 Standard_Boolean exchange, Sort = Standard_True;
1969 Sort = Standard_False;
1970 for (Index=1; Index < MaxShapes; Index++)
1972 if (MidXYZ(OrderInd(Index)) > MidXYZ(OrderInd(Index+1)))
1973 exchange = Standard_True;
1974 else if (MidXYZ(OrderInd(Index)) == MidXYZ(OrderInd(Index+1)) &&
1975 Length(OrderInd(Index)) > Length(OrderInd(Index+1)) )
1976 exchange = Standard_True;
1978 exchange = Standard_False;
1981 aTemp = OrderInd(Index);
1982 OrderInd(Index) = OrderInd(Index+1);
1983 OrderInd(Index+1) = aTemp;
1984 Sort = Standard_True;
1988 for (Index=1; Index <= MaxShapes; Index++)
1989 SL.Append( aShapes( OrderInd(Index) ));
1992 //=======================================================================
1993 //function : CheckTriangulation
1995 //=======================================================================
1996 bool GEOMImpl_IShapesOperations::CheckTriangulation (const TopoDS_Shape& aShape)
1998 // MESSAGE("CheckTriangulation");
2000 // OSD_Timer timer1;
2003 TopExp_Explorer exp (aShape, TopAbs_FACE);
2005 SetErrorCode("Shape without faces given");
2009 TopLoc_Location aTopLoc;
2010 Handle(Poly_Triangulation) aTRF;
2011 aTRF = BRep_Tool::Triangulation(TopoDS::Face(exp.Current()), aTopLoc);
2012 if (aTRF.IsNull()) {
2013 // calculate deflection
2014 Standard_Real aDeviationCoefficient = 0.001;
2017 BRepBndLib::Add(aShape, B);
2018 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
2019 B.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
2021 Standard_Real dx = aXmax - aXmin, dy = aYmax - aYmin, dz = aZmax - aZmin;
2022 Standard_Real aDeflection = Max(Max(dx, dy), dz) * aDeviationCoefficient * 4;
2024 // MESSAGE("Deflection = " << aDeflection);
2026 Standard_Real aHLRAngle = 0.349066;
2028 BRepMesh_IncrementalMesh Inc (aShape, aDeflection, Standard_False, aHLRAngle);