kopia lustrzana https://github.com/OpenDroneMap/ODM
rodzic
8958f4ff86
commit
09afe500a9
|
@ -214,32 +214,6 @@ struct vec3f
|
|||
|
||||
};
|
||||
|
||||
vec3f barycentric(const vec3f &p, const vec3f &a, const vec3f &b, const vec3f &c){
|
||||
vec3f v0 = b-a;
|
||||
vec3f v1 = c-a;
|
||||
vec3f v2 = p-a;
|
||||
double d00 = v0.dot(v0);
|
||||
double d01 = v0.dot(v1);
|
||||
double d11 = v1.dot(v1);
|
||||
double d20 = v2.dot(v0);
|
||||
double d21 = v2.dot(v1);
|
||||
double denom = d00*d11-d01*d01;
|
||||
double v = (d11 * d20 - d01 * d21) / denom;
|
||||
double w = (d00 * d21 - d01 * d20) / denom;
|
||||
double u = 1.0 - v - w;
|
||||
return vec3f(u,v,w);
|
||||
}
|
||||
|
||||
vec3f interpolate(const vec3f &p, const vec3f &a, const vec3f &b, const vec3f &c, const vec3f attrs[3])
|
||||
{
|
||||
vec3f bary = barycentric(p,a,b,c);
|
||||
vec3f out = vec3f(0,0,0);
|
||||
out = out + attrs[0] * bary.x;
|
||||
out = out + attrs[1] * bary.y;
|
||||
out = out + attrs[2] * bary.z;
|
||||
return out;
|
||||
}
|
||||
|
||||
double min(double v1, double v2) {
|
||||
return fmin(v1,v2);
|
||||
}
|
||||
|
@ -309,27 +283,18 @@ class SymetricMatrix {
|
|||
namespace Simplify
|
||||
{
|
||||
// Global Variables & Strctures
|
||||
enum Attributes {
|
||||
NONE,
|
||||
NORMAL = 2,
|
||||
TEXCOORD = 4,
|
||||
COLOR = 8
|
||||
};
|
||||
struct Triangle { int v[3];double err[4];int deleted,dirty,attr;vec3f n;vec3f uvs[3];int material; };
|
||||
struct Triangle { int v[3];double err[4];int deleted,dirty;vec3f n; };
|
||||
struct Vertex { vec3f p;int tstart,tcount;SymetricMatrix q;int border;};
|
||||
struct Ref { int tid,tvertex; };
|
||||
std::vector<Triangle> triangles;
|
||||
std::vector<Vertex> vertices;
|
||||
std::vector<Ref> refs;
|
||||
std::string mtllib;
|
||||
std::vector<std::string> materials;
|
||||
|
||||
// Helper functions
|
||||
|
||||
double vertex_error(SymetricMatrix q, double x, double y, double z);
|
||||
double calculate_error(int id_v1, int id_v2, vec3f &p_result);
|
||||
bool flipped(vec3f p,int i0,int i1,Vertex &v0,Vertex &v1,std::vector<int> &deleted);
|
||||
void update_uvs(int i0,const Vertex &v,const vec3f &p,std::vector<int> &deleted);
|
||||
void update_triangles(int i0,Vertex &v,std::vector<int> &deleted,int &deleted_triangles);
|
||||
void update_mesh(int iteration);
|
||||
void compact_mesh();
|
||||
|
@ -408,12 +373,6 @@ namespace Simplify
|
|||
|
||||
if( flipped(p,i1,i0,v1,v0,deleted1) ) continue;
|
||||
|
||||
if ( (t.attr & TEXCOORD) == TEXCOORD )
|
||||
{
|
||||
update_uvs(i0,v0,p,deleted0);
|
||||
update_uvs(i0,v1,p,deleted1);
|
||||
}
|
||||
|
||||
// not flipped, so remove edge
|
||||
v0.p=p;
|
||||
v0.q=v1.q+v0.q;
|
||||
|
@ -499,12 +458,6 @@ namespace Simplify
|
|||
if( flipped(p,i0,i1,v0,v1,deleted0) ) continue;
|
||||
if( flipped(p,i1,i0,v1,v0,deleted1) ) continue;
|
||||
|
||||
if ( (t.attr & TEXCOORD) == TEXCOORD )
|
||||
{
|
||||
update_uvs(i0,v0,p,deleted0);
|
||||
update_uvs(i0,v1,p,deleted1);
|
||||
}
|
||||
|
||||
// not flipped, so remove edge
|
||||
v0.p=p;
|
||||
v0.q=v1.q+v0.q;
|
||||
|
@ -568,23 +521,6 @@ namespace Simplify
|
|||
return false;
|
||||
}
|
||||
|
||||
// update_uvs
|
||||
|
||||
void update_uvs(int i0,const Vertex &v,const vec3f &p,std::vector<int> &deleted)
|
||||
{
|
||||
loopk(0,v.tcount)
|
||||
{
|
||||
Ref &r=refs[v.tstart+k];
|
||||
Triangle &t=triangles[r.tid];
|
||||
if(t.deleted)continue;
|
||||
if(deleted[k])continue;
|
||||
vec3f p1=vertices[t.v[0]].p;
|
||||
vec3f p2=vertices[t.v[1]].p;
|
||||
vec3f p3=vertices[t.v[2]].p;
|
||||
t.uvs[r.tvertex] = interpolate(p,p1,p2,p3,t.uvs);
|
||||
}
|
||||
}
|
||||
|
||||
// Update triangle connections and edge error after a edge is collapsed
|
||||
|
||||
void update_triangles(int i0,Vertex &v,std::vector<int> &deleted,int &deleted_triangles)
|
||||
|
@ -640,7 +576,7 @@ namespace Simplify
|
|||
loopi(0,triangles.size())
|
||||
{
|
||||
Triangle &t=triangles[i];
|
||||
vec3f n,p[3];
|
||||
vec3f n,p[3];
|
||||
loopj(0,3) p[j]=vertices[t.v[j]].p;
|
||||
n.cross(p[1]-p[0],p[2]-p[0]);
|
||||
n.normalize();
|
||||
|
@ -808,221 +744,5 @@ namespace Simplify
|
|||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
char *trimwhitespace(char *str)
|
||||
{
|
||||
char *end;
|
||||
|
||||
// Trim leading space
|
||||
while(isspace((unsigned char)*str)) str++;
|
||||
|
||||
if(*str == 0) // All spaces?
|
||||
return str;
|
||||
|
||||
// Trim trailing space
|
||||
end = str + strlen(str) - 1;
|
||||
while(end > str && isspace((unsigned char)*end)) end--;
|
||||
|
||||
// Write new null terminator
|
||||
*(end+1) = 0;
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
//Option : Load OBJ
|
||||
void load_obj(const char* filename, bool process_uv=false){
|
||||
vertices.clear();
|
||||
triangles.clear();
|
||||
//printf ( "Loading Objects %s ... \n",filename);
|
||||
FILE* fn;
|
||||
if(filename==NULL) return ;
|
||||
if((char)filename[0]==0) return ;
|
||||
if ((fn = fopen(filename, "rb")) == NULL)
|
||||
{
|
||||
printf ( "File %s not found!\n" ,filename );
|
||||
return;
|
||||
}
|
||||
char line[1000];
|
||||
memset ( line,0,1000 );
|
||||
int vertex_cnt = 0;
|
||||
int material = -1;
|
||||
std::map<std::string, int> material_map;
|
||||
std::vector<vec3f> uvs;
|
||||
std::vector<std::vector<int> > uvMap;
|
||||
|
||||
while(fgets( line, 1000, fn ) != NULL)
|
||||
{
|
||||
Vertex v;
|
||||
vec3f uv;
|
||||
|
||||
if (strncmp(line, "mtllib", 6) == 0)
|
||||
{
|
||||
mtllib = trimwhitespace(&line[7]);
|
||||
}
|
||||
if (strncmp(line, "usemtl", 6) == 0)
|
||||
{
|
||||
std::string usemtl = trimwhitespace(&line[7]);
|
||||
if (material_map.find(usemtl) == material_map.end())
|
||||
{
|
||||
material_map[usemtl] = materials.size();
|
||||
materials.push_back(usemtl);
|
||||
}
|
||||
material = material_map[usemtl];
|
||||
}
|
||||
|
||||
if ( line[0] == 'v' && line[1] == 't' )
|
||||
{
|
||||
if ( line[2] == ' ' )
|
||||
if(sscanf(line,"vt %lf %lf",
|
||||
&uv.x,&uv.y)==2)
|
||||
{
|
||||
uv.z = 0;
|
||||
uvs.push_back(uv);
|
||||
} else
|
||||
if(sscanf(line,"vt %lf %lf %lf",
|
||||
&uv.x,&uv.y,&uv.z)==3)
|
||||
{
|
||||
uvs.push_back(uv);
|
||||
}
|
||||
}
|
||||
else if ( line[0] == 'v' )
|
||||
{
|
||||
if ( line[1] == ' ' )
|
||||
if(sscanf(line,"v %lf %lf %lf",
|
||||
&v.p.x, &v.p.y, &v.p.z)==3)
|
||||
{
|
||||
vertices.push_back(v);
|
||||
}
|
||||
}
|
||||
int integers[9];
|
||||
if ( line[0] == 'f' )
|
||||
{
|
||||
Triangle t;
|
||||
bool tri_ok = false;
|
||||
bool has_uv = false;
|
||||
|
||||
if(sscanf(line,"f %d %d %d",
|
||||
&integers[0],&integers[1],&integers[2])==3)
|
||||
{
|
||||
tri_ok = true;
|
||||
}else
|
||||
if(sscanf(line,"f %d// %d// %d//",
|
||||
&integers[0],&integers[1],&integers[2])==3)
|
||||
{
|
||||
tri_ok = true;
|
||||
}else
|
||||
if(sscanf(line,"f %d//%d %d//%d %d//%d",
|
||||
&integers[0],&integers[3],
|
||||
&integers[1],&integers[4],
|
||||
&integers[2],&integers[5])==6)
|
||||
{
|
||||
tri_ok = true;
|
||||
}else
|
||||
if(sscanf(line,"f %d/%d/%d %d/%d/%d %d/%d/%d",
|
||||
&integers[0],&integers[6],&integers[3],
|
||||
&integers[1],&integers[7],&integers[4],
|
||||
&integers[2],&integers[8],&integers[5])==9)
|
||||
{
|
||||
tri_ok = true;
|
||||
has_uv = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("unrecognized sequence\n");
|
||||
printf("%s\n",line);
|
||||
while(1);
|
||||
}
|
||||
if ( tri_ok )
|
||||
{
|
||||
t.v[0] = integers[0]-1-vertex_cnt;
|
||||
t.v[1] = integers[1]-1-vertex_cnt;
|
||||
t.v[2] = integers[2]-1-vertex_cnt;
|
||||
t.attr = 0;
|
||||
|
||||
if ( process_uv && has_uv )
|
||||
{
|
||||
std::vector<int> indices;
|
||||
indices.push_back(integers[6]-1-vertex_cnt);
|
||||
indices.push_back(integers[7]-1-vertex_cnt);
|
||||
indices.push_back(integers[8]-1-vertex_cnt);
|
||||
uvMap.push_back(indices);
|
||||
t.attr |= TEXCOORD;
|
||||
}
|
||||
|
||||
t.material = material;
|
||||
//geo.triangles.push_back ( tri );
|
||||
triangles.push_back(t);
|
||||
//state_before = state;
|
||||
//state ='f';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( process_uv && uvs.size() )
|
||||
{
|
||||
loopi(0,triangles.size())
|
||||
{
|
||||
loopj(0,3)
|
||||
triangles[i].uvs[j] = uvs[uvMap[i][j]];
|
||||
}
|
||||
}
|
||||
|
||||
fclose(fn);
|
||||
|
||||
//printf("load_obj: vertices = %lu, triangles = %lu, uvs = %lu\n", vertices.size(), triangles.size(), uvs.size() );
|
||||
} // load_obj()
|
||||
|
||||
// Optional : Store as OBJ
|
||||
|
||||
void write_obj(const char* filename)
|
||||
{
|
||||
FILE *file=fopen(filename, "w");
|
||||
int cur_material = -1;
|
||||
bool has_uv = (triangles.size() && (triangles[0].attr & TEXCOORD) == TEXCOORD);
|
||||
|
||||
if (!file)
|
||||
{
|
||||
printf("write_obj: can't write data file \"%s\".\n", filename);
|
||||
exit(0);
|
||||
}
|
||||
if (!mtllib.empty())
|
||||
{
|
||||
fprintf(file, "mtllib %s\n", mtllib.c_str());
|
||||
}
|
||||
loopi(0,vertices.size())
|
||||
{
|
||||
//fprintf(file, "v %lf %lf %lf\n", vertices[i].p.x,vertices[i].p.y,vertices[i].p.z);
|
||||
fprintf(file, "v %g %g %g\n", vertices[i].p.x,vertices[i].p.y,vertices[i].p.z); //more compact: remove trailing zeros
|
||||
}
|
||||
if (has_uv)
|
||||
{
|
||||
loopi(0,triangles.size()) if(!triangles[i].deleted)
|
||||
{
|
||||
fprintf(file, "vt %g %g\n", triangles[i].uvs[0].x, triangles[i].uvs[0].y);
|
||||
fprintf(file, "vt %g %g\n", triangles[i].uvs[1].x, triangles[i].uvs[1].y);
|
||||
fprintf(file, "vt %g %g\n", triangles[i].uvs[2].x, triangles[i].uvs[2].y);
|
||||
}
|
||||
}
|
||||
int uv = 1;
|
||||
loopi(0,triangles.size()) if(!triangles[i].deleted)
|
||||
{
|
||||
if (triangles[i].material != cur_material)
|
||||
{
|
||||
cur_material = triangles[i].material;
|
||||
fprintf(file, "usemtl %s\n", materials[triangles[i].material].c_str());
|
||||
}
|
||||
if (has_uv)
|
||||
{
|
||||
fprintf(file, "f %d/%d %d/%d %d/%d\n", triangles[i].v[0]+1, uv, triangles[i].v[1]+1, uv+1, triangles[i].v[2]+1, uv+2);
|
||||
uv += 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(file, "f %d %d %d\n", triangles[i].v[0]+1, triangles[i].v[1]+1, triangles[i].v[2]+1);
|
||||
}
|
||||
//fprintf(file, "f %d// %d// %d//\n", triangles[i].v[0]+1, triangles[i].v[1]+1, triangles[i].v[2]+1); //more compact: remove trailing zeros
|
||||
}
|
||||
fclose(file);
|
||||
}
|
||||
};
|
||||
///////////////////////////////////////////
|
||||
|
|
|
@ -171,8 +171,6 @@ int main(int argc, char **argv) {
|
|||
t1.v[0] = cols * (y + 1) + x;
|
||||
t1.v[1] = cols * y + x + 1;
|
||||
t1.v[2] = cols * y + x;
|
||||
t1.attr = 0;
|
||||
t1.material = -1;
|
||||
|
||||
Simplify::triangles.push_back(t1);
|
||||
|
||||
|
@ -180,8 +178,6 @@ int main(int argc, char **argv) {
|
|||
t2.v[0] = cols * (y + 1) + x;
|
||||
t2.v[1] = cols * (y + 1) + x + 1;
|
||||
t2.v[2] = cols * y + x + 1;
|
||||
t2.attr = 0;
|
||||
t2.material = -1;
|
||||
|
||||
Simplify::triangles.push_back(t2);
|
||||
}
|
||||
|
|
Ładowanie…
Reference in New Issue