From 5942496913fdcc44851b79ccad6f1e7b05e7fe32 Mon Sep 17 00:00:00 2001
From: Emilie Marchandise <emilie.marchandise@uclouvain.be>
Date: Thu, 19 Jan 2012 16:43:44 +0000
Subject: [PATCH] splitMesh almost done for centerlines

---
 Mesh/CenterlineField.cpp       | 101 +++++++++++++++++++++++++++------
 Mesh/CenterlineField.h         |   4 ++
 benchmarks/levelset/square.geo |   2 +-
 3 files changed, 89 insertions(+), 18 deletions(-)

diff --git a/Mesh/CenterlineField.cpp b/Mesh/CenterlineField.cpp
index d82a3bdd6e..41dac287f5 100644
--- a/Mesh/CenterlineField.cpp
+++ b/Mesh/CenterlineField.cpp
@@ -23,6 +23,8 @@
 #include "MLine.h"
 #include "GEntity.h"
 #include "Field.h"
+#include "GFace.h"
+#include "Integration3D.h"
 
 #if defined(HAVE_ANN)
 #include <ANN/ANN.h>
@@ -181,12 +183,17 @@ Centerline::~Centerline(){
 void Centerline::importFile(std::string fileName){
 
   GModel *current = GModel::current();
+  std::vector<GEntity*> entities ;
+  current->getEntities(entities) ; 
+  for(unsigned int i = 0; i < entities.size(); i++){
+    if(entities[i]->dim() == 2) surfaces.push_back((GFace*)entities[i]);
+  }
+  entities.clear();
 
   mod = new GModel();
   mod->readVTK(fileName.c_str());
   mod->removeDuplicateMeshVertices(1.e-8);
-  std::vector<GEntity*> entities ;
-  mod->getEntities(entities) ;  
+  mod->getEntities(entities);  
   current->setAsCurrent();  
 
   int maxN = 0.0;
@@ -344,17 +351,13 @@ void Centerline::distanceToLines(){
   std::vector<double> distancesE;
   std::vector<SPoint3> closePts;
 
-  GModel *current = GModel::current();
-  std::vector<GEntity*> _entities ;
-  current->getEntities(_entities) ; 
-  for(unsigned int i = 0; i < _entities.size(); i++){
-    if( _entities[i]->dim() != 2) continue;
-    for(unsigned int j = 0; j < _entities[i]->getNumMeshElements(); j++){ 
-       MElement *e = _entities[i]->getMeshElement(j);
-       for (int k = 0; k < e->getNumVertices(); k++){
-	 MVertex *v = e->getVertex(k);
-	 pts_set.insert(SPoint3(v->x(), v->y(),v->z()));
-       }
+  for(unsigned int i = 0; i < surfaces.size(); i++){ 
+    for(int j = 0; j < surfaces[i]->getNumMeshElements(); j++){ 
+      MElement *e = surfaces[i]->getMeshElement(j);
+      for (int k = 0; k < e->getNumVertices(); k++){
+	MVertex *v = e->getVertex(k);
+	pts_set.insert(SPoint3(v->x(), v->y(),v->z()));
+      }
     }
   }
   std::set<SPoint3>::iterator its =  pts_set.begin();
@@ -392,7 +395,7 @@ void Centerline::computeRadii(){
       std::map<MLine*,double>::iterator itr = radiusl.find(l);
       if (itr != radiusl.end()){
 	edges[i].minRad = std::min(itr->second, edges[i].minRad);
-	edges[i].maxRad = std::min(itr->second, edges[i].maxRad);
+	edges[i].maxRad = std::max(itr->second, edges[i].maxRad);
       }
       else printf("ARGG line not found \n");
     }    
@@ -445,6 +448,8 @@ void Centerline::buildKdTree(){
 
 void Centerline::splitMesh(){
 
+  Msg::Info("Splitting surface mesh with centerline field ");
+
  for(unsigned int i = 0; i < edges.size(); ++i){
    std::vector<MLine*> lines = edges[i].lines;
    MVertex *v1 = edges[i].vE;
@@ -456,7 +461,7 @@ void Centerline::splitMesh(){
    else if (lines.back()->getVertex(1) == v1) v2 = lines.back()->getVertex(0);
    SVector3 dir(v2->x()-v1->x(),v2->y()-v1->y(),v2->z()-v1->z());
    if(edges[i].children.size() > 0.0){
-     cutByDisk(pt, dir, edges[i].maxRad);
+     cutByDisk(pt, dir, 1.2*edges[i].maxRad);
    }
  }
 
@@ -469,8 +474,70 @@ void Centerline::cutByDisk(SPoint3 pt, SVector3 norm, double rad){
   double b = norm.y();
   double c = norm.z();
   double d = -a * pt[0] - b * pt[1] - c * pt[2];
-  printf("PLane = %g %g %g %g \n", a, b, c, d);
-  exit(1);
+  printf("Plane = %g %g %g %g \n", a, b, c, d);
+  //ls = a * x + b * y + c * z + d;
+
+  //variables for using the cutting tools
+  std::vector<DI_Line *> lines;
+  std::vector<DI_Triangle *> triangles;
+  std::vector<DI_Quad *> quads;
+  DI_Point::Container cp;//cut points
+  std::vector<DI_IntegrationPoint *> ipV;//integration points vol
+  std::vector<DI_IntegrationPoint *> ipS;//integration points surf
+  bool isCut = false;
+  int integOrder = 1;
+  int recur = 0;
+  gLevelset *GLS = new gLevelsetPlane(0., 0., 0., 0.);
+  std::vector<gLevelset *> RPN;
+  RPN.push_back(GLS);
+
+  //loop over all surface mesh elements
+  for(unsigned int i = 0; i < surfaces.size(); i++){ 
+    for(int j = 0; j < surfaces[i]->getNumMeshElements(); j++){ 
+      MElement *e = surfaces[i]->getMeshElement(j);
+      if (e->getNumVertices() != 3){
+  	Msg::Error("Centerline split only implemented for tri meshes so far ..."); 
+  	exit(1);
+      }
+      int nbV = e->getNumVertices();
+
+      double **nodeLs= new double*[nbV];
+      DI_Triangle T(e->getVertex(0)->x(), e->getVertex(0)->y(), e->getVertex(0)->z(),
+  		    e->getVertex(1)->x(), e->getVertex(1)->y(), e->getVertex(1)->z(),
+  		    e->getVertex(2)->x(), e->getVertex(2)->y(), e->getVertex(2)->z());
+      SPoint3 cg(0.333*(e->getVertex(0)->x()+e->getVertex(1)->x()+e->getVertex(2)->x()), 
+  		 0.333*(e->getVertex(0)->y()+e->getVertex(1)->y()+e->getVertex(2)->y()),
+  		 0.333*(e->getVertex(0)->z()+e->getVertex(1)->z()+e->getVertex(2)->z()));
+      T.setPolynomialOrder(1);
+      double x0 = e->getVertex(0)->x(), y0= e->getVertex(0)->y(), z0=e->getVertex(0)->z();
+      double val0 = a * x0 + b * y0 + c * z0 + d;
+      double sign0 = val0;
+      bool zeroElem = false;
+      nodeLs[0] = new double[1];//one ls value
+      nodeLs[0][0]= val0;
+      for(int i=1;i<nbV;i++){
+	double x = e->getVertex(i)->x(), y= e->getVertex(i)->y(), z=e->getVertex(i)->z();
+  	double val = a * x + b * y + c * z + d;
+    	double sign = sign0*val;
+  	if (sign < 0.0 && !zeroElem) zeroElem = true;
+  	nodeLs[i] = new double[1];//one ls value
+	nodeLs[i][0]= val;
+      }
+      if (zeroElem){
+  	double radius = sqrt((cg.x()-pt.x())*(cg.x()-pt.x())+(cg.y()-pt.y())*(cg.y()-pt.y())+(cg.z()-pt.z())*(cg.z()-pt.z()));
+  	if (radius <  rad){
+      	  isCut = T.cut(RPN, ipV, ipS, cp, integOrder, integOrder, integOrder,
+      			quads, triangles, lines, recur, nodeLs);
+  	}
+      }
+      else triangles.push_back(&T);
+
+      for(int i=0;i<nbV;i++) delete nodeLs[i];
+      delete []nodeLs;
+    }
+  }
+
+  printf("split mesh done \n");
   return;
 
 }
diff --git a/Mesh/CenterlineField.h b/Mesh/CenterlineField.h
index 3f4146f0bf..e773cde8e8 100644
--- a/Mesh/CenterlineField.h
+++ b/Mesh/CenterlineField.h
@@ -15,6 +15,7 @@
 #include <string>
 #include "Field.h"
 class GModel;
+class GFace;
 class MLine;
 class MVertex;
 class GEntity;
@@ -64,6 +65,9 @@ class Centerline : public Field{
   std::map<MVertex*,int> colorp;
   std::map<MLine*,int> colorl;
 
+  //the tubular surface mesh
+  std::vector<GFace*> surfaces; 
+
  public:
   Centerline(std::string fileName);
   Centerline();
diff --git a/benchmarks/levelset/square.geo b/benchmarks/levelset/square.geo
index fe6e8719bf..2d0f8b1511 100644
--- a/benchmarks/levelset/square.geo
+++ b/benchmarks/levelset/square.geo
@@ -9,7 +9,7 @@
 
 Mesh.Algorithm=1;
 Mesh.CharacteristicLengthFactor=1.5;
-Mesh.ElementOrder=2;
+Mesh.ElementOrder=1;
 
 lc=0.1;
 Point(1) = {0.1, 0.1, 0.1}; //,lc};
-- 
GitLab