Salome HOME
debug of tests for DTM
[modules/hydro.git] / src / HYDROData / HYDROData_LandCover.cxx
index 3680865ca4a39b611265412e37f81b1c11311233..d17b52430ac43d87f6a1f3e5be0e33cbeab25e31 100644 (file)
@@ -20,7 +20,9 @@
 
 #include "HYDROData_PolylineXY.h"
 
+#include <BRep_Builder.hxx>
 #include <BRepBuilderAPI_MakeFace.hxx>
+#include <BRepBuilderAPI_MakeWire.hxx>
 #include <TDataStd_AsciiString.hxx>
 #include <TNaming_Builder.hxx>
 #include <TNaming_NamedShape.hxx>
 #include <TopoDS_Shape.hxx>
 #include <TopoDS_Wire.hxx>
 #include <TopoDS_Face.hxx>
+#include <TopExp_Explorer.hxx>
 #include <TopTools_ListOfShape.hxx>
 #include <TopTools_ListIteratorOfListOfShape.hxx>
 #include <NCollection_IncAllocator.hxx>
 #include <BOPAlgo_BOP.hxx>
+#include <ShapeAnalysis_Wire.hxx>
+#include <Precision.hxx>
+#include <TopTools_SequenceOfShape.hxx>
 
 #include <QColor>
 #include <QStringList>
@@ -40,6 +46,7 @@ IMPLEMENT_STANDARD_HANDLE( HYDROData_LandCover, HYDROData_Entity )
 IMPLEMENT_STANDARD_RTTIEXT( HYDROData_LandCover, HYDROData_Entity )
 
 HYDROData_LandCover::HYDROData_LandCover()
+: HYDROData_Entity( Geom_2d )
 {
 }
 
@@ -118,7 +125,8 @@ void HYDROData_LandCover::Update()
   
   removeShape();
 
-  TopoDS_Shape aResShape = buildShape();
+  TCollection_AsciiString anErrorMsg;
+  TopoDS_Shape aResShape = buildShape( GetPolylines(), anErrorMsg );
   
   setShape( aResShape );
 }
@@ -126,7 +134,7 @@ void HYDROData_LandCover::Update()
 void HYDROData_LandCover::SetPolylines( const HYDROData_SequenceOfObjects& thePolylines )
 {
   SetReferenceObjects( thePolylines, DataTag_Polylines );
-  SetToUpdate( true );
+  Changed( Geom_2d );
 }
 
 HYDROData_SequenceOfObjects HYDROData_LandCover::GetPolylines() const
@@ -193,12 +201,122 @@ void HYDROData_LandCover::removeShape()
     aLabel.ForgetAllAttributes();
   }
 }
