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