Salome HOME
9499aea834fd372eb43cfc4eaea9cfdbc9185d4b
[modules/hydro.git] / src / HYDROData / HYDROData_Channel.cxx
1
2 #include "HYDROData_Channel.h"
3
4 #include "HYDROData_Document.h"
5 #include "HYDROData_Polyline3D.h"
6 #include "HYDROData_Profile.h"
7 #include "HYDROData_PolylineXY.h"
8 #include "HYDROData_Projection.h"
9 #include "HYDROData_ShapesGroup.h"
10 #include "HYDROData_ShapesTool.h"
11
12 #include <BRepOffsetAPI_MakePipeShell.hxx>
13 #include <BRepOffsetAPI_MakePipe.hxx>
14 #include <BRepCheck_Analyzer.hxx>
15
16 #include <TopExp.hxx>
17
18 #include <TopoDS.hxx>
19 #include <TopoDS_Wire.hxx>
20 #include <TopoDS_Vertex.hxx>
21 #include <TopoDS_Face.hxx>
22
23 //#define DEB_CHANNEL 1
24 #ifdef DEB_CHANNEL
25 #include <BRepTools.hxx>
26 #endif
27
28 #include <QColor>
29 #include <QStringList>
30
31 #define PYTHON_CHANNEL_ID "KIND_CHANNEL"
32
33 IMPLEMENT_STANDARD_HANDLE(HYDROData_Channel,HYDROData_ArtificialObject)
34 IMPLEMENT_STANDARD_RTTIEXT(HYDROData_Channel,HYDROData_ArtificialObject)
35
36
37 HYDROData_Channel::HYDROData_Channel()
38 : HYDROData_ArtificialObject()
39 {
40 }
41
42 HYDROData_Channel::~HYDROData_Channel()
43 {
44 }
45
46 QStringList HYDROData_Channel::DumpToPython( MapOfTreatedObjects& theTreatedObjects ) const
47 {
48   QStringList aResList;
49
50   Handle(HYDROData_Document) aDocument = HYDROData_Document::Document( myLab );
51   if ( aDocument.IsNull() )
52     return aResList;
53
54   QString aDocName = aDocument->GetDocPyName();
55   QString aChannelName = GetName();
56
57   aResList << QString( "%1 = %2.CreateObject( %3 );" )
58               .arg( aChannelName ).arg( aDocName ).arg( PYTHON_CHANNEL_ID );
59   aResList << QString( "%1.SetName( \"%2\" );" )
60               .arg( aChannelName ).arg( aChannelName );
61   aResList << QString( "" );
62
63   // TODO
64
65   return aResList;
66 }
67
68 HYDROData_SequenceOfObjects HYDROData_Channel::GetAllReferenceObjects() const
69 {
70   HYDROData_SequenceOfObjects aResSeq = HYDROData_ArtificialObject::GetAllReferenceObjects();
71
72   Handle(HYDROData_Polyline3D) aGuideLine = GetGuideLine();
73   if ( !aGuideLine.IsNull() )
74     aResSeq.Append( aGuideLine );
75
76   Handle(HYDROData_Profile) aProfile = GetProfile();
77   if ( !aProfile.IsNull() )
78     aResSeq.Append( aProfile );
79
80   return aResSeq;
81 }
82
83 TopoDS_Shape HYDROData_Channel::GetTopShape() const
84 {
85   return getTopShape();
86 }
87
88 TopoDS_Shape HYDROData_Channel::GetShape3D() const
89 {
90   return getShape3D();
91 }
92
93 void HYDROData_Channel::Update()
94 {
95   HYDROData_ArtificialObject::Update();
96
97   Handle(HYDROData_Polyline3D) aGuideLine = GetGuideLine();
98   Handle(HYDROData_Profile) aProfile = GetProfile();
99   if ( aGuideLine.IsNull() || aProfile.IsNull() )
100     return;
101
102   // build 3d shape 
103   TopoDS_Wire aPathWire = TopoDS::Wire(aGuideLine->GetShape3D());
104   if(aPathWire.IsNull())
105     return;
106   TopoDS_Wire aProfileWire = TopoDS::Wire( aProfile->GetShape3D() );
107   if(aProfileWire.IsNull())
108     return;
109
110   BRepOffsetAPI_MakePipeShell aMkSweep(aPathWire);
111   aMkSweep.Add(aProfileWire,Standard_True, Standard_True);
112   aMkSweep.SetTransitionMode(BRepBuilderAPI_RightCorner);
113   //aMkSweep.SetMode(Standard_True);
114   aMkSweep.Build();
115   if(aMkSweep.IsDone()) {
116     const TopoDS_Shape& aChannel = aMkSweep.Shape();
117     BRepCheck_Analyzer aCheck(aChannel);
118     if(aCheck.IsValid()) 
119     {
120       //BRepTools::Write(aChannel, "ChanV.brep");  
121       SetShape3D( aMkSweep.Shape());
122     } else {
123 #ifdef DEB_CHANNEL
124       cout <<"NOT VALID" <<endl;
125       BRepTools::Write(aChannel, "ChanNV.brep");
126 #endif
127     }
128   }
129
130   TopoDS_Shape a3dShape = GetShape3D();
131   if ( a3dShape.IsNull() )
132     return;
133
134   // build 2d shape -- temporary solution!!
135   TopoDS_Face aProj = HYDROData_Projection::MakeProjection( a3dShape );
136   SetTopShape( aProj );
137   if ( aProj.IsNull() )
138     return;
139
140   // Create the channel groups
141   TopoDS_Shape aFirstShape = aMkSweep.FirstShape();
142   TopoDS_Shape aLastShape = aMkSweep.LastShape();
143   if ( aFirstShape.IsNull() || aFirstShape.ShapeType() != TopAbs_WIRE ||
144        aLastShape.IsNull()  || aLastShape.ShapeType() != TopAbs_WIRE )
145     return;
146
147   TopoDS_Wire anInletWire = TopoDS::Wire( aFirstShape );
148   TopoDS_Wire anOutletWire = TopoDS::Wire( aLastShape );
149
150   TopoDS_Vertex anInletFirstVert, anInletLastVert;
151   TopExp::Vertices( anInletWire, anInletFirstVert, anInletLastVert );
152
153   const TopTools_ListOfShape& aGeneratedLeftEdges = aMkSweep.Generated( anInletFirstVert );
154   const TopTools_ListOfShape& aGeneratedRightEdges = aMkSweep.Generated( anInletLastVert );
155
156   TopTools_SequenceOfShape aProjEdges;
157   HYDROData_ShapesTool::ExploreShapeToShapes( aProj, TopAbs_EDGE, aProjEdges );
158
159   TopTools_SequenceOfShape aProjLeftEdges;
160   findEdges( aProjEdges, aGeneratedLeftEdges, aProjLeftEdges );
161
162   TopTools_SequenceOfShape aProjRightEdges;
163   findEdges( aProjEdges, aGeneratedRightEdges, aProjRightEdges );
164
165   TopTools_SequenceOfShape aProjInletEdges;
166   findEdges( aProjEdges, anInletWire, aProjInletEdges );
167
168   TopTools_SequenceOfShape aProjOutletEdges;
169   findEdges( aProjEdges, anOutletWire, aProjOutletEdges );
170
171   QString aLeftGroupName = GetName() + "_Left_Bank";
172
173   Handle(HYDROData_ShapesGroup) aLeftGroup = createGroupObject();
174   aLeftGroup->SetName( aLeftGroupName );
175   aLeftGroup->SetShapes( aProjLeftEdges );
176
177   QString aRightGroupName = GetName() + "_Right_Bank";
178
179   Handle(HYDROData_ShapesGroup) aRightGroup = createGroupObject();
180   aRightGroup->SetName( aRightGroupName );
181   aRightGroup->SetShapes( aProjRightEdges );
182
183   QString anInGroupName = GetName() + "_Inlet";
184
185   Handle(HYDROData_ShapesGroup) anInGroup = createGroupObject();
186   anInGroup->SetName( anInGroupName );
187   anInGroup->SetShapes( aProjInletEdges );
188
189   QString anOutGroupName = GetName() + "_Outlet";
190
191   Handle(HYDROData_ShapesGroup) anOutGroup = createGroupObject();
192   anOutGroup->SetName( anOutGroupName );
193   anOutGroup->SetShapes( aProjOutletEdges );
194 }
195
196 QColor HYDROData_Channel::DefaultFillingColor()
197 {
198   return QColor( Qt::blue );
199 }
200
201 QColor HYDROData_Channel::DefaultBorderColor()
202 {
203   return QColor( Qt::transparent );
204 }
205
206 QColor HYDROData_Channel::getDefaultFillingColor() const
207 {
208   return DefaultFillingColor();
209 }
210
211 QColor HYDROData_Channel::getDefaultBorderColor() const
212 {
213   return DefaultBorderColor();
214 }
215
216 bool HYDROData_Channel::SetGuideLine( const Handle(HYDROData_Polyline3D)& theGuideLine )
217 {
218   Handle(HYDROData_Polyline3D) aPrevGuideLine = GetGuideLine();
219
220   if ( theGuideLine.IsNull() )
221   {
222     RemoveGuideLine();
223     return !aPrevGuideLine.IsNull();
224   }
225
226   if ( IsEqual( aPrevGuideLine, theGuideLine ) )
227     return false;
228
229   TopoDS_Wire aHydraulicWire = TopoDS::Wire( theGuideLine->GetTopShape() );
230   if ( aHydraulicWire.IsNull() )
231     return false; // The polyline must be a single wire
232
233   SetReferenceObject( theGuideLine, DataTag_GuideLine );
234
235   // Indicate model of the need to update the chanel presentation
236   SetToUpdate( true );
237
238   return true;
239 }
240
241 Handle(HYDROData_Polyline3D) HYDROData_Channel::GetGuideLine() const
242 {
243   return Handle(HYDROData_Polyline3D)::DownCast( 
244            GetReferenceObject( DataTag_GuideLine ) );
245 }
246
247 void HYDROData_Channel::RemoveGuideLine()
248 {
249   Handle(HYDROData_Polyline3D) aPrevGuideLine = GetGuideLine();
250   if ( aPrevGuideLine.IsNull() )
251     return;
252
253   ClearReferenceObjects( DataTag_GuideLine );
254
255   // Indicate model of the need to update the chanel presentation
256   SetToUpdate( true );
257 }
258
259 bool HYDROData_Channel::SetProfile( const Handle(HYDROData_Profile)& theProfile )
260 {
261   Handle(HYDROData_Profile) aPrevProfile = GetProfile();
262
263   if ( theProfile.IsNull() )
264   {
265     RemoveProfile();
266     return !aPrevProfile.IsNull();
267   }
268
269   if ( IsEqual( aPrevProfile, theProfile ) )
270     return false;
271
272   SetReferenceObject( theProfile, DataTag_Profile );
273
274   // Indicate model of the need to update the chanel presentation
275   SetToUpdate( true );
276
277   return true;
278 }
279
280 Handle(HYDROData_Profile) HYDROData_Channel::GetProfile() const
281 {
282   return Handle(HYDROData_Profile)::DownCast( 
283            GetReferenceObject( DataTag_Profile ) );
284 }
285
286 void HYDROData_Channel::RemoveProfile()
287 {
288   Handle(HYDROData_Profile) aPrevProfile = GetProfile();
289   if ( aPrevProfile.IsNull() )
290     return;
291
292   ClearReferenceObjects( DataTag_Profile );
293
294   // Indicate model of the need to update the chanel presentation
295   SetToUpdate( true );
296 }
297
298 ObjectKind HYDROData_Channel::getAltitudeObjectType() const
299 {
300   return KIND_OBSTACLE_ALTITUDE;
301 }
302
303 void HYDROData_Channel::findEdges( const TopTools_SequenceOfShape& theInShapes,
304                                    const TopTools_ListOfShape&     theEdges3D,
305                                    TopTools_SequenceOfShape&       theOutShapes ) const
306 {
307   theOutShapes.Clear();
308   if ( theEdges3D.IsEmpty() || theInShapes.IsEmpty() )
309     return;
310
311   const TopoDS_Shape& aFirstShape3D = theEdges3D.First();
312   const TopoDS_Shape& aLastShape3D = theEdges3D.Last();
313
314   TopoDS_Vertex aFirstVert, aLastVert, aDummyVert;
315   if ( !HYDROData_ShapesTool::Vertices( aFirstShape3D, aFirstVert, aDummyVert ) ||
316        !HYDROData_ShapesTool::Vertices( aLastShape3D, aDummyVert, aLastVert ) )
317     return;
318
319   bool isStarted = false;
320   for ( int i = 1, n = theInShapes.Length(); i <= n; ++i )
321   {
322     const TopoDS_Shape& anInShape = theInShapes.Value( i );
323
324     TopoDS_Vertex aShapeFirstVert, aShapeLastVert;
325     if ( !HYDROData_ShapesTool::Vertices( anInShape, aShapeFirstVert, aShapeLastVert ) )
326       continue;
327
328     if ( !isStarted )
329     {
330       isStarted = HYDROData_ShapesTool::IsVerticesEquals( aFirstVert, aShapeFirstVert, true );
331     }
332
333     if ( isStarted )
334     {
335       theOutShapes.Append( anInShape );
336
337       if ( HYDROData_ShapesTool::IsVerticesEquals( aLastVert, aShapeLastVert, true ) )
338         break;
339     }
340   }
341 }
342
343 void HYDROData_Channel::findEdges( const TopTools_SequenceOfShape& theProjShapes,
344                                    const TopoDS_Shape&             theEdge3D,
345                                    TopTools_SequenceOfShape&       theOutShapes ) const
346 {
347   TopTools_ListOfShape aTmpList;
348   aTmpList.Append( theEdge3D );
349   findEdges( theProjShapes, aTmpList, theOutShapes );
350 }
351