Salome HOME
e5b45109b0f778544d8d0866a31437d952a26530
[modules/hydro.git] / src / HYDROData / HYDROData_Tool.cxx
1
2 #include "HYDROData_Tool.h"
3
4 #include "HYDROData_ArtificialObject.h"
5 #include "HYDROData_Image.h"
6 #include "HYDROData_Iterator.h"
7 #include "HYDROData_NaturalObject.h"
8
9 #include <TopTools_SequenceOfShape.hxx>
10 #include <TopExp_Explorer.hxx>
11
12 #include <QFile>
13 #include <QStringList>
14 #include <QTextStream>
15
16 #include <limits>
17 #define CLASS2D 1
18 #ifdef CLASS2D
19 #include <gp_Pnt.hxx>
20 #include <gp_Vec.hxx>
21 #include <gp_Pln.hxx>
22 #include <TopExp.hxx>
23 #include <Geom_Plane.hxx>
24 #include <BRep_Tool.hxx>
25 #include <BRepBuilderAPI_FindPlane.hxx>
26 #include <TopoDS.hxx>
27 #include <TopoDS_Vertex.hxx>
28 #include <TopoDS_Wire.hxx>
29 #include <TopoDS_Face.hxx>
30 #include <TopoDS_Iterator.hxx>
31 #include <TopTools_MapOfShape.hxx>
32 #include <TColgp_SequenceOfVec.hxx>
33 #include <TopTools_ShapeMapHasher.hxx>
34 #undef _NCollection_MapHasher
35 #endif
36 static int aMaxNameId = std::numeric_limits<int>::max();
37
38 void HYDROData_Tool::WriteStringsToFile( QFile&             theFile,
39                                          const QStringList& theStrings,
40                                          const QString&     theSep )
41 {
42   if ( !theFile.isOpen() || theStrings.isEmpty() )
43     return;
44   
45   QString aWriteStr = theStrings.join( theSep );
46   if ( aWriteStr.isEmpty() )
47     return;
48
49   QTextStream anOutStream( &theFile );
50   anOutStream << aWriteStr << theSep << theSep;
51 }
52
53 void HYDROData_Tool::SetMustBeUpdatedObjects(
54   const Handle(HYDROData_Document)& theDoc  )
55 {
56   bool anIsChanged = true;
57
58   // iterate until there is no changes because objects on all level of dependency must be updated
59   while ( anIsChanged )
60   {
61     anIsChanged = false;
62
63     HYDROData_Iterator anIter( theDoc );
64     for ( ; anIter.More(); anIter.Next() )
65     {
66       Handle(HYDROData_Entity) anObject = anIter.Current();
67       if ( anObject.IsNull() || anObject->IsMustBeUpdated() )
68         continue;
69
70       HYDROData_SequenceOfObjects aRefSeq = anObject->GetAllReferenceObjects();
71       for ( int i = 1, n = aRefSeq.Length(); i <= n; ++i )
72       {
73         Handle(HYDROData_Entity) aRefObject = aRefSeq.Value( i );
74         if ( aRefObject.IsNull() || !aRefObject->IsMustBeUpdated() )
75           continue;
76
77         anObject->SetToUpdate( true );
78         anIsChanged = true;
79         break;
80       }
81     }
82   }
83 }
84
85 QString HYDROData_Tool::GenerateObjectName( const Handle(HYDROData_Document)& theDoc,
86                                             const QString&                    thePrefix,
87                                             const QStringList&                theUsedNames,
88                                             const bool                        theIsTryToUsePurePrefix )
89 {
90   QStringList aNamesList( theUsedNames );
91
92   // Collect all used names in the document
93   HYDROData_Iterator anIter( theDoc );
94   for( ; anIter.More(); anIter.Next() )
95   {
96     Handle(HYDROData_Entity) anObject = anIter.Current();
97     if( anObject.IsNull() )
98       continue;
99
100     QString anObjName = anObject->GetName();
101     if ( anObjName.isEmpty() )
102       continue;
103
104     aNamesList.append( anObjName );
105   }
106
107   QString aName;
108
109   if ( theIsTryToUsePurePrefix && !aNamesList.contains( thePrefix ) ) {
110     aName = thePrefix;
111   } else {
112     int anId = 1;
113     while( anId < aMaxNameId )
114     {
115       aName = QString( "%1_%2" ).arg( thePrefix ).arg( QString::number( anId++ ) );
116
117       // check that there are no other objects with the same name in the document
118       if ( !aNamesList.contains( aName ) )
119         break;
120     }
121   }
122
123   return aName;
124 }
125
126 Handle(HYDROData_Entity) HYDROData_Tool::FindObjectByName( const Handle(HYDROData_Document)& theDoc,
127                                                            const QString&                    theName,
128                                                            const ObjectKind                  theObjectKind )
129 {
130   Handle(HYDROData_Entity) anObject;
131   if ( theName.isEmpty() || theDoc.IsNull() )
132     return anObject;
133
134   QStringList aNamesList;
135   aNamesList << theName;
136
137   HYDROData_SequenceOfObjects aSeqOfObjs = FindObjectsByNames( theDoc, aNamesList, theObjectKind );
138   if( aSeqOfObjs.IsEmpty() )
139     return anObject;
140   
141   anObject = aSeqOfObjs.First();
142   return anObject;
143 }
144
145 HYDROData_SequenceOfObjects HYDROData_Tool::FindObjectsByNames( const Handle(HYDROData_Document)& theDoc,
146                                                                 const QStringList&                theNames,
147                                                                 const ObjectKind                  theObjectKind )
148 {
149   HYDROData_SequenceOfObjects aResSeq;
150   if( theDoc.IsNull() )
151     return aResSeq;
152
153   QStringList aNamesList = theNames;
154
155   HYDROData_Iterator anIter( theDoc, theObjectKind );
156   for( ; anIter.More(); anIter.Next() )
157   {
158     Handle(HYDROData_Entity) anObject = anIter.Current();
159     if( anObject.IsNull() )
160       continue;
161
162     QString anObjName = anObject->GetName();
163     if ( anObjName.isEmpty() || !aNamesList.contains( anObjName ) )
164       continue;
165
166     aResSeq.Append( anObject );
167
168     aNamesList.removeAll( anObjName );
169     if ( aNamesList.isEmpty() )
170       break;
171   }
172
173   return aResSeq;
174 }
175
176 bool HYDROData_Tool::IsGeometryObject( const Handle(HYDROData_Entity)& theObject )
177 {
178   if ( theObject.IsNull() )
179     return false;
180   
181   return theObject->IsKind( STANDARD_TYPE(HYDROData_ArtificialObject) ) ||
182          theObject->IsKind( STANDARD_TYPE(HYDROData_NaturalObject) );
183 }
184
185 void HYDROData_Tool::UpdateChildObjectName( const QString&                  theOldStr,
186                                             const QString&                  theNewStr,
187                                             const Handle(HYDROData_Entity)& theObject )
188 {
189   if ( theObject.IsNull() )
190     return;
191
192   QString anObjName = theObject->GetName();
193   if ( theOldStr.isEmpty() )
194   {
195     while ( anObjName.startsWith( '_' ) )
196       anObjName.remove( 0, 1 );
197
198     anObjName.prepend( theNewStr + "_" );
199   }
200   else if ( anObjName.startsWith( theOldStr ) )
201   {
202     anObjName.replace( 0, theOldStr.length(), theNewStr );
203   }
204   else
205     return;
206
207   theObject->SetName( anObjName );
208 }
209
210 QString HYDROData_Tool::GenerateNameForPython( const MapOfTreatedObjects& theTreatedObjects,
211                                                const QString&             thePrefix )
212 {
213   QString aName = thePrefix;
214   if ( !theTreatedObjects.contains( aName ) )
215     return aName;
216
217   int anId = 1;
218   while( anId < aMaxNameId )
219   {
220     aName = QString( "%1_%2" ).arg( thePrefix ).arg( QString::number( anId++ ) );
221
222     // check that there are no other objects with the same name
223     if ( !theTreatedObjects.contains( aName ) )
224       break;
225   }
226
227   return aName;
228 }
229 //======================================================================================================
230 // the Face to be: planer, whitout holes
231 #ifdef CLASS2D
232 TopAbs_State HYDROData_Tool::ComputePointState( const gp_XY& thePnt2d, const TopoDS_Face& theFace )
233 {
234   TopAbs_State aState(TopAbs_UNKNOWN);
235   if(theFace.IsNull()) return aState;  
236
237 #ifdef CLASS2D     
238   TopoDS_Wire aWire; int nb(0);
239   TopoDS_Iterator it(theFace);
240   for(;it.More();it.Next()) {
241           aWire = TopoDS::Wire(it.Value());
242           nb++;
243   }
244   if(nb > 1 || aWire.IsNull()) return aState;
245   gp_Pln aPlane;
246   gp_Vec aNormal;
247   BRepBuilderAPI_FindPlane fndPlane (theFace, Precision::Confusion());
248   if(fndPlane.Found())
249     aPlane = fndPlane.Plane()->Pln();
250   else
251     return aState;
252   aNormal = gp_Vec(aPlane.Axis().Direction());
253   if(theFace.Orientation() == TopAbs_REVERSED) 
254     aNormal.Reverse();
255   gp_Pnt aPoint = gp_Pnt (thePnt2d.X(), thePnt2d.Y(), 0);
256   TColgp_SequenceOfVec aSeq;
257   TopTools_MapOfShape aMap;
258   it.Initialize(aWire);
259   for (;it.More(); it.Next()) {
260         const TopoDS_Vertex& aVx = TopExp::FirstVertex(TopoDS::Edge(it.Value()), Standard_True);
261         if(!aMap.Add(aVx))
262           continue;
263         const gp_Pnt& aCurPnt = BRep_Tool::Pnt(TopoDS::Vertex(aVx));
264         if(aPoint.IsEqual(aCurPnt,Precision::Confusion())) {
265       aState = TopAbs_ON;
266           return aState;
267         }
268         gp_Vec aVec (aPoint, aCurPnt);
269         aSeq.Append(aVec);
270   }
271   Standard_Real anAng(0.0);
272   for(int i = 1;i < aSeq.Length();i++) {
273     const gp_Vec& aV1 = aSeq.Value(i);
274         const gp_Vec& aV2 = aSeq.Value(i+1);
275          anAng += aV1.AngleWithRef(aV2, aNormal);
276   }
277   anAng += aSeq.Value(aSeq.Length()).AngleWithRef(aSeq.Value(1), aNormal);
278   if(abs(anAng) > Precision::Angular())
279     aState = TopAbs_IN;
280   else
281          aState = TopAbs_OUT;
282
283 #else
284   BRepTopAdaptor_FClass2d aClassifier( theFace, Precision::Confusion() ); 
285   aState = aClassifier.Perform( gp_Pnt2d( thePoint ), Standard_False );
286 #endif
287   return aState;
288 }
289 #endif