Updated to reflect the Normal() -> TriangleNormal() change
This commit is contained in:
parent
62af567808
commit
63e67d5131
|
@ -8,7 +8,7 @@
|
||||||
* \ *
|
* \ *
|
||||||
* All rights reserved. *
|
* All rights reserved. *
|
||||||
* *
|
* *
|
||||||
* This program is free software; you can redistribute it and/or modify *
|
* This program is free software; you can redistribute it and/or modify *
|
||||||
* it under the terms of the GNU General Public License as published by *
|
* it under the terms of the GNU General Public License as published by *
|
||||||
* the Free Software Foundation; either version 2 of the License, or *
|
* the Free Software Foundation; either version 2 of the License, or *
|
||||||
* (at your option) any later version. *
|
* (at your option) any later version. *
|
||||||
|
@ -64,14 +64,14 @@ namespace vcg {
|
||||||
namespace tri {
|
namespace tri {
|
||||||
namespace io {
|
namespace io {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
This class encapsulate a filter for opening stl (sterolitograpy) meshes.
|
This class encapsulate a filter for opening stl (sterolitograpy) meshes.
|
||||||
The stl format is quite simple and rather un-flexible. It just stores, in ascii or binary the, unindexed, geometry of the faces.
|
The stl format is quite simple and rather un-flexible. It just stores, in ascii or binary the, unindexed, geometry of the faces.
|
||||||
*/
|
*/
|
||||||
template <class SaveMeshType>
|
template <class SaveMeshType>
|
||||||
class ExporterSTL
|
class ExporterSTL
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef typename SaveMeshType::FaceType FaceType;
|
typedef typename SaveMeshType::FaceType FaceType;
|
||||||
typedef unsigned short CallBackSTLFaceAttribute(const SaveMeshType &m, const FaceType &f);
|
typedef unsigned short CallBackSTLFaceAttribute(const SaveMeshType &m, const FaceType &f);
|
||||||
|
|
||||||
|
@ -83,75 +83,75 @@ static int Save(SaveMeshType &m, const char * filename, const int &mask, CallBac
|
||||||
static int Save(SaveMeshType &m, const char * filename , bool binary =true, int mask=0, const char *objectname=0, bool magicsMode=0)
|
static int Save(SaveMeshType &m, const char * filename , bool binary =true, int mask=0, const char *objectname=0, bool magicsMode=0)
|
||||||
{
|
{
|
||||||
typedef typename SaveMeshType::FaceIterator FaceIterator;
|
typedef typename SaveMeshType::FaceIterator FaceIterator;
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
|
|
||||||
fp = fopen(filename,"wb");
|
fp = fopen(filename,"wb");
|
||||||
if(fp==0)
|
if(fp==0)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
if(binary)
|
if(binary)
|
||||||
{
|
{
|
||||||
// Write Header
|
// Write Header
|
||||||
char header[128]="VCG ";
|
char header[128]="VCG ";
|
||||||
if(objectname) strncpy(header,objectname,80);
|
if(objectname) strncpy(header,objectname,80);
|
||||||
if(magicsMode)
|
if(magicsMode)
|
||||||
{
|
{
|
||||||
strncpy(header,"COLOR=XXX MATERIAL=AAA BBB CCC ",80);
|
strncpy(header,"COLOR=XXX MATERIAL=AAA BBB CCC ",80);
|
||||||
for(int i=0;i<3;++i)
|
for(int i=0;i<3;++i)
|
||||||
{
|
{
|
||||||
header[0x06+i]=0x7f;
|
header[0x06+i]=0x7f;
|
||||||
header[0x13+i]=0x7f;
|
header[0x13+i]=0x7f;
|
||||||
header[0x17+i]=0x7f;
|
header[0x17+i]=0x7f;
|
||||||
header[0x1b+i]=0x7f;
|
header[0x1b+i]=0x7f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fwrite(header,80,1,fp);
|
fwrite(header,80,1,fp);
|
||||||
// write number of facets
|
// write number of facets
|
||||||
fwrite(&m.fn,1,sizeof(int),fp);
|
fwrite(&m.fn,1,sizeof(int),fp);
|
||||||
Point3f p;
|
Point3f p;
|
||||||
unsigned short attributes=0;
|
unsigned short attributes=0;
|
||||||
for(FaceIterator fi=m.face.begin(); fi!=m.face.end(); ++fi) if( !(*fi).IsD() )
|
for(FaceIterator fi=m.face.begin(); fi!=m.face.end(); ++fi) if( !(*fi).IsD() )
|
||||||
{
|
{
|
||||||
// For each triangle write the normal, the three coords and a short set to zero
|
// For each triangle write the normal, the three coords and a short set to zero
|
||||||
p.Import(vcg::NormalizedNormal(*fi));
|
p.Import(vcg::TriangleNormal(*fi).Normalize());
|
||||||
fwrite(p.V(),3,sizeof(float),fp);
|
fwrite(p.V(),3,sizeof(float),fp);
|
||||||
|
|
||||||
for(int k=0;k<3;++k){
|
|
||||||
p.Import((*fi).V(k)->P());
|
|
||||||
fwrite(p.V(),3,sizeof(float),fp);
|
|
||||||
}
|
|
||||||
if ((mask & Mask::IOM_FACECOLOR) && tri::HasPerFaceColor(m))
|
|
||||||
{
|
|
||||||
if(magicsMode) attributes = 32768 | vcg::Color4b::ToUnsignedR5G5B5(fi->C());
|
|
||||||
else attributes = 32768 | vcg::Color4b::ToUnsignedB5G5R5(fi->C());
|
|
||||||
}
|
|
||||||
fwrite(&attributes,1,sizeof(short),fp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if(objectname) fprintf(fp,"solid %s\n",objectname);
|
|
||||||
else fprintf(fp,"solid vcg\n");
|
|
||||||
|
|
||||||
Point3f p;
|
for(int k=0;k<3;++k){
|
||||||
FaceIterator fi;
|
p.Import((*fi).V(k)->P());
|
||||||
for(fi=m.face.begin(); fi!=m.face.end(); ++fi) if( !(*fi).IsD() )
|
fwrite(p.V(),3,sizeof(float),fp);
|
||||||
{
|
}
|
||||||
// For each triangle write the normal, the three coords and a short set to zero
|
if ((mask & Mask::IOM_FACECOLOR) && tri::HasPerFaceColor(m))
|
||||||
p.Import(vcg::NormalizedNormal(*fi));
|
{
|
||||||
fprintf(fp," facet normal %13e %13e %13e\n",p[0],p[1],p[2]);
|
if(magicsMode) attributes = 32768 | vcg::Color4b::ToUnsignedR5G5B5(fi->C());
|
||||||
fprintf(fp," outer loop\n");
|
else attributes = 32768 | vcg::Color4b::ToUnsignedB5G5R5(fi->C());
|
||||||
for(int k=0;k<3;++k){
|
}
|
||||||
p.Import((*fi).V(k)->P());
|
fwrite(&attributes,1,sizeof(short),fp);
|
||||||
fprintf(fp," vertex %13e %13e %13e\n",p[0],p[1],p[2]);
|
}
|
||||||
}
|
}
|
||||||
fprintf(fp," endloop\n");
|
else
|
||||||
fprintf(fp," endfacet\n");
|
{
|
||||||
}
|
if(objectname) fprintf(fp,"solid %s\n",objectname);
|
||||||
fprintf(fp,"endsolid vcg\n");
|
else fprintf(fp,"solid vcg\n");
|
||||||
}
|
|
||||||
fclose(fp);
|
Point3f p;
|
||||||
return 0;
|
FaceIterator fi;
|
||||||
|
for(fi=m.face.begin(); fi!=m.face.end(); ++fi) if( !(*fi).IsD() )
|
||||||
|
{
|
||||||
|
// For each triangle write the normal, the three coords and a short set to zero
|
||||||
|
p.Import(TriangleNormal(*fi).Normalize());
|
||||||
|
fprintf(fp," facet normal %13e %13e %13e\n",p[0],p[1],p[2]);
|
||||||
|
fprintf(fp," outer loop\n");
|
||||||
|
for(int k=0;k<3;++k){
|
||||||
|
p.Import((*fi).V(k)->P());
|
||||||
|
fprintf(fp," vertex %13e %13e %13e\n",p[0],p[1],p[2]);
|
||||||
|
}
|
||||||
|
fprintf(fp," endloop\n");
|
||||||
|
fprintf(fp," endfacet\n");
|
||||||
|
}
|
||||||
|
fprintf(fp,"endsolid vcg\n");
|
||||||
|
}
|
||||||
|
fclose(fp);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
static const char *ErrorMsg(int error)
|
static const char *ErrorMsg(int error)
|
||||||
{
|
{
|
||||||
|
@ -160,7 +160,7 @@ static const char *ErrorMsg(int error)
|
||||||
{
|
{
|
||||||
stl_error_msg.resize(2 );
|
stl_error_msg.resize(2 );
|
||||||
stl_error_msg[0]="No errors";
|
stl_error_msg[0]="No errors";
|
||||||
stl_error_msg[1]="Can't open file";
|
stl_error_msg[1]="Can't open file";
|
||||||
}
|
}
|
||||||
|
|
||||||
if(error>1 || error<0) return "Unknown error";
|
if(error>1 || error<0) return "Unknown error";
|
||||||
|
@ -168,15 +168,15 @@ static const char *ErrorMsg(int error)
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
returns mask of capability one define with what are the saveable information of the format.
|
returns mask of capability one define with what are the saveable information of the format.
|
||||||
*/
|
*/
|
||||||
static int GetExportMaskCapability()
|
static int GetExportMaskCapability()
|
||||||
{
|
{
|
||||||
int capability = 0;
|
int capability = 0;
|
||||||
capability |= vcg::tri::io::Mask::IOM_VERTCOORD;
|
capability |= vcg::tri::io::Mask::IOM_VERTCOORD;
|
||||||
capability |= vcg::tri::io::Mask::IOM_FACEINDEX;
|
capability |= vcg::tri::io::Mask::IOM_FACEINDEX;
|
||||||
capability |= vcg::tri::io::Mask::IOM_FACECOLOR;
|
capability |= vcg::tri::io::Mask::IOM_FACECOLOR;
|
||||||
return capability;
|
return capability;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -57,7 +57,7 @@ namespace vcg {
|
||||||
typedef typename OpenMeshType::VertexPointer VertexPointer;
|
typedef typename OpenMeshType::VertexPointer VertexPointer;
|
||||||
typedef typename OpenMeshType::ScalarType ScalarType;
|
typedef typename OpenMeshType::ScalarType ScalarType;
|
||||||
typedef typename OpenMeshType::VertexType VertexType;
|
typedef typename OpenMeshType::VertexType VertexType;
|
||||||
typedef typename OpenMeshType::EdgeType EdgeType;
|
typedef typename OpenMeshType::EdgeType EdgeType;
|
||||||
typedef typename OpenMeshType::FaceType FaceType;
|
typedef typename OpenMeshType::FaceType FaceType;
|
||||||
typedef typename OpenMeshType::VertexIterator VertexIterator;
|
typedef typename OpenMeshType::VertexIterator VertexIterator;
|
||||||
typedef typename OpenMeshType::FaceIterator FaceIterator;
|
typedef typename OpenMeshType::FaceIterator FaceIterator;
|
||||||
|
@ -83,8 +83,8 @@ namespace vcg {
|
||||||
|
|
||||||
/// number of vertices
|
/// number of vertices
|
||||||
int numVertices;
|
int numVertices;
|
||||||
/// number of edges
|
/// number of edges
|
||||||
int numEdges;
|
int numEdges;
|
||||||
/// number of faces (the number of triangles could be
|
/// number of faces (the number of triangles could be
|
||||||
/// larger in presence of polygonal faces
|
/// larger in presence of polygonal faces
|
||||||
int numFaces;
|
int numFaces;
|
||||||
|
@ -115,11 +115,11 @@ namespace vcg {
|
||||||
Color4b c;
|
Color4b c;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ObjEdge
|
struct ObjEdge
|
||||||
{
|
{
|
||||||
int v0;
|
int v0;
|
||||||
int v1;
|
int v1;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ObjTexCoord
|
struct ObjTexCoord
|
||||||
{
|
{
|
||||||
|
@ -269,7 +269,7 @@ namespace vcg {
|
||||||
materials.push_back(defaultMaterial);
|
materials.push_back(defaultMaterial);
|
||||||
|
|
||||||
int numVertices = 0; // stores the number of vertices been read till now
|
int numVertices = 0; // stores the number of vertices been read till now
|
||||||
int numEdges = 0; // stores the number of edges read till now
|
int numEdges = 0; // stores the number of edges read till now
|
||||||
int numTriangles = 0; // stores the number of faces been read till now
|
int numTriangles = 0; // stores the number of faces been read till now
|
||||||
int numTexCoords = 0; // stores the number of texture coordinates been read till now
|
int numTexCoords = 0; // stores the number of texture coordinates been read till now
|
||||||
int numVNormals = 0; // stores the number of vertex normals been read till now
|
int numVNormals = 0; // stores the number of vertex normals been read till now
|
||||||
|
@ -279,8 +279,8 @@ namespace vcg {
|
||||||
// vertices and faces allocation
|
// vertices and faces allocation
|
||||||
VertexIterator vi = vcg::tri::Allocator<OpenMeshType>::AddVertices(m,oi.numVertices);
|
VertexIterator vi = vcg::tri::Allocator<OpenMeshType>::AddVertices(m,oi.numVertices);
|
||||||
//FaceIterator fi = Allocator<OpenMeshType>::AddFaces(m,oi.numFaces);
|
//FaceIterator fi = Allocator<OpenMeshType>::AddFaces(m,oi.numFaces);
|
||||||
// edges found
|
// edges found
|
||||||
std::vector<ObjEdge> ev;
|
std::vector<ObjEdge> ev;
|
||||||
std::vector<Color4b> vertexColorVector;
|
std::vector<Color4b> vertexColorVector;
|
||||||
ObjIndexedFace ff;
|
ObjIndexedFace ff;
|
||||||
const char *loadingStr = "Loading";
|
const char *loadingStr = "Loading";
|
||||||
|
@ -370,22 +370,22 @@ namespace vcg {
|
||||||
|
|
||||||
numVNormals++;
|
numVNormals++;
|
||||||
}
|
}
|
||||||
else if ( header.compare("l")==0 )
|
else if ( header.compare("l")==0 )
|
||||||
{
|
{
|
||||||
loadingStr = "Edge Loading";
|
loadingStr = "Edge Loading";
|
||||||
|
|
||||||
if (numTokens < 3)
|
if (numTokens < 3)
|
||||||
{
|
{
|
||||||
result = E_LESS_THAN_3_VERT_IN_FACE; // TODO add proper/handling error code
|
result = E_LESS_THAN_3_VERT_IN_FACE; // TODO add proper/handling error code
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjEdge e = { (atoi(tokens[1].c_str()) - 1),
|
ObjEdge e = { (atoi(tokens[1].c_str()) - 1),
|
||||||
(atoi(tokens[2].c_str()) - 1) };
|
(atoi(tokens[2].c_str()) - 1) };
|
||||||
ev.push_back(e);
|
ev.push_back(e);
|
||||||
|
|
||||||
numEdges++;
|
numEdges++;
|
||||||
}
|
}
|
||||||
else if( (header.compare("f")==0) || (header.compare("q")==0) ) // face
|
else if( (header.compare("f")==0) || (header.compare("q")==0) ) // face
|
||||||
{
|
{
|
||||||
loadingStr="Face Loading";
|
loadingStr="Face Loading";
|
||||||
|
@ -634,26 +634,26 @@ namespace vcg {
|
||||||
assert((numTriangles +numVertices) == numVerticesPlusFaces+extraTriangles);
|
assert((numTriangles +numVertices) == numVerticesPlusFaces+extraTriangles);
|
||||||
vcg::tri::Allocator<OpenMeshType>::AddFaces(m,numTriangles);
|
vcg::tri::Allocator<OpenMeshType>::AddFaces(m,numTriangles);
|
||||||
|
|
||||||
// Add found edges
|
// Add found edges
|
||||||
if (numEdges > 0)
|
if (numEdges > 0)
|
||||||
{
|
{
|
||||||
vcg::tri::Allocator<OpenMeshType>::AddEdges(m,numEdges);
|
vcg::tri::Allocator<OpenMeshType>::AddEdges(m,numEdges);
|
||||||
|
|
||||||
assert(m.edge.size() == size_t(m.en));
|
assert(m.edge.size() == size_t(m.en));
|
||||||
|
|
||||||
for(int i=0; i<numEdges; ++i)
|
for(int i=0; i<numEdges; ++i)
|
||||||
{
|
{
|
||||||
ObjEdge & e = ev[i];
|
ObjEdge & e = ev[i];
|
||||||
EdgeType & edge = m.edge[i];
|
EdgeType & edge = m.edge[i];
|
||||||
|
|
||||||
assert(e.v0 >= 0 && size_t(e.v0) < m.vert.size() &&
|
assert(e.v0 >= 0 && size_t(e.v0) < m.vert.size() &&
|
||||||
e.v1 >= 0 && size_t(e.v1) < m.vert.size());
|
e.v1 >= 0 && size_t(e.v1) < m.vert.size());
|
||||||
// TODO add proper handling of bad indices
|
// TODO add proper handling of bad indices
|
||||||
|
|
||||||
edge.V(0) = &(m.vert[e.v0]);
|
edge.V(0) = &(m.vert[e.v0]);
|
||||||
edge.V(1) = &(m.vert[e.v1]);
|
edge.V(1) = &(m.vert[e.v1]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//-------------------------------------------------------------------------------
|
//-------------------------------------------------------------------------------
|
||||||
|
|
||||||
// Now the final passes:
|
// Now the final passes:
|
||||||
|
@ -710,7 +710,7 @@ namespace vcg {
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
face::ComputeNormalizedNormal(m.face[i]);
|
m.face[i].N().Import(TriangleNormal(m.face[i]).Normalize());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -978,7 +978,7 @@ namespace vcg {
|
||||||
bool bHasPerVertexColor = false;
|
bool bHasPerVertexColor = false;
|
||||||
|
|
||||||
oi.numVertices=0;
|
oi.numVertices=0;
|
||||||
oi.numEdges=0;
|
oi.numEdges=0;
|
||||||
oi.numFaces=0;
|
oi.numFaces=0;
|
||||||
oi.numTexCoords=0;
|
oi.numTexCoords=0;
|
||||||
oi.numNormals=0;
|
oi.numNormals=0;
|
||||||
|
@ -1011,8 +1011,8 @@ namespace vcg {
|
||||||
else {
|
else {
|
||||||
if((line[0]=='f') || (line[0]=='q')) oi.numFaces++;
|
if((line[0]=='f') || (line[0]=='q')) oi.numFaces++;
|
||||||
else
|
else
|
||||||
if (line[0]=='l') oi.numEdges++;
|
if (line[0]=='l') oi.numEdges++;
|
||||||
else
|
else
|
||||||
if(line[0]=='u' && line[1]=='s') bHasPerFaceColor = true; // there is a usematerial so add per face color
|
if(line[0]=='u' && line[1]=='s') bHasPerFaceColor = true; // there is a usematerial so add per face color
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1035,8 +1035,8 @@ namespace vcg {
|
||||||
else
|
else
|
||||||
oi.mask |= vcg::tri::io::Mask::IOM_WEDGNORMAL;
|
oi.mask |= vcg::tri::io::Mask::IOM_WEDGNORMAL;
|
||||||
}
|
}
|
||||||
if (oi.numEdges)
|
if (oi.numEdges)
|
||||||
oi.mask |= vcg::tri::io::Mask::IOM_EDGEINDEX;
|
oi.mask |= vcg::tri::io::Mask::IOM_EDGEINDEX;
|
||||||
|
|
||||||
stream.close();
|
stream.close();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue