Salome HOME
refs #561: the draft data model for Strickler table
[modules/hydro.git] / src / HYDROData / HYDROData_ImmersibleZone.cxx
1 // Copyright (C) 2014-2015  EDF-R&D
2 // This library is free software; you can redistribute it and/or
3 // modify it under the terms of the GNU Lesser General Public
4 // License as published by the Free Software Foundation; either
5 // version 2.1 of the License, or (at your option) any later version.
6 //
7 // This library is distributed in the hope that it will be useful,
8 // but WITHOUT ANY WARRANTY; without even the implied warranty of
9 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
10 // Lesser General Public License for more details.
11 //
12 // You should have received a copy of the GNU Lesser General Public
13 // License along with this library; if not, write to the Free Software
14 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
15 //
16 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
17 //
18
19 #include "HYDROData_ImmersibleZone.h"
20
21 #include "HYDROData_IAltitudeObject.h"
22 #include "HYDROData_Document.h"
23 #include "HYDROData_ShapesGroup.h"
24 #include "HYDROData_PolylineXY.h"
25 #include "HYDROData_ShapesTool.h"
26
27 #include <BRepBuilderAPI_MakeFace.hxx>
28
29 #include <TopoDS.hxx>
30 #include <TopoDS_Face.hxx>
31 #include <TopoDS_Wire.hxx>
32 #include <TopoDS_Compound.hxx>
33 #include <TopExp_Explorer.hxx>
34 #include <TopTools_ListIteratorOfListOfShape.hxx>
35
36 #include <BRep_Builder.hxx>
37 #include <BRepAlgo_FaceRestrictor.hxx>
38 #include <BRepCheck_Analyzer.hxx>
39
40 #include <ShapeAnalysis.hxx>
41
42 #include <QColor>
43 #include <QStringList>
44
45 //#define HYDRODATA_IMZONE_DEB 1
46
47 IMPLEMENT_STANDARD_HANDLE(HYDROData_ImmersibleZone,HYDROData_NaturalObject)
48 IMPLEMENT_STANDARD_RTTIEXT(HYDROData_ImmersibleZone,HYDROData_NaturalObject)
49
50
51 HYDROData_ImmersibleZone::HYDROData_ImmersibleZone()
52 : HYDROData_NaturalObject()
53 {
54 }
55
56 HYDROData_ImmersibleZone::~HYDROData_ImmersibleZone()
57 {
58 }
59
60 QStringList HYDROData_ImmersibleZone::DumpToPython( MapOfTreatedObjects& theTreatedObjects ) const
61 {
62   QStringList aResList = dumpObjectCreation( theTreatedObjects );
63   
64   QString aZoneName = GetObjPyName();
65
66   Handle(HYDROData_IAltitudeObject) aRefAltitude = GetAltitudeObject();
67   setPythonReferenceObject( theTreatedObjects, aResList, aRefAltitude, "SetAltitudeObject" );
68
69   Handle(HYDROData_PolylineXY) aRefPolyline = GetPolyline();
70   setPythonReferenceObject( theTreatedObjects, aResList, aRefPolyline, "SetPolyline" );
71
72   aResList << QString( "" );
73
74   aResList << QString( "%1.Update();" ).arg( aZoneName );
75   aResList << QString( "" );
76
77   return aResList;
78 }
79
80 HYDROData_SequenceOfObjects HYDROData_ImmersibleZone::GetAllReferenceObjects() const
81 {
82   HYDROData_SequenceOfObjects aResSeq = HYDROData_NaturalObject::GetAllReferenceObjects();
83
84   Handle(HYDROData_PolylineXY) aRefPolyline = GetPolyline();
85   if ( !aRefPolyline.IsNull() )
86     aResSeq.Append( aRefPolyline );
87
88   return aResSeq;
89 }
90
91 TopoDS_Shape HYDROData_ImmersibleZone::GetTopShape() const
92 {
93   return getTopShape();
94 }
95
96 void HYDROData_ImmersibleZone::Update()
97 {
98   HYDROData_NaturalObject::Update();
99   
100   TopoDS_Shape aResShape = generateTopShape();
101   SetTopShape( aResShape );
102
103   createGroupObjects();
104 }
105
106 bool HYDROData_ImmersibleZone::IsHas2dPrs() const
107 {
108   return true;
109 }
110
111 TopoDS_Shape HYDROData_ImmersibleZone::generateTopShape() const
112 {
113   return generateTopShape( GetPolyline() );
114 }
115
116 TopoDS_Shape HYDROData_ImmersibleZone::generateTopShape( const Handle(HYDROData_PolylineXY)& aPolyline )
117 {
118   TopoDS_Face aResultFace = TopoDS_Face();
119
120   if( !aPolyline.IsNull() )
121   {
122     TopoDS_Shape aPolylineShape = aPolyline->GetShape();
123     TopTools_ListOfShape aWiresList;
124
125     if ( !aPolylineShape.IsNull() && 
126          aPolylineShape.ShapeType() == TopAbs_WIRE ) {
127       const TopoDS_Wire& aPolylineWire = TopoDS::Wire( aPolylineShape );
128       if ( !aPolylineWire.IsNull() ) {
129         BRepBuilderAPI_MakeFace aMakeFace( aPolylineWire, Standard_True );
130         aMakeFace.Build();
131         if( aMakeFace.IsDone() ) {
132           aResultFace = aMakeFace.Face();
133         }
134       }
135     } else {
136       TopExp_Explorer anExp( aPolylineShape, TopAbs_WIRE );
137       for ( ; anExp.More(); anExp.Next() ) {
138         if(!anExp.Current().IsNull()) {
139           const TopoDS_Wire& aWire = TopoDS::Wire( anExp.Current() );
140           aWiresList.Append( aWire );
141         }
142       }
143       if(aWiresList.IsEmpty())
144          return aResultFace;
145
146       BRepAlgo_FaceRestrictor aFR;
147       TopoDS_Face aRefFace;      
148       TopoDS_Shape aS = aWiresList.First();
149       BRepBuilderAPI_MakeFace aMakeFace( TopoDS::Wire(aWiresList.First()), Standard_True );
150       aMakeFace.Build();
151       if( aMakeFace.IsDone() ) {
152         aRefFace = aMakeFace.Face();
153       }
154       if(aRefFace.IsNull())
155         return aResultFace;
156
157       aFR.Init(aRefFace,Standard_False, Standard_True);
158       TopTools_ListIteratorOfListOfShape anIt( aWiresList );
159       for ( ; anIt.More(); anIt.Next() ) {
160         TopoDS_Wire& aWire = TopoDS::Wire( anIt.Value() );
161         if ( aWire.IsNull() ) 
162             continue;
163         aFR.Add(aWire);
164       }
165       aFR.Perform();
166       if (aFR.IsDone()) {
167         for (; aFR.More(); aFR.Next()) {
168           aResultFace = aFR.Current();
169           break;
170         }
171       }
172     }
173   }
174
175   if( aResultFace.IsNull() )
176     return aResultFace;
177
178   BRepCheck_Analyzer anAnalyzer( aResultFace );
179   if( anAnalyzer.IsValid() && aResultFace.ShapeType()==TopAbs_FACE )
180     return aResultFace;
181   else
182     return TopoDS_Face();
183 }
184
185 void HYDROData_ImmersibleZone::createGroupObjects()
186 {
187   TopoDS_Shape aZoneShape = GetTopShape();
188   
189   // Temporary solution while the restriction for polylines is not implemented
190   // and shape for zone can be compound and not face only
191   if ( !aZoneShape.IsNull() && aZoneShape.ShapeType() != TopAbs_FACE )
192   {
193     TopExp_Explorer aZoneFaceExp( aZoneShape, TopAbs_FACE );
194     if ( aZoneFaceExp.More() )
195       aZoneShape = aZoneFaceExp.Current(); // Take only first face into account
196   }
197
198   if ( aZoneShape.IsNull() || aZoneShape.ShapeType() != TopAbs_FACE )
199     return;
200
201   TopoDS_Face aZoneFace = TopoDS::Face( aZoneShape );
202   
203   TopoDS_Wire aZoneOuterWire = ShapeAnalysis::OuterWire( aZoneFace );
204
205   // Create outer edges group
206   QString anOutWiresGroupName = GetName() + "_Outer";
207
208   Handle(HYDROData_ShapesGroup) anOutWiresGroup = createGroupObject();
209   anOutWiresGroup->SetName( anOutWiresGroupName );
210
211   TopTools_SequenceOfShape anOuterEdges;
212   HYDROData_ShapesTool::ExploreShapeToShapes( aZoneOuterWire, TopAbs_EDGE, anOuterEdges );
213   anOutWiresGroup->SetShapes( anOuterEdges );
214
215   int anInnerCounter = 1;
216   TopExp_Explorer aZoneFaceExp( aZoneFace, TopAbs_WIRE );
217   for ( ; aZoneFaceExp.More(); aZoneFaceExp.Next() )
218   {
219     TopoDS_Wire aZoneWire = TopoDS::Wire( aZoneFaceExp.Current() );
220     if ( aZoneWire.IsEqual( aZoneOuterWire ) )
221       continue; // Skip the outer wire
222
223     TopTools_SequenceOfShape anInnerEdges;
224     HYDROData_ShapesTool::ExploreShapeToShapes( aZoneWire, TopAbs_EDGE, anInnerEdges );
225     if ( anInnerEdges.IsEmpty() )
226       continue;
227
228     QString anInWiresGroupName = GetName() + "_Inner_" + QString::number( anInnerCounter++ );
229
230     Handle(HYDROData_ShapesGroup) anInWiresGroup = createGroupObject();
231     anInWiresGroup->SetName( anInWiresGroupName );
232
233     anInWiresGroup->SetShapes( anInnerEdges );
234   }  
235 }
236
237 TopoDS_Shape HYDROData_ImmersibleZone::GetShape3D() const
238 {
239   return getTopShape();
240 }
241
242 QColor HYDROData_ImmersibleZone::DefaultFillingColor()
243 {
244   return QColor( Qt::darkBlue );
245 }
246
247 QColor HYDROData_ImmersibleZone::DefaultBorderColor()
248 {
249   return QColor( Qt::transparent );
250 }
251
252 QColor HYDROData_ImmersibleZone::getDefaultFillingColor() const
253 {
254   return DefaultFillingColor();
255 }
256
257 QColor HYDROData_ImmersibleZone::getDefaultBorderColor() const
258 {
259   return DefaultBorderColor();
260 }
261
262 void HYDROData_ImmersibleZone::SetPolyline( const Handle(HYDROData_PolylineXY)& thePolyline )
263 {
264   SetReferenceObject( thePolyline, DataTag_Polyline );
265   SetToUpdate( true );
266 }
267
268 Handle(HYDROData_PolylineXY) HYDROData_ImmersibleZone::GetPolyline() const
269 {
270   return Handle(HYDROData_PolylineXY)::DownCast( 
271            GetReferenceObject( DataTag_Polyline ) );
272 }
273
274 void HYDROData_ImmersibleZone::RemovePolyline()
275 {
276   ClearReferenceObjects( DataTag_Polyline );
277   SetToUpdate( true );
278 }
279
280