Salome HOME
refs #1501 p.2
[modules/hydro.git] / src / HYDROGUI / HYDROGUI_CurveCreatorProfile.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 <HYDROGUI_CurveCreatorProfile.h>
20 #include <CurveCreator_Displayer.hxx>
21 #include <CurveCreator_Section.hxx>
22 #include <QVector>
23
24 HYDROGUI_CurveCreatorProfile::HYDROGUI_CurveCreatorProfile()
25 : CurveCreator_Curve( CurveCreator::Dim2d )
26 {
27   CurveCreator_Section *aSection = new CurveCreator_Section;
28   aSection->myName     = getUniqSectionName();
29   aSection->myType     = CurveCreator::Polyline;
30   aSection->myIsClosed = false;
31
32   mySections.push_back( aSection );
33   mySkipSorting = true;
34 }
35
36 HYDROGUI_CurveCreatorProfile::~HYDROGUI_CurveCreatorProfile()
37 {
38 }
39
40 bool HYDROGUI_CurveCreatorProfile::moveSectionInternal( const int theISection,
41                                                         const int theNewIndex )
42 {
43   return false;
44 }
45
46 bool HYDROGUI_CurveCreatorProfile::moveSection( const int theISection,
47                                                 const int theNewIndex )
48 {
49   return false;
50 }
51
52 bool HYDROGUI_CurveCreatorProfile::clearInternal()
53 {
54   // erase curve from the viewer
55   if( myDisplayer )
56     myDisplayer->eraseAll( true );
57
58   // Delete all allocated data.
59   CurveCreator_Section* aSection = (CurveCreator_Section*)getSection( 0 );
60   if ( aSection )
61     aSection->myPoints.clear();
62
63   return true;
64 }
65
66 bool HYDROGUI_CurveCreatorProfile::joinInternal( const std::list<int>& theSections )
67 {
68   return false;
69 }
70
71 bool HYDROGUI_CurveCreatorProfile::join( const std::list<int>& theSections )
72 {
73   return false;
74 }
75
76 int HYDROGUI_CurveCreatorProfile::addSectionInternal( const std::string&               theName, 
77                                                       const CurveCreator::SectionType  theType,
78                                                       const bool                       theIsClosed, 
79                                                       const CurveCreator::Coordinates& thePoints )
80 {
81   return -1;
82 }
83
84 int HYDROGUI_CurveCreatorProfile::addSection( const std::string&              theName,
85                                               const CurveCreator::SectionType theType,
86                                               const bool                      theIsClosed )
87 {
88   return -1;
89 }
90
91 int HYDROGUI_CurveCreatorProfile::addSection( const std::string&               theName,
92                                               const CurveCreator::SectionType  theType,
93                                               const bool                       theIsClosed, 
94                                               const CurveCreator::Coordinates& thePoints )
95 {
96   return -1;
97 }
98
99 bool HYDROGUI_CurveCreatorProfile::removeSectionInternal( const int theISection )
100 {
101   return false;
102 }
103   
104 bool HYDROGUI_CurveCreatorProfile::removeSection( const int theISection )
105 {
106   return false;
107 }
108
109 bool HYDROGUI_CurveCreatorProfile::setClosedInternal( const int theISection, const bool theIsClosed )
110 {
111   return false;
112 }
113
114 bool HYDROGUI_CurveCreatorProfile::setClosed( const int theISection, const bool theIsClosed )
115 {
116   return false;
117 }
118
119 bool HYDROGUI_CurveCreatorProfile::addPointsInternal( const CurveCreator::SectionsMap &theSectionsMap )
120 {
121   bool res = false;
122
123   CurveCreator_Section* aSection = (CurveCreator_Section*)getSection( 0 );
124   if( !aSection )
125     return res;
126
127   CurveCreator::SectionsMap::const_iterator anIt = theSectionsMap.begin();
128   for ( ; anIt != theSectionsMap.end(); anIt++ )
129   {
130     int anISection = anIt->first;
131     if( anISection != 0 )
132       continue;
133
134     const CurveCreator::PosPointsList& aSectionPoints = anIt->second;
135
136     CurveCreator::PosPointsList::const_iterator aPntIt = aSectionPoints.begin();
137     for( ; aPntIt != aSectionPoints.end(); aPntIt++ )
138     {
139       const CurveCreator::Coordinates& aNewCoords = (*aPntIt)->myCoords;
140       CurveCreator::Coordinates::const_iterator aNewPntIt = aNewCoords.begin();
141       for( ; aNewPntIt != aNewCoords.end(); aNewPntIt++ )
142       {
143         const CurveCreator::TypeCoord& aCoordU = *aNewPntIt++;
144         if ( aNewPntIt == aNewCoords.end() )
145           break;
146         
147         const CurveCreator::TypeCoord& aCoordZ = *aNewPntIt;
148
149         CurveCreator::TypeCoord aC = aCoordU - 1;
150         if ( !aSection->myPoints.empty() )
151           aC = *(aSection->myPoints.end() - 2);
152
153         if ( aSection->myPoints.empty() || aCoordU >= aC )
154         {
155           aSection->myPoints.push_back( aCoordU );
156           aSection->myPoints.push_back( aCoordZ );
157         }
158         else if ( aCoordU < aSection->myPoints.front() )
159         {
160           aSection->myPoints.push_front( aCoordZ );
161           aSection->myPoints.push_front( aCoordU );
162         }
163         else
164         {
165           CurveCreator::Coordinates::iterator aRefPntIt = aSection->myPoints.begin();
166           for( ; aRefPntIt != aSection->myPoints.end(); aRefPntIt++ )
167           {
168             const CurveCreator::TypeCoord& aRefCoordU = *aRefPntIt++;
169             if ( aCoordU < aRefCoordU )
170               break;
171           }
172
173           aSection->myPoints.insert( aRefPntIt - 1, aNewPntIt - 1, aNewPntIt + 1 );
174         }
175       }
176     }
177
178     res = true;
179   }
180
181   if ( res )
182     redisplayCurve(false);
183
184   return res;
185 }
186
187 //! For internal use only! Undo/Redo are not used here.
188 bool HYDROGUI_CurveCreatorProfile::setPointInternal( const CurveCreator::SectionsMap &theSectionsMap )
189 {
190   bool aRes = false;
191
192   if ( mySkipSorting ) {
193     return CurveCreator_Curve::setPointInternal( theSectionsMap );
194   }
195
196   int anISection = 0;
197   CurveCreator_Section* aSection = (CurveCreator_Section*)getSection( anISection );
198   if( !aSection )
199     return aRes;
200
201   CurveCreator::SectionsMap::const_iterator anIt = theSectionsMap.begin();
202   if ( anIt == theSectionsMap.end() )
203     return aRes;
204
205   const CurveCreator::PosPointsList& aSectionPoints = anIt->second;
206
207   std::list<int> aConvPoints;
208   convert( aSectionPoints, aConvPoints );
209   removeSectionPoints( anISection, aConvPoints );
210
211   aRes = addPointsInternal( theSectionsMap );
212   if ( aRes )
213     redisplayCurve(false);
214
215   return aRes;
216 }
217
218 void HYDROGUI_CurveCreatorProfile::convert( const CurveCreator::PosPointsList& thePoints,
219                                             std::list<int>& theConvPoints )
220 {
221   theConvPoints.clear();
222
223   CurveCreator::PosPointsList::const_iterator aPntIt = thePoints.begin(),
224                                               aPntLast = thePoints.end();
225   for( ; aPntIt != aPntLast; aPntIt++ )
226   {
227     int anIPnt = (*aPntIt)->myID;
228     theConvPoints.push_back( anIPnt );
229   }
230 }
231
232 bool HYDROGUI_CurveCreatorProfile::canPointsBeSorted()
233 {
234   return false;
235 }
236
237 /**
238  *  Add one point to the specified section starting from the given theIPnt index
239  *  (or at the end of points if \a theIPnt is -1).
240  */
241 bool HYDROGUI_CurveCreatorProfile::addPoints( const CurveCreator::Coordinates& theCoords,
242                                               const int theISection,
243                                               const int theIPnt )
244 {
245   int anIPnt = theIPnt;
246
247   if ( anIPnt == - 1 && theCoords.size() > 1 ) {
248     CurveCreator::Coordinates aCoords;
249     for ( int i = 0, aNb = getNbPoints( theISection ); i < aNb; i++ ) {
250       aCoords = getPoint( theISection, i );
251       if ( aCoords.size() < 2 ) {
252         continue;
253       }
254
255       if ( theCoords[0] < aCoords[0] ) {
256         anIPnt = i;
257         break;
258       }
259     }
260   }
261   
262   return CurveCreator_Curve::addPoints( theCoords, theISection, anIPnt );
263 }
264
265 bool ULess( const gp_Pnt& p1, const gp_Pnt& p2 )
266 {
267   return p1.X() < p2.X();
268 }
269
270 Handle(TColgp_HArray1OfPnt) HYDROGUI_CurveCreatorProfile::GetDifferentPoints( int theISection ) const
271 {
272   Handle(TColgp_HArray1OfPnt) points = CurveCreator_Curve::GetDifferentPoints( theISection );
273   if( points.IsNull() )
274     return points;
275
276   QVector<gp_Pnt> vpoints( points->Size() );
277   for( int i=points->Lower(), j=0, n=points->Upper(); i<=n; i++, j++ )
278     vpoints[j] = points->Value( i );
279
280   qSort( vpoints.begin(), vpoints.end(), ULess );
281
282   for( int i=points->Lower(), j=0, n=points->Upper(); i<=n; i++, j++ )
283     points->SetValue( i, vpoints[j] );
284
285   return points;
286 }