/***************************************************************** * UVdata *****************************************************************/ UVdata::UVdata(Bsimplex* s) : SimplexData(key(), s), _uv_valid(false), _calc_type(SIMPLE_CALC), // default: simple subdiv scheme _did_subdiv(false), _mapping(0) { // The constructor is called (internally) only when the given // simplex does not already have a UVdata associated with it. // // UVdata gets looked-up by its classname. // For face data, slather UVdatas all over the // vertices and edges: if (is_face(s)) { Bface* f = (Bface*)s; get_data(f->v1()); get_data(f->v2()); get_data(f->v3()); get_data(f->e1()); get_data(f->e2()); get_data(f->e3()); // XXX - // If the UVdata is created on a pre-existing face // that has already generated its subdivision // elements, then currently the UVdatas won't be // created on those subdivision elements ... } }
int INFLATE::stroke_cb(CGESTUREptr& gest, DrawState*& s) { err_adv(debug, "INFLATE::stroke_cb"); reset_timeout(); // Verify that we have a starting face if ( _orig_face ) { Bface* face = 0; // Check that the stroke is straight enough to represent a line if (!(gest->straightness() > 0.8)) { err_adv(debug, "INFLATE::stroke_cb: gesture not straight"); return false; } // Check that the gesture starts on the mesh Bsurface::hit_ctrl_surface(gest->start(), 1, &face); if (!(face)) { err_adv(debug, "INFLATE::stroke_cb: can't get hit face"); return false; } // create VEXELs for the gesture and the face normal VEXEL fvec = VEXEL(face->v1()->loc(), face->norm()); VEXEL fgest = gest->endpt_vec(); // If gesture nearly parallel to normal: double a = rad2deg(line_angle(fvec,fgest)); err_adv(debug, "INFLATE::stroke_cb: angle: %f %s", a, (a > 15) ? "(bad)" : "(good)"); if (a > 15) { // Fail if angle is too extreme WORLD::message("Bad angle"); return 0; } // calculate extrude width double dist = fgest.length()/fvec.length(); err_adv(debug, "INFLATE::stroke_cb: strong_edge_len: %f, gest_len: %f, \ fvect_len: %f", avg_strong_edge_len(face), fgest.length(), fvec.length() ); // Convert to relative to local edge length dist /= avg_strong_edge_len(face); if (fvec*fgest<0) dist=-dist; // Get the sign right // Store the new inflate distance _preview_dist = dist; } return 1; // we used up the gesture... }
void visit(OctreeNode* node, double regularity, Bface_list& flist, ARRAY<Wvec>& blist) { if (node->get_leaf()) { if (node->get_disp()) { // subdivision ARRAY<QuadtreeNode*> fs; Bface_list temp; for (int i = 0; i < node->intersects().num(); i++) { Bface* f = node->intersects()[i]; temp += f; fs += new QuadtreeNode(f->v1()->loc(), f->v2()->loc(), f->v3()->loc()); fs.last()->build_quadtree(node, regularity); fs.last()->set_terms(); } // assign weights assign_weights(fs, regularity, node->center()); // pick a triangle int t = pick(fs); // moved below; want to ensure flist and blist stay in sync: // flist += temp[t]; //set node face Bface_list ftemp; ftemp += temp[t]; node->set_face(ftemp); // pick a point int p = pick(fs[t]->terms()); if (p != -1) { Wvec bc; temp[t]->project_barycentric(fs[t]->terms()[p]->urand_pick(), bc); blist += bc; flist += temp[t]; // moved from above node->set_point(bc); } for (int i = 0; i < fs.num(); i++) delete fs[i]; fs.clear(); } } else { for (int i = 0; i < 8; i++) visit(node->get_children()[i], regularity, flist, blist); } }
int INFLATE::line_cb(CGESTUREptr& gest, DrawState*& s) { // Activity occurred to extend the deadline for fading away: reset_timeout(); err_adv(debug, "INFLATE::line_cb"); // Verify that we have a starting face if ( _orig_face ) { // Check that the stroke is straight enough to represent a line Bface* face = 0; if (!(gest->straightness() > 0.8)) { err_adv(debug, "INFLATE::line_cb: gesture not straight"); return false; } // Check that the gesture starts on the mesh Bsurface::hit_ctrl_surface(gest->start(), 1, &face); if (!(face)) { err_adv(debug, "INFLATE::line_cb: can't get hit face"); return false; } // create VEXELs for the gesture and the face normal VEXEL fvec = VEXEL(face->v1()->loc(), face->norm()); VEXEL fgest = gest->endpt_vec(); // If gesture nearly parallel to normal: double a = rad2deg(line_angle(fvec,fgest)); err_adv(debug, "INFLATE::line_cb: angle: %f %s", a, (a > 15) ? "(bad)" : "(good)"); if (a > 15) { return false; } // calculate extrude width double dist = fgest.length()/fvec.length(); if (fvec*fgest<0) dist=-dist; // Get the sign right _preview_dist = dist; } // get here if nothing happened... // don't cancel (which would deactivate the widget), // just return 1 to indicate that we used up the gesture: return 1; }
void OctreeNode::build_octree(int height) { if (_leaf || _height == height) return; int i, j; Wpt_list pts; points(pts); for (i = 0; i < 8; i++) { _children[i] = new OctreeNode((pts[0]+pts[i])/2, (pts[i]+pts[7])/2, _height+1, this); } for (j = 0; j < _intersects.num(); j++) { Bface* f = _intersects[j]; for (i = 0; i < 8; i++) { OctreeNode* n = _children[i]; if (n->contains(f->v1()->loc()) && n->contains(f->v2()->loc()) && n->contains(f->v3()->loc())) { n->intersects() += f; break; } else if (n->overlaps(bface_bbox(f))) { n->intersects() += f; } } } for (i = 0; i < 8; i++) { if (_height+1 == height) { _children[i]->set_leaf(true); _children[i]->set_disp(true); } if (_children[i]->intersects().empty()) { _children[i]->set_leaf(true); _children[i]->set_disp(false); } _children[i]->build_octree(height); } }