- fixed "if there is color both vertex/face colors are enabled even if there is just one of them" bug
This commit is contained in:
parent
8b90ba72a3
commit
20fa52181f
|
|
@ -111,7 +111,7 @@ static void WedgeTexFromVertexTex(ComputeMeshType &m)
|
||||||
{
|
{
|
||||||
(*fi).WT(i).U() = (*fi).V(i)->T().U();
|
(*fi).WT(i).U() = (*fi).V(i)->T().U();
|
||||||
(*fi).WT(i).V() = (*fi).V(i)->T().V();
|
(*fi).WT(i).V() = (*fi).V(i)->T().V();
|
||||||
//(*fi).WT(i).N() = 0;
|
(*fi).WT(i).N() = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -29,19 +29,19 @@
|
||||||
#include <wrap/io_trimesh/io_fan_tessellator.h>
|
#include <wrap/io_trimesh/io_fan_tessellator.h>
|
||||||
|
|
||||||
namespace vcg {
|
namespace vcg {
|
||||||
namespace tri {
|
namespace tri {
|
||||||
namespace io {
|
namespace io {
|
||||||
|
|
||||||
// /** \addtogroup */
|
// /** \addtogroup */
|
||||||
// /* @{ */
|
// /* @{ */
|
||||||
/**
|
/**
|
||||||
This class encapsulate a filter for importing OFF meshes.
|
This class encapsulate a filter for importing OFF meshes.
|
||||||
A basic description of the OFF file format can be found at http://www.geomview.org/docs/html/geomview_41.html
|
A basic description of the OFF file format can be found at http://www.geomview.org/docs/html/geomview_41.html
|
||||||
*/
|
*/
|
||||||
template<class MESH_TYPE>
|
template<class MESH_TYPE>
|
||||||
class ImporterOFF
|
class ImporterOFF
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
typedef typename MESH_TYPE::VertexType VertexType;
|
typedef typename MESH_TYPE::VertexType VertexType;
|
||||||
typedef typename MESH_TYPE::VertexIterator VertexIterator;
|
typedef typename MESH_TYPE::VertexIterator VertexIterator;
|
||||||
|
|
@ -53,9 +53,11 @@ public:
|
||||||
typedef typename MESH_TYPE::ScalarType ScalarType;
|
typedef typename MESH_TYPE::ScalarType ScalarType;
|
||||||
|
|
||||||
// OFF codes
|
// OFF codes
|
||||||
enum OFFCodes {NoError=0, CantOpen, InvalidFile,
|
enum OFFCodes {
|
||||||
|
NoError = 0, CantOpen, InvalidFile,
|
||||||
InvalidFile_MissingOFF,
|
InvalidFile_MissingOFF,
|
||||||
UnsupportedFormat, ErrorNotTriangularFace,ErrorHighDimension,ErrorDegenerateFace};
|
UnsupportedFormat, ErrorNotTriangularFace, ErrorHighDimension, ErrorDegenerateFace
|
||||||
|
};
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Standard call for knowing the meaning of an error code
|
* Standard call for knowing the meaning of an error code
|
||||||
|
|
@ -70,7 +72,7 @@ public:
|
||||||
"Invalid file: OFF file should have in the first line the OFF keyword as a first token",
|
"Invalid file: OFF file should have in the first line the OFF keyword as a first token",
|
||||||
"Unsupported format", "Face with more than 3 vertices","File with high dimensional vertexes are not supported", "Error Degenerate Face with less than 3 vertices" };
|
"Unsupported format", "Face with more than 3 vertices","File with high dimensional vertexes are not supported", "Error Degenerate Face with less than 3 vertices" };
|
||||||
|
|
||||||
if(message_code>6 || message_code<0)
|
if (message_code > 6 || message_code < 0)
|
||||||
return "Unknown error";
|
return "Unknown error";
|
||||||
else
|
else
|
||||||
return error_msg[message_code];
|
return error_msg[message_code];
|
||||||
|
|
@ -87,24 +89,24 @@ public:
|
||||||
{
|
{
|
||||||
// To obtain the loading mask all the file must be parsed
|
// To obtain the loading mask all the file must be parsed
|
||||||
// to distinguish between per-vertex and per-face color attribute.
|
// to distinguish between per-vertex and per-face color attribute.
|
||||||
loadmask=0;
|
loadmask = 0;
|
||||||
MESH_TYPE dummyMesh;
|
MESH_TYPE dummyMesh;
|
||||||
return (Open(dummyMesh, filename, loadmask)==NoError);
|
return (Open(dummyMesh, filename, loadmask) == NoError);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int Open(MESH_TYPE &mesh, const char *filename,CallBackPos *cb=0)
|
static int Open(MESH_TYPE &mesh, const char *filename, CallBackPos *cb = 0)
|
||||||
{
|
{
|
||||||
int loadmask;
|
int loadmask;
|
||||||
return Open(mesh,filename,loadmask,cb);
|
return Open(mesh, filename, loadmask, cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int OpenMem(MESH_TYPE &mesh, const char *mem, size_t sz, int &loadmask,
|
static int OpenMem(MESH_TYPE &mesh, const char *mem, size_t sz, int &loadmask,
|
||||||
CallBackPos *cb=0)
|
CallBackPos *cb = 0)
|
||||||
{
|
{
|
||||||
std::string str;
|
std::string str;
|
||||||
str.append(mem,sz);
|
str.append(mem, sz);
|
||||||
std::istringstream strm(str);
|
std::istringstream strm(str);
|
||||||
return OpenStream(mesh,strm,loadmask,cb);
|
return OpenStream(mesh, strm, loadmask, cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
|
@ -115,20 +117,20 @@ public:
|
||||||
* \return the operation result
|
* \return the operation result
|
||||||
*/
|
*/
|
||||||
static int Open(MESH_TYPE &mesh, const char *filename, int &loadmask,
|
static int Open(MESH_TYPE &mesh, const char *filename, int &loadmask,
|
||||||
CallBackPos *cb=0)
|
CallBackPos *cb = 0)
|
||||||
{
|
{
|
||||||
std::ifstream stream(filename);
|
std::ifstream stream(filename);
|
||||||
if (stream.fail())
|
if (stream.fail())
|
||||||
return CantOpen;
|
return CantOpen;
|
||||||
return OpenStream(mesh,stream,loadmask,cb);
|
return OpenStream(mesh, stream, loadmask, cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int OpenStream(MESH_TYPE &mesh, std::istream &stream, int &loadmask,
|
static int OpenStream(MESH_TYPE &mesh, std::istream &stream, int &loadmask,
|
||||||
CallBackPos *cb=0)
|
CallBackPos *cb = 0)
|
||||||
{
|
{
|
||||||
std::vector< std::string > tokens;
|
std::vector< std::string > tokens;
|
||||||
TokenizeNextLine(stream, tokens);
|
TokenizeNextLine(stream, tokens);
|
||||||
if(tokens.empty()) return InvalidFile_MissingOFF;
|
if (tokens.empty()) return InvalidFile_MissingOFF;
|
||||||
|
|
||||||
bool isNormalDefined = false;
|
bool isNormalDefined = false;
|
||||||
bool isColorDefined = false;
|
bool isColorDefined = false;
|
||||||
|
|
@ -164,21 +166,26 @@ public:
|
||||||
std::string header = tokens[0];
|
std::string header = tokens[0];
|
||||||
if (header.rfind("OFF") != std::basic_string<char>::npos)
|
if (header.rfind("OFF") != std::basic_string<char>::npos)
|
||||||
{ // the OFF string is in the header go on parsing it.
|
{ // the OFF string is in the header go on parsing it.
|
||||||
for (int u = static_cast<int>(header.rfind("OFF")-1); u>=0; u--)
|
for (int u = static_cast<int>(header.rfind("OFF") - 1); u >= 0; u--)
|
||||||
{
|
{
|
||||||
if (header[u] == 'C') isColorDefined = true;
|
if (header[u] == 'C')
|
||||||
else if (header[u] == 'N') isNormalDefined = true;
|
isColorDefined = true;
|
||||||
else if (u>0 && header[u-1] == 'S' && header[u] == 'T') isTexCoordDefined = true;
|
else if (header[u] == 'N')
|
||||||
else if (header[u] == '4') homogeneousComponents = true;
|
isNormalDefined = true;
|
||||||
else if (header[u] == 'n') return ErrorHighDimension;
|
else if (u > 0 && header[u - 1] == 'S' && header[u] == 'T')
|
||||||
|
isTexCoordDefined = true;
|
||||||
|
else if (header[u] == '4')
|
||||||
|
homogeneousComponents = true;
|
||||||
|
else if (header[u] == 'n')
|
||||||
|
return ErrorHighDimension;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else return InvalidFile_MissingOFF;
|
else return InvalidFile_MissingOFF;
|
||||||
|
|
||||||
// If the file is slightly malformed and it has nvert and nface AFTER the OFF string instead of in the next line
|
// If the file is slightly malformed and it has nvert and nface AFTER the OFF string instead of in the next line
|
||||||
// we manage it here...
|
// we manage it here...
|
||||||
if(tokens.size()==1) TokenizeNextLine(stream, tokens);
|
if (tokens.size() == 1) TokenizeNextLine(stream, tokens);
|
||||||
else tokens.erase(tokens.begin(),tokens.begin()+1);
|
else tokens.erase(tokens.begin(), tokens.begin() + 1);
|
||||||
|
|
||||||
// Update loading mask
|
// Update loading mask
|
||||||
///////////////////////////////////////
|
///////////////////////////////////////
|
||||||
|
|
@ -187,7 +194,7 @@ public:
|
||||||
|
|
||||||
if (isNormalDefined) loadmask |= Mask::IOM_VERTNORMAL;
|
if (isNormalDefined) loadmask |= Mask::IOM_VERTNORMAL;
|
||||||
if (isTexCoordDefined) loadmask |= Mask::IOM_VERTTEXCOORD;
|
if (isTexCoordDefined) loadmask |= Mask::IOM_VERTTEXCOORD;
|
||||||
if (isColorDefined) { loadmask |= Mask::IOM_VERTCOLOR;loadmask |= Mask::IOM_FACECOLOR;}
|
//if (isColorDefined) { loadmask |= Mask::IOM_VERTCOLOR;loadmask |= Mask::IOM_FACECOLOR;}
|
||||||
|
|
||||||
|
|
||||||
//if(onlyMaskFlag) return NoError;
|
//if(onlyMaskFlag) return NoError;
|
||||||
|
|
@ -196,7 +203,7 @@ public:
|
||||||
mesh.Clear();
|
mesh.Clear();
|
||||||
|
|
||||||
// check on next 2 lines to detect corrupted files
|
// check on next 2 lines to detect corrupted files
|
||||||
if(tokens.size() < 3)
|
if (tokens.size() < 3)
|
||||||
return InvalidFile;
|
return InvalidFile;
|
||||||
|
|
||||||
unsigned int nVertices, nFaces, nEdges;
|
unsigned int nVertices, nFaces, nEdges;
|
||||||
|
|
@ -218,13 +225,13 @@ public:
|
||||||
TokenizeNextLine(stream, tokens);
|
TokenizeNextLine(stream, tokens);
|
||||||
size_t k = 0; // next token to read
|
size_t k = 0; // next token to read
|
||||||
|
|
||||||
for (unsigned int i=0; i<nVertices; i++, v_iter++)
|
for (unsigned int i = 0; i < nVertices; i++, v_iter++)
|
||||||
{
|
{
|
||||||
if (cb && (i%1000)==0)
|
if (cb && (i % 1000) == 0)
|
||||||
cb(i*50/nVertices, "Vertex Loading");
|
cb(i * 50 / nVertices, "Vertex Loading");
|
||||||
|
|
||||||
// Read 3 vertex coordinates
|
// Read 3 vertex coordinates
|
||||||
for (unsigned int j=0; j<3; j++)
|
for (unsigned int j = 0; j < 3; j++)
|
||||||
{
|
{
|
||||||
// Go to next line when needed
|
// Go to next line when needed
|
||||||
if (k == tokens.size()) // if EOL
|
if (k == tokens.size()) // if EOL
|
||||||
|
|
@ -236,14 +243,14 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read vertex coordinate
|
// Read vertex coordinate
|
||||||
(*v_iter).P()[j] = (ScalarType) atof(tokens[k].c_str());
|
(*v_iter).P()[j] = (ScalarType)atof(tokens[k].c_str());
|
||||||
k++;
|
k++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isNormalDefined)
|
if (isNormalDefined)
|
||||||
{
|
{
|
||||||
// Read 3 normal coordinates
|
// Read 3 normal coordinates
|
||||||
for (unsigned int j=0; j<3; j++)
|
for (unsigned int j = 0; j < 3; j++)
|
||||||
{
|
{
|
||||||
// Go to next line when needed
|
// Go to next line when needed
|
||||||
if (k == tokens.size()) // if EOL
|
if (k == tokens.size()) // if EOL
|
||||||
|
|
@ -255,7 +262,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read normal coordinate
|
// Read normal coordinate
|
||||||
(*v_iter).N()[j] = (ScalarType) atof(tokens[k].c_str());
|
(*v_iter).N()[j] = (ScalarType)atof(tokens[k].c_str());
|
||||||
k++;
|
k++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -297,9 +304,9 @@ public:
|
||||||
unsigned char r =
|
unsigned char r =
|
||||||
static_cast<unsigned char>(atoi(tokens[k].c_str()));
|
static_cast<unsigned char>(atoi(tokens[k].c_str()));
|
||||||
unsigned char g =
|
unsigned char g =
|
||||||
static_cast<unsigned char>(atoi(tokens[k+1].c_str()));
|
static_cast<unsigned char>(atoi(tokens[k + 1].c_str()));
|
||||||
unsigned char b =
|
unsigned char b =
|
||||||
static_cast<unsigned char>(atoi(tokens[k+2].c_str()));
|
static_cast<unsigned char>(atoi(tokens[k + 2].c_str()));
|
||||||
|
|
||||||
vcg::Color4b color(r, g, b, 255);
|
vcg::Color4b color(r, g, b, 255);
|
||||||
(*v_iter).C().Import(color);
|
(*v_iter).C().Import(color);
|
||||||
|
|
@ -308,8 +315,8 @@ public:
|
||||||
{
|
{
|
||||||
// floats
|
// floats
|
||||||
float r = static_cast<float>(atof(tokens[k].c_str()));
|
float r = static_cast<float>(atof(tokens[k].c_str()));
|
||||||
float g = static_cast<float>(atof(tokens[k+1].c_str()));
|
float g = static_cast<float>(atof(tokens[k + 1].c_str()));
|
||||||
float b = static_cast<float>(atof(tokens[k+2].c_str()));
|
float b = static_cast<float>(atof(tokens[k + 2].c_str()));
|
||||||
|
|
||||||
vcg::Color4f color(r, g, b, 1.0);
|
vcg::Color4f color(r, g, b, 1.0);
|
||||||
(*v_iter).C().Import(color);
|
(*v_iter).C().Import(color);
|
||||||
|
|
@ -324,11 +331,11 @@ public:
|
||||||
unsigned char r =
|
unsigned char r =
|
||||||
static_cast<unsigned char>(atoi(tokens[k].c_str()));
|
static_cast<unsigned char>(atoi(tokens[k].c_str()));
|
||||||
unsigned char g =
|
unsigned char g =
|
||||||
static_cast<unsigned char>(atoi(tokens[k+1].c_str()));
|
static_cast<unsigned char>(atoi(tokens[k + 1].c_str()));
|
||||||
unsigned char b =
|
unsigned char b =
|
||||||
static_cast<unsigned char>(atoi(tokens[k+2].c_str()));
|
static_cast<unsigned char>(atoi(tokens[k + 2].c_str()));
|
||||||
unsigned char a =
|
unsigned char a =
|
||||||
static_cast<unsigned char>(atoi(tokens[k+3].c_str()));
|
static_cast<unsigned char>(atoi(tokens[k + 3].c_str()));
|
||||||
|
|
||||||
Color4b color(r, g, b, a);
|
Color4b color(r, g, b, a);
|
||||||
(*v_iter).C().Import(color);
|
(*v_iter).C().Import(color);
|
||||||
|
|
@ -337,9 +344,9 @@ public:
|
||||||
{
|
{
|
||||||
// floats
|
// floats
|
||||||
float r = static_cast<float>(atof(tokens[k].c_str()));
|
float r = static_cast<float>(atof(tokens[k].c_str()));
|
||||||
float g = static_cast<float>(atof(tokens[k+1].c_str()));
|
float g = static_cast<float>(atof(tokens[k + 1].c_str()));
|
||||||
float b = static_cast<float>(atof(tokens[k+2].c_str()));
|
float b = static_cast<float>(atof(tokens[k + 2].c_str()));
|
||||||
float a = static_cast<float>(atof(tokens[k+3].c_str()));
|
float a = static_cast<float>(atof(tokens[k + 3].c_str()));
|
||||||
|
|
||||||
vcg::Color4f color(r, g, b, a);
|
vcg::Color4f color(r, g, b, a);
|
||||||
(*v_iter).C().Import(color);
|
(*v_iter).C().Import(color);
|
||||||
|
|
@ -352,7 +359,7 @@ public:
|
||||||
|
|
||||||
if (isTexCoordDefined)
|
if (isTexCoordDefined)
|
||||||
{
|
{
|
||||||
for (unsigned int j=0; j<2; j++)
|
for (unsigned int j = 0; j < 2; j++)
|
||||||
{
|
{
|
||||||
// Go to next line when needed
|
// Go to next line when needed
|
||||||
if (k == tokens.size()) // if EOL
|
if (k == tokens.size()) // if EOL
|
||||||
|
|
@ -377,16 +384,16 @@ public:
|
||||||
|
|
||||||
// READ FACES
|
// READ FACES
|
||||||
//////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////
|
||||||
if(FaceType::HasPolyInfo())
|
if (FaceType::HasPolyInfo())
|
||||||
{
|
{
|
||||||
for (unsigned int f=0; f < nFaces; f++)
|
for (unsigned int f = 0; f < nFaces; f++)
|
||||||
{
|
{
|
||||||
if(cb && (f%1000)==0) cb(50+f*50/nFaces,"Face Loading");
|
if (cb && (f % 1000) == 0) cb(50 + f * 50 / nFaces, "Face Loading");
|
||||||
TokenizeNextLine(stream, tokens);
|
TokenizeNextLine(stream, tokens);
|
||||||
int vert_per_face = atoi(tokens[0].c_str());
|
int vert_per_face = atoi(tokens[0].c_str());
|
||||||
std::vector<int> vInd(vert_per_face);
|
std::vector<int> vInd(vert_per_face);
|
||||||
k = 1;
|
k = 1;
|
||||||
for (int j=0; j < vert_per_face; j++)
|
for (int j = 0; j < vert_per_face; j++)
|
||||||
{
|
{
|
||||||
if (k == tokens.size()) // if EOL // Go to next line when needed
|
if (k == tokens.size()) // if EOL // Go to next line when needed
|
||||||
{
|
{
|
||||||
|
|
@ -397,36 +404,36 @@ public:
|
||||||
vInd[j] = atoi(tokens[k].c_str());
|
vInd[j] = atoi(tokens[k].c_str());
|
||||||
k++;
|
k++;
|
||||||
}
|
}
|
||||||
if(vert_per_face==3)
|
if (vert_per_face == 3)
|
||||||
Allocator<MESH_TYPE>::AddFace(mesh, &mesh.vert[ vInd[0] ], &mesh.vert[ vInd[1] ], &mesh.vert[ vInd[2] ]);
|
Allocator<MESH_TYPE>::AddFace(mesh, &mesh.vert[vInd[0]], &mesh.vert[vInd[1]], &mesh.vert[vInd[2]]);
|
||||||
|
|
||||||
if(vert_per_face==4)
|
if (vert_per_face == 4)
|
||||||
Allocator<MESH_TYPE>::AddQuadFace(mesh, &mesh.vert[ vInd[0] ], &mesh.vert[ vInd[1] ], &mesh.vert[ vInd[2] ],&mesh.vert[ vInd[3] ]);
|
Allocator<MESH_TYPE>::AddQuadFace(mesh, &mesh.vert[vInd[0]], &mesh.vert[vInd[1]], &mesh.vert[vInd[2]], &mesh.vert[vInd[3]]);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else // Standard Triangular Mesh Loading
|
else // Standard Triangular Mesh Loading
|
||||||
{
|
{
|
||||||
Allocator<MESH_TYPE>::AddFaces(mesh, nFaces);
|
Allocator<MESH_TYPE>::AddFaces(mesh, nFaces);
|
||||||
unsigned int f0=0;
|
unsigned int f0 = 0;
|
||||||
|
|
||||||
|
|
||||||
// Initial call to the QuadTriangulate with an empty vector to just reset the static set of existing diagonals
|
// Initial call to the QuadTriangulate with an empty vector to just reset the static set of existing diagonals
|
||||||
std::vector<VertexPointer> qtmp;
|
std::vector<VertexPointer> qtmp;
|
||||||
BitQuad<MESH_TYPE>::QuadTriangulate(qtmp);
|
BitQuad<MESH_TYPE>::QuadTriangulate(qtmp);
|
||||||
|
|
||||||
for (unsigned int f=0; f < nFaces; f++)
|
for (unsigned int f = 0; f < nFaces; f++)
|
||||||
{
|
{
|
||||||
f0 = f;
|
f0 = f;
|
||||||
if (stream.fail())
|
if (stream.fail())
|
||||||
return InvalidFile;
|
return InvalidFile;
|
||||||
|
|
||||||
if(cb && (f%1000)==0)
|
if (cb && (f % 1000) == 0)
|
||||||
cb(50+f*50/nFaces,"Face Loading");
|
cb(50 + f * 50 / nFaces, "Face Loading");
|
||||||
|
|
||||||
TokenizeNextLine(stream, tokens);
|
TokenizeNextLine(stream, tokens);
|
||||||
int vert_per_face = atoi(tokens[0].c_str());
|
int vert_per_face = atoi(tokens[0].c_str());
|
||||||
if(vert_per_face < 3)
|
if (vert_per_face < 3)
|
||||||
return ErrorDegenerateFace;
|
return ErrorDegenerateFace;
|
||||||
k = 1;
|
k = 1;
|
||||||
if (vert_per_face == 3)
|
if (vert_per_face == 3)
|
||||||
|
|
@ -440,19 +447,19 @@ public:
|
||||||
k = 0;
|
k = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
mesh.face[f].V(j) = &(mesh.vert[ atoi(tokens[k].c_str()) ]);
|
mesh.face[f].V(j) = &(mesh.vert[atoi(tokens[k].c_str())]);
|
||||||
k++;
|
k++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// The face must be triangulated
|
// The face must be triangulated
|
||||||
unsigned int trigs = vert_per_face-3; // number of extra faces to add
|
unsigned int trigs = vert_per_face - 3; // number of extra faces to add
|
||||||
nFaces += trigs;
|
nFaces += trigs;
|
||||||
Allocator<MESH_TYPE>::AddFaces(mesh, trigs);
|
Allocator<MESH_TYPE>::AddFaces(mesh, trigs);
|
||||||
std::vector<int> vertIndices(vert_per_face);
|
std::vector<int> vertIndices(vert_per_face);
|
||||||
std::vector<vcg::Point3f > polygonVect(vert_per_face); // vec of polygon loops used for the triangulation of polygonal face
|
std::vector<vcg::Point3f > polygonVect(vert_per_face); // vec of polygon loops used for the triangulation of polygonal face
|
||||||
for (int j=0; j < vert_per_face; j++)
|
for (int j = 0; j < vert_per_face; j++)
|
||||||
{
|
{
|
||||||
if (k == tokens.size()) // if EOL // Go to next line when needed
|
if (k == tokens.size()) // if EOL // Go to next line when needed
|
||||||
{
|
{
|
||||||
|
|
@ -461,27 +468,27 @@ public:
|
||||||
k = 0;
|
k = 0;
|
||||||
}
|
}
|
||||||
vertIndices[j] = atoi(tokens[k].c_str());
|
vertIndices[j] = atoi(tokens[k].c_str());
|
||||||
polygonVect[j].Import<ScalarType> (mesh.vert[ vertIndices[j] ].P());
|
polygonVect[j].Import<ScalarType>(mesh.vert[vertIndices[j]].P());
|
||||||
k++;
|
k++;
|
||||||
}
|
}
|
||||||
if(vert_per_face==4)
|
if (vert_per_face == 4)
|
||||||
{ // To well triangulate use the bitquad support function that reorders vertex for a simple fan
|
{ // To well triangulate use the bitquad support function that reorders vertex for a simple fan
|
||||||
std::vector<VertexPointer> q(4);
|
std::vector<VertexPointer> q(4);
|
||||||
for(int qqi=0;qqi<4;++qqi)
|
for (int qqi = 0; qqi < 4; ++qqi)
|
||||||
q[qqi]=& mesh.vert[vertIndices[qqi]];
|
q[qqi] = &mesh.vert[vertIndices[qqi]];
|
||||||
BitQuad<MESH_TYPE>::QuadTriangulate(q);
|
BitQuad<MESH_TYPE>::QuadTriangulate(q);
|
||||||
for(int qqi=0;qqi<4;++qqi)
|
for (int qqi = 0; qqi < 4; ++qqi)
|
||||||
vertIndices[qqi] = q[qqi]- & mesh.vert[0];
|
vertIndices[qqi] = q[qqi] - &mesh.vert[0];
|
||||||
// build a two face fan
|
// build a two face fan
|
||||||
for (int j=0; j<2; j++)
|
for (int j = 0; j < 2; j++)
|
||||||
{
|
{
|
||||||
mesh.face[f+j].V(0) = &(mesh.vert[ vertIndices[0 ] ]);
|
mesh.face[f + j].V(0) = &(mesh.vert[vertIndices[0]]);
|
||||||
mesh.face[f+j].V(1) = &(mesh.vert[ vertIndices[1+j] ]);
|
mesh.face[f + j].V(1) = &(mesh.vert[vertIndices[1 + j]]);
|
||||||
mesh.face[f+j].V(2) = &(mesh.vert[ vertIndices[2+j] ]);
|
mesh.face[f + j].V(2) = &(mesh.vert[vertIndices[2 + j]]);
|
||||||
if (tri::HasPerFaceFlags(mesh)) {
|
if (tri::HasPerFaceFlags(mesh)) {
|
||||||
// tag internal polygonal edges as "faux"
|
// tag internal polygonal edges as "faux"
|
||||||
if (j>0) mesh.face[f+j].SetF(0);
|
if (j > 0) mesh.face[f + j].SetF(0);
|
||||||
if (j<vert_per_face-3) mesh.face[f+j].SetF(2);
|
if (j < vert_per_face - 3) mesh.face[f + j].SetF(2);
|
||||||
loadmask |= Mask::IOM_BITPOLYGONAL;
|
loadmask |= Mask::IOM_BITPOLYGONAL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -499,100 +506,99 @@ public:
|
||||||
//qDebug("Warning: using fan tessellation for a polygon of %i vertices",vertexesPerFace);
|
//qDebug("Warning: using fan tessellation for a polygon of %i vertices",vertexesPerFace);
|
||||||
tri::io::FanTessellator(loopVect, indexTriangulatedVect);
|
tri::io::FanTessellator(loopVect, indexTriangulatedVect);
|
||||||
#endif
|
#endif
|
||||||
for (size_t j=0; j<indexTriangulatedVect.size(); j+=3)
|
for (size_t j = 0; j < indexTriangulatedVect.size(); j += 3)
|
||||||
{
|
{
|
||||||
mesh.face[f+j/3].V(0) = &(mesh.vert[ vertIndices[ indexTriangulatedVect[j+0] ] ]);
|
mesh.face[f + j / 3].V(0) = &(mesh.vert[vertIndices[indexTriangulatedVect[j + 0]]]);
|
||||||
mesh.face[f+j/3].V(1) = &(mesh.vert[ vertIndices[ indexTriangulatedVect[j+1] ] ]);
|
mesh.face[f + j / 3].V(1) = &(mesh.vert[vertIndices[indexTriangulatedVect[j + 1]]]);
|
||||||
mesh.face[f+j/3].V(2) = &(mesh.vert[ vertIndices[ indexTriangulatedVect[j+2] ] ]);
|
mesh.face[f + j / 3].V(2) = &(mesh.vert[vertIndices[indexTriangulatedVect[j + 2]]]);
|
||||||
// To correctly set Faux edges we have to clear the faux bit for all the edges that do not correspond to consecutive vertices
|
// To correctly set Faux edges we have to clear the faux bit for all the edges that do not correspond to consecutive vertices
|
||||||
// Consecutivity is in the space of the index of the polygon.
|
// Consecutivity is in the space of the index of the polygon.
|
||||||
for(int qq=0;qq<3;++qq)
|
for (int qq = 0; qq < 3; ++qq)
|
||||||
{
|
{
|
||||||
if( (indexTriangulatedVect[j+qq]+1)%vert_per_face == indexTriangulatedVect[j+(qq+1)%3])
|
if ((indexTriangulatedVect[j + qq] + 1) % vert_per_face == indexTriangulatedVect[j + (qq + 1) % 3])
|
||||||
mesh.face[f+j/3].ClearF(qq);
|
mesh.face[f + j / 3].ClearF(qq);
|
||||||
else mesh.face[f+j/3].SetF(qq);
|
else mesh.face[f + j / 3].SetF(qq);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
f+=trigs;
|
f += trigs;
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: It is assumed that colored face takes exactly one text line
|
// NOTE: It is assumed that colored face takes exactly one text line
|
||||||
// (otherwise it is impossible to parse color information since
|
// (otherwise it is impossible to parse color information since
|
||||||
// color components can vary)
|
// color components can vary)
|
||||||
size_t color_elements = tokens.size() - vert_per_face-1;
|
size_t color_elements = tokens.size() - vert_per_face - 1;
|
||||||
isColorDefined |= (color_elements>0);
|
//isColorDefined |= (color_elements>0);
|
||||||
if(isColorDefined) loadmask |= Mask::IOM_FACECOLOR;
|
//if(isColorDefined) loadmask |= Mask::IOM_FACECOLOR;
|
||||||
|
|
||||||
if( (color_elements>0) && tri::HasPerFaceColor(mesh) )
|
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
// set per-face color attribute
|
|
||||||
if (color_elements > 0)
|
if (color_elements > 0)
|
||||||
|
{
|
||||||
loadmask |= Mask::IOM_FACECOLOR;
|
loadmask |= Mask::IOM_FACECOLOR;
|
||||||
|
|
||||||
|
if (tri::HasPerFaceColor(mesh))
|
||||||
|
{
|
||||||
switch (color_elements)
|
switch (color_elements)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
{
|
{
|
||||||
for ( ; f0<=f; f0++)
|
for (; f0 <= f; f0++)
|
||||||
mesh.face[f0].C().Import(vcg::Color4f(.666f, .666f, .666f, .666f));
|
mesh.face[f0].C().Import(vcg::Color4f(.666f, .666f, .666f, .666f));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 1:
|
case 1:
|
||||||
{
|
{
|
||||||
for ( ; f0<=f; f0++)
|
for (; f0 <= f; f0++)
|
||||||
mesh.face[f0].C().Import( ColorMap( atoi(tokens[vert_per_face+1].c_str()) ) );
|
mesh.face[f0].C().Import(ColorMap(atoi(tokens[vert_per_face + 1].c_str())));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 3:
|
case 3:
|
||||||
{
|
{
|
||||||
if (tokens[vert_per_face+1].find('.')==std::string::npos) // if there is a float there is a dot
|
if (tokens[vert_per_face + 1].find('.') == std::string::npos) // if there is a float there is a dot
|
||||||
{
|
{
|
||||||
Color4b cc(Color4b::White);
|
Color4b cc(Color4b::White);
|
||||||
cc[0] = (unsigned char)atoi( tokens[vert_per_face+1].c_str() );
|
cc[0] = (unsigned char)atoi(tokens[vert_per_face + 1].c_str());
|
||||||
cc[1] = (unsigned char)atoi( tokens[vert_per_face+2].c_str() );
|
cc[1] = (unsigned char)atoi(tokens[vert_per_face + 2].c_str());
|
||||||
cc[2] = (unsigned char)atoi( tokens[vert_per_face+3].c_str() );
|
cc[2] = (unsigned char)atoi(tokens[vert_per_face + 3].c_str());
|
||||||
for ( ; f0<=f; f0++)
|
for (; f0 <= f; f0++)
|
||||||
mesh.face[f0].C()=cc;
|
mesh.face[f0].C() = cc;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
float color[3];
|
float color[3];
|
||||||
color[0] = (float) atof( tokens[vert_per_face+1].c_str() );
|
color[0] = (float)atof(tokens[vert_per_face + 1].c_str());
|
||||||
color[1] = (float) atof( tokens[vert_per_face+2].c_str() );
|
color[1] = (float)atof(tokens[vert_per_face + 2].c_str());
|
||||||
color[2] = (float) atof( tokens[vert_per_face+3].c_str() );
|
color[2] = (float)atof(tokens[vert_per_face + 3].c_str());
|
||||||
for ( ; f0<=f; f0++)
|
for (; f0 <= f; f0++)
|
||||||
mesh.face[f0].C().Import(vcg::Color4f(color[0], color[1], color[2], 1.0f));
|
mesh.face[f0].C().Import(vcg::Color4f(color[0], color[1], color[2], 1.0f));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 4:
|
case 4:
|
||||||
{
|
{
|
||||||
if (tokens[vert_per_face+1].find('.')==std::string::npos) // if it is a float there is a dot
|
if (tokens[vert_per_face + 1].find('.') == std::string::npos) // if it is a float there is a dot
|
||||||
{
|
{
|
||||||
Color4b cc;
|
Color4b cc;
|
||||||
cc[0] = (unsigned char) atoi(tokens[vert_per_face+1].c_str());
|
cc[0] = (unsigned char)atoi(tokens[vert_per_face + 1].c_str());
|
||||||
cc[1] = (unsigned char) atoi(tokens[vert_per_face+2].c_str());
|
cc[1] = (unsigned char)atoi(tokens[vert_per_face + 2].c_str());
|
||||||
cc[2] = (unsigned char) atoi(tokens[vert_per_face+3].c_str());
|
cc[2] = (unsigned char)atoi(tokens[vert_per_face + 3].c_str());
|
||||||
cc[3] = (unsigned char) atoi(tokens[vert_per_face+4].c_str());
|
cc[3] = (unsigned char)atoi(tokens[vert_per_face + 4].c_str());
|
||||||
for ( ; f0<=f; f0++)
|
for (; f0 <= f; f0++)
|
||||||
mesh.face[f0].C()=cc;
|
mesh.face[f0].C() = cc;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
float color[4];
|
float color[4];
|
||||||
color[0] = float( atof(tokens[vert_per_face+1].c_str()) );
|
color[0] = float(atof(tokens[vert_per_face + 1].c_str()));
|
||||||
color[1] = float( atof(tokens[vert_per_face+2].c_str()) );
|
color[1] = float(atof(tokens[vert_per_face + 2].c_str()));
|
||||||
color[2] = float( atof(tokens[vert_per_face+3].c_str()) );
|
color[2] = float(atof(tokens[vert_per_face + 3].c_str()));
|
||||||
color[3] = float( atof(tokens[vert_per_face+4].c_str()) );
|
color[3] = float(atof(tokens[vert_per_face + 4].c_str()));
|
||||||
for ( ; f0<=f; f0++)
|
for (; f0 <= f; f0++)
|
||||||
mesh.face[f0].C().Import(vcg::Color4f(color[0], color[1], color[2], color[3]));
|
mesh.face[f0].C().Import(vcg::Color4f(color[0], color[1], color[2], color[3]));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} //end switch
|
} //end switch
|
||||||
|
}
|
||||||
} // end if (isColorDefined)
|
} // end if (isColorDefined)
|
||||||
} // end of for f=...
|
} // end of for f=...
|
||||||
}
|
}
|
||||||
|
|
@ -600,7 +606,7 @@ public:
|
||||||
|
|
||||||
} // end Open
|
} // end Open
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Read the next valid line and parses it into "tokens", allowing the tokens to be read one at a time.
|
* Read the next valid line and parses it into "tokens", allowing the tokens to be read one at a time.
|
||||||
|
|
@ -612,7 +618,7 @@ protected:
|
||||||
std::string line;
|
std::string line;
|
||||||
do
|
do
|
||||||
std::getline(stream, line, '\n');
|
std::getline(stream, line, '\n');
|
||||||
while ((line[0] == '#' || line.length()==0 || line[0]=='\r' ) && (!stream.eof()));
|
while ((line[0] == '#' || line.length() == 0 || line[0] == '\r') && (!stream.eof()));
|
||||||
|
|
||||||
size_t from = 0;
|
size_t from = 0;
|
||||||
size_t to = 0;
|
size_t to = 0;
|
||||||
|
|
@ -620,18 +626,17 @@ protected:
|
||||||
tokens.clear();
|
tokens.clear();
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
while (from!=length && (line[from]==' ' || line[from] == '\t' || line[from] == '\r'))
|
while (from != length && (line[from] == ' ' || line[from] == '\t' || line[from] == '\r'))
|
||||||
from++;
|
from++;
|
||||||
if(from!=length)
|
if (from != length)
|
||||||
{
|
{
|
||||||
to = from+1;
|
to = from + 1;
|
||||||
while ( to!=length && (((line[to]!=' ') && (line[to] != '\t')) || (line[to] == '\r')))
|
while (to != length && (((line[to] != ' ') && (line[to] != '\t')) || (line[to] == '\r')))
|
||||||
to++;
|
to++;
|
||||||
tokens.push_back(line.substr(from, to-from).c_str());
|
tokens.push_back(line.substr(from, to - from).c_str());
|
||||||
from = to;
|
from = to;
|
||||||
}
|
}
|
||||||
}
|
} while (from < length);
|
||||||
while (from<length);
|
|
||||||
} // end Tokenize
|
} // end Tokenize
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
|
@ -794,10 +799,10 @@ protected:
|
||||||
};
|
};
|
||||||
return Color4f(colorMap[i][0], colorMap[i][1], colorMap[i][2], colorMap[i][3]);
|
return Color4f(colorMap[i][0], colorMap[i][1], colorMap[i][2], colorMap[i][3]);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
// /*! @} */
|
// /*! @} */
|
||||||
} //namespace io
|
} //namespace io
|
||||||
}//namespace tri
|
}//namespace tri
|
||||||
} // namespace vcg
|
} // namespace vcg
|
||||||
|
|
||||||
#endif //__VCGLIB_IMPORT_OFF
|
#endif //__VCGLIB_IMPORT_OFF
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue