Ejemplo n.º 1
0
bool
ContainsPoint(Volume* vol, const vector3& p, TAAPos aaPos)
{
//	iterate over face descriptors of the sides and check whether the point
//	lies inside or outside
	FaceDescriptor fd;
	vector3 n, dir;

//	to minimize rounding errors we'll compare against a small-constant which is
//	relative to the first edge of the examined volume.
	EdgeDescriptor ed;
	vol->edge_desc(0, ed);
	number len = EdgeLength(&ed, aaPos);

	// the constant should be relative to the same geometric measure as what it is
	// compared against later on, i.e. length*area, since otherwise problems arise
	// with geometries scaled to very small extensions;
	// which is why I changed sqrt(lenSq) to lenSq^1.5 (mbreit, 2015-05-11)
	const number locSmall = len * len * len * SMALL;

	for(size_t i = 0; i < vol->num_faces(); ++i){
		vol->face_desc(i, fd);
		CalculateNormalNoNormalize(n, &fd, aaPos);
		VecSubtract(dir, aaPos[fd.vertex(0)], p);

		if(VecDot(dir, n) < -locSmall)
			return false;
	}
	return true;
}
Ejemplo n.º 2
0
////////////////////////////////////////////////////////////////////////
//	GetNeighbours - sreiter
void GetNeighbours(std::vector<Volume*>& vVolsOut, Grid& grid, Volume* v,
					int side, bool clearContainer)
{
	if(clearContainer)
		vVolsOut.clear();

//	if VOLOPT_AUTOGENERATE_FACES and FACEOPT_STORE_ASSOCIATED_VOLUMES are
//	activated, we may use them to find the connected volume quite fast.
	if(grid.option_is_enabled(VOLOPT_AUTOGENERATE_FACES
							| FACEOPT_STORE_ASSOCIATED_VOLUMES))
	{
		Face* f = grid.get_face(v, side);
		Grid::AssociatedVolumeIterator iterEnd = grid.associated_volumes_end(f);
		for(Grid::AssociatedVolumeIterator iter = grid.associated_volumes_begin(f);
			iter != iterEnd; ++iter)
		{
			if(*iter != v)
				vVolsOut.push_back(*iter);
		}

		return;
	}

//	we can't assume that associated faces exist.
//	we have to find the neighbour by hand.
//	mark all vertices of the side
	grid.begin_marking();

	FaceDescriptor fd;
	v->face_desc(side, fd);
	uint numFaceVrts = fd.num_vertices();
	for(uint i = 0; i < numFaceVrts; ++ i)
		grid.mark(fd.vertex(i));

//	iterate over associated volumes of the first vertex and count
//	the number of marked vertices it contains.
	Vertex* vrt = fd.vertex(0);
	Grid::AssociatedVolumeIterator iterEnd = grid.associated_volumes_end(vrt);
	for(Grid::AssociatedVolumeIterator iter = grid.associated_volumes_begin(vrt);
		iter != iterEnd; ++iter)
	{
		Volume* vol = *iter;
		if(vol != v){
			size_t count = 0;
			uint numVrts = vol->num_vertices();
			for(uint i = 0; i < numVrts; ++i){
				if(grid.is_marked(vol->vertex(i)))
					++count;
			}

		//	if the number of marked vertices in vol matches the
		//	number of vertices of the specified side, we consider
		//	the volume to be a neighbout of that side.
			if(count == numFaceVrts)
				vVolsOut.push_back(vol);
		}
	}

	grid.end_marking();
}
Ejemplo n.º 3
0
UG_API 
bool OrientationMatches(FaceVertices* fv, Volume* v)
{
//	find the matching face desc and compare
	FaceDescriptor fd;
	for(size_t iface = 0; iface < v->num_faces(); ++iface){
		v->face_desc(iface, fd);
		if(CompareVertices(fv, &fd)){
		//	check if their orientation matches
		//	find the first vertex of fv in f
			size_t i;
			for(i = 0; i < fd.num_vertices(); ++i)
			{
				if(fd.vertex(i) == fv->vertex(0))
					break;
			}

			if(i < fd.num_vertices())
			{
			//	the first one has been found.
			//	check whether the second vertex of ed is the
			//	same as the next vertex of f
				if(fv->vertex(1) == fd.vertex((i+1) % fd.num_vertices()))
					return true;//	the orientation is the same
			}

		//	the orientation is not the same.
			return false;
		}
	}

//	the orientation is not the same.
	return false;
}
Ejemplo n.º 4
0
////////////////////////////////////////////////////////////////////////
//	MergeVertices
///	merges two vertices and restructures the adjacent elements.
void MergeVertices(Grid& grid, Vertex* v1, Vertex* v2)
{
//	make sure that GRIDOPT_VERTEXCENTRIC_INTERCONNECTION is enabled
    if(grid.num_edges() && (!grid.option_is_enabled(VRTOPT_STORE_ASSOCIATED_EDGES))) {
        LOG("  WARNING in MergeVertices: autoenabling VRTOPT_STORE_ASSOCIATED_EDGES\n");
        grid.enable_options(VRTOPT_STORE_ASSOCIATED_EDGES);
    }
    if(grid.num_faces() && (!grid.option_is_enabled(VRTOPT_STORE_ASSOCIATED_FACES))) {
        LOG("  WARNING in MergeVertices: autoenabling VRTOPT_STORE_ASSOCIATED_FACES\n");
        grid.enable_options(VRTOPT_STORE_ASSOCIATED_FACES);
    }
    if(grid.num_volumes() && (!grid.option_is_enabled(VRTOPT_STORE_ASSOCIATED_VOLUMES))) {
        LOG("  WARNING in MergeVertices: autoenabling VRTOPT_STORE_ASSOCIATED_VOLUMES\n");
        grid.enable_options(VRTOPT_STORE_ASSOCIATED_VOLUMES);
    }


    Edge* conEdge = grid.get_edge(v1, v2);
    if(conEdge) {
        //	perform an edge-collapse on conEdge
        CollapseEdge(grid, conEdge, v1);
    }
    else {
        //	notify the grid, that the two vertices will be merged
        grid.objects_will_be_merged(v1, v1, v2);

        //	we have to check if there are elements that connect the vertices.
        //	We have to delete those.
        EraseConnectingElements(grid, v1, v2);

        //	create new edges for each edge that is connected with v2.
        //	avoid double edges
        if(grid.num_edges() > 0)
        {
            EdgeDescriptor ed;
            Grid::AssociatedEdgeIterator iterEnd = grid.associated_edges_end(v2);
            for(Grid::AssociatedEdgeIterator iter = grid.associated_edges_begin(v2); iter != iterEnd; ++iter)
            {
                Edge* e = *iter;
                if(e->vertex(0) == v2)
                    ed.set_vertices(v1, e->vertex(1));
                else
                    ed.set_vertices(e->vertex(0), v1);

                Edge* existingEdge = grid.get_edge(ed);
                if(!existingEdge)
                    grid.create_by_cloning(e, ed, e);
                else
                    grid.objects_will_be_merged(existingEdge, existingEdge, e);
            }
        }

        //	create new faces for each face that is connected to v2
        //	avoid double faces.
        if(grid.num_faces() > 0)
        {
            FaceDescriptor fd;
            Grid::AssociatedFaceIterator iterEnd = grid.associated_faces_end(v2);
            for(Grid::AssociatedFaceIterator iter = grid.associated_faces_begin(v2); iter != iterEnd; ++iter)
            {
                Face* f = *iter;
                uint numVrts = f->num_vertices();
                fd.set_num_vertices(numVrts);
                for(uint i = 0; i < numVrts; ++i)
                {
                    if(f->vertex(i) == v2)
                        fd.set_vertex(i, v1);
                    else
                        fd.set_vertex(i, f->vertex(i));
                }

                Face* existingFace = grid.get_face(fd);
                if(!existingFace)
                    grid.create_by_cloning(f, fd, f);
                else
                    grid.objects_will_be_merged(existingFace, existingFace, f);
            }
        }

        //	create new volumes for each volume that is connected to v2
        if(grid.num_volumes() > 0)
        {
            VolumeDescriptor vd;
            Grid::AssociatedVolumeIterator iterEnd = grid.associated_volumes_end(v2);
            for(Grid::AssociatedVolumeIterator iter = grid.associated_volumes_begin(v2); iter != iterEnd; ++iter)
            {
                Volume* v = *iter;
                uint numVrts = v->num_vertices();
                vd.set_num_vertices(numVrts);
                for(uint i = 0; i < numVrts; ++i)
                {
                    if(v->vertex(i) == v2)
                        vd.set_vertex(i, v1);
                    else
                        vd.set_vertex(i, v->vertex(i));
                }

                //assert(!"avoid double volumes! implement FindVolume and use it here.");
                grid.create_by_cloning(v, vd, v);
            }
        }

        //	new elements have been created. remove the old ones.
        //	it is sufficient to simply erase v2.
        grid.erase(v2);
    }
}
Ejemplo n.º 5
0
void MinimizeEdgeLength_SwapsOnly(Grid& grid, EdgeIterator edgesBegin,
								  EdgeIterator edgesEnd, TAAPos& aaPos)
{
	using namespace std;

//	helper to collect neighbors
	Face* nbrFaces[2];
	vector<Edge*> edges;

//	flipCandidates
	queue<Edge*> candidates;

//	sadly we can't use marking. Thats why we attach a simple byte to the edges,
//	which will tell whether an edge is already a candidate.
	AByte aIsCandidate;
	grid.attach_to_edges_dv(aIsCandidate, 0, false);
	Grid::AttachmentAccessor<Edge, AByte> aaIsCandidate(grid, aIsCandidate);

//	set up candidate array
	for(EdgeIterator iter = edgesBegin; iter != edgesEnd; ++iter){
		aaIsCandidate[*iter] = 1;
		candidates.push(*iter);
	}


	while(!candidates.empty()){
		Edge* e = candidates.front();
		candidates.pop();
		aaIsCandidate[e] = 0;

	//	we only perform swaps on regular manifolds.
		if(GetAssociatedFaces(nbrFaces, grid, e, 2) == 2){
		//	make sure that both neighbors are triangles
			if(nbrFaces[0]->num_vertices() != 3 || nbrFaces[1]->num_vertices() != 3)
				continue;

		//	check whether a swap would make the edge shorter.
			Vertex* conVrt0 = GetConnectedVertex(e, nbrFaces[0]);
			Vertex* conVrt1 = GetConnectedVertex(e, nbrFaces[1]);
			if(VertexDistanceSq(conVrt0, conVrt1, aaPos) < EdgeLengthSq(e, aaPos))
			{
			//	it'll be shorter
			//	now make sure that associated triangles won't flip
			//todo: add support for 2d position attachments
				vector3 n0, n1;
				CalculateNormal(n0, nbrFaces[0], aaPos);
				CalculateNormal(n1, nbrFaces[1], aaPos);
				number oldDot = VecDot(n0, n1);

				FaceDescriptor ntri;
				ntri.set_num_vertices(3);
				ntri.set_vertex(0, e->vertex(0));
				ntri.set_vertex(1, conVrt1);
				ntri.set_vertex(2, conVrt0);
				CalculateNormal(n0, &ntri, aaPos);

				ntri.set_vertex(0, e->vertex(1));
				ntri.set_vertex(1, conVrt0);
				ntri.set_vertex(2, conVrt1);
				CalculateNormal(n1, &ntri, aaPos);

				number newDot = VecDot(n0, n1);

			//	if both have the same sign, we're fine!
				if(oldDot * newDot < 0){
					continue;//	not fine!
				}

			//	ok - everything is fine. Now swap the edge
				e = SwapEdge(grid,  e);

				UG_ASSERT(e, "SwapEdge did not produce a new edge.");

			//	all edges of associated triangles are candidates again (except e)
				GetAssociatedFaces(nbrFaces, grid, e, 2);
				for(size_t i = 0; i < 2; ++i){
					CollectAssociated(edges, grid, nbrFaces[i]);
					for(size_t j = 0; j < edges.size(); ++j){
						if(edges[j] != e && (!aaIsCandidate[edges[j]])){
							candidates.push(edges[j]);
							aaIsCandidate[edges[j]] = 1;
						}
					}
				}
			}
		}
	}

	grid.detach_from_edges(aIsCandidate);
}
Ejemplo n.º 6
0
HPREF_ELEMENT_TYPE ClassifyTrig(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, int dim, const FaceDescriptor & fd)
{
  HPREF_ELEMENT_TYPE type = HP_NONE; 
  
  int pnums[3]; 
	      
  INDEX_3 i3 (el.pnums[0], el.pnums[1], el.pnums[2]);
  i3.Sort();
  bool sing_face = faces.Used (i3);
   
  
  for (int j = 1; j <= 3; j++)
    {
      int ep1 = edgepoint.Test (el.PNumMod (j));
      int ep2 = edgepoint.Test (el.PNumMod (j+1));
      int ep3 = edgepoint.Test (el.PNumMod (j+2));
      
      if (dim == 2)
	{
	  // JS, Dec 11
	  ep1 = edgepoint_dom.Used (INDEX_2 (fd.SurfNr(), el.PNumMod(j))) ||
	    edgepoint_dom.Used (INDEX_2 (-1, el.PNumMod(j)));
	  ep2 = edgepoint_dom.Used (INDEX_2 (fd.SurfNr(), el.PNumMod(j+1))) ||
	    edgepoint_dom.Used (INDEX_2 (-1, el.PNumMod(j+1)));
	  ep3 = edgepoint_dom.Used (INDEX_2 (fd.SurfNr(), el.PNumMod(j+2))) ||
	    edgepoint_dom.Used (INDEX_2 (-1, el.PNumMod(j+2)));
	  /*
            ep1 = edgepoint_dom.Used (INDEX_2 (el.index, el.PNumMod(j)));
            ep2 = edgepoint_dom.Used (INDEX_2 (el.index, el.PNumMod(j+1)));
            ep3 = edgepoint_dom.Used (INDEX_2 (el.index, el.PNumMod(j+2)));
	  */
	  // ep3 = edgepoint_dom.Used (INDEX_2 (mesh.SurfaceElement(i).GetIndex(), el.PNumMod(j+2)));
	}
      
      
      
      int cp1 = cornerpoint.Test (el.PNumMod (j));
      int cp2 = cornerpoint.Test (el.PNumMod (j+1));
      int cp3 = cornerpoint.Test (el.PNumMod (j+2));
      
      ep1 |= cp1;
      ep2 |= cp2;
      ep3 |= cp3;
      
      
      // (*testout) << "cp = " << cp1 << cp2 << cp3 << ", ep = " << ep1 << ep2 << ep3 << endl;

      int p[3] = { el.PNumMod (j), el.PNumMod (j+1), el.PNumMod (j+2)};
      if(ep1)
	{
	  INDEX_2 i2a=INDEX_2::Sort(p[0], p[1]); 
	  INDEX_2 i2b=INDEX_2::Sort(p[0], p[2]); 
	  if(!edges.Used(i2a) && !edges.Used(i2b)) 
	    cp1 = 1; 
	}
      if(ep2)
	{
	  INDEX_2 i2a=INDEX_2::Sort(p[1], p[0]); 
	  INDEX_2 i2b=INDEX_2::Sort(p[1], p[2]); 
	  if(!edges.Used(i2a) && !edges.Used(i2b)) 
	    cp2 = 1; 
	}
      if(ep3)
	{
	  INDEX_2 i2a=INDEX_2::Sort(p[2], p[0]); 
	  INDEX_2 i2b=INDEX_2::Sort(p[2], p[1]); 
	  if(!edges.Used(i2a) && !edges.Used(i2b)) 
	    cp3= 1; 
	}		      
      
      
      int isedge1=0, isedge2=0, isedge3=0; 
      if(dim == 3 )
	{
	  INDEX_2 i2;
	  i2 = INDEX_2(el.PNumMod (j), el.PNumMod (j+1));
	  isedge1 = edges.Used (i2);
	  i2.Sort();
	  if(surf_edges.Used(i2) &&  surf_edges.Get(i2)   != fd.SurfNr()+1 && 
	     (face_edges.Get(i2) == -1 || face_edges.Get(i2) == fd.DomainIn() || face_edges.Get(i2) == fd.DomainOut()) ) 
	    {
	      isedge1=1;
	      ep1 = 1; ep2=1;
	    }
	  
	  i2 = INDEX_2(el.PNumMod (j+1), el.PNumMod (j+2));
	  isedge2 = edges.Used (i2);
	  i2.Sort();
	  if(surf_edges.Used(i2) &&  surf_edges.Get(i2)   != fd.SurfNr()+1 &&
	     (face_edges.Get(i2) == -1 || face_edges.Get(i2) == fd.DomainIn() || face_edges.Get(i2) == fd.DomainOut()) ) 
	    {
	      isedge2=1;
	      ep2 = 1; ep3=1;
	    }
	  i2 = INDEX_2(el.PNumMod (j+2), el.PNumMod (j+3));
	  isedge3 = edges.Used (i2);
	  i2.Sort();
	  if(surf_edges.Used(i2) &&  surf_edges.Get(i2)   != fd.SurfNr()+1 && 
	     (face_edges.Get(i2) == -1 || face_edges.Get(i2) == fd.DomainIn() || face_edges.Get(i2) == fd.DomainOut()) ) 
	    {
	      isedge3=1;
	      ep1 = 1; ep3=1;
	    }
	  
	  // cout << " isedge " << isedge1 << " \t " << isedge2 << " \t " << isedge3 << endl;  
	
	  if (!sing_face)
            {
              /*
                if (!isedge1)  { cp1 |= ep1; cp2 |= ep2; }
                if (!isedge2)  { cp2 |= ep2; cp3 |= ep3; }
                if (!isedge3)  { cp3 |= ep3; cp1 |= ep1; }
              */
              ep1 |= facepoint [el.PNumMod(j)] != 0;
              ep2 |= facepoint [el.PNumMod(j+1)] != 0;
              ep3 |= facepoint [el.PNumMod(j+2)] != 0;
	  
	  
              isedge1 |= face_edges.Used (INDEX_2::Sort (el.PNumMod(j), el.PNumMod(j+1)));
              isedge2 |= face_edges.Used (INDEX_2::Sort (el.PNumMod(j+1), el.PNumMod(j+2)));
              isedge3 |= face_edges.Used (INDEX_2::Sort (el.PNumMod(j+2), el.PNumMod(j+3)));
            }
	}
      
      if(dim ==2) 
	{ 
	  INDEX_2 i2;
	  i2 = INDEX_2(el.PNumMod (j), el.PNumMod (j+1));
	  i2.Sort();
	  isedge1 = edges.Used (i2);
	  if(isedge1)
	    {
	      ep1 = 1; ep2=1;
	    }
	  
	  i2 = INDEX_2(el.PNumMod (j+1), el.PNumMod (j+2));
	  i2.Sort();
	  isedge2 = edges.Used (i2);
	  if(isedge2)
	    {
	      ep2 = 1; ep3=1;
	    }
	  i2 = INDEX_2(el.PNumMod (j+2), el.PNumMod (j+3));
	  i2.Sort();
	  isedge3 = edges.Used (i2);
	  if(isedge3)
	    {
	      ep1 = 1; ep3=1;
	    }
	  
	  
	}
      
		  
      /*
        cout << " used " << face_edges.Used (INDEX_2::Sort (el.PNumMod(j), el.PNumMod(j+1))) << endl; 

        cout << " isedge " << isedge1 << " \t " << isedge2 << " \t " << isedge3 << endl; 
        cout << " ep " << ep1 << "\t" << ep2 << " \t " << ep3 << endl; 
        cout << " cp " << cp1 << "\t" << cp2 << " \t " << cp3 << endl; 
      */
		  

      
      if (isedge1 + isedge2 + isedge3 == 0)
	{
	  if (!ep1 && !ep2 && !ep3)
	    type = HP_TRIG;
	  
	  if (ep1 && !ep2 && !ep3)
	    type = HP_TRIG_SINGCORNER;
	  
	  if (ep1 && ep2 && !ep3)
	    type = HP_TRIG_SINGCORNER12;
	  
	  if (ep1 && ep2 && ep3)
	    {
	      if (dim == 2)
                type = HP_TRIG_SINGCORNER123_2D;
	      else
		type = HP_TRIG_SINGCORNER123;
	    }
	  
	  if (type != HP_NONE)
	    {
	      pnums[0] = el.PNumMod (j);
	      pnums[1] = el.PNumMod (j+1);
	      pnums[2] = el.PNumMod (j+2);
	      break;
	    }
	}
      
      if (isedge1 && !isedge2 && !isedge3)
	{
	  int code = 0;
	  if (cp1) code += 1;
	  if (cp2) code += 2;
	  if (ep3) code += 4;
	  
	  HPREF_ELEMENT_TYPE types[] =
	    {
	      HP_TRIG_SINGEDGE, 
	      HP_TRIG_SINGEDGECORNER1, 
	      HP_TRIG_SINGEDGECORNER2,
	      HP_TRIG_SINGEDGECORNER12, 
	      HP_TRIG_SINGEDGECORNER3, 
	      HP_TRIG_SINGEDGECORNER13, 
	      HP_TRIG_SINGEDGECORNER23, 
	      HP_TRIG_SINGEDGECORNER123, 
	    };
	  type = types[code];
	  pnums[0] = el.PNumMod (j);
	  pnums[1] = el.PNumMod (j+1);
	  pnums[2] = el.PNumMod (j+2);
	  break;
	}
      
      
      if (isedge1 && !isedge2 && isedge3)
	{
	  if (!cp3)
	    {
	      if (!cp2) type = HP_TRIG_SINGEDGES;
	      else      type = HP_TRIG_SINGEDGES2;
	    }
	  else
	    { 
	      if (!cp2) type = HP_TRIG_SINGEDGES3;
	      else      type = HP_TRIG_SINGEDGES23;
	    }
	  
	  pnums[0] = el.PNumMod (j);
	  pnums[1] = el.PNumMod (j+1);
	  pnums[2] = el.PNumMod (j+2);
	  break;
	}
       
      if (isedge1 && isedge2 && isedge3)
	{
	  type = HP_TRIG_3SINGEDGES;
	  pnums[0] = el.PNumMod (j);
	  pnums[1] = el.PNumMod (j+1);
	  pnums[2] = el.PNumMod (j+2);
	  break;
	}
    }
  
  for(int k=0;k<3;k++) el[k] = pnums[k]; 
  /*if(type != HP_NONE) 
    {
     
    cout << " TRIG with pnums " << pnums[0] << "\t"  << 
    pnums[1] << "\t"  << pnums[2] << endl; 
    cout << " type "  << type << endl; 
    }
  */
  return(type);
}
Ejemplo n.º 7
0
// #ifdef SABINE 
HPREF_ELEMENT_TYPE ClassifyTrig(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, int dim, const FaceDescriptor & fd)