-TopoDS_Shape HYDROData_LandCover::buildShape() const
+
+TopoDS_Shape HYDROData_LandCover::buildShape( const HYDROData_SequenceOfObjects& thePolylines,
+                                              TCollection_AsciiString& theErrorMsg )
 {
+  theErrorMsg.Clear();
   TopoDS_Shape aResShape;
 
+  BRepBuilderAPI_MakeWire aMakeWire;
+  
+  TopTools_ListOfShape aClosedWires;
+
+  int aNbPolylines = thePolylines.Length();
+  for ( int i = 1; i <= aNbPolylines; ++i ) {
+    Handle(HYDROData_PolylineXY) aPolyline = 
+      Handle(HYDROData_PolylineXY)::DownCast( thePolylines.Value( i ) );
+    
+    if ( aPolyline.IsNull() ) {
+      continue;
+    }
+
+    TopoDS_Shape aPolyShape = aPolyline->GetShape();
+    if ( aPolyShape.IsNull() ) {
+      continue;
+    }
+
+    // Extract polyline wire(s)
+    TopTools_ListOfShape aPolylineWires;
+      
+    if ( aPolyShape.ShapeType() == TopAbs_WIRE ) {
+      const TopoDS_Wire& aPolylineWire = TopoDS::Wire( aPolyShape );
+      if ( !aPolylineWire.IsNull() ) {
+        aPolylineWires.Append( aPolylineWire );
+      }
+    } else if ( aPolyShape.ShapeType() == TopAbs_COMPOUND ) {
+      TopExp_Explorer anExp( aPolyShape, TopAbs_WIRE );
+      for (; anExp.More(); anExp.Next() ) {
+        if(!anExp.Current().IsNull()) {
+          const TopoDS_Wire& aWire = TopoDS::Wire( anExp.Current() );
+          aPolylineWires.Append( aWire );
+        }
+      }
+    }
+    
+    TopTools_ListIteratorOfListOfShape anIt( aPolylineWires );
+    for ( ; anIt.More(); anIt.Next() ) {
+      TopoDS_Wire& aWire = TopoDS::Wire( anIt.Value() );
+      
+      if ( aWire.Closed() ) {
+        aClosedWires.Append( aWire );
+      } else {
+        aMakeWire.Add( aWire );
+        aMakeWire.Build();
+        if ( aMakeWire.IsDone() ) {
+          if ( aMakeWire.Wire().Closed() ) {
+            aClosedWires.Append( aMakeWire.Wire() );
+            aMakeWire = BRepBuilderAPI_MakeWire();
+          }
+        }
+      }
+    }
+  }
+
+  if ( aClosedWires.Extent() == 1 ) {
+    // make face
+    TopoDS_Wire aW = TopoDS::Wire( aClosedWires.First());
+    BRepBuilderAPI_MakeFace aMakeFace( aW );
+    aMakeFace.Build();
+    if( aMakeFace.IsDone() ) 
+    {
+      Handle(ShapeAnalysis_Wire) aSAW = new ShapeAnalysis_Wire(aW, aMakeFace.Face(), Precision::Confusion());
+      if (!aSAW->CheckSelfIntersection())
+        aResShape = aMakeFace.Face();
+      else
+        theErrorMsg = "Can't create landcover on the given polyline\nSelf-intersection of wire have been detected";
+    }
+  } else if ( aClosedWires.Extent() > 1 ) {
+    // make compound
+    BRep_Builder aBuilder;
+    TopoDS_Compound aCompound;
+    aBuilder.MakeCompound( aCompound );
+    TopTools_SequenceOfShape aSeq;
+    TopTools_ListIteratorOfListOfShape aWiresIter( aClosedWires );
+    bool anErrStat = false;
+    for ( ; aWiresIter.More() && !anErrStat; aWiresIter.Next() )
+    {
+      TopoDS_Wire aW = TopoDS::Wire( aWiresIter.Value() );
+      BRepBuilderAPI_MakeFace aMakeFace( aW );
+      aMakeFace.Build();
+      if( aMakeFace.IsDone() ) 
+      {
+        Handle(ShapeAnalysis_Wire) aSAW = new ShapeAnalysis_Wire(aW, aMakeFace.Face(), Precision::Confusion());
+        if (!aSAW->CheckSelfIntersection())
+          aSeq.Append( aMakeFace.Face() );
+        else
+        {
+          anErrStat = true;
+          theErrorMsg = "Can't create landcover on the given polyline\nSelf-intersection of wire(s) have been detected";
+        }
+      }
+    }
+    if (!anErrStat)
+    {
+      for (int i = 1; i <= aSeq.Length(); i++)
+        aBuilder.Add( aCompound, aSeq(i) );
+      aResShape = aCompound;
+    }
+    else
+      aResShape = TopoDS_Shape();
+  } else if ( aNbPolylines > 0 ) {
+    TCollection_AsciiString aSourceName = aNbPolylines > 1 ? "polylines" : "polyline";
+    theErrorMsg = "Can't build closed contour on the given ";
+    theErrorMsg += aSourceName;
+  }
+
   ///< \TODO to be reimplemented
+  /*
   TopoDS_Shape anArgShape;
   TopTools_ListOfShape aToolShapes;
   
@@ -263,6 +381,7 @@ TopoDS_Shape HYDROData_LandCover::buildShape() const
       aResShape = aBOP.Shape();
     }
   }
+  */
   
   return aResShape;
 }
\ No newline at end of file