X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FHYDROData%2FHYDROData_Stream.cxx;h=6a95bd0a69a94f730c791e599f126da3344d1cc4;hb=refs%2Ftags%2FBR_hydro_v_0_4;hp=061fa93576bcd5a669ab101be61c92a85c3c9886;hpb=3e0d42735e297e6c46a896443ba877a45678c194;p=modules%2Fhydro.git diff --git a/src/HYDROData/HYDROData_Stream.cxx b/src/HYDROData/HYDROData_Stream.cxx index 061fa935..6a95bd0a 100644 --- a/src/HYDROData/HYDROData_Stream.cxx +++ b/src/HYDROData/HYDROData_Stream.cxx @@ -10,6 +10,8 @@ #include #include +#include + #include #include #include @@ -27,9 +29,26 @@ #include #include #include +#include +#include +#include #include #include +#include +typedef NCollection_DataMap HYDROData_DataMapOfRealOfHDProfile; +//typedef HYDROData_DataMapOfRealOfHDProfile::Iterator HYDROData_DataMapIteratorOfDataMapOfRealOfHDProfile; +#include +#include +#include +#include +//#define DEB_HASINT 1 +#ifdef DEB_HASINT +#include +#include +#include +#endif + #define PYTHON_STREAM_ID "KIND_STREAM" IMPLEMENT_STANDARD_HANDLE(HYDROData_Stream,HYDROData_NaturalObject) @@ -219,8 +238,6 @@ bool HYDROData_Stream::HasIntersection( const Handle(HYDROData_Profile)& theProf if ( aHydraulicWire.IsNull() || aProfileWire.IsNull() ) return false; - // TODO - return true; // temporary BRepProj_Projection aProjector (aProfileWire, thePlane, gp::OZ().Direction()); if(!aProjector.IsDone()) return false; @@ -270,17 +287,19 @@ bool HYDROData_Stream::HasIntersection( const Handle(HYDROData_Profile)& theProf const TopoDS_Edge& anEdg1 = TopoDS::Edge(anExplo.Current()); if(anEdg1.IsNull()) continue; + Standard_Boolean hasSol(false); aCC.Perform(anEdg1); if(aCC.IsDone()) { + // find minimal dist for(Standard_Integer i=1; i<= aCC.NbExt();i++) if(aCC.SquareDistance(i) < aSqDist) { aSqDist = aCC.SquareDistance(i); anIndx = i; - hasInt = true; + hasSol = true; } } - if(hasInt) { - if(aSqDist <= SquareTolerance) { + if(hasSol) { + if(aSqDist <= SquareTolerance) { // hasInt const gp_Pnt& aPnt = aCC.PointOnE1(anIndx); if(aNum > 1) { TopExp::Vertices(anEdg1, aV1, aV2, Standard_True); @@ -289,34 +308,45 @@ bool HYDROData_Stream::HasIntersection( const Handle(HYDROData_Profile)& theProf Standard_Real aPar = aCC.ParameterOnE1(anIndx); outPar = aPar; } + hasInt = true; break; - } else { + } else { + // no ints-n if(aNum > 1) { TopExp::Vertices(anEdg1, aV1, aV2); outPar += BRep_Tool::Pnt(aV1).Distance(BRep_Tool::Pnt(aV2)); } } + } else if(aNum > 1) { + TopExp::Vertices(anEdg1, aV1, aV2); + outPar += BRep_Tool::Pnt(aV1).Distance(BRep_Tool::Pnt(aV2)); } } - return true; + if(hasInt) + return true; + return false; } + bool HYDROData_Stream::AddProfile( const Handle(HYDROData_Profile)& theProfile ) { if ( theProfile.IsNull() ) - return false; - gp_Ax2 aX2(gp::XOY()); - gp_Ax3 aX3(aX2); - gp_Pln aPln(aX3); - BRepBuilderAPI_MakeFace aMkr(aPln); - if(!aMkr.IsDone()) - return false; - const TopoDS_Face& aPlane = TopoDS::Face(aMkr.Shape()); + return false; + + Handle(HYDROData_PolylineXY) aHydAxis = GetHydraulicAxis(); + if ( aHydAxis.IsNull() ) + return false; + + TopoDS_Face aPlane; + if(!BuildFace(aHydAxis, aPlane)) + return false; + Standard_Real aPar(.0); if ( HasReference( theProfile, DataTag_Profile ) || !HasIntersection( theProfile, aPlane, aPar ) ) return false; // Object is already in reference list or it has no intersection - - insertProfileInToOrder( theProfile ); + + int aProfileIndex = insertParameter( aPar ); + insertProfileInToOrder( theProfile, aProfileIndex ); // Indicate model of the need to update the stream presentation SetToUpdate( true ); @@ -331,11 +361,35 @@ HYDROData_SequenceOfObjects HYDROData_Stream::GetProfiles() const bool HYDROData_Stream::RemoveProfile( const Handle(HYDROData_Profile)& theProfile ) { - if ( theProfile.IsNull() || !HasReference( theProfile, DataTag_Profile ) ) + if ( theProfile.IsNull() ) + return false; + + int aProfileIndex = -1; + + HYDROData_SequenceOfObjects aRefProfiles = GetProfiles(); + HYDROData_SequenceOfObjects::Iterator anIter( aRefProfiles ); + for ( int i = 0 ; anIter.More(); anIter.Next(), ++i ) + { + Handle(HYDROData_Profile) aProfile = + Handle(HYDROData_Profile)::DownCast( anIter.Value() ); + if ( aProfile.IsNull() ) + continue; + + if ( IsEqual( theProfile, aProfile ) ) + { + aProfileIndex = i; + break; + } + } + + if ( aProfileIndex == -1 ) return false; RemoveReferenceObject( theProfile->Label(), DataTag_Profile ); + // Remove parameter for removed profile + removeParameter( aProfileIndex ); + // Indicate model of the need to update the stream presentation SetToUpdate( true ); @@ -348,11 +402,15 @@ void HYDROData_Stream::RemoveProfiles() ClearReferenceObjects( DataTag_Profile ); + // Remove the parameters array + removeParametersArray(); + // Indicate model of the need to update the stream presentation SetToUpdate( anIsToUpdate ); } -void HYDROData_Stream::insertProfileInToOrder( const Handle(HYDROData_Profile)& theProfile ) +void HYDROData_Stream::insertProfileInToOrder( const Handle(HYDROData_Profile)& theProfile, + const int theBeforeIndex ) { Handle(HYDROData_PolylineXY) aHydAxis = GetHydraulicAxis(); if ( theProfile.IsNull() || aHydAxis.IsNull() ) @@ -363,8 +421,28 @@ void HYDROData_Stream::insertProfileInToOrder( const Handle(HYDROData_Profile)& if ( aHydraulicWire.IsNull() || aProfileWire.IsNull() ) return; - // TODO - AddReferenceObject( theProfile, DataTag_Profile ); // temporary for testing only + if ( theBeforeIndex == -1 ) + AddReferenceObject( theProfile, DataTag_Profile ); + else + InsertReferenceObject( theProfile, DataTag_Profile, theBeforeIndex ); +} + +bool HYDROData_Stream::BuildFace( const Handle(HYDROData_PolylineXY)& theHydAxis, TopoDS_Face& thePlane) const +{ + if ( theHydAxis.IsNull() ) return false; + TopoDS_Wire aHydraulicWire = TopoDS::Wire( theHydAxis->GetShape() ); + if(aHydraulicWire.IsNull()) return false; + gp_Ax2 aX2(gp::XOY()); + gp_Ax3 aX3(aX2); + gp_Pln aPln(aX3); + Bnd_Box B; + BRepBndLib::Add(aHydraulicWire,B); + Standard_Real axmin,aymin,azmin,axmax,aymax,azmax; + B.Get(axmin,aymin,azmin,axmax,aymax,azmax); + BRepBuilderAPI_MakeFace aMkr(aPln, axmin-500., axmax+500., aymin-500., aymax+500.); // to be tuned later according max/ Profile deviation + if(!aMkr.IsDone() || aMkr.Shape().IsNull()) return false; + thePlane = TopoDS::Face(aMkr.Shape()); + return true; } void HYDROData_Stream::updateProfilesOrder() @@ -378,24 +456,194 @@ void HYDROData_Stream::updateProfilesOrder() Handle(HYDROData_PolylineXY) aHydAxis = GetHydraulicAxis(); if ( aHydAxis.IsNull() ) + return; + + TopoDS_Face aPlane; + if ( !BuildFace( aHydAxis, aPlane ) ) return; - gp_Ax2 aX2(gp::XOY()); - gp_Ax3 aX3(aX2); - gp_Pln aPln(aX3); - BRepBuilderAPI_MakeFace aMkr(aPln); - if(!aMkr.IsDone()) - return; - const TopoDS_Face& aPlane = TopoDS::Face(aMkr.Shape()); - Standard_Real aPar(.0); + + Standard_Real aPar( .0 ); + +#ifdef DEB_HASINT + BRep_Builder aBB; + TopoDS_Compound aCmp; + aBB.MakeCompound(aCmp); +#endif + + HYDROData_DataMapOfRealOfHDProfile aDM; + TColStd_ListOfReal aList; HYDROData_SequenceOfObjects::Iterator anIter( aRefProfiles ); - for ( ; anIter.More(); anIter.Next() ) + for (int i = 1 ; anIter.More(); anIter.Next(), i++ ) { Handle(HYDROData_Profile) aProfile = Handle(HYDROData_Profile)::DownCast( anIter.Value() ); +#ifdef DEB_HASINT + TopoDS_Wire aProfileWire = TopoDS::Wire( aProfile->GetTopShape() ); + aBB.Add( aCmp, aProfileWire ); +#endif if ( aProfile.IsNull() || !HasIntersection( aProfile, aPlane, aPar ) ) continue; + + aDM.Bind( aPar, aProfile ); + aList.Append( aPar ); + } + + if ( aList.IsEmpty() ) + return; - insertProfileInToOrder( aProfile ); + TColStd_Array1OfReal anArr( 1, aList.Extent() ); + + TColStd_ListIteratorOfListOfReal it( aList ); + for ( int j = 1; it.More(); it.Next(), j++ ) + anArr( j ) = it.Value(); + + // sorting + if ( aList.Extent() > 1 ) + { + TCollection_CompareOfReal Compar; + SortTools_QuickSortOfReal::Sort( anArr, Compar ); + + for (int j = 1; j <= anArr.Length(); j++) { + const Standard_Real aKey = anArr(j); + const Handle(HYDROData_Profile)& aProfile = aDM.Find(aKey); + insertProfileInToOrder( aProfile ); + } + } else if ( aList.Extent() == 1 ) { + const Standard_Real aKey = aList.Last(); + const Handle(HYDROData_Profile)& aProfile = aDM.Find(aKey); + insertProfileInToOrder( aProfile ); + } + + setParametersArray( anArr ); + +#ifdef DEB_HASINT + TopoDS_Wire aHydraulicWire = TopoDS::Wire( aHydAxis->GetShape() ); + BRepTools::Write(aHydraulicWire, "Path.brep"); + BRepTools::Write(aCmp, "Prof.brep"); +#endif +} + +void HYDROData_Stream::setParametersArray( const TColStd_Array1OfReal& theArray ) +{ + if ( theArray.Length() == 0 ) + { + removeParametersArray(); + return; + } + + TDF_Label aLabel = myLab.FindChild( DataTag_ParamsArray ); + + Handle(TDataStd_RealArray) aParamsArray = + TDataStd_RealArray::Set( aLabel, theArray.Lower(), theArray.Upper() ); + + for ( int i = theArray.Lower(), n = theArray.Upper(); i <= n; ++i ) + { + const Standard_Real& aParam = theArray( i ); + aParamsArray->SetValue( i, aParam ); } } +TColStd_Array1OfReal* HYDROData_Stream::getParametersArray() const +{ + TColStd_Array1OfReal* anArray = NULL; + + TDF_Label aLabel = myLab.FindChild( DataTag_ParamsArray, false ); + if ( !aLabel.IsNull() ) + { + Handle(TDataStd_RealArray) aParamsArray; + if ( aLabel.FindAttribute( TDataStd_RealArray::GetID(), aParamsArray ) ) + { + anArray = new TColStd_Array1OfReal( aParamsArray->Lower(), aParamsArray->Upper() ); + for ( int i = aParamsArray->Lower(), n = aParamsArray->Upper(); i <= n; ++i ) + { + const Standard_Real& aParam = aParamsArray->Value( i ); + anArray->SetValue( i, aParam ); + } + } + } + + return anArray; +} + +void HYDROData_Stream::removeParametersArray() +{ + TDF_Label aLabel = myLab.FindChild( DataTag_ParamsArray, false ); + if ( !aLabel.IsNull() ) + aLabel.ForgetAllAttributes(); +} + +int HYDROData_Stream::insertParameter( const Standard_Real& theParam ) +{ + int aResIndex = -1; + + TColStd_Array1OfReal* anArr = getParametersArray(); + if ( anArr ) + { + aResIndex = 0; + + TColStd_Array1OfReal aNewArr( anArr->Lower(), anArr->Upper() + 1 ); + + bool isInserted = false; + for ( int i = anArr->Lower(), j = i, n = anArr->Upper(); i <= n; ++i, ++j ) + { + const Standard_Real& aStoredParam = anArr->Value( i ); + if ( !isInserted ) + { + if ( theParam > aStoredParam ) + { + aResIndex++; + } + else + { + aNewArr( j ) = theParam; + isInserted = true; + ++j; + } + } + + aNewArr( j ) = aStoredParam; + } + + if ( !isInserted ) + { + aResIndex = -1; + aNewArr( aNewArr.Upper() ) = theParam; + } + + setParametersArray( aNewArr ); + delete anArr; + } + else + { + TColStd_Array1OfReal aNewArr( 1, 1 ); + aNewArr.SetValue( 1, theParam ); + setParametersArray( aNewArr ); + } + + return aResIndex; +} + +void HYDROData_Stream::removeParameter( const int& theIndex ) +{ + TDF_Label aLabel = myLab.FindChild( DataTag_ParamsArray, false ); + if ( aLabel.IsNull() ) + return; + + Handle(TDataStd_RealArray) aParamsArray; + if ( !aLabel.FindAttribute( TDataStd_RealArray::GetID(), aParamsArray ) ) + return; + + TColStd_Array1OfReal aNewArr( aParamsArray->Lower(), aParamsArray->Upper() - 1 ); + + for ( int i = aParamsArray->Lower(), j = i, k = 0, n = aParamsArray->Upper(); i <= n; ++i, ++k ) + { + const Standard_Real& aStoredParam = aParamsArray->Value( i ); + if ( k == theIndex ) + continue; + + aNewArr.SetValue( j, aStoredParam ); + ++j; + } + + setParametersArray( aNewArr ); +}