Salome HOME
Dump to python corrected.
[modules/hydro.git] / src / HYDROData / HYDROData_Polyline3D.cxx
1
2 #include "HYDROData_Polyline3D.h"
3
4 #include "HYDROData_IAltitudeObject.h"
5 #include "HYDROData_Document.h"
6 #include "HYDROData_PolylineXY.h"
7 #include "HYDROData_Profile.h"
8 #include "HYDROData_ProfileUZ.h"
9 #include "HYDROData_Tool.h"
10
11 #include <gp_Pnt2d.hxx>
12 #include <gp_XY.hxx>
13 #include <gp_XYZ.hxx>
14
15 #include <TopoDS.hxx>
16 #include <TopoDS_Wire.hxx>
17
18 #include <QColor>
19 #include <QStringList>
20
21 IMPLEMENT_STANDARD_HANDLE(HYDROData_Polyline3D,HYDROData_Object)
22 IMPLEMENT_STANDARD_RTTIEXT(HYDROData_Polyline3D,HYDROData_Object)
23
24
25 HYDROData_Polyline3D::HYDROData_Polyline3D()
26 : HYDROData_Object()
27 {
28 }
29
30 HYDROData_Polyline3D::~HYDROData_Polyline3D()
31 {
32 }
33
34 QStringList HYDROData_Polyline3D::DumpToPython( MapOfTreatedObjects& theTreatedObjects ) const
35 {
36   QStringList aResList = dumpObjectCreation( theTreatedObjects );
37   QString aPolylineName = GetObjPyName();
38
39   Handle(HYDROData_PolylineXY) aRefPolyline = GetPolylineXY();
40   setPythonReferenceObject( theTreatedObjects, aResList, aRefPolyline, "SetPolylineXY" );
41
42   Handle(HYDROData_ProfileUZ) aRefProfileUZ = GetProfileUZ();
43   if ( !aRefProfileUZ.IsNull() )
44   {
45     Handle(HYDROData_Profile) aProfile = 
46       Handle(HYDROData_Profile)::DownCast( aRefProfileUZ->GetFatherObject() );
47     if ( !aProfile.IsNull() )
48     {
49       QString aProfileName = aProfile->GetObjPyName();
50       if ( !aProfileName.isEmpty() )
51       {
52         aResList << QString( "%1.SetProfileUZ( %2.GetProfileUZ() );" )
53                      .arg( aPolylineName ).arg( aProfileName );
54       }
55     }
56   }
57   else
58   {
59     Handle(HYDROData_IAltitudeObject) aRefBathymetry = GetAltitudeObject();
60     setPythonReferenceObject( theTreatedObjects, aResList, aRefBathymetry, "SetAltitudeObject" );
61   }
62
63   aResList << QString( "" );
64   aResList << QString( "%1.Update();" ).arg( aPolylineName );
65   aResList << QString( "" );
66
67   return aResList;
68 }
69
70 HYDROData_SequenceOfObjects HYDROData_Polyline3D::GetAllReferenceObjects() const
71 {
72   HYDROData_SequenceOfObjects aResSeq = HYDROData_Object::GetAllReferenceObjects();
73
74   Handle(HYDROData_PolylineXY) aPolylineXY = GetPolylineXY();
75   if ( !aPolylineXY.IsNull() )
76     aResSeq.Append( aPolylineXY );
77
78   Handle(HYDROData_ProfileUZ) aProfileUZ = GetProfileUZ();
79   if ( !aProfileUZ.IsNull() )
80     aResSeq.Append( aProfileUZ );
81
82   Handle(HYDROData_ProfileUZ) aChildProfileUZ = GetChildProfileUZ( false );
83   if ( !aChildProfileUZ.IsNull() )
84     aResSeq.Append( aChildProfileUZ );
85
86   return aResSeq;
87 }
88
89 TopoDS_Shape HYDROData_Polyline3D::GetTopShape() const
90 {
91   return getTopShape();
92 }
93
94 TopoDS_Shape HYDROData_Polyline3D::GetShape3D() const
95 {
96   return getShape3D();
97 }
98
99 void HYDROData_Polyline3D::Update()
100 {
101   HYDROData_Object::Update();
102
103   Handle(HYDROData_PolylineXY) aPolylineXY = GetPolylineXY();
104   if ( aPolylineXY.IsNull() )
105     return;
106
107   bool anIsSectionClosed = aPolylineXY->IsClosedSection( 0 );
108   HYDROData_IPolyline::SectionType aSectionType = aPolylineXY->GetSectionType( 0 );
109   HYDROData_IPolyline::PointsList aPolylinePoints = aPolylineXY->GetPoints( 0 );
110   if ( aPolylinePoints.IsEmpty() )
111     return;
112
113   Handle(HYDROData_ProfileUZ) aProfileUZ = GetProfileUZ();
114
115   Handle(HYDROData_IAltitudeObject) anAltitude = GetAltitudeObject();
116   if ( !anAltitude.IsNull() )
117     aProfileUZ = GetChildProfileUZ();
118
119   if ( aProfileUZ.IsNull() )
120     return;
121
122   HYDROData_IPolyline::PointsList aProfilePoints = aProfileUZ->GetPoints();
123   if ( aProfilePoints.IsEmpty() )
124     return;
125
126   const HYDROData_IPolyline::Point& aFirstPoint = aPolylinePoints.First();
127   const HYDROData_IPolyline::Point& aLastPoint = aPolylinePoints.Last();
128
129   const HYDROData_IPolyline::Point& aFirstParPoint = aProfilePoints.First();
130   const HYDROData_IPolyline::Point& aLastParPoint = aProfilePoints.Last();
131
132   double aPolylineCommonDist = aPolylineXY->GetDistance( 0, aPolylinePoints.Size() - 1 );
133   double aParCommonDist = gp_Pnt2d( aFirstParPoint.X(), 0 ).Distance( gp_Pnt2d( aLastParPoint.X(), 0 ) );
134
135   NCollection_Sequence<Polyline3DPoint> aResPoints;
136   
137   // Add first point as is
138   aResPoints.Append( Polyline3DPoint( aFirstPoint.X(), aFirstPoint.Y(), aFirstParPoint.Y() ) );
139
140   for ( int i = 2, aNbPoints = aPolylinePoints.Size(); i < aNbPoints; ++i )
141   {
142     const HYDROData_IPolyline::Point& aPolylinePoint = aPolylinePoints.Value( i );
143
144     double aDistance = aPolylineXY->GetDistance( 0, i - 1 );
145
146     double aParLen = ( aDistance / aPolylineCommonDist ) * aParCommonDist;
147     double aDepth = HYDROData_ProfileUZ::GetDepthFromDistance( aProfilePoints, aParLen );
148
149     Polyline3DPoint aCompPoint( aPolylinePoint.X(), aPolylinePoint.Y(), aDepth );
150     aResPoints.Append( aCompPoint );
151   }
152
153   // Add last point as is
154   aResPoints.Append( Polyline3DPoint( aLastPoint.X(), aLastPoint.Y(), aLastParPoint.Y() ) );
155
156   TopoDS_Wire aResWire = HYDROData_PolylineXY::BuildWire( aSectionType, anIsSectionClosed, aResPoints );
157   SetTopShape( aResWire );
158   SetShape3D( aResWire );
159
160
161 QColor HYDROData_Polyline3D::DefaultFillingColor()
162 {
163   return QColor( Qt::transparent );
164 }
165
166 QColor HYDROData_Polyline3D::DefaultBorderColor()
167 {
168   return QColor( Qt::red );
169 }
170
171 QColor HYDROData_Polyline3D::getDefaultFillingColor() const
172 {
173   return DefaultFillingColor();
174 }
175
176 QColor HYDROData_Polyline3D::getDefaultBorderColor() const
177 {
178   return DefaultBorderColor();
179 }
180
181 bool HYDROData_Polyline3D::SetPolylineXY( const Handle(HYDROData_PolylineXY)& thePolyline,
182                                           const bool                          theIsUpdateProfile )
183 {
184   if ( thePolyline.IsNull() )
185     return false;
186   
187   Handle(HYDROData_PolylineXY) aPrevPolyline = GetPolylineXY();
188   if ( IsEqual( aPrevPolyline, thePolyline ) )
189     return true;
190
191   SetReferenceObject( thePolyline, DataTag_PolylineXY );
192
193   // Update the child profile object 
194   if ( theIsUpdateProfile )
195     updateChildProfilePoints();
196
197   // Indicate model of the need to update the polyline presentation
198   SetToUpdate( true );
199
200   return true;
201 }
202
203 Handle(HYDROData_PolylineXY) HYDROData_Polyline3D::GetPolylineXY() const
204 {
205   return Handle(HYDROData_PolylineXY)::DownCast( 
206            GetReferenceObject( DataTag_PolylineXY ) );
207 }
208
209 void HYDROData_Polyline3D::RemovePolylineXY()
210 {
211   Handle(HYDROData_PolylineXY) aPrevPolyline = GetPolylineXY();
212   if ( aPrevPolyline.IsNull() )
213     return;
214
215   ClearReferenceObjects( DataTag_PolylineXY );
216
217   // Indicate model of the need to update the polyline presentation
218   SetToUpdate( true );
219 }
220
221 bool HYDROData_Polyline3D::SetProfileUZ( const Handle(HYDROData_ProfileUZ)& theProfile )
222 {
223   if ( theProfile.IsNull() )
224     return false;
225   
226   Handle(HYDROData_ProfileUZ) aPrevProfile = GetProfileUZ();
227   if ( IsEqual( aPrevProfile, theProfile ) )
228     return true;
229
230   SetReferenceObject( theProfile, DataTag_ProfileUZ );
231
232   // Remove the bathymetry, because one altitude object can be presented at time
233   RemoveAltitudeObject();
234
235   // Indicate model of the need to update the polyline presentation
236   SetToUpdate( true );
237
238   return true;
239 }
240
241 Handle(HYDROData_ProfileUZ) HYDROData_Polyline3D::GetProfileUZ() const
242 {
243   return Handle(HYDROData_ProfileUZ)::DownCast( 
244            GetReferenceObject( DataTag_ProfileUZ ) );
245 }
246
247 void HYDROData_Polyline3D::RemoveProfileUZ()
248 {
249   Handle(HYDROData_ProfileUZ) aPrevProfile = GetProfileUZ();
250   if ( aPrevProfile.IsNull() )
251     return;
252
253   ClearReferenceObjects( DataTag_ProfileUZ );
254
255   // Indicate model of the need to update the polyline presentation
256   SetToUpdate( true );
257 }
258
259 bool HYDROData_Polyline3D::SetAltitudeObject( 
260   const Handle(HYDROData_IAltitudeObject)& theAltitude )
261 {
262   Handle(HYDROData_IAltitudeObject) aPrevAltitude = GetAltitudeObject();
263
264   if ( !HYDROData_Object::SetAltitudeObject( theAltitude ) )
265     return false;
266
267   if ( IsEqual( aPrevAltitude, theAltitude ) )
268     return true;
269
270   // Remove the u,z profile, because one altitude object can be presented at time
271   RemoveProfileUZ();
272
273   // Create the child profile object 
274   updateChildProfilePoints();
275
276   return true;
277 }
278
279
280 void HYDROData_Polyline3D::RemoveAltitudeObject()
281 {
282   HYDROData_Object::RemoveAltitudeObject();
283
284   // Remove the child profile object 
285   removeChildProfileUZ();
286 }
287
288 Handle(HYDROData_ProfileUZ) HYDROData_Polyline3D::GetChildProfileUZ( const bool theIsCreate ) const
289 {
290   Handle(HYDROData_ProfileUZ) aProfileUZ =
291     Handle(HYDROData_ProfileUZ)::DownCast( GetReferenceObject( DataTag_ChildProfileUZ ) );
292   if ( !theIsCreate || !aProfileUZ.IsNull() )
293     return aProfileUZ;
294
295   Handle(HYDROData_Document) aDocument = HYDROData_Document::Document( myLab );
296   if ( aDocument.IsNull() )
297     return aProfileUZ;
298
299   Handle(HYDROData_Profile) aProfile =
300     Handle(HYDROData_Profile)::DownCast( aDocument->CreateObject( KIND_PROFILE ) );
301   
302   QString aProfilePref = GetName() + "_Profile";
303   QString aProfileName = HYDROData_Tool::GenerateObjectName( aDocument, aProfilePref );
304
305   aProfile->SetName( aProfileName );
306
307   aProfileUZ = aProfile->GetProfileUZ();
308
309   HYDROData_Polyline3D* me = const_cast<HYDROData_Polyline3D*>( this ); // Temporary to be revised
310   me->SetReferenceObject( aProfileUZ, DataTag_ChildProfileUZ );
311
312   return aProfileUZ;
313 }
314
315 HYDROData_IPolyline::PointsList generateProfileUZPoints(
316   const Handle(HYDROData_PolylineXY)&      thePolyline,
317   const Handle(HYDROData_IAltitudeObject)& theAltitude )
318 {
319   HYDROData_IPolyline::PointsList aPointsList;
320   if ( thePolyline.IsNull() || theAltitude.IsNull() )
321     return aPointsList;
322
323   bool anIsSectionClosed = thePolyline->IsClosedSection( 0 );
324   HYDROData_IPolyline::SectionType aSectionType = thePolyline->GetSectionType( 0 );
325   HYDROData_IPolyline::PointsList aPolylinePoints = thePolyline->GetPoints( 0 );
326   if ( aPolylinePoints.IsEmpty() )
327     return aPointsList;
328
329   for ( int i = 1, aNbPoints = aPolylinePoints.Size(); i <= aNbPoints; ++i )
330   {
331     const HYDROData_PolylineXY::Point& aSectPoint = aPolylinePoints.Value( i );
332
333     double aPointDistance = thePolyline->GetDistance( 0, i - 1 );
334     double aPointDepth = theAltitude->GetAltitudeForPoint( aSectPoint );
335     if( aPointDepth == theAltitude->GetInvalidAltitude() )
336       aPointDepth = 0.0;
337
338     HYDROData_IPolyline::Point anAltitudePoint( aPointDistance, aPointDepth );
339     aPointsList.Append( anAltitudePoint );
340   }
341
342   return aPointsList;
343 }
344
345 void HYDROData_Polyline3D::updateChildProfilePoints()
346 {
347   Handle(HYDROData_IAltitudeObject) anAltitude = GetAltitudeObject();
348   if ( anAltitude.IsNull() )
349     return;
350
351   Handle(HYDROData_ProfileUZ) aChildProfileUZ = GetChildProfileUZ();
352   if ( aChildProfileUZ.IsNull() )
353     return;
354
355   Handle(HYDROData_Profile) aProfile = 
356     Handle(HYDROData_Profile)::DownCast( aChildProfileUZ->GetFatherObject() );
357   if ( aProfile.IsNull() )
358     return;
359
360   HYDROData_IPolyline::PointsList aProfilePoints = 
361     generateProfileUZPoints( GetPolylineXY(), anAltitude );
362   aProfile->SetParametricPoints( aProfilePoints );
363
364   aProfile->Update();
365 }
366
367 void HYDROData_Polyline3D::removeChildProfileUZ()
368 {
369   Handle(HYDROData_ProfileUZ) aChildProfileUZ = GetChildProfileUZ( false );
370   if ( aChildProfileUZ.IsNull() )
371     return;
372
373   ClearReferenceObjects( DataTag_ChildProfileUZ );
374
375   /* Uncomment if removing is requested
376   Handle(HYDROData_Profile) aProfile = 
377     Handle(HYDROData_Profile)::DownCast( aChildProfileUZ->GetFatherObject() );
378   if ( !aProfile.IsNull() )
379     aProfile->Remove();
380   */
381 }
382
383