49 bool operator()(
u32 a,
u32 b)
const 51 for(
unsigned i=0; i<mAttribs.size(); ++i)
53 int val = mAttribs[i]->compare(a,b);
61 std::vector< const ArrayAbstract* > mAttribs;
74 bool operator()(
u32 a,
u32 b)
const 76 for(
unsigned i=0; i<mAttribs.size(); ++i)
78 if (mAttribs[i]->compare(a,b) != 0)
85 std::vector< const ArrayAbstract* > mAttribs;
93 ref<T> in_data = cast<T>(data);
97 out_data->resize(map_new_to_old.size());
98 for(
unsigned i=0; i<map_new_to_old.size(); ++i) {
99 int j = map_new_to_old[i];
100 out_data->at(i) = in_data->at(j);
111 if ( (out_data = regenerateT<ArrayInt4>(data, map_new_to_old)) )
114 if ( (out_data = regenerateT<ArrayInt3>(data, map_new_to_old)) )
117 if ( (out_data = regenerateT<ArrayInt2>(data, map_new_to_old)) )
120 if ( (out_data = regenerateT<ArrayUInt4>(data, map_new_to_old)) )
123 if ( (out_data = regenerateT<ArrayUInt3>(data, map_new_to_old)) )
126 if ( (out_data = regenerateT<ArrayUInt2>(data, map_new_to_old)) )
129 if ( (out_data = regenerateT<ArrayFloat4>(data, map_new_to_old)) )
132 if ( (out_data = regenerateT<ArrayFloat3>(data, map_new_to_old)) )
135 if ( (out_data = regenerateT<ArrayFloat2>(data, map_new_to_old)) )
138 if ( (out_data = regenerateT<ArrayDouble4>(data, map_new_to_old)) )
141 if ( (out_data = regenerateT<ArrayDouble3>(data, map_new_to_old)) )
144 if ( (out_data = regenerateT<ArrayDouble2>(data, map_new_to_old)) )
147 if ( (out_data = regenerateT<ArrayFloat1>(data, map_new_to_old)) )
150 if ( (out_data = regenerateT<ArrayDouble1>(data, map_new_to_old)) )
153 if ( (out_data = regenerateT<ArrayUInt1>(data, map_new_to_old)) )
156 if ( (out_data = regenerateT<ArrayInt1>(data, map_new_to_old)) )
159 if ( (out_data = regenerateT<ArrayByte1>(data, map_new_to_old)) )
162 if ( (out_data = regenerateT<ArrayShort1>(data, map_new_to_old)) )
165 if ( (out_data = regenerateT<ArrayUByte1>(data, map_new_to_old)) )
168 if ( (out_data = regenerateT<ArrayUShort1>(data, map_new_to_old)) )
171 if ( (out_data = regenerateT<ArrayUByte2>(data, map_new_to_old)) )
174 if ( (out_data = regenerateT<ArrayUByte3>(data, map_new_to_old)) )
177 if ( (out_data = regenerateT<ArrayUByte4>(data, map_new_to_old)) )
180 if ( (out_data = regenerateT<ArrayByte2>(data, map_new_to_old)) )
183 if ( (out_data = regenerateT<ArrayByte3>(data, map_new_to_old)) )
186 if ( (out_data = regenerateT<ArrayByte4>(data, map_new_to_old)) )
189 if ( (out_data = regenerateT<ArrayShort2>(data, map_new_to_old)) )
192 if ( (out_data = regenerateT<ArrayShort3>(data, map_new_to_old)) )
195 if ( (out_data = regenerateT<ArrayShort4>(data, map_new_to_old)) )
198 if ( (out_data = regenerateT<ArrayUShort2>(data, map_new_to_old)) )
201 if ( (out_data = regenerateT<ArrayUShort3>(data, map_new_to_old)) )
204 if ( (out_data = regenerateT<ArrayUShort4>(data, map_new_to_old)) )
215 mMapNewToOld.clear();
216 mMapOldToNew.clear();
224 std::vector<u32> verti;
225 verti.resize(vert_count);
226 mMapOldToNew.resize(vert_count);
228 for(
u32 i=0; i<verti.size(); ++i)
231 mMapOldToNew[i] = 0xFFFFFFFF;
234 std::sort(verti.begin(), verti.end(), LessCompare(geom));
235 EqualsCompare equal_vertex(geom);
236 mMapNewToOld.reserve(vert_count);
237 u32 unique_vert_idx = 0;
238 for(
unsigned i=1; i<verti.size(); ++i)
240 if ( !equal_vertex(verti[unique_vert_idx], verti[i]) )
242 for(
unsigned j=unique_vert_idx; j<i; ++j)
243 mMapOldToNew[verti[j]] = (
u32)mMapNewToOld.size();
244 mMapNewToOld.push_back(verti[unique_vert_idx]);
248 for(
unsigned j=unique_vert_idx; j<verti.size(); ++j)
250 mMapOldToNew[verti[j]] = (
u32)mMapNewToOld.size();
251 mMapNewToOld.push_back(verti[unique_vert_idx]);
260 std::vector< ref<DrawCall> > draw_cmd;
261 for(
size_t idraw=0; idraw<geom->
drawCalls().size(); ++idraw)
262 draw_cmd.push_back( geom->
drawCalls().at(idraw) );
265 for(
u32 idraw=0; idraw<draw_cmd.size(); ++idraw)
269 const u32 idx_count = draw_cmd[idraw]->countIndices();
272 for(
IndexIterator it = draw_cmd[idraw]->indexIterator(); it.hasNext(); it.next(), ++i)
276 Log::debug(
Say(
"DoubleVertexRemover : time=%.2ns, verts=%n/%n, saved=%n, ratio=%.2n\n") << timer.
elapsed() << mMapNewToOld.size() << verti.size() << verti.size() - mMapNewToOld.size() << (float)mMapNewToOld.size()/verti.size() );
static void debug(const String &message)
Use this function to provide extra information useful to investigate and solve problems.
The ArrayAbstract class defines an abstract interface to conveniently manipulate data stored in a Buf...
real elapsed(int index=0) const
A simple String formatting class.
const ArrayAbstract * vertexArray() const
Conventional vertex array.
void removeDoubles(Geometry *geom)
ref< ArrayAbstract > regenerate(ArrayAbstract *data, const std::vector< u32 > &map_new_to_old) const
Regenerates a new Array based on the given mapping.
The Geometry class is a Renderable that implements a polygonal mesh made of polygons, lines and points.
Visualization Library main namespace.
Simple class to be used as a timer and to retrieve the current time and date.
unsigned int u32
32 bits unsigned integer
const ArrayAbstract * vertexAttribArray(int attrib_location) const
Returns a generic vertex attribute's info.
arr_type * indexBuffer()
The BufferObject containing the indices used to render.
T_VectorType & at(size_t i)
virtual size_t size() const =0
Returns the number of elements of an array.
void regenerateVertices(const std::vector< u32 > &map_new_to_old)
Regenerates the vertex position and attributes using the given new-to-old map.
The ref<> class is used to reference-count an Object.
Wraps a IndexIteratorAbstract to iterate over the indices of a DrawCall.
Collection< DrawCall > & drawCalls()
Returns the list of DrawCall objects bound to a Geometry.