inline BBOX bface_bbox(Bface* face) { BBOX ret = BBOX(); ret.update(face->v1()->loc()); ret.update(face->v2()->loc()); ret.update(face->v3()->loc()); return ret; }
inline BBOX bface_bbox(QuadtreeNode* face) { BBOX ret = BBOX(); ret.update(face->v1()); ret.update(face->v2()); ret.update(face->v3()); return ret; }
bool LeafIterator::hasNext(int32_t max) { int i = 20; while (index < num_indices && ! region->contains(*ps, indices[index]) && i --> 0) index++; while (index < num_indices && ! region->contains(*ps, indices[index]) && ps->rank[index] < max) index++; return index < num_indices; }
bool MeshModel::updateMeshInfo() { if (getNumVertices() == 0) { printf("Loaded mesh has no vertices!\n"); return false; } if (getNumFaces() == 0) { printf("Loaded mesh has no faces!\n"); return false; } BBOX b = getActualBBox(); width = b.width(); height = b.height(); center = b.center(); std::map< int , std::map<int,int> > edgeCount; std::set<Vertex> normalVertices; for (auto iter = faces->begin() ; iter != faces->end() ; iter++) { int a = iter->a(); int b = iter->b(); int c = iter->c(); edgeCount[a][b]++; edgeCount[b][a]++; edgeCount[a][c]++; edgeCount[c][a]++; edgeCount[c][b]++; edgeCount[b][c]++; normalVertices.insert(a); normalVertices.insert(b); normalVertices.insert(c); } if (normalVertices.size() != getNumVertices()) { printf("Mesh has standalone vertices, aborting\n"); return false; } for (auto iter = faces->begin() ; iter != faces->end() ; iter++) { int a = iter->a(); int b = iter->b(); int c = iter->c(); if (edgeCount[a][b] == 1) { boundaryVertices->insert(a); boundaryVertices->insert(b); } if (edgeCount[b][c] == 1) { boundaryVertices->insert(b); boundaryVertices->insert(c); } if (edgeCount[a][c] == 1) { boundaryVertices->insert(a); boundaryVertices->insert(c); } } return true; }
std::vector<int32_t> query_BUQTree(PointSet ps, int count, BBOX region, BUQTree *root) { std::priority_queue<nugget> queue; std::vector<BUQTree*> front; front.push_back(root); while (! front.empty()) { BUQTree *node = front.back(); front.pop_back(); if (node->left) // is this an internal node? { auto compare = region.compare(node->bounds); if (compare == BBOX::Relation::ENCLOSED) queue.emplace(node->min_value, (PointIterator*) new InternalIterator(&ps, &node->best)); if (compare == BBOX::Relation::OVERLAP) { front.push_back(node->left); front.push_back(node->right); } } else // nope. leaf. { LeafIterator *iter = new LeafIterator(&ps, node->indices, node->num_indices, ®ion); queue.emplace(node->min_value, (PointIterator*) iter); } } std::vector<int32_t> best; int32_t stop; while (!queue.empty() && best.size() < count) { nugget n = queue.top(); queue.pop(); if (!queue.empty()) stop = queue.top().r; else stop = 0x7FFFFFFF; if (! n.iter->ready() ) { if (n.iter->hasNext(stop)) { n.r = n.iter->top(); queue.push(n); } continue; } best.push_back( n.iter->consume() ); if (n.iter->hasNext(stop)) { n.r = n.iter->top(); queue.push(n); } } return best; }
bool LeafIterator::ready() { if (index < num_indices) return region->contains(*ps, indices[index]); return false; }
void LMESH::fit(vector<Lvert*>& verts, bool do_gauss_seidel) { static bool debug = Config::get_var_bool("DEBUG_LMESH_FIT",false); static bool move_along_normal = Config::get_var_bool("FITTING_MOVE_ALONG_NORMAL",false); if (verts.empty()) return; // calculate the bounding box of the vertices BBOX box; size_t i; for (i=0; i<verts.size(); i++) box.update(verts[i]->loc()); double max_err = box.dim().length() * 1e-5; size_t n = verts.size(); // get original control point locations vector<Wpt> C(n); // original control points vector<Wpt> L(n); // current limit points for (i=0; i<n; i++) { C[i] = verts[i]->loc(); L[i] = Wpt::Origin(); } if(debug) { cerr << "LMESH::fit- fitting " << n << " vertices"<<endl; cerr << "Max_err = " << max_err <<endl; } // do 50 iterations... double prev_err = 0; vector<double> errors; for (int k=0; k<50; k++) { errors.clear(); double err = 0; if (do_gauss_seidel) { // Gauss-Seidel iteration: use updated values from the // current iteration as they are computed... for (size_t j=0; j<n; j++) { // don't need that L[] array... Wpt limit; verts[j]->limit_loc(limit); Wvec delt = C[j] - limit; errors.push_back(delt.length()); err += delt.length(); if(move_along_normal) delt = delt*verts[j]->norm()*verts[j]->norm(); verts[j]->offset_loc(delt); } } else { // compute the new offsets from the offsets computed in the // previous iteration size_t j; for (j=0; j<n; j++) verts[j]->limit_loc(L[j]); for (j=0; j<n; j++) { Wvec delt = C[j] - L[j]; err += delt.length(); errors.push_back(delt.length()); if(move_along_normal) delt = delt*verts[j]->norm()*verts[j]->norm(); verts[j]->offset_loc(delt); } } // compute the average error: err /= n; double avg,std_d,max,min; if (debug) { if (prev_err != 0) { err_msg("Iter %d: avg error: %f, reduction: %f", k, err, err/prev_err); statistics(errors,true,&avg,&std_d,&max,&min); } else { err_msg("Iter %d: avg error: %f", k, err); statistics(errors,true,&avg,&std_d,&max,&min); } } else statistics(errors,false,&avg,&std_d,&max,&min); prev_err = err; if (max < max_err) { if(debug) cerr << "Terminating at " << k <<" th iterations"<<endl; return; } } }