2011-11-24 82 views
1

我有這樣定義的頂點:刪除Vector中的重複項?

struct VERTEX 
{ 
    XMFLOAT3 Pos 
    XMFLOAT2 UV  

}; 

我定義的指標,紋理協調指數,UVcoordinate像這樣

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

OK頂點。我從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 

我嘗試使用後排序和唯一,但我得到編譯錯誤:

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 
+0

也許這將是一個好主意,向我們展示了代碼和編譯器錯誤。 – Simon

+0

您是否有重載相等運算符? – Hauleth

+0

不,我不重載平等運營商 – user943998

回答

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); 
    } 
} 

其他算法可以是所有元素的轉變在矢量一個地方早在預覽發生在重複的情況下(此方法僅適用於排序列表)

+0

你有希望嗎? :) – FailedDev

+0

是的,我:)! – AlexTheo

+0

好我雖然我是唯一一個:p – FailedDev

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()); 

希望這有助於。

+0

爲什麼indices.resize(..)而不是std :: remove(..)? – Simon

+0

for XMFLOAT3請檢查http://msdn.microsoft.com/en-us/library/windows/desktop/microsoft.directx_sdk.reference.xmfloat3%28v=vs.85%29.aspx – user943998

+0

謝謝我嘗試使用你的想法,但我偷了問題,但ii使用矢量我可以刪除重複,我認爲在XMFLOAT3的問題!或可能在我的結構! – user943998

0

我知道編譯器的輸出很混亂,但它試圖告訴你的是它不知道如何比較兩個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 
}