ibgview.cxx

来自「有限元学习研究用源代码(老外的),供科研人员参考」· CXX 代码 · 共 513 行

CXX
513
字号
#include <math.h>
#include <stdio.h>
#include <time.h>
extern "C"{
#include <GL/gl.h>
#include "glrender.h"
#include "gltools/glwin.h"
}
#include "ibg2.hxx"
#include "ibgoutput.hxx"

static int iso=1;
static wzFloat fac[3]={1,1,1};
static wzgrid grid;

static void ibgRendererCallback(iglRenderer rnd, void *data);
static void DrawRegionTriangle(double *p1, double *p2, double *p3, wzRegion r);
static void DrawFaceTriangle(double *p1, double *p2, double *p3, wzFace f);
static void DrawTetrahedron(double *p1, double *p2, double *p3, double *p4, wzRegion r);
static int checkPosition(double* x, double* min, double* max, double* center, int mode);
static int checkCorrectness(wzgrid g, wzInteger cc);

const wzInteger SwitchOutside 		= 0;
const wzInteger SwitchBad 		= 1;
const wzInteger SwitchOrientation	= 2;
const wzInteger SwitchRegionMaterial	= 3;
const wzInteger ModeBase 		= 4;
const wzInteger ModePrint 		= 5;
const wzInteger ModeSide 		= 6;
const wzInteger ModeSlice 		= 7;
const wzInteger ValueNode		= 8;
const wzInteger ValueCell		= 9;
const wzInteger ValueRegion		=10;
const wzInteger ValueFace		=11;
const wzInteger ValueShrink		=12;
const wzInteger ValueSide		=13;
const wzInteger ActionCenter		=14;

char* 	BaseModi[]	= {"faces","cells"};
int   	baseModi   	= 2;
char* 	PrintModi[] 	= {"none","nodes","cells"};
int   	printModi   	= 3;
char* 	SideModi[] 	= {"all","behind", "not before", "before", "not behind"};
int   	sideModi   	= 5;
char* 	SliceModi[] 	= {"none","x", "y", "z"};
int   	sliceModi   	= 4;

//const wzInteger BaseFaces 	= 0;
const wzInteger BaseCells 	= 1;
const wzInteger SideAll 	= 0;
const wzInteger SideBehind 	= 1;
const wzInteger SideNotBefore 	= 2;
const wzInteger SideBefore 	= 3;
const wzInteger SideNotBehind 	= 4;

static void ibgMarkCells(iglRenderer rnd, wzgrid grid, wzArray<wzIndex> hidden)
{
  wzInteger obj = iglrGetObject(rnd);
  wzInteger cc,cl,cr,*cn0,l,i,u,ul,ur;
  wzCellType t;
  wzInteger vn,vc,vr,vf,vs;
  wzInteger mode;
  wzInteger showOutside,showBad,material;
  iglrGetEnum(rnd,obj,ModeBase,&mode);
  iglrGetSwitch(rnd,obj,SwitchOutside,&showOutside);
  iglrGetSwitch(rnd,obj,SwitchRegionMaterial,&material);
  iglrGetSwitch(rnd,obj,SwitchBad,&showBad);
  iglrGetInteger(rnd,obj,ValueNode,&vn);
  iglrGetInteger(rnd,obj,ValueCell,&vc);
  iglrGetInteger(rnd,obj,ValueRegion,&vr);
  iglrGetInteger(rnd,obj,ValueFace,&vf);
  iglrGetInteger(rnd,obj,ValueSide,&vs);
  wzRangeLoop(grid->cells,cc){
    t   = grid->cct(cc);
    l   = wzCellTypePoints(t);
    cn0 = grid->ccn(cc);
    u   = grid->ccu(cc);
    if(material){
      if(wzCellTypeIsRegion(t))		u = (wzRegion(u)).material();
      else if(wzCellTypeIsFace(t))	u = (wzFace(u)).type();
    }
    if(vc){
      if(cc==vc)	hidden[cc] = 0; 
      else 		hidden[cc] = 1; 
      continue;
    }else if(vn){
      hidden[cc] = 1; 
      for(i=0;i<l;i++) if(cn0[i]==vn) hidden[cc] = 0; 
      if(wzCellTypeIsRegion(t)){
	if(vr>0)	{ if(u !=  vr) hidden[cc]=1;}
	else if(vr<0)	{ if(u == -vr) hidden[cc]=1;}
      }else if(wzCellTypeIsFace(t)){
	if(vf>0)	{ if(u !=  vf) hidden[cc]=1;}
	else if(vf<0)	{ if(u == -vf) hidden[cc]=1;}
      }
      continue;
    }
    hidden[cc] = 1; 
    if(mode==BaseCells){
      if(t!=wzCellType3Tetrahedron) continue;
      if(vr>0){
	if(u !=  vr) continue;
      }else if(vr<0){
	if(u == -vr) continue;
      }
    }else{
      if(t!=wzCellType3Triangle) continue;
      if(!showOutside){
	cl = grid->ccleft( cc,t); if(grid->ccu(cl)==0) continue;
	cr = grid->ccright(cc,t); if(grid->ccu(cr)==0) continue;
      }
      if(vr){
	cl = grid->ccleft( cc,t);  ul = grid->ccu(cl);
	cr = grid->ccright(cc,t);  ur = grid->ccu(cr);
	if(material){
	  ul = (wzRegion(ul)).material();
	  ur = (wzRegion(ur)).material();
	}
	if(vr>0){
	  if(ul !=  vr && ur !=  vr) continue;
	}else if(vr<0){
	  if(ul == -vr || ur == -vr) continue;
	}
      }
      if(vf>0){
	if(u !=  vf) continue;
      }else if(vf<0){
	if(u == -vf) continue;
      }
    }
    if(showBad) if(checkCorrectness(grid,cc)) continue;
    hidden[cc] = 0;
  }
}

