Salome HOME
Merge remote-tracking branch 'origin/BR_LAND_COVER' into BR_v14_rc
[modules/hydro.git] / src / HYDROData / HYDROData_LandCover.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_LandCover.h"
20
21 #include "HYDROData_PolylineXY.h"
22
23 #include <BRep_Builder.hxx>
24 #include <BRepBuilderAPI_MakeFace.hxx>
25 #include <BRepBuilderAPI_MakeWire.hxx>
26 #include <TDataStd_AsciiString.hxx>
27 #include <TNaming_Builder.hxx>
28 #include <TNaming_NamedShape.hxx>
29 #include <TopoDS.hxx>
30 #include <TopoDS_Shape.hxx>
31 #include <TopoDS_Wire.hxx>
32 #include <TopoDS_Face.hxx>
33 #include <TopExp_Explorer.hxx>
34 #include <TopTools_ListOfShape.hxx>
35 #include <TopTools_ListIteratorOfListOfShape.hxx>
36 #include <NCollection_IncAllocator.hxx>
37 #include <BOPAlgo_BOP.hxx>
38
39 #include <QColor>
40 #include <QStringList>
41
42 IMPLEMENT_STANDARD_HANDLE( HYDROData_LandCover, HYDROData_Entity )
43 IMPLEMENT_STANDARD_RTTIEXT( HYDROData_LandCover, HYDROData_Entity )
44
45 HYDROData_LandCover::HYDROData_LandCover()
46 {
47 }
48
49 HYDROData_LandCover::~HYDROData_LandCover()
50 {
51 }
52
53 const ObjectKind HYDROData_LandCover::GetKind() const
54 {
55   return KIND_LAND_COVER;
56 }
57
58 QStringList HYDROData_LandCover::DumpToPython( MapOfTreatedObjects& theTreatedObjects ) const
59 {
60   QStringList aResList = dumpObjectCreation( theTreatedObjects );
61   QString aName = GetObjPyName();
62   
63   // Set Strickler type
64   QString aType = GetStricklerType();
65   if ( !aType.isEmpty() ) {
66     aResList << QString( "" );
67     ///< \TODO to be implemented:
68     // aResList << QString( "%1.SetStricklerType( \"%2\" );" ).arg( aName ).arg( aType );
69     aResList << QString( "" );
70   }
71
72   // Set polylines
73   ///< \TODO to be implemented: 
74   
75   aResList << QString( "" );
76   aResList << QString( "%1.Update();" ).arg( aName );
77   aResList << QString( "" );
78
79   return aResList;
80 }
81
82 HYDROData_SequenceOfObjects HYDROData_LandCover::GetAllReferenceObjects() const
83 {
84   HYDROData_SequenceOfObjects aResSeq = HYDROData_Entity::GetAllReferenceObjects();
85
86   HYDROData_SequenceOfObjects aSeqOfPolylines = GetPolylines();
87   aResSeq.Append( aSeqOfPolylines );
88
89   return aResSeq;
90 }
91
92 bool HYDROData_LandCover::IsHas2dPrs() const
93 {
94   return true;
95 }
96
97 void HYDROData_LandCover::SetStricklerType( const QString& theType )
98 {
99   TCollection_AsciiString anAsciiStr( theType.toStdString().c_str() );
100   TDataStd_AsciiString::Set( myLab.FindChild( DataTag_StricklerType ), anAsciiStr );
101 }
102
103 QString HYDROData_LandCover::GetStricklerType() const
104 {
105   QString aType;
106
107   TDF_Label aLabel = myLab.FindChild( DataTag_StricklerType, false );
108   if ( !aLabel.IsNull() ) {
109     Handle(TDataStd_AsciiString) anAsciiStr;
110     if ( aLabel.FindAttribute( TDataStd_AsciiString::GetID(), anAsciiStr ) ) {
111       aType = QString( anAsciiStr->Get().ToCString() );
112     }
113   }
114
115   return aType;
116 }
117
118 void HYDROData_LandCover::Update()
119 {
120   HYDROData_Entity::Update();
121   
122   removeShape();
123
124   TCollection_AsciiString anErrorMsg;
125   TopoDS_Shape aResShape = buildShape( GetPolylines(), anErrorMsg );
126   
127   setShape( aResShape );
128 }
129
130 void HYDROData_LandCover::SetPolylines( const HYDROData_SequenceOfObjects& thePolylines )
131 {
132   SetReferenceObjects( thePolylines, DataTag_Polylines );
133   SetToUpdate( true );
134 }
135
136 HYDROData_SequenceOfObjects HYDROData_LandCover::GetPolylines() const
137 {
138   return GetReferenceObjects( DataTag_Polylines );
139 }
140
141 TopoDS_Shape HYDROData_LandCover::GetShape() const
142 {
143   TopoDS_Shape aShape;
144
145   TDF_Label aLabel = myLab.FindChild( DataTag_Shape, false );
146   if ( !aLabel.IsNull() )
147   {
148     Handle(TNaming_NamedShape) aNamedShape;
149     if( aLabel.FindAttribute( TNaming_NamedShape::GetID(), aNamedShape ) ) {
150       aShape = aNamedShape->Get();
151     }
152   }
153
154   return aShape;
155 }
156
157 void HYDROData_LandCover::SetFillingColor( const QColor& theColor )
158 {
159   SetColor( theColor, DataTag_FillingColor );
160 }
161
162 QColor HYDROData_LandCover::GetFillingColor() const
163 {
164   return GetColor( DefaultFillingColor(), DataTag_FillingColor );
165 }
166
167 void HYDROData_LandCover::SetBorderColor( const QColor& theColor )
168 {
169   SetColor( theColor, DataTag_BorderColor );
170 }
171
172 QColor HYDROData_LandCover::GetBorderColor() const
173 {
174   return GetColor( DefaultBorderColor(), DataTag_BorderColor );
175 }
176
177 QColor HYDROData_LandCover::DefaultFillingColor()
178 {
179   return QColor( Qt::magenta );
180 }
181
182 QColor HYDROData_LandCover::DefaultBorderColor()
183 {
184   return QColor( Qt::transparent );
185 }
186
187 void HYDROData_LandCover::setShape( const TopoDS_Shape& theShape )
188 {
189   TNaming_Builder aBuilder( myLab.FindChild( DataTag_Shape ) );
190   aBuilder.Generated( theShape );
191 }
192
193 void HYDROData_LandCover::removeShape()
194 {
195   TDF_Label aLabel = myLab.FindChild( DataTag_Shape, false );
196   if ( !aLabel.IsNull() ) {
197     aLabel.ForgetAllAttributes();
198   }
199 }
200  
201 TopoDS_Shape HYDROData_LandCover::buildShape( const HYDROData_SequenceOfObjects& thePolylines,
202                                               TCollection_AsciiString& theErrorMsg )
203 {
204   theErrorMsg.Clear();
205   TopoDS_Shape aResShape;
206
207   BRepBuilderAPI_MakeWire aMakeWire;
208   
209   TopTools_ListOfShape aClosedWires;
210
211   int aNbPolylines = thePolylines.Length();
212   for ( int i = 1; i <= aNbPolylines; ++i ) {
213     Handle(HYDROData_PolylineXY) aPolyline = 
214       Handle(HYDROData_PolylineXY)::DownCast( thePolylines.Value( i ) );
215     
216     if ( aPolyline.IsNull() ) {
217       continue;
218     }
219
220     TopoDS_Shape aPolyShape = aPolyline->GetShape();
221     if ( aPolyShape.IsNull() ) {
222       continue;
223     }
224
225     // Extract polyline wire(s)
226     TopTools_ListOfShape aPolylineWires;
227       
228     if ( aPolyShape.ShapeType() == TopAbs_WIRE ) {
229       const TopoDS_Wire& aPolylineWire = TopoDS::Wire( aPolyShape );
230       if ( !aPolylineWire.IsNull() ) {
231         aPolylineWires.Append( aPolylineWire );
232       }
233     } else if ( aPolyShape.ShapeType() == TopAbs_COMPOUND ) {
234       TopExp_Explorer anExp( aPolyShape, TopAbs_WIRE );
235       for (; anExp.More(); anExp.Next() ) {
236         if(!anExp.Current().IsNull()) {
237           const TopoDS_Wire& aWire = TopoDS::Wire( anExp.Current() );
238           aPolylineWires.Append( aWire );
239         }
240       }
241     }
242     
243     TopTools_ListIteratorOfListOfShape anIt( aPolylineWires );
244     for ( ; anIt.More(); anIt.Next() ) {
245       TopoDS_Wire& aWire = TopoDS::Wire( anIt.Value() );
246       
247       if ( aWire.Closed() ) {
248         aClosedWires.Append( aWire );
249       } else {
250         aMakeWire.Add( aWire );
251         aMakeWire.Build();
252         if ( aMakeWire.IsDone() ) {
253           if ( aMakeWire.Wire().Closed() ) {
254             aClosedWires.Append( aMakeWire.Wire() );
255             aMakeWire = BRepBuilderAPI_MakeWire();
256           }
257         }
258       }
259     }
260   }
261
262   if ( aClosedWires.Extent() == 1 ) {
263     // make face
264     BRepBuilderAPI_MakeFace aMakeFace( TopoDS::Wire( aClosedWires.First() ) );
265     aMakeFace.Build();
266     if( aMakeFace.IsDone() ) {
267       aResShape = aMakeFace.Face();
268     }
269   } else if ( aClosedWires.Extent() > 1 ) {
270     // make compound
271     BRep_Builder aBuilder;
272     TopoDS_Compound aCompound;
273     aBuilder.MakeCompound( aCompound );
274
275     TopTools_ListIteratorOfListOfShape aWiresIter( aClosedWires );
276     for ( ; aWiresIter.More(); aWiresIter.Next() ) {
277       BRepBuilderAPI_MakeFace aMakeFace( TopoDS::Wire( aWiresIter.Value() ) );
278       aMakeFace.Build();
279       if( aMakeFace.IsDone() ) {
280         aBuilder.Add( aCompound, aMakeFace.Face() );
281       }
282     }
283
284     aResShape = aCompound;
285   } else if ( aNbPolylines > 0 ) {
286     TCollection_AsciiString aSourceName = aNbPolylines > 1 ? "polylines" : "polyline";
287     theErrorMsg = "Can't build closed contour on the given ";
288     theErrorMsg += aSourceName;
289   }
290
291   ///< \TODO to be reimplemented
292   /*
293   TopoDS_Shape anArgShape;
294   TopTools_ListOfShape aToolShapes;
295   
296   HYDROData_SequenceOfObjects aRefPolylines = GetPolylines();
297   for ( int i = 1, n = aRefPolylines.Length(); i <= n; ++i ) {
298     Handle(HYDROData_PolylineXY) aPolyline = 
299       Handle(HYDROData_PolylineXY)::DownCast( aRefPolylines.Value( i ) );
300     
301     if ( aPolyline.IsNull() ) {
302       continue;
303     }
304
305     if ( !aPolyline->IsClosed() ) {
306       continue;
307     }
308
309     TopoDS_Shape aPolyShape = aPolyline->GetShape();
310     if ( aPolyShape.IsNull() || aPolyShape.ShapeType() != TopAbs_WIRE ) {
311       continue;
312     }
313
314     const TopoDS_Wire& aPolylineWire = TopoDS::Wire( aPolyShape );
315     if ( aPolylineWire.IsNull() ) {
316       continue;
317     }
318
319     TopoDS_Face aResultFace = TopoDS_Face();
320     BRepBuilderAPI_MakeFace aMakeFace( aPolylineWire, Standard_True );
321     aMakeFace.Build();
322     if( aMakeFace.IsDone() ) {
323       aResultFace = aMakeFace.Face();
324     }
325
326     if( aResultFace.IsNull() ) {
327       continue;
328     }
329
330     if ( anArgShape.IsNull() ) {
331       anArgShape = aResultFace;
332     } else {
333       aToolShapes.Append( aResultFace );
334     }
335   }
336
337   aResShape = anArgShape;
338
339   if ( !anArgShape.IsNull() && aToolShapes.Extent() > 0 ) {
340     Handle(NCollection_BaseAllocator)aAL=new NCollection_IncAllocator;
341     BOPAlgo_BOP aBOP(aAL);
342  
343     aBOP.AddArgument( anArgShape );
344
345     TopTools_ListIteratorOfListOfShape anIt(aToolShapes);
346     for( ; anIt.More(); anIt.Next() ) {
347       aBOP.AddTool( anIt.Value() );
348     }
349
350     aBOP.SetOperation( BOPAlgo_CUT );
351     aBOP.Perform();
352
353     if ( !aBOP.Shape().IsNull() ) {
354       aResShape = aBOP.Shape();
355     }
356   }
357   */
358   
359   return aResShape;
360 }