Salome HOME
Ref #250 - Fatal error after Join all selections operation
[modules/hydro.git] / src / HYDROCurveCreator / CurveCreator_Profile.cxx
1 // Copyright (C) 2013  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19
20 #include "CurveCreator_Profile.hxx"
21
22 #include "CurveCreator.hxx"
23 #include "CurveCreator_PosPoint.hxx"
24 #include "CurveCreator_Section.hxx"
25 #include "CurveCreator_Displayer.h"
26
27 #include <BRepBuilderAPI_MakeEdge.hxx>
28 #include <BRepBuilderAPI_MakeWire.hxx>
29 #include <Geom_CartesianPoint.hxx>
30 #include <gp_Pnt.hxx>
31 #include <gp_Lin.hxx>
32 #include <TopoDS_Edge.hxx>
33 #include <TopoDS_Face.hxx>
34 #include <TopoDS_Wire.hxx>
35 #include <TColgp_HArray1OfPnt.hxx>
36 #include <GeomAPI_Interpolate.hxx>
37
38 #include <stdio.h>
39
40 CurveCreator_Profile::CurveCreator_Profile()
41 : CurveCreator_Curve( CurveCreator::Dim2d )
42 {
43   CurveCreator_Section *aSection = new CurveCreator_Section;
44   aSection->myName     = getUniqSectionName();
45   aSection->myType     = CurveCreator::Polyline;
46   aSection->myIsClosed = false;
47
48   mySections.push_back( aSection );
49 }
50
51 CurveCreator_Profile::~CurveCreator_Profile()
52 {
53 }
54
55 bool CurveCreator_Profile::moveSectionInternal( const int theISection,
56                                                 const int theNewIndex )
57 {
58   return false;
59 }
60
61 bool CurveCreator_Profile::moveSection( const int theISection,
62                                         const int theNewIndex )
63 {
64   return false;
65 }
66
67 bool CurveCreator_Profile::clearInternal()
68 {
69   // erase curve from the viewer
70   if( myDisplayer )
71     myDisplayer->eraseAll( true );
72
73   // Delete all allocated data.
74   mySections[ 0 ]->myPoints.clear();
75
76   return true;
77 }
78
79 bool CurveCreator_Profile::joinInternal( const std::list<int>& theSections )
80 {
81   return false;
82 }
83
84 bool CurveCreator_Profile::join( const std::list<int>& theSections )
85 {
86   return false;
87 }
88
89 int CurveCreator_Profile::addSectionInternal( const std::string&               theName, 
90                                               const CurveCreator::SectionType  theType,
91                                               const bool                       theIsClosed, 
92                                               const CurveCreator::Coordinates& thePoints )
93 {
94   return -1;
95 }
96
97 int CurveCreator_Profile::addSection( const std::string&              theName,
98                                       const CurveCreator::SectionType theType,
99                                       const bool                      theIsClosed )
100 {
101   return -1;
102 }
103
104 int CurveCreator_Profile::addSection( const std::string&               theName,
105                                       const CurveCreator::SectionType  theType,
106                                       const bool                       theIsClosed, 
107                                       const CurveCreator::Coordinates& thePoints )
108 {
109   return -1;
110 }
111
112 bool CurveCreator_Profile::removeSectionInternal( const int theISection )
113 {
114   return false;
115 }
116   
117 bool CurveCreator_Profile::removeSection( const int theISection )
118 {
119   return false;
120 }
121
122 bool CurveCreator_Profile::setClosedInternal( const int theISection, 
123                                               const bool theIsClosed )
124 {
125   return false;
126 }
127
128 bool CurveCreator_Profile::setClosed( const int theISection, 
129                                       const bool theIsClosed )
130 {
131   return false;
132 }
133
134 bool CurveCreator_Profile::addPointsInternal( const CurveCreator::SectionsMap &theSectionsMap )
135 {
136   bool res = false;
137
138   CurveCreator_Section* aSection = mySections.at( 0 );
139   if( !aSection )
140     return res;
141
142   CurveCreator::SectionsMap::const_iterator anIt = theSectionsMap.begin();
143   for ( ; anIt != theSectionsMap.end(); anIt++ )
144   {
145     int anISection = anIt->first;
146     if( anISection != 0 )
147       continue;
148
149     const CurveCreator::PosPointsList& aSectionPoints = anIt->second;
150
151     CurveCreator::PosPointsList::const_iterator aPntIt = aSectionPoints.begin();
152     for( ; aPntIt != aSectionPoints.end(); aPntIt++ )
153     {
154       const CurveCreator::Coordinates& aNewCoords = (*aPntIt)->myCoords;
155       CurveCreator::Coordinates::const_iterator aNewPntIt = aNewCoords.begin();
156       for( ; aNewPntIt != aNewCoords.end(); aNewPntIt++ )
157       {
158         const CurveCreator::TypeCoord& aCoordU = *aNewPntIt++;
159         if ( aNewPntIt == aNewCoords.end() )
160           break;
161         
162         const CurveCreator::TypeCoord& aCoordZ = *aNewPntIt;
163
164         CurveCreator::TypeCoord aC = aCoordU - 1;
165         if ( !aSection->myPoints.empty() )
166           aC = *(aSection->myPoints.end() - 2);
167
168         if ( aSection->myPoints.empty() || aCoordU >= aC )
169         {
170           aSection->myPoints.push_back( aCoordU );
171           aSection->myPoints.push_back( aCoordZ );
172         }
173         else if ( aCoordU < aSection->myPoints.front() )
174         {
175           aSection->myPoints.push_front( aCoordZ );
176           aSection->myPoints.push_front( aCoordU );
177         }
178         else
179         {
180           CurveCreator::Coordinates::iterator aRefPntIt = aSection->myPoints.begin();
181           for( ; aRefPntIt != aSection->myPoints.end(); aRefPntIt++ )
182           {
183             const CurveCreator::TypeCoord& aRefCoordU = *aRefPntIt++;
184             if ( aCoordU < aRefCoordU )
185               break;
186           }
187
188           aSection->myPoints.insert( aRefPntIt - 1, aNewPntIt - 1, aNewPntIt + 1 );
189         }
190       }
191     }
192
193     res = true;
194   }
195
196   if ( res )
197     redisplayCurve();
198
199   return res;
200 }
201
202 //! For internal use only! Undo/Redo are not used here.
203 bool CurveCreator_Profile::setPointInternal( const CurveCreator::SectionsMap &theSectionsMap )
204 {
205   bool aRes = false;
206
207   if ( mySkipSorting ) {
208     return CurveCreator_Curve::setPointInternal( theSectionsMap );
209   }
210
211   int anISection = 0;
212   CurveCreator_Section* aSection = mySections.at( anISection );
213   if( !aSection )
214     return aRes;
215
216   CurveCreator::SectionsMap::const_iterator anIt = theSectionsMap.begin();
217   if ( anIt == theSectionsMap.end() )
218     return aRes;
219
220   const CurveCreator::PosPointsList& aSectionPoints = anIt->second;
221
222   std::list<int> aConvPoints;
223   convert( aSectionPoints, aConvPoints );
224   removeSectionPoints( anISection, aConvPoints );
225
226   aRes = addPointsInternal( theSectionsMap );
227   if ( aRes )
228     redisplayCurve();
229
230   return aRes;
231 }
232
233 void CurveCreator_Profile::convert( const CurveCreator::PosPointsList& thePoints,
234                                     std::list<int>& theConvPoints )
235 {
236   theConvPoints.clear();
237
238   CurveCreator::PosPointsList::const_iterator aPntIt = thePoints.begin(),
239                                               aPntLast = thePoints.end();
240   for( ; aPntIt != aPntLast; aPntIt++ )
241   {
242     int anIPnt = (*aPntIt)->myID;
243     theConvPoints.push_back( anIPnt );
244   }
245 }
246
247 bool CurveCreator_Profile::canPointsBeSorted()
248 {
249   return true;
250 }
251
252 /**
253  *  Add one point to the specified section starting from the given theIPnt index
254  *  (or at the end of points if \a theIPnt is -1).
255  */
256 bool CurveCreator_Profile::addPoints( const CurveCreator::Coordinates& theCoords,
257                                       const int theISection,
258                                       const int theIPnt )
259 {
260   int anIPnt = theIPnt;
261
262   if ( anIPnt == - 1 && theCoords.size() > 1 ) {
263     CurveCreator::Coordinates aCoords;
264     for ( int i = 0, aNb = getNbPoints( theISection ); i < aNb; i++ ) {
265       aCoords = getPoint( theISection, i );
266       if ( aCoords.size() < 2 ) {
267         continue;
268       }
269
270       if ( theCoords[0] < aCoords[0] ) {
271         anIPnt = i;
272         break;
273       }
274     }
275   }
276   
277   return CurveCreator_Curve::addPoints( theCoords, theISection, anIPnt );
278 }