static void ibgComputeBoundingBox(iglRenderer rnd, wzgrid grid, wzArray<wzIndex> hidden, 
				  wzFloat *xm, wzFloat *xp)
{
  wzIndex i,j,l,t,cc;
  wzInteger *cn0;
  wzFloat *f;
  for(i=0;i<3;i++) xm[i] = +wzInfty;
  for(i=0;i<3;i++) xp[i] = -wzInfty;
  wzRangeLoop(grid->cells,cc){
    if(hidden[cc]) continue;
    t   = grid->cct(cc);
    l   = wzCellTypePoints(t);
    cn0 = grid->ccn(cc);
    for(j=0;j<l;j++){
      f=grid->cnx(cn0[j]);
      for(i=0;i<3;i++){
	if(xm[i]>f[i]) xm[i] = f[i];
	if(xp[i]<f[i]) xp[i] = f[i];
      }
    }
  }
  for(i=0;i<3;i++) if(xm[i]>xp[i]){xm[i]=grid->cgmin(i);xp[i]=grid->cgmax(i);}
}

static void ibgBoundingBox(iglRenderer rnd, void *data)
{
  wzFloat dd,xm[3],xp[3],xc[3],dx[3];
  wzIndex i;
  wzgrid grid = *(wzgrid *) &data;
  wzArray<wzIndex> hidden(grid->cells);
  ibgMarkCells(rnd,grid,hidden);
  ibgComputeBoundingBox(rnd,grid,hidden,xm,xp);
  dd = 0;
  for(i=0;i<3;i++){
    dx[i] =     (xp[i]-xm[i]);
    xc[i] = 0.5*(xp[i]+xm[i]);
    if(dd<dx[i]) dd=dx[i];
  }
  for(i=0;i<3;i++){
    xm[i] = xc[i]-dd;
    xp[i] = xc[i]+dd;
    if(xm[i] < grid->cgmin(i)) xm[i] = grid->cgmin(i);
    if(xp[i] > grid->cgmax(i)) xp[i] = grid->cgmax(i);
  }
  if(iso){
    fac[0] = grid->cgmax(0)-grid->cgmin(0);
    fac[1] = grid->cgmax(1)-grid->cgmin(1);
    fac[2] = grid->cgmax(2)-grid->cgmin(2);
  }else{
    fac[0]=fac[1]=fac[2]=1;
  }
  //  iglrGetVolume(rnd,&xm[0],&xp[0],&xm[1],&xp[1],&xm[2],&xp[2]);
  iglrSetVolume(rnd,
		xm[0]/fac[0],xp[0]/fac[0],
		xm[1]/fac[1],xp[1]/fac[1],
		xm[2]/fac[2],xp[2]/fac[2]);
}
  

