Ejemplo n.º 1
0
bool
Skin::correct_face(Bface* f, bool& changed)
{
   //                                 
   //  BBBBBBBBBBBBBBB                
   //  B            /|                
   //  B          /  |                
   //  B   f    /    |   Change this, where quad face f        
   //  B      /      |   is adjacent to 2 boundary edgees...
   //  B    /        |                
   //  B  /          |                
   //  B/- - - - - - o                
   //                                 
   //  BBBBBBBBBBBBBBB                
   //  B\            |                
   //  B  \          |                
   //  B    \        |  ... to this, where neither face of
   //  B      \      |  the quad is adjacent to more than 1              
   //  B        \    |  boundary edge.              
   //  B          \  |                
   //  B - - - - - - o                
   //                                 

   assert(f);

   // boundary edges have flag == 1, others have flag == 0
   uint n = num_edge_flags_set(f);
   if (n < 2) return true;      // not a problem
   if (n > 2) {
      // unfixable problem
      err_adv(debug, "  can't fix face with %d boundary edges", n);
      return false;
   }

   // 2 boundary edges; get the non-boundary one:
   Bedge* e = boundary_connector(f);
   assert(e);

   // we want to swap it; only possible if it has 2 faces:
   if (e->nfaces() != 2) {
      err_adv(debug, "  can't fix edge with %d faces", e->nfaces());
      return false;
   }

   // swapping won't do any good if its other face has boundary edges too:
   if (!(num_edge_flags_set(e->f1()) == 0 || num_edge_flags_set(e->f2()) == 0)) {
      err_adv(debug, "  unfixable edge found, giving up");
      return false;
   }

   // try to swap it:
   if (e->do_swap()) {
      err_adv(debug, "  swapped edge");
      return changed = true;
   }
   err_adv(debug, "  edge swap failed");
   return false;
}
Ejemplo n.º 2
0
UVpt
LoopUV::centroid(CLvert* v) const
{
   assert(v);

   switch (UVdata::discontinuity_degree(v)) {
    case 0:
    {
       // No discontinuity:
       UVpt ret;
       for (int i=0; i<v->degree(); i++)
          ret += UVdata::get_uv(v->nbr(i), v->e(i)->get_face());
       return ret / v->degree();
    }
    case 2:
    {
       // Find the 2 discontinuity edges and get the uv values of
       // their opposite vertices that agree with the current vertex.
       CUVpt& uv = UVdata::get_uv(v,_face);
       UVpt ret;
       for (int i=0; i<v->degree(); i++) {
          Bedge* e = v->e(i);
          if (!UVdata::is_continuous(e)) {
             if (UVdata::lookup(e->f1()) && UVdata::get_uv(v,e->f1()) == uv)
                ret += UVdata::get_uv(v->nbr(i), e->f1());
             else if (UVdata::lookup(e->f2()) &&
                      UVdata::get_uv(v,e->f2()) == uv)
                ret += UVdata::get_uv(v->nbr(i), e->f2());
             else
                assert(0);
          }
       }
       return ret/2;
    }
    default:
       // Treat as a corner vertex
       return UVdata::get_uv(v, _face);
   }
}
Ejemplo n.º 3
0
int 
SELECT_WIDGET:: slash_cb(CGESTUREptr& gest, DrawState*& s)
{

	
	if (_mode==SEL_FACE) //widget is in face selection mode 
	{
		select_list.clear();

		Bface* f = find_face(gest->start(),0.25,MIN_PIX_AREA);
		// f should be the currently selected face
		if (f && f->is_selected() && f->is_quad())
		{
	
			f=f->quad_rep();

		//line in screen space coresponding to the slash
		PIXELline slash(gest->start(),gest->end());

		Bedge *e1,*e2,*e3,*e4;
		Bedge* edge = 0;
		
		//get and test the quad edges against the stroke line 
		f->get_quad_edges(e1,e2,e3,e4);

		if( e1->pix_line().intersect_segs(slash) )
		{
			edge=e1;
		}
		else
		if( e2->pix_line().intersect_segs(slash) )
		{
			edge=e2;
		}
		else
		if( e3->pix_line().intersect_segs(slash) )
		{
			edge=e3;
		}
		else
		if( e4->pix_line().intersect_segs(slash) )
		{
			edge=e4;
		}
		else
		{
			//error
			cerr << "ERROR no intersection" << endl;
			return 1;
		}
		
			//walk the geometry and select faces

			Bface* fn = f;
			do
			{			
				if (!fn->is_selected())	
					select_list +=fn;
		
				assert(edge);			//I'm paranoid too
				assert(edge->f1()!=edge->f2());

				//grabs the face on the other side of the edge
				//even if we are not directly adjacent to this edge
				fn=fn->other_quad_face(edge);
				
				if (fn) //if a valid face than advance the edge pointer
				{
					assert(edge!=fn->opposite_quad_edge(edge));
					edge = fn->opposite_quad_edge(edge);
	
					fn = fn->quad_rep(); //all faces on the selection list are rep faces

				}
				else
					cerr << "No face on the other side of the edge" << endl;

			} //quit if not a valid face or not a quad
			while(fn&&(fn->is_quad())&&edge&&(fn!=f));


			_mode=SLASH_SEL;  //go into pattern editing mode
			end_face=0;		//prepare the 2nd step data
			pattern=0;
			for (int i=0; i<MAX_PATTERN_SIZE; i++)
				pattern_array[i]=1; //fill the default pattern with ones
		}
		else
			cerr << "This is not a quad" << endl;

	}
	else
		if( _mode==SLASH_SEL)//pattern editing mode
		{ //activates upon second slash motion


			//adds the entire list to the selected group
			//undo deselects the entire group

			Bface_list final_list;

			//copy the face pointers to the final list 
			//using the pattern as a repeating template
			//and stop at the end face
			for (int i = 0; i<(end_face ? (end_face) : select_list.num()) ; i++)
			{
				if (pattern ? pattern_array[(i%pattern)+1] : 1)
				final_list+=select_list[i];
			}

		
		   WORLD::add_command(new MESH_SELECT_CMD(final_list));
		
		   return cancel_cb(gest,s);

		}
		else
			cerr << "wrong mode " << endl;
	return 1;
}