Exemplo n.º 1
0
 static INDEX_3 Sort (int i1, int i2, int i3)
 {
     if (i1 > i2) Swap (i1, i2);
     if (i2 > i3) Swap (i2, i3);
     if (i1 > i2) Swap (i1, i2);
     return INDEX_3 (i1, i2, i3);
 }
Exemplo n.º 2
0
float NoiseSampler::vnoise(const glm::vec3& p) {
  int ix = FLOOR(p[0]);
  int iy = FLOOR(p[1]);
  int iz = FLOOR(p[2]);
  float fy = p[1]-iy;
  float fx = p[0]-ix;
  float fz = p[2]-iz;

  float xp[4], yp[4], zp[4];

  for(int k = -1; k <= 2; k++) {
    for(int j = -1; j <= 2; j++) {
      for(int i = -1; i <= 2; i++) {
        xp[i+1] = m_value_table[INDEX_3(ix+i, iy+j, iz+k)];
      }
      yp[j+1] = catmull_rom4(fx, xp);
    }
    zp[k+1] = catmull_rom4(fy, yp);
  }
  return catmull_rom4(fz, zp);
}
Exemplo n.º 3
0
HPREF_ELEMENT_TYPE ClassifyPrism(HPRefElement & el, INDEX_2_HASHTABLE<int> & edges, INDEX_2_HASHTABLE<int> & edgepoint_dom, 
                                 BitArray & cornerpoint, BitArray & edgepoint, INDEX_3_HASHTABLE<int> & faces, INDEX_2_HASHTABLE<int> & face_edges, 
                                 INDEX_2_HASHTABLE<int> & surf_edges, Array<int, PointIndex::BASE> & facepoint)
{

  HPREF_ELEMENT_TYPE type = HP_NONE;
  
  int p[6];
  for(int m=1;m<=6;m++)
    {
      int point_sing[6]={0,0,0,0,0,0}; 
      int face_sing[5]={0,0,0,0,0};
      int edge_sing[9]={0,0,0,0,0,0,0,0,0}; 
      
      if(m<4)
	{ 
	  p[0]= m; p[1]=m%3+1; p[2]=(m%3+1)%3+1;
	  for(int l=3;l<6;l++) p[l]=p[l-3]+3;  
	}
      else
	{
	  p[0] = m; p[1]=(m%3+1)%3+4; p[2]=m%3+4;
	  for(int l=3;l<6;l++) p[l]=p[l-3]-3; 
	}
      
      for(int j=0;j<6;j++) 
	{ 
	  if(cornerpoint.Test(el.PNum(p[j])))  { point_sing[p[j]-1]=3;}
	  else if(edgepoint.Test(el.PNum(p[j]))) point_sing[p[j]-1]=2;
	  else if (facepoint[el.PNum(p[j])] == -1 || facepoint[el.PNum(p[j])] == el.GetIndex())
	    point_sing[p[j]-1] = 1;  
	}
      
      const ELEMENT_EDGE * eledges = MeshTopology::GetEdges (PRISM);
      for(int k=0;k<9;k++)
	{
	  INDEX_2 i2 = INDEX_2 :: Sort(el.PNum(p[eledges[k][0]-1]),el.PNum(p[eledges[k][1]-1])); 
	  if (edges.Used(i2)) edge_sing[k] = 2;
	  else edge_sing[k] = face_edges.Used(i2);
	}
      
      const ELEMENT_FACE * elfaces  = MeshTopology::GetFaces (PRISM);
      for (int k=0;k<5;k++)
	{
	  INDEX_3 i3; 
	  
	  if(k<2) 
	    i3 = INDEX_3::Sort(el.pnums[p[elfaces[k][0]-1]-1], el.pnums[p[elfaces[k][1]-1]-1], 
			       el.pnums[p[elfaces[k][2]-1]-1]); 
	  else 
	    { 
	      INDEX_4  i4 = INDEX_4(el.pnums[p[elfaces[k][0]-1]-1], el.pnums[p[elfaces[k][1]-1]-1], el.pnums[p[elfaces[k][2]-1]-1],el.pnums[p[elfaces[k][3]-1]-1]); 
	      i4.Sort();
	      i3 = INDEX_3(i4.I1(), i4.I2(), i4.I3()); 
	    }
	  
	  if (faces.Used (i3))
	    {
	      int domnr = faces.Get(i3); 
	      if (domnr == -1 || domnr == el.GetIndex())
		face_sing[k] = 1; 
	      
	    } 
	} 
      if (face_sing[1] > face_sing[0]) {m=m+2; continue;}  
      
      
      //int cp = 0;  
      
      int qfsing = face_sing[2] + face_sing[3] + face_sing[4];
      int tfsing = face_sing[0] + face_sing[1]; 
      int evsing = edge_sing[6] + edge_sing[7] + edge_sing[8];
      int ehsing = edge_sing[0] + edge_sing[1] + edge_sing[2] + edge_sing[3] + edge_sing[4] + edge_sing[5];
      
      if (qfsing + tfsing + evsing + ehsing == 0)  
	{ type = HP_PRISM;  break;}
      
      HPREF_ELEMENT_TYPE types[] = {HP_NONE,HP_NONE,HP_NONE};   
      
      int fb = (1-face_sing[4])* face_sing[3] * (face_sing[2] + face_sing[3]) + 3*face_sing[4]*face_sing[3]*face_sing[2];  
      int sve[3] = {edge_sing[7] , edge_sing[8], edge_sing[6]}; 
      
            
      if(fb!=qfsing) continue; 
      
      
      switch(fb)
	{ 
	case 0: 
	  if (evsing == 0 && ehsing==3*tfsing) 
	    {
	      types[0] = HP_PRISM; 
	      types[1] = HP_PRISM_1FA_0E_0V;   
	      types[2] = HP_PRISM_2FA_0E_0V; 
	    } 
	  if(evsing > 0 &&  sve[0] == evsing) // 1 vertical edge 1-4 
	    { 
	      types[0] = HP_PRISM_SINGEDGE;
	      types[1] = HP_PRISM_1FA_1E_0V;
	      types[2] = HP_PRISM_2FA_1E_0V;   
	    }
	  
	  if(sve[0] > 0 && sve[1] > 0 && sve[2] == 0)
	    {
	      types[0] = HP_PRISM_SINGEDGE_V12;
	      types[1] = HP_PRISM_1FA_2E_0V; 
	      types[2] = HP_PRISM_2FA_2E_0V; 
	    }
	  if(sve[0] > 0 && sve[1] > 0 && sve[2] > 0) 
	    {
	      types[0] = HP_PRISM_3E_0V;
	      types[1] = HP_PRISM_1FA_3E_0V;
	      types[2] = HP_PRISM_2FA_3E_0V;
	      
	      if ( edge_sing[0] > 1 && edge_sing[2] > 1 &&  
		   edge_sing[4] > 1 && edge_sing[5] > 1 && tfsing==0)
		types[0] = HP_PRISM_3E_4EH; 
	    }
	  
	  break;
	case 1:
	  if(sve[0] <= 1 && sve[1] <= 1)  
	    if(sve[2]==0)
	      { 
		types[0] = HP_PRISM_1FB_0E_0V;
		types[1] = HP_PRISM_1FA_1FB_0E_0V;
		types[2] = HP_PRISM_2FA_1FB_0E_0V;  
	      }
	    else
	      { 
		types[0] = HP_PRISM_1FB_1EC_0V;
		types[1] = HP_PRISM_1FA_1FB_1EC_0V;
		types[2] = HP_PRISM_2FA_1FB_1EC_0V; 
	      }
	  
	  if(sve[0] > 1 && sve[2] >= 1 && sve[1] <= 1)
	    { 
	      types[0] = HP_PRISM_1FB_2EB_0V;  
	      types[1] = HP_PRISM_1FA_1FB_2EB_0V;
	      types[2] = HP_PRISM_2FA_1FB_2EB_0V; 
	    }
	  
	  if(sve[0] > 1 && sve[1] <= 1 && sve[2] == 0) // ea && !eb  
	    {
	      types[0] = HP_PRISM_1FB_1EA_0V;
	      types[1] = HP_PRISM_1FA_1FB_1EA_0V;
	      types[2] = HP_PRISM_2FA_1FB_1EA_0V; 
	    } 
	  
	  if(sve[0] <= 1 && sve[1] > 1 && sve[2] == 0)
	    types[1] = HP_PRISM_1FA_1FB_1EB_0V; 
	  
	  if(sve[0] > 1 && sve[1]>1) 
	    if(sve[2] == 0)  // ea && eb 
	      {
		types[0] = HP_PRISM_1FB_2EA_0V;
		types[1] = HP_PRISM_1FA_1FB_2EA_0V;
		types[2] = HP_PRISM_2FA_1FB_2EA_0V; 
	      }
	  if(sve[0] <= 1 && sve[1] > 1 && sve[2] >0)
	    types[1] = HP_PRISM_1FA_1FB_2EC_0V; 
	  
	  if(sve[0] > 1 && sve[1] > 1 && sve[2] >= 1) //sve[2] can also be a face-edge  
	    {
	      types[0] = HP_PRISM_1FB_3E_0V;  
	      types[1] = HP_PRISM_1FA_1FB_3E_0V; 
	      types[2] = HP_PRISM_2FA_1FB_3E_0V; 
	    } 
	  
	  break;  
	  
	case 2:
	  if(sve[0] <= 1) 
	    cout << " **** WARNING: Edge between to different singular faces should be marked singular " << endl; 
		      
	  if(sve[1] <= 1)   
	    if(sve[2] <=1) 
	      { 
		types[0] = HP_PRISM_2FB_0E_0V; 
		types[1] = HP_PRISM_1FA_2FB_0E_0V;
		types[2] = HP_PRISM_2FA_2FB_0E_0V;
	      }
	    else
	      { 
		types[0] = HP_PRISM_2FB_1EC_0V; 
		types[1] = HP_PRISM_1FA_2FB_1EC_0V; 
		types[2] = HP_PRISM_2FA_2FB_1EC_0V;   
	      }
	  else
	    if(sve[2] <= 1) 
	      types[1] = HP_PRISM_1FA_2FB_1EB_0V; 
	    else
	      { 
		types[0] = HP_PRISM_2FB_3E_0V; 
		types[1] = HP_PRISM_1FA_2FB_3E_0V; 
		types[2] = HP_PRISM_2FA_2FB_3E_0V; 
	      }
	  
	  break;
	  
	case 3: 
	  types[0] = HP_PRISM_3FB_0V; 
	  types[1] = HP_PRISM_1FA_3FB_0V; 
	  types[2] = HP_PRISM_2FA_3FB_0V; 
	  break;
	}
      type = types[tfsing];
      
         
      if(type != HP_NONE)  
	break;
    }
	 
  /*
   *testout << " Prism with pnums " << endl; 
   for(int j=0;j<6;j++) *testout << el.pnums[j] << "\t"; 
   *testout << endl; 
   */
  
  if(type != HP_NONE) 
    {
      int pnums[6]; 
      for(int j=0;j<6;j++) pnums[j] = el.PNum (p[j]);
      for(int k=0;k<6;k++) el.pnums[k] = pnums[k]; 
    }

  /* *testout << " Classified Prism with pnums " << endl; 
     for(int j=0;j<6;j++) *testout << el.pnums[j] << "\t"; 
     *testout << endl; 
     */ 
  return(type); 
}
Exemplo n.º 4
0
HPREF_ELEMENT_TYPE ClassifyPyramid(HPRefElement & el, INDEX_2_HASHTABLE<int> & edges, INDEX_2_HASHTABLE<int> & edgepoint_dom, 
                                   BitArray & cornerpoint, BitArray & edgepoint, INDEX_3_HASHTABLE<int> & faces, INDEX_2_HASHTABLE<int> & face_edges, 
                                   INDEX_2_HASHTABLE<int> & surf_edges, Array<int, PointIndex::BASE> & facepoint)
{
  HPREF_ELEMENT_TYPE type = HP_NONE;
  
  // implementation only for HP_PYRAMID
  //                         HP_PYRAMID_0E_1V
  //                         HP_PYRAMID_EDGES
  //                         HP_PYRAMID_1FB_0E_1VA
  // up to now other cases are refine dummies 
  
  // indices of bot,top-faces combinations
  // int index[6][2] = {{0,1},{1,0},{2,4},{4,2},{3,5},{5,3}}; 

  const ELEMENT_FACE * elfaces  = MeshTopology::GetFaces (PYRAMID);
  const ELEMENT_EDGE * eledges = MeshTopology::GetEdges (PYRAMID);
  
  int point_sing[5]={0,0,0,0,0}; 
  int face_sing[5] = {0,0,0,0,0};
  int edge_sing[8] = {0,0,0,0,0,0,0,0};
  
  int spoint=0, sedge=0, sface=0; 
   
  for(int m=0;m<4 && type == HP_NONE;m++) 
    {
      int p[5] = {m%4, m%4+1, m%4+2, m%4+3, 4}; 

      for(int l=0;l<5;l++) 
	{
	  if(cornerpoint.Test(el.pnums[p[l]]))  
	    point_sing[l]=3;
	  
          else if(edgepoint.Test(el.pnums[p[l]]))
	    point_sing[l]=2;
	  
	  else if (facepoint[el.pnums[p[l]]] == -1 || facepoint[el.pnums[p[l]]] == el.GetIndex())
	    point_sing[l] = 1;   
	  
	  spoint += point_sing[l]; 
	}
      
      for(int k=0;k<8;k++)
	{
	  INDEX_2 i2 = INDEX_2 :: Sort(el.pnums[p[eledges[k][0]-1]],
				       el.pnums[p[eledges[k][1]-1]]); 
	  if (edges.Used(i2)) 
	    edge_sing[k] = 2;
	  else 
	    edge_sing[k] = face_edges.Used(i2);
	  
	  sedge += edge_sing[k]; 
	}
  
      for (int k=0;k<5;k++)
	{
	  INDEX_3 i3; 
	  INDEX_4  i4 = INDEX_4(el.pnums[p[elfaces[k][0]-1]], el.pnums[p[elfaces[k][1]-1]], el.pnums[p[elfaces[k][2]-1]],
				el.pnums[p[elfaces[k][3]-1]]); 
	  i4.Sort();
	  i3 = INDEX_3(i4.I1(), i4.I2(), i4.I3()); 
	  
	  if (faces.Used (i3))
	    {
	      
	      int domnr = faces.Get(i3); 
	      if (domnr == -1 || domnr == el.GetIndex())
		face_sing[k] = 1;
	    } 
	  sface +=face_sing[k]; 
	} 
  
      if(!sface && !spoint && !sedge) return(HP_PYRAMID); 
      
      if(!sface && !sedge && point_sing[p[0]] == spoint) 
	type = HP_PYRAMID_0E_1V; 
      
      if(!sface && edge_sing[0] + edge_sing[2] == sedge && 
	 spoint == point_sing[0] + point_sing[1] + point_sing[3]) 
	type = HP_PYRAMID_EDGES; 
      
      if(sface && sface == face_sing[0] && spoint == point_sing[4] + 2)
	type = HP_PYRAMID_1FB_0E_1VA; 
      
      
      if(type != HP_NONE) 
	{ 
	  int pnums[8]; 
	  for(int l=0;l<5;l++) pnums[l] = el[p[l]];
	  for(int l=0;l<5;l++) el[l] = pnums[l];
	  el.type=type; 
	  break; 
	} 
    }
  
  return (type); 
  
}
Exemplo n.º 5
0
HPREF_ELEMENT_TYPE ClassifyHex(HPRefElement & el, INDEX_2_HASHTABLE<int> & edges, INDEX_2_HASHTABLE<int> & edgepoint_dom, 
                               BitArray & cornerpoint, BitArray & edgepoint, INDEX_3_HASHTABLE<int> & faces, INDEX_2_HASHTABLE<int> & face_edges, 
                               INDEX_2_HASHTABLE<int> & surf_edges, Array<int, PointIndex::BASE> & facepoint)
{
  HPREF_ELEMENT_TYPE type = HP_NONE;
  
  // implementation only for HP_HEX_1F_0E_0V
  //                         HP_HEX_1FA_1FB_0E_0V
  //                         HP_HEX 
  // up to now other cases are refine dummies 
  
  // indices of bot,top-faces combinations
  int index[6][2] = {{0,1},{1,0},{2,4},{4,2},{3,5},{5,3}}; 
  int p[8]; 
  const ELEMENT_FACE * elfaces  = MeshTopology::GetFaces (HEX);
  const ELEMENT_EDGE * eledges = MeshTopology::GetEdges (HEX);
  
  for(int m=0;m<6 && type == HP_NONE;m++) 
    for(int j=0;j<4 && type == HP_NONE;j++) 
      { 
	int point_sing[8]={0,0,0,0,0,0,0,0}; 
	int face_sing[6] = {0,0,0,0,0,0};
	int edge_sing[12] = {0,0,0,0,0,0,0,0,0,0,0,0};
	int spoint=0, sface=0, sedge=0; 
	for(int l=0;l<4;l++) 
	  {
	    p[l] = elfaces[index[m][0]][(4-j-l)%4]; 
	    p[l+4] = elfaces[index[m][1]][(j+l)%4];
	  }
	
	for(int l=0;l<8;l++) 
	  if(cornerpoint.Test(el.PNum(p[l])))  
	    { 
	      point_sing[p[l]-1]=3;
	      spoint++; 
	    }
	  else if(edgepoint.Test(el.PNum(p[l]))) point_sing[p[l]-1]=2;
	  else if (facepoint[el.PNum(p[l])] == -1 || facepoint[el.PNum(p[l])] == el.GetIndex())
	    point_sing[p[l]-1] = 1;   
	
	for(int k=0;k<12;k++)
          {
            INDEX_2 i2 = INDEX_2 :: Sort(el.PNum(p[eledges[k][0]-1]),el.PNum(p[eledges[k][1]-1])); 
            if (edges.Used(i2)) 
              { 
                edge_sing[k] = 2;
                sedge++; 
              }
            else edge_sing[k] = face_edges.Used(i2);
          }
	
	for (int k=0;k<6;k++)
          {
            INDEX_3 i3; 
	  
	
            INDEX_4  i4 = INDEX_4(el.pnums[p[elfaces[k][0]-1]-1], el.pnums[p[elfaces[k][1]-1]-1], el.pnums[p[elfaces[k][2]-1]-1],el.pnums[p[elfaces[k][3]-1]-1]); 
            i4.Sort();
            i3 = INDEX_3(i4.I1(), i4.I2(), i4.I3()); 
	  
            if (faces.Used (i3))
              {
	      
                int domnr = faces.Get(i3); 
                if (domnr == -1 || domnr == el.GetIndex())
                  {
                    face_sing[k] = 1;
                    sface++;
                  }
	      
              } 
          } 
	
	if(!sface && !sedge && !spoint) type = HP_HEX; 
	if(!sedge && !spoint) 
	  {
	    if(face_sing[0] && face_sing[2] && sface==2) 
	      type = HP_HEX_1FA_1FB_0E_0V; 
	    if (face_sing[0] && sface==1)  
	      type = HP_HEX_1F_0E_0V; 
	  }
	
	el.type=type; 

	if(type != HP_NONE) 
	  {
	    int pnums[8]; 
	    for(int l=0;l<8;l++) pnums[l] = el[p[l]-1];
	    for(int l=0;l<8;l++) el[l] = pnums[l];
	    /* cout << " HEX with pnums " << pnums[0] << "\t"  << 
               pnums[1] << "\t"  << pnums[2] << "\t"  << pnums[3] << "\t"  << 
               pnums[4] << "\t"  <<  pnums[5] << endl << " of type " << type << endl; */
	    break; 
	  }
      }
  
  return (type); 

}
Exemplo n.º 6
0
  void RefinePrisms (Mesh & mesh, const CSGeometry * geom, 
		     ZRefinementOptions & opt)
  {
    int i, j;
    bool found, change;
    int cnt = 0;


    // markers for z-refinement:  p1, p2, levels  
    // p1-p2 is an edge to be refined
    ARRAY<INDEX_3> ref_uniform;
    ARRAY<INDEX_3> ref_singular;
    ARRAY<INDEX_4 > ref_slices;

    BitArray first_id(geom->identifications.Size());
    first_id.Set();

  
    INDEX_2_HASHTABLE<int> & identpts = 
      mesh.GetIdentifications().GetIdentifiedPoints ();

    if (&identpts)
      {
	for (i = 1; i <= identpts.GetNBags(); i++)
	  for (j = 1; j <= identpts.GetBagSize(i); j++)
	    {
	      INDEX_2 pair;
	      int idnr;
	      identpts.GetData(i, j, pair, idnr);
	      const CloseSurfaceIdentification * csid = 
		dynamic_cast<const CloseSurfaceIdentification*> 
		(geom->identifications.Get(idnr));
	      if (csid)
		{
		  if (!csid->GetSlices().Size())
		    {
		      if (first_id.Test (idnr))
			{
			  first_id.Clear(idnr);
			  ref_uniform.Append (INDEX_3 (pair.I1(), pair.I2(), csid->RefLevels()));
			  ref_singular.Append (INDEX_3 (pair.I1(), pair.I2(), csid->RefLevels1()));
			  ref_singular.Append (INDEX_3 (pair.I2(), pair.I1(), csid->RefLevels2()));
			}
		    }
		  else
		    {   
		      //const ARRAY<double> & slices = csid->GetSlices();
		      INDEX_4 i4;
		      i4[0] = pair.I1();
		      i4[1] = pair.I2();
		      i4[2] = idnr;
		      i4[3] = csid->GetSlices().Size();
		      ref_slices.Append (i4);
		    }
		}
	    }
      }

  
  
    ARRAY<EdgePointGeomInfo> epgi;

    while (1)
      {
	cnt++;
	PrintMessage (3, "Z-Refinement, level = ", cnt);
	INDEX_2_HASHTABLE<int> refedges(mesh.GetNSE()+1);


	found = 0;
	// mark prisms due to close surface flags:
	int oldsize = ref_uniform.Size();
	for (i = 1; i <= oldsize; i++)
	  {
	    int pi1 = ref_uniform.Get(i).I1();
	    int pi2 = ref_uniform.Get(i).I2();
	    int levels = ref_uniform.Get(i).I3();

	    if (levels > 0)
	      {
		const Point3d & p1 = mesh.Point(pi1);
		const Point3d & p2 = mesh.Point(pi2);
		int npi(0);
	      
		INDEX_2 edge(pi1, pi2);
		edge.Sort();
		if (!refedges.Used(edge))
		  {
		    Point3d np = Center (p1, p2);
		    npi = mesh.AddPoint (np);
		    refedges.Set (edge, npi);
		    found = 1;
		  }

		ref_uniform.Elem(i) = INDEX_3(pi1, npi, levels-1);
		ref_uniform.Append (INDEX_3(pi2, npi, levels-1));
	      }
	  }
	for (i = 1; i <= ref_singular.Size(); i++)
	  {
	    int pi1 = ref_singular.Get(i).I1();
	    int pi2 = ref_singular.Get(i).I2();
	    int levels = ref_singular.Get(i).I3();

	    if (levels > 0)
	      {
		const Point3d & p1 = mesh.Point(pi1);
		const Point3d & p2 = mesh.Point(pi2);
		int npi;
	      
		INDEX_2 edge(pi1, pi2);
		edge.Sort();
		if (!refedges.Used(edge))
		  {
		    Point3d np = Center (p1, p2);
		    npi = mesh.AddPoint (np);
		    refedges.Set (edge, npi);
		    found = 1;
		  }
		else
		  npi = refedges.Get (edge);

		ref_singular.Elem(i) = INDEX_3(pi1, npi, levels-1);
	      }
	  }

	for (i = 1; i <= ref_slices.Size(); i++)
	  {
	    int pi1 = ref_slices.Get(i)[0];
	    int pi2 = ref_slices.Get(i)[1];
	    int idnr = ref_slices.Get(i)[2];
	    int slicenr = ref_slices.Get(i)[3];

	    if (slicenr > 0)
	      {
		const Point3d & p1 = mesh.Point(pi1);
		const Point3d & p2 = mesh.Point(pi2);
		int npi;

		const CloseSurfaceIdentification * csid = 
		  dynamic_cast<const CloseSurfaceIdentification*> 
		  (geom->identifications.Get(idnr));

	      
		INDEX_2 edge(pi1, pi2);
		edge.Sort();
		if (!refedges.Used(edge))
		  {
		    const ARRAY<double> & slices = csid->GetSlices();
		    //(*testout) << "idnr " << idnr << " i " << i << endl;
		    //(*testout) << "slices " << slices << endl;
		    double slicefac = slices.Get(slicenr);
		    double slicefaclast = 
		      (slicenr == slices.Size()) ? 1 : slices.Get(slicenr+1);
		    
		    Point3d np = p1 + (slicefac / slicefaclast) * (p2-p1);
		    //(*testout) << "slicenr " << slicenr << " slicefac " << slicefac << " quot " << (slicefac / slicefaclast) << " np " << np << endl;
		    npi = mesh.AddPoint (np);
		    refedges.Set (edge, npi);
		    found = 1;
		  }
		else
		  npi = refedges.Get (edge);
		
		ref_slices.Elem(i)[1] = npi;
		ref_slices.Elem(i)[3] --;
	      }
	  }




	for (i = 1; i <= mesh.GetNE(); i++)
	  {
	    Element & el = mesh.VolumeElement (i);
	    if (el.GetType() != PRISM)
	      continue;

	    for (j = 1; j <= 3; j++)
	      {
		int pi1 = el.PNum(j);
		int pi2 = el.PNum(j+3);
		const Point3d & p1 = mesh.Point(pi1);
		const Point3d & p2 = mesh.Point(pi2);

		bool ref = 0;

		/*
		  if (Dist (p1, p2) > mesh.GetH (Center (p1, p2)))
		  ref = 1;
		*/

		/*
		  if (cnt <= opt.minref)
		  ref = 1;
		*/

		/*
		  if ((pi1 == 460 || pi2 == 460 ||
		  pi1 == 461 || pi2 == 461) && cnt <= 8) ref = 1;
		*/
		if (ref == 1)
		  {
		    INDEX_2 edge(pi1, pi2);
		    edge.Sort();
		    if (!refedges.Used(edge))
		      {
			Point3d np = Center (p1, p2);
			int npi = mesh.AddPoint (np);
			refedges.Set (edge, npi);
			found = 1;
		      }
		  }
	      }
	  }
      
	if (!found) break;

	// build closure:
	PrintMessage (5, "start closure");
	do
	  {
	    PrintMessage (5, "start loop");
	    change = 0;
	    for (i = 1; i <= mesh.GetNE(); i++)
	      {
		Element & el = mesh.VolumeElement (i);
		if (el.GetType() != PRISM)
		  continue;
	      
		bool hasref = 0, hasnonref = 0;
		for (j = 1; j <= 3; j++)
		  {
		    int pi1 = el.PNum(j);
		    int pi2 = el.PNum(j+3);
		    if (pi1 != pi2)
		      {
			INDEX_2 edge(pi1, pi2);
			edge.Sort();
			if (refedges.Used(edge))
			  hasref = 1;
			else 
			  hasnonref = 1;
		      }
		  }

		if (hasref && hasnonref)
		  {
		    //		  cout << "el " << i << " in closure" << endl;
		    change = 1;
		    for (j = 1; j <= 3; j++)
		      {
			int pi1 = el.PNum(j);
			int pi2 = el.PNum(j+3);
			const Point3d & p1 = mesh.Point(pi1);
			const Point3d & p2 = mesh.Point(pi2);
		      
			INDEX_2 edge(pi1, pi2);
			edge.Sort();
			if (!refedges.Used(edge))
			  {
			    Point3d np = Center (p1, p2);
			    int npi = mesh.AddPoint (np);
			    refedges.Set (edge, npi);
			  }
		      }
		  }
	      }
	  }
	while (change);

	PrintMessage (5, "Do segments");

	//      (*testout) << "closure formed, np = " << mesh.GetNP() << endl;

	int oldns = mesh.GetNSeg();

	for (i = 1; i <= oldns; i++)
	  {
	    const Segment & el = mesh.LineSegment(i);

	    INDEX_2 i2(el.p1, el.p2);
	    i2.Sort();
	  
	    int pnew;
	    EdgePointGeomInfo ngi;
      
	    if (refedges.Used(i2))
	      {
		pnew = refedges.Get(i2);
		//	      ngi = epgi.Get(pnew);
	      }
	    else
	      {
		continue;

		// 	      Point3d pb;

		// 	      /*
		// 	      geom->PointBetween (mesh.Point (el.p1),
		// 				  mesh.Point (el.p2),
		// 				  el.surfnr1, el.surfnr2,
		// 				  el.epgeominfo[0], el.epgeominfo[1],
		// 				  pb, ngi);
		// 	      */
		// 	      pb = Center (mesh.Point (el.p1), mesh.Point (el.p2));

		// 	      pnew = mesh.AddPoint (pb);
	      
		// 	      refedges.Set (i2, pnew);
	      
		// 	      if (pnew > epgi.Size())
		// 		epgi.SetSize (pnew);
		// 	      epgi.Elem(pnew) = ngi;
	      }
	  
	    Segment ns1 = el;
	    Segment ns2 = el;
	    ns1.p2 = pnew;
	    ns1.epgeominfo[1] = ngi;
	    ns2.p1 = pnew;
	    ns2.epgeominfo[0] = ngi;

	    mesh.LineSegment(i) = ns1;
	    mesh.AddSegment (ns2);
	  }
      
	PrintMessage (5, "Segments done, NSeg = ", mesh.GetNSeg());

	// do refinement
	int oldne = mesh.GetNE();
	for (i = 1; i <= oldne; i++)
	  {
	    Element & el = mesh.VolumeElement (i);
	    if (el.GetNP() != 6)
	      continue;

	    int npi[3];
	    for (j = 1; j <= 3; j++)
	      {
		int pi1 = el.PNum(j);
		int pi2 = el.PNum(j+3);

		if (pi1 == pi2)
		  npi[j-1] = pi1;
		else
		  {
		    INDEX_2 edge(pi1, pi2);
		    edge.Sort();
		    if (refedges.Used (edge))
		      npi[j-1] = refedges.Get(edge);
		    else
		      {
			/*
			  (*testout) << "ERROR: prism " << i << " has hanging node !!" 
			  << ", edge = " << edge << endl;
			  cerr << "ERROR: prism " << i << " has hanging node !!" << endl;
			*/
			npi[j-1] = 0;
		      }
		  }
	      }

	    if (npi[0])
	      {
		Element nel1(6), nel2(6);
		for (j = 1; j <= 3; j++)
		  {
		    nel1.PNum(j) = el.PNum(j);
		    nel1.PNum(j+3) = npi[j-1];
		    nel2.PNum(j) = npi[j-1];
		    nel2.PNum(j+3) = el.PNum(j+3);
		  }
		nel1.SetIndex (el.GetIndex());
		nel2.SetIndex (el.GetIndex());
		mesh.VolumeElement (i) = nel1;
		mesh.AddVolumeElement (nel2);
	      }
	  }

      
	PrintMessage (5, "Elements done, NE = ", mesh.GetNE());


	// do surface elements
	int oldnse = mesh.GetNSE();
	//      cout << "oldnse = " << oldnse << endl;
	for (i = 1; i <= oldnse; i++)
	  {
	    Element2d & el = mesh.SurfaceElement (i);
	    if (el.GetType() != QUAD)
	      continue;

	    int index = el.GetIndex();
	    int npi[2];
	    for (j = 1; j <= 2; j++)
	      {
		int pi1, pi2;

		if (j == 1)
		  {
		    pi1 = el.PNum(1);
		    pi2 = el.PNum(4);
		  }
		else
		  {
		    pi1 = el.PNum(2);
		    pi2 = el.PNum(3);
		  }

		if (pi1 == pi2)
		  npi[j-1] = pi1;
		else
		  {
		    INDEX_2 edge(pi1, pi2);
		    edge.Sort();
		    if (refedges.Used (edge))
		      npi[j-1] = refedges.Get(edge);
		    else
		      {
			npi[j-1] = 0;
		      }
		  }
	      }

	    if (npi[0])
	      {
		Element2d nel1(QUAD), nel2(QUAD);
		for (j = 1; j <= 4; j++)
		  {
		    nel1.PNum(j) = el.PNum(j);
		    nel2.PNum(j) = el.PNum(j);
		  }
		nel1.PNum(3) = npi[1];
		nel1.PNum(4) = npi[0];
		nel2.PNum(1) = npi[0];
		nel2.PNum(2) = npi[1];
		/*
		  for (j = 1; j <= 2; j++)
		  {
		  nel1.PNum(j) = el.PNum(j);
		  nel1.PNum(j+2) = npi[j-1];
		  nel2.PNum(j) = npi[j-1];
		  nel2.PNum(j+2) = el.PNum(j+2);
		  }
		*/
		nel1.SetIndex (el.GetIndex());
		nel2.SetIndex (el.GetIndex());

		mesh.SurfaceElement (i) = nel1;
		mesh.AddSurfaceElement (nel2);

		int si = mesh.GetFaceDescriptor (index).SurfNr();

		Point<3> hp = mesh.Point(npi[0]);
		geom->GetSurface(si)->Project (hp);
		mesh.Point (npi[0]).SetPoint (hp);

		hp = mesh.Point(npi[1]);
		geom->GetSurface(si)->Project (hp);
		mesh.Point (npi[1]).SetPoint (hp);

		//	      geom->GetSurface(si)->Project (mesh.Point(npi[0]));
		//	      geom->GetSurface(si)->Project (mesh.Point(npi[1]));
	      }
	  }

	PrintMessage (5, "Surface elements done, NSE = ", mesh.GetNSE());

      }
  }