From 9218079f8cf4460cb52a0207fb11539f1a96f236 Mon Sep 17 00:00:00 2001
From: Jean-Francois Remacle <jean-francois.remacle@uclouvain.be>
Date: Wed, 19 May 2010 19:53:38 +0000
Subject: [PATCH]

---
 Geo/ACISEdge.cpp             | 40 +++++-------------------------------
 Geo/ACISFace.cpp             | 14 ++++++++++++-
 Geo/ACISFace.h               |  2 ++
 Geo/GEntity.h                |  1 +
 Geo/GFace.cpp                | 22 ++++++++++++++++++++
 Geo/GFace.h                  |  4 ++++
 Geo/GModelIO_ACIS.cpp        |  2 +-
 Mesh/meshGFace.cpp           | 11 ++++++----
 benchmarks/boolean/nurbs.lua |  4 ++--
 9 files changed, 57 insertions(+), 43 deletions(-)

diff --git a/Geo/ACISEdge.cpp b/Geo/ACISEdge.cpp
index d21676905f..a02792cc96 100644
--- a/Geo/ACISEdge.cpp
+++ b/Geo/ACISEdge.cpp
@@ -60,40 +60,11 @@ Range<double> ACISEdge::parBounds(int i) const
 
 SPoint2 ACISEdge::reparamOnFace(const GFace *face, double epar, int dir) const
 {
-  COEDGE *ce = 0, *firstce = _e->coedge();
-  COEDGE *foundce = 0, *ffoundce=0;
-  int fedir;
-  ce = firstce;
-  
-  int count =0;
-  do {
-    LOOP *l = ce->loop();
-    FACE *f = l->face();
-    count ++;
-    
-    if(f==(FACE*)face->getNativePtr())
-    {
-      fedir = ce->sense()==FORWARD? 1 : 0;
-      if(fedir==dir)
-	foundce = ce;
-      else
-	ffoundce = ce; // save this for later
-    }
-    ce = ce->partner();
-  } while (ce != firstce && !foundce);
-  if(!foundce && ffoundce){
-    foundce = ffoundce;
-    fedir = !fedir;
-  }
-
-  if(!foundce){
-    Msg::Fatal("reparamOnFace - no coedge");
-  }
-  
   CURVE *c = _e->geometry();
   SPAposition vpos = c->equation().eval_position(epar);
   SPApar_pos fpar = ((FACE*)(face->getNativePtr()))->geometry()->equation().param(vpos);
   SPoint2 pt2(fpar.u, fpar.v);
+  face->moveToValidRange(pt2);
   return pt2;
 }
 
