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