X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FGEOMImpl%2FGEOMImpl_IShapesOperations.cxx;h=d8991212334f26f665e2f9494a9509c1dc895bcf;hb=705488d6da5598ee7d7eff324ac849fa22536277;hp=ee637328b3dc62bff205353889f668a4651a2ddd;hpb=d3dd282390888d7dc091ba2c2ffe7923bd7458e6;p=modules%2Fgeom.git diff --git a/src/GEOMImpl/GEOMImpl_IShapesOperations.cxx b/src/GEOMImpl/GEOMImpl_IShapesOperations.cxx index ee637328b..d89912123 100644 --- a/src/GEOMImpl/GEOMImpl_IShapesOperations.cxx +++ b/src/GEOMImpl/GEOMImpl_IShapesOperations.cxx @@ -13,8 +13,12 @@ using namespace std; #include "GEOMImpl_IShapes.hxx" #include "GEOMImpl_IGlue.hxx" +#include "GEOMImpl_Block6Explorer.hxx" + #include "GEOM_Function.hxx" +#include "GEOMAlgo_FinderShapeOn.hxx" + #include "utilities.h" #include "OpUtil.hxx" #include "Utils_ExceptHandlers.hxx" @@ -22,26 +26,49 @@ using namespace std; #include #include #include +#include +#include #include +#include + #include #include +#include +#include #include #include #include #include +#include +#include +#include #include #include +#include #include #include #include #include +#include +#include +#include +#include +#include + +#include + #include #include +#include #include #include +#include +#include + +//#include #include // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC @@ -114,7 +141,7 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeEdge //Make a Python command TCollection_AsciiString anEntry, aDescr; TDF_Tool::Entry(anEdge->GetEntry(), anEntry); - aDescr += (anEntry+" = IShapesOperations.MakeEdge("); + aDescr += (anEntry+" = geompy.MakeEdge("); TDF_Tool::Entry(thePnt1->GetEntry(), anEntry); aDescr += (anEntry+", "); TDF_Tool::Entry(thePnt2->GetEntry(), anEntry); @@ -186,12 +213,11 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFace (Handle(GEOM_Object) th TCollection_AsciiString anEntry, aDescr; TDF_Tool::Entry(aFace->GetEntry(), anEntry); aDescr += anEntry; - aDescr += " = IShapesOperations.MakeFace("; + aDescr += " = geompy.MakeFace("; TDF_Tool::Entry(theWire->GetEntry(), anEntry); aDescr += anEntry; if (isPlanarWanted) aDescr += ", 1)"; - else aDescr += ", 0)"; @@ -207,7 +233,8 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFace (Handle(GEOM_Object) th */ //============================================================================= Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFaceWires - (list theShapes, bool isPlanarWanted) + (list theShapes, + const bool isPlanarWanted) { SetErrorCode(KO); @@ -256,13 +283,13 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFaceWires //Make a Python command TCollection_AsciiString anEntry, aDescr; TDF_Tool::Entry(aShape->GetEntry(), anEntry); - aDescr += (anEntry + " = IShapesOperations.MakeFaceWires(["); + aDescr += (anEntry + " = geompy.MakeFaceWires(["); // Shapes it = theShapes.begin(); if (it != theShapes.end()) { TDF_Tool::Entry((*it)->GetEntry(), anEntry); + aDescr += anEntry; it++; - aDescr += (anEntry+", "); for (; it != theShapes.end(); it++) { aDescr += ", "; TDF_Tool::Entry((*it)->GetEntry(), anEntry); @@ -300,7 +327,7 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeShell Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeSolidShells (list theShapes) { - return MakeShape(theShapes, GEOM_SOLID, SOLID_SHELLS, "MakeSolidShells"); + return MakeShape(theShapes, GEOM_SOLID, SOLID_SHELLS, "MakeSolid"); } //============================================================================= @@ -350,7 +377,7 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeSolidShell (Handle(GEOM_Obje TCollection_AsciiString anEntry, aDescr(""); TDF_Tool::Entry(aSolid->GetEntry(), anEntry); aDescr += anEntry; - aDescr += " = IShapesOperations.MakeSolidShell("; + aDescr += " = geompy.MakeSolid("; TDF_Tool::Entry(theShell->GetEntry(), anEntry); aDescr += (anEntry+")"); @@ -427,14 +454,14 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeShape //Make a Python command TCollection_AsciiString anEntry, aDescr(""); TDF_Tool::Entry(aShape->GetEntry(), anEntry); - aDescr += (anEntry + " = IShapesOperations."); + aDescr += (anEntry + " = geompy."); aDescr += (theMethodName + "(["); // Shapes it = theShapes.begin(); if (it != theShapes.end()) { TDF_Tool::Entry((*it)->GetEntry(), anEntry); + aDescr += anEntry; it++; - aDescr += (anEntry+", "); for (; it != theShapes.end(); it++) { aDescr += ", "; TDF_Tool::Entry((*it)->GetEntry(), anEntry); @@ -482,6 +509,7 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeGlueFaces aCI.SetTolerance(theTolerance); //Compute the sub-shape value + Standard_Boolean isWarning = Standard_False; try { if (!GetSolver()->ComputeFunction(aFunction)) { SetErrorCode("Shape driver failed to glue faces"); @@ -491,21 +519,27 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeGlueFaces catch (Standard_Failure) { Handle(Standard_Failure) aFail = Standard_Failure::Caught(); SetErrorCode(aFail->GetMessageString()); - return NULL; + // to provide warning + if (!aFunction->GetValue().IsNull()) { + isWarning = Standard_True; + } else { + return NULL; + } } //Make a Python command TCollection_AsciiString anEntry, aDescr; TDF_Tool::Entry(aGlued->GetEntry(), anEntry); aDescr += anEntry; - aDescr += " = IShapesOperations.MakeGlueFaces("; + aDescr += " = geompy.MakeGlueFaces("; TDF_Tool::Entry(theShape->GetEntry(), anEntry); aDescr += anEntry + ", "; aDescr += TCollection_AsciiString(theTolerance) + ")"; aFunction->SetDescription(aDescr); - SetErrorCode(OK); + // to provide warning + if (!isWarning) SetErrorCode(OK); return aGlued; } @@ -519,6 +553,9 @@ Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::MakeExplode const Standard_Integer theShapeType, const Standard_Boolean isSorted) { +// OSD_Timer timer1, timer2, timer3, timer4; +// timer1.Start(); + SetErrorCode(KO); if (theShape.IsNull()) return NULL; @@ -556,9 +593,15 @@ Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::MakeExplode return aSeq; } +// timer1.Stop(); +// timer2.Start(); + if (isSorted) SortShapes(listShape); +// timer2.Stop(); +// timer3.Start(); + TopTools_IndexedMapOfShape anIndices; TopExp::MapShapes(aShape, anIndices); Handle(TColStd_HArray1OfInteger) anArray; @@ -577,10 +620,13 @@ Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::MakeExplode anAsciiList += ","; } +// timer3.Stop(); +// timer4.Start(); + anAsciiList.Trunc(anAsciiList.Length() - 1); anAsciiList += "]"; - anAsciiList = TCollection_AsciiString("\n") + anAsciiList; + anAsciiList = TCollection_AsciiString("\n\t") + anAsciiList; //The explode doesn't change object so no new function is requiered. aFunction = theShape->GetLastFunction(); @@ -588,7 +634,100 @@ Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::MakeExplode //Make a Python command TCollection_AsciiString aDescr(anAsciiList); TDF_Tool::Entry(theShape->GetEntry(), anEntry); - aDescr += " = IShapesOperations.MakeExplode("; + if (isSorted) + aDescr += " = geompy.SubShapeAllSorted( "; + else + aDescr += " = geompy.SubShapeAll( "; + aDescr += (anEntry + ", "); + aDescr += theShapeType; + aDescr += " )"; + + TCollection_AsciiString anOldDescr = aFunction->GetDescription(); + anOldDescr = anOldDescr + aDescr; + aFunction->SetDescription(anOldDescr); + + SetErrorCode(OK); + +// timer4.Stop(); + +// cout << "Explosure takes:" << endl; +// timer1.Show(); +// cout << "Sorting takes:" << endl; +// timer2.Show(); +// cout << "Sub-shapes addition takes:" << endl; +// timer3.Show(); +// cout << "Update Description takes:" << endl; +// timer4.Show(); + + return aSeq; +} + +//============================================================================= +/*! + * GetSubShapeAllIDs + */ +//============================================================================= +Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::SubShapeAllIDs + (Handle(GEOM_Object) theShape, + const Standard_Integer theShapeType, + const Standard_Boolean isSorted) +{ + SetErrorCode(KO); + + if (theShape.IsNull()) return NULL; + TopoDS_Shape aShape = theShape->GetValue(); + if (aShape.IsNull()) return NULL; + + Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger; + TopTools_MapOfShape mapShape; + TopTools_ListOfShape listShape; + + if (aShape.ShapeType() == TopAbs_COMPOUND && + (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE || + TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPSOLID || + TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPOUND)) { + TopoDS_Iterator It (aShape, Standard_True, Standard_True); + for (; It.More(); It.Next()) { + if (mapShape.Add(It.Value())) { + if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE || + TopAbs_ShapeEnum(theShapeType) == It.Value().ShapeType()) { + listShape.Append(It.Value()); + } + } + } + } else { + TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType)); + for (; exp.More(); exp.Next()) + if (mapShape.Add(exp.Current())) + listShape.Append(exp.Current()); + } + + if (listShape.IsEmpty()) { + SetErrorCode("The given shape has no sub-shapes of the requested type"); + return aSeq; + } + + if (isSorted) + SortShapes(listShape); + + TopTools_IndexedMapOfShape anIndices; + TopExp::MapShapes(aShape, anIndices); + Handle(TColStd_HArray1OfInteger) anArray; + + TopTools_ListIteratorOfListOfShape itSub (listShape); + for (int index = 1; itSub.More(); itSub.Next(), ++index) { + TopoDS_Shape aValue = itSub.Value(); + aSeq->Append(anIndices.FindIndex(aValue)); + } + + //The explode doesn't change object so no new function is required. + Handle(GEOM_Function) aFunction = theShape->GetLastFunction(); + + //Make a Python command + TCollection_AsciiString aDescr + ("\n\tlistSubShapeAllIDs = geompy.SubShapeAllIDs("); + TCollection_AsciiString anEntry; + TDF_Tool::Entry(theShape->GetEntry(), anEntry); aDescr += (anEntry + ","); if (isSorted) aDescr += (TCollection_AsciiString(theShapeType) + ", 1)"); @@ -600,7 +739,6 @@ Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::MakeExplode aFunction->SetDescription(anOldDescr); SetErrorCode(OK); - return aSeq; } @@ -619,7 +757,7 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetSubShape Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1); anArray->SetValue(1, theID); - Handle(GEOM_Object) anObj = GetEngine()->AddSubShape(theMainShape, anArray); + Handle(GEOM_Object) anObj = GetEngine()->AddSubShape(theMainShape, anArray,true); if (anObj.IsNull()) { SetErrorCode("Can not get a sub-shape with the given ID"); return NULL; @@ -629,13 +767,12 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetSubShape Handle(GEOM_Function) aFunction = theMainShape->GetLastFunction(); //Make a Python command - TCollection_AsciiString aDescr ("\n"); + TCollection_AsciiString aDescr ("\n\t"); TCollection_AsciiString anEntry; TDF_Tool::Entry(anObj->GetEntry(), anEntry); - aDescr += anEntry + " = IShapesOperations.GetSubShape("; + aDescr += anEntry + " = geompy.GetSubShape("; TDF_Tool::Entry(theMainShape->GetEntry(), anEntry); - aDescr += anEntry + ", "; - aDescr += TCollection_AsciiString(theID) + ")"; + aDescr += anEntry + ", [" + theID + "])"; TCollection_AsciiString anOldDescr = aFunction->GetDescription(); anOldDescr = anOldDescr + aDescr; @@ -744,7 +881,7 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::ReverseShape(Handle(GEOM_Object) TCollection_AsciiString anEntry, aDescr; TDF_Tool::Entry(aReversed->GetEntry(), anEntry); aDescr += anEntry; - aDescr += " = IShapesOperations.ReverseShape("; + aDescr += " = geompy.ChangeOrientation("; TDF_Tool::Entry(theShape->GetEntry(), anEntry); aDescr += anEntry + ")"; @@ -754,6 +891,611 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::ReverseShape(Handle(GEOM_Object) return aReversed; } +//============================================================================= +/*! + * GetFreeFacesIDs + */ +//============================================================================= +Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetFreeFacesIDs + (Handle(GEOM_Object) theShape) +{ + SetErrorCode(KO); + + if (theShape.IsNull()) return NULL; + TopoDS_Shape aShape = theShape->GetValue(); + if (aShape.IsNull()) return NULL; + + Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger; + + TopTools_IndexedDataMapOfShapeListOfShape mapFaceBlocks; + GEOMImpl_Block6Explorer::MapShapesAndAncestors + (aShape, TopAbs_FACE, TopAbs_SOLID, mapFaceBlocks); + + Standard_Integer ind = 1, nbFaces = mapFaceBlocks.Extent(); + + if (nbFaces == 0) { + SetErrorCode("The given shape has no faces"); + return aSeq; + } + + TopTools_IndexedMapOfShape anIndices; + TopExp::MapShapes(aShape, anIndices); + + Standard_Integer id; + for (; ind <= nbFaces; ind++) { + if (mapFaceBlocks.FindFromIndex(ind).Extent() != 2) { + id = anIndices.FindIndex(mapFaceBlocks.FindKey(ind)); + aSeq->Append(id); + } + } + + //The explode doesn't change object so no new function is required. + Handle(GEOM_Function) aFunction = theShape->GetLastFunction(); + + //Make a Python command + TCollection_AsciiString aDescr ("\n\tlistFreeFacesIDs = geompy.GetFreeFacesIDs("); + TCollection_AsciiString anEntry; + TDF_Tool::Entry(theShape->GetEntry(), anEntry); + aDescr += (anEntry + ")"); + + TCollection_AsciiString anOldDescr = aFunction->GetDescription(); + anOldDescr = anOldDescr + aDescr; + aFunction->SetDescription(anOldDescr); + + SetErrorCode(OK); + return aSeq; +} + +//============================================================================= +/*! + * GetSharedShapes + */ +//============================================================================= +Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetSharedShapes + (Handle(GEOM_Object) theShape1, + Handle(GEOM_Object) theShape2, + const Standard_Integer theShapeType) +{ + SetErrorCode(KO); + + if (theShape1.IsNull() || theShape2.IsNull()) return NULL; + + TopoDS_Shape aShape1 = theShape1->GetValue(); + TopoDS_Shape aShape2 = theShape2->GetValue(); + + if (aShape1.IsNull() || aShape2.IsNull()) return NULL; + + TopTools_IndexedMapOfShape anIndices; + TopExp::MapShapes(aShape1, anIndices); + Handle(TColStd_HArray1OfInteger) anArray; + + TopTools_IndexedMapOfShape mapShape1; + TopExp::MapShapes(aShape1, TopAbs_ShapeEnum(theShapeType), mapShape1); + + Handle(GEOM_Object) anObj; + Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient; + + TopTools_MapOfShape mapShape2; + TopExp_Explorer exp (aShape2, TopAbs_ShapeEnum(theShapeType)); + for (; exp.More(); exp.Next()) { + TopoDS_Shape aSS = exp.Current(); + if (mapShape2.Add(aSS) && mapShape1.Contains(aSS)) { + anArray = new TColStd_HArray1OfInteger(1,1); + anArray->SetValue(1, anIndices.FindIndex(aSS)); + anObj = GetEngine()->AddSubShape(theShape1, anArray); + aSeq->Append(anObj); + } + } + + if (aSeq->IsEmpty()) { + SetErrorCode("The given shapes have no shared sub-shapes of the requested type"); + return aSeq; + } + + //The explode doesn't change object so no new function is required. + Handle(GEOM_Function) aFunction = theShape1->GetLastFunction(); + + //Make a Python command + TCollection_AsciiString aDescr + ("\n\tlistSharedShapes = geompy.GetSharedShapes("); + TCollection_AsciiString anEntry; + TDF_Tool::Entry(theShape1->GetEntry(), anEntry); + aDescr += (anEntry + ","); + TDF_Tool::Entry(theShape2->GetEntry(), anEntry); + aDescr += (anEntry + ","); + aDescr += TCollection_AsciiString(theShapeType) + ")"; + + TCollection_AsciiString anOldDescr = aFunction->GetDescription(); + anOldDescr = anOldDescr + aDescr; + aFunction->SetDescription(anOldDescr); + + SetErrorCode(OK); + return aSeq; +} + +//============================================================================= +/*! + * GetShapesOnPlane + */ +//============================================================================= +Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnPlane + (const Handle(GEOM_Object)& theShape, + const Standard_Integer theShapeType, + const Handle(GEOM_Object)& theAx1, + const GEOMAlgo_State theState) +{ + SetErrorCode(KO); + + if (theShape.IsNull() || theAx1.IsNull()) return NULL; + + TopoDS_Shape aShape = theShape->GetValue(); + TopoDS_Shape anAx1 = theAx1->GetValue(); + + if (aShape.IsNull() || anAx1.IsNull()) return NULL; + + TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType); + if (aShapeType != TopAbs_VERTEX && + aShapeType != TopAbs_EDGE && + aShapeType != TopAbs_FACE && + aShapeType != TopAbs_SOLID) { + SetErrorCode("Only solids, vertices, edges or faces can be found by this method"); + return NULL; + } + + // Create plane + if (anAx1.ShapeType() != TopAbs_EDGE) return NULL; + TopoDS_Edge anEdge = TopoDS::Edge(anAx1); + TopoDS_Vertex V1, V2; + TopExp::Vertices(anEdge, V1, V2, Standard_True); + if (V1.IsNull() || V2.IsNull()) { + SetErrorCode("Bad edge given for the plane normal vector"); + return NULL; + } + gp_Pnt aLoc = BRep_Tool::Pnt(V1); + gp_Vec aVec (aLoc, BRep_Tool::Pnt(V2)); + if (aVec.Magnitude() < Precision::Confusion()) { + SetErrorCode("Vector with null magnitude given"); + return NULL; + } + + Handle(Geom_Plane) aPlane = new Geom_Plane(aLoc, aVec); + + // Call algo + GEOMAlgo_FinderShapeOn aFinder; + Standard_Real aTol = 0.0001; // default value + + aFinder.SetShape(aShape); + aFinder.SetTolerance(aTol); + aFinder.SetSurface(aPlane); + aFinder.SetShapeType(aShapeType); + aFinder.SetState(theState); + + aFinder.Perform(); + + // Interprete results + Standard_Integer iErr = aFinder.ErrorStatus(); + // the detailed description of error codes is in GEOMAlgo_FinderShapeOn.cxx + if (iErr) { + MESSAGE(" iErr : " << iErr); + TCollection_AsciiString aMsg (" iErr : "); + aMsg += TCollection_AsciiString(iErr); + SetErrorCode(aMsg); + return NULL; + } + Standard_Integer iWrn = aFinder.WarningStatus(); + // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn.cxx + if (iWrn) { + MESSAGE(" *** iWrn : " << iWrn); + } + + const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result + + if (listSS.Extent() < 1) { + SetErrorCode("Not a single sub-shape of the requested type found on the given plane"); + return NULL; + } + + // Fill sequence of objects + TopTools_IndexedMapOfShape anIndices; + TopExp::MapShapes(aShape, anIndices); + + Handle(GEOM_Object) anObj; + Handle(TColStd_HArray1OfInteger) anArray; + Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient; + + TopTools_ListIteratorOfListOfShape itSub (listSS); + for (int index = 1; itSub.More(); itSub.Next(), ++index) { + int id = anIndices.FindIndex(itSub.Value()); + anArray = new TColStd_HArray1OfInteger(1,1); + anArray->SetValue(1, id); + anObj = GetEngine()->AddSubShape(theShape, anArray); + aSeq->Append(anObj); + } + + // The GetShapesOnPlane() doesn't change object so no new function is required. + Handle(GEOM_Function) aFunction = theShape->GetLastFunction(); + + // Make a Python command + TCollection_AsciiString anEntry, aDescr + ("\n\tlistShapesOnPlane = geompy.GetShapesOnPlane("); + TDF_Tool::Entry(theShape->GetEntry(), anEntry); + aDescr += anEntry + TCollection_AsciiString(theShapeType) + ","; + TDF_Tool::Entry(theAx1->GetEntry(), anEntry); + aDescr += anEntry + ","; + aDescr += TCollection_AsciiString(theState) + ")"; + + TCollection_AsciiString anOldDescr = aFunction->GetDescription(); + anOldDescr += aDescr; + aFunction->SetDescription(anOldDescr); + + SetErrorCode(OK); + return aSeq; +} + +//============================================================================= +/*! + * GetShapesOnCylinder + */ +//============================================================================= +Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnCylinder + (const Handle(GEOM_Object)& theShape, + const Standard_Integer theShapeType, + const Handle(GEOM_Object)& theAxis, + const Standard_Real theRadius, + const GEOMAlgo_State theState) +{ + SetErrorCode(KO); + + if (theShape.IsNull() || theAxis.IsNull()) return NULL; + + TopoDS_Shape aShape = theShape->GetValue(); + TopoDS_Shape anAxis = theAxis->GetValue(); + + if (aShape.IsNull() || anAxis.IsNull()) return NULL; + + TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType); + if (aShapeType != TopAbs_VERTEX && + aShapeType != TopAbs_EDGE && + aShapeType != TopAbs_FACE && + aShapeType != TopAbs_SOLID) { + SetErrorCode("Only solids, vertices, edges or faces can be found by this method"); + return NULL; + } + + //Axis of the cylinder + if (anAxis.ShapeType() != TopAbs_EDGE) { + SetErrorCode("Not an edge given for the axis"); + return NULL; + } + TopoDS_Edge anEdge = TopoDS::Edge(anAxis); + TopoDS_Vertex V1, V2; + TopExp::Vertices(anEdge, V1, V2, Standard_True); + if (V1.IsNull() || V2.IsNull()) { + SetErrorCode("Bad edge given for the axis"); + return NULL; + } + gp_Pnt aLoc = BRep_Tool::Pnt(V1); + gp_Vec aVec (aLoc, BRep_Tool::Pnt(V2)); + if (aVec.Magnitude() < Precision::Confusion()) { + SetErrorCode("Vector with null magnitude given"); + return NULL; + } + + gp_Ax3 anAx3 (aLoc, aVec); + Handle(Geom_CylindricalSurface) aCylinder = + new Geom_CylindricalSurface(anAx3, theRadius); + + // Call algo + GEOMAlgo_FinderShapeOn aFinder; + Standard_Real aTol = 0.0001; // default value + + aFinder.SetShape(aShape); + aFinder.SetTolerance(aTol); + aFinder.SetSurface(aCylinder); + aFinder.SetShapeType(aShapeType); + aFinder.SetState(theState); + + aFinder.Perform(); + + // Interprete results + Standard_Integer iErr = aFinder.ErrorStatus(); + // the detailed description of error codes is in GEOMAlgo_FinderShapeOn.cxx + if (iErr) { + MESSAGE(" iErr : " << iErr); + TCollection_AsciiString aMsg (" iErr : "); + aMsg += TCollection_AsciiString(iErr); + SetErrorCode(aMsg); + return NULL; + } + Standard_Integer iWrn = aFinder.WarningStatus(); + // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn.cxx + if (iWrn) { + MESSAGE(" *** iWrn : " << iWrn); + } + + const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result + + if (listSS.Extent() < 1) { + SetErrorCode("Not a single sub-shape of the requested type found on the given cylinder"); + return NULL; + } + + // Fill sequence of objects + TopTools_IndexedMapOfShape anIndices; + TopExp::MapShapes(aShape, anIndices); + + Handle(GEOM_Object) anObj; + Handle(TColStd_HArray1OfInteger) anArray; + Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient; + + TopTools_ListIteratorOfListOfShape itSub (listSS); + for (int index = 1; itSub.More(); itSub.Next(), ++index) { + int id = anIndices.FindIndex(itSub.Value()); + anArray = new TColStd_HArray1OfInteger(1,1); + anArray->SetValue(1, id); + anObj = GetEngine()->AddSubShape(theShape, anArray); + aSeq->Append(anObj); + } + + // The GetShapesOnCylinder() doesn't change object so no new function is required. + Handle(GEOM_Function) aFunction = theShape->GetLastFunction(); + + // Make a Python command + TCollection_AsciiString anEntry, aDescr + ("\n\tlistShapesOnCylinder = geompy.GetShapesOnCylinder("); + TDF_Tool::Entry(theShape->GetEntry(), anEntry); + aDescr += anEntry + TCollection_AsciiString(theShapeType) + ","; + TDF_Tool::Entry(theAxis->GetEntry(), anEntry); + aDescr += anEntry + ","; + aDescr += TCollection_AsciiString(theRadius) + ","; + aDescr += TCollection_AsciiString(theState) + ")"; + + TCollection_AsciiString anOldDescr = aFunction->GetDescription(); + anOldDescr += aDescr; + aFunction->SetDescription(anOldDescr); + + SetErrorCode(OK); + return aSeq; +} + +//============================================================================= +/*! + * GetShapesOnSphere + */ +//============================================================================= +Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnSphere + (const Handle(GEOM_Object)& theShape, + const Standard_Integer theShapeType, + const Handle(GEOM_Object)& theCenter, + const Standard_Real theRadius, + const GEOMAlgo_State theState) +{ + SetErrorCode(KO); + + if (theShape.IsNull() || theCenter.IsNull()) return NULL; + + TopoDS_Shape aShape = theShape->GetValue(); + TopoDS_Shape aCenter = theCenter->GetValue(); + + if (aShape.IsNull() || aCenter.IsNull()) return NULL; + + TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType); + if (aShapeType != TopAbs_VERTEX && + aShapeType != TopAbs_EDGE && + aShapeType != TopAbs_FACE && + aShapeType != TopAbs_SOLID) { + SetErrorCode("Only solids, vertices, edges or faces can be found by this method"); + return NULL; + } + + // Center of the sphere + if (aCenter.ShapeType() != TopAbs_VERTEX) return NULL; + gp_Pnt aLoc = BRep_Tool::Pnt(TopoDS::Vertex(aCenter)); + + gp_Ax3 anAx3 (aLoc, gp::DZ()); + Handle(Geom_SphericalSurface) aSphere = + new Geom_SphericalSurface(anAx3, theRadius); + + // Call algo + GEOMAlgo_FinderShapeOn aFinder; + Standard_Real aTol = 0.0001; // default value + + aFinder.SetShape(aShape); + aFinder.SetTolerance(aTol); + aFinder.SetSurface(aSphere); + aFinder.SetShapeType(aShapeType); + aFinder.SetState(theState); + + aFinder.Perform(); + + // Interprete results + Standard_Integer iErr = aFinder.ErrorStatus(); + // the detailed description of error codes is in GEOMAlgo_FinderShapeOn.cxx + if (iErr) { + MESSAGE(" iErr : " << iErr); + TCollection_AsciiString aMsg (" iErr : "); + aMsg += TCollection_AsciiString(iErr); + SetErrorCode(aMsg); + return NULL; + } + Standard_Integer iWrn = aFinder.WarningStatus(); + // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn.cxx + if (iWrn) { + MESSAGE(" *** iWrn : " << iWrn); + } + + const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result + + if (listSS.Extent() < 1) { + SetErrorCode("Not a single sub-shape of the requested type found on the given sphere"); + return NULL; + } + + // Fill sequence of objects + TopTools_IndexedMapOfShape anIndices; + TopExp::MapShapes(aShape, anIndices); + + Handle(GEOM_Object) anObj; + Handle(TColStd_HArray1OfInteger) anArray; + Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient; + + TopTools_ListIteratorOfListOfShape itSub (listSS); + for (int index = 1; itSub.More(); itSub.Next(), ++index) { + int id = anIndices.FindIndex(itSub.Value()); + anArray = new TColStd_HArray1OfInteger(1,1); + anArray->SetValue(1, id); + anObj = GetEngine()->AddSubShape(theShape, anArray); + aSeq->Append(anObj); + } + + // The GetShapesOnSphere() doesn't change object so no new function is required. + Handle(GEOM_Function) aFunction = theShape->GetLastFunction(); + + // Make a Python command + TCollection_AsciiString anEntry, aDescr + ("\n\tlistShapesOnSphere = geompy.GetShapesOnSphere("); + TDF_Tool::Entry(theShape->GetEntry(), anEntry); + aDescr += anEntry + TCollection_AsciiString(theShapeType) + ","; + TDF_Tool::Entry(theCenter->GetEntry(), anEntry); + aDescr += anEntry + ","; + aDescr += TCollection_AsciiString(theRadius) + ","; + aDescr += TCollection_AsciiString(theState) + ")"; + + TCollection_AsciiString anOldDescr = aFunction->GetDescription(); + anOldDescr += aDescr; + aFunction->SetDescription(anOldDescr); + + SetErrorCode(OK); + return aSeq; +} + +//============================================================================= +/*! + * GetInPlace + */ +//============================================================================= +Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlace + (Handle(GEOM_Object) theShapeWhere, + Handle(GEOM_Object) theShapeWhat) +{ + SetErrorCode(KO); + + if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL; + + TopoDS_Shape aWhere = theShapeWhere->GetValue(); + TopoDS_Shape aWhat = theShapeWhat->GetValue(); + + if (aWhere.IsNull() || aWhat.IsNull()) return NULL; + + //Fill array of indices + Handle(TColStd_HArray1OfInteger) aModifiedArray; + + Handle(GEOM_Function) aWhereFunction = theShapeWhere->GetLastFunction(); + + TopTools_IndexedMapOfShape aWhereIndices; + TopExp::MapShapes(aWhere, aWhereIndices); + + if (aWhereIndices.Contains(aWhat)) { + + // entity was not changed by the operation + Standard_Integer aWhatIndex = aWhereIndices.FindIndex(aWhat); + aModifiedArray = new TColStd_HArray1OfInteger(1,1); + aModifiedArray->SetValue(1, aWhatIndex); + + } else { + + TDF_Label aHistoryLabel = aWhereFunction->GetHistoryEntry(Standard_False); + if (aHistoryLabel.IsNull()) { + SetErrorCode("Modifications history does not exist for the shape under consideration."); + return NULL; + } + + // search in history for all argument shapes + Standard_Boolean isFound = Standard_False; + + TDF_LabelSequence aLabelSeq; + aWhereFunction->GetDependency(aLabelSeq); + Standard_Integer nbArg = aLabelSeq.Length(); + + for (Standard_Integer iarg = 1; iarg <= nbArg && !isFound; iarg++) { + + TDF_Label anArgumentRefLabel = aLabelSeq.Value(iarg); + + Handle(GEOM_Object) anArgumentObject = GEOM_Object::GetReferencedObject(anArgumentRefLabel); + TopoDS_Shape anArgumentShape = anArgumentObject->GetValue(); + + TopTools_IndexedMapOfShape anArgumentIndices; + TopExp::MapShapes(anArgumentShape, anArgumentIndices); + + if (anArgumentIndices.Contains(aWhat)) { + isFound = Standard_True; + Standard_Integer aWhatIndex = anArgumentIndices.FindIndex(aWhat); + + // Find corresponding label in history + TDF_Label anArgumentHistoryLabel = + aWhereFunction->GetArgumentHistoryEntry(anArgumentRefLabel, Standard_False); + if (anArgumentHistoryLabel.IsNull()) { + // Lost History of operation argument. Possibly, all its entities was removed. + SetErrorCode(OK); + return NULL; + } + + TDF_Label aWhatHistoryLabel = anArgumentHistoryLabel.FindChild(aWhatIndex, Standard_False); + if (aWhatHistoryLabel.IsNull()) { + // Removed entity + SetErrorCode(OK); + return NULL; + } + + Handle(TDataStd_IntegerArray) anIntegerArray; + if (!aWhatHistoryLabel.FindAttribute(TDataStd_IntegerArray::GetID(), anIntegerArray)) { + SetErrorCode("Error: Empty modifications history for the sought shape."); + return NULL; + } + + aModifiedArray = anIntegerArray->Array(); + if (aModifiedArray->Length() == 0) { + SetErrorCode("Error: Empty modifications history for the sought shape."); + return NULL; + } + } + } + + if (!isFound) { + SetErrorCode("The sought shape does not belong to any operation argument."); + return NULL; + } + } + + //Add a new object + Handle(GEOM_Object) aResult = GetEngine()->AddSubShape(theShapeWhere, aModifiedArray); + + if (aModifiedArray->Length() > 1) { + //Set a GROUP type + aResult->SetType(GEOM_GROUP); + + //Set a sub shape type + TDF_Label aFreeLabel = aResult->GetFreeLabel(); + TopAbs_ShapeEnum aShapeType = aWhat.ShapeType(); + TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aShapeType); + } + + //Make a Python command + TCollection_AsciiString anEntry, aDescr; + TDF_Tool::Entry(aResult->GetEntry(), anEntry); + aDescr += anEntry; + aDescr += " = geompy.GetInPlace("; + TDF_Tool::Entry(theShapeWhere->GetEntry(), anEntry); + aDescr += anEntry + ","; + TDF_Tool::Entry(theShapeWhat->GetEntry(), anEntry); + aDescr += anEntry + ")"; + + Handle(GEOM_Function) aFunction = aResult->GetFunction(1); + aFunction->SetDescription(aDescr); + + SetErrorCode(OK); + return aResult; +} //======================================================================= //function : SortShapes