static void ibgRendererCallback(iglRenderer rnd, void *data)
{
  wzInteger l,i,j,*cn0,cc,in,ic;
  wzFloat xm[3],xp[3],xc[3],dx[3];
  wzFloat *n[4],x[3],xx[4][3];
  double	pp,qq;
  char temp[256];
  wzInteger obj = iglrGetObject(rnd);
  wzCellType t;
  wzSegment s;
  wzInteger ori;
  wzInteger print,printNodes,printCells,slice,side;
  iglrGetSliceState(rnd,&slice);
  if(slice) return;

  wzgrid grid = *(wzgrid *) &data;
  wzArray<wzIndex> hidden(grid->cells);
  ibgMarkCells(rnd,grid,hidden);

  iglrGetEnum(rnd,obj,ModeSide,&side);
  iglrGetPoint(rnd,xc);
  iglrGetVolume(rnd,&xm[0],&xp[0],&xm[1],&xp[1],&xm[2],&xp[2]);
  for(i=0;i<3;i++){
    xm[i] *= fac[i];
    xp[i] *= fac[i];
    xc[i] *= fac[i];
    dx[i] = xp[i] - xm[i];
    xm[i] -= 0.001*dx[i];
    xp[i] += 0.001*dx[i];
  }
  wzRangeLoop(grid->cells,cc){
    if(hidden[cc]) continue;
    t   = grid->cct(cc);
    l   = wzCellTypePoints(t);
    cn0 = grid->ccn(cc);
    for(i=0;i<l;i++) n[i]=grid->cnx(cn0[i]);
    for(i=0;i<3;i++) {x[i]=0; for(j=0;j<l;j++) x[i] += n[j][i]; x[i] /= l;}
    if(checkPosition(x,xm,xp,xc,side)>0) continue;
    hidden[cc] = 1;
  }

  iglrGetSwitch(rnd,obj,SwitchOrientation,&ori);
  iglrGetDouble(rnd,obj,ValueShrink,&qq);
  qq /= 100; pp=1-qq;
  glBegin(GL_TRIANGLES);
  wzRangeLoop(grid->cells,cc){
    if(hidden[cc]) continue;
    t   = grid->cct(cc);
    l   = wzCellTypePoints(t);
    cn0 = grid->ccn(cc);
    for(i=0;i<l;i++){
      n[i]=grid->cnx(cn0[i]);
    }
    if(qq>0.001){
      for(i=0;i<3;i++) {
	x[i]=0; for(j=0;j<l;j++) x[i] += n[j][i]; x[i] /= l;
	for(j=0;j<l;j++) xx[j][i] = (pp*n[j][i] + qq*x[i])/fac[i];
      }
    }else{
      for(i=0;i<3;i++) {
	for(j=0;j<l;j++) xx[j][i] = n[j][i]/fac[i];
      }
    }
    if(l==4){
      DrawTetrahedron(xx[0],xx[1],xx[2],xx[3],grid->ccu(cc));
    }else if (ori){
      if(grid->ccu(grid->ccleft(cc,t))>grid->ccu(grid->ccright(cc,t)))
	DrawFaceTriangle(xx[0],xx[1],xx[2],grid->ccu(cc));
      else
	DrawFaceTriangle(xx[0],xx[2],xx[1],grid->ccu(cc));
    }else{
      if(grid->ccu(grid->ccleft(cc,t))>grid->ccu(grid->ccright(cc,t)))
	DrawFaceTriangle(xx[0],xx[2],xx[1],grid->ccu(cc));
      else
	DrawFaceTriangle(xx[0],xx[1],xx[2],grid->ccu(cc));
    }
  }
  glEnd();

  iglrGetSwitch(rnd,obj,ModePrint,&print);
  if(print==0) goto end;
  printNodes = print & 1;
  printCells = print & 2;
  glColor3f(1.0,1.0,1.0);
  wzRangeLoop(grid->cells,cc){
    if(hidden[cc]) continue;
    cn0 = grid->ccn(cc);
    t   = grid->cct(cc);
    l   = wzCellTypePoints(t);
    for(i=0;i<l;i++){
      in  = cn0[i];
      n[i]= grid->cnx(in);
      s   = grid->Point[in].segment();
      if(printNodes){      
	for(j=0;j<3;j++) x[j]= n[i][j]/fac[j];
	if(s.isFace()) in = -in;
	wzColor& col = s.color();
	glColor3f(col.r()/255.0,col.g()/255.0,col.b()/255.0);
	glRasterPos3f(n[i][0]/fac[0],n[i][1]/fac[1],n[i][2]/fac[2]);
	sprintf(temp,"%d",in);
	iglrPrint(rnd,temp);
      }
    }
    if(printCells){
      for(i=0;i<3;i++) {x[i]=0; for(j=0;j<l;j++) x[i] += n[j][i]; x[i] /= l;}
      if(wzCellTypeIsRegion(t)){
	wzColor& col=((wzRegion)(grid->ccu(cc))).color(); ic = cc;
	glColor3f(col.r()/255.0,col.g()/255.0,col.b()/255.0);
      }else if(wzCellTypeIsFace(t)){
	wzColor& col=((wzFace)(grid->ccu(cc))).color(); ic = -cc;
	glColor3f(col.r()/255.0,col.g()/255.0,col.b()/255.0);
      }
      glRasterPos3f(x[0]/fac[0],x[1]/fac[1],x[2]/fac[2]);
      sprintf(temp,"%d",ic);
      iglrPrint(rnd,temp);
    }
  }

end:
  grid = 0;
}

