X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FHYDROData%2FHYDROData_Tool.cxx;h=b45c2970d3c220b85e956b9e578b388318c434c3;hb=fce3f1240b6161d7cb837344078e5943b90eca65;hp=9cb932d340a7066442e860a91959c030c7002799;hpb=010fbf49c40c5a990222597ad773a8877856e0a4;p=modules%2Fhydro.git diff --git a/src/HYDROData/HYDROData_Tool.cxx b/src/HYDROData/HYDROData_Tool.cxx index 9cb932d3..b45c2970 100644 --- a/src/HYDROData/HYDROData_Tool.cxx +++ b/src/HYDROData/HYDROData_Tool.cxx @@ -1,10 +1,60 @@ +// Copyright (C) 2014-2015 EDF-R&D +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// -#include "HYDROData_Tool.h" - +#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 + +static int aMaxNameId = INT_MAX; void HYDROData_Tool::WriteStringsToFile( QFile& theFile, const QStringList& theStrings, const QString& theSep ) @@ -17,5 +67,407 @@ void HYDROData_Tool::WriteStringsToFile( QFile& theFile, return; QTextStream anOutStream( &theFile ); - anOutStream << aWriteStr << theSep << theSep; + anOutStream << aWriteStr.toUtf8() << theSep << theSep; +} + +QString HYDROData_Tool::GenerateObjectName( const Handle(HYDROData_Document)& theDoc, + const QString& thePrefix, + const QStringList& theUsedNames, + const bool theIsTryToUsePurePrefix ) +{ + QStringList aNamesList( theUsedNames ); + + // Collect all used names in the document + HYDROData_Iterator anIter( theDoc ); + for( ; anIter.More(); anIter.Next() ) + { + Handle(HYDROData_Entity) anObject = anIter.Current(); + if( anObject.IsNull() ) + continue; + + QString anObjName = anObject->GetName(); + if ( anObjName.isEmpty() ) + continue; + + aNamesList.append( anObjName ); + } + + QString aName; + + if ( theIsTryToUsePurePrefix && !aNamesList.contains( thePrefix ) ) { + aName = thePrefix; + } else { + int anId = 1; + while( anId < aMaxNameId ) + { + aName = QString( "%1_%2" ).arg( thePrefix ).arg( QString::number( anId++ ) ); + + // check that there are no other objects with the same name in the document + if ( !aNamesList.contains( aName ) ) + break; + } + } + + return aName; +} + +bool HYDROData_Tool::IsGeometryObject( const Handle(HYDROData_Entity)& theObject ) +{ + if ( theObject.IsNull() ) + return false; + + return theObject->IsKind( STANDARD_TYPE(HYDROData_ArtificialObject) ) || + theObject->IsKind( STANDARD_TYPE(HYDROData_NaturalObject) ); +} + +void HYDROData_Tool::UpdateChildObjectName( const QString& theOldStr, + const QString& theNewStr, + const Handle(HYDROData_Entity)& theObject ) +{ + if ( theObject.IsNull() ) + return; + + QString anObjName = theObject->GetName(); + if ( theOldStr.isEmpty() ) + { + while ( anObjName.startsWith( '_' ) ) + anObjName.remove( 0, 1 ); + + anObjName.prepend( theNewStr + "_" ); + } + else if ( anObjName.startsWith( theOldStr ) ) + { + anObjName.replace( 0, theOldStr.length(), theNewStr ); + } + else + return; + + theObject->SetName( anObjName ); +} + +QString HYDROData_Tool::GenerateNameForPython( const MapOfTreatedObjects& theTreatedObjects, + const QString& thePrefix ) +{ + QString aName = thePrefix; + if ( !theTreatedObjects.contains( aName ) ) + return aName; + + int anId = 1; + while( anId < aMaxNameId ) + { + aName = QString( "%1_%2" ).arg( thePrefix ).arg( QString::number( anId++ ) ); + + // check that there are no other objects with the same name + if ( !theTreatedObjects.contains( aName ) ) + break; + } + + return aName; +} +//====================================================================================================== +TopAbs_State HYDROData_Tool::ComputePointState( const gp_XY& theXY, const TopoDS_Face& theFace ) +{ + TopAbs_State aState(TopAbs_UNKNOWN); + if(theFace.IsNull()) return aState; + Standard_Real aTol = BRep_Tool::Tolerance(theFace); + BRepAdaptor_Surface Ads ( theFace, Standard_False ); + Standard_Real toluv = Min ( Ads.UResolution(aTol), Ads.VResolution(aTol) ); + const gp_Pln& aPlane = Ads.Surface().Plane(); + gp_Pnt aPnt(theXY.X(), theXY.Y(), 0.); + Standard_Real aU1, aV1; + ElSLib::Parameters(aPlane,aPnt, aU1, aV1); + BRepTopAdaptor_FClass2d aClassifier( theFace, toluv ); + aState = aClassifier.Perform( gp_Pnt2d(aU1, aV1), Standard_False ); + return aState; +} + +double HYDROData_Tool::GetAltitudeForEdge( const TopoDS_Edge& theEdge, + const gp_XY& thePoint, + double theParameterTolerance, + double theSquareDistanceTolerance, + double theInvalidAltitude ) +{ + double aFirst, aLast; + Handle(Geom_Curve) aCurve = BRep_Tool::Curve( theEdge, aFirst, aLast ); + if( aCurve.IsNull() ) + return theInvalidAltitude; + + gp_Pnt aFirstPnt, aLastPnt; + + aCurve->D0( aFirst, aFirstPnt ); + aCurve->D0( aLast, aLastPnt ); + + gp_Pnt2d aFirstPnt2d( aFirstPnt.X(), aFirstPnt.Y() ); + gp_Pnt2d aLastPnt2d( aLastPnt.X(), aLastPnt.Y() ); + + double aFirstDist = 0; + double aLastDist = aFirstPnt2d.SquareDistance( aLastPnt2d ); + double aNecDist = aFirstPnt2d.SquareDistance( thePoint ); + + while( fabs( aLast - aFirst ) > theParameterTolerance ) + { + double aMid = ( aFirst + aLast ) / 2; + gp_Pnt aMidPnt; + aCurve->D0( aMid, aMidPnt ); + double aDist = aFirstPnt2d.SquareDistance( gp_Pnt2d( aMidPnt.X(), aMidPnt.Y() ) ); + + if( aDist < aNecDist ) + aFirst = aMid; + else + aLast = aMid; + } + + double aMid = ( aFirst + aLast ) / 2; + gp_Pnt aMidPnt; + aCurve->D0( aMid, aMidPnt ); + + gp_Pnt2d aMidPnt2d( aMidPnt.X(), aMidPnt.Y() ); + if( aMidPnt2d.SquareDistance( thePoint ) < theSquareDistanceTolerance ) + return aMidPnt.Z(); + else + return theInvalidAltitude; +} + +double HYDROData_Tool::GetAltitudeForWire( const TopoDS_Wire& theWire, + const gp_XY& thePoint, + double theParameterTolerance, + double theSquareDistanceTolerance, + double theInvalidAltitude ) +{ + TopExp_Explorer anExp( theWire, TopAbs_EDGE ); + for( ; anExp.More(); anExp.Next() ) + { + double anAltitude = GetAltitudeForEdge( TopoDS::Edge( anExp.Current() ), thePoint, + theParameterTolerance, theSquareDistanceTolerance, theInvalidAltitude ); + if( anAltitude != theInvalidAltitude ) + return anAltitude; + } + return theInvalidAltitude; +} + +TopoDS_Shape HYDROData_Tool::getFirstShapeFromGroup( const HYDROData_SequenceOfObjects& theGroups, + const int theGroupId ) +{ + TopoDS_Shape aResShape; + if ( theGroupId < 1 || theGroupId > theGroups.Length() ) + return aResShape; + + Handle(HYDROData_ShapesGroup) aGroup = + Handle(HYDROData_ShapesGroup)::DownCast( theGroups.Value( theGroupId ) ); + if ( aGroup.IsNull() ) + return aResShape; + + TopTools_SequenceOfShape aGroupShapes; + aGroup->GetShapes( aGroupShapes ); + + if ( !aGroupShapes.IsEmpty() ) + aResShape = aGroupShapes.First(); + + return aResShape; +} + +TCollection_ExtendedString HYDROData_Tool::toExtString( const QString& theStr ) +{ + TCollection_ExtendedString aRes; + if( !theStr.isEmpty() ) + { + Standard_ExtString extStr = new Standard_ExtCharacter[ ( theStr.length() + 1 ) * 2 ]; + memcpy( (void*)extStr, theStr.unicode(), theStr.length() * 2 ); + ((short*)extStr)[theStr.length()] = '\0'; + aRes = TCollection_ExtendedString( extStr ); + delete [] extStr; + } + return aRes; +} + +QString HYDROData_Tool::toQString( const TCollection_ExtendedString& theStr ) +{ + return QString( (QChar*)theStr.ToExtString(), theStr.Length() ); +} + +Quantity_Color HYDROData_Tool::toOccColor( const QColor& theColor ) +{ + double r = theColor.red() / 255.0; + double g = theColor.green() / 255.0; + double b = theColor.blue() / 255.0; + + return Quantity_Color( r, g, b, Quantity_TOC_RGB ); +} + +QColor HYDROData_Tool::toQtColor( const Quantity_Color& theColor ) +{ + int r = 255 * theColor.Red(); + int g = 255 * theColor.Green(); + int b = 255 * theColor.Blue(); + return QColor( r, g, b ); +} + +bool HYDROData_Tool::IsNan( double theValue ) +{ +#ifdef WIN32 + return _isnan( theValue ); +#else + return isnan( theValue ); +#endif +} + +bool HYDROData_Tool::IsInf( double theValue ) +{ +#ifdef WIN32 + return (!_finite( theValue ) ); +#else + return isinf( theValue ); +#endif +} + +static void MakeShellG(const NCollection_Map& FG, + TopoDS_Shape& outSh) +{ + BRep_Builder bb; + NCollection_Map::Iterator itFG(FG); + if (FG.Extent() > 1) + { + //face nb > 1 => make shell + TopoDS_Shell outShell; + bb.MakeShell(outShell); + for (;itFG.More();itFG.Next()) + bb.Add(outShell, itFG.Value()); + outSh = outShell; + } + else if (FG.Extent() == 1) + { + outSh = itFG.Value(); //one face + } +} + +TopoDS_Shape HYDROData_Tool::RebuildCmp(const TopoDS_Shape& in) +{ + TopTools_IndexedDataMapOfShapeListOfShape mE2LF; + TopExp::MapShapesAndAncestors(in, TopAbs_EDGE, TopAbs_FACE, mE2LF); + if (mE2LF.IsEmpty()) + return TopoDS_Shape(); + NCollection_Map dfm; + //TopExp::MapShapes(aFuseShape, TopAbs_FACE, dfm); + TopExp_Explorer expf(in, TopAbs_FACE); + for (;expf.More(); expf.Next()) + dfm.Add(TopoDS::Face(expf.Current())); + + int nbF = dfm.Extent(); + TopExp_Explorer exp_f(in, TopAbs_FACE); + const TopoDS_Face& FF = TopoDS::Face(exp_f.Current()); + NCollection_List CurrFS; + NCollection_List NeighFS; + NCollection_Map PrF; + CurrFS.Append(FF); + NCollection_List> GL_F; + NCollection_Map OneGr; + bool end = false; + while (!end) + { + NCollection_List::Iterator it_currfs(CurrFS); + NeighFS.Clear(); + for (;it_currfs.More();it_currfs.Next()) + { + const TopoDS_Face& CF = it_currfs.Value(); + TopExp_Explorer exp_edge(CF, TopAbs_EDGE); + for (;exp_edge.More();exp_edge.Next()) + { + const TopoDS_Shape& CE = exp_edge.Current(); + const TopTools_ListOfShape& lsf = mE2LF.FindFromKey(CE); + TopTools_ListIteratorOfListOfShape ls_it(lsf); //always one face (since all faces are planar) + for (;ls_it.More();ls_it.Next()) + { + const TopoDS_Face& F = TopoDS::Face(ls_it.Value()); + if (F.IsSame(CF)) + continue; + if (!PrF.Contains(F)) + { + OneGr.Add(F); + NeighFS.Append(F); + PrF.Add(F); + } + } + } + OneGr.Add(CF); + PrF.Add(CF); + } + if (NeighFS.IsEmpty()) + { + GL_F.Append(OneGr); + OneGr.Clear(); + dfm.Subtract(PrF); + if (dfm.IsEmpty()) + end = true; + else + { + NCollection_Map::Iterator itDm(dfm); + const TopoDS_Face& nsh = itDm.Key(); + NeighFS.Append(nsh); + } + } + CurrFS = NeighFS; + } + + TopoDS_Shape sh; + + if (GL_F.Extent() > 1) + { + TopoDS_Compound cmp; + NCollection_List>::Iterator itGL_F(GL_F); + BRep_Builder bb; + bb.MakeCompound(cmp); + for (;itGL_F.More();itGL_F.Next()) + { + MakeShellG(itGL_F.Value(), sh); + if (!sh.IsNull()) + bb.Add(cmp, sh); + } + return cmp; + } + else if (GL_F.Extent() == 1) + { + MakeShellG(GL_F.First(), sh); + return sh; + } + +} + + +std::ostream& operator<<( std::ostream& theStream, const QString& theText ) +{ + theStream << theText.toStdString(); + return theStream; +} + +std::ostream& operator<<( std::ostream& theStream, const QColor& theColor ) +{ + theStream << "[" << theColor.red() << ", " << theColor.green() << ", " << theColor.blue() << "]"; + return theStream; +} + +std::ostream& operator<<( std::ostream& theStream, const TopoDS_Shape& theShape ) +{ + theStream << "[" << theShape.TShape().operator->() << "]"; + return theStream; +} + +std::ostream& operator<<( std::ostream& theStream, const TopoDS_Face& theFace ) +{ + theStream << "[" << theFace.TShape().operator->() << "]"; + return theStream; +} + +std::ostream& operator<<( std::ostream& theStream, const gp_XY& theXY ) +{ + theStream << "(" << theXY.X() << "; " << theXY.Y() << ")"; + return theStream; +} + +bool operator == ( const gp_XY& thePoint1, const gp_XY& thePoint2 ) +{ + const double EPS = 1E-3; + return + fabs( thePoint1.X() - thePoint2.X() ) < EPS && + fabs( thePoint1.Y() - thePoint2.Y() ) < EPS; + }