删除Vector中的重复项?

时间:2011-11-24 15:34:15

标签: c++

我有一个像这样定义的顶点:

struct VERTEX
{
  XMFLOAT3 Pos  
  XMFLOAT2 UV    

}; 

我定义了一个索引,Textures协调索引,UVcoordinate和Vertices就像这样

vector <int> indices ;
vector <int> Texcoordindex ; 
vector <XMFLOAT2> UVCoinate ;
vector <XMFLOAT3> Verices;

行。我从3D文件(在这种情况下是一个obj文件)中设置索引,纹理协调索引,UV坐标和顶点。

现在,当我想定义一个faces数组时,我发现一些顶点是用多个UV坐标定义的。我想删除具有相同UV坐标的重复顶点,并使新索引和顶点向量仅存储具有顶点新索引的非重复顶点。

这是obj文件:

# This file uses centimeters as units for non-parametric coordinates.

v -12.830015 0.000000 12.061520
v 12.027525 0.000000 12.061520
v -12.830015 15.862570 12.061520
v 12.027525 15.862570 12.061520
v -12.830015 15.862570 -12.622024
v 12.027525 15.862570 -12.622024
v -12.830015 0.000000 -12.622024
v 12.027525 0.000000 -12.622024

vt 0.375000 0.000000
vt 0.625000 0.000000
vt 0.375000 0.250000
vt 0.625000 0.250000
vt 0.375000 0.500000
vt 0.625000 0.500000
vt 0.375000 0.750000
vt 0.625000 0.750000
vt 0.375000 1.000000
vt 0.625000 1.000000
vt 0.875000 0.000000
vt 0.875000 0.250000
vt 0.125000 0.000000
vt 0.125000 0.250000
f 1/1 2/2 3/3
f 3/3 2/2 4/4
f 3/3 4/4 5/5
f 5/5 4/4 6/6
f 5/5 6/6 7/7
f 7/7 6/6 8/8
f 7/7 8/8 1/9
f 1/9 8/8 2/10
f 2/2 8/11 4/4
f 4/4 8/11 6/12
f 7/13 1/1 5/14
f 5/14 1/1 3/3

我希望结果是这样的

# This file uses centimeters as units for non-parametric coordinates.

v -12.830015 0.000000 12.061520
v 12.027525 0.000000 12.061520
v -12.830015 15.862570 12.061520
v 12.027525 15.862570 12.061520
v -12.830015 15.862570 -12.622024
v 12.027525 15.862570 -12.622024
v -12.830015 0.000000 -12.622024
v 12.027525 0.000000 -12.622024

vt 0.375000 0.000000
vt 0.625000 0.000000
vt 0.375000 0.250000
vt 0.625000 0.250000
vt 0.375000 0.500000
vt 0.625000 0.500000
vt 0.375000 0.750000
vt 0.625000 0.750000
vt 0.375000 1.000000
vt 0.625000 1.000000
vt 0.875000 0.000000
vt 0.875000 0.250000
vt 0.125000 0.000000
vt 0.125000 0.250000

删除重复的

后的新顶点
f 1/1 2/2 3/3
f 4/4 5/5 6/6 
f 7/7 8/8 1/9 
f 2/10 8/116/12
f7/13 5/14

我尝试使用sort和unique,但是我遇到了编译错误:

error C2784: 'bool std::operator <(const std::list<_Ty,_Ax> &,const std::list<_Ty,_Ax> &)' : could not deduce template argument for 'const std::list<_Ty,_Ax> &' from 'VERTEX'  c:\program files (x86)\microsoft visual studio 10.0\vc\include\algorithm    3559    1   Mesh_test

error C2784: 'bool std::operator <(const std::basic_string<_Elem,_Traits,_Alloc> &,const _Elem *)' : could not deduce template argument for 'const std::basic_string<_Elem,_Traits,_Alloc> &' from 'VERTEX' c:\program files (x86)\microsoft visual studio 10.0\vc\include\algorithm    3559    1   Mesh_test

error C2784: 'bool std::operator <(const _Elem *,const std::basic_string<_Elem,_Traits,_Alloc> &)' : could not deduce template argument for 'const _Elem *' from 'VERTEX'   c:\program files (x86)\microsoft visual studio 10.0\vc\include\algorithm    3559    1   Mesh_test

error C2784: 'bool std::operator <(const std::basic_string<_Elem,_Traits,_Alloc> &,const 
std::basic_string<_Elem,_Traits,_Alloc> &)' : could not deduce template argument for 'const std::basic_string<_Elem,_Traits,_Alloc> &' from 'VERTEX'    c:\program files (x86)\microsoft visual studio 10.0\vc\include\algorithm    3559    1   Mesh_test