static int checkCorrectness(wzgrid g, wzInteger cc)
{
  wzInteger* cn0 = g->ccn(cc);
  wzIndex i,cl,cr;
  wzIndex t = g->cct(cc),u = g->ccu(cc);
  wzIndex codim = wzCellTypeCODIM(t);
  if(codim==1){
       cl = wzGridCellLeft( *g,cc,t); 
       if(g->ccu(cl)==0) return 1;
       cr = wzGridCellRight(*g,cc,t); 
       if(g->ccu(cr)==0) return 1;
  }
  for(i=0;i<wzCellTypePoints(t);i++){
    wzSegment s = g->Point[cn0[i]].segment();
    if(s.codim()<codim) return 0;
    if(s.codim()>codim) continue;
    if(s.index()!=u) 	return 0;
  }
  return 1;
}

/* returns 0 if outside, 1 if visible, -1 if inside but hidden */
static int checkPosition(double* x, double* min, double* max, double* center, int mode)
{
  int i;
  for(i=0;i<3;i++){
    if(x[i]<min[i]) return 0;
    if(x[i]>max[i]) return 0;
  }
  switch(mode){
  case SideAll:
    return 1;
  case SideBehind:
    for(i=0;i<3;i++) if(x[i]>center[i]) return -1;
    return 1;
  case SideNotBefore:
    for(i=0;i<3;i++) if(x[i]<center[i]) return 1;
    return -1;
  case SideBefore:
    for(i=0;i<3;i++) if(x[i]<center[i]) return -1;
    return 1;
  case SideNotBehind:
    for(i=0;i<3;i++) if(x[i]>center[i]) return 1;
    return -1;
  }
  return 1;
}


static void DrawTetrahedron(double *p1, double *p2, double *p3, double *p4, wzRegion r)
{
 wzColor col;
 col=r.color();
 glColor3f(col.r()/255.0,col.g()/255.0,col.b()/255.0);

 glVertex3f(p1[0],p1[1],p1[2]);
 glVertex3f(p2[0],p2[1],p2[2]);
 glVertex3f(p3[0],p3[1],p3[2]);

 glVertex3f(p1[0],p1[1],p1[2]);
 glVertex3f(p4[0],p4[1],p4[2]);
 glVertex3f(p2[0],p2[1],p2[2]);

 glVertex3f(p4[0],p4[1],p4[2]);
 glVertex3f(p1[0],p1[1],p1[2]);
 glVertex3f(p3[0],p3[1],p3[2]);

 glVertex3f(p2[0],p2[1],p2[2]);
 glVertex3f(p4[0],p4[1],p4[2]);
 glVertex3f(p3[0],p3[1],p3[2]);
}

static void DrawRegionTriangle(double *p1, double *p2, double *p3, wzRegion r)
{
 wzColor col;
 col=r.color();
 glColor3f(col.r()/255.0,col.g()/255.0,col.b()/255.0);
 glVertex3f(p1[0],p1[1],p1[2]);
 glVertex3f(p2[0],p2[1],p2[2]);
 glVertex3f(p3[0],p3[1],p3[2]);
}

static void DrawFaceTriangle(double *p1, double *p2, double *p3, wzFace f)
{
 wzColor col;
 col=f.color();
 glColor3f(col.r()/255.0,col.g()/255.0,col.b()/255.0);
 glVertex3f(p1[0],p1[1],p1[2]);
 glVertex3f(p2[0],p2[1],p2[2]);
 glVertex3f(p3[0],p3[1],p3[2]);
}