{
  HPREF_ELEMENT_TYPE type = HP_NONE; 
  
  int pnums[3]; 
  int p[3];   
  
  INDEX_3 i3 (el.pnums[0], el.pnums[1], el.pnums[2]);
  i3.Sort();
  bool sing_face = faces.Used (i3);
  
  // *testout << " facepoint " << facepoint << endl;  
      

  // Try all rotations of the trig 
  for (int j=0;j<3;j++) 
    {
      int point_sing[3] = {0,0,0}; 
      int edge_sing[3] = {0,0,0}; 
      // *testout << " actual rotation of trig points " ;  
      for(int m=0;m<3;m++) 
	{ 
	  p[m] = (j+m)%3 +1; // local vertex number
	  pnums[m] = el.PNum(p[m]); // global vertex number 
	  // *testout << pnums[m] << " \t "; 
	}
      // *testout << endl ; 
      
      if(dim == 3) 
	{
	  // face point 
	  for(int k=0;k<3;k++)
	    if(!sing_face)
	      { 
		//	*testout << " fp [" << k << "] = " << facepoint[pnums[k]] << endl;   
		//	*testout << " fd.DomainIn()" <<  fd.DomainIn() << endl; 
		//	*testout  << " fd.DomainOut()" <<  fd.DomainOut() << endl; 
		if( facepoint[pnums[k]]  && (facepoint[pnums[k]] ==-1 || 
					     facepoint[pnums[k]] == fd.DomainIn() ||   facepoint[pnums[k]] == fd.DomainOut()))
		  point_sing[p[k]-1] = 1; 
	      } 
	  // if point is on face_edge in next step sing = 2 

	  /*	  *testout << " pointsing NACH FACEPOints ... FALLS EDGEPOINT UMSETZEN" ; 
            for (int k=0;k<3;k++) *testout << "\t" << point_sing[p[k]-1] ;
            *testout << endl; */
	}
      
      const ELEMENT_EDGE * eledges = MeshTopology::GetEdges(TRIG); 
      
      if(dim==3)
	{
	  for(int k=0;k<3;k++) 
	    { 
	      int ep1=p[eledges[k][0]-1];  
	      int ep2=p[eledges[k][1]-1];  
	      INDEX_2 i2(el.PNum(ep1),el.PNum(ep2)); 
	      
	      if(edges.Used(i2)) 
		{
		  
		  edge_sing[k]=2;
		  point_sing[ep1-1] = 2; 
		  point_sing[ep2-1] = 2; 
		}
	      else // face_edge? 
		{	  
		  i2.Sort();  
		  if(surf_edges.Used(i2) && surf_edges.Get(i2) != fd.SurfNr()+1)  // edge not face_edge acc. to surface in which trig lies
		    if(face_edges.Get(i2)==-1 ||face_edges.Get(i2) == fd.DomainIn() || face_edges.Get(i2) == fd.DomainOut() )
		      { 
			edge_sing[k]=1;
		      } 
		    else
		      { 
			point_sing[ep1-1] = 0; // set to edge_point 
			point_sing[ep2-1] = 0; // set to edge_point
		      } 
		}
	      
	      /*  *testout << " pointsing NACH edges UND FACEEDGES UMSETZEN ... " ; 
                  for (int k=0;k<3;k++) *testout << "\t" << point_sing[p[k]-1] ; 
                  *testout << endl;          
                  */
	    }
	}
      /*
       *testout << " dim " << dim << endl; 
       *testout << " edgepoint_dom " << edgepoint_dom << endl; 
       */
      if(dim==2)
	{
	  for(int k=0;k<3;k++) 
	    { 
	      int ep1=p[eledges[k][0]-1];  
	      int ep2=p[eledges[k][1]-1];  
	     
	      INDEX_2 i2(el.PNum(ep1),el.PNum(ep2));  
	     
	      if(edges.Used(i2)) 
		{
		  
		  if(edgepoint_dom.Used(INDEX_2(fd.SurfNr(),pnums[ep1-1])) || 
		     edgepoint_dom.Used(INDEX_2(-1,pnums[ep1-1])) || 
		     edgepoint_dom.Used(INDEX_2(fd.SurfNr(),pnums[ep2-1])) || 
		     edgepoint_dom.Used(INDEX_2(-1,pnums[ep2-1]))) 
		    {
		      edge_sing[k]=2;
		      point_sing[ep1-1] = 2;
		      point_sing[ep2-1] = 2; 
		    }
		}
	     
	    }
	}

     
	 
      for(int k=0;k<3;k++) 
	if(edgepoint.Test(pnums[k])) //edgepoint, but not member of sing_edge on trig -> cp 
	  {
	    INDEX_2 i2a=INDEX_2::Sort(el.PNum(p[k]), el.PNum(p[(k+1)%3])); 
	    INDEX_2 i2b=INDEX_2::Sort(el.PNum(p[k]), el.PNum(p[(k+2)%3])); 
	    
	    if(!edges.Used(i2a) && !edges.Used(i2b)) 
	      point_sing[p[k]-1] = 3; 	
	  } 
      
      for(int k=0;k<3;k++) 
	if(cornerpoint.Test(el.PNum(p[k]))) 
	  point_sing[p[k]-1] = 3; 
      
      *testout << "point_sing = " << point_sing[0] << point_sing[1] << point_sing[2] << endl;

      if(edge_sing[0] + edge_sing[1] + edge_sing[2] == 0) 
        { 
          int ps = point_sing[0] + point_sing[1] + point_sing[2]; 
	 
          if(ps==0) 
            type = HP_TRIG; 
          else if(point_sing[p[0]-1]  && !point_sing[p[1]-1] && !point_sing[p[2]-1])
            type = HP_TRIG_SINGCORNER;
          else if(point_sing[p[0]-1] && point_sing[p[1]-1] && !point_sing[p[2]-1]) 
            type = HP_TRIG_SINGCORNER12; 
          else if(point_sing[p[0]-1] && point_sing[p[1]-1] && point_sing[p[2]-1]) 
            { 
              if(dim==2) type = HP_TRIG_SINGCORNER123_2D; 
              else type = HP_TRIG_SINGCORNER123; 
            } 
        } 
      else
        if (edge_sing[2] && !edge_sing[0] && !edge_sing[1]) //E[2]=(1,2) 
          { 
            int code = 0; 
            if(point_sing[p[0]-1] > edge_sing[2]) code+=1; 
            if(point_sing[p[1]-1] > edge_sing[2]) code+=2; 
            if(point_sing[p[2]-1]) code+=4; 
	
            HPREF_ELEMENT_TYPE types[] =
              {
                HP_TRIG_SINGEDGE, 
                HP_TRIG_SINGEDGECORNER1, 
                HP_TRIG_SINGEDGECORNER2,
                HP_TRIG_SINGEDGECORNER12, 
                HP_TRIG_SINGEDGECORNER3, 
                HP_TRIG_SINGEDGECORNER13, 
                HP_TRIG_SINGEDGECORNER23, 
                HP_TRIG_SINGEDGECORNER123, 
              };
            type = types[code]; 
	
          }  // E[0] = [0,2], E[1] =[1,2], E[2] = [0,1]
        else 
          if(edge_sing[2] && !edge_sing[1] && edge_sing[0])
            {
              if(point_sing[p[2]-1] <= edge_sing[0] ) 
                { 
                  if(point_sing[p[1]-1]<= edge_sing[2]) type = HP_TRIG_SINGEDGES; 
                  else type = HP_TRIG_SINGEDGES2; 
                } 
              else 
                {
                  if(point_sing[p[1]-1]<= edge_sing[2]) 
                    type = HP_TRIG_SINGEDGES3; 
                  else type = HP_TRIG_SINGEDGES23; 
                }
            }
          else if (edge_sing[2] && edge_sing[1] && edge_sing[0])
            type = HP_TRIG_3SINGEDGES; 
     
      //  cout << " run for " <<  j << " gives type " << type << endl; 
      //*testout << " run for " <<  j << " gives type " << type << endl; 

      if(type!=HP_NONE) break;
    }

  *testout << "type = " << type << endl;
    
  for(int k=0;k<3;k++) el[k] = pnums[k]; 
  /*if(type != HP_NONE) 
    {
     
    cout << " TRIG with pnums " << pnums[0] << "\t"  << 
    pnums[1] << "\t"  << pnums[2] << endl; 
    cout << " type "  << type << endl; 
    }
  */
      return(type);
}
Ejemplo n.º 8
0
HPREF_ELEMENT_TYPE ClassifyQuad(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, int dim, const FaceDescriptor & fd)
{
  HPREF_ELEMENT_TYPE type = HP_NONE; 
  
  int ep1(-1), ep2(-1), ep3(-1), ep4(-1), cp1(-1), cp2(-1), cp3(-1), cp4(-1);
  int isedge1, isedge2, isedge3, isedge4;

  *testout << "edges = " << edges << endl;
  
  for (int j = 1; j <= 4; j++)
    {
      ep1 = edgepoint.Test (el.PNumMod (j));
      ep2 = edgepoint.Test (el.PNumMod (j+1));
      ep3 = edgepoint.Test (el.PNumMod (j+2));
      ep4 = edgepoint.Test (el.PNumMod (j+3));

      if (dim == 2)
        {
          ep1 = edgepoint_dom.Used (INDEX_2 (el.GetIndex(), el.PNumMod(j)));
          ep2 = edgepoint_dom.Used (INDEX_2 (el.GetIndex(), el.PNumMod(j+1)));
          ep3 = edgepoint_dom.Used (INDEX_2 (el.GetIndex(), el.PNumMod(j+2)));
          ep4 = edgepoint_dom.Used (INDEX_2 (el.GetIndex(), el.PNumMod(j+3)));
        }

      cp1 = cornerpoint.Test (el.PNumMod (j));
      cp2 = cornerpoint.Test (el.PNumMod (j+1));
      cp3 = cornerpoint.Test (el.PNumMod (j+2));
      cp4 = cornerpoint.Test (el.PNumMod (j+3));

      ep1 |= cp1;
      ep2 |= cp2;
      ep3 |= cp3;
      ep4 |= cp4;
		
      int p[4] = { el.PNumMod (j), el.PNumMod (j+1), el.PNumMod (j+2), el.PNumMod(j+4)};
      //int epp[4] = { ep1, ep2, ep3, ep4}; 
      int cpp[4] = { cp1, cp2, cp3, cp4};
      for(int k=0;k<0;k++)
        {
          INDEX_2 i2a=INDEX_2::Sort(p[k], p[(k+1)%4]); 
          INDEX_2 i2b=INDEX_2::Sort(p[k], p[(k-1)%4]); 
          if(!edges.Used(i2a) && !edges.Used(i2b)) 
            cpp[k] = 1; 
        }
      cp1= cpp[0]; cp2=cpp[1]; cp3=cpp[2]; cp4=cpp[3];
		  

      if(dim ==3) 
        { 
          INDEX_2 i2;
          i2 = INDEX_2(el.PNumMod (j), el.PNumMod (j+1));
          // i2.Sort();
          isedge1 = edges.Used (i2);
          i2.Sort();
          if(surf_edges.Used(i2)  &&  surf_edges.Get(i2)   != fd.SurfNr()+1 && 
             (face_edges.Get(i2) == -1 || face_edges.Get(i2) == fd.DomainIn() || face_edges.Get(i2) == fd.DomainOut()) ) 
            {
              isedge1=1;
              ep1 = 1; ep2=1;
            }
          i2 = INDEX_2(el.PNumMod (j+1), el.PNumMod (j+2));
          // i2.Sort();
          isedge2 = edges.Used (i2);
          i2.Sort();
          if(surf_edges.Used(i2)  &&  surf_edges.Get(i2)   != fd.SurfNr()+1 && 
             (face_edges.Get(i2) == -1 || face_edges.Get(i2) == fd.DomainIn() || face_edges.Get(i2) == fd.DomainOut()) ) 
            {  
              isedge2=1;
              ep2=1; ep3=1;
            }
          i2 = INDEX_2(el.PNumMod (j+2), el.PNumMod (j+3));
          // i2.Sort();
          isedge3 = edges.Used (i2); 
          i2.Sort();
          if(surf_edges.Used(i2)   &&  surf_edges.Get(i2)   != fd.SurfNr()+1 && (face_edges.Get(i2) == -1 || face_edges.Get(i2) == fd.DomainIn() || face_edges.Get(i2) == fd.DomainOut()) ) 
            {
              isedge3=1;
              ep3=1; ep4=1;
            }
          i2 = INDEX_2(el.PNumMod (j+3), el.PNumMod (j+4));
          // i2.Sort();
          isedge4 = edges.Used (i2);
          i2.Sort();
          if(surf_edges.Used(i2)  &&  surf_edges.Get(i2)   != fd.SurfNr()+1 && 
             (face_edges.Get(i2) == -1 || face_edges.Get(i2) == fd.DomainIn() || face_edges.Get(i2) == fd.DomainOut()) ) 
            { 
              isedge4=1;
              ep4=1; ep1=1;
            } 
		    

          //MH***********************************************************************************************************
          if(ep1)
            if(edgepoint.Test(p[0]))
              {
                INDEX_2 i2a=INDEX_2::Sort(p[0], p[1]); 
                INDEX_2 i2b=INDEX_2::Sort(p[0], p[3]); 
                if(!edges.Used(i2a) && !edges.Used(i2b)) 
                  cp1 = 1; 
              }
          if(ep2)
            if(edgepoint.Test(p[1]))
              {
                INDEX_2 i2a=INDEX_2::Sort(p[0], p[1]); 
                INDEX_2 i2b=INDEX_2::Sort(p[1], p[2]); 
                if(!edges.Used(i2a) && !edges.Used(i2b)) 
                  cp2 = 1; 
              }
          if(ep3)
            if(edgepoint.Test(p[2]))
              {
                INDEX_2 i2a=INDEX_2::Sort(p[2], p[1]); 
                INDEX_2 i2b=INDEX_2::Sort(p[3], p[2]); 
                if(!edges.Used(i2a) && !edges.Used(i2b)) 
                  cp3 = 1; 
              }
          if(ep4)
            if(edgepoint.Test(p[3]))
              {
                INDEX_2 i2a=INDEX_2::Sort(p[0], p[3]); 
                INDEX_2 i2b=INDEX_2::Sort(p[3], p[2]); 
                if(!edges.Used(i2a) && !edges.Used(i2b)) 
                  cp4 = 1; 
              }
          //MH*****************************************************************************************************************************
        }
      else
        { 
          INDEX_2 i2;
          i2 = INDEX_2(el.PNumMod (j), el.PNumMod (j+1));
          i2.Sort();
          isedge1 = edges.Used (i2);
          if(isedge1)
            {
              ep1 = 1; ep2=1;
            }
          i2 = INDEX_2(el.PNumMod (j+1), el.PNumMod (j+2));
          i2.Sort();
          isedge2 = edges.Used (i2);
          if(isedge2)
            {  
              ep2=1; ep3=1;
            }
          i2 = INDEX_2(el.PNumMod (j+2), el.PNumMod (j+3));
          i2.Sort();
          isedge3 = edges.Used (i2); 
		      
          if(isedge3)
            {
              ep3=1; ep4=1;
            }
          i2 = INDEX_2(el.PNumMod (j+3), el.PNumMod (j+4));
          i2.Sort();
          isedge4 = edges.Used (i2);
          if(isedge4)
            { 
              ep4=1; ep1=1;
            } 
        }

      int sumcp = cp1 + cp2 + cp3 + cp4;
      int sumep = ep1 + ep2 + ep3 + ep4;
      int sumedge = isedge1 + isedge2 + isedge3 + isedge4;

      *testout << "isedge = " << isedge1 << isedge2 << isedge3 << isedge4 << endl;
      *testout << "iscp = " << cp1 << cp2 << cp3 << cp4 << endl;
      *testout << "isep = " << ep1 << ep2 << ep3 << ep4 << endl;

      switch (sumedge)
        {
        case 0:
          {
            switch (sumep)
              {
              case 0: 
                type = HP_QUAD; 
                break;
              case 1: 
                if (ep1) type = HP_QUAD_SINGCORNER;
                break; 
              case 2:
                {
                  if (ep1 && ep2) type = HP_QUAD_0E_2VA;
                  if (ep1 && ep3) type = HP_QUAD_0E_2VB;
                  break;
                }
              case 3: 
                if (!ep4) type = HP_QUAD_0E_3V; 
                break; 
              case 4: 
                type = HP_QUAD_0E_4V; 
                break; 
              }
            break;
          }
        case 1:
          {
            if (isedge1)
              {
                switch (cp1+cp2+ep3+ep4)
                  {
                  case 0: 
                    type = HP_QUAD_SINGEDGE; 
                    break;
                  case 1:
                    {
                      if (cp1) type = HP_QUAD_1E_1VA;
                      if (cp2) type = HP_QUAD_1E_1VB;
                      if (ep3) type = HP_QUAD_1E_1VC;
                      if (ep4) type = HP_QUAD_1E_1VD; 
                      break; 
                    }
                  case 2:
                    {
                      if (cp1 && cp2) type = HP_QUAD_1E_2VA; 
                      if (cp1 && ep3) type = HP_QUAD_1E_2VB; 
                      if (cp1 && ep4) type = HP_QUAD_1E_2VC; 
                      if (cp2 && ep3) type = HP_QUAD_1E_2VD; 
                      if (cp2 && ep4) type = HP_QUAD_1E_2VE; 
                      if (ep3 && ep4) type = HP_QUAD_1E_2VF; 
                      break; 
                    }
                  case 3:
                    {
                      if (cp1 && cp2 && ep3) type = HP_QUAD_1E_3VA;
                      if (cp1 && cp2 && ep4) type = HP_QUAD_1E_3VB;
                      if (cp1 && ep3 && ep4) type = HP_QUAD_1E_3VC;
                      if (cp2 && ep3 && ep4) type = HP_QUAD_1E_3VD;
                      break;
                    }
                  case 4:
                    {
                      type = HP_QUAD_1E_4V; 
                      break;
                    }
                  }
              }
            break;
          }
        case 2:
          {
            if (isedge1 && isedge4)
              {
                if (!cp2 && !ep3 && !cp4)
                  type = HP_QUAD_2E;
			  
                if (cp2 && !ep3 && !cp4)
                  type = HP_QUAD_2E_1VA;
                if (!cp2 && ep3 && !cp4)
                  type = HP_QUAD_2E_1VB;
                if (!cp2 && !ep3 && cp4)
                  type = HP_QUAD_2E_1VC;

                if (cp2 && ep3 && !cp4)
                  type = HP_QUAD_2E_2VA;
                if (cp2 && !ep3 && cp4)
                  type = HP_QUAD_2E_2VB;
                if (!cp2 && ep3 && cp4)
                  type = HP_QUAD_2E_2VC;

                if (cp2 && ep3 && cp4)
                  type = HP_QUAD_2E_3V;
              }
            if (isedge1 && isedge3)
              {
                switch (sumcp)
                  {
                  case 0: 
                    type = HP_QUAD_2EB_0V; break;
                  case 1:
                    {
                      if (cp1) type = HP_QUAD_2EB_1VA; 
                      if (cp2) type = HP_QUAD_2EB_1VB; 
                      break;
                    }
                  case 2:
                    {
                      if (cp1 && cp2) { type = HP_QUAD_2EB_2VA; }
                      if (cp1 && cp3) { type = HP_QUAD_2EB_2VB; }
                      if (cp1 && cp4) { type = HP_QUAD_2EB_2VC; }
                      if (cp2 && cp4) { type = HP_QUAD_2EB_2VD; }
                      break;
                    }
                  case 3:
                    {
                      if (cp1 && cp2 && cp3) { type = HP_QUAD_2EB_3VA; }
                      if (cp1 && cp2 && cp4) { type = HP_QUAD_2EB_3VB; }
                      break;
                    }
                  case 4:
                    {
                      type = HP_QUAD_2EB_4V; break;
                    }
                  }
              }
            break;
          }

        case 3:
          {
            if (isedge1 && isedge2 && isedge4)
              {
                if (!cp3 && !cp4) type = HP_QUAD_3E;
                if (cp3 && !cp4) type = HP_QUAD_3E_3VA;
                if (!cp3 && cp4) type = HP_QUAD_3E_3VB;
                if (cp3 && cp4) type = HP_QUAD_3E_4V;
              }
            break;
          }

        case 4:
          {
            type = HP_QUAD_4E;
            break;
          }
        }

      if (type != HP_NONE)
        {
          int pnums[4]; 
          pnums[0] = el.PNumMod (j); 
          pnums[1] = el.PNumMod (j+1);
          pnums[2] = el.PNumMod (j+2); 
          pnums[3] = el.PNumMod (j+3);
          for (int k=0;k<4;k++) el[k] = pnums[k]; 
	
          /*  cout << " QUAD with pnums " << pnums[0] << "\t"  << 
              pnums[1] << "\t"  << pnums[2] << "\t"  << pnums[3] 
              << endl << " of type " << type << endl; */
		   		      
          break;
        }
    }
  if (type == HP_NONE)
    {
      (*testout) << "undefined element" << endl
                 << "cp = " << cp1 << cp2 << cp3 << cp4 << endl
                 << "ep = " << ep1 << ep2 << ep3 << ep4 << endl
                 << "isedge = " << isedge1 << isedge2 << isedge3 
                 << isedge4 << endl;
    }
	    
  *testout << "quad type = " << type << endl;

  return type;  
}	    
Ejemplo n.º 9
0
void MultiGridRefiner::refine()
{
	assert(m_pMG && "refiner not has to be assigned to a multi-grid!");
	if(!m_pMG)
		return;

//	the multi-grid
	MultiGrid& mg = *m_pMG;

//	make sure that the required options are enabled.
	if(!mg.option_is_enabled(GRIDOPT_FULL_INTERCONNECTION))
	{
		LOG("WARNING in MultiGridRefiner::refine(): auto-enabling GRIDOPT_FULL_INTERCONNECTION.\n");
		mg.enable_options(GRIDOPT_FULL_INTERCONNECTION);
	}

//	access position attachments
	Grid::VertexAttachmentAccessor<APosition> aaPos;
	if(mg.has_vertex_attachment(aPosition))
		aaPos.access(mg, aPosition);

//	collect objects for refine
	collect_objects_for_refine();

//	notify derivates that refinement begins
	refinement_step_begins();
	
//	cout << "num marked edges: " << m_selMarks.num<Edge>() << endl;
//	cout << "num marked faces: " << m_selMarks.num<Face>() << endl;

//	we want to add new elements in a new layer.
	bool bHierarchicalInsertionWasEnabled = mg.hierarchical_insertion_enabled();
	if(!bHierarchicalInsertionWasEnabled)
		mg.enable_hierarchical_insertion(true);


//	some buffers
	vector<Vertex*> vVrts;
	vector<Vertex*> vEdgeVrts;
	vector<Edge*>	vEdges;
	vector<Face*>		vFaces;

//	some repeatedly used objects
	EdgeDescriptor ed;
	FaceDescriptor fd;
	VolumeDescriptor vd;

//LOG("creating new vertices\n");
//	create new vertices from marked vertices
	for(VertexIterator iter = m_selMarks.begin<Vertex>();
		iter != m_selMarks.end<Vertex>(); ++iter)
	{
		Vertex* v = *iter;
		if(!mg.get_child_vertex(v))
		{
		//	create a new vertex in the next layer.
			Vertex* nVrt = *mg.create_by_cloning(v, v);

			if(aaPos.valid())
			{
				aaPos[nVrt] = aaPos[v];
			//	change z-coord to visualise the hierarchy
				//aaPos[nVrt].z() += 0.01;
			}
		}
	}

//LOG("creating new edges\n");
//	create new vertices and edges from marked edges
	for(EdgeIterator iter = m_selMarks.begin<Edge>();
		iter != m_selMarks.end<Edge>(); ++iter)
	{
	//	collect_objects_for_refine removed all edges that already were
	//	refined. No need to check that again.
		Edge* e = *iter;
		int rule = get_rule(e);
		switch(rule)
		{
		case RM_COPY:
			{
			//	clone the edge.
				ed.set_vertices(mg.get_child_vertex(e->vertex(0)),
								mg.get_child_vertex(e->vertex(1)));
				Edge* newEdge = *mg.create_by_cloning(e, ed, e);
				set_status(newEdge, SM_COPY);
			}break;

		default:
			{
			//	create two new edges by edge-split
				RegularVertex* nVrt = *mg.create<RegularVertex>(e);
				Vertex* substituteVrts[2];
				substituteVrts[0] = mg.get_child_vertex(e->vertex(0));
				substituteVrts[1] = mg.get_child_vertex(e->vertex(1));

				if(aaPos.valid())
				{
					VecScaleAdd(aaPos[nVrt], 0.5, aaPos[e->vertex(0)],
											0.5, aaPos[e->vertex(1)]);
				//	change z-coord to visualise the hierarchy
					//aaPos[nVrt].z() += 0.01;
				}

			//	split the edge
				e->refine(vEdges, nVrt, substituteVrts);
				assert((vEdges.size() == 2) && "RegularEdge refine produced wrong number of edges.");
				mg.register_element(vEdges[0], e);
				mg.register_element(vEdges[1], e);
				set_status(vEdges[0], SM_REGULAR);
				set_status(vEdges[1], SM_REGULAR);
			}break;
		}
	}

//LOG("creating new faces\n");
//	create new vertices and faces from marked faces
	for(FaceIterator iter = m_selMarks.begin<Face>();
		iter != m_selMarks.end<Face>(); ++iter)
	{
		Face* f = *iter;

		int rule = get_rule(f);
		switch(rule)
		{
		case RM_COPY:
			{
			//	clone the face.
				if(fd.num_vertices() != f->num_vertices())
					fd.set_num_vertices(f->num_vertices());

				for(size_t i = 0; i < fd.num_vertices(); ++i)
					fd.set_vertex(i, mg.get_child_vertex(f->vertex(i)));

				Face* nf = *mg.create_by_cloning(f, fd, f);
				set_status(nf, SM_COPY);
			}break;

		default:
			{
			//	collect child-vertices
				vVrts.clear();
				for(uint j = 0; j < f->num_vertices(); ++j){
					vVrts.push_back(mg.get_child_vertex(f->vertex(j)));
				}

			//	collect the associated edges
				vEdgeVrts.clear();
				//bool bIrregular = false;
				for(uint j = 0; j < f->num_edges(); ++j){
					Vertex* vrt = mg.get_child_vertex(mg.get_edge(f, j));
					vEdgeVrts.push_back(vrt);
					//if(!vrt)
					//	bIrregular = true;
				}
/*
				if(bIrregular){
					assert((get_rule(f) != RM_REFINE) && "Bad refinement-rule set during collect_objects_for_refine!");
		//TODO:	care about anisotropy
					set_rule(f, RM_IRREGULAR);
				}
*/
				Vertex* newVrt;
				if(f->refine(vFaces, &newVrt, &vEdgeVrts.front(), NULL, &vVrts.front())){
				//	if a new vertex was generated, we have to register it
					if(newVrt){
						mg.register_element(newVrt, f);
						if(aaPos.valid()){
							aaPos[newVrt] = CalculateCenter(f, aaPos);
						//	change z-coord to visualise the hierarchy
							//aaPos[newVrt].z() += 0.01;
						}
					}

					int oldRule = get_rule(f);

				//	register the new faces and assign status
					for(size_t j = 0; j < vFaces.size(); ++j){
						mg.register_element(vFaces[j], f);
						switch(oldRule)
						{
						case RM_REFINE:	set_status(vFaces[j], SM_REGULAR); break;
						case RM_IRREGULAR:	set_status(vFaces[j], SM_IRREGULAR); break;
						default:
							assert((oldRule == RM_REFINE) && "rule not yet handled.");//always fails.
							break;
						}
					}
				}
				else{
					LOG("  WARNING in Refine: could not refine face.\n");
				}
			}
		}
	}

//	done - clean up
	if(!bHierarchicalInsertionWasEnabled)
		mg.enable_hierarchical_insertion(false);

	m_selMarks.clear();
	
//	notify derivates that refinement ends
	refinement_step_ends();
}
Ejemplo n.º 10
0
void InsertCenterVertex(Grid& g, Volume* vol, Vertex* vrt, bool eraseOldVol)
{
//	get the sides of the volume and create new elements
	FaceDescriptor fd;
	for(size_t i = 0; i < vol->num_faces(); ++i){
		vol->face_desc(i, fd);
		if(fd.num_vertices() == 3){
		//	create a tetrahedron
			g.create<Tetrahedron>(TetrahedronDescriptor(fd.vertex(2), fd.vertex(1),
														fd.vertex(0), vrt), vol);
		}
		else if(fd.num_vertices() == 4){
		//	create a pyramid
			g.create<Pyramid>(PyramidDescriptor(fd.vertex(3), fd.vertex(2),
												fd.vertex(1), fd.vertex(0), vrt), vol);
		}
		else{
			UG_THROW("Unsupported face type in InsertCenterVertex (#Corners "
					<< fd.num_vertices() << ")");
		}
	}

	if(eraseOldVol)
		g.erase(vol);
}