error C2784: 'bool std::operator <(const std::vector<_Ty,_Ax> &,const std::vector<_Ty,_Ax> &)' : could not deduce template argument for 'const std::vector<_Ty,_Ax> &' from 'VERTEX'    c:\program files (x86)\microsoft visual studio 10.0\vc\include\algorithm    3559    1   Mesh_test


error C2784: 'bool std::operator <(const std::unique_ptr<_Ty,_Dx> &,const std::unique_ptr<_Ty2,_Dx2> &)' : could not deduce template argument for 'const std::unique_ptr<_Ty,_Dx> &' from 'VERTEX'  c:\program files (x86)\microsoft visual studio 10.0\vc\include\algorithm    3559    1   Mesh_test


error C2784: 'bool std::operator <(const std::reverse_iterator<_RanIt> &,const std::reverse_iterator<_RanIt2> &)' : could not deduce template argument for 'const std::reverse_iterator<_RanIt> &' from 'VERTEX'    c:\program files (x86)\microsoft visual studio 10.0\vc\include\algorithm    3559    1   Mesh_test


error C2784: 'bool std::operator <(const std::_Revranit<_RanIt,_Base> &,const std::_Revranit<_RanIt2,_Base2> &)' : could not deduce template argument for 'const std::_Revranit<_RanIt,_Base> &' from 'VERTEX'  c:\program files (x86)\microsoft visual studio 10.0\vc\include\algorithm    3559    1   Mesh_test


error C2784: 'bool std::operator <(const std::pair<_Ty1,_Ty2> &,const std::pair<_Ty1,_Ty2> &)' : could not deduce template argument for 'const std::pair<_Ty1,_Ty2> &' from 'VERTEX'    c:\program files (x86)\microsoft visual studio 10.0\vc\include\algorithm    3559    1   Mesh_test

error C2676: binary '<' : 'VERTEX' does not define this operator or a conversion to a type acceptable to the predefined operator    c:\program files (x86)\microsoft visual studio 10.0\vc\include\algorithm    3559    1   Mesh_test

error C1903: unable to recover from previous error(s); stopping compilation c:\program files (x86)\microsoft visual studio 10.0\vc\include\algorithm    3559    1   Mesh_test

3 个答案:

答案 0 :(得分:2)

没有代码和编译器错误,就无法诊断问题。但是,使用std::sortstd::unique删除indices向量中的重复项的示例如下:

std::sort(indices.begin(), indices.end());
vector<int>::iterator it = std::unique(indices.begin(), indices.end());
indices.erase(it,indices.end());

我不知道XMLFLOAT3XMLFLOAT2类型是什么,因此可能需要将谓词传递给std::sortstd::unique

编辑:用于XMFLOAT3

bool xmfloat3_lt(const XMFLOAT3 f1, const XMFLOAT3 f2)
{
    if (f1.x < f2.x) return true;
    if (f1.y < f2.y) return true;
    if (f1.z < f2.z) return true;
    return false;
}

bool xmfloat3_eq(const XMFLOAT3 f1, const XMFLOAT3 f2)
{
    return f1.x == f2.x &&
           f1.y == f2.y &&
           f1.z == f2.z;
}

std::sort(Verices.begin(), Verices.end(), xmfloat3_lt);
vector<XMFLOAT3>::iterator it = std::unique(
    Verices.begin(), Verices.end(), xmfloat3_eq);
Verices.erase(it,Verices.end());

希望这有帮助。

答案 1 :(得分:2)

如果内存使用没有任何限制,你可以声明一个新的矢量保留大小与你的一个相同,并且只使用std :: find函数来放入不在此向量中的值来确定是否值已经在您的新向量中。

std::vector newVector;
newVector.reserve( oldVector.size() );

对于旧矢量的所有元素:

if( newVector.find(element))
{
  if( find( newVector.begin(), newVector.end(), newVector.size() != newVector.end() )
  {
    newVector.push_back(element);
   }
}

其他算法可以将向量中的所有元素移位到预览位置,以防重复(此方法仅适用于已排序的数组 - 列表)

答案 2 :(得分:0)

我知道编译器输出令人困惑,但它试图告诉你的是它不知道如何比较两个VERTEX对象。您可以定义一个运算符&lt;在你班上:

struct VERTEX
{
  XMFLOAT3 Pos;  
  XMFLOAT2 UV;

  bool operator<(const VERTEX &that) const
  {
    // return true if you consider this vertex to be less than that vertex.
  }
};

或作为全球职能

bool operator<(const VERTEX &v1,const VERTEX &v2)
{
  // return true if you consider v1 to be less than v2
}