diff --git a/apps/nexus/nexusmt.cpp b/apps/nexus/nexusmt.cpp index 5e78c3eb..7bb607d9 100644 --- a/apps/nexus/nexusmt.cpp +++ b/apps/nexus/nexusmt.cpp @@ -26,23 +26,36 @@ bool FrustumPolicy::Expand(unsigned int patch, Nexus::PatchInfo &entry) { return entry.error > error * frustum.Resolution(dist); } */ -float FrustumMetric::GetError(Node *node) { +float Metric::GetError(Node *node) { float max_error = 0; - std::vector::iterator frag; - for(frag = node->frags.begin(); frag != node->frags.end(); frag++) { - vector::iterator cell; - for(cell = (*frag).begin(); cell != (*frag).end(); cell++) { - Nexus::PatchInfo &entry = (*index)[*cell]; - Sphere3f &sphere = entry.sphere; - float dist = Distance(sphere, frustum.ViewPoint()); - if(dist < 0) break; - float error = entry.error/frustum.Resolution(dist); - if(frustum.IsOutside(sphere.Center(), sphere.Radius())) - error *= 4; - if(max_error < error) max_error = error; - } + vector::iterator frag; + for(frag = node->frags.begin(); frag != node->frags.end(); frag++) { + float error = GetError(*frag); + if(max_error < error) max_error = error; } - return max_error; + return max_error; +} + +float Metric::GetError(Frag &frag) { + float max_error = 0; + vector::iterator cell; + for(cell = frag.begin(); cell != frag.end(); cell++) { + float error = GetError(*cell); + if(max_error < error) max_error = error; + } + return max_error; +} + +float FrustumMetric::GetError(unsigned int cell) { + float max_error = 0; + Nexus::PatchInfo &entry = (*index)[cell]; + Sphere3f &sphere = entry.sphere; + float dist = Distance(sphere, frustum.ViewPoint()); + if(dist < 0) return 1e40; + float error = entry.error/frustum.Resolution(dist); + if(frustum.IsOutside(sphere.Center(), sphere.Radius())) + error /= 4; + return error; } void Policy::Init() { @@ -472,24 +485,21 @@ void NexusMt::Select(vector &selected) { } } -void NexusMt::PushNode(Node *node, vector &heap) { - if(node->pushed) return; - - float error = metric->GetError(node); - heap.push_back(TNode(node, error)); - push_heap(heap.begin(), heap.end()); -} - void NexusMt::VisitNode(Node *node, vector &heap) { if(node->visited) return; vector::iterator i; for(i = node->in.begin(); i != node->in.end(); i++) - VisitNode(*i, heap); + VisitNode(*i, heap); + + for(unsigned int k = 0; k < node->out.size(); k++) { + Node *outnode = node->out[k]; + float error = metric->GetError(node->frags[k]); + // if(node->pushed) continue + heap.push_back(TNode(outnode, error)); + push_heap(heap.begin(), heap.end()); + } - for(i = node->out.begin(); i != node->out.end(); i++) - PushNode(*i, heap); - node->visited = true; policy.NodeVisited(node); } diff --git a/apps/nexus/nexusmt.h b/apps/nexus/nexusmt.h index 21b5a09f..86b2a715 100644 --- a/apps/nexus/nexusmt.h +++ b/apps/nexus/nexusmt.h @@ -33,21 +33,23 @@ namespace nxs { public: vector *index; - virtual float GetError(Node *node) = 0; + float GetError(Node *node); + float GetError(Frag &frag); + virtual float GetError(unsigned int cell) = 0; virtual void GetView() {} }; class FlatMetric: public Metric { public: void GetView() {} - float GetError(Node *node); + float GetError(unsigned int cell); }; class DeltaMetric: public Metric { public: vcg::Point3f delta; void GetView() {} - float GetError(Node *node); + float GetError(unsigned int cell); }; class FrustumMetric: public Metric { @@ -55,7 +57,7 @@ namespace nxs { vcg::Frustumf frustum; void GetView() { frustum.GetView(); } - float GetError(Node *node); + float GetError(unsigned int cell); }; class Policy { @@ -139,7 +141,6 @@ class NexusMt: public Nexus { protected: void LoadHistory(); void ClearHistory(); - void PushNode(Node *node, std::vector &heap); void VisitNode(Node *node, std::vector &heap); void Select(std::vector &selected); Patch &LoadPatch(unsigned int p); diff --git a/apps/nexus/nxsbuild.cpp b/apps/nexus/nxsbuild.cpp index db2f1e66..3f803c0e 100644 --- a/apps/nexus/nxsbuild.cpp +++ b/apps/nexus/nxsbuild.cpp @@ -85,7 +85,10 @@ void nxs::NexusFill(Crude &crude, VertRemap &vert_remap, VFile &border_remap) { - + + //TODO: is it faster to collect faces and vertices + //from all around or better to pass linearly all the dataset + //and write where needed? i wonder. //finally for every patch we collect the vertices //and fill the patch. //we need to remember start and size in border_remap; @@ -93,8 +96,6 @@ void nxs::NexusFill(Crude &crude, for(unsigned int i = 0; i < nexus.index.size(); i++) { Patch patch = nexus.GetPatch(i); Nexus::PatchInfo &entry = nexus.index[i]; - // cerr << "entryf: " << entry.nface << endl; - // cerr << "nf: " << patch.nf << endl; //make a copy of faces (we need to write there :P) Crude::Face *faces = new Crude::Face[patch.nf]; @@ -113,11 +114,11 @@ void nxs::NexusFill(Crude &crude, for(int j = 0; j < 3; j++) { if(!remap.count(face[j])) { Point3f &v = crude.vert[face[j]]; - patch.VertBegin()[remap.size()] = v; + patch.Vert(remap.size()) = v; entry.sphere.Add(v); remap[face[j]] = count++; } - patch.FaceBegin()[k*3 + j] = remap[face[j]]; + patch.Face(k)[j] = remap[face[j]]; } } assert(count == remap.size()); @@ -156,7 +157,7 @@ void nxs::NexusFill(Crude &crude, //and last convert RemapLinks into Links - + //TODO probably this part is really slow for(unsigned int i = 0; i < nexus.borders.borders.size(); i++) { BorderEntry &local = nexus.borders.borders[i]; //* 2 is to accomodate future borders