]> SALOME platform Git repositories - modules/hydro.git/blob - src/HYDROData/HYDROData_Polyline3D.cxx
Salome HOME
Projection of polyline on bathymetry object (Feature #234).
[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_ProfileUZ.h"
8
9 #include <gp_Pnt2d.hxx>
10 #include <gp_XY.hxx>
11 #include <gp_XYZ.hxx>
12
13 #include <TopoDS.hxx>
14 #include <TopoDS_Wire.hxx>
15
16 #include <QColor>
17 #include <QStringList>
18
19 #define PYTHON_POLYLINE_ID "KIND_POLYLINE"
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;
37
38   Handle(HYDROData_Document) aDocument = HYDROData_Document::Document( myLab );
39   if ( aDocument.IsNull() )
40     return aResList;
41
42   QString aDocName = aDocument->GetDocPyName();
43   QString aPolylineName = GetName();
44
45   aResList << QString( "%1 = %2.CreateObject( %3 );" )
46               .arg( aPolylineName ).arg( aDocName ).arg( PYTHON_POLYLINE_ID );
47   aResList << QString( "%1.SetName( \"%1\" );" ).arg( aPolylineName );
48   aResList << QString( "" );
49
50   // TODO
51
52   return aResList;
53 }
54
55 HYDROData_SequenceOfObjects HYDROData_Polyline3D::GetAllReferenceObjects() const
56 {
57   HYDROData_SequenceOfObjects aResSeq = HYDROData_Object::GetAllReferenceObjects();
58
59   Handle(HYDROData_PolylineXY) aPolylineXY = GetPolylineXY();
60   if ( !aPolylineXY.IsNull() )
61     aResSeq.Append( aPolylineXY );
62
63   Handle(HYDROData_ProfileUZ) aProfileUZ = GetProfileUZ();
64   if ( !aProfileUZ.IsNull() )
65     aResSeq.Append( aProfileUZ );
66
67   return aResSeq;
68 }
69
70 TopoDS_Shape HYDROData_Polyline3D::GetTopShape() const
71 {
72   return getTopShape();
73 }
74
75 TopoDS_Shape HYDROData_Polyline3D::GetShape3D() const
76 {
77   return getShape3D();
78 }
79
80 HYDROData_IPolyline::PointsList generateProfileUZPoints(
81   const Handle(HYDROData_PolylineXY)& thePolyline,
82   const Handle(HYDROData_Bathymetry)& theBathymetry )
83 {
84   HYDROData_IPolyline::PointsList aPointsList;
85   if ( thePolyline.IsNull() || theBathymetry.IsNull() )
86     return aPointsList;
87
88   bool anIsSectionClosed = thePolyline->IsClosedSection( 0 );
89   HYDROData_IPolyline::SectionType aSectionType = thePolyline->GetSectionType( 0 );
90   HYDROData_IPolyline::PointsList aPolylinePoints = thePolyline->GetPoints( 0 );
91   if ( aPolylinePoints.IsEmpty() )
92     return aPointsList;
93
94   for ( int i = 1, aNbPoints = aPolylinePoints.Size(); i <= aNbPoints; ++i )
95   {
96     const HYDROData_PolylineXY::Point& aSectPoint = aPolylinePoints.Value( i );
97
98     double aPointDistance = thePolyline->GetDistance( 0, i - 1 );
99     double aPointDepth = theBathymetry->GetAltitudeForPoint( aSectPoint );
100
101     HYDROData_IPolyline::Point anAltitudePoint( aPointDistance, aPointDepth );
102     aPointsList.Append( anAltitudePoint );
103   }
104
105   return aPointsList;
106 }
107
108 void HYDROData_Polyline3D::Update()
109 {
110   HYDROData_Object::Update();
111
112   Handle(HYDROData_PolylineXY) aPolylineXY = GetPolylineXY();
113   if ( aPolylineXY.IsNull() )
114     return;
115
116   bool anIsSectionClosed = aPolylineXY->IsClosedSection( 0 );
117   HYDROData_IPolyline::SectionType aSectionType = aPolylineXY->GetSectionType( 0 );
118   HYDROData_IPolyline::PointsList aPolylinePoints = aPolylineXY->GetPoints( 0 );
119   if ( aPolylinePoints.IsEmpty() )
120     return;
121
122   HYDROData_IPolyline::PointsList aProfilePoints;
123
124   Handle(HYDROData_ProfileUZ) aProfileUZ = GetProfileUZ();
125   Handle(HYDROData_Bathymetry) aBathymetry = GetBathymetry();
126
127   if ( !aProfileUZ.IsNull() )
128   {
129     aProfilePoints = aProfileUZ->GetPoints();
130   }
131   else if ( !aBathymetry.IsNull() )
132   {
133     aProfilePoints = generateProfileUZPoints( aPolylineXY, aBathymetry );
134   }
135
136   if ( aProfilePoints.IsEmpty() )
137     return;
138
139   const HYDROData_IPolyline::Point& aFirstPoint = aPolylinePoints.First();
140   const HYDROData_IPolyline::Point& aLastPoint = aPolylinePoints.Last();
141
142   const HYDROData_IPolyline::Point& aFirstParPoint = aProfilePoints.First();
143   const HYDROData_IPolyline::Point& aLastParPoint = aProfilePoints.Last();
144
145   double aPolylineCommonDist = aPolylineXY->GetDistance( 0, aPolylinePoints.Size() - 1 );
146   double aParCommonDist = gp_Pnt2d( aFirstParPoint.X(), 0 ).Distance( gp_Pnt2d( aLastParPoint.X(), 0 ) );
147
148   NCollection_Sequence<Polyline3DPoint> aResPoints;
149   
150   // Add first point as is
151   aResPoints.Append( Polyline3DPoint( aFirstPoint.X(), aFirstPoint.Y(), aFirstParPoint.Y() ) );
152
153   for ( int i = 2, aNbPoints = aPolylinePoints.Size(); i < aNbPoints; ++i )
154   {
155     const HYDROData_IPolyline::Point& aPolylinePoint = aPolylinePoints.Value( i );
156
157     double aDistance = aPolylineXY->GetDistance( 0, i - 1 );
158
159     double aParLen = ( aDistance / aPolylineCommonDist ) * aParCommonDist;
160     double aDepth = HYDROData_ProfileUZ::GetDepthFromDistance( aProfilePoints, aParLen );
161
162     Polyline3DPoint aCompPoint( aPolylinePoint.X(), aPolylinePoint.Y(), aDepth );
163     aResPoints.Append( aCompPoint );
164   }
165
166   // Add last point as is
167   aResPoints.Append( Polyline3DPoint( aLastPoint.X(), aLastPoint.Y(), aLastParPoint.Y() ) );
168
169   TopoDS_Wire aResWire = HYDROData_PolylineXY::BuildWire( aSectionType, anIsSectionClosed, aResPoints );
170   SetTopShape( aResWire );
171   SetShape3D( aResWire );
172
173
174 QColor HYDROData_Polyline3D::DefaultFillingColor()
175 {
176   return QColor( Qt::transparent );
177 }
178
179 QColor HYDROData_Polyline3D::DefaultBorderColor()
180 {
181   return QColor( Qt::red );
182 }
183
184 QColor HYDROData_Polyline3D::getDefaultFillingColor() const
185 {
186   return DefaultFillingColor();
187 }
188
189 QColor HYDROData_Polyline3D::getDefaultBorderColor() const
190 {
191   return DefaultBorderColor();
192 }
193
194 bool HYDROData_Polyline3D::SetPolylineXY( const Handle(HYDROData_PolylineXY)& thePolyline )
195 {
196   if ( thePolyline.IsNull() )
197     return false;
198   
199   Handle(HYDROData_PolylineXY) aPrevPolyline = GetPolylineXY();
200   if ( IsEqual( aPrevPolyline, thePolyline ) )
201     return true;
202
203   SetReferenceObject( thePolyline, DataTag_PolylineXY );
204
205   // Indicate model of the need to update the polyline presentation
206   SetToUpdate( true );
207
208   return true;
209 }
210
211 Handle(HYDROData_PolylineXY) HYDROData_Polyline3D::GetPolylineXY() const
212 {
213   return Handle(HYDROData_PolylineXY)::DownCast( 
214            GetReferenceObject( DataTag_PolylineXY ) );
215 }
216
217 void HYDROData_Polyline3D::RemovePolylineXY()
218 {
219   Handle(HYDROData_PolylineXY) aPrevPolyline = GetPolylineXY();
220   if ( aPrevPolyline.IsNull() )
221     return;
222
223   ClearReferenceObjects( DataTag_PolylineXY );
224
225   // Indicate model of the need to update the polyline presentation
226   SetToUpdate( true );
227 }
228
229 bool HYDROData_Polyline3D::SetProfileUZ( const Handle(HYDROData_ProfileUZ)& theProfile )
230 {
231   if ( theProfile.IsNull() )
232     return false;
233   
234   Handle(HYDROData_ProfileUZ) aPrevProfile = GetProfileUZ();
235   if ( IsEqual( aPrevProfile, theProfile ) )
236     return true;
237
238   SetReferenceObject( theProfile, DataTag_ProfileUZ );
239
240   // Remove the bathymetry, because one altitude object can be presented at time
241   RemoveBathymetry();
242
243   // Indicate model of the need to update the polyline presentation
244   SetToUpdate( true );
245
246   return true;
247 }
248
249 Handle(HYDROData_ProfileUZ) HYDROData_Polyline3D::GetProfileUZ() const
250 {
251   return Handle(HYDROData_ProfileUZ)::DownCast( 
252            GetReferenceObject( DataTag_ProfileUZ ) );
253 }
254
255 void HYDROData_Polyline3D::RemoveProfileUZ()
256 {
257   Handle(HYDROData_ProfileUZ) aPrevProfile = GetProfileUZ();
258   if ( aPrevProfile.IsNull() )
259     return;
260
261   ClearReferenceObjects( DataTag_ProfileUZ );
262
263   // Indicate model of the need to update the polyline presentation
264   SetToUpdate( true );
265 }
266
267
268 bool HYDROData_Polyline3D::SetBathymetry( const Handle(HYDROData_Bathymetry)& theBathymetry )
269 {
270   if ( !HYDROData_Object::SetBathymetry( theBathymetry ) )
271     return false;
272
273   // Remove the u,z profile, because one altitude object can be presented at time
274   RemoveProfileUZ();
275
276   return true;
277 }
278