Salome HOME
Import profiles protection (Bug #203).
[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 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_IAltitudeObject) aRefAltitude = GetAltitudeObject();
76   setPythonReferenceObject( theTreatedObjects, aResList, aRefAltitude, "SetAltitudeObject" );
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   return generateTopShape( GetPolyline() );
113 }
114
115 TopoDS_Shape HYDROData_ImmersibleZone::generateTopShape( const Handle(HYDROData_PolylineXY)& aPolyline )
116 {
117   TopoDS_Face aResultFace = TopoDS_Face();
118
119   if( !aPolyline.IsNull() )
120   {
121     TopoDS_Shape aPolylineShape = aPolyline->GetShape();
122     TopTools_ListOfShape aWiresList;
123
124     if ( !aPolylineShape.IsNull() && 
125          aPolylineShape.ShapeType() == TopAbs_WIRE ) {
126       const TopoDS_Wire& aPolylineWire = TopoDS::Wire( aPolylineShape );
127       if ( !aPolylineWire.IsNull() ) {
128         BRepBuilderAPI_MakeFace aMakeFace( aPolylineWire, Standard_True );
129         aMakeFace.Build();
130         if( aMakeFace.IsDone() ) {
131           return aMakeFace.Face();
132         }
133       }
134     } else {
135       TopExp_Explorer anExp( aPolylineShape, TopAbs_WIRE );
136       for ( ; anExp.More(); anExp.Next() ) {
137         if(!anExp.Current().IsNull()) {
138           const TopoDS_Wire& aWire = TopoDS::Wire( anExp.Current() );
139           aWiresList.Append( aWire );
140         }
141       }
142       if(aWiresList.IsEmpty())
143          return aResultFace;
144
145       BRepAlgo_FaceRestrictor aFR;
146       TopoDS_Face aRefFace;      
147       TopoDS_Shape aS = aWiresList.First();
148       BRepBuilderAPI_MakeFace aMakeFace( TopoDS::Wire(aWiresList.First()), Standard_True );
149       aMakeFace.Build();
150       if( aMakeFace.IsDone() ) {
151         aRefFace = aMakeFace.Face();
152       }
153       if(aRefFace.IsNull())
154         return aResultFace;
155
156       aFR.Init(aRefFace,Standard_False, Standard_True);
157       TopTools_ListIteratorOfListOfShape anIt( aWiresList );
158       for ( ; anIt.More(); anIt.Next() ) {
159         TopoDS_Wire& aWire = TopoDS::Wire( anIt.Value() );
160         if ( aWire.IsNull() ) 
161             continue;
162         aFR.Add(aWire);
163       }
164       aFR.Perform();
165       if (aFR.IsDone()) {
166         for (; aFR.More(); aFR.Next()) {
167           aResultFace = aFR.Current();
168           break;
169         }
170       }
171     }
172   }
173
174   if( aResultFace.IsNull() )
175     return aResultFace;
176
177   BRepCheck_Analyzer anAnalyzer( aResultFace );
178   if( anAnalyzer.IsValid() && aResultFace.ShapeType()==TopAbs_FACE )
179     return aResultFace;
180   else
181     return TopoDS_Face();
182 }
183
184 void HYDROData_ImmersibleZone::createGroupObjects()
185 {
186   TopoDS_Shape aZoneShape = GetTopShape();
187   
188   // Temporary solution while the restriction for polylines is not implemented
189   // and shape for zone can be compound and not face only
190   if ( !aZoneShape.IsNull() && aZoneShape.ShapeType() != TopAbs_FACE )
191   {
192     TopExp_Explorer aZoneFaceExp( aZoneShape, TopAbs_FACE );
193     if ( aZoneFaceExp.More() )
194       aZoneShape = aZoneFaceExp.Current(); // Take only first face into account
195   }
196
197   if ( aZoneShape.IsNull() || aZoneShape.ShapeType() != TopAbs_FACE )
198     return;
199
200   TopoDS_Face aZoneFace = TopoDS::Face( aZoneShape );
201   
202   TopoDS_Wire aZoneOuterWire = ShapeAnalysis::OuterWire( aZoneFace );
203
204   // Create outer edges group
205   QString anOutWiresGroupName = GetName() + "_Outer";
206
207   Handle(HYDROData_ShapesGroup) anOutWiresGroup = createGroupObject();
208   anOutWiresGroup->SetName( anOutWiresGroupName );
209
210   TopTools_SequenceOfShape anOuterEdges;
211   HYDROData_ShapesTool::ExploreShapeToShapes( aZoneOuterWire, TopAbs_EDGE, anOuterEdges );
212   anOutWiresGroup->SetShapes( anOuterEdges );
213
214   int anInnerCounter = 1;
215   TopExp_Explorer aZoneFaceExp( aZoneFace, TopAbs_WIRE );
216   for ( ; aZoneFaceExp.More(); aZoneFaceExp.Next() )
217   {
218     TopoDS_Wire aZoneWire = TopoDS::Wire( aZoneFaceExp.Current() );
219     if ( aZoneWire.IsEqual( aZoneOuterWire ) )
220       continue; // Skip the outer wire
221
222     TopTools_SequenceOfShape anInnerEdges;
223     HYDROData_ShapesTool::ExploreShapeToShapes( aZoneWire, TopAbs_EDGE, anInnerEdges );
224     if ( anInnerEdges.IsEmpty() )
225       continue;
226
227     QString anInWiresGroupName = GetName() + "_Inner_" + QString::number( anInnerCounter++ );
228
229     Handle(HYDROData_ShapesGroup) anInWiresGroup = createGroupObject();
230     anInWiresGroup->SetName( anInWiresGroupName );
231
232     anInWiresGroup->SetShapes( anInnerEdges );
233   }  
234 }
235
236 TopoDS_Shape HYDROData_ImmersibleZone::GetShape3D() const
237 {
238   return getTopShape();
239 }
240
241 QColor HYDROData_ImmersibleZone::DefaultFillingColor()
242 {
243   return QColor( Qt::darkBlue );
244 }
245
246 QColor HYDROData_ImmersibleZone::DefaultBorderColor()
247 {
248   return QColor( Qt::transparent );
249 }
250
251 QColor HYDROData_ImmersibleZone::getDefaultFillingColor() const
252 {
253   return DefaultFillingColor();
254 }
255
256 QColor HYDROData_ImmersibleZone::getDefaultBorderColor() const
257 {
258   return DefaultBorderColor();
259 }
260
261 void HYDROData_ImmersibleZone::SetPolyline( const Handle(HYDROData_PolylineXY)& thePolyline )
262 {
263   SetReferenceObject( thePolyline, DataTag_Polyline );
264   SetToUpdate( true );
265 }
266
267 Handle(HYDROData_PolylineXY) HYDROData_ImmersibleZone::GetPolyline() const
268 {
269   return Handle(HYDROData_PolylineXY)::DownCast( 
270            GetReferenceObject( DataTag_Polyline ) );
271 }
272
273 void HYDROData_ImmersibleZone::RemovePolyline()
274 {
275   ClearReferenceObjects( DataTag_Polyline );
276   SetToUpdate( true );
277 }
278
279