Salome HOME
Merge branch 'master' of https://git.salome-platform.org/gitpub/modules/hydro
[modules/hydro.git] / src / HYDROData / HYDROData_ShapeFile.cxx
index 42936173613dedc144156dc450b255dd39fbd97a..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,6 +378,8 @@ void HYDROData_ShapeFile::ReadSHPPolygon(SHPObject* anObj, int i, TopoDS_Face& F
   BRep_Builder BB;
   BB.MakeFace(F);
 
+  NCollection_Sequence<TopoDS_Wire> allWires;
+
   TopTools_SequenceOfShape aWires;
   for ( int i = 0 ; i < nParts ; i++ )
   { 
@@ -386,7 +390,7 @@ void HYDROData_ShapeFile::ReadSHPPolygon(SHPObject* anObj, int i, TopoDS_Face& F
       EndIndex = anObj->panPartStart[i + 1];
     else
       EndIndex = anObj->nVertices;
-    
+
     TopoDS_Wire W;
     BB.MakeWire(W);
 
@@ -416,11 +420,66 @@ 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
+      W.Closed (Standard_True);
+      W.Orientation(TopAbs_FORWARD);
       BB.Add(W, E);
     }
-    //Wire must be closed anyway
-    W.Closed (BRep_Tool::IsClosed (W));
-    W.Orientation(TopAbs_FORWARD);
+    allWires.Append(W);
+  }
+
+  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_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 == OutWIndex && FClass.PerformInfinitePoint() == TopAbs_IN) 
+      W.Reverse();
+    if ( i != OutWIndex && FClass.PerformInfinitePoint() == TopAbs_OUT) 
+      W.Reverse();
+    //
     BB.Add(F, W);
   }
   
@@ -711,6 +770,11 @@ int HYDROData_ShapeFile::TryOpenShapeFile(QString theFileName)
 {
   QString aSHPfile = theFileName.simplified();
   QString aSHXfile = theFileName.simplified().replace( theFileName.simplified().size() - 4, 4, ".shx");
+
+  QString anExt = theFileName.split('.', QString::SkipEmptyParts).back();
+  if (anExt.toLower() != "shp")
+    return -3;
+
   FILE* pFileSHP = NULL;
   pFileSHP = fopen (aSHPfile.toAscii().data(), "r");
   FILE* pFileSHX = NULL;