]> SALOME platform Git repositories - modules/hydro.git/blob - src/HYDROData/HYDROData_ImmersibleZone.cxx
Salome HOME
first part of the porting on OCCT 7.0
[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 #include <TopTools_HSequenceOfShape.hxx>
36
37 #include <BRep_Builder.hxx>
38 #include <BRepAlgo_FaceRestrictor.hxx>
39 #include <BRepCheck_Analyzer.hxx>
40
41 #include <ShapeAnalysis.hxx>
42 #include <ShapeAnalysis_FreeBounds.hxx>
43
44 #include <QColor>
45 #include <QStringList>
46
47 #define DEB_IMZ
48 #include <BRepTools.hxx>
49 #define _DEVDEBUG_
50 #include "HYDRO_trace.hxx"
51
52 //#define HYDRODATA_IMZONE_DEB 1
53
54 IMPLEMENT_STANDARD_RTTIEXT(HYDROData_ImmersibleZone,HYDROData_NaturalObject)
55
56
57 HYDROData_ImmersibleZone::HYDROData_ImmersibleZone()
58 : HYDROData_NaturalObject( Geom_2d )
59 {
60 }
61
62 HYDROData_ImmersibleZone::~HYDROData_ImmersibleZone()
63 {
64 }
65
66 QStringList HYDROData_ImmersibleZone::DumpToPython( const QString& thePyScriptPath,
67                                                     MapOfTreatedObjects& theTreatedObjects ) const
68 {
69   QStringList aResList = dumpObjectCreation( theTreatedObjects );
70   
71   QString aZoneName = GetObjPyName();
72
73   Handle(HYDROData_IAltitudeObject) aRefAltitude = GetAltitudeObject();
74   setPythonReferenceObject( thePyScriptPath, theTreatedObjects, aResList, aRefAltitude, "SetAltitudeObject" );
75
76   Handle(HYDROData_PolylineXY) aRefPolyline = GetPolyline();
77   setPythonReferenceObject( thePyScriptPath, theTreatedObjects, aResList, aRefPolyline, "SetPolyline" );
78
79   if (!this->IsSubmersible())
80     {
81       aResList << QString( "%1.SetIsSubmersible(False)" ).arg( aZoneName );
82     }
83
84   aResList << QString( "" );
85
86   aResList << QString( "%1.Update()" ).arg( aZoneName );
87   aResList << QString( "" );
88
89   return aResList;
90 }
91
92 HYDROData_SequenceOfObjects HYDROData_ImmersibleZone::GetAllReferenceObjects() const
93 {
94   HYDROData_SequenceOfObjects aResSeq = HYDROData_NaturalObject::GetAllReferenceObjects();
95
96   Handle(HYDROData_PolylineXY) aRefPolyline = GetPolyline();
97   if ( !aRefPolyline.IsNull() )
98     aResSeq.Append( aRefPolyline );
99
100   return aResSeq;
101 }
102
103 void HYDROData_ImmersibleZone::Update()
104 {
105   HYDROData_NaturalObject::Update();
106   
107   TopoDS_Shape aResShape = generateTopShape();
108   SetTopShape( aResShape );
109
110   createGroupObjects();
111 }
112
113 bool HYDROData_ImmersibleZone::IsHas2dPrs() const
114 {
115   return true;
116 }
117
118 TopoDS_Shape HYDROData_ImmersibleZone::generateTopShape() const
119 {
120   return generateTopShape( GetPolyline() );
121 }
122
123 TopoDS_Shape HYDROData_ImmersibleZone::generateTopShape( const Handle(HYDROData_PolylineXY)& aPolyline )
124 {
125   DEBTRACE("generateTopShape");
126   TopoDS_Face aResultFace = TopoDS_Face(); // --- result: default = null face
127
128   if (!aPolyline.IsNull())
129     {
130       TopoDS_Shape aPolylineShape = aPolyline->GetShape();
131 #ifdef DEB_IMZ
132       std::string brepName = "imz.brep";
133       BRepTools::Write(aPolylineShape, brepName.c_str());
134 #endif
135       TopTools_ListOfShape aWiresList;
136
137       if (!aPolylineShape.IsNull() && aPolylineShape.ShapeType() == TopAbs_WIRE)
138         {
139           // --- only one wire: try to make a face
140           DEBTRACE("one wire: try to build a face");
141           const TopoDS_Wire& aPolylineWire = TopoDS::Wire(aPolylineShape);
142           if (!aPolylineWire.IsNull())
143             {
144               BRepBuilderAPI_MakeFace aMakeFace(aPolylineWire, Standard_True);
145               aMakeFace.Build();
146               if (aMakeFace.IsDone())
147                 {
148                   DEBTRACE(" a face with the only wire given");
149                   aResultFace = aMakeFace.Face();
150                 }
151             }
152         }
153       else
154         {
155           // --- a list of wires ? inventory of wires and edges
156           Handle(TopTools_HSequenceOfShape) aSeqWires = new TopTools_HSequenceOfShape;
157           Handle(TopTools_HSequenceOfShape) aSeqEdges = new TopTools_HSequenceOfShape;
158           TopExp_Explorer anExp(aPolylineShape, TopAbs_WIRE);
159           DEBTRACE("list of wires ?");
160           for (; anExp.More(); anExp.Next())
161             {
162               if (!anExp.Current().IsNull())
163                 {
164                   const TopoDS_Wire& aWire = TopoDS::Wire(anExp.Current());
165                   aWiresList.Append(aWire);
166                   DEBTRACE("  append wire");
167                   TopExp_Explorer it2(aWire, TopAbs_EDGE);
168                   for (; it2.More(); it2.Next())
169                     aSeqEdges->Append(it2.Current());
170                 }
171             }
172           if (aWiresList.IsEmpty())
173             return aResultFace; // --- no wires: null result
174
175           if (aSeqEdges->Length() > 1)
176             {
177               DEBTRACE("try to connect all the edges together, build a unique wire and a face");
178               // --- try to create one wire by connecting edges with a distance tolerance (no necessity of sharing points)
179               ShapeAnalysis_FreeBounds::ConnectEdgesToWires(aSeqEdges, 1E-5, Standard_False, aSeqWires);
180
181               if (aSeqWires->Length() == 1)
182                 {
183                   // --- one wire: try to make a face
184                   const TopoDS_Wire& aPolylineWire = TopoDS::Wire(aSeqWires->Value(1));
185                   if (!aPolylineWire.IsNull())
186                     {
187                       BRepBuilderAPI_MakeFace aMakeFace(aPolylineWire, Standard_True);
188                       aMakeFace.Build();
189                       if (aMakeFace.IsDone())
190                         {
191                           DEBTRACE("  a face from all the wires connected");
192                           aResultFace = aMakeFace.Face();
193                         }
194                     }
195                 }
196             }
197
198           if (aResultFace.IsNull())
199             {
200             DEBTRACE("try to make a face with the first wire of the list and other wires as restrictions");
201               // --- try to make a face with the first wire of the list and other wires as restrictions
202               BRepAlgo_FaceRestrictor aFR;
203               TopoDS_Face aRefFace;
204               TopoDS_Shape aS = aWiresList.First();
205               BRepBuilderAPI_MakeFace aMakeFace(TopoDS::Wire(aWiresList.First()), Standard_True);
206               aMakeFace.Build();
207               if (aMakeFace.IsDone())
208                 {
209                   DEBTRACE("  a face with first wire");
210                   aRefFace = aMakeFace.Face();
211                 }
212               if (!aRefFace.IsNull())
213                 {
214                   aFR.Init(aRefFace, Standard_False, Standard_True);
215                   TopTools_ListIteratorOfListOfShape anIt(aWiresList);
216                   for (; anIt.More(); anIt.Next())
217                     {
218                       TopoDS_Wire& aWire = TopoDS::Wire(anIt.Value());
219                       if (aWire.IsNull())
220                         continue;
221                       aFR.Add(aWire);
222                     }
223                   aFR.Perform();
224                   if (aFR.IsDone())
225                     {
226                       for (; aFR.More(); aFR.Next())
227                         {
228                           DEBTRACE("  a restricted face");
229                           aResultFace = aFR.Current();
230                           break;
231                         }
232                     }
233                 }
234             }
235         }
236     }
237
238   if (aResultFace.IsNull())
239     return aResultFace;
240
241   DEBTRACE("check the face");
242   BRepCheck_Analyzer anAnalyzer(aResultFace);
243   if (anAnalyzer.IsValid() && aResultFace.ShapeType() == TopAbs_FACE)
244     {
245       DEBTRACE("face OK");
246       return aResultFace;
247     }
248   else
249     DEBTRACE("bad face");
250   return TopoDS_Face();
251 }
252
253 void HYDROData_ImmersibleZone::createGroupObjects()
254 {
255   TopoDS_Shape aZoneShape = GetTopShape();
256   
257   // Temporary solution while the restriction for polylines is not implemented
258   // and shape for zone can be compound and not face only
259   if ( !aZoneShape.IsNull() && aZoneShape.ShapeType() != TopAbs_FACE )
260   {
261     TopExp_Explorer aZoneFaceExp( aZoneShape, TopAbs_FACE );
262     if ( aZoneFaceExp.More() )
263       aZoneShape = aZoneFaceExp.Current(); // Take only first face into account
264   }
265
266   if ( aZoneShape.IsNull() || aZoneShape.ShapeType() != TopAbs_FACE )
267     return;
268
269   TopoDS_Face aZoneFace = TopoDS::Face( aZoneShape );
270   
271   TopoDS_Wire aZoneOuterWire = ShapeAnalysis::OuterWire( aZoneFace );
272
273   // Create outer edges group
274   QString anOutWiresGroupName = GetName() + "_Outer";
275
276   Handle(HYDROData_ShapesGroup) anOutWiresGroup = createGroupObject();
277   anOutWiresGroup->SetName( anOutWiresGroupName );
278
279   TopTools_SequenceOfShape anOuterEdges;
280   HYDROData_ShapesTool::ExploreShapeToShapes( aZoneOuterWire, TopAbs_EDGE, anOuterEdges );
281   anOutWiresGroup->SetShapes( anOuterEdges );
282
283   int anInnerCounter = 1;
284   TopExp_Explorer aZoneFaceExp( aZoneFace, TopAbs_WIRE );
285   for ( ; aZoneFaceExp.More(); aZoneFaceExp.Next() )
286   {
287     TopoDS_Wire aZoneWire = TopoDS::Wire( aZoneFaceExp.Current() );
288     if ( aZoneWire.IsEqual( aZoneOuterWire ) )
289       continue; // Skip the outer wire
290
291     TopTools_SequenceOfShape anInnerEdges;
292     HYDROData_ShapesTool::ExploreShapeToShapes( aZoneWire, TopAbs_EDGE, anInnerEdges );
293     if ( anInnerEdges.IsEmpty() )
294       continue;
295
296     QString anInWiresGroupName = GetName() + "_Inner_" + QString::number( anInnerCounter++ );
297
298     Handle(HYDROData_ShapesGroup) anInWiresGroup = createGroupObject();
299     anInWiresGroup->SetName( anInWiresGroupName );
300
301     anInWiresGroup->SetShapes( anInnerEdges );
302   }  
303 }
304
305 TopoDS_Shape HYDROData_ImmersibleZone::GetShape3D() const
306 {
307   return GetTopShape();
308 }
309
310 QColor HYDROData_ImmersibleZone::DefaultFillingColor() const
311 {
312   return QColor( Qt::darkBlue );
313 }
314
315 QColor HYDROData_ImmersibleZone::DefaultBorderColor() const
316 {
317   return QColor( Qt::transparent );
318 }
319
320 void HYDROData_ImmersibleZone::SetPolyline( const Handle(HYDROData_PolylineXY)& thePolyline )
321 {
322   if( IsEqual( GetPolyline(), thePolyline ) )
323     return;
324
325   SetReferenceObject( thePolyline, DataTag_Polyline );
326   Changed( Geom_2d );
327 }
328
329 Handle(HYDROData_PolylineXY) HYDROData_ImmersibleZone::GetPolyline() const
330 {
331   return Handle(HYDROData_PolylineXY)::DownCast( 
332            GetReferenceObject( DataTag_Polyline ) );
333 }
334
335 void HYDROData_ImmersibleZone::RemovePolyline()
336 {
337   ClearReferenceObjects( DataTag_Polyline );
338   Changed( Geom_2d );
339 }