Salome HOME
Update mechanism is corrected (Bug #182).
[modules/hydro.git] / src / HYDROData / HYDROData_Polyline3D.cxx
1
2 #include "HYDROData_Polyline3D.h"
3
4 #include "HYDROData_Document.h"
5 #include "HYDROData_PolylineXY.h"
6 #include "HYDROData_ProfileUZ.h"
7
8 #include <gp_Pnt2d.hxx>
9 #include <gp_XY.hxx>
10 #include <gp_XYZ.hxx>
11
12 #include <TopoDS.hxx>
13 #include <TopoDS_Wire.hxx>
14
15 #include <QStringList>
16
17 #define PYTHON_POLYLINE_ID "KIND_POLYLINE"
18
19 IMPLEMENT_STANDARD_HANDLE(HYDROData_Polyline3D,HYDROData_Object)
20 IMPLEMENT_STANDARD_RTTIEXT(HYDROData_Polyline3D,HYDROData_Object)
21
22
23 HYDROData_Polyline3D::HYDROData_Polyline3D()
24 : HYDROData_Object()
25 {
26 }
27
28 HYDROData_Polyline3D::~HYDROData_Polyline3D()
29 {
30 }
31
32 QStringList HYDROData_Polyline3D::DumpToPython( MapOfTreatedObjects& theTreatedObjects ) const
33 {
34   QStringList aResList;
35
36   Handle(HYDROData_Document) aDocument = HYDROData_Document::Document( myLab );
37   if ( aDocument.IsNull() )
38     return aResList;
39
40   QString aDocName = aDocument->GetDocPyName();
41   QString aPolylineName = GetName();
42
43   aResList << QString( "%1 = %2.CreateObject( %3 );" )
44               .arg( aPolylineName ).arg( aDocName ).arg( PYTHON_POLYLINE_ID );
45   aResList << QString( "%1.SetName( \"%1\" );" ).arg( aPolylineName );
46   aResList << QString( "" );
47
48   // TODO
49
50   return aResList;
51 }
52
53 HYDROData_SequenceOfObjects HYDROData_Polyline3D::GetAllReferenceObjects() const
54 {
55   HYDROData_SequenceOfObjects aResSeq = HYDROData_Object::GetAllReferenceObjects();
56
57   Handle(HYDROData_PolylineXY) aPolylineXY = GetPolylineXY();
58   if ( !aPolylineXY.IsNull() )
59     aResSeq.Append( aPolylineXY );
60
61   Handle(HYDROData_ProfileUZ) aProfileUZ = GetProfileUZ();
62   if ( !aProfileUZ.IsNull() )
63     aResSeq.Append( aProfileUZ );
64
65   return aResSeq;
66 }
67
68 TopoDS_Shape HYDROData_Polyline3D::GetTopShape() const
69 {
70   return getTopShape();
71 }
72
73 TopoDS_Shape HYDROData_Polyline3D::GetShape3D() const
74 {
75   return getShape3D();
76 }
77
78 void HYDROData_Polyline3D::Update()
79 {
80   HYDROData_Object::Update();
81
82   Handle(HYDROData_PolylineXY) aPolylineXY = GetPolylineXY();
83   Handle(HYDROData_ProfileUZ) aProfileUZ = GetProfileUZ();
84   if ( aPolylineXY.IsNull() || aProfileUZ.IsNull() )
85     return;
86
87   bool anIsSectionClosed = aPolylineXY->IsClosedSection( 0 );
88   HYDROData_IPolyline::SectionType aSectionType = aPolylineXY->GetSectionType( 0 );
89   HYDROData_IPolyline::PointsList aPolylinePoints = aPolylineXY->GetPoints( 0 );
90   HYDROData_IPolyline::PointsList aProfilePoints = aProfileUZ->GetPoints();
91   if ( aPolylinePoints.IsEmpty() || aProfilePoints.IsEmpty() )
92     return;
93
94   const HYDROData_IPolyline::Point& aFirstPoint = aPolylinePoints.First();
95   const HYDROData_IPolyline::Point& aLastPoint = aPolylinePoints.Last();
96
97   const HYDROData_IPolyline::Point& aFirstParPoint = aProfilePoints.First();
98   const HYDROData_IPolyline::Point& aLastParPoint = aProfilePoints.Last();
99
100   double aPolylineCommonDist = aPolylineXY->GetDistance( 0, aPolylinePoints.Size() - 1 );
101   double aParCommonDist = gp_Pnt2d( aFirstParPoint.X(), 0 ).Distance( gp_Pnt2d( aLastParPoint.X(), 0 ) );
102
103   NCollection_Sequence<Polyline3DPoint> aResPoints;
104   
105   // Add first point as is
106   aResPoints.Append( Polyline3DPoint( aFirstPoint.X(), aFirstPoint.Y(), aFirstParPoint.Y() ) );
107
108   for ( int i = 2, aNbPoints = aPolylinePoints.Size(); i < aNbPoints; ++i )
109   {
110     const HYDROData_IPolyline::Point& aPolylinePoint = aPolylinePoints.Value( i );
111
112     double aDistance = aPolylineXY->GetDistance( 0, i - 1 );
113
114     double aParLen = ( aDistance / aPolylineCommonDist ) * aParCommonDist;
115     double aDepth = aProfileUZ->GetDepthFromDistance( aParLen );
116
117     Polyline3DPoint aCompPoint( aPolylinePoint.X(), aPolylinePoint.Y(), aDepth );
118     aResPoints.Append( aCompPoint );
119   }
120
121   // Add last point as is
122   aResPoints.Append( Polyline3DPoint( aLastPoint.X(), aLastPoint.Y(), aLastParPoint.Y() ) );
123
124   TopoDS_Wire aResWire = HYDROData_PolylineXY::BuildWire( aSectionType, anIsSectionClosed, aResPoints );
125   SetTopShape( aResWire );
126   SetShape3D( aResWire );
127
128
129 bool HYDROData_Polyline3D::SetPolylineXY( const Handle(HYDROData_PolylineXY)& thePolyline )
130 {
131   if ( thePolyline.IsNull() )
132     return false;
133   
134   Handle(HYDROData_PolylineXY) aPrevPolyline = GetPolylineXY();
135   if ( IsEqual( aPrevPolyline, thePolyline ) )
136     return true;
137
138   SetReferenceObject( thePolyline, DataTag_PolylineXY );
139
140   // Indicate model of the need to update the polyline presentation
141   SetToUpdate( true );
142
143   return true;
144 }
145
146 Handle(HYDROData_PolylineXY) HYDROData_Polyline3D::GetPolylineXY() const
147 {
148   return Handle(HYDROData_PolylineXY)::DownCast( 
149            GetReferenceObject( DataTag_PolylineXY ) );
150 }
151
152 void HYDROData_Polyline3D::RemovePolylineXY()
153 {
154   Handle(HYDROData_PolylineXY) aPrevPolyline = GetPolylineXY();
155   if ( aPrevPolyline.IsNull() )
156     return;
157
158   ClearReferenceObjects( DataTag_PolylineXY );
159
160   // Indicate model of the need to update the polyline presentation
161   SetToUpdate( true );
162 }
163
164 bool HYDROData_Polyline3D::SetProfileUZ( const Handle(HYDROData_ProfileUZ)& theProfile )
165 {
166   if ( theProfile.IsNull() )
167     return false;
168   
169   Handle(HYDROData_ProfileUZ) aPrevProfile = GetProfileUZ();
170   if ( IsEqual( aPrevProfile, theProfile ) )
171     return true;
172
173   SetReferenceObject( theProfile, DataTag_ProfileUZ );
174
175   // Indicate model of the need to update the polyline presentation
176   SetToUpdate( true );
177
178   return true;
179 }
180
181 Handle(HYDROData_ProfileUZ) HYDROData_Polyline3D::GetProfileUZ() const
182 {
183   return Handle(HYDROData_ProfileUZ)::DownCast( 
184            GetReferenceObject( DataTag_ProfileUZ ) );
185 }
186
187 void HYDROData_Polyline3D::RemoveProfileUZ()
188 {
189   Handle(HYDROData_ProfileUZ) aPrevProfile = GetProfileUZ();
190   if ( aPrevProfile.IsNull() )
191     return;
192
193   ClearReferenceObjects( DataTag_ProfileUZ );
194
195   // Indicate model of the need to update the polyline presentation
196   SetToUpdate( true );
197 }
198