1 // Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
2 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License.
9 // This library is distributed in the hope that it will be useful
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // Lesser General Public License for more details.
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 // See http://www.salome-platform.org/
20 #include <Standard_Stream.hxx>
22 #include "GEOMImpl_IShapesOperations.hxx"
24 #include "GEOMImpl_Types.hxx"
26 #include "GEOMImpl_VectorDriver.hxx"
27 #include "GEOMImpl_ShapeDriver.hxx"
28 #include "GEOMImpl_CopyDriver.hxx"
29 #include "GEOMImpl_GlueDriver.hxx"
31 #include "GEOMImpl_IVector.hxx"
32 #include "GEOMImpl_IShapes.hxx"
33 #include "GEOMImpl_IGlue.hxx"
35 #include "GEOMImpl_Block6Explorer.hxx"
37 #include "GEOM_Function.hxx"
38 #include "GEOM_PythonDump.hxx"
40 #include "GEOMAlgo_FinderShapeOn1.hxx"
41 #include "GEOMAlgo_FinderShapeOnQuad.hxx"
43 #include "utilities.h"
45 #include "Utils_ExceptHandlers.hxx"
47 #include <TFunction_DriverTable.hxx>
48 #include <TFunction_Driver.hxx>
49 #include <TFunction_Logbook.hxx>
50 #include <TDataStd_Integer.hxx>
51 #include <TDataStd_IntegerArray.hxx>
52 #include <TDF_Tool.hxx>
54 #include <BRepExtrema_ExtCF.hxx>
56 #include <BRep_Tool.hxx>
57 #include <BRepGProp.hxx>
58 #include <BRepAdaptor_Curve.hxx>
59 #include <BRepBndLib.hxx>
60 #include <BRepBuilderAPI_MakeFace.hxx>
61 #include <BRepMesh_IncrementalMesh.hxx>
66 #include <TopoDS_Shape.hxx>
67 #include <TopoDS_Face.hxx>
68 #include <TopoDS_Edge.hxx>
69 #include <TopoDS_Vertex.hxx>
70 #include <TopoDS_Iterator.hxx>
71 #include <TopExp_Explorer.hxx>
72 #include <TopLoc_Location.hxx>
73 #include <TopTools_MapOfShape.hxx>
74 #include <TopTools_Array1OfShape.hxx>
75 #include <TopTools_ListIteratorOfListOfShape.hxx>
76 #include <TopTools_IndexedMapOfShape.hxx>
78 #include <Geom_Surface.hxx>
79 #include <Geom_Plane.hxx>
80 #include <Geom_SphericalSurface.hxx>
81 #include <Geom_CylindricalSurface.hxx>
82 #include <GeomAdaptor_Surface.hxx>
84 #include <Geom2d_Curve.hxx>
86 #include <Bnd_Box.hxx>
87 #include <GProp_GProps.hxx>
90 #include <TColStd_Array1OfReal.hxx>
91 #include <TColStd_HArray1OfInteger.hxx>
96 //#include <OSD_Timer.hxx>
98 #include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
100 //=============================================================================
104 //=============================================================================
105 GEOMImpl_IShapesOperations::GEOMImpl_IShapesOperations (GEOM_Engine* theEngine, int theDocID)
106 : GEOM_IOperations(theEngine, theDocID)
108 MESSAGE("GEOMImpl_IShapesOperations::GEOMImpl_IShapesOperations");
111 //=============================================================================
115 //=============================================================================
116 GEOMImpl_IShapesOperations::~GEOMImpl_IShapesOperations()
118 MESSAGE("GEOMImpl_IShapesOperations::~GEOMImpl_IShapesOperations");
122 //=============================================================================
126 //=============================================================================
127 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeEdge
128 (Handle(GEOM_Object) thePnt1, Handle(GEOM_Object) thePnt2)
132 if (thePnt1.IsNull() || thePnt2.IsNull()) return NULL;
134 //Add a new Edge object
135 Handle(GEOM_Object) anEdge = GetEngine()->AddObject(GetDocID(), GEOM_EDGE);
137 //Add a new Vector function
138 Handle(GEOM_Function) aFunction =
139 anEdge->AddFunction(GEOMImpl_VectorDriver::GetID(), VECTOR_TWO_PNT);
141 //Check if the function is set correctly
142 if (aFunction->GetDriverGUID() != GEOMImpl_VectorDriver::GetID()) return NULL;
144 GEOMImpl_IVector aPI (aFunction);
146 Handle(GEOM_Function) aRef1 = thePnt1->GetLastFunction();
147 Handle(GEOM_Function) aRef2 = thePnt2->GetLastFunction();
148 if (aRef1.IsNull() || aRef2.IsNull()) return NULL;
150 aPI.SetPoint1(aRef1);
151 aPI.SetPoint2(aRef2);
153 //Compute the Edge value
155 if (!GetSolver()->ComputeFunction(aFunction)) {
156 SetErrorCode("Vector driver failed");
160 catch (Standard_Failure) {
161 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
162 SetErrorCode(aFail->GetMessageString());
166 //Make a Python command
167 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdge("
168 << thePnt1 << ", " << thePnt2 << ")";
174 //=============================================================================
178 //=============================================================================
179 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeWire
180 (list<Handle(GEOM_Object)> theShapes)
182 return MakeShape(theShapes, GEOM_WIRE, WIRE_EDGES, "MakeWire");
185 //=============================================================================
189 //=============================================================================
190 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFace (Handle(GEOM_Object) theWire,
191 const bool isPlanarWanted)
195 if (theWire.IsNull()) return NULL;
197 //Add a new Face object
198 Handle(GEOM_Object) aFace = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
200 //Add a new Shape function for creation of a face from a wire
201 Handle(GEOM_Function) aFunction =
202 aFace->AddFunction(GEOMImpl_ShapeDriver::GetID(), FACE_WIRE);
203 if (aFunction.IsNull()) return NULL;
205 //Check if the function is set correctly
206 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
208 GEOMImpl_IShapes aCI (aFunction);
210 Handle(GEOM_Function) aRefWire = theWire->GetLastFunction();
212 if (aRefWire.IsNull()) return NULL;
214 aCI.SetBase(aRefWire);
215 aCI.SetIsPlanar(isPlanarWanted);
217 //Compute the Face value
219 if (!GetSolver()->ComputeFunction(aFunction)) {
220 SetErrorCode("Shape driver failed to compute a face");
224 catch (Standard_Failure) {
225 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
226 SetErrorCode(aFail->GetMessageString());
230 //Make a Python command
231 GEOM::TPythonDump(aFunction) << aFace << " = geompy.MakeFace("
232 << theWire << ", " << (int)isPlanarWanted << ")";
238 //=============================================================================
242 //=============================================================================
243 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFaceWires
244 (list<Handle(GEOM_Object)> theShapes,
245 const bool isPlanarWanted)
250 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
253 Handle(GEOM_Function) aFunction =
254 aShape->AddFunction(GEOMImpl_ShapeDriver::GetID(), FACE_WIRES);
255 if (aFunction.IsNull()) return NULL;
257 //Check if the function is set correctly
258 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
260 GEOMImpl_IShapes aCI (aFunction);
262 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
265 list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
266 for (; it != theShapes.end(); it++) {
267 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
268 if (aRefSh.IsNull()) {
269 SetErrorCode("NULL argument shape for the face construction");
272 aShapesSeq->Append(aRefSh);
274 aCI.SetShapes(aShapesSeq);
276 aCI.SetIsPlanar(isPlanarWanted);
280 if (!GetSolver()->ComputeFunction(aFunction)) {
281 SetErrorCode("Shape driver failed");
285 catch (Standard_Failure) {
286 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
287 SetErrorCode(aFail->GetMessageString());
291 //Make a Python command
292 GEOM::TPythonDump pd (aFunction);
293 pd << aShape << " = geompy.MakeFaceWires([";
296 it = theShapes.begin();
297 if (it != theShapes.end()) {
299 while (it != theShapes.end()) {
300 pd << ", " << (*it++);
303 pd << "], " << (int)isPlanarWanted << ")";
309 //=============================================================================
313 //=============================================================================
314 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeShell
315 (list<Handle(GEOM_Object)> theShapes)
317 return MakeShape(theShapes, GEOM_SHELL, SHELL_FACES, "MakeShell");
320 //=============================================================================
324 //=============================================================================
325 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeSolidShells
326 (list<Handle(GEOM_Object)> theShapes)
328 return MakeShape(theShapes, GEOM_SOLID, SOLID_SHELLS, "MakeSolidShells");
331 //=============================================================================
335 //=============================================================================
336 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeSolidShell (Handle(GEOM_Object) theShell)
340 if (theShell.IsNull()) return NULL;
342 //Add a new Solid object
343 Handle(GEOM_Object) aSolid = GetEngine()->AddObject(GetDocID(), GEOM_SOLID);
345 //Add a new Solid function for creation of a solid from a shell
346 Handle(GEOM_Function) aFunction =
347 aSolid->AddFunction(GEOMImpl_ShapeDriver::GetID(), SOLID_SHELL);
348 if (aFunction.IsNull()) return NULL;
350 //Check if the function is set correctly
351 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
353 GEOMImpl_IShapes aCI (aFunction);
355 Handle(GEOM_Function) aRefShell = theShell->GetLastFunction();
357 if (aRefShell.IsNull()) return NULL;
359 aCI.SetBase(aRefShell);
361 //Compute the Solid value
363 if (!GetSolver()->ComputeFunction(aFunction)) {
364 SetErrorCode("Solid driver failed");
368 catch (Standard_Failure) {
369 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
370 SetErrorCode(aFail->GetMessageString());
374 //Make a Python command
375 GEOM::TPythonDump(aFunction) << aSolid
376 << " = geompy.MakeSolid(" << theShell << ")";
382 //=============================================================================
386 //=============================================================================
387 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeCompound
388 (list<Handle(GEOM_Object)> theShapes)
390 return MakeShape(theShapes, GEOM_COMPOUND, COMPOUND_SHAPES, "MakeCompound");
393 //=============================================================================
397 //=============================================================================
398 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeShape
399 (list<Handle(GEOM_Object)> theShapes,
400 const Standard_Integer theObjectType,
401 const Standard_Integer theFunctionType,
402 const TCollection_AsciiString& theMethodName)
407 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), theObjectType);
410 Handle(GEOM_Function) aFunction =
411 aShape->AddFunction(GEOMImpl_ShapeDriver::GetID(), theFunctionType);
412 if (aFunction.IsNull()) return NULL;
414 //Check if the function is set correctly
415 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
417 GEOMImpl_IShapes aCI (aFunction);
419 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
422 list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
423 for (; it != theShapes.end(); it++) {
424 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
425 if (aRefSh.IsNull()) {
426 SetErrorCode("NULL argument shape for the shape construction");
429 aShapesSeq->Append(aRefSh);
431 aCI.SetShapes(aShapesSeq);
435 if (!GetSolver()->ComputeFunction(aFunction)) {
436 SetErrorCode("Shape driver failed");
440 catch (Standard_Failure) {
441 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
442 SetErrorCode(aFail->GetMessageString());
446 //Make a Python command
447 GEOM::TPythonDump pd (aFunction);
448 pd << aShape << " = geompy." << theMethodName.ToCString() << "([";
451 it = theShapes.begin();
452 if (it != theShapes.end()) {
454 while (it != theShapes.end()) {
455 pd << ", " << (*it++);
464 //=============================================================================
468 //=============================================================================
469 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeGlueFaces
470 (Handle(GEOM_Object) theShape,
471 const Standard_Real theTolerance)
475 if (theShape.IsNull()) return NULL;
477 //Add a new Glued object
478 Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
480 //Add a new Glue function
481 Handle(GEOM_Function) aFunction;
482 aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_FACES);
483 if (aFunction.IsNull()) return NULL;
485 //Check if the function is set correctly
486 if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
488 GEOMImpl_IGlue aCI (aFunction);
490 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
491 if (aRefShape.IsNull()) return NULL;
493 aCI.SetBase(aRefShape);
494 aCI.SetTolerance(theTolerance);
496 //Compute the sub-shape value
497 Standard_Boolean isWarning = Standard_False;
499 if (!GetSolver()->ComputeFunction(aFunction)) {
500 SetErrorCode("Shape driver failed to glue faces");
504 catch (Standard_Failure) {
505 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
506 SetErrorCode(aFail->GetMessageString());
507 // to provide warning
508 if (!aFunction->GetValue().IsNull()) {
509 isWarning = Standard_True;
515 //Make a Python command
516 GEOM::TPythonDump(aFunction) << aGlued << " = geompy.MakeGlueFaces("
517 << theShape << ", " << theTolerance << ")";
519 // to provide warning
520 if (!isWarning) SetErrorCode(OK);
524 //=============================================================================
528 //=============================================================================
529 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::MakeExplode
530 (Handle(GEOM_Object) theShape,
531 const Standard_Integer theShapeType,
532 const Standard_Boolean isSorted)
534 // OSD_Timer timer1, timer2, timer3, timer4;
539 if (theShape.IsNull()) return NULL;
540 TopoDS_Shape aShape = theShape->GetValue();
541 if (aShape.IsNull()) return NULL;
543 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
544 Handle(GEOM_Object) anObj;
545 Handle(GEOM_Function) aFunction;
546 TopTools_MapOfShape mapShape;
547 TopTools_ListOfShape listShape;
549 if (aShape.ShapeType() == TopAbs_COMPOUND &&
550 (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
551 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPSOLID ||
552 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPOUND)) {
553 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
554 for (; It.More(); It.Next()) {
555 if (mapShape.Add(It.Value())) {
556 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
557 TopAbs_ShapeEnum(theShapeType) == It.Value().ShapeType()) {
558 listShape.Append(It.Value());
563 TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
564 for (; exp.More(); exp.Next())
565 if (mapShape.Add(exp.Current()))
566 listShape.Append(exp.Current());
569 if (listShape.IsEmpty()) {
570 SetErrorCode("The given shape has no sub-shapes of the requested type");
578 SortShapes(listShape);
583 TopTools_IndexedMapOfShape anIndices;
584 TopExp::MapShapes(aShape, anIndices);
585 Handle(TColStd_HArray1OfInteger) anArray;
587 TopTools_ListIteratorOfListOfShape itSub (listShape);
588 TCollection_AsciiString anAsciiList, anEntry;
589 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
590 TopoDS_Shape aValue = itSub.Value();
591 anArray = new TColStd_HArray1OfInteger(1,1);
592 anArray->SetValue(1, anIndices.FindIndex(aValue));
593 anObj = GetEngine()->AddSubShape(theShape, anArray);
596 // for python command
597 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
598 anAsciiList += anEntry;
602 //Make a Python command
603 anAsciiList.Trunc(anAsciiList.Length() - 1);
605 aFunction = theShape->GetLastFunction();
606 TCollection_AsciiString anOldDescr = aFunction->GetDescription();
608 GEOM::TPythonDump pd (aFunction);
609 pd << anOldDescr.ToCString() << "\n\t[" << anAsciiList.ToCString();
610 pd << "] = geompy.SubShapeAll" << (isSorted ? "Sorted(" : "(");
611 pd << theShape << ", " << theShapeType << ")";
617 // cout << "Explosure takes:" << endl;
619 // cout << "Sorting takes:" << endl;
621 // cout << "Sub-shapes addition takes:" << endl;
623 // cout << "Update Description takes:" << endl;
629 //=============================================================================
633 //=============================================================================
634 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::SubShapeAllIDs
635 (Handle(GEOM_Object) theShape,
636 const Standard_Integer theShapeType,
637 const Standard_Boolean isSorted)
641 if (theShape.IsNull()) return NULL;
642 TopoDS_Shape aShape = theShape->GetValue();
643 if (aShape.IsNull()) return NULL;
645 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
646 TopTools_MapOfShape mapShape;
647 TopTools_ListOfShape listShape;
649 if (aShape.ShapeType() == TopAbs_COMPOUND &&
650 (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
651 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPSOLID ||
652 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPOUND)) {
653 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
654 for (; It.More(); It.Next()) {
655 if (mapShape.Add(It.Value())) {
656 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
657 TopAbs_ShapeEnum(theShapeType) == It.Value().ShapeType()) {
658 listShape.Append(It.Value());
663 TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
664 for (; exp.More(); exp.Next())
665 if (mapShape.Add(exp.Current()))
666 listShape.Append(exp.Current());
669 if (listShape.IsEmpty()) {
670 SetErrorCode("The given shape has no sub-shapes of the requested type");
675 SortShapes(listShape);
677 TopTools_IndexedMapOfShape anIndices;
678 TopExp::MapShapes(aShape, anIndices);
679 Handle(TColStd_HArray1OfInteger) anArray;
681 TopTools_ListIteratorOfListOfShape itSub (listShape);
682 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
683 TopoDS_Shape aValue = itSub.Value();
684 aSeq->Append(anIndices.FindIndex(aValue));
687 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
688 TCollection_AsciiString anOldDescr = aFunction->GetDescription();
690 //Make a Python command
691 GEOM::TPythonDump pd (aFunction);
692 pd << anOldDescr.ToCString() << "\n\tlistSubShapeIDs = geompy.SubShapeAll";
693 pd << (isSorted ? "SortedIDs(" : "IDs(");
694 pd << theShape << ", " << theShapeType << ")";
700 //=============================================================================
704 //=============================================================================
705 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetSubShape
706 (Handle(GEOM_Object) theMainShape,
707 const Standard_Integer theID)
711 if (theMainShape.IsNull()) return NULL;
713 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
714 anArray->SetValue(1, theID);
715 Handle(GEOM_Object) anObj = GetEngine()->AddSubShape(theMainShape, anArray,true);
716 if (anObj.IsNull()) {
717 SetErrorCode("Can not get a sub-shape with the given ID");
721 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
723 //Make a Python command
724 GEOM::TPythonDump(aFunction) << anObj << " = geompy.GetSubShape("
725 << theMainShape << ", [" << theID << "])";
732 //=============================================================================
736 //=============================================================================
737 Standard_Integer GEOMImpl_IShapesOperations::NumberOfFaces (Handle(GEOM_Object) theShape)
741 Standard_Integer nb = 0;
743 if (theShape.IsNull()) return -1;
744 TopoDS_Shape aShape = theShape->GetValue();
745 if (aShape.IsNull()) return -1;
747 TopTools_MapOfShape mapShape;
749 TopExp_Explorer exp (aShape, TopAbs_FACE);
750 for (; exp.More(); exp.Next())
751 if (mapShape.Add(exp.Current()))
758 //=============================================================================
762 //=============================================================================
763 Standard_Integer GEOMImpl_IShapesOperations::NumberOfEdges (Handle(GEOM_Object) theShape)
767 Standard_Integer nb = 0;
769 if (theShape.IsNull()) return -1;
770 TopoDS_Shape aShape = theShape->GetValue();
771 if (aShape.IsNull()) return -1;
773 TopTools_MapOfShape mapShape;
775 TopExp_Explorer exp (aShape, TopAbs_EDGE);
776 for (; exp.More(); exp.Next())
777 if (mapShape.Add(exp.Current()))
784 //=============================================================================
788 //=============================================================================
789 Handle(GEOM_Object) GEOMImpl_IShapesOperations::ReverseShape(Handle(GEOM_Object) theShape)
793 if (theShape.IsNull()) return NULL;
795 //Add a new reversed object
796 Handle(GEOM_Object) aReversed = GetEngine()->AddObject(GetDocID(), theShape->GetType());
798 //Add a new Revese function
799 Handle(GEOM_Function) aFunction;
800 aFunction = aReversed->AddFunction(GEOMImpl_ShapeDriver::GetID(), REVERSE_ORIENTATION);
801 if (aFunction.IsNull()) return NULL;
803 //Check if the function is set correctly
804 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
806 GEOMImpl_IShapes aSI (aFunction);
808 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
809 if (aRefShape.IsNull()) return NULL;
811 aSI.SetBase(aRefShape);
813 //Compute the sub-shape value
815 if (!GetSolver()->ComputeFunction(aFunction)) {
816 SetErrorCode("Shape driver failed to reverse shape");
820 catch (Standard_Failure) {
821 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
822 SetErrorCode(aFail->GetMessageString());
826 //Make a Python command
827 GEOM::TPythonDump(aFunction) << aReversed
828 << " = geompy.ChangeOrientation(" << theShape << ")";
834 //=============================================================================
838 //=============================================================================
839 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetFreeFacesIDs
840 (Handle(GEOM_Object) theShape)
844 if (theShape.IsNull()) return NULL;
845 TopoDS_Shape aShape = theShape->GetValue();
846 if (aShape.IsNull()) return NULL;
848 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
850 TopTools_IndexedDataMapOfShapeListOfShape mapFaceBlocks;
851 GEOMImpl_Block6Explorer::MapShapesAndAncestors
852 (aShape, TopAbs_FACE, TopAbs_SOLID, mapFaceBlocks);
854 Standard_Integer ind = 1, nbFaces = mapFaceBlocks.Extent();
857 SetErrorCode("The given shape has no faces");
861 TopTools_IndexedMapOfShape anIndices;
862 TopExp::MapShapes(aShape, anIndices);
865 for (; ind <= nbFaces; ind++) {
866 if (mapFaceBlocks.FindFromIndex(ind).Extent() != 2) {
867 id = anIndices.FindIndex(mapFaceBlocks.FindKey(ind));
872 //The explode doesn't change object so no new function is required.
873 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
874 TCollection_AsciiString anOldDescr = aFunction->GetDescription();
876 //Make a Python command
877 GEOM::TPythonDump(aFunction) << anOldDescr.ToCString()
878 << "\n\tlistFreeFacesIDs = geompy.GetFreeFacesIDs(" << theShape << ")";
884 //=======================================================================
885 //function : GetSharedShapes
887 //=======================================================================
889 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetSharedShapes
890 (Handle(GEOM_Object) theShape1,
891 Handle(GEOM_Object) theShape2,
892 const Standard_Integer theShapeType)
896 if (theShape1.IsNull() || theShape2.IsNull()) return NULL;
898 TopoDS_Shape aShape1 = theShape1->GetValue();
899 TopoDS_Shape aShape2 = theShape2->GetValue();
901 if (aShape1.IsNull() || aShape2.IsNull()) return NULL;
903 TopTools_IndexedMapOfShape anIndices;
904 TopExp::MapShapes(aShape1, anIndices);
905 Handle(TColStd_HArray1OfInteger) anArray;
907 TopTools_IndexedMapOfShape mapShape1;
908 TopExp::MapShapes(aShape1, TopAbs_ShapeEnum(theShapeType), mapShape1);
910 Handle(GEOM_Object) anObj;
911 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
912 TCollection_AsciiString anAsciiList, anEntry;
914 TopTools_MapOfShape mapShape2;
915 TopExp_Explorer exp (aShape2, TopAbs_ShapeEnum(theShapeType));
916 for (; exp.More(); exp.Next()) {
917 TopoDS_Shape aSS = exp.Current();
918 if (mapShape2.Add(aSS) && mapShape1.Contains(aSS)) {
919 anArray = new TColStd_HArray1OfInteger(1,1);
920 anArray->SetValue(1, anIndices.FindIndex(aSS));
921 anObj = GetEngine()->AddSubShape(theShape1, anArray);
924 // for python command
925 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
926 anAsciiList += anEntry;
931 if (aSeq->IsEmpty()) {
932 SetErrorCode("The given shapes have no shared sub-shapes of the requested type");
936 //Make a Python command
937 anAsciiList.Trunc(anAsciiList.Length() - 1);
939 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
941 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
942 << "] = geompy.GetSharedShapes(" << theShape1 << ", "
943 << theShape2 << ", " << theShapeType << ")";
949 //=============================================================================
953 //=============================================================================
954 static GEOM::TPythonDump& operator<< (GEOM::TPythonDump& theDump,
955 const GEOMAlgo_State theState)
959 theDump << "geompy.GEOM.ST_IN";
961 case GEOMAlgo_ST_OUT:
962 theDump << "geompy.GEOM.ST_OUT";
965 theDump << "geompy.GEOM.ST_ON";
967 case GEOMAlgo_ST_ONIN:
968 theDump << "geompy.GEOM.ST_ONIN";
970 case GEOMAlgo_ST_ONOUT:
971 theDump << "geompy.GEOM.ST_ONOUT";
974 theDump << "geompy.GEOM.ST_UNKNOWN";
980 //=======================================================================
981 //function : checkTypeShapesOn
983 * \brief Checks if theShapeType parameter of GetShapesOnXXX() is OK
984 * \param theShapeType - the shape type to check
985 * \retval bool - result of the check
987 //=======================================================================
989 bool GEOMImpl_IShapesOperations::checkTypeShapesOn(const Standard_Integer theShapeType)
991 if (theShapeType != TopAbs_VERTEX &&
992 theShapeType != TopAbs_EDGE &&
993 theShapeType != TopAbs_FACE &&
994 theShapeType != TopAbs_SOLID) {
995 SetErrorCode("Only solids, vertices, edges or faces can be found by this method");
1001 //=======================================================================
1002 //function : makePlane
1004 * \brief Creates Geom_Plane
1005 * \param theAx1 - shape object defining plane parameters
1006 * \retval Handle(Geom_Surface) - resulting surface
1008 //=======================================================================
1010 Handle(Geom_Surface) GEOMImpl_IShapesOperations::makePlane(const TopoDS_Shape& anAx1)
1012 if (anAx1.ShapeType() != TopAbs_EDGE) return NULL;
1013 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
1014 TopoDS_Vertex V1, V2;
1015 TopExp::Vertices(anEdge, V1, V2, Standard_True);
1016 if (V1.IsNull() || V2.IsNull()) {
1017 SetErrorCode("Bad edge given for the plane normal vector");
1020 gp_Pnt aLoc = BRep_Tool::Pnt(V1);
1021 gp_Vec aVec (aLoc, BRep_Tool::Pnt(V2));
1022 if (aVec.Magnitude() < Precision::Confusion()) {
1023 SetErrorCode("Vector with null magnitude given");
1026 return new Geom_Plane(aLoc, aVec);
1029 //=======================================================================
1030 //function : makeCylinder
1032 * \brief Creates Geom_CylindricalSurface
1033 * \param theAx1 - edge defining cylinder axis
1034 * \param theRadius - cylinder radius
1035 * \retval Handle(Geom_Surface) - resulting surface
1037 //=======================================================================
1039 Handle(Geom_Surface) GEOMImpl_IShapesOperations::makeCylinder(const TopoDS_Shape& anAxis,
1040 const Standard_Real theRadius)
1042 //Axis of the cylinder
1043 if (anAxis.ShapeType() != TopAbs_EDGE) {
1044 SetErrorCode("Not an edge given for the axis");
1047 TopoDS_Edge anEdge = TopoDS::Edge(anAxis);
1048 TopoDS_Vertex V1, V2;
1049 TopExp::Vertices(anEdge, V1, V2, Standard_True);
1050 if (V1.IsNull() || V2.IsNull()) {
1051 SetErrorCode("Bad edge given for the axis");
1054 gp_Pnt aLoc = BRep_Tool::Pnt(V1);
1055 gp_Vec aVec (aLoc, BRep_Tool::Pnt(V2));
1056 if (aVec.Magnitude() < Precision::Confusion()) {
1057 SetErrorCode("Vector with null magnitude given");
1061 gp_Ax3 anAx3 (aLoc, aVec);
1062 return new Geom_CylindricalSurface(anAx3, theRadius);
1066 //=======================================================================
1067 //function : getShapesOnSurfaceIDs
1069 * \brief Find IDs of subshapes complying with given status about surface
1070 * \param theSurface - the surface to check state of subshapes against
1071 * \param theShape - the shape to explore
1072 * \param theShapeType - type of subshape of theShape
1073 * \param theState - required state
1074 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1076 //=======================================================================
1078 Handle(TColStd_HSequenceOfInteger)
1079 GEOMImpl_IShapesOperations::getShapesOnSurfaceIDs(const Handle(Geom_Surface)& theSurface,
1080 const TopoDS_Shape& theShape,
1081 TopAbs_ShapeEnum theShapeType,
1082 GEOMAlgo_State theState)
1084 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
1085 // MESSAGE("--------------------------- GetShapesOnPlane phase 1 takes:");
1086 // OSD_Timer timer1;
1089 // Check presence of triangulation, build if need
1090 if (!CheckTriangulation(theShape))
1094 GEOMAlgo_FinderShapeOn1 aFinder;
1095 Standard_Real aTol = 0.0001; // default value
1097 aFinder.SetShape(theShape);
1098 aFinder.SetTolerance(aTol);
1099 aFinder.SetSurface(theSurface);
1100 aFinder.SetShapeType(theShapeType);
1101 aFinder.SetState(theState);
1103 // Sets the minimal number of inner points for the faces that do not have own
1104 // inner points at all (for e.g. rectangular planar faces have just 2 triangles).
1106 aFinder.SetNbPntsMin(3);
1107 // Sets the maximal number of inner points for edges or faces.
1108 // It is usefull for the cases when this number is very big (e.g =2000) to improve
1109 // the performance. If this value =0, all inner points will be taken into account.
1111 aFinder.SetNbPntsMax(100);
1116 // MESSAGE("--------------------------- Perform on Plane takes:");
1123 // MESSAGE("--------------------------- GetShapesOnPlane phase 3 takes:");
1127 // Interprete results
1128 Standard_Integer iErr = aFinder.ErrorStatus();
1129 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
1131 MESSAGE(" iErr : " << iErr);
1132 TCollection_AsciiString aMsg (" iErr : ");
1133 aMsg += TCollection_AsciiString(iErr);
1137 Standard_Integer iWrn = aFinder.WarningStatus();
1138 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
1140 MESSAGE(" *** iWrn : " << iWrn);
1143 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
1145 if (listSS.Extent() < 1) {
1146 SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
1153 // MESSAGE("--------------------------- GetShapesOnPlane phase 4 takes:");
1157 // Fill sequence of object IDs
1158 aSeqOfIDs = new TColStd_HSequenceOfInteger;
1160 TopTools_IndexedMapOfShape anIndices;
1161 TopExp::MapShapes(theShape, anIndices);
1163 TopTools_ListIteratorOfListOfShape itSub (listSS);
1164 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
1165 int id = anIndices.FindIndex(itSub.Value());
1166 aSeqOfIDs->Append(id);
1173 //=======================================================================
1174 //function : getObjectsShapesOn
1176 * \brief Find shape objects and their entries by their ids
1177 * \param theShapeIDs - incoming shape ids
1178 * \param theShapeEntries - outgoing entries like "entry1, entry2, ..."
1179 * \retval Handle(TColStd_HSequenceOfTransient) - found shape objects
1181 //=======================================================================
1183 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::
1184 getObjectsShapesOn(const Handle(GEOM_Object)& theShape,
1185 const Handle(TColStd_HSequenceOfInteger)& theShapeIDs,
1186 TCollection_AsciiString & theShapeEntries)
1188 Handle(TColStd_HSequenceOfTransient) aSeq;
1190 if ( !theShapeIDs.IsNull() && theShapeIDs->Length() > 0 )
1192 aSeq = new TColStd_HSequenceOfTransient;
1193 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
1194 TCollection_AsciiString anEntry;
1195 for ( int i = 1; i <= theShapeIDs->Length(); ++i )
1197 anArray->SetValue(1, theShapeIDs->Value( i ));
1198 Handle(GEOM_Object) anObj = GetEngine()->AddSubShape(theShape, anArray);
1199 aSeq->Append( anObj );
1201 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
1202 if ( i != 1 ) theShapeEntries += ",";
1203 theShapeEntries += anEntry;
1209 //=======================================================================
1210 //function : getShapesOnSurface
1212 * \brief Find subshapes complying with given status about surface
1213 * \param theSurface - the surface to check state of subshapes against
1214 * \param theShape - the shape to explore
1215 * \param theShapeType - type of subshape of theShape
1216 * \param theState - required state
1217 * \param theShapeEntries - outgoing entries like "entry1, entry2, ..."
1218 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1220 //=======================================================================
1222 Handle(TColStd_HSequenceOfTransient)
1223 GEOMImpl_IShapesOperations::getShapesOnSurface(const Handle(Geom_Surface)& theSurface,
1224 const Handle(GEOM_Object)& theShape,
1225 TopAbs_ShapeEnum theShapeType,
1226 GEOMAlgo_State theState,
1227 TCollection_AsciiString & theShapeEntries)
1229 // Find subshapes ids
1230 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
1231 getShapesOnSurfaceIDs (theSurface, theShape->GetValue(), theShapeType, theState);
1232 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
1235 return getObjectsShapesOn( theShape, aSeqOfIDs, theShapeEntries );
1238 //=============================================================================
1242 //=============================================================================
1243 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnPlane
1244 (const Handle(GEOM_Object)& theShape,
1245 const Standard_Integer theShapeType,
1246 const Handle(GEOM_Object)& theAx1,
1247 const GEOMAlgo_State theState)
1251 // MESSAGE("--------------------------- GetShapesOnPlane phase 1 takes:");
1252 // OSD_Timer timer1;
1255 if (theShape.IsNull() || theAx1.IsNull()) return NULL;
1257 TopoDS_Shape aShape = theShape->GetValue();
1258 TopoDS_Shape anAx1 = theAx1->GetValue();
1260 if (aShape.IsNull() || anAx1.IsNull()) return NULL;
1262 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
1263 if ( !checkTypeShapesOn( theShapeType ))
1267 Handle(Geom_Surface) aPlane = makePlane( anAx1 );
1268 if ( aPlane.IsNull() )
1272 TCollection_AsciiString anAsciiList;
1273 Handle(TColStd_HSequenceOfTransient) aSeq;
1274 aSeq = getShapesOnSurface( aPlane, theShape, aShapeType, theState, anAsciiList );
1275 if ( aSeq.IsNull() || aSeq->Length() == 0 )
1281 // MESSAGE("--------------------------- GetShapesOnPlane phase 5 takes:");
1285 // Make a Python command
1287 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
1288 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1290 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
1291 << "] = geompy.GetShapesOnPlane(" << theShape << ", "
1292 << theShapeType << ", " << theAx1 << ", " << theState << ")";
1298 //=============================================================================
1300 * GetShapesOnCylinder
1302 //=============================================================================
1303 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnCylinder
1304 (const Handle(GEOM_Object)& theShape,
1305 const Standard_Integer theShapeType,
1306 const Handle(GEOM_Object)& theAxis,
1307 const Standard_Real theRadius,
1308 const GEOMAlgo_State theState)
1312 if (theShape.IsNull() || theAxis.IsNull()) return NULL;
1314 TopoDS_Shape aShape = theShape->GetValue();
1315 TopoDS_Shape anAxis = theAxis->GetValue();
1317 if (aShape.IsNull() || anAxis.IsNull()) return NULL;
1319 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
1320 if ( !checkTypeShapesOn( aShapeType ))
1323 // Create a cylinder surface
1324 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
1325 if ( aCylinder.IsNull() )
1329 TCollection_AsciiString anAsciiList;
1330 Handle(TColStd_HSequenceOfTransient) aSeq;
1331 aSeq = getShapesOnSurface( aCylinder, theShape, aShapeType, theState, anAsciiList );
1332 if ( aSeq.IsNull() || aSeq->Length() == 0 )
1335 // Make a Python command
1337 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
1338 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1340 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
1341 << "] = geompy.GetShapesOnCylinder(" << theShape << ", " << theShapeType
1342 << ", " << theAxis << ", " << theRadius << ", " << theState << ")";
1348 //=============================================================================
1352 //=============================================================================
1353 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnSphere
1354 (const Handle(GEOM_Object)& theShape,
1355 const Standard_Integer theShapeType,
1356 const Handle(GEOM_Object)& theCenter,
1357 const Standard_Real theRadius,
1358 const GEOMAlgo_State theState)
1362 if (theShape.IsNull() || theCenter.IsNull()) return NULL;
1364 TopoDS_Shape aShape = theShape->GetValue();
1365 TopoDS_Shape aCenter = theCenter->GetValue();
1367 if (aShape.IsNull() || aCenter.IsNull()) return NULL;
1369 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
1370 if ( !checkTypeShapesOn( aShapeType ))
1373 // Center of the sphere
1374 if (aCenter.ShapeType() != TopAbs_VERTEX) return NULL;
1375 gp_Pnt aLoc = BRep_Tool::Pnt(TopoDS::Vertex(aCenter));
1377 gp_Ax3 anAx3 (aLoc, gp::DZ());
1378 Handle(Geom_SphericalSurface) aSphere =
1379 new Geom_SphericalSurface(anAx3, theRadius);
1382 TCollection_AsciiString anAsciiList;
1383 Handle(TColStd_HSequenceOfTransient) aSeq;
1384 aSeq = getShapesOnSurface( aSphere, theShape, aShapeType, theState, anAsciiList );
1385 if ( aSeq.IsNull() || aSeq->Length() == 0 )
1388 // Make a Python command
1390 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
1391 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1393 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
1394 << "] = geompy.GetShapesOnSphere(" << theShape << ", " << theShapeType
1395 << ", " << theCenter << ", " << theRadius << ", " << theState << ")";
1401 //=======================================================================
1402 //function : getCreatedLast
1404 * \brief Select the object created last
1405 * \param theObj1 - Object 1
1406 * \param theObj2 - Object 2
1407 * \retval Handle(GEOM_Object) - selected object
1409 //=======================================================================
1411 Handle(GEOM_Object) GEOMImpl_IShapesOperations::getCreatedLast(const Handle(GEOM_Object)& theObj1,
1412 const Handle(GEOM_Object)& theObj2)
1414 if ( theObj1.IsNull() ) return theObj2;
1415 if ( theObj2.IsNull() ) return theObj1;
1416 return ( theObj1->GetEntry().Tag() > theObj2->GetEntry().Tag() ) ? theObj1 : theObj2;
1419 //=============================================================================
1421 * GetShapesOnPlaneIDs
1423 //=============================================================================
1424 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnPlaneIDs
1425 (const Handle(GEOM_Object)& theShape,
1426 const Standard_Integer theShapeType,
1427 const Handle(GEOM_Object)& theAx1,
1428 const GEOMAlgo_State theState)
1432 if (theShape.IsNull() || theAx1.IsNull()) return NULL;
1434 TopoDS_Shape aShape = theShape->GetValue();
1435 TopoDS_Shape anAx1 = theAx1->GetValue();
1437 if (aShape.IsNull() || anAx1.IsNull()) return NULL;
1439 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
1440 if ( !checkTypeShapesOn( aShapeType ))
1444 Handle(Geom_Surface) aPlane = makePlane( anAx1 );
1445 if ( aPlane.IsNull() )
1449 Handle(TColStd_HSequenceOfInteger) aSeq;
1450 aSeq = getShapesOnSurfaceIDs( aPlane, aShape, aShapeType, theState );
1452 // The GetShapesOnPlaneIDs() doesn't change object so no new function is required.
1453 Handle(GEOM_Function) aFunction = getCreatedLast(theShape,theAx1)->GetLastFunction();
1455 // Make a Python command
1456 const bool append = true;
1457 GEOM::TPythonDump(aFunction,append)
1458 << "listShapesOnPlane = geompy.GetShapesOnPlaneIDs"
1459 << "(" << theShape << "," << theShapeType << "," << theAx1 << "," << theState << ")";
1465 //=============================================================================
1467 * GetShapesOnCylinderIDs
1469 //=============================================================================
1470 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnCylinderIDs
1471 (const Handle(GEOM_Object)& theShape,
1472 const Standard_Integer theShapeType,
1473 const Handle(GEOM_Object)& theAxis,
1474 const Standard_Real theRadius,
1475 const GEOMAlgo_State theState)
1479 if (theShape.IsNull() || theAxis.IsNull()) return NULL;
1481 TopoDS_Shape aShape = theShape->GetValue();
1482 TopoDS_Shape anAxis = theAxis->GetValue();
1484 if (aShape.IsNull() || anAxis.IsNull()) return NULL;
1486 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
1487 if ( !checkTypeShapesOn( aShapeType ))
1490 // Create a cylinder surface
1491 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
1492 if ( aCylinder.IsNull() )
1496 Handle(TColStd_HSequenceOfInteger) aSeq;
1497 aSeq = getShapesOnSurfaceIDs( aCylinder, aShape, aShapeType, theState );
1499 // The GetShapesOnCylinder() doesn't change object so no new function is required.
1500 Handle(GEOM_Function) aFunction = getCreatedLast(theShape,theAxis)->GetLastFunction();
1502 // Make a Python command
1503 const bool append = true;
1504 GEOM::TPythonDump(aFunction,append)
1505 << "listShapesOnCylinder = geompy.GetShapesOnCylinderIDs"
1506 << "(" << theShape << ", " << theShapeType << ", " << theAxis << ", "
1507 << theRadius << ", " << theState << ")";
1513 //=============================================================================
1515 * GetShapesOnSphereIDs
1517 //=============================================================================
1518 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnSphereIDs
1519 (const Handle(GEOM_Object)& theShape,
1520 const Standard_Integer theShapeType,
1521 const Handle(GEOM_Object)& theCenter,
1522 const Standard_Real theRadius,
1523 const GEOMAlgo_State theState)
1527 if (theShape.IsNull() || theCenter.IsNull()) return NULL;
1529 TopoDS_Shape aShape = theShape->GetValue();
1530 TopoDS_Shape aCenter = theCenter->GetValue();
1532 if (aShape.IsNull() || aCenter.IsNull()) return NULL;
1534 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
1535 if ( !checkTypeShapesOn( aShapeType ))
1538 // Center of the sphere
1539 if (aCenter.ShapeType() != TopAbs_VERTEX) return NULL;
1540 gp_Pnt aLoc = BRep_Tool::Pnt(TopoDS::Vertex(aCenter));
1542 gp_Ax3 anAx3 (aLoc, gp::DZ());
1543 Handle(Geom_SphericalSurface) aSphere =
1544 new Geom_SphericalSurface(anAx3, theRadius);
1547 Handle(TColStd_HSequenceOfInteger) aSeq;
1548 aSeq = getShapesOnSurfaceIDs( aSphere, aShape, aShapeType, theState );
1550 // The GetShapesOnSphere() doesn't change object so no new function is required.
1551 Handle(GEOM_Function) aFunction = getCreatedLast(theShape,theCenter)->GetLastFunction();
1553 // Make a Python command
1554 const bool append = true;
1555 GEOM::TPythonDump(aFunction,append)
1556 << "listShapesOnCylinder = geompy.GetShapesOnCylinderIDs"
1557 << "(" << theShape << ", " << theShapeType << ", " << theCenter << ", "
1558 << theRadius << ", " << theState << ")";
1564 //=======================================================================
1565 //function : getShapesOnQuadrangleIDs
1567 * \brief Find IDs of subshapes complying with given status about quadrangle
1568 * \param theShape - the shape to explore
1569 * \param theShapeType - type of subshape of theShape
1570 * \param theTopLeftPoint - top left quadrangle corner
1571 * \param theTopRigthPoint - top right quadrangle corner
1572 * \param theBottomLeftPoint - bottom left quadrangle corner
1573 * \param theBottomRigthPoint - bottom right quadrangle corner
1574 * \param theState - required state
1575 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1577 //=======================================================================
1579 Handle(TColStd_HSequenceOfInteger)
1580 GEOMImpl_IShapesOperations::getShapesOnQuadrangleIDs (const Handle(GEOM_Object)& theShape,
1581 const Standard_Integer theShapeType,
1582 const Handle(GEOM_Object)& theTopLeftPoint,
1583 const Handle(GEOM_Object)& theTopRigthPoint,
1584 const Handle(GEOM_Object)& theBottomLeftPoint,
1585 const Handle(GEOM_Object)& theBottomRigthPoint,
1586 const GEOMAlgo_State theState)
1590 if ( theShape.IsNull() ||
1591 theTopLeftPoint.IsNull() ||
1592 theTopRigthPoint.IsNull() ||
1593 theBottomLeftPoint.IsNull() ||
1594 theBottomRigthPoint.IsNull() )
1597 TopoDS_Shape aShape = theShape->GetValue();
1598 TopoDS_Shape aTL = theTopLeftPoint->GetValue();
1599 TopoDS_Shape aTR = theTopRigthPoint->GetValue();
1600 TopoDS_Shape aBL = theBottomLeftPoint->GetValue();
1601 TopoDS_Shape aBR = theBottomRigthPoint->GetValue();
1603 if (aShape.IsNull() ||
1608 aTL.ShapeType() != TopAbs_VERTEX ||
1609 aTR.ShapeType() != TopAbs_VERTEX ||
1610 aBL.ShapeType() != TopAbs_VERTEX ||
1611 aBR.ShapeType() != TopAbs_VERTEX )
1614 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
1615 if ( !checkTypeShapesOn( aShapeType ))
1618 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
1620 // Check presence of triangulation, build if need
1621 if (!CheckTriangulation(aShape))
1625 gp_Pnt aPntTL = BRep_Tool::Pnt(TopoDS::Vertex(aTL));
1626 gp_Pnt aPntTR = BRep_Tool::Pnt(TopoDS::Vertex(aTR));
1627 gp_Pnt aPntBL = BRep_Tool::Pnt(TopoDS::Vertex(aBL));
1628 gp_Pnt aPntBR = BRep_Tool::Pnt(TopoDS::Vertex(aBR));
1630 GEOMAlgo_FinderShapeOnQuad aFinder( aPntTL, aPntTR, aPntBL, aPntBR );
1631 Standard_Real aTol = 0.0001; // default value
1633 aFinder.SetShape(aShape);
1634 aFinder.SetTolerance(aTol);
1635 //aFinder.SetSurface(theSurface);
1636 aFinder.SetShapeType(aShapeType);
1637 aFinder.SetState(theState);
1639 // Sets the minimal number of inner points for the faces that do not have own
1640 // inner points at all (for e.g. rectangular planar faces have just 2 triangles).
1642 aFinder.SetNbPntsMin(3);
1643 // Sets the maximal number of inner points for edges or faces.
1644 // It is usefull for the cases when this number is very big (e.g =2000) to improve
1645 // the performance. If this value =0, all inner points will be taken into account.
1647 aFinder.SetNbPntsMax(100);
1651 // Interprete results
1652 Standard_Integer iErr = aFinder.ErrorStatus();
1653 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
1655 MESSAGE(" iErr : " << iErr);
1656 TCollection_AsciiString aMsg (" iErr : ");
1657 aMsg += TCollection_AsciiString(iErr);
1661 Standard_Integer iWrn = aFinder.WarningStatus();
1662 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
1664 MESSAGE(" *** iWrn : " << iWrn);
1667 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
1669 if (listSS.Extent() < 1) {
1670 SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
1674 // Fill sequence of object IDs
1675 aSeqOfIDs = new TColStd_HSequenceOfInteger;
1677 TopTools_IndexedMapOfShape anIndices;
1678 TopExp::MapShapes(aShape, anIndices);
1680 TopTools_ListIteratorOfListOfShape itSub (listSS);
1681 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
1682 int id = anIndices.FindIndex(itSub.Value());
1683 aSeqOfIDs->Append(id);
1688 //=======================================================================
1689 //function : GetShapesOnQuadrangle
1691 * \brief Find subshapes complying with given status about quadrangle
1692 * \param theShape - the shape to explore
1693 * \param theShapeType - type of subshape of theShape
1694 * \param theTopLeftPoint - top left quadrangle corner
1695 * \param theTopRigthPoint - top right quadrangle corner
1696 * \param theBottomLeftPoint - bottom left quadrangle corner
1697 * \param theBottomRigthPoint - bottom right quadrangle corner
1698 * \param theState - required state
1699 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1701 //=======================================================================
1703 Handle(TColStd_HSequenceOfTransient)
1704 GEOMImpl_IShapesOperations::GetShapesOnQuadrangle (const Handle(GEOM_Object)& theShape,
1705 const Standard_Integer theShapeType,
1706 const Handle(GEOM_Object)& theTopLeftPoint,
1707 const Handle(GEOM_Object)& theTopRigthPoint,
1708 const Handle(GEOM_Object)& theBottomLeftPoint,
1709 const Handle(GEOM_Object)& theBottomRigthPoint,
1710 const GEOMAlgo_State theState)
1713 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
1714 getShapesOnQuadrangleIDs( theShape,
1719 theBottomRigthPoint,
1721 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->IsEmpty() )
1724 // Find objects by indices
1725 TCollection_AsciiString anAsciiList;
1726 Handle(TColStd_HSequenceOfTransient) aSeq;
1727 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
1728 if ( aSeq.IsNull() || aSeq->IsEmpty() )
1731 // Make a Python command
1733 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
1734 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1736 GEOM::TPythonDump(aFunction)
1737 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnQuadrangle("
1739 << theShapeType << ", "
1740 << theTopLeftPoint << ", "
1741 << theTopRigthPoint << ", "
1742 << theBottomLeftPoint << ", "
1743 << theBottomRigthPoint << ", "
1750 //=======================================================================
1751 //function : GetShapesOnQuadrangleIDs
1753 * \brief Find IDs of subshapes complying with given status about quadrangle
1754 * \param theShape - the shape to explore
1755 * \param theShapeType - type of subshape of theShape
1756 * \param theTopLeftPoint - top left quadrangle corner
1757 * \param theTopRigthPoint - top right quadrangle corner
1758 * \param theBottomLeftPoint - bottom left quadrangle corner
1759 * \param theBottomRigthPoint - bottom right quadrangle corner
1760 * \param theState - required state
1761 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1763 //=======================================================================
1765 Handle(TColStd_HSequenceOfInteger)
1766 GEOMImpl_IShapesOperations::GetShapesOnQuadrangleIDs (const Handle(GEOM_Object)& theShape,
1767 const Standard_Integer theShapeType,
1768 const Handle(GEOM_Object)& theTopLeftPoint,
1769 const Handle(GEOM_Object)& theTopRigthPoint,
1770 const Handle(GEOM_Object)& theBottomLeftPoint,
1771 const Handle(GEOM_Object)& theBottomRigthPoint,
1772 const GEOMAlgo_State theState)
1775 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
1776 getShapesOnQuadrangleIDs( theShape,
1781 theBottomRigthPoint,
1783 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->IsEmpty() )
1786 // Make a Python command
1788 // The GetShapesOnCylinder() doesn't change object so no new function is required.
1789 Handle(GEOM_Object) lastObj = getCreatedLast(theShape,theTopLeftPoint);
1790 lastObj = getCreatedLast(lastObj,theTopRigthPoint);
1791 lastObj = getCreatedLast(lastObj,theBottomRigthPoint);
1792 lastObj = getCreatedLast(lastObj,theBottomLeftPoint);
1793 Handle(GEOM_Function) aFunction = lastObj->GetLastFunction();
1795 const bool append = true;
1796 GEOM::TPythonDump(aFunction,append)
1797 << "listShapesOnQuadrangle = geompy.GetShapesOnQuadrangleIDs("
1799 << theShapeType << ", "
1800 << theTopLeftPoint << ", "
1801 << theTopRigthPoint << ", "
1802 << theBottomLeftPoint << ", "
1803 << theBottomRigthPoint << ", "
1811 //=============================================================================
1815 //=============================================================================
1816 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlace
1817 (Handle(GEOM_Object) theShapeWhere,
1818 Handle(GEOM_Object) theShapeWhat)
1822 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
1824 TopoDS_Shape aWhere = theShapeWhere->GetValue();
1825 TopoDS_Shape aWhat = theShapeWhat->GetValue();
1827 if (aWhere.IsNull() || aWhat.IsNull()) return NULL;
1829 //Fill array of indices
1830 Handle(TColStd_HArray1OfInteger) aModifiedArray;
1832 Handle(GEOM_Function) aWhereFunction = theShapeWhere->GetLastFunction();
1834 TopTools_IndexedMapOfShape aWhereIndices;
1835 TopExp::MapShapes(aWhere, aWhereIndices);
1837 if (aWhereIndices.Contains(aWhat)) {
1839 // entity was not changed by the operation
1840 Standard_Integer aWhatIndex = aWhereIndices.FindIndex(aWhat);
1841 aModifiedArray = new TColStd_HArray1OfInteger(1,1);
1842 aModifiedArray->SetValue(1, aWhatIndex);
1846 TDF_Label aHistoryLabel = aWhereFunction->GetHistoryEntry(Standard_False);
1847 if (aHistoryLabel.IsNull()) {
1848 SetErrorCode("Modifications history does not exist for the shape under consideration.");
1852 // search in history for all argument shapes
1853 Standard_Boolean isFound = Standard_False;
1855 TDF_LabelSequence aLabelSeq;
1856 aWhereFunction->GetDependency(aLabelSeq);
1857 Standard_Integer nbArg = aLabelSeq.Length();
1859 for (Standard_Integer iarg = 1; iarg <= nbArg && !isFound; iarg++) {
1861 TDF_Label anArgumentRefLabel = aLabelSeq.Value(iarg);
1863 Handle(GEOM_Object) anArgumentObject = GEOM_Object::GetReferencedObject(anArgumentRefLabel);
1864 TopoDS_Shape anArgumentShape = anArgumentObject->GetValue();
1866 TopTools_IndexedMapOfShape anArgumentIndices;
1867 TopExp::MapShapes(anArgumentShape, anArgumentIndices);
1869 if (anArgumentIndices.Contains(aWhat)) {
1870 isFound = Standard_True;
1871 Standard_Integer aWhatIndex = anArgumentIndices.FindIndex(aWhat);
1873 // Find corresponding label in history
1874 TDF_Label anArgumentHistoryLabel =
1875 aWhereFunction->GetArgumentHistoryEntry(anArgumentRefLabel, Standard_False);
1876 if (anArgumentHistoryLabel.IsNull()) {
1877 // Lost History of operation argument. Possibly, all its entities was removed.
1882 TDF_Label aWhatHistoryLabel = anArgumentHistoryLabel.FindChild(aWhatIndex, Standard_False);
1883 if (aWhatHistoryLabel.IsNull()) {
1889 Handle(TDataStd_IntegerArray) anIntegerArray;
1890 if (!aWhatHistoryLabel.FindAttribute(TDataStd_IntegerArray::GetID(), anIntegerArray)) {
1891 SetErrorCode("Error: Empty modifications history for the sought shape.");
1895 aModifiedArray = anIntegerArray->Array();
1896 if (aModifiedArray->Length() == 0) {
1897 SetErrorCode("Error: Empty modifications history for the sought shape.");
1904 SetErrorCode("The sought shape does not belong to any operation argument.");
1910 Handle(GEOM_Object) aResult = GetEngine()->AddSubShape(theShapeWhere, aModifiedArray);
1912 if (aModifiedArray->Length() > 1) {
1914 aResult->SetType(GEOM_GROUP);
1916 //Set a sub shape type
1917 TDF_Label aFreeLabel = aResult->GetFreeLabel();
1918 TopAbs_ShapeEnum aShapeType = aWhat.ShapeType();
1919 TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aShapeType);
1922 //Make a Python command
1923 Handle(GEOM_Function) aFunction = aResult->GetFunction(1);
1925 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetInPlace("
1926 << theShapeWhere << ", " << theShapeWhat << ")";
1932 //=======================================================================
1933 //function : SortShapes
1935 //=======================================================================
1936 void GEOMImpl_IShapesOperations::SortShapes(TopTools_ListOfShape& SL)
1938 Standard_Integer MaxShapes = SL.Extent();
1939 TopTools_Array1OfShape aShapes (1,MaxShapes);
1940 TColStd_Array1OfInteger OrderInd(1,MaxShapes);
1941 TColStd_Array1OfReal MidXYZ (1,MaxShapes); //X,Y,Z;
1942 TColStd_Array1OfReal Length (1,MaxShapes); //X,Y,Z;
1944 // Computing of CentreOfMass
1945 Standard_Integer Index;
1948 TopTools_ListIteratorOfListOfShape it(SL);
1949 for (Index=1; it.More(); Index++)
1951 TopoDS_Shape S = it.Value();
1952 SL.Remove( it ); // == it.Next()
1954 OrderInd.SetValue (Index, Index);
1955 if (S.ShapeType() == TopAbs_VERTEX)
1957 GPoint = BRep_Tool::Pnt( TopoDS::Vertex( S ));
1958 Length.SetValue( Index, (Standard_Real) S.Orientation());
1962 BRepGProp::LinearProperties (S, GPr);
1963 GPoint = GPr.CentreOfMass();
1964 Length.SetValue( Index, GPr.Mass() );
1966 MidXYZ.SetValue(Index,
1967 GPoint.X()*999 + GPoint.Y()*99 + GPoint.Z()*0.9);
1970 Standard_Integer aTemp;
1971 Standard_Boolean exchange, Sort = Standard_True;
1974 Sort = Standard_False;
1975 for (Index=1; Index < MaxShapes; Index++)
1977 if (MidXYZ(OrderInd(Index)) > MidXYZ(OrderInd(Index+1)))
1978 exchange = Standard_True;
1979 else if (MidXYZ(OrderInd(Index)) == MidXYZ(OrderInd(Index+1)) &&
1980 Length(OrderInd(Index)) > Length(OrderInd(Index+1)) )
1981 exchange = Standard_True;
1983 exchange = Standard_False;
1986 aTemp = OrderInd(Index);
1987 OrderInd(Index) = OrderInd(Index+1);
1988 OrderInd(Index+1) = aTemp;
1989 Sort = Standard_True;
1993 for (Index=1; Index <= MaxShapes; Index++)
1994 SL.Append( aShapes( OrderInd(Index) ));
1997 //=======================================================================
1998 //function : CheckTriangulation
2000 //=======================================================================
2001 bool GEOMImpl_IShapesOperations::CheckTriangulation (const TopoDS_Shape& aShape)
2003 // MESSAGE("CheckTriangulation");
2005 // OSD_Timer timer1;
2008 TopExp_Explorer exp (aShape, TopAbs_FACE);
2010 SetErrorCode("Shape without faces given");
2014 TopLoc_Location aTopLoc;
2015 Handle(Poly_Triangulation) aTRF;
2016 aTRF = BRep_Tool::Triangulation(TopoDS::Face(exp.Current()), aTopLoc);
2017 if (aTRF.IsNull()) {
2018 // calculate deflection
2019 Standard_Real aDeviationCoefficient = 0.001;
2022 BRepBndLib::Add(aShape, B);
2023 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
2024 B.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
2026 Standard_Real dx = aXmax - aXmin, dy = aYmax - aYmin, dz = aZmax - aZmin;
2027 Standard_Real aDeflection = Max(Max(dx, dy), dz) * aDeviationCoefficient * 4;
2029 // MESSAGE("Deflection = " << aDeflection);
2031 Standard_Real aHLRAngle = 0.349066;
2033 BRepMesh_IncrementalMesh Inc (aShape, aDeflection, Standard_False, aHLRAngle);