Salome HOME
refs #636: flags for geometry 2d/3d change
[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
21 #include "HYDROData_ArtificialObject.h"
22 #include "HYDROData_Image.h"
23 #include "HYDROData_Iterator.h"
24 #include "HYDROData_NaturalObject.h"
25 #include "HYDROData_ShapesGroup.h"
26
27 #include <QFile>
28 #include <QStringList>
29 #include <QTextStream>
30
31 #include <limits>
32 #include <gp_Pnt.hxx>
33 #include <gp_Pln.hxx>
34 #include <ElSLib.hxx>
35 #include <TopAbs_State.hxx>
36 #include <BRepAdaptor_Surface.hxx>
37 #include <BRepTopAdaptor_FClass2d.hxx>
38 #include <BRep_Tool.hxx>
39 #include <Geom_Curve.hxx>
40 #include <TopoDS.hxx>
41 #include <TopoDS_Wire.hxx>
42 #include <TopExp_Explorer.hxx>
43
44 static int aMaxNameId = std::numeric_limits<int>::max();
45
46 void HYDROData_Tool::WriteStringsToFile( QFile&             theFile,
47                                          const QStringList& theStrings,
48                                          const QString&     theSep )
49 {
50   if ( !theFile.isOpen() || theStrings.isEmpty() )
51     return;
52   
53   QString aWriteStr = theStrings.join( theSep );
54   if ( aWriteStr.isEmpty() )
55     return;
56
57   QTextStream anOutStream( &theFile );
58   anOutStream << aWriteStr << theSep << theSep;
59 }
60
61 QString HYDROData_Tool::GenerateObjectName( const Handle(HYDROData_Document)& theDoc,
62                                             const QString&                    thePrefix,
63                                             const QStringList&                theUsedNames,
64                                             const bool                        theIsTryToUsePurePrefix )
65 {
66   QStringList aNamesList( theUsedNames );
67
68   // Collect all used names in the document
69   HYDROData_Iterator anIter( theDoc );
70   for( ; anIter.More(); anIter.Next() )
71   {
72     Handle(HYDROData_Entity) anObject = anIter.Current();
73     if( anObject.IsNull() )
74       continue;
75
76     QString anObjName = anObject->GetName();
77     if ( anObjName.isEmpty() )
78       continue;
79
80     aNamesList.append( anObjName );
81   }
82
83   QString aName;
84
85   if ( theIsTryToUsePurePrefix && !aNamesList.contains( thePrefix ) ) {
86     aName = thePrefix;
87   } else {
88     int anId = 1;
89     while( anId < aMaxNameId )
90     {
91       aName = QString( "%1_%2" ).arg( thePrefix ).arg( QString::number( anId++ ) );
92
93       // check that there are no other objects with the same name in the document
94       if ( !aNamesList.contains( aName ) )
95         break;
96     }
97   }
98
99   return aName;
100 }
101
102 bool HYDROData_Tool::IsGeometryObject( const Handle(HYDROData_Entity)& theObject )
103 {
104   if ( theObject.IsNull() )
105     return false;
106   
107   return theObject->IsKind( STANDARD_TYPE(HYDROData_ArtificialObject) ) ||
108          theObject->IsKind( STANDARD_TYPE(HYDROData_NaturalObject) );
109 }
110
111 void HYDROData_Tool::UpdateChildObjectName( const QString&                  theOldStr,
112                                             const QString&                  theNewStr,
113                                             const Handle(HYDROData_Entity)& theObject )
114 {
115   if ( theObject.IsNull() )
116     return;
117
118   QString anObjName = theObject->GetName();
119   if ( theOldStr.isEmpty() )
120   {
121     while ( anObjName.startsWith( '_' ) )
122       anObjName.remove( 0, 1 );
123
124     anObjName.prepend( theNewStr + "_" );
125   }
126   else if ( anObjName.startsWith( theOldStr ) )
127   {
128     anObjName.replace( 0, theOldStr.length(), theNewStr );
129   }
130   else
131     return;
132
133   theObject->SetName( anObjName );
134 }
135
136 QString HYDROData_Tool::GenerateNameForPython( const MapOfTreatedObjects& theTreatedObjects,
137                                                const QString&             thePrefix )
138 {
139   QString aName = thePrefix;
140   if ( !theTreatedObjects.contains( aName ) )
141     return aName;
142
143   int anId = 1;
144   while( anId < aMaxNameId )
145   {
146     aName = QString( "%1_%2" ).arg( thePrefix ).arg( QString::number( anId++ ) );
147
148     // check that there are no other objects with the same name
149     if ( !theTreatedObjects.contains( aName ) )
150       break;
151   }
152
153   return aName;
154 }
155 //======================================================================================================
156 TopAbs_State HYDROData_Tool::ComputePointState( const gp_XY& theXY, const TopoDS_Face& theFace )
157 {
158   TopAbs_State aState(TopAbs_UNKNOWN);
159   if(theFace.IsNull()) return aState;  
160   Standard_Real aTol = BRep_Tool::Tolerance(theFace);
161   BRepAdaptor_Surface Ads ( theFace, Standard_False );
162   Standard_Real toluv = Min ( Ads.UResolution(aTol), Ads.VResolution(aTol) ); 
163   const gp_Pln& aPlane = Ads.Surface().Plane();
164   gp_Pnt aPnt(theXY.X(), theXY.Y(), 0.);
165   Standard_Real aU1, aV1;
166   ElSLib::Parameters(aPlane,aPnt, aU1, aV1);
167   BRepTopAdaptor_FClass2d aClassifier( theFace, toluv ); 
168   aState = aClassifier.Perform( gp_Pnt2d(aU1, aV1), Standard_False );
169   return aState;
170 }
171
172 double HYDROData_Tool::GetAltitudeForEdge( const TopoDS_Edge& theEdge,
173                                            const gp_XY& thePoint,
174                                            double theParameterTolerance,
175                                            double theSquareDistanceTolerance,
176                                            double theInvalidAltitude )
177 {
178   double aFirst, aLast;
179   Handle(Geom_Curve) aCurve = BRep_Tool::Curve( theEdge, aFirst, aLast );
180   if( aCurve.IsNull() )
181     return theInvalidAltitude;
182
183   gp_Pnt aFirstPnt, aLastPnt;
184
185   aCurve->D0( aFirst, aFirstPnt );
186   aCurve->D0( aLast, aLastPnt );
187
188   gp_Pnt2d aFirstPnt2d( aFirstPnt.X(), aFirstPnt.Y() );
189   gp_Pnt2d aLastPnt2d( aLastPnt.X(), aLastPnt.Y() );
190
191   double aFirstDist = 0;
192   double aLastDist = aFirstPnt2d.SquareDistance( aLastPnt2d );
193   double aNecDist = aFirstPnt2d.SquareDistance( thePoint );
194
195   while( fabs( aLast - aFirst ) > theParameterTolerance )
196   {
197     double aMid = ( aFirst + aLast ) / 2;
198     gp_Pnt aMidPnt;
199     aCurve->D0( aMid, aMidPnt );
200     double aDist = aFirstPnt2d.SquareDistance( gp_Pnt2d( aMidPnt.X(), aMidPnt.Y() ) );
201
202     if( aDist < aNecDist )
203       aFirst = aMid;
204     else
205       aLast = aMid;
206   }
207
208   double aMid = ( aFirst + aLast ) / 2;
209   gp_Pnt aMidPnt;
210   aCurve->D0( aMid, aMidPnt );
211
212   gp_Pnt2d aMidPnt2d( aMidPnt.X(), aMidPnt.Y() );
213   if( aMidPnt2d.SquareDistance( thePoint ) < theSquareDistanceTolerance )
214     return aMidPnt.Z();
215   else
216     return theInvalidAltitude;
217 }
218
219 double HYDROData_Tool::GetAltitudeForWire( const TopoDS_Wire& theWire,
220                                            const gp_XY& thePoint,
221                                            double theParameterTolerance,
222                                            double theSquareDistanceTolerance,
223                                            double theInvalidAltitude )
224 {
225   TopExp_Explorer anExp( theWire, TopAbs_EDGE );
226   for( ; anExp.More(); anExp.Next() )
227   {
228     double anAltitude = GetAltitudeForEdge( TopoDS::Edge( anExp.Current() ), thePoint,
229       theParameterTolerance, theSquareDistanceTolerance, theInvalidAltitude );
230     if( anAltitude != theInvalidAltitude )
231       return anAltitude;
232   }
233   return theInvalidAltitude;
234 }
235
236 TopoDS_Shape HYDROData_Tool::getFirstShapeFromGroup( const HYDROData_SequenceOfObjects& theGroups,
237                                                      const int                          theGroupId )
238 {
239   TopoDS_Shape aResShape;
240   if ( theGroupId < 1 || theGroupId > theGroups.Length() )
241     return aResShape;
242
243   Handle(HYDROData_ShapesGroup) aGroup =
244     Handle(HYDROData_ShapesGroup)::DownCast( theGroups.Value( theGroupId ) );
245   if ( aGroup.IsNull() )
246     return aResShape;
247
248   TopTools_SequenceOfShape aGroupShapes;
249   aGroup->GetShapes( aGroupShapes );
250
251   if ( !aGroupShapes.IsEmpty() )
252     aResShape = aGroupShapes.First();
253
254   return aResShape;
255 }