Salome HOME
29bc3a6d34c8f5627b9885830ad99a4e8f5bd98a
[modules/hydro.git] / src / HYDROData / HYDROData_ImmersibleZone.cxx
1
2 #include "HYDROData_ImmersibleZone.h"
3
4 #include "HYDROData_Bathymetry.h"
5 #include "HYDROData_Document.h"
6 #include "HYDROData_ShapesGroup.h"
7 #include "HYDROData_PolylineXY.h"
8 #include "HYDROData_Tool.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 PYTHON_IMMERSIBLE_ZONE_ID "KIND_IMMERSIBLE_ZONE"
29 //#define HYDRODATA_IMZONE_DEB 1
30
31 IMPLEMENT_STANDARD_HANDLE(HYDROData_ImmersibleZone,HYDROData_NaturalObject)
32 IMPLEMENT_STANDARD_RTTIEXT(HYDROData_ImmersibleZone,HYDROData_NaturalObject)
33
34
35 HYDROData_ImmersibleZone::HYDROData_ImmersibleZone()
36 : HYDROData_NaturalObject()
37 {
38 }
39
40 HYDROData_ImmersibleZone::~HYDROData_ImmersibleZone()
41 {
42 }
43
44 QStringList HYDROData_ImmersibleZone::DumpToPython( MapOfTreatedObjects& theTreatedObjects ) const
45 {
46   QStringList aResList;
47
48   Handle(HYDROData_Document) aDocument = HYDROData_Document::Document( myLab );
49   if ( aDocument.IsNull() )
50     return aResList;
51
52   QString aDocName = aDocument->GetDocPyName();
53   QString aZoneName = GetName();
54
55   aResList << QString( "%1 = %2.CreateObject( %3 );" )
56               .arg( aZoneName ).arg( aDocName ).arg( PYTHON_IMMERSIBLE_ZONE_ID );
57   aResList << QString( "%1.SetName( \"%2\" );" )
58               .arg( aZoneName ).arg( aZoneName );
59   aResList << QString( "" );
60
61   QColor aFillingColor = GetFillingColor();
62   aResList << QString( "filling_color = QColor( %1, %2, %3, %4 );" )
63               .arg( aFillingColor.red()  ).arg( aFillingColor.green() )
64               .arg( aFillingColor.blue() ).arg( aFillingColor.alpha() );
65   aResList << QString( "%1.SetFillingColor( filling_color );" ).arg( aZoneName );
66   aResList << QString( "" );
67
68   QColor aBorderColor = GetBorderColor();
69   aResList << QString( "border_color = QColor( %1, %2, %3, %4 );" )
70               .arg( aBorderColor.red()  ).arg( aBorderColor.green() )
71               .arg( aBorderColor.blue() ).arg( aBorderColor.alpha() );
72   aResList << QString( "%1.SetBorderColor( border_color );" ).arg( aZoneName );
73   aResList << QString( "" );
74
75   Handle(HYDROData_Bathymetry) aRefBathymetry = GetBathymetry();
76   setPythonReferenceObject( theTreatedObjects, aResList, aRefBathymetry, "SetBathymetry" );
77
78   Handle(HYDROData_PolylineXY) aRefPolyline = GetPolyline();
79   setPythonReferenceObject( theTreatedObjects, aResList, aRefPolyline, "SetPolyline" );
80
81   return aResList;
82 }
83
84 HYDROData_SequenceOfObjects HYDROData_ImmersibleZone::GetAllReferenceObjects() const
85 {
86   HYDROData_SequenceOfObjects aResSeq = HYDROData_NaturalObject::GetAllReferenceObjects();
87
88   Handle(HYDROData_PolylineXY) aRefPolyline = GetPolyline();
89   if ( !aRefPolyline.IsNull() )
90     aResSeq.Append( aRefPolyline );
91
92   return aResSeq;
93 }
94
95 TopoDS_Shape HYDROData_ImmersibleZone::GetTopShape() const
96 {
97   return getTopShape();
98 }
99
100 void HYDROData_ImmersibleZone::Update()
101 {
102   HYDROData_NaturalObject::Update();
103   
104   TopoDS_Shape aResShape = generateTopShape();
105   SetTopShape( aResShape );
106
107   createGroupObjects();
108 }
109
110 TopoDS_Shape HYDROData_ImmersibleZone::generateTopShape() const
111 {
112   TopoDS_Shape aResShape = TopoDS_Face();
113
114   Handle(HYDROData_PolylineXY) aPolyline = GetPolyline();
115   if( !aPolyline.IsNull() )
116   {
117     TopoDS_Shape aPolylineShape = aPolyline->GetShape();
118     TopTools_ListOfShape aWiresList;
119
120     if ( !aPolylineShape.IsNull() && 
121          aPolylineShape.ShapeType() == TopAbs_WIRE ) {
122       const TopoDS_Wire& aPolylineWire = TopoDS::Wire( aPolylineShape );
123       if ( !aPolylineWire.IsNull() ) {
124         BRepBuilderAPI_MakeFace aMakeFace( aPolylineWire, Standard_True );
125         aMakeFace.Build();
126         if( aMakeFace.IsDone() ) {
127           return aMakeFace.Face();
128         }
129       }
130     } else {
131       TopExp_Explorer anExp( aPolylineShape, TopAbs_WIRE );
132       for ( ; anExp.More(); anExp.Next() ) {
133         if(!anExp.Current().IsNull()) {
134           const TopoDS_Wire& aWire = TopoDS::Wire( anExp.Current() );
135           aWiresList.Append( aWire );
136         }
137       }
138       if(aWiresList.IsEmpty())
139          return aResShape;
140       BRepAlgo_FaceRestrictor aFR;
141       TopoDS_Face aRefFace;      
142       TopoDS_Shape aS = aWiresList.First();
143       BRepBuilderAPI_MakeFace aMakeFace( TopoDS::Wire(aWiresList.First()), Standard_True );
144       aMakeFace.Build();
145       if( aMakeFace.IsDone() ) {
146         aRefFace = aMakeFace.Face();
147       }
148       if(aRefFace.IsNull())
149         return aResShape;
150       aFR.Init(aRefFace,Standard_False, Standard_True);
151       TopTools_ListIteratorOfListOfShape anIt( aWiresList );
152       for ( ; anIt.More(); anIt.Next() ) {
153         TopoDS_Wire& aWire = TopoDS::Wire( anIt.Value() );
154         if ( aWire.IsNull() ) 
155             continue;
156         aFR.Add(aWire);
157       }
158       aFR.Perform();
159       if (aFR.IsDone()) {
160         TopoDS_Compound aResult;
161         BRep_Builder aBB;
162         aBB.MakeCompound(aResult);
163         for (; aFR.More(); aFR.Next()) {
164           const TopoDS_Face& aFF = aFR.Current();
165           aBB.Add(aResult,aFF);
166         }
167         BRepCheck_Analyzer aChecker(aResult);
168         if(aChecker.IsValid())
169           aResShape = aResult;
170 #ifdef HYDRODATA_IMZONE_DEB
171         else {
172           aResShape = aResult;
173         }
174 #endif
175       }
176     }
177   }
178   return aResShape;
179 }
180
181 void HYDROData_ImmersibleZone::createGroupObjects()
182 {
183   TopoDS_Shape aZoneShape = GetTopShape();
184   
185   // Temporary solution while the restriction for polylines is not implemented
186   // and shape for zone can be compound and not face only
187   if ( !aZoneShape.IsNull() && aZoneShape.ShapeType() != TopAbs_FACE )
188   {
189     TopExp_Explorer aZoneFaceExp( aZoneShape, TopAbs_FACE );
190     if ( aZoneFaceExp.More() )
191       aZoneShape = aZoneFaceExp.Current(); // Take only first face into account
192   }
193
194   if ( aZoneShape.IsNull() || aZoneShape.ShapeType() != TopAbs_FACE )
195     return;
196
197   TopoDS_Face aZoneFace = TopoDS::Face( aZoneShape );
198   
199   TopoDS_Wire aZoneOuterWire = ShapeAnalysis::OuterWire( aZoneFace );
200
201   TopTools_SequenceOfShape anInnerEdges;
202
203   TopExp_Explorer aZoneFaceExp( aZoneFace, TopAbs_WIRE );
204   for ( ; aZoneFaceExp.More(); aZoneFaceExp.Next() )
205   {
206     TopoDS_Wire aZoneWire = TopoDS::Wire( aZoneFaceExp.Current() );
207     if ( aZoneWire.IsEqual( aZoneOuterWire ) )
208       continue; // Skip the outer wire
209
210     TopTools_SequenceOfShape anEdges;
211     HYDROData_Tool::ExploreShapeToShapes( aZoneWire, TopAbs_EDGE, anEdges );
212     anInnerEdges.Append( anEdges );
213   }
214   
215   // Create outer edges group
216   QString anOutWiresGroupName = GetName() + "_Outer_Wire";
217
218   Handle(HYDROData_ShapesGroup) anOutWiresGroup = createGroupObject();
219   anOutWiresGroup->SetName( anOutWiresGroupName );
220
221   TopTools_SequenceOfShape anEdges;
222   HYDROData_Tool::ExploreShapeToShapes( aZoneOuterWire, TopAbs_EDGE, anEdges );
223   anOutWiresGroup->SetShapes( anEdges );
224
225   // Create group for inner edges only if edges is not empty
226   if ( !anInnerEdges.IsEmpty() )
227   {
228     QString anInWiresGroupName = GetName() + "_Inner_Wires";
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