00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include <3dsparse/MeshLODTri.h>
00027 #include <3dsparse/MeshLODVector.h>
00028 #include <common/Defines.h>
00029
00030
00031
00032
00033
00034 MeshLODVector::MeshLODVector(Vector &v, int _id)
00035 : Vector(v), id(_id)
00036 {
00037
00038 }
00039
00040 MeshLODVector::~MeshLODVector()
00041 {
00042
00043 }
00044
00045 void MeshLODVector::addNeighbour(MeshLODVector *vector)
00046 {
00047 if (vector != this)
00048 {
00049 bool found = false;
00050 std::list<MeshLODVector *>::iterator neighborItor;
00051 for (neighborItor = neighbor.begin();
00052 neighborItor != neighbor.end();
00053 neighborItor++)
00054 {
00055 if (*neighborItor == vector)
00056 {
00057 found = true;
00058 break;
00059 }
00060 }
00061 if (!found) neighbor.push_back(vector);
00062 }
00063 }
00064
00065 void MeshLODVector::removeNeighbor(MeshLODVector *vector)
00066 {
00067 for (unsigned int i=0; i<neighbor.size(); i++)
00068 {
00069 MeshLODVector *vec = neighbor.front();
00070 neighbor.pop_front();
00071 if (vec == vector)
00072 {
00073 break;
00074 }
00075 neighbor.push_back(vec);
00076 }
00077 }
00078
00079 void MeshLODVector::removeIfNonNeighbor(MeshLODVector *n)
00080 {
00081
00082 std::list<MeshLODTri *>::iterator faceItor;
00083 for (faceItor = face.begin();
00084 faceItor != face.end();
00085 faceItor++)
00086 {
00087 MeshLODTri *tri = (*faceItor);
00088 if(tri->hasVertex(n)) return;
00089 }
00090 removeNeighbor(n);
00091 }
00092
00093 void MeshLODVector::removeFace(MeshLODTri *rface)
00094 {
00095 for (unsigned int i=0; i<face.size(); i++)
00096 {
00097 MeshLODTri *tri = face.front();
00098 face.pop_front();
00099 if (tri == rface)
00100 {
00101 break;
00102 }
00103 face.push_back(tri);
00104 }
00105 }
00106
00107 float MeshLODVector::computeEdgeCollapseCost(MeshLODVector *neigbour)
00108 {
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122 float edgelength = (*neigbour - *this).Magnitude();
00123
00124
00125 std::list<MeshLODTri *> sides;
00126 std::list<MeshLODTri *>::iterator faceItor;
00127 for (faceItor = face.begin();
00128 faceItor != face.end();
00129 faceItor++)
00130 {
00131 if ((*faceItor)->hasVertex(neigbour))
00132 {
00133 sides.push_back(*faceItor);
00134 }
00135 }
00136
00137
00138
00139 float curvature = 0;
00140 for (faceItor = face.begin();
00141 faceItor != face.end();
00142 faceItor++)
00143 {
00144 float mincurv = 1;
00145
00146 std::list<MeshLODTri *>::iterator sideItor;
00147 for (sideItor = sides.begin();
00148 sideItor != sides.end();
00149 sideItor++)
00150 {
00151
00152 float dotprod = (*faceItor)->normal.dotP((*sideItor)->normal);
00153 mincurv = MIN(mincurv,(1-dotprod)/2.0f);
00154 }
00155
00156 curvature = MAX(curvature,mincurv);
00157 }
00158
00159
00160 return edgelength * curvature;
00161 }
00162
00163 void MeshLODVector::computeEdgeCostAtVertex()
00164 {
00165
00166
00167
00168
00169
00170
00171
00172 collapse = NULL;
00173 if(neighbor.empty())
00174 {
00175
00176 objdist = -0.01f;
00177 }
00178 else
00179 {
00180
00181 objdist = 1000000;
00182 std::list<MeshLODVector *>::iterator neighborItor;
00183 for (neighborItor = neighbor.begin();
00184 neighborItor != neighbor.end();
00185 neighborItor++)
00186 {
00187 float dist = computeEdgeCollapseCost(*neighborItor);
00188 if(dist < objdist)
00189 {
00190 collapse = *neighborItor;
00191 objdist = dist;
00192 }
00193 }
00194 }
00195 }
00196
00197 void MeshLODVector::collapseVertex()
00198
00199 {
00200
00201
00202
00203
00204
00205 if(!collapse)
00206 {
00207
00208 }
00209 else
00210 {
00211
00212 std::list<MeshLODVector *> tmp(neighbor);
00213
00214
00215 std::list<MeshLODTri *> delList(face);
00216 while (!delList.empty())
00217 {
00218 MeshLODTri *tri = delList.front();
00219 if (tri->hasVertex(collapse))
00220 {
00221 delete tri;
00222 }
00223 delList.pop_front();
00224 }
00225
00226
00227 std::list<MeshLODTri *> tmpList(face);
00228 while (!tmpList.empty())
00229 {
00230 MeshLODTri *tri = tmpList.front();
00231 tmpList.pop_front();
00232 tri->replaceVertex(this, collapse);
00233 }
00234
00235
00236 while(!neighbor.empty())
00237 {
00238 neighbor.back()->removeNeighbor(this);
00239 neighbor.pop_back();
00240 }
00241
00242
00243 std::list<MeshLODVector *>::iterator tmpItor = tmp.begin();
00244 for (tmpItor = tmp.begin();
00245 tmpItor != tmp.end();
00246 tmpItor++)
00247 {
00248 (*tmpItor)->computeEdgeCostAtVertex();
00249 }
00250 }
00251 }