簡體   English   中英

刪除Vector中的重復項?

[英]Remove Duplicates in Vector?

我有一個像這樣定義的頂點:

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

沒有代碼和編譯器錯誤,就無法診斷問題。 但是使用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());

希望這可以幫助。

如果它對內存使用沒有任何限制,你可以聲明一個新的向量保留大小與你的一個相同,並且僅使用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);
   }
}

其他算法可以將向量中的所有元素移位到預覽位置的一個位置以防重復(此方法僅適用於已排序的數組 - 列表)

我知道編譯器輸出令人困惑,但它試圖告訴你的是它不知道如何比較兩個VERTEX對象。 你可以在你的班級中定義一個算子<

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
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM