Blob Blame History Raw
diff -rupN netgen-5.1/libsrc/meshing/meshtype.cpp netgen-5.1-new/libsrc/meshing/meshtype.cpp
--- netgen-5.1/libsrc/meshing/meshtype.cpp	2013-06-25 13:28:59.000000000 +0200
+++ netgen-5.1-new/libsrc/meshing/meshtype.cpp	2014-06-13 19:54:42.968358572 +0200
@@ -1,4 +1,5 @@
 #include <mystdlib.h>
+#include <float.h> // to get DBL_MIN defined
 
 #include "meshing.hpp"  
 
@@ -666,7 +667,8 @@ namespace netgen
 
         double det = trans.Det();
 
-        if (det <= 0)
+        // if (det <= 0)
+        if (det <= DBL_MIN) // avoid FPE
           err += 1e12;
         else
           err += frob * frob / det;
@@ -722,7 +724,8 @@ namespace netgen
 
             double det = trans(0,0)*trans(1,1)-trans(1,0)*trans(0,1);
 
-            if (det <= 0)
+            // if (det <= 0)
+            if (det <= DBL_MIN)  // avoid FPE
               {
                 dd = 0;
                 return 1e12;
@@ -806,7 +809,8 @@ namespace netgen
           = dtrans(0,0) * trans(1,1) - trans(0,1) * dtrans(1,0)
           + trans(0,0) * dtrans(1,1) - dtrans(0,1) * trans(1,0);
 
-        if (det <= 0)
+        // if (det <= 0)
+        if (det <= DBL_MIN) // avoid FPE
           err += 1e12;
         else
           {
@@ -856,7 +860,8 @@ namespace netgen
         frob /= 2;
 
         double det = trans.Det();
-        if (det <= 0)
+        //if (det <= 0)
+        if (det <= DBL_MIN) // avoid FPE
           err += 1e12;
         else
           err += frob * frob / det;
@@ -1864,7 +1869,8 @@ namespace netgen
       case PYRAMID:
         {
           double noz = 1-p(2);
-          if (noz == 0.0) noz = 1e-10;
+          //if (noz == 0.0) noz = 1e-10;
+          if (noz <= DBL_MIN) noz = 1e-10; // avoid FPE
 
           double xi  = p(0) / noz;
           double eta = p(1) / noz;
@@ -2030,7 +2036,8 @@ namespace netgen
 
         double det = -trans.Det();
       
-        if (det <= 0)
+        //if (det <= 0)
+        if (det <= DBL_MIN) // avoid FPE
           err += 1e12;
         else
           err += frob * frob * frob / det;
@@ -2102,7 +2109,8 @@ namespace netgen
         ddet *= -1;
 
       
-        if (det <= 0)
+        //if (det <= 0)
+        if (det <= DBL_MIN) // avoid FPE
           err += 1e12;
         else
           {
@@ -2184,7 +2192,7 @@ namespace netgen
       
         det *= -1;
       
-        if (det <= 0)
+        if (det <= DBL_MIN)
           err += 1e12;
         else
           {
@@ -2513,10 +2521,10 @@ namespace netgen
 
   MeshingParameters :: MeshingParameters ()
   {
-    optimize3d = "cmdmustm";
+    optimize3d = (char*)"cmdmustm"; // optimize3d = "cmdmustm";
     //optimize3d = "cmdmstm";
     optsteps3d = 3;
-    optimize2d = "smsmsmSmSmSm";
+    optimize2d = (char*)"smsmsmSmSmSm"; // optimize2d = "smsmsmSmSmSm";
     optsteps2d = 3;
     opterrpow = 2;
     blockfill = 1;
diff -rupN netgen-5.1/libsrc/meshing/meshtype.hpp netgen-5.1-new/libsrc/meshing/meshtype.hpp
--- netgen-5.1/libsrc/meshing/meshtype.hpp	2013-06-25 13:28:59.000000000 +0200
+++ netgen-5.1-new/libsrc/meshing/meshtype.hpp	2014-06-13 19:54:42.969358572 +0200
@@ -15,6 +15,7 @@ namespace netgen
     Classes for NETGEN
   */
 
+class Mesh; // added due to compilation errors on some platforms
 
 
   enum ELEMENT_TYPE { 
diff -rupN netgen-5.1/libsrc/meshing/smoothing2.cpp netgen-5.1-new/libsrc/meshing/smoothing2.cpp
--- netgen-5.1/libsrc/meshing/smoothing2.cpp	2013-06-25 13:28:59.000000000 +0200
+++ netgen-5.1-new/libsrc/meshing/smoothing2.cpp	2014-06-13 19:54:42.969358572 +0200
@@ -361,7 +361,8 @@ namespace netgen
     vgrad = 0;
     double badness = 0;
 
-    ld.meshthis -> GetNormalVector (ld.surfi, ld.sp1, ld.gi1, n);
+    //normal already computed: ld.meshthis -> GetNormalVector (ld.surfi, ld.sp1, ld.gi1, n);
+    n = ld.normal;
     pp1 = ld.sp1 + x(0) * ld.t1 + x(1) * ld.t2;
 
     //  meshthis -> ProjectPoint (surfi, pp1);
@@ -577,7 +578,8 @@ namespace netgen
     vgrad = 0;
     badness = 0;
 
-    ld.meshthis -> GetNormalVector (ld.surfi, ld.sp1, ld.gi1, n);
+    //normal already computed: ld.meshthis -> GetNormalVector (ld.surfi, ld.sp1, ld.gi1, n);
+    n = ld.normal;
 
     pp1 = ld.sp1 + x(0) * ld.t1 + x(1) * ld.t2;
 
@@ -649,7 +651,8 @@ namespace netgen
     vgrad = 0;
     badness = 0;
 
-    ld.meshthis -> GetNormalVector (ld.surfi, ld.sp1, ld.gi1, n);
+    //normal already computed: ld.meshthis -> GetNormalVector (ld.surfi, ld.sp1, ld.gi1, n);
+    n = ld.normal;
 
     // pp1 = sp1;
     //    pp1.Add2 (x.Get(1), t1, x.Get(2), t2);
@@ -1079,7 +1082,7 @@ namespace netgen
 		{
 		  mesh[pi] = Point<3> (origp);
 		}
-	    
+	      break; // exit as <fact> is not used anymore
 	    }
 	}
       }
diff -rupN netgen-5.1/libsrc/occ/occconstruction.cpp netgen-5.1-new/libsrc/occ/occconstruction.cpp
--- netgen-5.1/libsrc/occ/occconstruction.cpp	2013-06-25 13:28:59.000000000 +0200
+++ netgen-5.1-new/libsrc/occ/occconstruction.cpp	2014-06-13 19:54:42.970358572 +0200
@@ -28,7 +28,7 @@
 #include <BRepAlgoAPI_Common.hxx>
 #include <BRepAlgoAPI_Fuse.hxx>
 #include <BRepAlgoAPI_Section.hxx>
-#include <BRepOffsetAPI_Sewing.hxx>
+//#include <BRepOffsetAPI_Sewing.hxx>
 //#include <BRepAlgo_Sewing.hxx>
 #include <BRepOffsetAPI_MakeOffsetShape.hxx>
 #include <ShapeFix_Shape.hxx>
diff -rupN netgen-5.1/libsrc/occ/occgenmesh.cpp netgen-5.1-new/libsrc/occ/occgenmesh.cpp
--- netgen-5.1/libsrc/occ/occgenmesh.cpp	2013-06-25 13:28:59.000000000 +0200
+++ netgen-5.1-new/libsrc/occ/occgenmesh.cpp	2014-06-13 19:54:42.971358572 +0200
@@ -57,6 +57,8 @@ namespace netgen
 
 
 
+   
+   static // useless out of this file
    double ComputeH (double kappa)
    {
       double hret;
@@ -74,8 +76,7 @@ namespace netgen
    }
 
 
-
-
+   static // useless out of this file
    void RestrictHTriangle (gp_Pnt2d & par0, gp_Pnt2d & par1, gp_Pnt2d & par2,
                            BRepLProp_SLProps * prop, Mesh & mesh, int depth, double h = 0)
    {
@@ -171,8 +172,8 @@ namespace netgen
          if(h < 1e-4*maxside)
             return;
 
-
-         if (h > 30) return;
+         // commented to restrict H on a large sphere for example
+         //if (h > 30) return;
       }
 
       if (h < maxside && depth < 10)
@@ -231,6 +232,7 @@ namespace netgen
 
 
 
+   static // useless out of this file
    void DivideEdge (TopoDS_Edge & edge, Array<MeshPoint> & ps,
                     Array<double> & params, Mesh & mesh)
    {
@@ -250,8 +252,8 @@ namespace netgen
       hvalue[0] = 0;
       pnt = c->Value(s0);
 
-      double olddist = 0;
-      double dist = 0;
+      //double olddist = 0; -- useless variables
+      //double dist = 0;
 
       int tmpVal = (int)(DIVIDEEDGESECTIONS);
 
@@ -259,15 +261,19 @@ namespace netgen
       {
          oldpnt = pnt;
          pnt = c->Value(s0+(i/double(DIVIDEEDGESECTIONS))*(s1-s0));
+         // -- no more than 1 segment per <edge length>/DIVIDEEDGESECTIONS
          hvalue[i] = hvalue[i-1] +
-            1.0/mesh.GetH(Point3d(pnt.X(), pnt.Y(), pnt.Z()))*
-            pnt.Distance(oldpnt);
+         //   1.0/mesh.GetH(Point3d(pnt.X(), pnt.Y(), pnt.Z()))*
+         //   pnt.Distance(oldpnt);
+           min( 1.0,
+                1.0/mesh.GetH(Point3d(pnt.X(), pnt.Y(), pnt.Z()))*
+                pnt.Distance(oldpnt));
 
          //(*testout) << "mesh.GetH(Point3d(pnt.X(), pnt.Y(), pnt.Z())) " << mesh.GetH(Point3d(pnt.X(), pnt.Y(), pnt.Z()))
          //	   <<  " pnt.Distance(oldpnt) " << pnt.Distance(oldpnt) << endl;
 
-         olddist = dist;
-         dist = pnt.Distance(oldpnt);
+         //olddist = dist; -- useless variables
+         //dist = pnt.Distance(oldpnt);
       }
 
       //  nsubedges = int(ceil(hvalue[DIVIDEEDGESECTIONS]));
@@ -282,7 +288,10 @@ namespace netgen
       {
          if (hvalue[i1]/hvalue[DIVIDEEDGESECTIONS]*nsubedges >= i)
          {
-            params[i] = s0+(i1/double(DIVIDEEDGESECTIONS))*(s1-s0);
+            // -- for nsubedges comparable to DIVIDEEDGESECTIONS
+            //params[i] = s0+(i1/double(DIVIDEEDGESECTIONS))*(s1-s0);
+            double d1 = i1 - (hvalue[i1] - i*hvalue[DIVIDEEDGESECTIONS]/nsubedges)/(hvalue[i1]-hvalue[i1-1]);
+            params[i] = s0+(d1/double(DIVIDEEDGESECTIONS))*(s1-s0);
             pnt = c->Value(params[i]);
             ps[i-1] = MeshPoint (Point3d(pnt.X(), pnt.Y(), pnt.Z()));
             i++;
@@ -326,6 +335,7 @@ namespace netgen
       (*testout) << "nedges = " << nedges << endl;
 
       double eps = 1e-6 * geom.GetBoundingBox().Diam();
+      const double eps2 = eps * eps; // -- small optimization
 
       for (int i = 1; i <= nvertices; i++)
       {
@@ -335,7 +345,8 @@ namespace netgen
          bool exists = 0;
          if (merge_solids)
             for (PointIndex pi = 1; pi <= mesh.GetNP(); pi++)
-               if ( Dist2 (mesh[pi], Point<3>(mp)) < eps*eps)
+               //if ( Dist2 (mesh[pi], Point<3>(mp)) < eps*eps)              
+               if ( Dist2 (mesh[pi], Point<3>(mp)) < eps2 ) // -- small optimization
                {
                   exists = 1;
                   break;
@@ -365,6 +376,7 @@ namespace netgen
          {
             TopoDS_Face face = TopoDS::Face(exp1.Current());
             int facenr = geom.fmap.FindIndex(face);
+            if ( facenr < 1 ) continue; // -- to support SALOME sub-meshes
 
             if (face2solid[0][facenr-1] == 0)
                face2solid[0][facenr-1] = solidnr;
@@ -384,6 +396,7 @@ namespace netgen
       int facenr = 0;
       int edgenr = 0;
 
+      edgenr = mesh.GetNSeg(); // to support SALOME sub-meshes
 
       (*testout) << "faces = " << geom.fmap.Extent() << endl;
       int curr = 0;
@@ -445,6 +458,7 @@ namespace netgen
                   //(*testout) << "ignoring degenerated edge" << endl;
                   continue;
                }
+               if ( geom.emap.FindIndex(edge) < 1 ) continue; // to support SALOME sub-meshes
 
                if (geom.vmap.FindIndex(TopExp::FirstVertex (edge)) ==
                   geom.vmap.FindIndex(TopExp::LastVertex (edge)))
@@ -482,15 +496,64 @@ namespace netgen
                }
                else
                {
-                  Point<3> fp = occ2ng (BRep_Tool::Pnt (TopExp::FirstVertex (edge)));
-                  Point<3> lp = occ2ng (BRep_Tool::Pnt (TopExp::LastVertex (edge)));
+                 TopoDS_Iterator vIt( edge, false );
+                 TopoDS_Vertex v1 = TopoDS::Vertex( vIt.Value() ); vIt.Next();
+                 TopoDS_Vertex v2 = TopoDS::Vertex( vIt.Value() );
+                 if ( v1.Orientation() == TopAbs_REVERSED )
+                   std::swap( v1, v2 );
+                 const bool isClosedEdge = v1.IsSame( v2 );
+                 
+                  Point<3> fp = occ2ng (BRep_Tool::Pnt (v1));
+                  Point<3> lp = occ2ng (BRep_Tool::Pnt (v2));
+                  double tol2 = std::min( eps*eps, 1e-6 * Dist2( fp, lp ));
+                  if ( isClosedEdge )
+                    tol2 = BRep_Tool::Tolerance( v1 ) * BRep_Tool::Tolerance( v1 );
 
                   pnums[0] = -1;
                   pnums.Last() = -1;
                   for (PointIndex pi = 1; pi < first_ep; pi++)
                   {
-                     if (Dist2 (mesh[pi], fp) < eps*eps) pnums[0] = pi;
-                     if (Dist2 (mesh[pi], lp) < eps*eps) pnums.Last() = pi;
+                    if (Dist2 (mesh[pi], fp) < tol2) pnums[0] = pi;
+                    if (Dist2 (mesh[pi], lp) < tol2) pnums.Last() = pi;
+                  }
+                  if (( isClosedEdge && pnums[0] != pnums.Last() ) ||
+                      ( !isClosedEdge && pnums[0] == pnums.Last() ))
+                    pnums[0] = pnums.Last() = -1;
+                  if ( pnums[0] == -1 || pnums.Last() == -1 )
+                  {
+                    // take into account a possible large gap between a vertex and an edge curve
+                    // end and a large vertex tolerance covering the whole edge
+                    if ( pnums[0] == -1 )
+                    {
+                      double tol = BRep_Tool::Tolerance( v1 );
+                      for (PointIndex pi = 1; pi < first_ep; pi++)
+                        if (pi != pnums.Last() && Dist2 (mesh[pi], fp) < 2*tol*tol)
+                          pnums[0] = pi;
+
+                      if ( pnums[0] == -1 )
+                        pnums[0] = first_ep-1- nvertices + geom.vmap.FindIndex ( v1 );
+                    }
+                    if ( isClosedEdge )
+                    {
+                      pnums.Last() = pnums[0];
+                    }
+                    else
+                    {
+                      if ( pnums.Last() == -1 )
+                      {
+                        double tol = BRep_Tool::Tolerance( v2 );
+                        for (PointIndex pi = 1; pi < first_ep; pi++)
+                          if (pi != pnums[0] && Dist2 (mesh[pi], lp) < 2*tol*tol)
+                            pnums.Last() = pi;
+
+                        if ( pnums.Last() == -1 )
+                          pnums.Last() = first_ep-1-nvertices + geom.vmap.FindIndex ( v2 );
+                      }
+
+                      if ( Dist2( fp, mesh[PointIndex(pnums[0])]) >
+                           Dist2( lp, mesh[PointIndex(pnums.Last())]))
+                      std::swap( pnums[0], pnums.Last() );
+                    }
                   }
                }
 
@@ -1458,3 +1521,4 @@ namespace netgen
 }
 
 #endif
+
diff -rupN netgen-5.1/libsrc/occ/occgeom.cpp netgen-5.1-new/libsrc/occ/occgeom.cpp
--- netgen-5.1/libsrc/occ/occgeom.cpp	2013-06-25 13:28:59.000000000 +0200
+++ netgen-5.1-new/libsrc/occ/occgeom.cpp	2014-06-13 19:54:42.971358572 +0200
@@ -8,6 +8,8 @@
 #include "ShapeAnalysis_CheckSmallFace.hxx"
 #include "ShapeAnalysis_DataMapOfShapeListOfReal.hxx"
 #include "ShapeAnalysis_Surface.hxx"
+#include <BRepTopAdaptor_FClass2d.hxx> // -- to optimize Project() and FastProject()
+#include <TopAbs_State.hxx>
 #include "BRepAlgoAPI_Fuse.hxx"
 #include "BRepCheck_Analyzer.hxx"
 #include "BRepLib.hxx"
@@ -16,10 +18,17 @@
 #include "ShapeFix_FixSmallFace.hxx"
 #include "Partition_Spliter.hxx"
 
-
 namespace netgen
 {
-   void OCCGeometry :: PrintNrShapes ()
+  // free data used to optimize Project() and FastProject()
+  OCCGeometry::~OCCGeometry()
+  {
+    NCollection_DataMap<int,BRepTopAdaptor_FClass2d*>::Iterator it(fclsmap);
+    for (; it.More(); it.Next())
+      delete it.Value();
+  }
+
+  void OCCGeometry :: PrintNrShapes ()
    {
       TopExp_Explorer e;
       int count = 0;
@@ -951,25 +960,58 @@ namespace netgen
    }
 
 
+   // returns a projector and a classifier for the given surface
+   void OCCGeometry::GetFaceTools(int surfi, Handle(ShapeAnalysis_Surface)& proj,
+                                  BRepTopAdaptor_FClass2d*& cls) const
+   {
+     //MSV: organize caching projector in the map
+     if (fprjmap.IsBound(surfi))
+     {
+       proj = fprjmap.Find(surfi);
+       cls = fclsmap.Find(surfi);
+     }
+     else
+     {
+       const TopoDS_Face& aFace = TopoDS::Face(fmap(surfi));
+       Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace);
+       proj = new ShapeAnalysis_Surface(aSurf);
+       fprjmap.Bind(surfi, proj);
+       cls = new BRepTopAdaptor_FClass2d(aFace,Precision::Confusion());
+       fclsmap.Bind(surfi, cls);
+     }
+   }
 
-
-   void OCCGeometry :: Project (int surfi, Point<3> & p) const
+   // void OCCGeometry :: Project (int surfi, Point<3> & p) const
+   bool OCCGeometry :: Project (int surfi, Point<3> & p, double& u, double& v) const
    {
       static int cnt = 0;
       if (++cnt % 1000 == 0) cout << "Project cnt = " << cnt << endl;
 
       gp_Pnt pnt(p(0), p(1), p(2));
 
-      double u,v;
-      Handle( Geom_Surface ) thesurf = BRep_Tool::Surface(TopoDS::Face(fmap(surfi)));
-      Handle( ShapeAnalysis_Surface ) su = new ShapeAnalysis_Surface( thesurf );
-      gp_Pnt2d suval = su->ValueOfUV ( pnt, BRep_Tool::Tolerance( TopoDS::Face(fmap(surfi)) ) );
-      suval.Coord( u, v);
-      pnt = thesurf->Value( u, v );
-
-
+      // -- Optimization: use cached projector and classifier
+      // double u,v;
+      // Handle( Geom_Surface ) thesurf = BRep_Tool::Surface(TopoDS::Face(fmap(surfi)));
+      // Handle( ShapeAnalysis_Surface ) su = new ShapeAnalysis_Surface( thesurf );
+      // gp_Pnt2d suval = su->ValueOfUV ( pnt, BRep_Tool::Tolerance( TopoDS::Face(fmap(surfi)) ) );
+      // suval.Coord( u, v);
+      // pnt = thesurf->Value( u, v );  
+
+      Handle(ShapeAnalysis_Surface) proj;
+      BRepTopAdaptor_FClass2d *cls;
+      GetFaceTools(surfi, proj, cls);
+  
+      gp_Pnt2d p2d = proj->ValueOfUV(pnt, Precision::Confusion());
+      if (cls->Perform(p2d) == TopAbs_OUT)
+      {
+        return false;
+      }
+      pnt = proj->Value(p2d);
+      p2d.Coord(u, v);
+  
       p = Point<3> (pnt.X(), pnt.Y(), pnt.Z());
 
+      return true;
    }
 
 
@@ -979,54 +1021,69 @@ namespace netgen
    {
       gp_Pnt p(ap(0), ap(1), ap(2));
 
-      Handle(Geom_Surface) surface = BRep_Tool::Surface(TopoDS::Face(fmap(surfi)));
-
-      gp_Pnt x = surface->Value (u,v);
-
-      if (p.SquareDistance(x) <= sqr(PROJECTION_TOLERANCE)) return true;
-
-      gp_Vec du, dv;
-
-      surface->D1(u,v,x,du,dv);
-
-      int count = 0;
-
-      gp_Pnt xold;
-      gp_Vec n;
-      double det, lambda, mu;
-
-      do {
-         count++;
-
-         n = du^dv;
-
-         det = Det3 (n.X(), du.X(), dv.X(),
-            n.Y(), du.Y(), dv.Y(),
-            n.Z(), du.Z(), dv.Z());
-
-         if (det < 1e-15) return false;
-
-         lambda = Det3 (n.X(), p.X()-x.X(), dv.X(),
-            n.Y(), p.Y()-x.Y(), dv.Y(),
-            n.Z(), p.Z()-x.Z(), dv.Z())/det;
-
-         mu     = Det3 (n.X(), du.X(), p.X()-x.X(),
-            n.Y(), du.Y(), p.Y()-x.Y(),
-            n.Z(), du.Z(), p.Z()-x.Z())/det;
-
-         u += lambda;
-         v += mu;
-
-         xold = x;
-         surface->D1(u,v,x,du,dv);
-
-      } while (xold.SquareDistance(x) > sqr(PROJECTION_TOLERANCE) && count < 50);
-
-      //    (*testout) << "FastProject count: " << count << endl;
-
-      if (count == 50) return false;
-
-      ap = Point<3> (x.X(), x.Y(), x.Z());
+      // -- Optimization: use cached projector and classifier
+      // Handle(Geom_Surface) surface = BRep_Tool::Surface(TopoDS::Face(fmap(surfi)));
+      // 
+      // gp_Pnt x = surface->Value (u,v);
+      // 
+      // if (p.SquareDistance(x) <= sqr(PROJECTION_TOLERANCE)) return true;
+      // 
+      // gp_Vec du, dv;
+      // 
+      // surface->D1(u,v,x,du,dv);
+      // 
+      // int count = 0;
+      // 
+      // gp_Pnt xold;
+      // gp_Vec n;
+      // double det, lambda, mu;
+      // 
+      // do {
+      //    count++;
+      // 
+      //    n = du^dv;
+      // 
+      //    det = Det3 (n.X(), du.X(), dv.X(),
+      //       n.Y(), du.Y(), dv.Y(),
+      //       n.Z(), du.Z(), dv.Z());
+      // 
+      //    if (det < 1e-15) return false;
+      // 
+      //    lambda = Det3 (n.X(), p.X()-x.X(), dv.X(),
+      //       n.Y(), p.Y()-x.Y(), dv.Y(),
+      //       n.Z(), p.Z()-x.Z(), dv.Z())/det;
+      // 
+      //    mu     = Det3 (n.X(), du.X(), p.X()-x.X(),
+      //       n.Y(), du.Y(), p.Y()-x.Y(),
+      //       n.Z(), du.Z(), p.Z()-x.Z())/det;
+      // 
+      //    u += lambda;
+      //    v += mu;
+      // 
+      //    xold = x;
+      //    surface->D1(u,v,x,du,dv);
+      // 
+      // } while (xold.SquareDistance(x) > sqr(PROJECTION_TOLERANCE) && count < 50);
+      // 
+      // //    (*testout) << "FastProject count: " << count << endl;
+      // 
+      // if (count == 50) return false;
+      // 
+      // ap = Point<3> (x.X(), x.Y(), x.Z());
+      Handle(ShapeAnalysis_Surface) proj;
+      BRepTopAdaptor_FClass2d *cls;
+      GetFaceTools(surfi, proj, cls);
+    
+      gp_Pnt2d p2d = proj->NextValueOfUV(gp_Pnt2d(u,v), p, Precision::Confusion());
+      if (cls->Perform(p2d) == TopAbs_OUT)
+      {
+        //cout << "Projection fails" << endl;
+        return false;
+      }
+    
+      p = proj->Value(p2d);
+      p2d.Coord(u, v);
+      ap = Point<3> (p.X(), p.Y(), p.Z());
 
       return true;
    }
diff -rupN netgen-5.1/libsrc/occ/occgeom.hpp netgen-5.1-new/libsrc/occ/occgeom.hpp
--- netgen-5.1/libsrc/occ/occgeom.hpp	2013-06-25 13:28:59.000000000 +0200
+++ netgen-5.1-new/libsrc/occ/occgeom.hpp	2014-06-13 19:54:42.972358572 +0200
@@ -15,8 +15,8 @@
 #include "Geom_Curve.hxx"
 #include "Geom2d_Curve.hxx"
 #include "Geom_Surface.hxx"
-#include "GeomAPI_ProjectPointOnSurf.hxx"
-#include "GeomAPI_ProjectPointOnCurve.hxx"
+// #include "GeomAPI_ProjectPointOnSurf.hxx"
+// #include "GeomAPI_ProjectPointOnCurve.hxx"
 #include "BRepTools.hxx"
 #include "TopExp.hxx"
 #include "BRepBuilderAPI_MakeVertex.hxx"
@@ -42,8 +42,8 @@
 #include "Geom_Curve.hxx"
 #include "Geom2d_Curve.hxx"
 #include "Geom_Surface.hxx"
-#include "GeomAPI_ProjectPointOnSurf.hxx"
-#include "GeomAPI_ProjectPointOnCurve.hxx"
+// #include "GeomAPI_ProjectPointOnSurf.hxx"
+// #include "GeomAPI_ProjectPointOnCurve.hxx"
 #include "TopoDS_Wire.hxx"
 #include "BRepTools_WireExplorer.hxx"
 #include "BRepTools.hxx"
@@ -68,7 +68,7 @@
 #include "IGESToBRep_Reader.hxx"
 #include "Interface_Static.hxx"
 #include "GeomAPI_ExtremaCurveCurve.hxx"
-#include "Standard_ErrorHandler.hxx"
+//#include "Standard_ErrorHandler.hxx"
 #include "Standard_Failure.hxx"
 #include "ShapeUpgrade_ShellSewing.hxx"
 #include "ShapeFix_Shape.hxx"
@@ -80,6 +80,10 @@
 #include "ShapeAnalysis.hxx"
 #include "ShapeBuild_ReShape.hxx"
 
+// -- Optimization: to use cached projector and classifier
+#include <NCollection_DataMap.hxx>
+class Handle_ShapeAnalysis_Surface;
+class BRepTopAdaptor_FClass2d;
 
 // Philippose - 29/01/2009
 // OpenCascade XDE Support
@@ -192,6 +196,9 @@ namespace netgen
    class OCCGeometry : public NetgenGeometry
    {
       Point<3> center;
+      // -- Optimization: to use cached projector and classifier
+      mutable NCollection_DataMap<int,Handle_ShapeAnalysis_Surface> fprjmap;
+      mutable NCollection_DataMap<int,BRepTopAdaptor_FClass2d*> fclsmap;
 
    public:
       TopoDS_Shape shape;
@@ -247,6 +254,8 @@ namespace netgen
      virtual void Save (string filename) const;
 
 
+      ~OCCGeometry();      // -- to free cached projector and classifier
+
       void BuildFMap();
 
       Box<3> GetBoundingBox()
@@ -266,9 +275,14 @@ namespace netgen
       Point<3> Center()
       {  return center;}
 
-      void Project (int surfi, Point<3> & p) const;
+      // void Project (int surfi, Point<3> & p) const; -- optimization
+      bool Project (int surfi, Point<3> & p, double& u, double& v) const;
       bool FastProject (int surfi, Point<3> & ap, double& u, double& v) const;
 
+      // -- Optimization: to use cached projector and classifier
+      void GetFaceTools(int surfi, Handle(ShapeAnalysis_Surface)& proj,
+                        BRepTopAdaptor_FClass2d*& cls) const;
+
       OCCSurface GetSurface (int surfi)
       {
          cout << "OCCGeometry::GetSurface using PLANESPACE" << endl;
diff -rupN netgen-5.1/libsrc/occ/occmeshsurf.cpp netgen-5.1-new/libsrc/occ/occmeshsurf.cpp
--- netgen-5.1/libsrc/occ/occmeshsurf.cpp	2013-06-25 13:28:59.000000000 +0200
+++ netgen-5.1-new/libsrc/occ/occmeshsurf.cpp	2014-06-13 19:54:42.972358572 +0200
@@ -6,6 +6,7 @@
 #include <meshing.hpp>
 #include <GeomLProp_SLProps.hxx>
 #include <ShapeAnalysis_Surface.hxx>
+#include <GeomAPI_ProjectPointOnCurve.hxx> // -- moved here from occgeom.hpp
 
 
 namespace netgen
@@ -434,23 +435,33 @@ namespace netgen
 
   void MeshOptimize2dOCCSurfaces :: ProjectPoint (INDEX surfind, Point<3> & p) const
   {
-    geometry.Project (surfind, p);
+    // geometry.Project (surfind, p); -- signature of Project() changed for optimization
+    double u, v;
+    geometry.Project (surfind, p, u, v);
   }
 
 
   int MeshOptimize2dOCCSurfaces :: ProjectPointGI (INDEX surfind, Point<3> & p, PointGeomInfo & gi) const
   {
-    double u = gi.u;
-    double v = gi.v;
+    //double u = gi.u;
+    //double v = gi.v;
 
     Point<3> hp = p;
-    if (geometry.FastProject (surfind, hp, u, v))
-      {
-	p = hp;
-	return 1;
-      }
-    ProjectPoint (surfind, p); 
-    return CalcPointGeomInfo (surfind, gi, p); 
+    // -- u and v are computed by FastProject() and Project(), no need to call CalcPointGeomInfo()
+    // if (geometry.FastProject (surfind, hp, u, v))
+    //   {
+    //    p = hp;
+    //    return 1;
+    //   }
+    // ProjectPoint (surfind, p); 
+    // return CalcPointGeomInfo (surfind, gi, p); 
+    bool ok;
+    if (gi.trignum > 0)
+      ok = geometry.FastProject (surfind, hp, gi.u, gi.v);
+    else
+      ok = geometry.Project (surfind, hp, gi.u, gi.v);
+    p = hp;
+    return ok;
   }
 
 
@@ -680,7 +691,8 @@ namespace netgen
 	if (!geometry.FastProject (surfi, hnewp, u, v))
 	  {
 	  //  cout << "Fast projection to surface fails! Using OCC projection" << endl;
-	    geometry.Project (surfi, hnewp);
+	    // geometry.Project (surfi, hnewp); -- Project() changed for optimization
+	    geometry.Project (surfi, hnewp, u, v);
 	  }
 
 	newgi.trignum = 1;
@@ -689,7 +701,7 @@ namespace netgen
       }
   
     newp = hnewp;
-  }
+  }//; -- to compile with -Wall -pedantic
 
 
   void OCCRefinementSurfaces :: 
@@ -708,14 +720,18 @@ namespace netgen
     hnewp = Point<3> (pnt.X(), pnt.Y(), pnt.Z());
     newp = hnewp;
     newgi = ap1;
-  };
+  }
 
 
   void OCCRefinementSurfaces :: ProjectToSurface (Point<3> & p, int surfi) const
   {
     if (surfi > 0)
-      geometry.Project (surfi, p);
-  };
+    // geometry.Project (surfi, p); -- Project() changed for optimization
+    {
+      double u, v;
+      geometry.Project (surfi, p, u, v);
+    }
+  }//; -- to compile with -Wall -pedantic
 
   void OCCRefinementSurfaces :: ProjectToSurface (Point<3> & p, int surfi, PointGeomInfo & gi) const
   {
@@ -723,9 +739,10 @@ namespace netgen
       if (!geometry.FastProject (surfi, p, gi.u, gi.v))
 	{
 	  cout << "Fast projection to surface fails! Using OCC projection" << endl;
-	  geometry.Project (surfi, p);
+          double u, v;
+	  geometry.Project (surfi, p, u, v);
 	}
-  };
+  }
 
 
 
diff -rupN netgen-5.1/libsrc/occ/Partition_Inter3d.cxx netgen-5.1-new/libsrc/occ/Partition_Inter3d.cxx
--- netgen-5.1/libsrc/occ/Partition_Inter3d.cxx	2013-06-25 13:28:59.000000000 +0200
+++ netgen-5.1-new/libsrc/occ/Partition_Inter3d.cxx	2014-06-13 19:54:42.969358572 +0200
@@ -243,9 +243,11 @@ static void PutInBounds (const TopoDS_Fa
       Standard_Integer i, nbExt = anExtPS.NbExt();
       Extrema_POnSurf aPOnSurf;
       for (i = 1; i <= nbExt; ++i )
-	if (anExtPS.Value( i ) <= TolE)               // V6.3
-	  // if (anExtPS.SquareDistance( i ) <= TolE)   // V6.5
-	  {
+        // porting to OCCT6.5.1
+	//if (anExtPS.Value( i ) <= TolE)               // V6.3
+	// if (anExtPS.SquareDistance( i ) <= TolE)   // V6.5
+        if (anExtPS.SquareDistance( i ) <= TolE * TolE)
+	{
           aPOnSurf = anExtPS.Point( i );
           break;
         }
diff -rupN netgen-5.1/libsrc/occ/Partition_Loop2d.cxx netgen-5.1-new/libsrc/occ/Partition_Loop2d.cxx
--- netgen-5.1/libsrc/occ/Partition_Loop2d.cxx	2013-06-25 13:28:59.000000000 +0200
+++ netgen-5.1-new/libsrc/occ/Partition_Loop2d.cxx	2014-06-13 19:54:42.970358572 +0200
@@ -210,7 +210,7 @@ static Standard_Boolean  SelectEdge(cons
     Cc->D1(uc, PC, CTg1);
     if (!isForward) CTg1.Reverse();
 
-    Standard_Real anglemin = 3 * PI, tolAng = 1.e-8;
+    Standard_Real anglemin = 3 * M_PI, tolAng = 1.e-8;
 
     // select an edge whose first derivative is most left of CTg1
     // ie an angle between Tg1 and CTg1 is least
@@ -234,7 +234,7 @@ static Standard_Boolean  SelectEdge(cons
       // -PI < angle < PI
       Standard_Real angle = Tg1.Angle(CTg1);
 
-      if (PI - Abs(angle) <= tolAng)
+      if (M_PI - Abs(angle) <= tolAng)
       {
         // an angle is too close to PI; assure that an angle sign really
         // reflects an edge position: +PI - an edge is worst,
diff -rupN netgen-5.1/libsrc/occ/Partition_Spliter.cxx netgen-5.1-new/libsrc/occ/Partition_Spliter.cxx
--- netgen-5.1/libsrc/occ/Partition_Spliter.cxx	2013-06-25 13:28:59.000000000 +0200
+++ netgen-5.1-new/libsrc/occ/Partition_Spliter.cxx	2014-06-13 19:54:42.970358572 +0200
@@ -1169,8 +1169,10 @@ static void findEqual (const TopTools_Li
           for (; j<=nbj && ok; ++j) {
             if (Extrema.IsMin(j)) {
 	      hasMin = Standard_True;
-	      ok = Extrema.Value(j) <= tol;  // V6.3
+	      // porting to OCCT6.5.1
+	      //ok = Extrema.Value(j) <= tol;  // V6.3
 	      // ok = Extrema.SquareDistance(j) <= tol;  // V6.5
+	      ok = Extrema.SquareDistance(j) <= tol * tol;
 	    }
           }
         }
diff -rupN netgen-5.1/libsrc/occ/utilities.h netgen-5.1-new/libsrc/occ/utilities.h
--- netgen-5.1/libsrc/occ/utilities.h	2013-08-14 16:09:45.000000000 +0200
+++ netgen-5.1-new/libsrc/occ/utilities.h	2014-06-13 19:54:42.972358572 +0200
@@ -33,6 +33,7 @@
 
 #include <string>
 #include <iostream>
+#include <iomanip>
 #include <cstdlib>
 // #include "SALOME_Log.hxx"
 
diff -rupN netgen-5.1/libsrc/stlgeom/stlgeommesh.cpp netgen-5.1-new/libsrc/stlgeom/stlgeommesh.cpp
--- netgen-5.1/libsrc/stlgeom/stlgeommesh.cpp	2013-06-25 13:28:59.000000000 +0200
+++ netgen-5.1-new/libsrc/stlgeom/stlgeommesh.cpp	2014-06-13 19:54:42.972358572 +0200
@@ -1435,7 +1435,8 @@ int STLMeshingDummy (STLGeometry* stlgeo
 	  /*
 	  if (!optstring || strlen(optstring) == 0)
 	    {
-	      mparam.optimize2d = "smcm";
+	      //mparam.optimize2d = (char*)"smcm";
+              mparam.optimize2d = (char*)"smcm";
 	    }
 	  else
 	    {
@@ -1453,7 +1454,7 @@ int STLMeshingDummy (STLGeometry* stlgeo
 	      mesh -> LoadLocalMeshSize (mparam.meshsizefilename);	      
 	      mesh -> CalcLocalHFromSurfaceCurvature (mparam.grading, 
 						      stlparam.resthsurfmeshcurvfac);
-	      mparam.optimize2d = "cmsmSm";
+	      mparam.optimize2d = "(char*)cmsmSm";
 	      STLSurfaceOptimization (*stlgeometry, *mesh, mparam);
 #ifdef STAT_STREAM
 	      (*statout) << GetTime() << " & ";
@@ -1560,7 +1561,8 @@ int STLMeshingDummy (STLGeometry* stlgeo
 	  /*
 	  if (!optstring || strlen(optstring) == 0)
 	    {
-	      mparam.optimize3d = "cmdmstm";
+              //mparam.optimize3d = "cmdmstm";
+	      mparam.optimize3d = (char*)"cmdmstm";
 	    }
 	  else
 	    {
diff -rupN netgen-5.1/nglib/nglib.h netgen-5.1-new/nglib/nglib.h
--- netgen-5.1/nglib/nglib.h	2013-06-25 13:28:56.000000000 +0200
+++ netgen-5.1-new/nglib/nglib.h	2014-06-13 19:54:42.973358572 +0200
@@ -24,7 +24,7 @@
 // Philippose - 14.02.2009
 // Modifications for creating a DLL in Windows
 #ifdef WIN32
-   #ifdef NGLIB_EXPORTS || nglib_EXPORTS
+   #if defined NGLIB_EXPORTS || defined nglib_EXPORTS
       #define DLL_HEADER   __declspec(dllexport)
    #else
       #define DLL_HEADER   __declspec(dllimport)