Skip to content
Snippets Groups Projects
DiscreteSurface.cpp 11.5 KiB
Newer Older
// $Id: DiscreteSurface.cpp,v 1.25 2005-09-07 17:12:16 remacle Exp $
Christophe Geuzaine's avatar
Christophe Geuzaine committed
//
// Copyright (C) 1997-2005 C. Geuzaine, J.-F. Remacle
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
// USA.
//
// Please report all bugs and problems to "gmsh@geuz.org".

#include "Gmsh.h"
#include "Numeric.h"
#include "Mesh.h"
#include "CAD.h"
#include "Geo.h"
#include "Create.h"
#include "Interpolation.h"
#include "Context.h"
#include "BDS.h"
Christophe Geuzaine's avatar
Christophe Geuzaine committed

extern Mesh *THEM;
extern Context_T CTX;
extern void Move_SimplexBaseToSimplex(Mesh * M, int dimension);
void Mesh_To_BDS(Mesh *m)

  Msg(STATUS2, "Moving the mesh in the new gmsh structure\n");
  Move_SimplexBaseToSimplex(m, 3);
  // create the structure
  if (m->bds)delete m->bds;
  m->bds = new BDS_Mesh;
  PhysicalGroup *p;

  m->bds->Min[0] = m->bds->Min[1] = m->bds->Min[2] = 1.e12;
  m->bds->Max[0] = m->bds->Max[1] =m->bds-> Max[2] = -1.e12;

  Msg(STATUS2, "Moving the nodes\n");
  // copy the nodes
  List_T *vertices = Tree2List ( m->Vertices ) ;
  for (int i=0;i<List_Nbr ( vertices ) ;++i)
    {
      Vertex *v;
      List_Read ( vertices, i, &v);
      if ( v->Pos.X < m->bds->Min [0]) m->bds->Min[0] = v->Pos.X;
      if ( v->Pos.Y < m->bds->Min [1]) m->bds->Min[1] = v->Pos.Y;
      if ( v->Pos.Z < m->bds->Min [2]) m->bds->Min[2] = v->Pos.Z;
      if ( v->Pos.X > m->bds->Max [0]) m->bds->Max[0] = v->Pos.X;
      if ( v->Pos.Y > m->bds->Max [1]) m->bds->Max[1] = v->Pos.Y;
      if ( v->Pos.Z > m->bds->Max [2]) m->bds->Max[2] = v->Pos.Z;
      m->bds->add_point (v->Num,v->Pos.X,v->Pos.Y,v->Pos.Z); 
  m->bds->LC = sqrt ((m->bds->Min[0]-m->bds->Max[0])*(m->bds->Min[0]-m->bds->Max[0])+
	     (m->bds->Min[1]-m->bds->Max[1])*(m->bds->Min[1]-m->bds->Max[1])+
	     (m->bds->Min[2]-m->bds->Max[2])*(m->bds->Min[2]-m->bds->Max[2]));
  List_Delete (vertices);

  for(int i = 0; i < List_Nbr(m->PhysicalGroups); i++) {
    List_Read(m->PhysicalGroups, i, &p);
    if(p->Typ == MSH_PHYSICAL_POINT) {
      m->bds->add_geom  (p->Num,0); 
      BDS_GeomEntity *g = m->bds->get_geom  (p->Num,0);
      for(int j = 0; j < List_Nbr(p->Entities); j++) {
	int Num;
        List_Read(p->Entities, j, &Num); 
	BDS_Point *ppp = m->bds->find_point (Num);
	ppp->g = g;
	g->p = ppp;
      }
    }
  }

  Msg(STATUS2, "Moving the curves\n");
  List_T *curves = Tree2List ( m->Curves ) ;
  for (int i=0;i<List_Nbr ( curves ) ;++i)
      Curve *c;
      List_Read ( curves, i, &c);
      m->bds->add_geom  ( c->Num, 1);
      BDS_GeomEntity *g = m->bds->get_geom  (c->Num,1);
      List_T *simplices = Tree2List ( c->Simplexes ) ;
      Simplex *simp;
      for (int j=0;j<List_Nbr ( simplices) ;++j)
	{
	  List_Read(simplices,j,&simp);
	  BDS_Edge *edge = m->bds->add_edge (simp->V[0]->Num,simp->V[1]->Num); 
	  edge->g = g;
	  if (!edge->p1->g)edge->p1->g = g;
	  if (!edge->p2->g)edge->p2->g = g;
	}
      List_Delete(simplices);
  List_Delete (curves);
  Msg(STATUS2, "Moving the surfaces\n");
  List_T *surfaces = Tree2List ( m->Surfaces ) ;
  for (int i=0;i<List_Nbr ( surfaces ) ;++i)
    {
      Surface *s;
      List_Read ( surfaces, i, &s);
      m->bds->add_geom  ( s->Num, 2);
      BDS_GeomEntity *g = m->bds->get_geom  (s->Num,2);
      printf("a new surface %d %d is created\n",g->classif_tag,g->classif_degree);
      List_T *simplices = Tree2List ( s->Simplexes ) ;
      Simplex *simp;
      for (int j=0;j<List_Nbr ( simplices) ;++j)
	  List_Read(simplices,j,&simp);
	  BDS_Triangle *t = m->bds->add_triangle (simp->V[0]->Num,simp->V[1]->Num,simp->V[2]->Num); 
	  t->g = g;	
	  BDS_Point *n[3];
	  t->getNodes (n);
	  for (int K=0;K<3;K++)
	    if (!n[K]->g) n[K]->g = g;
	  if (!t->e1->g)t->e1->g = g;
	  if (!t->e2->g)t->e2->g = g;
	  if (!t->e3->g)t->e3->g = g;
      List_Delete(simplices);
  List_Delete (surfaces);
  
  Msg(STATUS2, "Moving the %d volumes\n",Tree_Nbr(m->Volumes));
  List_T *volumes = Tree2List ( m->Volumes ) ;
  for (int i=0;i<List_Nbr ( volumes ) ;++i)
      Volume *v;
      List_Read ( volumes, i, &v);
      m->bds->add_geom  ( v->Num, 3);
      BDS_GeomEntity *g = m->bds->get_geom  (v->Num,3);
      List_T *simplices = Tree2List ( v->Simplexes ) ;
      Simplex *simp;
      printf("%d tets\n",List_Nbr ( simplices));
      for (int j=0;j<List_Nbr ( simplices) ;++j)
	  List_Read(simplices,j,&simp);
	  BDS_Tet *t = m->bds->add_tet (simp->V[0]->Num,simp->V[1]->Num,simp->V[2]->Num,simp->V[3]->Num); 
	  t->g = g;
	  BDS_Point *n[4];
	  t->getNodes (n);
	  for (int K=0;K<4;K++)
	    if (!n[K]->g) n[K]->g = g;
	  if (!t->f1->g) t->f1->g  = g;
	  if (!t->f2->g) t->f2->g  = g;
	  if (!t->f3->g) t->f3->g  = g;
	  if (!t->f4->g) t->f4->g  = g;
	  if (!t->f1->e1->g) t->f1->e1->g  = g;
	  if (!t->f2->e1->g) t->f2->e1->g  = g;
	  if (!t->f3->e1->g) t->f3->e1->g  = g;
	  if (!t->f4->e1->g) t->f4->e1->g  = g;
	  if (!t->f1->e2->g) t->f1->e2->g  = g;
	  if (!t->f2->e2->g) t->f2->e2->g  = g;
	  if (!t->f3->e2->g) t->f3->e2->g  = g;
	  if (!t->f4->e2->g) t->f4->e2->g  = g;
	  if (!t->f1->e3->g) t->f1->e3->g  = g;
	  if (!t->f2->e3->g) t->f2->e3->g  = g;
	  if (!t->f3->e3->g) t->f3->e3->g  = g;
	  if (!t->f4->e3->g) t->f4->e3->g  = g;

      List_Delete(simplices);
  List_Delete (volumes);
  
}
extern int addMeshPartition(int Num, Mesh * M);

void BDS_To_Mesh_2(Mesh *m)
{
  Msg(STATUS2, "Moving the surface mesh in the old gmsh structure\n");
  
  Tree_Action(m->Vertices, Free_Vertex);  
  Tree_Delete(m->Vertices);
  m->Vertices = Tree_Create(sizeof(Vertex *), compareVertex);
  
  {
    std::set<BDS_Point*, PointLessThan>::iterator it   = m->bds_mesh->points.begin();
    std::set<BDS_Point*, PointLessThan>::iterator ite  = m->bds_mesh->points.end();
    while (it != ite)
      {
	Vertex *vert = Create_Vertex((*it)->iD, (*it)->X,(*it)->Y,(*it)->Z, 1.0, 0.0);
	Tree_Add (m->Vertices,&vert);
	++it;
      }
  }
  
  
  {
    std::list<BDS_Edge*>::iterator it  = m->bds_mesh->edges.begin();
    std::list<BDS_Edge*>::iterator ite = m->bds_mesh->edges.end();
    while(it!=ite)
      {
	BDS_GeomEntity *g = (*it)->g;
	if (g && g->classif_degree == 1)
	  {
	    Vertex *v1 = FindVertex((*it)->p1->iD, m);
	    Vertex *v2 = FindVertex((*it)->p2->iD, m);
	    SimplexBase *simp = Create_SimplexBase(v1,v2,NULL, NULL);
	    Curve *c = FindCurve (g->classif_tag,m);
	    if (c)
	      simp->iEnt = g->classif_tag;
	    Tree_Insert(c->Simplexes, &simp);
	  }
	++it;
      }
  }
  {
    std::list<BDS_Triangle*>::iterator it  = m->bds_mesh->triangles.begin();
    std::list<BDS_Triangle*>::iterator ite = m->bds_mesh->triangles.end();
    while (it!=ite){
      BDS_GeomEntity *g = (*it)->g;
      if (g && g->classif_degree == 2)
	  {
	    BDS_Point *nod[3];
	    (*it)->getNodes (nod);
	    Vertex *v1 = FindVertex(nod[0]->iD, m);
	    Vertex *v2 = FindVertex(nod[1]->iD, m);
	    Vertex *v3 = FindVertex(nod[2]->iD, m);
	    SimplexBase *simp = Create_SimplexBase(v1,v2,v3, NULL);
	    BDS_GeomEntity *g = (*it)->g;
	    Surface *s = FindSurface (g->classif_tag,m);
		simp->iEnt = g->classif_tag;
		simp->iPart = addMeshPartition((*it)->partition, m);
	      printf("impossible to find surface %d\n",g->classif_tag);
	    Tree_Add(s->Simplexes, &simp);
	  }
      ++it;
    }
  }
  {
    std::list<BDS_Tet*>::iterator it  = m->bds_mesh->tets.begin();
    std::list<BDS_Tet*>::iterator ite = m->bds_mesh->tets.end();
    while (it!=ite){
      BDS_Point *nod[4];
      (*it)->getNodes (nod);
      Vertex *v1 = FindVertex(nod[0]->iD, m);
      Vertex *v2 = FindVertex(nod[1]->iD, m);
      Vertex *v3 = FindVertex(nod[2]->iD, m);
      Vertex *v4 = FindVertex(nod[3]->iD, m);
      SimplexBase *simp = Create_SimplexBase(v1,v2,v3, v4);
      BDS_GeomEntity *g = (*it)->g;
      Volume *v = FindVolume (g->classif_tag,m);
      if(v)
	{
	  simp->iEnt = g->classif_tag;
	  simp->iPart = addMeshPartition((*it)->partition, m);
      else
	printf("argh\n");
      Tree_Add(v->Simplexes, &simp);
      ++it;
    Msg(STATUS2, "Ready");
void BDS_To_Mesh(Mesh *m)
{
    Tree_Action(m->Points, Free_Vertex);  
    Tree_Delete(m->Points);
    Tree_Action(m->Volumes, Free_Volume);
    Tree_Action(m->Surfaces, Free_Surface);
    Tree_Action(m->Curves, Free_Curve);
    Tree_Delete(m->Surfaces);
    Tree_Delete(m->Curves);
    Tree_Delete(m->Volumes);
    m->Points = Tree_Create(sizeof(Vertex *), compareVertex);
    m->Curves = Tree_Create(sizeof(Curve *), compareCurve);
    m->Surfaces = Tree_Create(sizeof(Surface *), compareSurface);
    m->Volumes = Tree_Create(sizeof(Volume *), compareVolume);
    std::set<BDS_GeomEntity*,GeomLessThan>::iterator it  = m->bds->geom.begin(); 
    std::set<BDS_GeomEntity*,GeomLessThan>::iterator ite = m->bds->geom.end(); 
    
    while (it != ite)
    {
	if ((*it)->classif_degree ==3 )
	{
	    Volume *_Vol = 0; 
	    _Vol = FindVolume((*it)->classif_tag, m);
	    if (!_Vol) 
		_Vol = Create_Volume((*it)->classif_tag,MSH_VOLUME_DISCRETE);	
	    Tree_Add(m->Volumes, &_Vol);	    	   
	}
	else if ((*it)->classif_degree ==2 )
	    Surface *_Surf = 0; 
	    _Surf = FindSurface((*it)->classif_tag, m);
	    if (!_Surf) 
		_Surf = Create_Surface((*it)->classif_tag, MSH_SURF_DISCRETE);	
	    //	    _Surf->bds = m->bds;
	    End_Surface(_Surf);
	    Tree_Add(m->Surfaces, &_Surf);	    	   
	}
	else if ((*it)->classif_degree ==1  )
	    Curve *_c = 0; 
	    _c = FindCurve((*it)->classif_tag, m);
	    if (!_c) 
		_c = Create_Curve((*it)->classif_tag, MSH_SEGM_DISCRETE, 1, NULL, NULL, -1, -1, 0., 1.);	
	    //	    _c->bds = m->bds;
	    End_Curve(_c);
	    Tree_Add(m->Curves, &_c);
	}
	else if ((*it)->classif_degree == 0 )
	{
	  BDS_Point *p = (*it)->p;
	  if (p)
	    {
	      Vertex *_v = Create_Vertex(p->iD, p->X,p->Y,p->Z,1,0);	
	      Tree_Add(m->Points, &_v);
	    }

    CTX.mesh.changed = 1;

Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
// Public interface for discrete surface/curve mesh algo

int MeshDiscreteSurface(Surface *s)
  const int NITER = 10;
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
    Msg(STATUS2, "Discrete Surface Mesh Generator...");
    // s->bds is the discrete surface that defines the geometry
    if(!THEM->bds_mesh){
      THEM->bds_mesh = new BDS_Mesh (*(THEM->bds));
      int iter = 0;
      while(iter < NITER && THEM->bds_mesh->adapt_mesh(CTX.mesh.lc_factor * THEM->bds->LC, 
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
						    true, THEM->bds)){
	Msg(STATUS2, "Iteration %2d/%d done (%d triangles)\n",iter, NITER,THEM->bds_mesh->triangles.size());
	iter ++;
      }
      BDS_To_Mesh_2(THEM);
      Msg(STATUS2, "Mesh has %d vertices (%d)\n",Tree_Nbr(THEM->Vertices),THEM->bds->points.size());
      //	    THEM->bds_mesh->save_gmsh_format ( "3.msh" ); 
      return 1;
    return 2;
  }
  else if(s->Typ == MSH_SURF_DISCRETE){
    // nothing to do: we suppose that the surface is represented by
    // a mesh that will not be modified
    return 2;
  }
  else
    return 0;
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
}

int MeshDiscreteCurve(Curve *c)
{
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
  if(c->Typ == MSH_SEGM_DISCRETE){
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
    // nothing else to do: we assume that the curve is represented by
    // a mesh that will not be modified
Christophe Geuzaine's avatar
 
Christophe Geuzaine committed
    return 1;
  }
  else
    return 0;
}