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