Daily backup.
This commit is contained in:
parent
f51fcfcd5f
commit
58c2168719
|
@ -1,4 +1,3 @@
|
||||||
#include <vector>
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
// stuff to define the mesh
|
// stuff to define the mesh
|
||||||
|
@ -7,10 +6,6 @@
|
||||||
#include <vcg/complex/trimesh/base.h>
|
#include <vcg/complex/trimesh/base.h>
|
||||||
#include <vcg/simplex/face/with/av.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/trimesh/update/topology.h>
|
||||||
|
|
||||||
#include <vcg/complex/local_optimization.h>
|
#include <vcg/complex/local_optimization.h>
|
||||||
|
@ -19,44 +14,45 @@
|
||||||
#include <vcg/space/point3.h>
|
#include <vcg/space/point3.h>
|
||||||
|
|
||||||
#include "pvoronoi.h"
|
#include "pvoronoi.h"
|
||||||
#include "border.h"
|
//#include "border.h"
|
||||||
|
|
||||||
class MyEdge;
|
#include "decimate.h"
|
||||||
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(){}
|
|
||||||
};
|
|
||||||
|
|
||||||
using namespace vcg;
|
using namespace vcg;
|
||||||
using namespace tri;
|
using namespace tri;
|
||||||
using namespace nxs;
|
using namespace nxs;
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
float Clustering(unsigned int target_faces,
|
class MyEdge;
|
||||||
vector<Point3f> &newvert,
|
class MyFace;
|
||||||
vector<unsigned int> &newface,
|
class MyVertex:
|
||||||
vector<Link> &newbord,
|
public vcg::VertexAFVMVNf<DUMMYEDGETYPE, MyFace,DUMMYTETRATYPE> {
|
||||||
vector<int> &vert_remap) {
|
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 Cluster(MyMesh &mesh, unsigned int target_faces);
|
||||||
|
float Quadric(MyMesh &mesh, unsigned int target_faces);
|
||||||
|
|
||||||
float Decimate(unsigned int target_faces,
|
float nxs::Decimate(Decimation mode,
|
||||||
|
unsigned int target_faces,
|
||||||
vector<Point3f> &newvert,
|
vector<Point3f> &newvert,
|
||||||
vector<unsigned int> &newface,
|
vector<unsigned int> &newface,
|
||||||
vector<Link> &newbord,
|
vector<Link> &newbord,
|
||||||
|
@ -65,7 +61,6 @@ float Decimate(unsigned int target_faces,
|
||||||
MyMesh mesh;
|
MyMesh mesh;
|
||||||
|
|
||||||
//build mesh
|
//build mesh
|
||||||
|
|
||||||
for(unsigned int i = 0; i < newvert.size(); i++) {
|
for(unsigned int i = 0; i < newvert.size(); i++) {
|
||||||
MyVertex vertex;
|
MyVertex vertex;
|
||||||
vertex.ClearFlags();
|
vertex.ClearFlags();
|
||||||
|
@ -85,18 +80,17 @@ float Decimate(unsigned int target_faces,
|
||||||
}
|
}
|
||||||
mesh.fn = mesh.face.size();
|
mesh.fn = mesh.face.size();
|
||||||
|
|
||||||
//emark borders
|
//mark borders
|
||||||
for(unsigned int i = 0; i < newbord.size(); i++)
|
for(unsigned int i = 0; i < newbord.size(); i++)
|
||||||
mesh.vert[newbord[i].start_vert].ClearW();
|
mesh.vert[newbord[i].start_vert].ClearW();
|
||||||
|
|
||||||
|
|
||||||
// int FinalSize = mesh.face.size()/2;
|
// int FinalSize = mesh.face.size()/2;
|
||||||
// if(FinalSize > target_faces) FinalSize = target_faces;
|
// if(FinalSize > target_faces) FinalSize = target_faces;
|
||||||
int FinalSize = target_faces;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
printf("mesh loaded %d %d \n",mesh.vn,mesh.fn);
|
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;
|
float error = DeciSession.currMetric/4;//1; //get error;
|
||||||
int t3=clock();
|
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) {
|
float Cluster(MyMesh &mesh, unsigned int target_faces) {
|
||||||
unsigned int starting = mesh.vn;
|
unsigned int starting = mesh.vn;
|
||||||
|
|
||||||
|
|
|
@ -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
|
|
@ -124,15 +124,15 @@ void Nexus::Close() {
|
||||||
borders.Close();
|
borders.Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
Patch Nexus::GetPatch(unsigned int patch) {
|
Patch Nexus::GetPatch(unsigned int patch, bool flush) {
|
||||||
Entry &entry = index[patch];
|
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);
|
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];
|
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);
|
return Border(start, entry.border_used, entry.border_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -49,8 +49,8 @@ class Nexus {
|
||||||
virtual bool Load(const std::string &filename);
|
virtual bool Load(const std::string &filename);
|
||||||
virtual void Close();
|
virtual void Close();
|
||||||
|
|
||||||
Patch GetPatch(unsigned int patch);
|
Patch GetPatch(unsigned int patch, bool flush = true);
|
||||||
Border GetBorder(unsigned int patch);
|
Border GetBorder(unsigned int patch, bool flush = true);
|
||||||
|
|
||||||
bool IsCompressed() { return signature & NXS_COMPRESSED; }
|
bool IsCompressed() { return signature & NXS_COMPRESSED; }
|
||||||
|
|
||||||
|
|
|
@ -86,15 +86,18 @@ void NexusMt::Render() {
|
||||||
for(unsigned int i = 0; i < cells.size(); i++) {
|
for(unsigned int i = 0; i < cells.size(); i++) {
|
||||||
unsigned int cell = cells[i];
|
unsigned int cell = cells[i];
|
||||||
Nexus::Entry &entry = index[cell];
|
Nexus::Entry &entry = index[cell];
|
||||||
|
|
||||||
//frustum culling
|
//frustum culling
|
||||||
// if(frustum.Outside(entry.sphere.center, entry.sphere.radius))
|
// if(frustum.Outside(entry.sphere.center, entry.sphere.radius))
|
||||||
// continue;
|
// continue;
|
||||||
|
|
||||||
Patch patch = GetPatch(cell);
|
Patch patch = GetPatch(cell);
|
||||||
glVertexPointer(3, GL_FLOAT, 0, patch.VertBegin());
|
glVertexPointer(3, GL_FLOAT, 0, patch.VertBegin());
|
||||||
if(use_colors)
|
if(use_colors)
|
||||||
glColorPointer(4, GL_UNSIGNED_BYTE, 0, patch.ColorBegin());
|
glColorPointer(4, GL_UNSIGNED_BYTE, 0, patch.ColorBegin());
|
||||||
if(use_normals)
|
if(use_normals)
|
||||||
glNormalPointer(GL_SHORT, 8, patch.Norm16Begin());
|
glNormalPointer(GL_SHORT, 8, patch.Norm16Begin());
|
||||||
|
|
||||||
switch(mode) {
|
switch(mode) {
|
||||||
case POINTS:
|
case POINTS:
|
||||||
glDrawArrays(GL_POINTS, 0, patch.nv); break;
|
glDrawArrays(GL_POINTS, 0, patch.nv); break;
|
||||||
|
|
|
@ -24,6 +24,9 @@
|
||||||
History
|
History
|
||||||
|
|
||||||
$Log: not supported by cvs2svn $
|
$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
|
Revision 1.8 2004/09/30 00:27:42 ponchio
|
||||||
Lot of changes. Backup.
|
Lot of changes. Backup.
|
||||||
|
|
||||||
|
@ -66,12 +69,6 @@ Created
|
||||||
|
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#ifdef WIN32
|
|
||||||
#include "getopt.h"
|
|
||||||
#else
|
|
||||||
#include <unistd.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
@ -95,7 +92,7 @@ int height = 768;
|
||||||
|
|
||||||
SDL_Surface *screen = NULL;
|
SDL_Surface *screen = NULL;
|
||||||
|
|
||||||
bool init() {
|
bool init(const string &str) {
|
||||||
|
|
||||||
if(SDL_Init(SDL_INIT_VIDEO) != 0) {
|
if(SDL_Init(SDL_INIT_VIDEO) != 0) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -117,7 +114,7 @@ bool init() {
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_WM_SetIcon(SDL_LoadBMP("inspector.bmp"), NULL);
|
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);
|
glDisable(GL_DITHER);
|
||||||
|
@ -135,54 +132,53 @@ bool init() {
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
enum Mode { SCREEN, GEO };
|
|
||||||
int level = 0;
|
int level = 0;
|
||||||
int apatch = -1;
|
int apatch = -1;
|
||||||
float error = 1;
|
float error = 4;
|
||||||
Mode mode = SCREEN;
|
|
||||||
|
|
||||||
Trackball track;
|
Trackball track;
|
||||||
int option;
|
int option;
|
||||||
|
|
||||||
while((option = getopt(argc, argv, "l:p:g:s:")) != EOF) {
|
if(argc != 2) {
|
||||||
switch(option) {
|
cerr << "Usage: " << argv[0] << " <nexus file>\n";
|
||||||
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";
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
NexusMt nexus;
|
NexusMt nexus;
|
||||||
if(!nexus.Load(argv[optind])) {
|
if(!nexus.Load(argv[1])) {
|
||||||
cerr << "Could not load nexus file: " << argv[1] << endl;
|
cerr << "Could not load nexus file: " << argv[1] << endl;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
Sphere3f sphere = nexus.sphere;
|
Sphere3f sphere = nexus.sphere;
|
||||||
|
|
||||||
if(!init()) {
|
if(!init(argv[1])) {
|
||||||
cerr << "Could not init SDL window\n";
|
cerr << "Could not init SDL window\n";
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// FrustumPolicy frustum_policy;
|
// 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_borders = true;
|
||||||
bool show_colors = true;
|
bool show_colors = true;
|
||||||
bool show_normals = true;
|
bool show_normals = true;
|
||||||
|
NexusMt::Mode mode = NexusMt::SMOOTH;
|
||||||
|
NexusMt::PolicyKind policy = NexusMt::FRUSTUM;
|
||||||
|
|
||||||
glClearColor(0, 0, 0, 0);
|
glClearColor(0, 0, 0, 0);
|
||||||
glEnable(GL_LIGHTING);
|
glEnable(GL_LIGHTING);
|
||||||
glEnable(GL_LIGHT0);
|
glEnable(GL_LIGHT0);
|
||||||
|
@ -193,21 +189,25 @@ int main(int argc, char *argv[]) {
|
||||||
SDL_Event event;
|
SDL_Event event;
|
||||||
int x, y;
|
int x, y;
|
||||||
float alpha = 0;
|
float alpha = 0;
|
||||||
|
bool redraw = false;
|
||||||
while( !quit ) {
|
while( !quit ) {
|
||||||
while( SDL_WaitEvent( &event ) ){
|
bool first = true;
|
||||||
|
SDL_WaitEvent(&event);
|
||||||
|
while( first || SDL_PollEvent( &event ) ){
|
||||||
|
first = false;
|
||||||
switch( event.type ) {
|
switch( event.type ) {
|
||||||
case SDL_QUIT: quit = 1; break;
|
case SDL_QUIT: quit = 1; break;
|
||||||
case SDL_KEYDOWN:
|
case SDL_KEYDOWN:
|
||||||
switch(event.key.keysym.sym) {
|
switch(event.key.keysym.sym) {
|
||||||
case SDLK_q: exit(0); break;
|
case SDLK_q: exit(0); break;
|
||||||
case SDLK_b: show_borders = !show_borders;break;
|
case SDLK_b: show_borders = !show_borders; break;
|
||||||
case SDLK_c:
|
case SDLK_c: show_colors = !show_colors; break;
|
||||||
show_colors = !show_colors;
|
case SDLK_n: show_normals = !show_normals; break;
|
||||||
|
|
||||||
break;
|
case SDLK_s: policy = NexusMt::FRUSTUM; break;
|
||||||
case SDLK_n:
|
case SDLK_p: mode = NexusMt::POINTS; break;
|
||||||
show_normals = !show_normals;
|
case SDLK_d: mode = NexusMt::DEBUG; break;
|
||||||
break;
|
case SDLK_m: mode = NexusMt::SMOOTH; break;
|
||||||
|
|
||||||
case SDLK_r:
|
case SDLK_r:
|
||||||
case SDLK_SPACE: rotate = !rotate; break;
|
case SDLK_SPACE: rotate = !rotate; break;
|
||||||
|
@ -219,10 +219,6 @@ int main(int argc, char *argv[]) {
|
||||||
case SDLK_PLUS: error *= 1.1;
|
case SDLK_PLUS: error *= 1.1;
|
||||||
cerr << "error: " << error << endl; break;
|
cerr << "error: " << error << endl; break;
|
||||||
}
|
}
|
||||||
//quit = 1;
|
|
||||||
//error++;
|
|
||||||
//if(error == 5) error = 0;
|
|
||||||
//render.setMaxError(error/10.0);
|
|
||||||
break;
|
break;
|
||||||
case SDL_MOUSEBUTTONDOWN:
|
case SDL_MOUSEBUTTONDOWN:
|
||||||
x = event.button.x;
|
x = event.button.x;
|
||||||
|
@ -233,24 +229,26 @@ int main(int argc, char *argv[]) {
|
||||||
track.MouseWheel(-1);
|
track.MouseWheel(-1);
|
||||||
} else
|
} else
|
||||||
track.MouseDown(x, y, 1);
|
track.MouseDown(x, y, 1);
|
||||||
// hand.buttonDown(x, y, 1);
|
|
||||||
break;
|
break;
|
||||||
case SDL_MOUSEBUTTONUP:
|
case SDL_MOUSEBUTTONUP:
|
||||||
x = event.button.x;
|
x = event.button.x;
|
||||||
y = height - event.button.y;
|
y = height - event.button.y;
|
||||||
track.MouseUp(x, y, 1);
|
track.MouseUp(x, y, 1);
|
||||||
// hand.buttonUp(x, y);
|
|
||||||
break;
|
break;
|
||||||
case SDL_MOUSEMOTION:
|
case SDL_MOUSEMOTION:
|
||||||
while(SDL_PeepEvents(&event, 1, SDL_GETEVENT, SDL_MOUSEMOTIONMASK));
|
while(SDL_PeepEvents(&event, 1, SDL_GETEVENT, SDL_MOUSEMOTIONMASK));
|
||||||
x = event.motion.x;
|
x = event.motion.x;
|
||||||
y = height - event.motion.y;
|
y = height - event.motion.y;
|
||||||
track.MouseMove(x, y);
|
track.MouseMove(x, y);
|
||||||
// hand.mouseMove(x, y);
|
|
||||||
break;
|
break;
|
||||||
|
case SDL_VIDEOEXPOSE:
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
|
redraw = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!redraw) continue;
|
||||||
|
redraw = false;
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
glMatrixMode(GL_PROJECTION);
|
glMatrixMode(GL_PROJECTION);
|
||||||
glLoadIdentity();
|
glLoadIdentity();
|
||||||
|
@ -259,110 +257,35 @@ int main(int argc, char *argv[]) {
|
||||||
glLoadIdentity();
|
glLoadIdentity();
|
||||||
gluLookAt(0,0,5, 0,0,0, 0,1,0);
|
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.GetView();
|
||||||
track.Apply();
|
track.Apply();
|
||||||
|
|
||||||
float scale = 2/sphere.Radius();
|
float scale = 2/sphere.Radius();
|
||||||
// glRotatef(alpha, 0, 1, 0);
|
|
||||||
// if(rotate)
|
|
||||||
// alpha++;
|
|
||||||
// if(alpha > 360) alpha = 0;
|
|
||||||
glScalef(scale, scale, scale);
|
glScalef(scale, scale, scale);
|
||||||
Point3f center = sphere.Center();
|
Point3f center = sphere.Center();
|
||||||
glTranslatef(-center[0], -center[1], -center[2]);
|
glTranslatef(-center[0], -center[1], -center[2]);
|
||||||
|
|
||||||
nexus.SetMode(NexusMt::DEBUG);
|
glColor3f(0.9, 0.9, 0.9);
|
||||||
nexus.SetPolicy(NexusMt::FRUSTUM, error);
|
nexus.SetMode(mode);
|
||||||
|
nexus.SetPolicy(policy, error);
|
||||||
nexus.SetComponent(NexusMt::COLOR, show_colors);
|
nexus.SetComponent(NexusMt::COLOR, show_colors);
|
||||||
nexus.SetComponent(NexusMt::NORMAL, show_normals);
|
nexus.SetComponent(NexusMt::NORMAL, show_normals);
|
||||||
|
|
||||||
nexus.Render();
|
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();
|
SDL_GL_SwapBuffers();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Clean up
|
// Clean up
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,6 @@ void nxs::ComputeNormals(Nexus &nexus) {
|
||||||
bool use_short = (nexus.signature & NXS_NORMALS_SHORT) != 0;
|
bool use_short = (nexus.signature & NXS_NORMALS_SHORT) != 0;
|
||||||
|
|
||||||
//first step normals in the same patch.
|
//first step normals in the same patch.
|
||||||
cerr << "First step" << endl;
|
|
||||||
for(unsigned int p = 0; p < nexus.index.size(); p++) {
|
for(unsigned int p = 0; p < nexus.index.size(); p++) {
|
||||||
Patch patch = nexus.GetPatch(p);
|
Patch patch = nexus.GetPatch(p);
|
||||||
|
|
||||||
|
@ -43,6 +42,7 @@ void nxs::ComputeNormals(Nexus &nexus) {
|
||||||
normals[f[1]] += norm;
|
normals[f[1]] += norm;
|
||||||
normals[f[2]] += norm;
|
normals[f[2]] += norm;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(nexus.signature & NXS_STRIP)
|
if(nexus.signature & NXS_STRIP)
|
||||||
for(unsigned int i = 0; i < patch.nf-2; i++) {
|
for(unsigned int i = 0; i < patch.nf-2; i++) {
|
||||||
unsigned short *f = patch.FaceBegin() + i;
|
unsigned short *f = patch.FaceBegin() + i;
|
||||||
|
@ -72,16 +72,13 @@ void nxs::ComputeNormals(Nexus &nexus) {
|
||||||
normals.size() * sizeof(Point3f));
|
normals.size() * sizeof(Point3f));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cerr << "Second step" << endl;
|
|
||||||
//Second step unify normals across borders
|
//Second step unify normals across borders
|
||||||
for(unsigned int p = 0; p < nexus.index.size(); p++) {
|
for(unsigned int p = 0; p < nexus.index.size(); p++) {
|
||||||
//notice now ew allow flushing of old patches
|
//notice now ew allow flushing of old patches
|
||||||
cerr << "Colleting" << endl;
|
|
||||||
|
|
||||||
Patch patch = nexus.GetPatch(p);
|
Patch patch = nexus.GetPatch(p);
|
||||||
Border border = nexus.GetBorder(p);
|
Border border = nexus.GetBorder(p);
|
||||||
|
|
||||||
cerr << "nv: " << patch.nv << " nf: " << patch.nf << endl;
|
|
||||||
//first pass we collect all normals
|
//first pass we collect all normals
|
||||||
map<unsigned short, Point3f> normals;
|
map<unsigned short, Point3f> normals;
|
||||||
for(unsigned int i = 0; i < border.Size(); i++) {
|
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);
|
normals[link.start_vert] += remote.Norm32(link.end_vert);
|
||||||
}
|
}
|
||||||
|
|
||||||
cerr << "Adding" << endl;
|
|
||||||
//second pass we update values in all the patches involved
|
//second pass we update values in all the patches involved
|
||||||
for(unsigned int i = 0; i < border.Size(); i++) {
|
for(unsigned int i = 0; i < border.Size(); i++) {
|
||||||
Link &link = border[i];
|
Link &link = border[i];
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}*/
|
||||||
|
}
|
|
@ -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
|
|
@ -13,6 +13,17 @@ using namespace vcg;
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif
|
#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[]) {
|
int main(int argc, char *argv[]) {
|
||||||
|
|
||||||
string input;
|
string input;
|
||||||
|
@ -160,9 +171,10 @@ int main(int argc, char *argv[]) {
|
||||||
<< " -n<float>: Normal quantization\n"
|
<< " -n<float>: Normal quantization\n"
|
||||||
<< " -c<float>: Color quantization\n"
|
<< " -c<float>: Color quantization\n"
|
||||||
<< " -t<float>: Texture quantization\n\n";
|
<< " -t<float>: Texture quantization\n\n";
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
input = argv[optind];
|
input = argv[optind];
|
||||||
if(!output.size()) output = input + "00";
|
|
||||||
|
|
||||||
Nexus nexus;
|
Nexus nexus;
|
||||||
if(!nexus.Load(input)) {
|
if(!nexus.Load(input)) {
|
||||||
|
@ -228,6 +240,8 @@ int main(int argc, char *argv[]) {
|
||||||
signature |= add;
|
signature |= add;
|
||||||
signature &= ~remove;
|
signature &= ~remove;
|
||||||
|
|
||||||
|
if(!output.size()) output = input + getSuffix(signature);
|
||||||
|
|
||||||
Nexus out;
|
Nexus out;
|
||||||
if(!out.Create(output, (Signature)signature)) {
|
if(!out.Create(output, (Signature)signature)) {
|
||||||
cerr << "Could not open output: " << output << endl;
|
cerr << "Could not open output: " << output << endl;
|
||||||
|
@ -243,6 +257,7 @@ int main(int argc, char *argv[]) {
|
||||||
vector<unsigned short> strip;
|
vector<unsigned short> strip;
|
||||||
if(add_strip) {
|
if(add_strip) {
|
||||||
ComputeTriStrip(src_patch.nf, src_patch.FaceBegin(), strip);
|
ComputeTriStrip(src_patch.nf, src_patch.FaceBegin(), strip);
|
||||||
|
assert(strip.size() < 32767);
|
||||||
out.AddPatch(src_entry.nvert, strip.size(), src_entry.border_size);
|
out.AddPatch(src_entry.nvert, strip.size(), src_entry.border_size);
|
||||||
} else
|
} else
|
||||||
out.AddPatch(src_entry.nvert, src_entry.nface, src_entry.border_size);
|
out.AddPatch(src_entry.nvert, src_entry.nface, src_entry.border_size);
|
||||||
|
|
|
@ -2,6 +2,9 @@
|
||||||
|
|
||||||
using namespace nxs;
|
using namespace nxs;
|
||||||
|
|
||||||
|
void pad(unsigned int &size) {
|
||||||
|
while(size&0x3) size++;
|
||||||
|
}
|
||||||
|
|
||||||
Patch::Patch(Signature signature, Chunk *s,
|
Patch::Patch(Signature signature, Chunk *s,
|
||||||
unsigned short nvert, unsigned short nface):
|
unsigned short nvert, unsigned short nface):
|
||||||
|
@ -24,7 +27,27 @@ void Patch::Init(Signature signature,
|
||||||
//align memory
|
//align memory
|
||||||
if(((int)vstart) & 0x2) vstart = (float *)(((char *)vstart) + 2);
|
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)
|
if(signature & NXS_COLORS)
|
||||||
nstart = cstart + nv * sizeof(unsigned int);
|
nstart = cstart + nv * sizeof(unsigned int);
|
||||||
else
|
else
|
||||||
|
@ -42,7 +65,8 @@ void Patch::Init(Signature signature,
|
||||||
else if(signature & NXS_TEXTURES_FLOAT)
|
else if(signature & NXS_TEXTURES_FLOAT)
|
||||||
dstart = tstart + nv * sizeof(float) * 2;
|
dstart = tstart + nv * sizeof(float) * 2;
|
||||||
else
|
else
|
||||||
dstart = tstart;
|
dstart = tstart;*/
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int Patch::ChunkSize(Signature signature,
|
unsigned int Patch::ChunkSize(Signature signature,
|
||||||
|
@ -63,7 +87,7 @@ unsigned int Patch::ByteSize(Signature signature,
|
||||||
size += nface * 3 * sizeof(unsigned short);
|
size += nface * 3 * sizeof(unsigned short);
|
||||||
|
|
||||||
//memory alignment
|
//memory alignment
|
||||||
if(size & 0x2) size += 2;
|
pad(size);
|
||||||
|
|
||||||
size += nvert * sizeof(vcg::Point3f);
|
size += nvert * sizeof(vcg::Point3f);
|
||||||
|
|
||||||
|
@ -84,8 +108,10 @@ unsigned int Patch::ByteSize(Signature signature,
|
||||||
|
|
||||||
if(signature & NXS_DATA8)
|
if(signature & NXS_DATA8)
|
||||||
size += nvert * sizeof(char);
|
size += nvert * sizeof(char);
|
||||||
|
pad(size);
|
||||||
if(signature & NXS_DATA16)
|
if(signature & NXS_DATA16)
|
||||||
size += nvert * 2 * sizeof(char);
|
size += nvert * 2 * sizeof(char);
|
||||||
|
pad(size);
|
||||||
if(signature & NXS_DATA32)
|
if(signature & NXS_DATA32)
|
||||||
size += nvert * 4 * sizeof(char);
|
size += nvert * 4 * sizeof(char);
|
||||||
if(signature & NXS_DATA64)
|
if(signature & NXS_DATA64)
|
||||||
|
|
|
@ -80,11 +80,11 @@ inline unsigned short *Patch::Face(unsigned short f) {
|
||||||
}
|
}
|
||||||
|
|
||||||
inline unsigned int *Patch::ColorBegin() {
|
inline unsigned int *Patch::ColorBegin() {
|
||||||
return (unsigned int *)(((char *)vstart) + cstart);
|
return (unsigned int *)(vstart + cstart);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline short *Patch::Norm16Begin() {
|
inline short *Patch::Norm16Begin() {
|
||||||
return (short *)(((char *)vstart) + nstart);
|
return (short *)(vstart + nstart);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline short *Patch::Norm16(unsigned short v) {
|
inline short *Patch::Norm16(unsigned short v) {
|
||||||
|
@ -92,7 +92,7 @@ inline short *Patch::Norm16(unsigned short v) {
|
||||||
}
|
}
|
||||||
|
|
||||||
inline vcg::Point3f *Patch::Norm32Begin() {
|
inline vcg::Point3f *Patch::Norm32Begin() {
|
||||||
return (vcg::Point3f *)(((char *)vstart) + nstart);
|
return (vcg::Point3f *)(vstart + nstart);
|
||||||
}
|
}
|
||||||
inline vcg::Point3f &Patch::Norm32(unsigned short v) {
|
inline vcg::Point3f &Patch::Norm32(unsigned short v) {
|
||||||
return Norm32Begin()[v];
|
return Norm32Begin()[v];
|
||||||
|
|
|
@ -24,6 +24,9 @@
|
||||||
History
|
History
|
||||||
|
|
||||||
$Log: not supported by cvs2svn $
|
$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
|
Revision 1.5 2004/09/28 10:26:07 ponchio
|
||||||
Voronoi partition changes.
|
Voronoi partition changes.
|
||||||
|
|
||||||
|
@ -121,6 +124,7 @@ void VoronoiChain::Init(Crude &crude, float scaling, int steps) {
|
||||||
seeds.push_back(fine[i]);
|
seeds.push_back(fine[i]);
|
||||||
}
|
}
|
||||||
swap(fine, seeds);
|
swap(fine, seeds);
|
||||||
|
if(fine.size() == 0) fine.push_back(Point3f(0,0,0));
|
||||||
fine.Init();
|
fine.Init();
|
||||||
|
|
||||||
//here goes some optimization pass.
|
//here goes some optimization pass.
|
||||||
|
@ -158,6 +162,7 @@ void VoronoiChain::Init(Crude &crude, float scaling, int steps) {
|
||||||
seeds.push_back(coarse[i]);
|
seeds.push_back(coarse[i]);
|
||||||
}
|
}
|
||||||
swap(coarse, seeds);
|
swap(coarse, seeds);
|
||||||
|
if(coarse.size() == 0) coarse.push_back(Point3f(0,0,0));
|
||||||
coarse.Init();
|
coarse.Init();
|
||||||
|
|
||||||
|
|
||||||
|
@ -395,6 +400,7 @@ void VoronoiChain::BuildLevel(Nexus &nexus, unsigned int offset,
|
||||||
seeds.push_back(coarse[i]);
|
seeds.push_back(coarse[i]);
|
||||||
}
|
}
|
||||||
swap(coarse, seeds);
|
swap(coarse, seeds);
|
||||||
|
if(coarse.size() == 0) coarse.push_back(Point3f(0,0,0));
|
||||||
coarse.Init();
|
coarse.Init();
|
||||||
|
|
||||||
//Coarse optimization
|
//Coarse optimization
|
||||||
|
|
|
@ -24,6 +24,9 @@
|
||||||
History
|
History
|
||||||
|
|
||||||
$Log: not supported by cvs2svn $
|
$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
|
Revision 1.4 2004/09/21 00:53:23 ponchio
|
||||||
Lotsa changes.
|
Lotsa changes.
|
||||||
|
|
||||||
|
@ -54,21 +57,13 @@ using namespace std;
|
||||||
#include "voronoichain.h"
|
#include "voronoichain.h"
|
||||||
#include "pintersect.h"
|
#include "pintersect.h"
|
||||||
#include "vert_remap.h"
|
#include "vert_remap.h"
|
||||||
|
|
||||||
|
#include "decimate.h"
|
||||||
|
#include "nxsbuild.h"
|
||||||
using namespace vcg;
|
using namespace vcg;
|
||||||
using namespace nxs;
|
using namespace nxs;
|
||||||
|
|
||||||
struct RemapLink {
|
/*void RemapVertices(Crude &crude,
|
||||||
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,
|
|
||||||
VertRemap &vert_remap,
|
VertRemap &vert_remap,
|
||||||
VFile<unsigned int> &face_remap,
|
VFile<unsigned int> &face_remap,
|
||||||
vector<unsigned int> &patch_verts);
|
vector<unsigned int> &patch_verts);
|
||||||
|
@ -85,7 +80,7 @@ void NexusFill(Crude &crude,
|
||||||
VFile<RemapLink> &border_remap);
|
VFile<RemapLink> &border_remap);
|
||||||
|
|
||||||
void NexusFixBorder(Nexus &nexus,
|
void NexusFixBorder(Nexus &nexus,
|
||||||
VFile<RemapLink> &border_remap);
|
VFile<RemapLink> &border_remap);*/
|
||||||
|
|
||||||
void NexusSplit(Nexus &nexus, VoronoiChain &vchain,
|
void NexusSplit(Nexus &nexus, VoronoiChain &vchain,
|
||||||
unsigned int level,
|
unsigned int level,
|
||||||
|
@ -95,19 +90,19 @@ void NexusSplit(Nexus &nexus, VoronoiChain &vchain,
|
||||||
Nexus::Update &update,
|
Nexus::Update &update,
|
||||||
float error);
|
float error);
|
||||||
|
|
||||||
float Decimate(unsigned int target_faces,
|
/*float Decimate(unsigned int target_faces,
|
||||||
vector<Point3f> &newvert,
|
vector<Point3f> &newvert,
|
||||||
vector<unsigned int> &newface,
|
vector<unsigned int> &newface,
|
||||||
vector<Link> &newbord,
|
vector<Link> &newbord,
|
||||||
vector<int> &vert_remap);
|
vector<int> &vert_remap);*/
|
||||||
|
|
||||||
void ReverseHistory(vector<Nexus::Update> &history);
|
void ReverseHistory(vector<Nexus::Update> &history);
|
||||||
|
|
||||||
enum Decimation { QUADRIC, CLUSTER };
|
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
|
|
||||||
Decimation decimation = QUADRIC;
|
Decimation decimation = CLUSTER;
|
||||||
unsigned int patch_size = 1000;
|
unsigned int patch_size = 1000;
|
||||||
unsigned int patch_threshold = 0xffffffff;
|
unsigned int patch_threshold = 0xffffffff;
|
||||||
unsigned int optimization_steps = 5;
|
unsigned int optimization_steps = 5;
|
||||||
|
@ -286,7 +281,8 @@ int main(int argc, char *argv[]) {
|
||||||
|
|
||||||
//simplyfy mesh
|
//simplyfy mesh
|
||||||
vector<int> vert_remap;
|
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);
|
newvert, newface, newbord, vert_remap);
|
||||||
|
|
||||||
|
|
||||||
|
@ -338,7 +334,7 @@ int main(int argc, char *argv[]) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RemapVertices(Crude &crude,
|
/*void RemapVertices(Crude &crude,
|
||||||
VertRemap &vert_remap,
|
VertRemap &vert_remap,
|
||||||
VFile<unsigned int> &face_remap,
|
VFile<unsigned int> &face_remap,
|
||||||
vector<unsigned int> &patch_verts) {
|
vector<unsigned int> &patch_verts) {
|
||||||
|
@ -355,9 +351,9 @@ void RemapVertices(Crude &crude,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
|
|
||||||
void NexusAllocate(Crude &crude,
|
/*void NexusAllocate(Crude &crude,
|
||||||
Nexus &nexus,
|
Nexus &nexus,
|
||||||
VFile<unsigned int> &face_remap,
|
VFile<unsigned int> &face_remap,
|
||||||
vector<unsigned int> &patch_faces,
|
vector<unsigned int> &patch_faces,
|
||||||
|
@ -404,10 +400,10 @@ void NexusAllocate(Crude &crude,
|
||||||
faces[entry.nface] = face;
|
faces[entry.nface] = face;
|
||||||
entry.nface++;
|
entry.nface++;
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
|
|
||||||
|
|
||||||
void NexusFill(Crude &crude,
|
/*void NexusFill(Crude &crude,
|
||||||
Nexus &nexus,
|
Nexus &nexus,
|
||||||
VertRemap &vert_remap,
|
VertRemap &vert_remap,
|
||||||
VFile<RemapLink> &border_remap) {
|
VFile<RemapLink> &border_remap) {
|
||||||
|
@ -479,9 +475,9 @@ void NexusFill(Crude &crude,
|
||||||
//we can now update bounding sphere.
|
//we can now update bounding sphere.
|
||||||
for(unsigned int i = 0; i < nexus.index.size(); i++)
|
for(unsigned int i = 0; i < nexus.index.size(); i++)
|
||||||
nexus.sphere.Add(nexus.index[i].sphere);
|
nexus.sphere.Add(nexus.index[i].sphere);
|
||||||
}
|
}*/
|
||||||
|
|
||||||
void NexusFixBorder(Nexus &nexus,
|
/*void NexusFixBorder(Nexus &nexus,
|
||||||
VFile<RemapLink> &border_remap) {
|
VFile<RemapLink> &border_remap) {
|
||||||
|
|
||||||
//and last convert RemapLinks into Links
|
//and last convert RemapLinks into Links
|
||||||
|
@ -532,28 +528,7 @@ void NexusFixBorder(Nexus &nexus,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
nexus.borders.Flush();
|
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,
|
void NexusSplit(Nexus &nexus, VoronoiChain &vchain,
|
||||||
|
|
Loading…
Reference in New Issue