Salome HOME
Merge branch 'master' of https://git.salome-platform.org/gitpub/modules/hydro
[modules/hydro.git] / src / HYDROData / HYDROData_ShapeFile.cxx
index 5f48cb2adfbb4e921ddbf7ed649143c0ebf715e5..93a75c2a4c212add5c924eefde6668f961afcd02 100644 (file)
@@ -59,6 +59,8 @@
 #include <TopLoc_Location.hxx>
 #include <Geom_Plane.hxx>
 #include <NCollection_Array1.hxx>
+#include <BRepBndLib.hxx>
+#include <Bnd_Box.hxx>
 
 #ifdef WIN32
   #pragma warning( disable: 4996 )
@@ -113,7 +115,7 @@ void HYDROData_ShapeFile::Export(const QString& aFileName, const Handle_HYDRODat
   if (bCheckLinear && !aLCM->CheckLinear())
     return;
   //
-  SHPHandle hSHPHandle;
+  SHPHandle hSHPHandle = NULL;
   if ( !aLCM.IsNull() && !aLCM->IsEmpty())
   {
     hSHPHandle = SHPCreate( aFileName.toAscii().data(), SHPT_POLYGON );
@@ -125,7 +127,7 @@ void HYDROData_ShapeFile::Export(const QString& aFileName, const Handle_HYDRODat
         aNonExpList.append(aLCM->GetName() + "_" +  QString::number(It.Index()));
     }
   }
-  if (hSHPHandle->nRecords > 0)
+  if (hSHPHandle && hSHPHandle->nRecords > 0)
     SHPClose( hSHPHandle );
   else
   {
@@ -376,7 +378,7 @@ void HYDROData_ShapeFile::ReadSHPPolygon(SHPObject* anObj, int i, TopoDS_Face& F
   BRep_Builder BB;
   BB.MakeFace(F);
 
-  NCollection_Sequence<NCollection_Sequence<TopoDS_Edge> > allEdges;
+  NCollection_Sequence<TopoDS_Wire> allWires;
 
   TopTools_SequenceOfShape aWires;
   for ( int i = 0 ; i < nParts ; i++ )
@@ -389,7 +391,8 @@ void HYDROData_ShapeFile::ReadSHPPolygon(SHPObject* anObj, int i, TopoDS_Face& F
     else
       EndIndex = anObj->nVertices;
 
-    NCollection_Sequence<TopoDS_Edge> EPerW;
+    TopoDS_Wire W;
+    BB.MakeWire(W);
 
     //First point is same as the last point 
     int NbPnts = EndIndex - StartIndex - 1;
@@ -417,30 +420,64 @@ void HYDROData_ShapeFile::ReadSHPPolygon(SHPObject* anObj, int i, TopoDS_Face& F
         E = BRepLib_MakeEdge(aTC, VPoints.First(), VPoints.Value(VPoints.Upper() - 1)).Edge();
       //Add edge to wire
       //If SHP file is correct then the outer wire and the holes will have the correct orientations
-      
-      EPerW.Append(E);
+      W.Closed (Standard_True);
+      W.Orientation(TopAbs_FORWARD);
+      BB.Add(W, E);
     }
-    allEdges.Append(EPerW);
+    allWires.Append(W);
   }
 
-  for (int i = 1; i <= allEdges.Size(); i++)
+  int OutWIndex = -1;
+  if (allWires.Size() > 1)
+  {
+    NCollection_Sequence<Bnd_Box> BBs;
+    //try to find the largest bbox
+    for (int i = 1; i <= allWires.Size(); i++)
+    {
+      TopoDS_Wire W = allWires(i);
+      Bnd_Box BB;
+      BRepBndLib::AddClose(W, BB);
+      BBs.Append(BB);
+    }
+    for (int i = 1; i <= BBs.Size(); i++)
+    {
+      bool IsIn = false;
+      for (int j = 1; j <= BBs.Size(); j++)
+      {
+        if (i == j)
+          continue;
+        Standard_Real iXmax, iXmin, iYmax, iYmin, z0, z1;
+        Standard_Real jXmax, jXmin, jYmax, jYmin;
+        BBs(i).Get(iXmin, iYmin, z0, iXmax, iYmax, z1);
+        BBs(j).Get(jXmin, jYmin, z0, jXmax, jYmax, z1);
+        if (!(iXmin > jXmin && 
+            iYmin > jYmin &&
+            iXmax < jXmax &&
+            iYmax < jYmax))
+          IsIn = true;
+      }
+      if (IsIn)
+      {
+        OutWIndex = i;
+        break;
+      }
+    }
+  }
+  else
+    OutWIndex = 1; //one wire => no need to check
+
+  for (int i = 1; i <= allWires.Size(); i++)
   {
-    TopoDS_Wire W;
-    BB.MakeWire(W);
-    for (int j = 1; j <= allEdges(i).Size(); j++)
-      BB.Add(W, allEdges(i)(j));
-    W.Closed (Standard_True);
-    W.Orientation(TopAbs_FORWARD);
-    //check on the dummy face first
     TopoDS_Face DF;
     BB.MakeFace(DF);
+    TopoDS_Wire W = allWires(i);
     BB.Add(DF, W);
     BB.UpdateFace(DF, aPlaneSur, TopLoc_Location(), Precision::Confusion());
     //
     BRepTopAdaptor_FClass2d FClass(DF, Precision::PConfusion());
-    if ( i == 1 && FClass.PerformInfinitePoint() != TopAbs_OUT
+    if ( i == OutWIndex && FClass.PerformInfinitePoint() == TopAbs_IN
       W.Reverse();
-    if ( i > 1 && FClass.PerformInfinitePoint() != TopAbs_IN
+    if ( i != OutWIndex && FClass.PerformInfinitePoint() == TopAbs_OUT
       W.Reverse();
     //
     BB.Add(F, W);