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.
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.
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
16 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 #include "HYDROData_ImmersibleZone.h"
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"
27 #include <BRepBuilderAPI_MakeFace.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>
37 #include <BRep_Builder.hxx>
38 #include <BRepAlgo_FaceRestrictor.hxx>
39 #include <BRepCheck_Analyzer.hxx>
41 #include <ShapeAnalysis.hxx>
42 #include <ShapeAnalysis_FreeBounds.hxx>
45 #include <QStringList>
48 #include <BRepTools.hxx>
50 #include "HYDRO_trace.hxx"
52 //#define HYDRODATA_IMZONE_DEB 1
54 IMPLEMENT_STANDARD_HANDLE(HYDROData_ImmersibleZone,HYDROData_NaturalObject)
55 IMPLEMENT_STANDARD_RTTIEXT(HYDROData_ImmersibleZone,HYDROData_NaturalObject)
58 HYDROData_ImmersibleZone::HYDROData_ImmersibleZone()
59 : HYDROData_NaturalObject( Geom_2d )
63 HYDROData_ImmersibleZone::~HYDROData_ImmersibleZone()
67 QStringList HYDROData_ImmersibleZone::DumpToPython( const QString& thePyScriptPath,
68 MapOfTreatedObjects& theTreatedObjects ) const
70 QStringList aResList = dumpObjectCreation( theTreatedObjects );
72 QString aZoneName = GetObjPyName();
74 Handle(HYDROData_IAltitudeObject) aRefAltitude = GetAltitudeObject();
75 setPythonReferenceObject( thePyScriptPath, theTreatedObjects, aResList, aRefAltitude, "SetAltitudeObject" );
77 Handle(HYDROData_PolylineXY) aRefPolyline = GetPolyline();
78 setPythonReferenceObject( thePyScriptPath, theTreatedObjects, aResList, aRefPolyline, "SetPolyline" );
80 if (!this->IsSubmersible())
82 aResList << QString( "%1.SetIsSubmersible(False)" ).arg( aZoneName );
85 aResList << QString( "" );
87 aResList << QString( "%1.Update()" ).arg( aZoneName );
88 aResList << QString( "" );
93 HYDROData_SequenceOfObjects HYDROData_ImmersibleZone::GetAllReferenceObjects() const
95 HYDROData_SequenceOfObjects aResSeq = HYDROData_NaturalObject::GetAllReferenceObjects();
97 Handle(HYDROData_PolylineXY) aRefPolyline = GetPolyline();
98 if ( !aRefPolyline.IsNull() )
99 aResSeq.Append( aRefPolyline );
104 void HYDROData_ImmersibleZone::Update()
106 HYDROData_NaturalObject::Update();
108 RemoveGroupObjects();
109 TopoDS_Shape aResShape = generateTopShape();
110 SetTopShape( aResShape );
112 createGroupObjects();
115 bool HYDROData_ImmersibleZone::IsHas2dPrs() const
120 TopoDS_Shape HYDROData_ImmersibleZone::generateTopShape() const
122 return generateTopShape( GetPolyline() );
125 TopoDS_Shape HYDROData_ImmersibleZone::generateTopShape( const Handle(HYDROData_PolylineXY)& aPolyline )
127 //DEBTRACE("generateTopShape");
128 TopoDS_Face aResultFace = TopoDS_Face(); // --- result: default = null face
130 if (!aPolyline.IsNull())
132 TopoDS_Shape aPolylineShape = aPolyline->GetShape();
134 std::string brepName = "imz.brep";
135 BRepTools::Write(aPolylineShape, brepName.c_str());
137 TopTools_ListOfShape aWiresList;
139 if (!aPolylineShape.IsNull() && aPolylineShape.ShapeType() == TopAbs_WIRE)
141 // --- only one wire: try to make a face
142 //DEBTRACE("one wire: try to build a face");
143 const TopoDS_Wire& aPolylineWire = TopoDS::Wire(aPolylineShape);
144 if (!aPolylineWire.IsNull())
146 BRepBuilderAPI_MakeFace aMakeFace(aPolylineWire, Standard_True);
148 if (aMakeFace.IsDone())
150 //DEBTRACE(" a face with the only wire given");
151 aResultFace = aMakeFace.Face();
157 // --- a list of wires ? inventory of wires and edges
158 Handle(TopTools_HSequenceOfShape) aSeqWires = new TopTools_HSequenceOfShape;
159 Handle(TopTools_HSequenceOfShape) aSeqEdges = new TopTools_HSequenceOfShape;
160 TopExp_Explorer anExp(aPolylineShape, TopAbs_WIRE);
161 //DEBTRACE("list of wires ?");
162 for (; anExp.More(); anExp.Next())
164 if (!anExp.Current().IsNull())
166 const TopoDS_Wire& aWire = TopoDS::Wire(anExp.Current());
167 aWiresList.Append(aWire);
168 //DEBTRACE(" append wire");
169 TopExp_Explorer it2(aWire, TopAbs_EDGE);
170 for (; it2.More(); it2.Next())
171 aSeqEdges->Append(it2.Current());
174 if (aWiresList.IsEmpty())
175 return aResultFace; // --- no wires: null result
177 if (aSeqEdges->Length() > 1)
179 //DEBTRACE("try to connect all the edges together, build a unique wire and a face");
180 // --- try to create one wire by connecting edges with a distance tolerance (no necessity of sharing points)
181 ShapeAnalysis_FreeBounds::ConnectEdgesToWires(aSeqEdges, 1E-5, Standard_False, aSeqWires);
183 if (aSeqWires->Length() == 1)
185 // --- one wire: try to make a face
186 const TopoDS_Wire& aPolylineWire = TopoDS::Wire(aSeqWires->Value(1));
187 if (!aPolylineWire.IsNull())
189 BRepBuilderAPI_MakeFace aMakeFace(aPolylineWire, Standard_True);
191 if (aMakeFace.IsDone())
193 //DEBTRACE(" a face from all the wires connected");
194 aResultFace = aMakeFace.Face();
200 if (aResultFace.IsNull())
202 //DEBTRACE("try to make a face with the first wire of the list and other wires as restrictions");
203 // --- try to make a face with the first wire of the list and other wires as restrictions
204 BRepAlgo_FaceRestrictor aFR;
205 TopoDS_Face aRefFace;
206 TopoDS_Shape aS = aWiresList.First();
207 BRepBuilderAPI_MakeFace aMakeFace(TopoDS::Wire(aWiresList.First()), Standard_True);
209 if (aMakeFace.IsDone())
211 //DEBTRACE(" a face with first wire");
212 aRefFace = aMakeFace.Face();
214 if (!aRefFace.IsNull())
216 aFR.Init(aRefFace, Standard_False, Standard_True);
217 TopTools_ListIteratorOfListOfShape anIt(aWiresList);
218 for (; anIt.More(); anIt.Next())
220 TopoDS_Wire& aWire = TopoDS::Wire(anIt.Value());
228 for (; aFR.More(); aFR.Next())
230 //DEBTRACE(" a restricted face");
231 aResultFace = aFR.Current();
240 if (aResultFace.IsNull())
243 //DEBTRACE("check the face");
244 BRepCheck_Analyzer anAnalyzer(aResultFace);
245 if (anAnalyzer.IsValid() && aResultFace.ShapeType() == TopAbs_FACE)
247 //DEBTRACE("face OK");
252 //DEBTRACE("bad face");
254 return TopoDS_Face();
257 void HYDROData_ImmersibleZone::createGroupObjects()
259 TopoDS_Shape aZoneShape = GetTopShape();
261 // Temporary solution while the restriction for polylines is not implemented
262 // and shape for zone can be compound and not face only
263 if ( !aZoneShape.IsNull() && aZoneShape.ShapeType() != TopAbs_FACE )
265 TopExp_Explorer aZoneFaceExp( aZoneShape, TopAbs_FACE );
266 if ( aZoneFaceExp.More() )
267 aZoneShape = aZoneFaceExp.Current(); // Take only first face into account
270 if ( aZoneShape.IsNull() || aZoneShape.ShapeType() != TopAbs_FACE )
273 TopoDS_Face aZoneFace = TopoDS::Face( aZoneShape );
275 TopoDS_Wire aZoneOuterWire = ShapeAnalysis::OuterWire( aZoneFace );
277 // Create outer edges group
278 QString anOutWiresGroupName = GetName() + "_Outer";
280 Handle(HYDROData_ShapesGroup) anOutWiresGroup = createGroupObject();
281 anOutWiresGroup->SetName( anOutWiresGroupName );
283 TopTools_SequenceOfShape anOuterEdges;
284 HYDROData_ShapesTool::ExploreShapeToShapes( aZoneOuterWire, TopAbs_EDGE, anOuterEdges );
285 anOutWiresGroup->SetShapes( anOuterEdges );
287 int anInnerCounter = 1;
288 TopExp_Explorer aZoneFaceExp( aZoneFace, TopAbs_WIRE );
289 for ( ; aZoneFaceExp.More(); aZoneFaceExp.Next() )
291 TopoDS_Wire aZoneWire = TopoDS::Wire( aZoneFaceExp.Current() );
292 if ( aZoneWire.IsEqual( aZoneOuterWire ) )
293 continue; // Skip the outer wire
295 TopTools_SequenceOfShape anInnerEdges;
296 HYDROData_ShapesTool::ExploreShapeToShapes( aZoneWire, TopAbs_EDGE, anInnerEdges );
297 if ( anInnerEdges.IsEmpty() )
300 QString anInWiresGroupName = GetName() + "_Inner_" + QString::number( anInnerCounter++ );
302 Handle(HYDROData_ShapesGroup) anInWiresGroup = createGroupObject();
303 anInWiresGroup->SetName( anInWiresGroupName );
305 anInWiresGroup->SetShapes( anInnerEdges );
309 TopoDS_Shape HYDROData_ImmersibleZone::GetShape3D() const
311 return GetTopShape();
314 QColor HYDROData_ImmersibleZone::DefaultFillingColor() const
316 return QColor( Qt::darkBlue );
319 QColor HYDROData_ImmersibleZone::DefaultBorderColor() const
321 return QColor( Qt::transparent );
324 void HYDROData_ImmersibleZone::SetPolyline( const Handle(HYDROData_PolylineXY)& thePolyline )
326 if( IsEqual( GetPolyline(), thePolyline ) )
329 SetReferenceObject( thePolyline, DataTag_Polyline );
333 Handle(HYDROData_PolylineXY) HYDROData_ImmersibleZone::GetPolyline() const
335 return Handle(HYDROData_PolylineXY)::DownCast(
336 GetReferenceObject( DataTag_Polyline ) );
339 void HYDROData_ImmersibleZone::RemovePolyline()
341 ClearReferenceObjects( DataTag_Polyline );