コード例 #1
0
   void send_d(CBvert* v, CBface* f)
   {
	assert(v && f);   
	   
	Bface_list faces = v->get_faces();

	Wvec acc_U(0,0,0);
	Wvec acc_V(0,0,0);

   Wvec U_vec,V_vec;

	UVvec derivative;

   Wvec vertex_normal = v->norm();
   Wvec base_2 = cross(vertex_normal,Wvec(1.0,0.0,0.0)); //use perpend!!
   Wvec base_3 = cross(vertex_normal,base_2);


   base_2 = base_2.normalized();
   base_3 = base_3.normalized();


	   for(int i=0; i<faces.num(); i++)
	   {
         //getting the previously computed face gradients

         UV_grad grad = face_gradient_map[faces[i]];
         
         U_vec = grad.U_grad;
         V_vec = grad.V_grad;



         //rotate to tangent plane

         double U_magnitude = U_vec.length();
         double V_magnitude = V_vec.length();

         U_vec =  Wvec((base_2 * (base_2 * U_vec)) + (base_3 * (base_3 * U_vec)));
         V_vec =  Wvec((base_2 * (base_2 * V_vec)) + (base_3 * (base_3 * V_vec)));

         U_vec = U_vec.normalized() * U_magnitude;
         V_vec = V_vec.normalized() * V_magnitude;

         acc_U += U_vec;
         acc_V += V_vec;

	   }

	   //just simple average for now
	   acc_U = (acc_U / double(faces.num()) );
	   acc_V = (acc_V / double(faces.num()) );

      //cerr << " dV = " << acc_V << endl;

	   send_dU(acc_U);
	   send_dV(acc_V);

   }
コード例 #2
0
ファイル: sps.C プロジェクト: ArnaudGastinel/jot-lib
inline Wpt_list
get_pts(Bface_list& flist, ARRAY<Wvec>& blist)
{
   assert(flist.num() == blist.num());
   Wpt_list pts;
   for (int i = 0; i < flist.num(); i++) {
      Wpt pt;
      flist[i]->bc2pos(blist[i], pt);
      pts += pt;
   }
   return pts;
}
コード例 #3
0
//compute face gradients and store them inside the map
   void compute_face_gradients(Patch* patch)
   {
      if(valid_gradients) return;

      face_gradient_map.clear();

      Bface_list faces = patch->faces();

      UV_grad gradient;
      UVvec derivative;

      for(int i=0; i<faces.num(); i++)
      {
         derivative = att_function->dFdx(faces[i]);

		   gradient.U_grad[0] = derivative[0]; 
		   gradient.V_grad[0] = derivative[1]; 

		   derivative = att_function->dFdy(faces[i]);

		   gradient.U_grad[1] = derivative[0]; 
		   gradient.V_grad[1] = derivative[1]; 

		   derivative = att_function->dFdz(faces[i]);

		   gradient.U_grad[2] = derivative[0]; 
		   gradient.V_grad[2] = derivative[1]; 
         
         face_gradient_map[faces[i]]= gradient; //uses the face pointer as a key

      }

      valid_gradients = true;
   }
コード例 #4
0
ファイル: uv_data.C プロジェクト: ArnaudGastinel/jot-lib
void
UVdata::split(Bvert* v)
{
   if (!v) return;

   UVdata* uvd = lookup(v);
   if (uvd && uvd->_uv_valid) {
      // If uvd->_uv_valid is true, we must set it to false
      // and then push the old uv coord onto all the
      // neighboring faces.
      Bface_list faces = v->get_all_faces();
      for (int i=0; i<faces.num(); i++) {
         if (lookup(faces[i]) == NULL) {
            if (debug) {
               err_msg("UVdata::split: continous vert next to non-uv face!");
               GtexUtil::show_tris(Bface_list(faces[i]));
               WORLD::show(v->loc(), 6, Color::red);
            }
            continue;
         }
//         get_data(faces[i]);
         assert(lookup(faces[i]) != NULL); // must be, right?
         faces[i]->tex_coord(v) = uvd->_uv;
      }
      uvd->_uv_valid = false;
   }
}
コード例 #5
0
ファイル: skin.C プロジェクト: ArnaudGastinel/jot-lib
Skin::Skin(
   Skin* parent,
   CBface_list& skel_faces,
   MULTI_CMDptr cmd) :
   _skel_faces(skel_faces),
   _updater(0),
   _partner(0),
   _reverse(false)
{
   _inflate = parent->_inflate;
   err_adv(debug, "Skin::Skin: (child)");

   assert(parent && parent->_res_level > 0);

   set_name(parent->name());

   _reverse = parent->_reverse;

//   assert(!_skel_faces.has_any_secondary());

   // Update parent mesh elements to our level.
   // This also ensures the child patch is created and filled.
   LMESH::update_subdivision(parent->skin_faces(), 1);
   err_adv(debug, "  updated subdivision at parent");

   // Bsurface method: record parent/child relationship mutually.
   //   set _parent   = parent and parent->_child = this.
   //   set Patch     = child of parent's Patch.
   //   set mesh      = child of parent's mesh.
   //   set res level = parent res level - 1.
   set_parent(parent);
   err_adv(debug, "  set parent");

   // Set up our vert mapper, based on the parent:
   _mapper = subdiv_mapper(parent->_mapper);
   if (_mapper.is_valid())
      err_adv(debug, "  set mapper");
   else
      err_adv(debug, "  failed to get subdiv mapper");

   // Generate verts, edges, faces of the new skin.
   // But if any already exist, it does not duplicate them.
   // Also add memes as needed.
   gen_faces(); 
   err_adv(debug, "  generated elements");

   Bface_list extras = skin_faces().minus(_mapper.a_to_b(_skel_faces));
   if (debug && !extras.empty()) {
      cerr << "found "
           << extras.num()
           << " unexpected faces" << endl;
      push(extras, cmd);
   }
   // finish up: create child or join to skeleton:
   finish_ctor(cmd);
}
コード例 #6
0
ファイル: inflate.C プロジェクト: ArnaudGastinel/jot-lib
//! Given the starting face "orig_face" and an offset amount "dist",
//! determine the appropriate edit level, re-map orig_face to that
//! level, and "inflate" the portion of the mesh reachable from
//! orig_face by amount dist. The offset may be made relative to the
//! local edge length.
bool
INFLATE::do_inflate(
   Bface*               orig_face,
   double               dist,
   Bsurface*&           output,
   Bface_list*&         reversed_faces,
   MULTI_CMDptr         cmd)
{

   // Reject garbage
   if (fabs(dist) < epsAbsMath()) {
      err_adv(debug, "INFLATE::do_inflate: bad offset distance: %f", dist);
      return 0;
   }

   // Throw out trash
   if (!get_lmesh(orig_face)) {
      err_adv(debug, "INFLATE::do_inflate: error: bad face");
      return 0;
   }
   Lface* face = (Lface*)orig_face;

   err_adv(debug, "INFLATE::do_inflate: face at level %d", subdiv_level(face));

   // Decide which level to do inflation -- should match offset dist

   int rel_level = 0;
   // XXX - it may not be a good idea
   //if (!choose_level(face, dist, rel_level))    // defined above
   //   return 0;

   // Remap face to chosen level
   face = remap(face, rel_level);
   if (!face) {
      err_adv(debug, "INFLATE::do_inflate: can't remap %d from level %d",
              rel_level, subdiv_level(face));
      return 0;
   }
   assert(face && face->mesh());
   err_adv(debug, "chosen edit level: %d", subdiv_level(face));

   // Get set of reachable faces:
   Bface_list set = Bface_list::reachable_faces(face);
   assert(set.mesh() != NULL);
   err_adv(debug, "reachable faces: %d, subdiv level: %d, total faces: %d",
           set.num(), set.mesh()->subdiv_level(), set.mesh()->nfaces());

   if (!set.is_consistently_oriented()) {
      err_msg("INFLATE::do_inflate: rejecting inconsistently \
              oriented surface...");
      return 0;
   }
コード例 #7
0
ファイル: lmesh.C プロジェクト: ArnaudGastinel/jot-lib
Bvert_list
LMESH::get_subdiv_inputs(CBvert_list& verts)
{
   static bool debug = Config::get_var_bool("DEBUG_LMESH_SUBDIV_INPUTS",false);

   // Given a set of vertices from the same LMESH, return
   // the vertices of the parent LMESH that affect the
   // subdivision locations of the given vertices.

   // Require verts share common LMESH
   // XXX - could relax this, provided we test each Bvert
   //       to ensure it is really an Lvert.
   if (!isa(verts.mesh()))
      return Bvert_list();

   // Get direct parent vertices and edges
   Bvert_list vp;       // vertex parents
   Bedge_list ep;       // edge parents
   get_parents(verts, vp, ep);

   err_adv(debug, "%d verts: parents: %d verts, %d edges",
           verts.num(), vp.num(), ep.num());

   // Clear flags of all adjacent faces
   clear_face_flags(vp);
   ep.clear_flag02();

   // Put all adjacent faces into a list
   Bface_list faces = get_q_faces(vp);
   err_adv(debug, "parent faces from verts: %d", faces.num());
   try_append(faces, ep.get_primary_faces());
   err_adv(debug, "parent faces from edges too: %d", faces.num());

   // Pull out the vertices:
   return faces.get_verts();
}
コード例 #8
0
bool
SELECT_WIDGET::select_faces(CPIXEL_list& pts)
{
   err_adv(debug, "SELECT_WIDGET::select_faces:");

   if (pts.num() < 2) {
      err_adv(debug, "  too few points: %d", pts.num());
      return false;
   }

   Bface* f = find_face(pts[0], 0.25, MIN_PIX_AREA);
   if (!(f && f->is_selected())) {
      err_adv(debug, "  bad starter face");
      return false;
   }
   
//    // XXX - Old code (to be deleted).  Selects faces individually instead of as
//    // a group:
//    for (int i=0; i<pts.num(); i++)
//       try_select_face(pts[i], 0.1);

   Bface_list flist;

   for(int i = 0; i < pts.num(); ++i){
      
      f = find_face(pts[i], 0.1, MIN_PIX_AREA);
      if (!f || f->is_selected())
         continue;
      flist += f;
      
   }
   
   if(flist.num() > 0){
      
      WORLD::add_command(new MESH_SELECT_CMD(flist));
      err_adv(debug, "  succeeded");
      return true;
      
   }
   
   err_adv(debug, "  no faces selected");
   return false;
   
}
コード例 #9
0
ファイル: inflate.C プロジェクト: ArnaudGastinel/jot-lib
//! Given boundary curve (near-planar), activate the
//! widget to inflate ...
bool
INFLATE::setup(Bface *bf, double dist, double dur)
{

   reset();

   // Given the starting face f and an offset amount h,
   // determine the appropriate edit level, re-map f to that
   // level, and "inflate" the portion of the mesh reachable
   // from f by h, relative to the local edge length.

   // reject garbage
   if (!(bf && LMESH::isa(bf->mesh()))) {
      err_adv(debug, "INFLATE::setup: error: bad face");
      return 0;
   }
   Lface* f = (Lface*)bf;

   err_adv(debug, "setup: face at level %d", bf->mesh()->subdiv_level());

   // get avg edge length of edges in face:
   double avg_len = avg_strong_edge_len(f);
   if (avg_len < epsAbsMath()) {
      err_adv(debug, "INFLATE::setup: bad average edge length: %f", avg_len);
      return 0;
   }


   // Get set of reachable faces:
   Bface_list set
      = Bface_list::reachable_faces(f);
   assert(set.mesh() != NULL);
   err_adv(debug, "reachable faces: %d, subdiv level: %d, total faces: %d",
           set.num(), set.mesh()->subdiv_level(), set.mesh()->nfaces());

   // given face set should be an entire connected piece.
   if (!is_maximal_connected(set
          )) {
      err_adv(debug, "INFLATE::setup: rejecting subset of surface...");
      return 0;
   }

   Bface_list p = set;//get_top_level(set);
   assert(LMESH::isa(p.mesh()));
   err_adv(debug, "top level: %d faces (out of %d)",
           p.num(), p.mesh()->nfaces());

   BMESH* m = p.mesh();
   if (!m) {
      err_adv(debug, "INFLATE::setup: Error: null mesh");
      return 0;
   }
   if (!LMESH::isa(m)) {
      err_adv(debug, "INFLATE::setup: Error: non-LMESH");
      return 0;
   }
   if (!p.is_consistently_oriented()) {
      err_adv(debug, "INFLATE::setup: Error: inconsistently oriented faces");
      return 0;
   }

   // We ensured the mesh in an LMESH so this is okay:
   _boundary=p.get_boundary();

   if (_boundary.edges().empty()) {
      err_adv(debug, "INFLATE::setup: Error: No boundary. Quitting.");
      _boundary.reset();
      return 0;
   }

   // ******** From here on, we accept it ********

   err_adv(debug, "Inflating... %d boundary loops",
           _boundary.num_line_strips());

   _faces = p;
   _mode = false;
   _d     = _boundary.cur_edges().avg_len();
   _mesh  = (LMESH*)m;
   _orig_face = bf;
   _preview_dist = dist;

   // Set the timeout duration
   set_timeout(dur);

   // Become the active widget and get in the world's DRAWN list:
   activate();

   return true;
}
コード例 #10
0
ファイル: sps.C プロジェクト: ArnaudGastinel/jot-lib
void 
remove_nodes(Bface_list& flist, ARRAY<Wvec>& blist, double min_dist, ARRAY<OctreeNode*>& t)
{
//    if (flist.num() != blist.num()) {
//       return;
//    }
   assert(flist.num() == blist.num());
   Wpt_list pts = get_pts(flist, blist);
   ARRAY< ARRAY<int> > N;
   ARRAY<bool> to_remove;
   for (int i = 0; i < pts.num(); i++) {
      N += ARRAY<int>();
      to_remove += false;
   }

   for (int i = 0; i < pts.num(); i++) {
      for (int j = 0; j < t[i]->neibors().num(); j++) {
         int index = t[i]->neibors()[j]->get_term_index();
         
         if (index < pts.num())
         {
            if (pts[i].dist(pts[index]) < min_dist) {
               N[i] += index;
               N[index] += i;
            }
         }
         else
         {
            //cerr << "Sps Warning, index > pts.num()" << endl;
         }

      }
   }

   priority_queue< Priority, vector<Priority> > queue;
   ARRAY<int> versions;
   for (int i = 0; i < pts.num(); i++) {
      if (!to_remove[i] && !N[i].empty()) {
         Priority p;
         p._priority = center(pts, N[i]).dist(pts[i]);
         p._index = i;
         p._version = 0;
         queue.push(p);
      }
      versions += 0;
   }

   while (!queue.empty()) {
      Priority p = queue.top();
      queue.pop();
      int r = p._index;
      if (p._version == versions[r]) {
         to_remove[r] = true;
         for (int i = 0; i < N[r].num(); i++) {
            N[N[r][i]] -= r;
            versions[N[r][i]]++;
            if (!N[N[r][i]].empty()) {
               Priority q;
               q._priority = center(pts, N[N[r][i]]).dist(pts[N[r][i]]);
               q._index = N[r][i];
               q._version = versions[N[r][i]];
               queue.push(q);
            }
         }
      }
   }
   versions.clear();

   Bface_list ftemp(flist);
   ARRAY<Wvec> btemp(blist);
   flist.clear();
   blist.clear();
   for (int i = 0; i < ftemp.num(); i++)
      if (!to_remove[i]) {
         flist += ftemp[i];
         blist += btemp[i];
      }
}
コード例 #11
0
void 
ProxySurface::trim_proxy_surface()
{
   assert(_proxy_mesh);

   int n = 0; //number of faces outside the bounding box   
   //get all the quads
   Bface_list faces = _proxy_mesh->faces();
   //clear out all the markings
   for(int i=0; i < faces.num(); ++i)
   {
      if(faces[i])
         ProxyData::set_mark(faces[i],this, false);
      //else
      //   cerr << "FACE is NULL" << endl;
   }
   //mark all the faces that do not overap bounding box
   for(int i=0; i < faces.num(); ++i)
   {
      if(faces[i]){
         bool t1 = (is_inside_bounding_box(faces[i]->e1())) ? true : false;
         bool t2 = (is_inside_bounding_box(faces[i]->e2())) ? true : false;
         bool t3 = (is_inside_bounding_box(faces[i]->e3())) ? true : false;
         
         // If all the edges are outside, then mark the face
         if(!t1 && !t2 && !t3){
            //cerr << "we can delete this face" << endl;
            ProxyData::set_mark(faces[i], this, true);
            n++;
         }
      }else {
         //cerr << "FACE is NULL" << endl;
      }
   }

   if(n < 1)
      return; 

   //for all verts check to see if all the faces that it is attached to has a marked
   Bvert_list verts = _proxy_mesh->verts();
   for(int i=0; i < verts.num(); ++i)
   {
      ARRAY<Bface*> ret;
      verts[i]->get_quad_faces(ret);
      // Make sure that all adjasent faces need to be deleted
      bool do_it=true;
      for(int k=0; k < ret.num(); ++k)
      {
         if(ret[k]){
            assert(ret[k]->is_quad());            
            if(!ProxyData::get_mark(ret[k], this) || !ProxyData::get_mark(ret[k]->quad_partner(), this))
            {
              // cerr << "vert degree " << verts[i]->p_degree() << endl;
               do_it = false;
               break;
            }
         }
      }
      if(do_it){
         UVpt remove_uv;
         UVdata::get_uv(verts[i], remove_uv);
         remove_vert_grid(remove_uv);

         _proxy_mesh->remove_vertex(verts[i]);
         _proxy_mesh->changed();
      }
   }
   //clean up faces
   Bface_list faces2 = _proxy_mesh->faces();
   for(int i=0; i < faces2.num(); ++i)
   {
      if(!(faces2[i]->is_quad()) || !(faces2[i]->quad_partner())){
         _proxy_mesh->remove_face(faces2[i]);
         _proxy_mesh->changed();
      }
      
   }

   //debug_grid();

   
}
コード例 #12
0
ファイル: skin.C プロジェクト: ArnaudGastinel/jot-lib
Skin* 
Skin::create_multi_sleeve(
   Bface_list interior,         // interior skeleton surface
   VertMapper skel_map,         // tells how some skel verts are identified
   MULTI_CMDptr cmd)
{
   err_adv(debug, "Skin::create_multi_sleeve");

   //assert(!has_secondary_any_level(interior));
   assert(cmd != 0);

   if (!skel_map.is_valid()) {
      err_msg("Skin::create_multi_sleeve: invalid skel map");
      return 0;
   }

   Bface_list exterior       = interior.exterior_faces();
   Bface_list all_skel_faces = interior + exterior;

   // need an LMESH that contains all faces
   LMESH* mesh = LMESH::upcast(all_skel_faces.mesh());
   if (!mesh) {
      err_adv(debug, "  bad skel mesh");
      return 0;
   }

   // Get relative refinement level
   int R = max_subdiv_edit_level(all_skel_faces, interior);

   err_adv(debug, "  skel region res level: %d", R);

   LMESH* ctrl = mesh->control_mesh();
   int old_lev = ctrl->cur_level();
   int ref_lev = mesh->subdiv_level() + R;
   ctrl->update_subdivision(ref_lev);
   if (ref_lev < old_lev)
      ctrl->update_subdivision(old_lev);

   Skin* cur = new Skin(mesh, exterior, skel_map, R, false, "sleeve", cmd);
   cur->set_all_sticky();
   cur->freeze(cur->skin_faces().get_boundary().edges().get_verts());
   for (int k=1; k<=R; k++) {
      
      err_adv(debug, "  top of loop: k = %d", k);

      // XXX - temporary
      if (!check(interior.mesh()->faces()))
         return cur;

      // Update the skeleton to the next level
      LMESH::update_subdivision(interior + exterior, 1);

      // Map skel faces to next level. Avoid new holes.
      // Take account of new regions that don't exist at
      // previous level.

      err_adv(debug, "  getting interior subdiv faces");
      int n = interior.num();
      interior = get_subdiv_faces(interior, 1); // no holes can form here
      if (4*n != interior.num()) {
         err_adv(debug, "  *** ERROR *** got %d interior subdiv faces from %d",
                 interior.num(), n);
      }

      err_adv(debug, "  getting skel subdiv faces");
      n = cur->skel_faces().num();
      exterior = get_subdiv_faces(cur->skel_faces(), 1);
      if (4*n != exterior.num()) {
         err_adv(debug, "  *** ERROR *** got %d exterior subdiv faces from %d",
                 exterior.num(), n);
      }

      // check for holes:
      if (exterior.has_any_secondary()) {
         err_adv(debug, "  removing secondary skel faces at level %d", k);
         exterior = exterior.primary_faces(); // remove holes
      }

      // check for new regions:
      err_adv(debug, "  checking for new faces");
      Bface_list new_faces = interior.two_ring_faces().minus(interior + exterior);
      assert(new_faces.is_all_primary()); // must be true (we think)
      if (!new_faces.empty()) {
         err_adv(debug, "  adding %d new faces at level %d",
                 new_faces.num(), k);
         exterior.append(new_faces);
      }

      // get version of skel_map at new level:
      cur = new Skin(cur, exterior, cmd);

      // make the ones on or near the boundary "sticky"
      cur->set_all_sticky(false);
      cur->set_sticky(
         cur->skin_faces().
         get_boundary().
         edges().
         get_verts().
         one_ring_faces().
         get_verts()
         );
      cur->freeze(cur->skin_faces().get_boundary().edges().get_verts());

      // put memes in place, not just use position they inherited
      // from subdivision
      cur->do_update();
   }

   // Join skin to skel at level R
   err_adv(debug, "  joining to skel...");
   if (cur->join_to_skel(interior, cmd)) {
      err_adv(debug, "  ...succeeded");
   } else {
      err_adv(debug, "  ...failed");
   }

   _debug_instance = cur;
   return upcast(cur->control());
}
コード例 #13
0
ファイル: uv_data.C プロジェクト: ArnaudGastinel/jot-lib
bool
UVdata::handle_subdiv_calc()
{
   // Some of you may have been wondering why anyone would
   // need UVdata on an edge. The whole reason is to pick up
   // this here callback, which is generated when it is time
   // to recompute subdivision values for an edge or vertex.
   // (I.e., this is also why you need UVdata on a vertex).
   //
   // XXX - Currently we aren't keeping track of when
   //       subdivision uv-coords need to be recomputed. We
   //       just get this callback whenever subdivision
   //       *locations* need to be recomputed. So the wrong
   //       thing happens if you change the uv-coords of the
   //       control mesh but not the vertex locations or
   //       connectivity. And if you change the vertex
   //       locations but not the uv-coords the latter get
   //       recomputed even though they don't need to be.

   // XXX - even worser: working on a deadline, we're changing
   //  mesh connectivity at arbitrary subdivision levels
   //  (not previously done), and that's leading to an assertion
   //  failure in subdiv_uv(Bedge*, Bface*) below...
   //  needs to get fixed (later)
   //   lem - 1/6/2002
//   return 0;

   // Don't compute it more than once.  Current policy is uv
   // coords are assigned but not later edited or changed ever.
   // Why? Because with mesh connectivity edits happening at
   // arbitrary levels of subdivision, we don't want parent
   // elements forcing inappropriate uv values on elements at
   // current level. -- lem 12/29/2004; same deadline :(
   if (_did_subdiv) {
//      return false;
   }
   _did_subdiv = true;

   if (is_edge(simplex())) {
      Ledge* e = (Ledge*) simplex();

      if ( !e->get_face() )
         return false;

      if (is_continuous(e)) {
         // Set a single uv-coord on the subdivision vertex
         // to be used regardless of the face containing it.
         _set(e->subdiv_vertex(), subdiv_uv(e, e->get_face()));
      } else {
         // Compute 2 separate subdiv uv-coords, set each one
         // on the 3 sub-faces on each side of the edge.
         // (If a face is missing or has no uv-coords it's a no-op).
         set_subdiv_uv(e, (Lface*)e->f1());
         set_subdiv_uv(e, (Lface*)e->f2());
      }
   } else if (is_vert(simplex())) {
      Lvert* v = (Lvert*) simplex();

      if ( !v->get_face() )
         return false;

      if (is_continuous(v)) {
         // Set a single uv-coord on the subdivision vertex
         // to be used regardless of the face containing it.
         _set(v->subdiv_vertex(), subdiv_uv(v, v->get_face()));
      } else {
         // Compute and set a separate uv-coord for each face
         // surrounding the subdiv vert:
         Bface_list faces;
         v->get_faces(faces);
         for (int i=0; i<faces.num(); i++)
            set_subdiv_uv(v, (Lface*)faces[i]);
      }
   } else {
      // We get here if this UVdata is on a Bface or a null simplex.
      // Neither should ever happen.
      assert(0);
   }

   // Returning 0 means we are not overriding the normal
   // subdivision calculation.
   return 0;
}