]> SALOME platform Git repositories - modules/hydro.git/blob - src/HYDROData/HYDROData_Stream.cxx
Salome HOME
Linux compilation.
[modules/hydro.git] / src / HYDROData / HYDROData_Stream.cxx
1
2 #include "HYDROData_Stream.h"
3
4 #include "HYDROData_Document.h"
5 #include "HYDROData_PolylineXY.h"
6 #include "HYDROData_Profile.h"
7
8 #include <BRep_Builder.hxx>
9 #include <BRepBuilderAPI_MakeEdge.hxx>
10 #include <BRepBuilderAPI_MakeWire.hxx>
11 #include <BRepBuilderAPI_MakeFace.hxx>
12
13 #include <TopoDS.hxx>
14 #include <TopoDS_Wire.hxx>
15 #include <TopoDS_Shell.hxx>
16 #include <TopoDS_Face.hxx>
17
18 #include <QStringList>
19
20 #define PYTHON_STREAM_ID "KIND_STREAM"
21
22 IMPLEMENT_STANDARD_HANDLE(HYDROData_Stream,HYDROData_NaturalObject)
23 IMPLEMENT_STANDARD_RTTIEXT(HYDROData_Stream,HYDROData_NaturalObject)
24
25
26 HYDROData_Stream::HYDROData_Stream()
27 : HYDROData_NaturalObject()
28 {
29 }
30
31 HYDROData_Stream::~HYDROData_Stream()
32 {
33 }
34
35 QStringList HYDROData_Stream::DumpToPython( MapOfTreatedObjects& theTreatedObjects ) const
36 {
37   QStringList aResList;
38
39   Handle(HYDROData_Document) aDocument = HYDROData_Document::Document( myLab );
40   if ( aDocument.IsNull() )
41     return aResList;
42
43   QString aDocName = aDocument->GetDocPyName();
44   QString aStreamName = GetName();
45
46   aResList << QString( "%1 = %2.CreateObject( %3 );" )
47               .arg( aStreamName ).arg( aDocName ).arg( PYTHON_STREAM_ID );
48   aResList << QString( "%1.SetName( \"%2\" );" )
49               .arg( aStreamName ).arg( aStreamName );
50   aResList << QString( "" );
51
52   // TODO
53
54   return aResList;
55 }
56
57 HYDROData_SequenceOfObjects HYDROData_Stream::GetAllReferenceObjects() const
58 {
59   HYDROData_SequenceOfObjects aResSeq = HYDROData_Object::GetAllReferenceObjects();
60
61   Handle(HYDROData_PolylineXY) aHydAxis = GetHydraulicAxis();
62   if ( !aHydAxis.IsNull() )
63     aResSeq.Append( aHydAxis );
64
65   HYDROData_SequenceOfObjects aSeqOfProfiles = GetProfiles();
66   aResSeq.Append( aSeqOfProfiles );
67
68   return aResSeq;
69 }
70
71 TopoDS_Shape HYDROData_Stream::GetTopShape() const
72 {
73   return getTopShape();
74 }
75
76 TopoDS_Shape HYDROData_Stream::GetShape3D() const
77 {
78   return getShape3D();
79 }
80
81 void HYDROData_Stream::Update()
82 {
83   HYDROData_NaturalObject::Update();
84
85   Handle(HYDROData_PolylineXY) aHydAxis = GetHydraulicAxis();
86   HYDROData_SequenceOfObjects aRefProfiles = GetProfiles();
87   if ( aHydAxis.IsNull() || aRefProfiles.IsEmpty() )
88     return; 
89
90   TopoDS_Shell a2dShell;
91   BRep_Builder a2dShellBuilder;
92   a2dShellBuilder.MakeShell( a2dShell );
93
94   bool anIsFirst = true;
95   gp_Pnt aPrevFirstPoint, aPrevLastPoint;
96   
97   // Construct the top presentation
98   HYDROData_SequenceOfObjects::Iterator anIter( aRefProfiles );
99   for ( ; anIter.More(); anIter.Next() )
100   {
101     Handle(HYDROData_Profile) aProfile =
102       Handle(HYDROData_Profile)::DownCast( anIter.Value() );
103     if ( aProfile.IsNull() )
104       continue;
105
106     gp_XY aPnt1, aPnt2;
107     if ( !aProfile->GetFirstPoint( aPnt1 ) || !aProfile->GetLastPoint( aPnt2 ) )
108       continue;
109     
110     gp_Pnt aCurFirstPoint( aPnt1.X(), aPnt1.Y(), 0 );
111     gp_Pnt aCurLastPoint(  aPnt2.X(), aPnt2.Y(), 0 );
112
113     if ( anIsFirst )
114     {
115       aPrevFirstPoint = aCurFirstPoint;
116       aPrevLastPoint = aCurLastPoint;
117       anIsFirst = false;
118       continue;
119     }
120
121     BRepBuilderAPI_MakeEdge aFirstEdge( aPrevFirstPoint, aPrevLastPoint );
122     BRepBuilderAPI_MakeEdge aSecondEdge( aPrevLastPoint, aCurLastPoint );
123     BRepBuilderAPI_MakeEdge aThirdEdge( aCurLastPoint, aCurFirstPoint );
124     BRepBuilderAPI_MakeEdge aFourthEdge( aCurFirstPoint, aPrevFirstPoint );
125
126     BRepBuilderAPI_MakeWire aMakeWire( aFirstEdge.Edge(), aSecondEdge.Edge(), 
127                                        aThirdEdge.Edge(), aFourthEdge.Edge() );
128     
129     TopoDS_Wire aSectProfileWire = aMakeWire.Wire();
130     
131     BRepBuilderAPI_MakeFace aMakeFace( aSectProfileWire, Standard_True );
132     aMakeFace.Build();
133     if( aMakeFace.IsDone() )
134     {
135       a2dShellBuilder.Add( a2dShell, aMakeFace.Face() );
136     }
137
138     aPrevFirstPoint = aCurFirstPoint;
139     aPrevLastPoint = aCurLastPoint;
140   }
141
142   SetTopShape( a2dShell );
143
144   // Construct the 3D presentation
145   /// TODO
146 }
147
148 bool HYDROData_Stream::SetHydraulicAxis( const Handle(HYDROData_PolylineXY)& theAxis )
149 {
150   Handle(HYDROData_PolylineXY) aPrevAxis = GetHydraulicAxis();
151
152   if ( theAxis.IsNull() )
153   {
154     RemoveHydraulicAxis();
155     return !aPrevAxis.IsNull();
156   }
157
158   if ( IsEqual( aPrevAxis, theAxis ) )
159     return false;
160
161   TopoDS_Wire aHydraulicWire = TopoDS::Wire( theAxis->GetShape() );
162   if ( aHydraulicWire.IsNull() )
163     return false; // The polyline must be a single wire
164
165   SetReferenceObject( theAxis, DataTag_HydraulicAxis );
166
167   // Update the order of profiles
168   updateProfilesOrder();
169
170   // Indicate model of the need to update the stream presentation
171   SetToUpdate( true );
172
173   return true;
174 }
175
176 Handle(HYDROData_PolylineXY) HYDROData_Stream::GetHydraulicAxis() const
177 {
178   return Handle(HYDROData_PolylineXY)::DownCast( 
179            GetReferenceObject( DataTag_HydraulicAxis ) );
180 }
181
182 void HYDROData_Stream::RemoveHydraulicAxis()
183 {
184   Handle(HYDROData_PolylineXY) aPrevAxis = GetHydraulicAxis();
185   if ( aPrevAxis.IsNull() )
186     return;
187
188   ClearReferenceObjects( DataTag_HydraulicAxis );
189
190   // We remove the reference profiles
191   RemoveProfiles();
192
193   // Indicate model of the need to update the stream presentation
194   SetToUpdate( true );
195 }
196
197 bool HYDROData_Stream::HasIntersection( const Handle(HYDROData_Profile)& theProfile ) const
198 {
199   Handle(HYDROData_PolylineXY) aHydAxis = GetHydraulicAxis();
200   if ( theProfile.IsNull() || aHydAxis.IsNull() )
201     return false; 
202
203   TopoDS_Wire aHydraulicWire = TopoDS::Wire( aHydAxis->GetShape() );
204   TopoDS_Wire aProfileWire = TopoDS::Wire( theProfile->GetTopShape() );
205   if ( aHydraulicWire.IsNull() || aProfileWire.IsNull() )
206     return false;
207
208   // TODO
209
210   return true;
211 }
212
213 bool HYDROData_Stream::AddProfile( const Handle(HYDROData_Profile)& theProfile )
214 {
215   if ( theProfile.IsNull() )
216     return false; 
217
218   if ( HasReference( theProfile, DataTag_Profile ) || !HasIntersection( theProfile ) )
219     return false; // Object is already in reference list or it has no intersection
220
221   insertProfileInToOrder( theProfile );
222   
223   // Indicate model of the need to update the stream presentation
224   SetToUpdate( true );
225
226   return true;
227 }
228
229 HYDROData_SequenceOfObjects HYDROData_Stream::GetProfiles() const
230 {
231   return GetReferenceObjects( DataTag_Profile );
232 }
233
234 bool HYDROData_Stream::RemoveProfile( const Handle(HYDROData_Profile)& theProfile )
235 {
236   if ( theProfile.IsNull() || !HasReference( theProfile, DataTag_Profile ) )
237     return false;
238
239   RemoveReferenceObject( theProfile->Label(), DataTag_Profile );
240
241   // Indicate model of the need to update the stream presentation
242   SetToUpdate( true );
243
244   return true;
245 }
246
247 void HYDROData_Stream::RemoveProfiles()
248 {
249   bool anIsToUpdate = IsMustBeUpdated() || NbReferenceObjects( DataTag_Profile ) > 0;
250
251   ClearReferenceObjects( DataTag_Profile );
252
253   // Indicate model of the need to update the stream presentation
254   SetToUpdate( anIsToUpdate );
255 }
256
257 void HYDROData_Stream::insertProfileInToOrder( const Handle(HYDROData_Profile)& theProfile )
258 {
259   Handle(HYDROData_PolylineXY) aHydAxis = GetHydraulicAxis();
260   if ( theProfile.IsNull() || aHydAxis.IsNull() )
261     return; 
262
263   TopoDS_Wire aHydraulicWire = TopoDS::Wire( aHydAxis->GetShape() );
264   TopoDS_Wire aProfileWire = TopoDS::Wire( theProfile->GetTopShape() );
265   if ( aHydraulicWire.IsNull() || aProfileWire.IsNull() )
266     return;
267
268   // TODO
269   AddReferenceObject( theProfile, DataTag_Profile ); // temporary for testing only
270 }
271
272 void HYDROData_Stream::updateProfilesOrder()
273 {
274   HYDROData_SequenceOfObjects aRefProfiles = GetProfiles();
275   if ( aRefProfiles.IsEmpty() )
276     return;
277
278   // At first we remove all profiles from order
279   RemoveProfiles();
280
281   Handle(HYDROData_PolylineXY) aHydAxis = GetHydraulicAxis();
282   if ( aHydAxis.IsNull() )
283     return;
284
285   HYDROData_SequenceOfObjects::Iterator anIter( aRefProfiles );
286   for ( ; anIter.More(); anIter.Next() )
287   {
288     Handle(HYDROData_Profile) aProfile =
289       Handle(HYDROData_Profile)::DownCast( anIter.Value() );
290     if ( aProfile.IsNull() || !HasIntersection( aProfile ) )
291       continue;
292
293     insertProfileInToOrder( aProfile );
294   }
295 }
296