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