Salome HOME
Bug #168: filter for invalid polyline.
[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 bool HYDROData_Tool::IsGeometryObject( const Handle(HYDROData_Entity)& theObject )
127 {
128   if ( theObject.IsNull() )
129     return false;
130   
131   return theObject->IsKind( STANDARD_TYPE(HYDROData_ArtificialObject) ) ||
132          theObject->IsKind( STANDARD_TYPE(HYDROData_NaturalObject) );
133 }
134
135 void HYDROData_Tool::UpdateChildObjectName( const QString&                  theOldStr,
136                                             const QString&                  theNewStr,
137                                             const Handle(HYDROData_Entity)& theObject )
138 {
139   if ( theObject.IsNull() )
140     return;
141
142   QString anObjName = theObject->GetName();
143   if ( theOldStr.isEmpty() )
144   {
145     while ( anObjName.startsWith( '_' ) )
146       anObjName.remove( 0, 1 );
147
148     anObjName.prepend( theNewStr + "_" );
149   }
150   else if ( anObjName.startsWith( theOldStr ) )
151   {
152     anObjName.replace( 0, theOldStr.length(), theNewStr );
153   }
154   else
155     return;
156
157   theObject->SetName( anObjName );
158 }
159
160 QString HYDROData_Tool::GenerateNameForPython( const MapOfTreatedObjects& theTreatedObjects,
161                                                const QString&             thePrefix )
162 {
163   QString aName = thePrefix;
164   if ( !theTreatedObjects.contains( aName ) )
165     return aName;
166
167   int anId = 1;
168   while( anId < aMaxNameId )
169   {
170     aName = QString( "%1_%2" ).arg( thePrefix ).arg( QString::number( anId++ ) );
171
172     // check that there are no other objects with the same name
173     if ( !theTreatedObjects.contains( aName ) )
174       break;
175   }
176
177   return aName;
178 }
179 //======================================================================================================
180 // the Face to be: planer, whitout holes
181 #ifdef CLASS2D
182 TopAbs_State HYDROData_Tool::ComputePointState( const gp_XY& thePnt2d, const TopoDS_Face& theFace )
183 {
184   TopAbs_State aState(TopAbs_UNKNOWN);
185   if(theFace.IsNull()) return aState;  
186
187 #ifdef CLASS2D     
188   TopoDS_Wire aWire; int nb(0);
189   TopoDS_Iterator it(theFace);
190   for(;it.More();it.Next()) {
191           aWire = TopoDS::Wire(it.Value());
192           nb++;
193   }
194   if(nb > 1 || aWire.IsNull()) return aState;
195   gp_Pln aPlane;
196   gp_Vec aNormal;
197   BRepBuilderAPI_FindPlane fndPlane (theFace, Precision::Confusion());
198   if(fndPlane.Found())
199     aPlane = fndPlane.Plane()->Pln();
200   else
201     return aState;
202   aNormal = gp_Vec(aPlane.Axis().Direction());
203   if(theFace.Orientation() == TopAbs_REVERSED) 
204     aNormal.Reverse();
205   gp_Pnt aPoint = gp_Pnt (thePnt2d.X(), thePnt2d.Y(), 0);
206   TColgp_SequenceOfVec aSeq;
207   TopTools_MapOfShape aMap;
208   it.Initialize(aWire);
209   for (;it.More(); it.Next()) {
210         const TopoDS_Vertex& aVx = TopExp::FirstVertex(TopoDS::Edge(it.Value()), Standard_True);
211         if(!aMap.Add(aVx))
212           continue;
213         const gp_Pnt& aCurPnt = BRep_Tool::Pnt(TopoDS::Vertex(aVx));
214         if(aPoint.IsEqual(aCurPnt,Precision::Confusion())) {
215       aState = TopAbs_ON;
216           return aState;
217         }
218         gp_Vec aVec (aPoint, aCurPnt);
219         aSeq.Append(aVec);
220   }
221   Standard_Real anAng(0.0);
222   for(int i = 1;i < aSeq.Length();i++) {
223     const gp_Vec& aV1 = aSeq.Value(i);
224         const gp_Vec& aV2 = aSeq.Value(i+1);
225          anAng += aV1.AngleWithRef(aV2, aNormal);
226   }
227   anAng += aSeq.Value(aSeq.Length()).AngleWithRef(aSeq.Value(1), aNormal);
228   if(abs(anAng) > Precision::Angular())
229     aState = TopAbs_IN;
230   else
231          aState = TopAbs_OUT;
232
233 #else
234   BRepTopAdaptor_FClass2d aClassifier( theFace, Precision::Confusion() ); 
235   aState = aClassifier.Perform( gp_Pnt2d( thePoint ), Standard_False );
236 #endif
237   return aState;
238 }
239 #endif