Salome HOME
refs #482: new function for export calculation case
[modules/hydro.git] / src / HYDROData / HYDROData_ImmersibleZone.cxx
1
2 #include "HYDROData_ImmersibleZone.h"
3
4 #include "HYDROData_IAltitudeObject.h"
5 #include "HYDROData_Document.h"
6 #include "HYDROData_ShapesGroup.h"
7 #include "HYDROData_PolylineXY.h"
8 #include "HYDROData_ShapesTool.h"
9
10 #include <BRepBuilderAPI_MakeFace.hxx>
11
12 #include <TopoDS.hxx>
13 #include <TopoDS_Face.hxx>
14 #include <TopoDS_Wire.hxx>
15 #include <TopoDS_Compound.hxx>
16 #include <TopExp_Explorer.hxx>
17 #include <TopTools_ListIteratorOfListOfShape.hxx>
18
19 #include <BRep_Builder.hxx>
20 #include <BRepAlgo_FaceRestrictor.hxx>
21 #include <BRepCheck_Analyzer.hxx>
22
23 #include <ShapeAnalysis.hxx>
24
25 #include <QColor>
26 #include <QStringList>
27
28 //#define HYDRODATA_IMZONE_DEB 1
29
30 IMPLEMENT_STANDARD_HANDLE(HYDROData_ImmersibleZone,HYDROData_NaturalObject)
31 IMPLEMENT_STANDARD_RTTIEXT(HYDROData_ImmersibleZone,HYDROData_NaturalObject)
32
33
34 HYDROData_ImmersibleZone::HYDROData_ImmersibleZone()
35 : HYDROData_NaturalObject()
36 {
37 }
38
39 HYDROData_ImmersibleZone::~HYDROData_ImmersibleZone()
40 {
41 }
42
43 QStringList HYDROData_ImmersibleZone::DumpToPython( MapOfTreatedObjects& theTreatedObjects ) const
44 {
45   QStringList aResList = dumpObjectCreation( theTreatedObjects );
46   
47   QString aZoneName = GetObjPyName();
48
49   Handle(HYDROData_IAltitudeObject) aRefAltitude = GetAltitudeObject();
50   setPythonReferenceObject( theTreatedObjects, aResList, aRefAltitude, "SetAltitudeObject" );
51
52   Handle(HYDROData_PolylineXY) aRefPolyline = GetPolyline();
53   setPythonReferenceObject( theTreatedObjects, aResList, aRefPolyline, "SetPolyline" );
54
55   aResList << QString( "" );
56
57   aResList << QString( "%1.Update();" ).arg( aZoneName );
58   aResList << QString( "" );
59
60   return aResList;
61 }
62
63 HYDROData_SequenceOfObjects HYDROData_ImmersibleZone::GetAllReferenceObjects() const
64 {
65   HYDROData_SequenceOfObjects aResSeq = HYDROData_NaturalObject::GetAllReferenceObjects();
66
67   Handle(HYDROData_PolylineXY) aRefPolyline = GetPolyline();
68   if ( !aRefPolyline.IsNull() )
69     aResSeq.Append( aRefPolyline );
70
71   return aResSeq;
72 }
73
74 TopoDS_Shape HYDROData_ImmersibleZone::GetTopShape() const
75 {
76   return getTopShape();
77 }
78
79 void HYDROData_ImmersibleZone::Update()
80 {
81   HYDROData_NaturalObject::Update();
82   
83   TopoDS_Shape aResShape = generateTopShape();
84   SetTopShape( aResShape );
85
86   createGroupObjects();
87 }
88
89 bool HYDROData_ImmersibleZone::IsHas2dPrs() const
90 {
91   return true;
92 }
93
94 TopoDS_Shape HYDROData_ImmersibleZone::generateTopShape() const
95 {
96   return generateTopShape( GetPolyline() );
97 }
98
99 TopoDS_Shape HYDROData_ImmersibleZone::generateTopShape( const Handle(HYDROData_PolylineXY)& aPolyline )
100 {
101   TopoDS_Face aResultFace = TopoDS_Face();
102
103   if( !aPolyline.IsNull() )
104   {
105     TopoDS_Shape aPolylineShape = aPolyline->GetShape();
106     TopTools_ListOfShape aWiresList;
107
108     if ( !aPolylineShape.IsNull() && 
109          aPolylineShape.ShapeType() == TopAbs_WIRE ) {
110       const TopoDS_Wire& aPolylineWire = TopoDS::Wire( aPolylineShape );
111       if ( !aPolylineWire.IsNull() ) {
112         BRepBuilderAPI_MakeFace aMakeFace( aPolylineWire, Standard_True );
113         aMakeFace.Build();
114         if( aMakeFace.IsDone() ) {
115           aResultFace = aMakeFace.Face();
116         }
117       }
118     } else {
119       TopExp_Explorer anExp( aPolylineShape, TopAbs_WIRE );
120       for ( ; anExp.More(); anExp.Next() ) {
121         if(!anExp.Current().IsNull()) {
122           const TopoDS_Wire& aWire = TopoDS::Wire( anExp.Current() );
123           aWiresList.Append( aWire );
124         }
125       }
126       if(aWiresList.IsEmpty())
127          return aResultFace;
128
129       BRepAlgo_FaceRestrictor aFR;
130       TopoDS_Face aRefFace;      
131       TopoDS_Shape aS = aWiresList.First();
132       BRepBuilderAPI_MakeFace aMakeFace( TopoDS::Wire(aWiresList.First()), Standard_True );
133       aMakeFace.Build();
134       if( aMakeFace.IsDone() ) {
135         aRefFace = aMakeFace.Face();
136       }
137       if(aRefFace.IsNull())
138         return aResultFace;
139
140       aFR.Init(aRefFace,Standard_False, Standard_True);
141       TopTools_ListIteratorOfListOfShape anIt( aWiresList );
142       for ( ; anIt.More(); anIt.Next() ) {
143         TopoDS_Wire& aWire = TopoDS::Wire( anIt.Value() );
144         if ( aWire.IsNull() ) 
145             continue;
146         aFR.Add(aWire);
147       }
148       aFR.Perform();
149       if (aFR.IsDone()) {
150         for (; aFR.More(); aFR.Next()) {
151           aResultFace = aFR.Current();
152           break;
153         }
154       }
155     }
156   }
157
158   if( aResultFace.IsNull() )
159     return aResultFace;
160
161   BRepCheck_Analyzer anAnalyzer( aResultFace );
162   if( anAnalyzer.IsValid() && aResultFace.ShapeType()==TopAbs_FACE )
163     return aResultFace;
164   else
165     return TopoDS_Face();
166 }
167
168 void HYDROData_ImmersibleZone::createGroupObjects()
169 {
170   TopoDS_Shape aZoneShape = GetTopShape();
171   
172   // Temporary solution while the restriction for polylines is not implemented
173   // and shape for zone can be compound and not face only
174   if ( !aZoneShape.IsNull() && aZoneShape.ShapeType() != TopAbs_FACE )
175   {
176     TopExp_Explorer aZoneFaceExp( aZoneShape, TopAbs_FACE );
177     if ( aZoneFaceExp.More() )
178       aZoneShape = aZoneFaceExp.Current(); // Take only first face into account
179   }
180
181   if ( aZoneShape.IsNull() || aZoneShape.ShapeType() != TopAbs_FACE )
182     return;
183
184   TopoDS_Face aZoneFace = TopoDS::Face( aZoneShape );
185   
186   TopoDS_Wire aZoneOuterWire = ShapeAnalysis::OuterWire( aZoneFace );
187
188   // Create outer edges group
189   QString anOutWiresGroupName = GetName() + "_Outer";
190
191   Handle(HYDROData_ShapesGroup) anOutWiresGroup = createGroupObject();
192   anOutWiresGroup->SetName( anOutWiresGroupName );
193
194   TopTools_SequenceOfShape anOuterEdges;
195   HYDROData_ShapesTool::ExploreShapeToShapes( aZoneOuterWire, TopAbs_EDGE, anOuterEdges );
196   anOutWiresGroup->SetShapes( anOuterEdges );
197
198   int anInnerCounter = 1;
199   TopExp_Explorer aZoneFaceExp( aZoneFace, TopAbs_WIRE );
200   for ( ; aZoneFaceExp.More(); aZoneFaceExp.Next() )
201   {
202     TopoDS_Wire aZoneWire = TopoDS::Wire( aZoneFaceExp.Current() );
203     if ( aZoneWire.IsEqual( aZoneOuterWire ) )
204       continue; // Skip the outer wire
205
206     TopTools_SequenceOfShape anInnerEdges;
207     HYDROData_ShapesTool::ExploreShapeToShapes( aZoneWire, TopAbs_EDGE, anInnerEdges );
208     if ( anInnerEdges.IsEmpty() )
209       continue;
210
211     QString anInWiresGroupName = GetName() + "_Inner_" + QString::number( anInnerCounter++ );
212
213     Handle(HYDROData_ShapesGroup) anInWiresGroup = createGroupObject();
214     anInWiresGroup->SetName( anInWiresGroupName );
215
216     anInWiresGroup->SetShapes( anInnerEdges );
217   }  
218 }
219
220 TopoDS_Shape HYDROData_ImmersibleZone::GetShape3D() const
221 {
222   return getTopShape();
223 }
224
225 QColor HYDROData_ImmersibleZone::DefaultFillingColor()
226 {
227   return QColor( Qt::darkBlue );
228 }
229
230 QColor HYDROData_ImmersibleZone::DefaultBorderColor()
231 {
232   return QColor( Qt::transparent );
233 }
234
235 QColor HYDROData_ImmersibleZone::getDefaultFillingColor() const
236 {
237   return DefaultFillingColor();
238 }
239
240 QColor HYDROData_ImmersibleZone::getDefaultBorderColor() const
241 {
242   return DefaultBorderColor();
243 }
244
245 void HYDROData_ImmersibleZone::SetPolyline( const Handle(HYDROData_PolylineXY)& thePolyline )
246 {
247   SetReferenceObject( thePolyline, DataTag_Polyline );
248   SetToUpdate( true );
249 }
250
251 Handle(HYDROData_PolylineXY) HYDROData_ImmersibleZone::GetPolyline() const
252 {
253   return Handle(HYDROData_PolylineXY)::DownCast( 
254            GetReferenceObject( DataTag_Polyline ) );
255 }
256
257 void HYDROData_ImmersibleZone::RemovePolyline()
258 {
259   ClearReferenceObjects( DataTag_Polyline );
260   SetToUpdate( true );
261 }
262
263