Daily backup.

This commit is contained in:
Federico Ponchio 2004-10-01 16:54:57 +00:00
parent f51fcfcd5f
commit 58c2168719
14 changed files with 520 additions and 268 deletions

View File

@ -1,4 +1,3 @@
#include <vector>
#include <iostream>
// stuff to define the mesh
@ -7,10 +6,6 @@
#include <vcg/complex/trimesh/base.h>
#include <vcg/simplex/face/with/av.h>
// io
//#include <wrap/io_trimesh/import_ply.h>
//#include <wrap/io_trimesh/export_ply.h>
// update
#include <vcg/complex/trimesh/update/topology.h>
#include <vcg/complex/local_optimization.h>
@ -19,53 +14,53 @@
#include <vcg/space/point3.h>
#include "pvoronoi.h"
#include "border.h"
//#include "border.h"
class MyEdge;
class MyFace;
class MyVertex:public vcg::VertexAFVMVNf<DUMMYEDGETYPE , MyFace,DUMMYTETRATYPE>{public:
ScalarType w;
vcg::math::Quadric<vcg::Plane3<ScalarType,false> >q;
ScalarType & W(){return w;}
} ;
class MyFace : public vcg::FaceAV<MyVertex,DUMMYEDGETYPE , MyFace>{};
class MyMesh:
public vcg::tri::TriMesh< std::vector<MyVertex>, std::vector<MyFace > >{};
class MyTriEdgeCollapse:
public vcg::tri::TriEdgeCollapseQuadric< MyMesh, MyTriEdgeCollapse >{
public:
typedef vcg::tri::TriEdgeCollapseQuadric<MyMesh, MyTriEdgeCollapse > TECQ;
typedef TECQ::PosType PosType;
MyTriEdgeCollapse(PosType p, int i):TECQ(p,i){}
~MyTriEdgeCollapse(){}
};
#include "decimate.h"
using namespace vcg;
using namespace tri;
using namespace nxs;
using namespace std;
float Clustering(unsigned int target_faces,
vector<Point3f> &newvert,
vector<unsigned int> &newface,
vector<Link> &newbord,
vector<int> &vert_remap) {
}
class MyEdge;
class MyFace;
class MyVertex:
public vcg::VertexAFVMVNf<DUMMYEDGETYPE, MyFace,DUMMYTETRATYPE> {
public:
ScalarType w;
vcg::math::Quadric<vcg::Plane3<ScalarType, false> > q;
ScalarType & W() { return w; }
};
class MyFace : public vcg::FaceAV<MyVertex,DUMMYEDGETYPE , MyFace> {};
class MyMesh:
public vcg::tri::TriMesh< std::vector<MyVertex>, std::vector<MyFace > > {};
class MyTriEdgeCollapse:
public vcg::tri::TriEdgeCollapseQuadric< MyMesh, MyTriEdgeCollapse > {
public:
typedef vcg::tri::TriEdgeCollapseQuadric<MyMesh, MyTriEdgeCollapse > TECQ;
typedef TECQ::PosType PosType;
MyTriEdgeCollapse(PosType p, int i): TECQ(p, i) {}
~MyTriEdgeCollapse() {}
};
float Cluster(MyMesh &mesh, unsigned int target_faces);
float Quadric(MyMesh &mesh, unsigned int target_faces);
float Decimate(unsigned int target_faces,
vector<Point3f> &newvert,
vector<unsigned int> &newface,
vector<Link> &newbord,
vector<int> &vert_remap) {
float nxs::Decimate(Decimation mode,
unsigned int target_faces,
vector<Point3f> &newvert,
vector<unsigned int> &newface,
vector<Link> &newbord,
vector<int> &vert_remap) {
MyMesh mesh;
//build mesh
for(unsigned int i = 0; i < newvert.size(); i++) {
MyVertex vertex;
vertex.ClearFlags();
@ -85,18 +80,17 @@ float Decimate(unsigned int target_faces,
}
mesh.fn = mesh.face.size();
//emark borders
//mark borders
for(unsigned int i = 0; i < newbord.size(); i++)
mesh.vert[newbord[i].start_vert].ClearW();
// int FinalSize = mesh.face.size()/2;
// if(FinalSize > target_faces) FinalSize = target_faces;
int FinalSize = target_faces;
printf("mesh loaded %d %d \n",mesh.vn,mesh.fn);
printf("reducing it to %i\n",FinalSize);
printf("reducing it to %i\n", target_faces);
/*
@ -115,7 +109,11 @@ float Decimate(unsigned int target_faces,
float error = DeciSession.currMetric/4;//1; //get error;
int t3=clock();
*/
float error = Cluster(mesh, target_faces);
float error;
if(mode == CLUSTER)
error = Cluster(mesh, target_faces);
else
error = Quadric(mesh, target_faces);
@ -164,6 +162,34 @@ float Decimate(unsigned int target_faces,
}
float Quadric(MyMesh &mesh, unsigned int target_faces) {
vcg::tri::UpdateTopology<MyMesh>::VertexFace(mesh);
vcg::LocalOptimization<MyMesh> DeciSession(mesh);
MyTriEdgeCollapse::SetDefaultParams();
DeciSession.Init<MyTriEdgeCollapse>();
DeciSession.SetTargetSimplices(target_faces);
DeciSession.DoOptimization();
float error = 0;
int count = 0;
for(unsigned int i = 0; i < mesh.face.size(); i++) {
MyFace &face = mesh.face[i];
if(face.IsD()) continue;
for(int k = 0; k < 3; k++) {
error += (face.cV(k)->cP() - face.cV((k+1)%3)->cP()).Norm();
count++;
}
}
error /= count;
cerr << "Error: " << error << endl;
cerr << "faces: " << mesh.fn << endl;
cerr << "verts: " << mesh.vn << endl;
return error;
}
float Cluster(MyMesh &mesh, unsigned int target_faces) {
unsigned int starting = mesh.vn;

20
apps/nexus/decimate.h Normal file
View File

@ -0,0 +1,20 @@
#ifndef NXS_DECIMATE_H
#define NXS_DECIMATE_H
#include <vector>
#include "border.h"
#include <vcg/space/point3.h>
namespace nxs {
enum Decimation { QUADRIC, CLUSTER };
float Decimate(Decimation mode,
unsigned int target_faces,
std::vector<vcg::Point3f> &newvert,
std::vector<unsigned int> &newface,
std::vector<Link> &newbord,
std::vector<int> &vert_remap);
}
#endif

View File

@ -124,15 +124,15 @@ void Nexus::Close() {
borders.Close();
}
Patch Nexus::GetPatch(unsigned int patch) {
Patch Nexus::GetPatch(unsigned int patch, bool flush) {
Entry &entry = index[patch];
Chunk *start = patches.GetRegion(entry.patch_start, entry.patch_size);
Chunk *start = patches.GetRegion(entry.patch_start, entry.patch_size,flush);
return Patch(signature, start, entry.nvert, entry.nface);
}
Border Nexus::GetBorder(unsigned int patch) {
Border Nexus::GetBorder(unsigned int patch, bool flush) {
Entry &entry = index[patch];
Link *start = borders.GetRegion(entry.border_start, entry.border_size);
Link *start = borders.GetRegion(entry.border_start, entry.border_size,flush);
return Border(start, entry.border_used, entry.border_size);
}

View File

@ -49,8 +49,8 @@ class Nexus {
virtual bool Load(const std::string &filename);
virtual void Close();
Patch GetPatch(unsigned int patch);
Border GetBorder(unsigned int patch);
Patch GetPatch(unsigned int patch, bool flush = true);
Border GetBorder(unsigned int patch, bool flush = true);
bool IsCompressed() { return signature & NXS_COMPRESSED; }

View File

@ -86,15 +86,18 @@ void NexusMt::Render() {
for(unsigned int i = 0; i < cells.size(); i++) {
unsigned int cell = cells[i];
Nexus::Entry &entry = index[cell];
//frustum culling
// if(frustum.Outside(entry.sphere.center, entry.sphere.radius))
// continue;
Patch patch = GetPatch(cell);
glVertexPointer(3, GL_FLOAT, 0, patch.VertBegin());
if(use_colors)
glColorPointer(4, GL_UNSIGNED_BYTE, 0, patch.ColorBegin());
if(use_normals)
glNormalPointer(GL_SHORT, 8, patch.Norm16Begin());
switch(mode) {
case POINTS:
glDrawArrays(GL_POINTS, 0, patch.nv); break;

View File

@ -24,6 +24,9 @@
History
$Log: not supported by cvs2svn $
Revision 1.9 2004/09/30 23:56:33 ponchio
Backup (added strips and normals)
Revision 1.8 2004/09/30 00:27:42 ponchio
Lot of changes. Backup.
@ -66,12 +69,6 @@ Created
****************************************************************************/
#ifdef WIN32
#include "getopt.h"
#else
#include <unistd.h>
#endif
#include <iostream>
using namespace std;
@ -95,7 +92,7 @@ int height = 768;
SDL_Surface *screen = NULL;
bool init() {
bool init(const string &str) {
if(SDL_Init(SDL_INIT_VIDEO) != 0) {
return false;
@ -117,7 +114,7 @@ bool init() {
}
SDL_WM_SetIcon(SDL_LoadBMP("inspector.bmp"), NULL);
SDL_WM_SetCaption(" Inspector", "Inspector");
SDL_WM_SetCaption(str.c_str(), str.c_str());
glDisable(GL_DITHER);
@ -135,54 +132,53 @@ bool init() {
int main(int argc, char *argv[]) {
enum Mode { SCREEN, GEO };
int level = 0;
int apatch = -1;
float error = 1;
Mode mode = SCREEN;
float error = 4;
Trackball track;
int option;
while((option = getopt(argc, argv, "l:p:g:s:")) != EOF) {
switch(option) {
case 'l': level = atoi(optarg); break;
case 'p': apatch = atoi(optarg); break;
case 'g': mode = GEO; error = (float)atof(optarg); break;
case 's': mode = SCREEN; error = (float)atof(optarg); break;
default: cerr << "Unknown option: " << (char)option << endl;
return -1;
}
}
if(optind != argc - 1) {
cerr << "Usage: " << argv[0] << " <nexus file> [options]\n"
<< " -l <n>: show level n\n"
<< " -p <n>: show patch n\n"
<< " -g <e>: extract at geometry error e\n"
<< " -s <e>: extract at screen error e\n\n";
if(argc != 2) {
cerr << "Usage: " << argv[0] << " <nexus file>\n";
return -1;
}
NexusMt nexus;
if(!nexus.Load(argv[optind])) {
if(!nexus.Load(argv[1])) {
cerr << "Could not load nexus file: " << argv[1] << endl;
return -1;
}
Sphere3f sphere = nexus.sphere;
if(!init()) {
if(!init(argv[1])) {
cerr << "Could not init SDL window\n";
return -1;
}
// FrustumPolicy frustum_policy;
cerr << "Commands: \n"
" q: quit\n"
" s: screen error extraction\n"
" g: geometry error extraction\n"
" p: draw points\n"
" d: debug mode (show patches colored)\n"
" m: smooth mode\n"
" c: show colors\n"
" n: show normals\n"
" r: rotate model\n"
" -: decrease error\n"
" +: increase error (= too)\n";
bool rotate = true;
bool rotate = false;
bool show_borders = true;
bool show_colors = true;
bool show_normals = true;
NexusMt::Mode mode = NexusMt::SMOOTH;
NexusMt::PolicyKind policy = NexusMt::FRUSTUM;
glClearColor(0, 0, 0, 0);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
@ -190,24 +186,28 @@ int main(int argc, char *argv[]) {
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_CULL_FACE);
int quit = 0;
SDL_Event event;
SDL_Event event;
int x, y;
float alpha = 0;
while( !quit ) {
while( SDL_WaitEvent( &event ) ){
bool redraw = false;
while( !quit ) {
bool first = true;
SDL_WaitEvent(&event);
while( first || SDL_PollEvent( &event ) ){
first = false;
switch( event.type ) {
case SDL_QUIT: quit = 1; break;
case SDL_KEYDOWN:
switch(event.key.keysym.sym) {
case SDLK_q: exit(0); break;
case SDLK_b: show_borders = !show_borders;break;
case SDLK_c:
show_colors = !show_colors;
case SDLK_b: show_borders = !show_borders; break;
case SDLK_c: show_colors = !show_colors; break;
case SDLK_n: show_normals = !show_normals; break;
break;
case SDLK_n:
show_normals = !show_normals;
break;
case SDLK_s: policy = NexusMt::FRUSTUM; break;
case SDLK_p: mode = NexusMt::POINTS; break;
case SDLK_d: mode = NexusMt::DEBUG; break;
case SDLK_m: mode = NexusMt::SMOOTH; break;
case SDLK_r:
case SDLK_SPACE: rotate = !rotate; break;
@ -219,10 +219,6 @@ int main(int argc, char *argv[]) {
case SDLK_PLUS: error *= 1.1;
cerr << "error: " << error << endl; break;
}
//quit = 1;
//error++;
//if(error == 5) error = 0;
//render.setMaxError(error/10.0);
break;
case SDL_MOUSEBUTTONDOWN:
x = event.button.x;
@ -233,135 +229,62 @@ int main(int argc, char *argv[]) {
track.MouseWheel(-1);
} else
track.MouseDown(x, y, 1);
// hand.buttonDown(x, y, 1);
break;
case SDL_MOUSEBUTTONUP:
x = event.button.x;
y = height - event.button.y;
track.MouseUp(x, y, 1);
// hand.buttonUp(x, y);
break;
case SDL_MOUSEMOTION:
while(SDL_PeepEvents(&event, 1, SDL_GETEVENT, SDL_MOUSEMOTIONMASK));
x = event.motion.x;
y = height - event.motion.y;
track.MouseMove(x, y);
// hand.mouseMove(x, y);
break;
case SDL_VIDEOEXPOSE:
default: break;
}
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(40, 1, 0.1, 100);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0,0,5, 0,0,0, 0,1,0);
track.GetView();
track.Apply();
float scale = 2/sphere.Radius();
// glRotatef(alpha, 0, 1, 0);
// if(rotate)
// alpha++;
// if(alpha > 360) alpha = 0;
glScalef(scale, scale, scale);
Point3f center = sphere.Center();
glTranslatef(-center[0], -center[1], -center[2]);
nexus.SetMode(NexusMt::DEBUG);
nexus.SetPolicy(NexusMt::FRUSTUM, error);
nexus.SetComponent(NexusMt::COLOR, show_colors);
nexus.SetComponent(NexusMt::NORMAL, show_normals);
nexus.Render();
/* vector<unsigned int> cells;
if(apatch != -1) {
cells.push_back(apatch);
} else if(mode == GEO) {
nexus.ExtractFixed(cells, error);
} else if(mode == SCREEN) {
frustum_policy.error = error;
frustum_policy.GetView();
nexus.Extract(cells, &frustum_policy);
} else {
for(int i = 0; i < nexus.index.size(); i++) {
if(nexus.index[i].error == 0)
cells.push_back(i);
}
}
glColor3f(1, 1, 1);
for(unsigned int i = 0; i < cells.size(); i++) {
unsigned int cell = cells[i];
Patch patch = nexus.GetPatch(cell);
if(show_color) {
unsigned int val = cell + 1;
glColor3ub(((val * 27)%128) + 128,
((val * 37)%128) + 128,
((val * 87)%128) + 128);
}
glBegin(GL_TRIANGLES);
unsigned short *f = patch.FaceBegin();
for(unsigned int j = 0; j < patch.nf*3; j+= 3) {
Point3f &p1 = patch.Vert(f[j]);
Point3f &p2 = patch.Vert(f[j+1]);
Point3f &p3 = patch.Vert(f[j+2]);
Point3f n = ((p2 - p1) ^ (p3 - p1));
if(!show_normals) {
glNormal3f(n[0], n[1], n[2]);
glVertex3f(p1[0], p1[1], p1[2]);
glVertex3f(p2[0], p2[1], p2[2]);
glVertex3f(p3[0], p3[1], p3[2]);
} else {
short *n1 = patch.Norm16(f[j]);
short *n2 = patch.Norm16(f[j+1]);
short *n3 = patch.Norm16(f[j+2]);
glNormal3s(n1[0], n1[1], n1[2]);
glVertex3f(p1[0], p1[1], p1[2]);
glNormal3s(n2[0], n2[1], n2[2]);
glVertex3f(p2[0], p2[1], p2[2]);
glNormal3s(n3[0], n3[1], n3[2]);
glVertex3f(p3[0], p3[1], p3[2]);
}
}
glEnd();
}
if(show_borders) {
for(unsigned int i = 0; i < cells.size(); i++) {
unsigned int cell = cells[i];
Patch patch = nexus.GetPatch(cell);
//drawing borders
glColor3f(1, 1, 1);
Border border = nexus.GetBorder(cell);
glPointSize(4);
glDisable(GL_LIGHTING);
glDisable(GL_DEPTH_TEST);
glBegin(GL_POINTS);
for(unsigned int k = 0; k < border.Size(); k++) {
if(border[k].IsNull()) continue;
Point3f &p = patch.Vert(border[k].start_vert);
glVertex3f(p[0], p[1], p[2]);
}
glEnd();
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);
}
}
*/
SDL_GL_SwapBuffers();
redraw = true;
}
if(!redraw) continue;
redraw = false;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(40, 1, 0.1, 100);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0,0,5, 0,0,0, 0,1,0);
glRotatef(alpha, 0, 1, 0);
if(rotate) {
alpha++;
if(alpha > 360) alpha = 0;
SDL_Event redraw;
redraw.type = SDL_VIDEOEXPOSE;
SDL_PushEvent(&redraw);
}
track.GetView();
track.Apply();
float scale = 2/sphere.Radius();
glScalef(scale, scale, scale);
Point3f center = sphere.Center();
glTranslatef(-center[0], -center[1], -center[2]);
glColor3f(0.9, 0.9, 0.9);
nexus.SetMode(mode);
nexus.SetPolicy(policy, error);
nexus.SetComponent(NexusMt::COLOR, show_colors);
nexus.SetComponent(NexusMt::NORMAL, show_normals);
nexus.Render();
SDL_GL_SwapBuffers();
}
// Clean up

View File

@ -23,10 +23,9 @@ void nxs::ComputeNormals(Nexus &nexus) {
bool use_short = (nexus.signature & NXS_NORMALS_SHORT) != 0;
//first step normals in the same patch.
cerr << "First step" << endl;
for(unsigned int p = 0; p < nexus.index.size(); p++) {
Patch patch = nexus.GetPatch(p);
vector<Point3f> normals;
normals.resize(patch.nv, Point3f(0, 0, 0));
@ -43,6 +42,7 @@ void nxs::ComputeNormals(Nexus &nexus) {
normals[f[1]] += norm;
normals[f[2]] += norm;
}
if(nexus.signature & NXS_STRIP)
for(unsigned int i = 0; i < patch.nf-2; i++) {
unsigned short *f = patch.FaceBegin() + i;
@ -72,16 +72,13 @@ void nxs::ComputeNormals(Nexus &nexus) {
normals.size() * sizeof(Point3f));
}
}
cerr << "Second step" << endl;
//Second step unify normals across borders
for(unsigned int p = 0; p < nexus.index.size(); p++) {
//notice now ew allow flushing of old patches
cerr << "Colleting" << endl;
Patch patch = nexus.GetPatch(p);
Border border = nexus.GetBorder(p);
cerr << "nv: " << patch.nv << " nf: " << patch.nf << endl;
//first pass we collect all normals
map<unsigned short, Point3f> normals;
for(unsigned int i = 0; i < border.Size(); i++) {
@ -108,7 +105,6 @@ void nxs::ComputeNormals(Nexus &nexus) {
normals[link.start_vert] += remote.Norm32(link.end_vert);
}
cerr << "Adding" << endl;
//second pass we update values in all the patches involved
for(unsigned int i = 0; i < border.Size(); i++) {
Link &link = border[i];

223
apps/nexus/nxsbuild.cpp Normal file
View File

@ -0,0 +1,223 @@
#include "nxsbuild.h"
#include <set>
#include <map>
using namespace nxs;
using namespace vcg;
using namespace std;
void nxs::RemapVertices(Crude &crude,
VertRemap &vert_remap,
VFile<unsigned int> &face_remap,
vector<unsigned int> &patch_verts) {
for(unsigned int i = 0; i < crude.Faces(); i++) {
Crude::Face &face = crude.GetFace(i);
unsigned int patch = face_remap[i];
for(int k = 0; k < 3; k++) {
set<unsigned int> pp;
vert_remap.GetValues(face[k], pp);
if(!pp.count(patch)) {
vert_remap.Insert(face[k], patch);
patch_verts[patch]++;
}
}
}
}
void nxs::NexusAllocate(Crude &crude,
Nexus &nexus,
VFile<unsigned int> &face_remap,
vector<unsigned int> &patch_faces,
vector<unsigned int> &patch_verts) {
nexus.index.resize(patch_faces.size());
unsigned int totchunks = 0;
//now that we know various sizes, lets allocate space
for(unsigned int i = 0; i < nexus.index.size(); i++) {
Nexus::Entry &entry = nexus.index[i];
if(patch_faces[i] == 0 || patch_verts[i] == 0)
cerr << "Warning! Empty patch.\n";
entry.patch_start = totchunks;
entry.patch_size = Patch::ChunkSize(nexus.signature,
patch_verts[i], patch_faces[i]);
totchunks += entry.patch_size;
entry.border_start = 0xffffffff;
entry.nvert = patch_verts[i];
entry.nface = 0;
entry.error = 0;
}
nexus.patches.Resize(totchunks);
//now we sort the faces into the patches (but still using absolute indexing
//instead of relative indexing
for(unsigned int i = 0; i < crude.face.Size(); i++) {
Crude::Face &face = crude.face[i];
unsigned int npatch = face_remap[i];
Nexus::Entry &entry = nexus.index[npatch];
//TODO this is slow because we have to initialize patch.
//just get patch.start.
Patch patch = nexus.GetPatch(npatch);
Crude::Face *faces = (Crude::Face *)patch.start;
faces[entry.nface] = face;
entry.nface++;
}
}
void nxs::NexusFill(Crude &crude,
Nexus &nexus,
VertRemap &vert_remap,
VFile<RemapLink> &border_remap) {
//finally for every patch we collect the vertices
//and fill the patch.
//we need to remember start and size in border_remap;
// vector<unsigned int> border_start;
// vector<unsigned int> border_size;
for(unsigned int i = 0; i < nexus.index.size(); i++) {
Patch patch = nexus.GetPatch(i);
Nexus::Entry &entry = nexus.index[i];
//make a copy of faces (we need to write there :P)
Crude::Face *faces = new Crude::Face[patch.nf];
memcpy(faces, (Crude::Face *)patch.start,
patch.nf * sizeof(Crude::Face));
//collect all vertices we need.
//TODO an hash_map would be faster?
unsigned int count = 0;
map<unsigned int, unsigned short> remap;
for(unsigned int k = 0; k < patch.nf; k++) {
Crude::Face &face = faces[k];
for(int j = 0; j < 3; j++) {
if(!remap.count(face[j])) {
assert(count < patch.nv);
Point3f &v = crude.vert[face[j]];
patch.VertBegin()[remap.size()] = v;
entry.sphere.Add(v);
remap[face[j]] = count++;
}
patch.FaceBegin()[k*3 + j] = remap[face[j]];
}
}
assert(count == remap.size());
assert(entry.nvert == remap.size());
//record start of border:
entry.border_start = border_remap.Size();
//TODO hash_set?
set<unsigned int> border_patches;
map<unsigned int, unsigned short>::iterator m;
for(m = remap.begin(); m != remap.end(); m++) {
RemapLink link;
link.abs_vert = (*m).first;
link.rel_vert = (*m).second;
vert_remap.GetValues(link.abs_vert, border_patches);
assert(border_patches.size() >= 1);
if(border_patches.size() == 1) continue; //its not a border
set<unsigned int>::iterator s;
for(s = border_patches.begin(); s != border_patches.end(); s++) {
if((*s) == i) continue;
link.patch = *s;
border_remap.PushBack(link);
}
}
//and number of borders:
entry.border_used = border_remap.Size() - entry.border_start;
delete []faces;
}
//we can now update bounding sphere.
for(unsigned int i = 0; i < nexus.index.size(); i++)
nexus.sphere.Add(nexus.index[i].sphere);
}
void nxs::NexusFixBorder(Nexus &nexus,
VFile<RemapLink> &border_remap) {
//and last convert RemapLinks into Links
nexus.borders.Resize(border_remap.Size() * 2);
//* 2 is to accomodate future borders
for(unsigned int i = 0; i < nexus.index.size(); i++) {
Nexus::Entry &local = nexus.index[i];
local.border_start *= 2;
local.border_size = local.border_used * 2;
}
for(unsigned int i = 0; i < nexus.index.size(); i++) {
Nexus::Entry &local = nexus.index[i];
unsigned int remap_start = local.border_start/2;
//* 2 is to accomodate future borders
// K is the main iterator (where we write to in nexus.borders)
for(unsigned int k = 0; k < local.border_used; k++) {
RemapLink start_link = border_remap[k + remap_start];
assert(start_link.rel_vert < local.nvert);
Nexus::Entry &remote = nexus.index[start_link.patch];
bool found = false;
unsigned int remote_remap_start = remote.border_start/2;
for(unsigned int j = 0; j < remote.border_used; j++) {
RemapLink end_link = border_remap[j + remote_remap_start];
assert(end_link.rel_vert < remote.nvert);
if(start_link.abs_vert == end_link.abs_vert &&
end_link.patch == i) { //found the match
assert(!found);
nexus.borders[k + local.border_start] = Link(start_link.rel_vert,
end_link.rel_vert,
start_link.patch);
found = true;
}
}
assert(nexus.borders[k + local.border_start].start_vert < local.nvert);
assert(found);
}
}
nexus.borders.Flush();
//Checking border consistency:
/* for(unsigned int i = 0; i < nexus.index.size(); i++) {
Border border = nexus.GetBorder(i);
Nexus::Entry &entry = nexus.index[i];
for(unsigned int k = 0; k < border.Size(); k++) {
Link &link = border[k];
if(link.start_vert >= entry.nvert) {
cerr << "K: " << k << endl;
cerr << "patch: " << i << " nvert: " << entry.nvert << " startv: "
<< link.start_vert << endl;
cerr << "bstart: " << entry.border_start
<< "bsize: " << entry.border_size << endl;
}
assert(link.end_patch < nexus.index.size());
assert(link.start_vert < entry.nvert);
Nexus::Entry &remote = nexus.index[link.end_patch];
assert(link.end_vert < remote.nvert);
}
}*/
}

39
apps/nexus/nxsbuild.h Normal file
View File

@ -0,0 +1,39 @@
#ifndef NXS_BUILD_H
#define NXS_BUILD_H
#include "vert_remap.h"
#include "crude.h"
#include "nexus.h"
#include <vector>
namespace nxs {
struct RemapLink {
unsigned int rel_vert;
unsigned int patch;
unsigned int abs_vert;
};
void RemapVertices(Crude &crude,
VertRemap &vert_remap,
VFile<unsigned int> &face_remap,
std::vector<unsigned int> &patch_verts);
void NexusAllocate(Crude &crude,
nxs::Nexus &nexus,
VFile<unsigned int> &face_remap,
std::vector<unsigned int> &patch_faces,
std::vector<unsigned int> &patch_verts);
void NexusFill(Crude &crude,
Nexus &nexus,
VertRemap &vert_remap,
VFile<RemapLink> &border_remap);
void NexusFixBorder(Nexus &nexus,
VFile<RemapLink> &border_remap);
}
#endif

View File

@ -13,6 +13,17 @@ using namespace vcg;
#include <unistd.h>
#endif
string getSuffix(unsigned int signature) {
string suff;
if(signature&NXS_COMPRESSED) suff += "Z";
if(signature&NXS_STRIP) suff += "S";
if(signature&NXS_COLORS) suff += "C";
if(signature&NXS_NORMALS_SHORT) suff += "N";
if(signature&NXS_TEXTURES_SHORT) suff += "T";
if(signature&NXS_DATA32) suff += "D";
return suff;
}
int main(int argc, char *argv[]) {
string input;
@ -160,9 +171,10 @@ int main(int argc, char *argv[]) {
<< " -n<float>: Normal quantization\n"
<< " -c<float>: Color quantization\n"
<< " -t<float>: Texture quantization\n\n";
return -1;
}
input = argv[optind];
if(!output.size()) output = input + "00";
Nexus nexus;
if(!nexus.Load(input)) {
@ -228,6 +240,8 @@ int main(int argc, char *argv[]) {
signature |= add;
signature &= ~remove;
if(!output.size()) output = input + getSuffix(signature);
Nexus out;
if(!out.Create(output, (Signature)signature)) {
cerr << "Could not open output: " << output << endl;
@ -243,6 +257,7 @@ int main(int argc, char *argv[]) {
vector<unsigned short> strip;
if(add_strip) {
ComputeTriStrip(src_patch.nf, src_patch.FaceBegin(), strip);
assert(strip.size() < 32767);
out.AddPatch(src_entry.nvert, strip.size(), src_entry.border_size);
} else
out.AddPatch(src_entry.nvert, src_entry.nface, src_entry.border_size);

View File

@ -2,6 +2,9 @@
using namespace nxs;
void pad(unsigned int &size) {
while(size&0x3) size++;
}
Patch::Patch(Signature signature, Chunk *s,
unsigned short nvert, unsigned short nface):
@ -24,7 +27,27 @@ void Patch::Init(Signature signature,
//align memory
if(((int)vstart) & 0x2) vstart = (float *)(((char *)vstart) + 2);
cstart = nv * sizeof(float) * 3;
cstart = nv * 3;
if(signature & NXS_COLORS)
nstart = cstart + nv;
else
nstart = cstart;
if(signature & NXS_NORMALS_SHORT)
tstart = nstart + nv * 2;
else if(signature & NXS_NORMALS_FLOAT)
tstart = nstart + nv * 3;
else
tstart = nstart;
if(signature & NXS_TEXTURES_SHORT)
dstart = tstart + nv;
else if(signature & NXS_TEXTURES_FLOAT)
dstart = tstart + nv;
else
dstart = tstart;
/* cstart = nv * sizeof(float) * 3;
if(signature & NXS_COLORS)
nstart = cstart + nv * sizeof(unsigned int);
else
@ -42,7 +65,8 @@ void Patch::Init(Signature signature,
else if(signature & NXS_TEXTURES_FLOAT)
dstart = tstart + nv * sizeof(float) * 2;
else
dstart = tstart;
dstart = tstart;*/
}
unsigned int Patch::ChunkSize(Signature signature,
@ -63,7 +87,7 @@ unsigned int Patch::ByteSize(Signature signature,
size += nface * 3 * sizeof(unsigned short);
//memory alignment
if(size & 0x2) size += 2;
pad(size);
size += nvert * sizeof(vcg::Point3f);
@ -84,8 +108,10 @@ unsigned int Patch::ByteSize(Signature signature,
if(signature & NXS_DATA8)
size += nvert * sizeof(char);
pad(size);
if(signature & NXS_DATA16)
size += nvert * 2 * sizeof(char);
pad(size);
if(signature & NXS_DATA32)
size += nvert * 4 * sizeof(char);
if(signature & NXS_DATA64)

View File

@ -80,11 +80,11 @@ inline unsigned short *Patch::Face(unsigned short f) {
}
inline unsigned int *Patch::ColorBegin() {
return (unsigned int *)(((char *)vstart) + cstart);
return (unsigned int *)(vstart + cstart);
}
inline short *Patch::Norm16Begin() {
return (short *)(((char *)vstart) + nstart);
return (short *)(vstart + nstart);
}
inline short *Patch::Norm16(unsigned short v) {
@ -92,7 +92,7 @@ inline short *Patch::Norm16(unsigned short v) {
}
inline vcg::Point3f *Patch::Norm32Begin() {
return (vcg::Point3f *)(((char *)vstart) + nstart);
return (vcg::Point3f *)(vstart + nstart);
}
inline vcg::Point3f &Patch::Norm32(unsigned short v) {
return Norm32Begin()[v];

View File

@ -24,6 +24,9 @@
History
$Log: not supported by cvs2svn $
Revision 1.6 2004/09/30 00:27:42 ponchio
Lot of changes. Backup.
Revision 1.5 2004/09/28 10:26:07 ponchio
Voronoi partition changes.
@ -121,6 +124,7 @@ void VoronoiChain::Init(Crude &crude, float scaling, int steps) {
seeds.push_back(fine[i]);
}
swap(fine, seeds);
if(fine.size() == 0) fine.push_back(Point3f(0,0,0));
fine.Init();
//here goes some optimization pass.
@ -158,6 +162,7 @@ void VoronoiChain::Init(Crude &crude, float scaling, int steps) {
seeds.push_back(coarse[i]);
}
swap(coarse, seeds);
if(coarse.size() == 0) coarse.push_back(Point3f(0,0,0));
coarse.Init();
@ -395,6 +400,7 @@ void VoronoiChain::BuildLevel(Nexus &nexus, unsigned int offset,
seeds.push_back(coarse[i]);
}
swap(coarse, seeds);
if(coarse.size() == 0) coarse.push_back(Point3f(0,0,0));
coarse.Init();
//Coarse optimization

View File

@ -24,6 +24,9 @@
History
$Log: not supported by cvs2svn $
Revision 1.5 2004/09/30 00:27:42 ponchio
Lot of changes. Backup.
Revision 1.4 2004/09/21 00:53:23 ponchio
Lotsa changes.
@ -54,21 +57,13 @@ using namespace std;
#include "voronoichain.h"
#include "pintersect.h"
#include "vert_remap.h"
#include "decimate.h"
#include "nxsbuild.h"
using namespace vcg;
using namespace nxs;
struct RemapLink {
unsigned int rel_vert;
unsigned int patch;
unsigned int abs_vert;
};
/*void RemapFaces(Crude &crude,
VoronoiChain &vchain,
VFile<unsigned int> &face_remap,
vector<unsigned int> &patch_faces);*/
void RemapVertices(Crude &crude,
/*void RemapVertices(Crude &crude,
VertRemap &vert_remap,
VFile<unsigned int> &face_remap,
vector<unsigned int> &patch_verts);
@ -85,7 +80,7 @@ void NexusFill(Crude &crude,
VFile<RemapLink> &border_remap);
void NexusFixBorder(Nexus &nexus,
VFile<RemapLink> &border_remap);
VFile<RemapLink> &border_remap);*/
void NexusSplit(Nexus &nexus, VoronoiChain &vchain,
unsigned int level,
@ -95,19 +90,19 @@ void NexusSplit(Nexus &nexus, VoronoiChain &vchain,
Nexus::Update &update,
float error);
float Decimate(unsigned int target_faces,
/*float Decimate(unsigned int target_faces,
vector<Point3f> &newvert,
vector<unsigned int> &newface,
vector<Link> &newbord,
vector<int> &vert_remap);
vector<int> &vert_remap);*/
void ReverseHistory(vector<Nexus::Update> &history);
enum Decimation { QUADRIC, CLUSTER };
int main(int argc, char *argv[]) {
Decimation decimation = QUADRIC;
Decimation decimation = CLUSTER;
unsigned int patch_size = 1000;
unsigned int patch_threshold = 0xffffffff;
unsigned int optimization_steps = 5;
@ -286,7 +281,8 @@ int main(int argc, char *argv[]) {
//simplyfy mesh
vector<int> vert_remap;
float error = Decimate((unsigned int)(newface.size() * scaling/3),
float error = Decimate(decimation,
(unsigned int)((newface.size()/3) * scaling),
newvert, newface, newbord, vert_remap);
@ -338,7 +334,7 @@ int main(int argc, char *argv[]) {
return 0;
}
void RemapVertices(Crude &crude,
/*void RemapVertices(Crude &crude,
VertRemap &vert_remap,
VFile<unsigned int> &face_remap,
vector<unsigned int> &patch_verts) {
@ -355,9 +351,9 @@ void RemapVertices(Crude &crude,
}
}
}
}
}*/
void NexusAllocate(Crude &crude,
/*void NexusAllocate(Crude &crude,
Nexus &nexus,
VFile<unsigned int> &face_remap,
vector<unsigned int> &patch_faces,
@ -404,10 +400,10 @@ void NexusAllocate(Crude &crude,
faces[entry.nface] = face;
entry.nface++;
}
}
}*/
void NexusFill(Crude &crude,
/*void NexusFill(Crude &crude,
Nexus &nexus,
VertRemap &vert_remap,
VFile<RemapLink> &border_remap) {
@ -479,9 +475,9 @@ void NexusFill(Crude &crude,
//we can now update bounding sphere.
for(unsigned int i = 0; i < nexus.index.size(); i++)
nexus.sphere.Add(nexus.index[i].sphere);
}
}*/
void NexusFixBorder(Nexus &nexus,
/*void NexusFixBorder(Nexus &nexus,
VFile<RemapLink> &border_remap) {
//and last convert RemapLinks into Links
@ -532,28 +528,7 @@ void NexusFixBorder(Nexus &nexus,
}
}
nexus.borders.Flush();
//Checking border consistency:
/* for(unsigned int i = 0; i < nexus.index.size(); i++) {
Border border = nexus.GetBorder(i);
Nexus::Entry &entry = nexus.index[i];
for(unsigned int k = 0; k < border.Size(); k++) {
Link &link = border[k];
if(link.start_vert >= entry.nvert) {
cerr << "K: " << k << endl;
cerr << "patch: " << i << " nvert: " << entry.nvert << " startv: "
<< link.start_vert << endl;
cerr << "bstart: " << entry.border_start
<< "bsize: " << entry.border_size << endl;
}
assert(link.end_patch < nexus.index.size());
assert(link.start_vert < entry.nvert);
Nexus::Entry &remote = nexus.index[link.end_patch];
assert(link.end_vert < remote.nvert);
}
}*/
}
} */
void NexusSplit(Nexus &nexus, VoronoiChain &vchain,