@@ -105,13 +76,12 @@ GPoint ACISEdge::closestPoint(const SPoint3 &qp, double &param) const{
 // True if the edge is a seam for the given face
 bool ACISEdge::isSeam(const GFace *face) const
 {
-  //  return false;
   CURVE *_cur = _e->geometry();
   if (!(((FACE*)face->getNativePtr())->geometry()->equation().periodic_u()) && 
-      !(((FACE*)face->getNativePtr())->geometry()->equation().periodic_u()))
+      !(((FACE*)face->getNativePtr())->geometry()->equation().periodic_v()))
       return 0;
   else if ( (((FACE*)face->getNativePtr())->geometry()->equation().periodic_u()) && 
-           !(((FACE*)face->getNativePtr())->geometry()->equation().periodic_u()))
+           !(((FACE*)face->getNativePtr())->geometry()->equation().periodic_v()))
   {
      SPAinterval cur_rang = _cur->equation().param_range();
      SPAinterval sur_rang_u = ((FACE*)face->getNativePtr())->geometry()->equation().param_range_u();
@@ -129,7 +99,7 @@ bool ACISEdge::isSeam(const GFace *face) const
         return 0;
   }
   else if (!(((FACE*)face->getNativePtr())->geometry()->equation().periodic_u()) && 
-            (((FACE*)face->getNativePtr())->geometry()->equation().periodic_u()))
+            (((FACE*)face->getNativePtr())->geometry()->equation().periodic_v()))
   {
      SPAinterval cur_rang = _cur->equation().param_range();
      SPAinterval sur_rang_v = ((FACE*)face->getNativePtr())->geometry()->equation().param_range_v();
@@ -147,7 +117,7 @@ bool ACISEdge::isSeam(const GFace *face) const
         return 0;
   }
   else if ((((FACE*)face->getNativePtr())->geometry()->equation().periodic_u()) && 
-           (((FACE*)face->getNativePtr())->geometry()->equation().periodic_u()))
+           (((FACE*)face->getNativePtr())->geometry()->equation().periodic_v()))
   {
      SPAinterval cur_rang = _cur->equation().param_range();
      SPAinterval sur_rang_u = ((FACE*)face->getNativePtr())->geometry()->equation().param_range_u();
diff --git a/Geo/ACISFace.cpp b/Geo/ACISFace.cpp
index 40856964e1..f7bc632d3e 100644
--- a/Geo/ACISFace.cpp
+++ b/Geo/ACISFace.cpp
@@ -189,9 +189,21 @@ double ACISFace::curvatures(const SPoint2 &param,
 
 bool ACISFace::containsPoint(const SPoint3 &pt) const
 { 
-  return false;
+  SPAposition ps(pt.x(),pt.y(),pt.z());
+  if (_f->geometry()->equation().test_point(ps))
+    return 1;
+  else 
+    return 0;
 }
 
+double ACISFace::period(int dir) const { 
+  if (dir == 0)
+    return _f->geometry()->equation().param_period_u();
+  else if (dir == 1)
+    return _f->geometry()->equation().param_period_v();
+}
+
+
 bool ACISFace::buildSTLTriangulation(bool force)
 {
   if(stl_triangles.size()){
diff --git a/Geo/ACISFace.h b/Geo/ACISFace.h
index c2a041553c..dcfe9a4adb 100644
--- a/Geo/ACISFace.h
+++ b/Geo/ACISFace.h
@@ -24,6 +24,8 @@ class ACISFace : public GFace {
  public:
   ACISFace(GModel *m, FACE *f, int num);
   virtual ~ACISFace(){}
+  virtual bool periodic(int dir) const { return _periodic[dir]; }
+  virtual double period(int dir) const;
   Range<double> parBounds(int i) const; 
   virtual GPoint point(double par1, double par2) const; 
   virtual GPoint closestPoint(const SPoint3 & queryPoint, const double initialGuess[2]) const; 
diff --git a/Geo/GEntity.h b/Geo/GEntity.h
index 3d5c8ac388..1ba28e5509 100644
--- a/Geo/GEntity.h
+++ b/Geo/GEntity.h
@@ -194,6 +194,7 @@ class GEntity {
 
   // true if entity is periodic in the "dim" direction.
   virtual bool periodic(int dim) const { return false; }
+  virtual double period(int dim) const { return 0.0; }
 
   // true if there are parametric degeneracies in the "dim" direction.
   virtual bool degenerate(int dim) const { return false; }
diff --git a/Geo/GFace.cpp b/Geo/GFace.cpp
index f1572a01fa..2236d7ef6d 100644
--- a/Geo/GFace.cpp
+++ b/Geo/GFace.cpp
@@ -1156,6 +1156,28 @@ void GFace::replaceEdges (std::list<GEdge*> &new_edges)
   l_dirs = newdirs;
 }
 
+void GFace::moveToValidRange(SPoint2 &pt) const
+{
+  //  printf("coucou %8d %12.5E %12.5E %d %d\n",
+  //	 tag(),pt.x(),pt.y(),
+  //	 periodic(0),periodic(1));
+  for(int i=0; i < 2; i++){
+    if(periodic(i)){
+      Range<double> range = parBounds(i);
+      double tol = 1e-6*(range.high()-range.low());
+      if(pt[i] < range.low()-tol)
+	pt[i] += period(i);
+      if(pt[i] > range.high()+tol)
+	pt[i] -= period(i);
+      if(pt[i] < range.low())
+	pt[i] = range.low();
+      if(pt[i] > range.high())
+	pt[i] = range.high();
+    }
+  }
+}
+
+
 #include "Bindings.h"
 
 void GFace::registerBindings(binding *b)
diff --git a/Geo/GFace.h b/Geo/GFace.h
index 42f85bfdb9..51b2513ac5 100644
--- a/Geo/GFace.h
+++ b/Geo/GFace.h
@@ -233,6 +233,10 @@ class GFace : public GEntity
   // reset the mesh attributes to default values
   virtual void resetMeshAttributes();
 
+  // for periodic faces, move parameters into the range chosen
+  // for that face
+  void moveToValidRange(SPoint2 &pt) const;
+
   // compound
   void setCompound(GFaceCompound *gfc) { compound = gfc; }
   GFaceCompound *getCompound() const { return compound; }
diff --git a/Geo/GModelIO_ACIS.cpp b/Geo/GModelIO_ACIS.cpp
index 40ac6462b0..5459d704df 100644
--- a/Geo/GModelIO_ACIS.cpp
+++ b/Geo/GModelIO_ACIS.cpp
@@ -234,7 +234,7 @@ void ACIS_Internals::loadSAT(std::string fileName, GModel *gm)
       //      printf("VERTEX FOUND\n");
     }
     if (is_BODY(e)){
-      //      api_split_periodic_faces(e);
+      api_split_periodic_faces(e);
       {
 	ENTITY_LIST vertex_list;
 	outcome prout = api_get_vertices (e,vertex_list);
diff --git a/Mesh/meshGFace.cpp b/Mesh/meshGFace.cpp
index 82a17a77f4..854874116e 100644
--- a/Mesh/meshGFace.cpp
+++ b/Mesh/meshGFace.cpp
@@ -835,6 +835,8 @@ static bool buildConsecutiveListOfVertices(GFace *gf, GEdgeLoop &gel,
     std::vector<SPoint2> mesh1d_seam;
     
     bool seam = ges.ge->isSeam(gf);
+
+    if (seam)printf("face %d has seam %d\n",gf->tag(),ges.ge->tag());
     
     Range<double> range = ges.ge->parBounds(0);
     
@@ -1332,7 +1334,7 @@ void deMeshGFace::operator() (GFace *gf)
   gf->meshStatistics.nbTriangle = gf->meshStatistics.nbEdge = 0;
 }
 
-int debugSurface = -1;
+int debugSurface = -100;
 
 void meshGFace::operator() (GFace *gf)
 {
@@ -1385,10 +1387,11 @@ void meshGFace::operator() (GFace *gf)
   Msg::Debug("Computing edge loops");
 
   Msg::Debug("Generating the mesh");
-  if(noSeam(gf) || gf->getNativeType() == GEntity::GmshModel || 
-     gf->edgeLoops.empty()){
+  if ((gf->getNativeType() != GEntity::AcisModel || (!gf->periodic(0) &&!gf->periodic(1)))&&
+      (noSeam(gf) || gf->getNativeType() == GEntity::GmshModel || 
+       gf->edgeLoops.empty())){
     meshGenerator(gf, 0, repairSelfIntersecting1dMesh,
-                  debugSurface >= 0 || debugSurface == -100);
+		  debugSurface >= 0 || debugSurface == -100);
   }
   else {
     if(!meshGeneratorPeriodic
diff --git a/benchmarks/boolean/nurbs.lua b/benchmarks/boolean/nurbs.lua
index 97c3efa30d..bd83cf472f 100644
--- a/benchmarks/boolean/nurbs.lua
+++ b/benchmarks/boolean/nurbs.lua
@@ -20,8 +20,8 @@ g:addLine(v7,v2);
 --	   {0,0,0,0,0.25,0.5,0.75,1,1,1,1},{1,1,1,1,1,1,1},{4,1,1,1,1,1,4}); 
 
 g:addBezier (v1,v2, {{v3:x(),v3:y(),0},{v4:x(),v4:y(),0},{v5:x(),v5:y(),0},{v6:x(),v6:y(),0},{v7:x(),v7:y(),0}}); 
-g:addNURBS (v1,v2, {{v3:x(),v3:y(),0},{v4:x(),v4:y(),0},{v5:x(),v5:y(),0},{v6:x(),v6:y(),0},{v7:x(),v7:y(),0}},	   
-	    {0,0.25,0.5,0.75,1}}},{1,1,1,1,1,1,1},{4,1,1,1,4}); 							   
+g:addNURBS (v1,v2, {{v3:x(),v3:y(),0},{v4:x(),v4:y(),0},{v5:x(),v5:y(),0},{v6:x(),v6:y(),0},{v7:x(),v7:y(),0}},
+            {0,0.25,0.5,0.75,1},{1,1,1,1,1,1,1},{4,1,1,1,4}); 							   
 g:addNURBS (v1,v2, {{v3:x(),v3:y(),0},{v4:x(),v4:y(),0},{v5:x(),v5:y(),0},{v6:x(),v6:y(),0},{v7:x(),v7:y(),0}},	   
 	   {0,0.5,1},{1,1,1,1,1,1,1},{4,3,4}); 							   
 
-- 
GitLab