stl ,functor and vertex duplicate
hy.
I'm try to import mesh from a collada file.
I use a mesh class and in a file called import.cpp i'm import that mesh.
so i declared a Vertex data vector and a index vector for store the data and at the end copy
the vector data to the mesh vertex and index properties.
i have create a vertex struct:
struct Vertex
{
Vertex(){}
Vertex(float x, float y, float z,
float nx, float ny, float nz, float u, float v)
{
_x = x; _y = y; _z = z;
_nx = nx; _ny = ny; _nz = nz;
_u = u; _v = v;
}
float _x, _y, _z, _nx, _ny, _nz, _u, _v;
bool operator ==(const Vertex& other) const;
bool operator < (const Vertex& other) const;
static const DWORD FVF;
};
now i insert the points from the collada importation and i must check if a point exist ,
for this i use a member var set<Vertex*> m_PresentVertex
declared as
std::set<Vertex *, ig::SLessPointerFunctor <Vertex> > m_PresentVertex
and a functor
namespace ig{
template <typename TClass>
struct SLessPointerFunctor{
bool operator ()(const TClass * v1, const TClass * v2) const{
return *v1 < *v2;
}
};
}
bool Vertex::operator<(const Vertex& other) const{
return (this->_x < other._x) || (this->_y < other._y) || (this->_z < other._z) || (this->_nx < other._nx) || (this->_ny < other._ny) || (this->_nz < other._nz);
}
for use the find method of the set container to check if a vertex already exist,but the normal values
are different .if exist i duplicate
the vertex , assign the new normal and insert it in the m_PresentVertex(for future check).
If the vertex not exists i'm insert it in the index m_AllIndex.push_back(IndexFace->nVertex);and
in the set container m_PresentVertex.insert(v1);
i have a vector:m_AllVertex that contains all the vertex data (is imported before and contains all'
the vertex of the mesh)and a vector m_AllIndex to insert tthe indexes of the mesh.
m_pApi->NormalFaceReset();
m_pApi->FaceReset();
Vertex* vIter;
int index = 0;
typedef vector<Vertex*>::size_type sz;
std::set<Vertex *, ig::SLessPointerFunctor <Vertex> >::iterator iter;
for(index;m_pApi->NextFace();index++)
{
I_INDEXES *IndexFace = new I_INDEXES();
if(m_pApi->ImportFaces(IndexFace))
{
//prendo il primo vertice
Vertex * v1 = new Vertex();
v1->_nx =m_AllVertex[IndexFace->nVertex]->_nx;
v1->_ny =m_AllVertex[IndexFace->nVertex]->_ny;
v1->_nz =m_AllVertex[IndexFace->nVertex]->_nz;
v1->_x =m_AllVertex[IndexFace->nVertex]->_x;
v1->_y =m_AllVertex[IndexFace->nVertex]->_y;
v1->_z =m_AllVertex[IndexFace->nVertex]->_z;
//e la prima normale
NORMAL * n1 = m_AllNormals[IndexFace->nNormal];
iter = m_PresentVertex.find(v1);
//se il vertice è gia presente
if(iter != m_PresentVertex.end())
{
//leggo l'oggetto trovato
vIter =*iter;
//setto le nuove normali
vIter->_nx = n1->nx;
vIter->_ny = n1->ny;
vIter->_nz = n1->nz;
sz sizeArray = m_AllVertex.size();
// lo aggiungo ai vertici
m_AllVertex.push_back(vIter);
// il nuovo indice è la grandezza dell'array
m_AllIndex.push_back((int)sizeArray);
m_PresentVertex.insert(vIter);//i catch " invalid operator <" error!!!!!
}
else
{
m_AllIndex.push_back(IndexFace->nVertex);
m_PresentVertex.insert(v1);
}
}
the problem is that when i try to insert the first duplicate vertex with different normal i catch
an error:" invalid operator <"
I see that may be a problem of the functor , because if i change it the error disappear.
Is the functor correct?
ps. i use vc++ 8.0
thanks.
Your operator< is not correct. For sorting, it is necessary that operator< be a "strict weak ordering". Among other things, this means that you can't have a situation where a<b AND b<a. But that's exactly the situation you have there: For a vertex A with x=1 and y=0, and a vertex B with x=0 and y=1, A<B and B<A both return true, because each has at least one component less than the corresponding component on the other object.
The solution is to reconsider if and why you need your vertices to be sorted, as opposed to merely unique (as a hash table would provide). If you actually do, rewrite operator< in a way that will accomplish that. (Your current implementation accomplishes nothing useful.)
The solution is to reconsider if and why you need your vertices to be sorted, as opposed to merely unique (as a hash table would provide). If you actually do, rewrite operator< in a way that will accomplish that. (Your current implementation accomplishes nothing useful.)
Just created a COLLADA loader there myself, it might have a slight issue with textures though :(. About to do some more work on it actually :p
Just to give you an idea of what direction i went with mine...
-I used a triangulated collada file, then loaded each xml node in to a custom TreeList.
-I loaded all the vertex positions first and created the vertex objects, note they only have position at this stage.
-Then i read the next 2 sources in to a normal and a uv std::vector<>.
-Then the triangle index data is read and the index numbers used to build the indice list and to add the normal and uv coordinates to the respective vertice.
Note the read order is maintained so as to make proper use of the index values in <triangles>
data assumptions
<mesh>
<source "positions">
<source "Normal">
<source "UVMap">
<triangles> ((VertexIndex) (Normal Index) (UVMap)) * 3 for each triangle
</mesh>
Just to give you an idea of what direction i went with mine...
-I used a triangulated collada file, then loaded each xml node in to a custom TreeList.
-I loaded all the vertex positions first and created the vertex objects, note they only have position at this stage.
-Then i read the next 2 sources in to a normal and a uv std::vector<>.
-Then the triangle index data is read and the index numbers used to build the indice list and to add the normal and uv coordinates to the respective vertice.
Note the read order is maintained so as to make proper use of the index values in <triangles>
data assumptions
<mesh>
<source "positions">
<source "Normal">
<source "UVMap">
<triangles> ((VertexIndex) (Normal Index) (UVMap)) * 3 for each triangle
</mesh>
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement