virtual UVpt get_attrib(CBvert* v, CBface* f) { assert(v&&f); TexCoordGen* tg = f->patch()->tex_coord_gen(); if (tg) return tg->uv_from_vert(v,f); else if (UVdata::lookup(f)) return UVdata::get_uv(v,f); else return UVpt(0.0,0.0); }
Wvec b() const { return _map->dv(UVpt(0,0)); }
Wvec n() const { return _map->norm(UVpt(0,0)); }
Wvec t() const { return _map->du(UVpt(0,0)); }
Wpt o() const { return _map->map(UVpt(0,0)); }
void ProxySurface::create_proxy_surface() { // create it only if needed if (_proxy_mesh || !_patch) { return; } _proxy_mesh = new BMESH; mlib::NDCZpt a_t, c_t; _patch->mesh()->get_bb().ndcz_bounding_box(_patch->obj_to_ndc(),a_t,c_t); // Clamp the min and max to screen a_t[0] = max(a_t[0],-1.0); a_t[1] = max(a_t[1],-1.0); c_t[0] = min(c_t[0], 1.0); c_t[1] = min(c_t[1], 1.0); BBOXpix bb = BBOXpix(PIXEL(a_t), PIXEL(c_t)); double len = max(bb.width(),bb.height()); PIXEL a_p(a_t); XYpt a = XYpt(a_p); XYpt b = XYpt(a_p + VEXEL(len, 0)); XYpt c = XYpt(a_p + VEXEL(len,len)); XYpt d = XYpt(a_p + VEXEL( 0,len)); Wpt cc = VIEW::peek_cam()->data()->center(); // create a quad organized in XY space // first create vertices (XY square in CCW order): _proxy_mesh->add_vertex(Wpt(a, cc)); _proxy_mesh->add_vertex(Wpt(b, cc)); _proxy_mesh->add_vertex(Wpt(c, cc)); _proxy_mesh->add_vertex(Wpt(d, cc)); // now create the quad: Patch* pa = _proxy_mesh->new_patch(); _proxy_mesh->add_quad(0,1,2,3, UVpt(0,0), UVpt(1,0), UVpt(1,1), UVpt(0,1), pa); UVdata::set(_proxy_mesh->bv(0), (UVpt(0,0))); UVdata::set(_proxy_mesh->bv(1), (UVpt(1,0))); UVdata::set(_proxy_mesh->bv(2), (UVpt(1,1))); UVdata::set(_proxy_mesh->bv(3), (UVpt(0,1))); put_vert_grid(UVpt(0,0), _proxy_mesh->bv(0)); put_vert_grid(UVpt(1,0), _proxy_mesh->bv(1)); put_vert_grid(UVpt(1,1), _proxy_mesh->bv(2)); put_vert_grid(UVpt(0,1), _proxy_mesh->bv(3)); _o = _proxy_mesh->bv(0)->pix(); _u_o = _proxy_mesh->bv(1)->pix(); _v_o = _proxy_mesh->bv(3)->pix(); // grow more quads if needed, though it is never needed (yet): while (grow_proxy_surface() > 0) ; // finish up: _proxy_mesh->changed(); }
// 2 // 3|_|1 // 0 Bface* ProxySurface::neighbor_face(int dir, Bface* face) { UVpt base_uv = baseUVpt(face); UVpt uv1, uv2, uv3, uv4; switch (dir) { case 0: uv1 = UVpt(base_uv[0], base_uv[1]); uv2 = UVpt(base_uv[0]+1, base_uv[1]); uv3 = UVpt(base_uv[0], base_uv[1]-1); uv4 = UVpt(base_uv[0]+1, base_uv[1]-1); break; case 1: uv1 = UVpt(base_uv[0]+1, base_uv[1]); uv2 = UVpt(base_uv[0]+2, base_uv[1]); uv3 = UVpt(base_uv[0]+1, base_uv[1]+1); uv4 = UVpt(base_uv[0]+2, base_uv[1]+1); break; case 2: uv1 = UVpt(base_uv[0], base_uv[1]+1); uv2 = UVpt(base_uv[0]+1, base_uv[1]+1); uv3 = UVpt(base_uv[0], base_uv[1]+2); uv4 = UVpt(base_uv[0]+1, base_uv[1]+2); break; case 3: uv1 = UVpt(base_uv[0]-1, base_uv[1]); uv2 = UVpt(base_uv[0], base_uv[1]); uv3 = UVpt(base_uv[0], base_uv[1]+1); uv4 = UVpt(base_uv[0]-1, base_uv[1]+1); break; default: cerr << "ProxySurface::neighbor_face: invalid diraction" << endl; assert(0); } Bvert* v1 = get_vert_grid(uv1); Bvert* v2 = get_vert_grid(uv2); Bvert* v3 = get_vert_grid(uv3); Bvert* v4 = get_vert_grid(uv4); if(!v1 || !v2 || !v3 || !v4) return 0; Bface* n = lookup_quad(v1, v2, v3, v4); assert(n); assert(n->is_quad()); n = (n->is_quad_rep()) ? n : n->quad_partner(); return n; }
void ProxySurface::grow_quad_from_edge(BMESH* m, EdgeStrip* boundary, int i) { // i is the position of the edge in the boundary Bedge* e = boundary->edge(i); assert(e); //make sure is still a boundary edge if not, return... if(e->nfaces() > 1){ return; } Bvert* v2 = boundary->vert(i); Bvert* v1 = boundary->next_vert(i); assert(v1); assert(v2); if(!(UVdata::is_continuous(e))) { cerr << "ProxySurface::grow_quad_from_edge: e is discontinous!!!" << endl; return; } UVpt uv_1, uv_2, uv_3, uv_4; if(!(UVdata::get_uv(v2, uv_2))) { cerr << "ProxySurface::grow_quad_from_edge: v2 vertex does not have UVdata!!!" << endl; return; } if(!(UVdata::get_uv(v1, uv_1))) { cerr << "ProxySurface::grow_quad_from_edge: v1 vertex does not have UVdata!!!" << endl; return; } // constant in u dir -> v line if(uv_1[0] == uv_2[0]){ if(uv_1[1] > uv_2[1]) { uv_3 = UVpt(uv_2[0]+1,uv_2[1]); uv_4 = UVpt(uv_1[0]+1,uv_1[1]); } else { uv_3 = UVpt(uv_2[0]-1,uv_2[1]); uv_4 = UVpt(uv_1[0]-1,uv_1[1]); } } else { assert(uv_1[1] == uv_2[1]); //constant in v dir if(uv_1[0] > uv_2[0]) { uv_3 = UVpt(uv_2[0],uv_2[1]-1); uv_4 = UVpt(uv_1[0],uv_1[1]-1); } else { uv_3 = UVpt(uv_2[0],uv_2[1]+1); uv_4 = UVpt(uv_1[0],uv_1[1]+1); } } // double dist = e->length(); //cerr << "grow quad: " << i << " " << uv_1 << " " << uv_2 << " " << uv_3 << " " << uv_4 << endl; Bvert* v_1 = vertFromUV(uv_1); Bvert* v_2 = vertFromUV(uv_2); Bvert* v_3 = vertFromUV(uv_3); Bvert* v_4 = vertFromUV(uv_4); assert(v_1 && v_2 && v_3 && v_4); //cerr << "grow quad: " << i << " " << v_1->wloc() << " " << v_2->wloc() << " " << v_3->wloc() << " " << v_4->wloc() << endl; m->add_quad(v_1, v_2, v_3, v_4, uv_1, uv_2, uv_3, uv_4, m->patch(0)); UVdata::set(v_1, uv_1); UVdata::set(v_2, uv_2); UVdata::set(v_3, uv_3); UVdata::set(v_4, uv_4); //PixelsData::get_pix(v_1, this); //PixelsData::get_pix(v_2, this); //PixelsData::get_pix(v_3, this); //PixelsData::get_pix(v_4, this); PixelsData::set_pix(v_1, this,v_1->pix()); PixelsData::set_pix(v_2, this,v_2->pix()); PixelsData::set_pix(v_3, this,v_3->pix()); PixelsData::set_pix(v_4, this,v_4->pix()); }