void ibgToGL(wzgrid g)
{
 ibgView.add(g,"test","test");
 ibgView.show();
 ibgView.reset();
}
void ibgToGL(wzgrid g, wzgrid g1)
{
 ibgView.add(g,"test","test");
 ibgView.add(g1,"test","test");
 ibgView.show();
 ibgView.reset();
}
void ibgToGL(wzgrid g, wzgrid g1, wzgrid g2)
{
 ibgView.add(g,"test","test");
 ibgView.add(g1,"test","test");
 ibgView.add(g2,"test","test");
 ibgView.show();
 ibgView.reset();
}
void ibgToGL(wzgrid g, wzgrid g1, wzgrid g2, wzgrid g3)
{
 ibgView.add(g,"test","test");
 ibgView.add(g1,"test","test");
 ibgView.add(g2,"test","test");
 ibgView.add(g3,"test","test");
 ibgView.show();
 ibgView.reset();
}

ibgGLViewer::ibgGLViewer(char* title)
{
 rnd= (void*) iglrCreate(title,"","",0,0,500,500);
 i=1;
}

void ibgGLViewer::show()
{
 iglrSetDataValid((iglRenderer)rnd,0 );
 iglrender((iglRenderer)rnd);
}
void ibgGLViewer::reset()
{
 i=1;
}


ibgGLViewer::~ibgGLViewer()
{
 iglrDestroy((iglRenderer) rnd);
}

ibgViewer& ibgView(* new ibgGLViewer());

void ibgGLViewer::add(wzgrid g, char* name, char* title)
{
  // char s[256]; 
 iglrDefineObject((iglRenderer)rnd,i,
	name[0],name,title,"ibgview.html#Keys",
	(iglrCallback)ibgRendererCallback,*(void**)&g);
 iglrDefineSwitch((iglRenderer)rnd,i,SwitchOutside,GLW_o,
		  "Outside","Show outer boundaries","ibgview.html#o");
 iglrDefineSwitch((iglRenderer)rnd,i,SwitchBad,GLW_b,
		  "Bad","Show bad cells only","ibgview.html#b");
 iglrDefineSwitch((iglRenderer)rnd,i,SwitchOrientation,GLW_O,
		  "Orientation","Switch orientation of faces","ibgview.html#O");
 iglrDefineSwitch((iglRenderer)rnd,i,SwitchRegionMaterial,GLW_r,
		  "Reg-Mat","Show region/material","ibgview.html#r");
 iglrDefineEnum((iglRenderer)rnd,i,ModeBase,GLW_m,
		"Mode","basic grid modes","ibgview.html#m",
		baseModi,BaseModi);
 iglrDefineEnum((iglRenderer)rnd,i,ModePrint,GLW_p,
		"Print","print numbers","ibgview.html#p",
		printModi,PrintModi);
 iglrDefineEnum((iglRenderer)rnd,i,ModeSide,GLW_s,
		"Side","choose the part to show","ibgview.html#s",
		sideModi,SideModi);
 iglrDefineEnum((iglRenderer)rnd,i,ModeSlice,GLW_i,
		"Intersection","choose x/y/z intersection","ibgview.html#i",
		sliceModi,SliceModi);
 iglrDefineInteger((iglRenderer)rnd,i,ValueNode,GLW_N,
		"node","set node","ibgview.html#N",
		0,g->points.last());
 iglrDefineInteger((iglRenderer)rnd,i,ValueCell,GLW_C,
		"cell","set cell","ibgview.html#C",
		0,g->cells.last());
 iglrDefineInteger((iglRenderer)rnd,i,ValueRegion,GLW_R,
		"region","set region","ibgview.html#R",
		-50,50);
 iglrDefineInteger((iglRenderer)rnd,i,ValueFace,GLW_F,
		"face","set face","ibgview.html#F",
		-50,50);
 iglrDefineInteger((iglRenderer)rnd,i,ValueSide,GLW_n,
		"side","side","ibgview.html#n",
		0,4);
 iglrDefineDouble((iglRenderer)rnd,i,ValueShrink,GLW_S,
		"shrink","shrinks cells (in %)","ibgview.html#S",
		0.0,99.0);
 iglrDefineAction((iglRenderer)rnd,i,ActionCenter,GLW_c,
		"center","centers the picture","ibgview.html#c",
		(iglrCallback) ibgBoundingBox);
 i++;
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?