Salome HOME
Merge remote-tracking branch 'origin/master' into BR_LAND_COVER_MAP
[modules/hydro.git] / src / HYDROData / HYDROData_Tool.cxx
1 // Copyright (C) 2014-2015  EDF-R&D
2 // This library is free software; you can redistribute it and/or
3 // modify it under the terms of the GNU Lesser General Public
4 // License as published by the Free Software Foundation; either
5 // version 2.1 of the License, or (at your option) any later version.
6 //
7 // This library is distributed in the hope that it will be useful,
8 // but WITHOUT ANY WARRANTY; without even the implied warranty of
9 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
10 // Lesser General Public License for more details.
11 //
12 // You should have received a copy of the GNU Lesser General Public
13 // License along with this library; if not, write to the Free Software
14 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
15 //
16 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
17 //
18
19 #include <HYDROData_Tool.h>
20 #include <HYDROData_ArtificialObject.h>
21 #include <HYDROData_Document.h>
22 #include <HYDROData_Entity.h>
23 #include <HYDROData_Iterator.h>
24 #include <HYDROData_NaturalObject.h>
25 #include <HYDROData_ShapesGroup.h>
26 #include <QColor>
27 #include <QFile>
28 #include <QStringList>
29 #include <QTextStream>
30 #include <BRep_Tool.hxx>
31 #include <BRepAdaptor_Surface.hxx>
32 #include <BRepTopAdaptor_FClass2d.hxx>
33 #include <ElSLib.hxx>
34 #include <Geom_Curve.hxx>
35 #include <gp_Pln.hxx>
36 #include <TopExp_Explorer.hxx>
37 #include <TopoDS.hxx>
38 #include <TopoDS_Face.hxx>
39 #include <TopoDS_Shape.hxx>
40 #include <TopoDS_Wire.hxx>
41 #include <limits>
42
43 static int aMaxNameId = std::numeric_limits<int>::max();
44
45 void HYDROData_Tool::WriteStringsToFile( QFile&             theFile,
46                                          const QStringList& theStrings,
47                                          const QString&     theSep )
48 {
49   if ( !theFile.isOpen() || theStrings.isEmpty() )
50     return;
51   
52   QString aWriteStr = theStrings.join( theSep );
53   if ( aWriteStr.isEmpty() )
54     return;
55
56   QTextStream anOutStream( &theFile );
57   anOutStream << aWriteStr << theSep << theSep;
58 }
59
60 QString HYDROData_Tool::GenerateObjectName( const Handle(HYDROData_Document)& theDoc,
61                                             const QString&                    thePrefix,
62                                             const QStringList&                theUsedNames,
63                                             const bool                        theIsTryToUsePurePrefix )
64 {
65   QStringList aNamesList( theUsedNames );
66
67   // Collect all used names in the document
68   HYDROData_Iterator anIter( theDoc );
69   for( ; anIter.More(); anIter.Next() )
70   {
71     Handle(HYDROData_Entity) anObject = anIter.Current();
72     if( anObject.IsNull() )
73       continue;
74
75     QString anObjName = anObject->GetName();
76     if ( anObjName.isEmpty() )
77       continue;
78
79     aNamesList.append( anObjName );
80   }
81
82   QString aName;
83
84   if ( theIsTryToUsePurePrefix && !aNamesList.contains( thePrefix ) ) {
85     aName = thePrefix;
86   } else {
87     int anId = 1;
88     while( anId < aMaxNameId )
89     {
90       aName = QString( "%1_%2" ).arg( thePrefix ).arg( QString::number( anId++ ) );
91
92       // check that there are no other objects with the same name in the document
93       if ( !aNamesList.contains( aName ) )
94         break;
95     }
96   }
97
98   return aName;
99 }
100
101 bool HYDROData_Tool::IsGeometryObject( const Handle(HYDROData_Entity)& theObject )
102 {
103   if ( theObject.IsNull() )
104     return false;
105   
106   return theObject->IsKind( STANDARD_TYPE(HYDROData_ArtificialObject) ) ||
107          theObject->IsKind( STANDARD_TYPE(HYDROData_NaturalObject) );
108 }
109
110 void HYDROData_Tool::UpdateChildObjectName( const QString&                  theOldStr,
111                                             const QString&                  theNewStr,
112                                             const Handle(HYDROData_Entity)& theObject )
113 {
114   if ( theObject.IsNull() )
115     return;
116
117   QString anObjName = theObject->GetName();
118   if ( theOldStr.isEmpty() )
119   {
120     while ( anObjName.startsWith( '_' ) )
121       anObjName.remove( 0, 1 );
122
123     anObjName.prepend( theNewStr + "_" );
124   }
125   else if ( anObjName.startsWith( theOldStr ) )
126   {
127     anObjName.replace( 0, theOldStr.length(), theNewStr );
128   }
129   else
130     return;
131
132   theObject->SetName( anObjName );
133 }
134
135 QString HYDROData_Tool::GenerateNameForPython( const MapOfTreatedObjects& theTreatedObjects,
136                                                const QString&             thePrefix )
137 {
138   QString aName = thePrefix;
139   if ( !theTreatedObjects.contains( aName ) )
140     return aName;
141
142   int anId = 1;
143   while( anId < aMaxNameId )
144   {
145     aName = QString( "%1_%2" ).arg( thePrefix ).arg( QString::number( anId++ ) );
146
147     // check that there are no other objects with the same name
148     if ( !theTreatedObjects.contains( aName ) )
149       break;
150   }
151
152   return aName;
153 }
154 //======================================================================================================
155 TopAbs_State HYDROData_Tool::ComputePointState( const gp_XY& theXY, const TopoDS_Face& theFace )
156 {
157   TopAbs_State aState(TopAbs_UNKNOWN);
158   if(theFace.IsNull()) return aState;  
159   Standard_Real aTol = BRep_Tool::Tolerance(theFace);
160   BRepAdaptor_Surface Ads ( theFace, Standard_False );
161   Standard_Real toluv = Min ( Ads.UResolution(aTol), Ads.VResolution(aTol) ); 
162   const gp_Pln& aPlane = Ads.Surface().Plane();
163   gp_Pnt aPnt(theXY.X(), theXY.Y(), 0.);
164   Standard_Real aU1, aV1;
165   ElSLib::Parameters(aPlane,aPnt, aU1, aV1);
166   BRepTopAdaptor_FClass2d aClassifier( theFace, toluv ); 
167   aState = aClassifier.Perform( gp_Pnt2d(aU1, aV1), Standard_False );
168   return aState;
169 }
170
171 double HYDROData_Tool::GetAltitudeForEdge( const TopoDS_Edge& theEdge,
172                                            const gp_XY& thePoint,
173                                            double theParameterTolerance,
174                                            double theSquareDistanceTolerance,
175                                            double theInvalidAltitude )
176 {
177   double aFirst, aLast;
178   Handle(Geom_Curve) aCurve = BRep_Tool::Curve( theEdge, aFirst, aLast );
179   if( aCurve.IsNull() )
180     return theInvalidAltitude;
181
182   gp_Pnt aFirstPnt, aLastPnt;
183
184   aCurve->D0( aFirst, aFirstPnt );
185   aCurve->D0( aLast, aLastPnt );
186
187   gp_Pnt2d aFirstPnt2d( aFirstPnt.X(), aFirstPnt.Y() );
188   gp_Pnt2d aLastPnt2d( aLastPnt.X(), aLastPnt.Y() );
189
190   double aFirstDist = 0;
191   double aLastDist = aFirstPnt2d.SquareDistance( aLastPnt2d );
192   double aNecDist = aFirstPnt2d.SquareDistance( thePoint );
193
194   while( fabs( aLast - aFirst ) > theParameterTolerance )
195   {
196     double aMid = ( aFirst + aLast ) / 2;
197     gp_Pnt aMidPnt;
198     aCurve->D0( aMid, aMidPnt );
199     double aDist = aFirstPnt2d.SquareDistance( gp_Pnt2d( aMidPnt.X(), aMidPnt.Y() ) );
200
201     if( aDist < aNecDist )
202       aFirst = aMid;
203     else
204       aLast = aMid;
205   }
206
207   double aMid = ( aFirst + aLast ) / 2;
208   gp_Pnt aMidPnt;
209   aCurve->D0( aMid, aMidPnt );
210
211   gp_Pnt2d aMidPnt2d( aMidPnt.X(), aMidPnt.Y() );
212   if( aMidPnt2d.SquareDistance( thePoint ) < theSquareDistanceTolerance )
213     return aMidPnt.Z();
214   else
215     return theInvalidAltitude;
216 }
217
218 double HYDROData_Tool::GetAltitudeForWire( const TopoDS_Wire& theWire,
219                                            const gp_XY& thePoint,
220                                            double theParameterTolerance,
221                                            double theSquareDistanceTolerance,
222                                            double theInvalidAltitude )
223 {
224   TopExp_Explorer anExp( theWire, TopAbs_EDGE );
225   for( ; anExp.More(); anExp.Next() )
226   {
227     double anAltitude = GetAltitudeForEdge( TopoDS::Edge( anExp.Current() ), thePoint,
228       theParameterTolerance, theSquareDistanceTolerance, theInvalidAltitude );
229     if( anAltitude != theInvalidAltitude )
230       return anAltitude;
231   }
232   return theInvalidAltitude;
233 }
234
235 TopoDS_Shape HYDROData_Tool::getFirstShapeFromGroup( const HYDROData_SequenceOfObjects& theGroups,
236                                                      const int                          theGroupId )
237 {
238   TopoDS_Shape aResShape;
239   if ( theGroupId < 1 || theGroupId > theGroups.Length() )
240     return aResShape;
241
242   Handle(HYDROData_ShapesGroup) aGroup =
243     Handle(HYDROData_ShapesGroup)::DownCast( theGroups.Value( theGroupId ) );
244   if ( aGroup.IsNull() )
245     return aResShape;
246
247   TopTools_SequenceOfShape aGroupShapes;
248   aGroup->GetShapes( aGroupShapes );
249
250   if ( !aGroupShapes.IsEmpty() )
251     aResShape = aGroupShapes.First();
252
253   return aResShape;
254 }
255
256 TCollection_ExtendedString HYDROData_Tool::toExtString( const QString& theStr )
257 {
258   TCollection_ExtendedString aRes;
259   if( !theStr.isEmpty() )
260   {
261           Standard_ExtString extStr = new Standard_ExtCharacter[ ( theStr.length() + 1 ) * 2 ];
262           memcpy( (void*)extStr, theStr.unicode(), theStr.length() * 2 );
263           ((short*)extStr)[theStr.length()] = '\0';
264     aRes = TCollection_ExtendedString( extStr );
265           delete [] extStr;
266   }
267   return aRes;
268 }
269
270 QString HYDROData_Tool::toQString( const TCollection_ExtendedString& theStr )
271 {
272   return QString( (QChar*)theStr.ToExtString(), theStr.Length() );
273 }
274
275 std::ostream& operator<<( std::ostream& theStream, const QString& theText )
276 {
277   theStream << theText.toStdString();
278   return theStream;
279 }
280
281 std::ostream& operator<<( std::ostream& theStream, const QColor& theColor )
282 {
283   theStream << "[" << theColor.red() << ", " << theColor.green() << ", " << theColor.blue() << "]";
284   return theStream;
285 }
286
287 std::ostream& operator<<( std::ostream& theStream, const TopoDS_Shape& theShape )
288 {
289   theStream << "[" << theShape.TShape().operator->() << "]";
290   return theStream;
291 }
292
293 std::ostream& operator<<( std::ostream& theStream, const TopoDS_Face& theFace )
294 {
295   theStream << "[" << theFace.TShape().operator->() << "]";
296   return theStream;
297 }
298
299