Salome HOME
19c9900abfbbaa0302b98c833ccf8b73a28ec008
[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 TopoDS_Shape HYDROData_Stream::GetTopShape() const
58 {
59   return getTopShape();
60 }
61
62 TopoDS_Shape HYDROData_Stream::GetShape3D() const
63 {
64   return getShape3D();
65 }
66
67 void HYDROData_Stream::Update()
68 {
69   HYDROData_NaturalObject::Update();
70
71   Handle(HYDROData_PolylineXY) aHydAxis = GetHydraulicAxis();
72   HYDROData_SequenceOfObjects aRefProfiles = GetProfiles();
73   if ( aHydAxis.IsNull() || aRefProfiles.IsEmpty() )
74     return; 
75
76   TopoDS_Shell a2dShell;
77   BRep_Builder a2dShellBuilder;
78   a2dShellBuilder.MakeShell( a2dShell );
79
80   bool anIsFirst = true;
81   gp_Pnt aPrevFirstPoint, aPrevLastPoint;
82   
83   // Construct the top presentation
84   HYDROData_SequenceOfObjects::Iterator anIter( aRefProfiles );
85   for ( ; anIter.More(); anIter.Next() )
86   {
87     Handle(HYDROData_Profile) aProfile =
88       Handle(HYDROData_Profile)::DownCast( anIter.Value() );
89     if ( aProfile.IsNull() )
90       continue;
91
92     gp_XY aPnt1, aPnt2;
93     if ( !aProfile->GetFirstPoint( aPnt1 ) || !aProfile->GetLastPoint( aPnt2 ) )
94       continue;
95     
96     gp_Pnt aCurFirstPoint( aPnt1.X(), aPnt1.Y(), 0 );
97     gp_Pnt aCurLastPoint(  aPnt2.X(), aPnt2.Y(), 0 );
98
99     if ( anIsFirst )
100     {
101       aPrevFirstPoint = aCurFirstPoint;
102       aPrevLastPoint = aCurLastPoint;
103       anIsFirst = false;
104       continue;
105     }
106
107     BRepBuilderAPI_MakeEdge aFirstEdge( aPrevFirstPoint, aPrevLastPoint );
108     BRepBuilderAPI_MakeEdge aSecondEdge( aPrevLastPoint, aCurLastPoint );
109     BRepBuilderAPI_MakeEdge aThirdEdge( aCurLastPoint, aCurFirstPoint );
110     BRepBuilderAPI_MakeEdge aFourthEdge( aCurFirstPoint, aPrevFirstPoint );
111
112     BRepBuilderAPI_MakeWire aMakeWire( aFirstEdge.Edge(), aSecondEdge.Edge(), 
113                                        aThirdEdge.Edge(), aFourthEdge.Edge() );
114     
115     TopoDS_Wire aSectProfileWire = aMakeWire.Wire();
116     
117     BRepBuilderAPI_MakeFace aMakeFace( aSectProfileWire, Standard_True );
118     aMakeFace.Build();
119     if( aMakeFace.IsDone() )
120     {
121       a2dShellBuilder.Add( a2dShell, aMakeFace.Face() );
122     }
123
124     aPrevFirstPoint = aCurFirstPoint;
125     aPrevLastPoint = aCurLastPoint;
126   }
127
128   SetTopShape( a2dShell );
129
130   // Construct the 3D presentation
131   /// TODO
132 }
133
134 bool HYDROData_Stream::SetHydraulicAxis( const Handle(HYDROData_PolylineXY)& theAxis )
135 {
136   Handle(HYDROData_PolylineXY) aPrevAxis = GetHydraulicAxis();
137
138   if ( theAxis.IsNull() )
139   {
140     RemoveHydraulicAxis();
141     return !aPrevAxis.IsNull();
142   }
143
144   if ( IsEqual( aPrevAxis, theAxis ) )
145     return false;
146
147   TopoDS_Wire aHydraulicWire = TopoDS::Wire( theAxis->GetShape() );
148   if ( aHydraulicWire.IsNull() )
149     return false; // The polyline must be a single wire
150
151   SetReferenceObject( theAxis, DataTag_HydraulicAxis );
152
153   // Update the order of profiles
154   updateProfilesOrder();
155
156   // Indicate model of the need to update the stream presentation
157   SetToUpdate( true );
158
159   return true;
160 }
161
162 Handle(HYDROData_PolylineXY) HYDROData_Stream::GetHydraulicAxis() const
163 {
164   return Handle(HYDROData_PolylineXY)::DownCast( 
165            GetReferenceObject( DataTag_HydraulicAxis ) );
166 }
167
168 void HYDROData_Stream::RemoveHydraulicAxis()
169 {
170   Handle(HYDROData_PolylineXY) aPrevAxis = GetHydraulicAxis();
171   if ( aPrevAxis.IsNull() )
172     return;
173
174   ClearReferenceObjects( DataTag_HydraulicAxis );
175
176   // We remove the reference profiles
177   RemoveProfiles();
178
179   // Indicate model of the need to update the stream presentation
180   SetToUpdate( true );
181 }
182
183 bool HYDROData_Stream::HasIntersection( const Handle(HYDROData_Profile)& theProfile ) const
184 {
185   Handle(HYDROData_PolylineXY) aHydAxis = GetHydraulicAxis();
186   if ( theProfile.IsNull() || aHydAxis.IsNull() )
187     return false; 
188
189   TopoDS_Wire aHydraulicWire = TopoDS::Wire( aHydAxis->GetShape() );
190   TopoDS_Wire aProfileWire = TopoDS::Wire( theProfile->GetTopShape() );
191   if ( aHydraulicWire.IsNull() || aProfileWire.IsNull() )
192     return false;
193
194   // TODO
195
196   return true;
197 }
198
199 bool HYDROData_Stream::AddProfile( const Handle(HYDROData_Profile)& theProfile )
200 {
201   if ( theProfile.IsNull() )
202     return false; 
203
204   if ( HasReference( theProfile, DataTag_Profile ) || !HasIntersection( theProfile ) )
205     return false; // Object is already in reference list or it has no intersection
206
207   insertProfileInToOrder( theProfile );
208   
209   // Indicate model of the need to update the stream presentation
210   SetToUpdate( true );
211
212   return true;
213 }
214
215 HYDROData_SequenceOfObjects HYDROData_Stream::GetProfiles() const
216 {
217   return GetReferenceObjects( DataTag_Profile );
218 }
219
220 bool HYDROData_Stream::RemoveProfile( const Handle(HYDROData_Profile)& theProfile )
221 {
222   if ( theProfile.IsNull() || !HasReference( theProfile, DataTag_Profile ) )
223     return false;
224
225   RemoveReferenceObject( theProfile->Label(), DataTag_Profile );
226
227   // Indicate model of the need to update the stream presentation
228   SetToUpdate( true );
229
230   return true;
231 }
232
233 void HYDROData_Stream::RemoveProfiles()
234 {
235   bool anIsToUpdate = IsMustBeUpdated() || NbReferenceObjects( DataTag_Profile ) > 0;
236
237   ClearReferenceObjects( DataTag_Profile );
238
239   // Indicate model of the need to update the stream presentation
240   SetToUpdate( anIsToUpdate );
241 }
242
243 void HYDROData_Stream::insertProfileInToOrder( const Handle(HYDROData_Profile)& theProfile )
244 {
245   Handle(HYDROData_PolylineXY) aHydAxis = GetHydraulicAxis();
246   if ( theProfile.IsNull() || aHydAxis.IsNull() )
247     return; 
248
249   TopoDS_Wire aHydraulicWire = TopoDS::Wire( aHydAxis->GetShape() );
250   TopoDS_Wire aProfileWire = TopoDS::Wire( theProfile->GetTopShape() );
251   if ( aHydraulicWire.IsNull() || aProfileWire.IsNull() )
252     return;
253
254   // TODO
255   AddReferenceObject( theProfile, DataTag_Profile ); // temporary for testing only
256 }
257
258 void HYDROData_Stream::updateProfilesOrder()
259 {
260   HYDROData_SequenceOfObjects aRefProfiles = GetProfiles();
261   if ( aRefProfiles.IsEmpty() )
262     return;
263
264   // At first we remove all profiles from order
265   RemoveProfiles();
266
267   Handle(HYDROData_PolylineXY) aHydAxis = GetHydraulicAxis();
268   if ( aHydAxis.IsNull() )
269     return;
270
271   HYDROData_SequenceOfObjects::Iterator anIter( aRefProfiles );
272   for ( ; anIter.More(); anIter.Next() )
273   {
274     Handle(HYDROData_Profile) aProfile =
275       Handle(HYDROData_Profile)::DownCast( anIter.Value() );
276     if ( aProfile.IsNull() || !HasIntersection( aProfile ) )
277       continue;
278
279     insertProfileInToOrder( aProfile );
280   }
281 }
282