#include "ElementProxyHeaders.hpp" #include //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // bool ElementPolygonMeshProxy::OptimizeFlatShading(OptimizeFlatShadingProcess *process) { Check_Object(this); Check_Object(process); // //-------------------------- // Make sure we can continue //-------------------------- // process->OptimizeCallback(this); if (!process->continueProcess) return true; // //------------------------------------------------------ // Make sure that we only have a single mesh to evaluate //------------------------------------------------------ // unsigned unique_combinations = GetPrimitiveCount(); if (!unique_combinations) { Destroy(); return false; } Verify(unique_combinations == 1); // //-------------------------------------------- // If we aren't in flat coloring mode, we done //-------------------------------------------- // MLR_I_PMesh *primitive = GetPrimitive(0); Check_Object(primitive); MLRState state = primitive->GetReferenceState(); if (state.GetFlatColoringMode() == MLRState::FlatColoringOffMode) return true; // //------------------------------------------- // Create a new polymesh and set its position //------------------------------------------- // GroupProxy *parent = GetParentGroupProxy(); LinearMatrix4D m; GetLocalToParent(&m); PolygonMeshProxy *mesh; if (parent) { Check_Object(parent); mesh = parent->AppendNewPolygonMeshProxy(); } else mesh = GetSceneProxy()->AppendNewPolygonMeshProxy(); LinearMatrix4D matrix; if (mesh->GetLocalToParent(&matrix)) SetLocalToParent(matrix); // //----------------------------------------------------------------- // Make an array of all the vertices in the mesh and figure out the // minimum set of base vertices //----------------------------------------------------------------- // DynamicArrayOf original_vertices; UseVertexArray(&original_vertices); unsigned old_vertex_count = original_vertices.GetLength(); DynamicArrayOf new_vertices(old_vertex_count); DynamicArrayOf locked(old_vertex_count); unsigned new_vertex_count=0; int v,i; for (v=0; vIsAllButNormalEqual(new_vertices[i], 0.0f)) break; } // //------------------------------------------------------ // If the vertex couldn't be matched, add it to the list //------------------------------------------------------ // if (i == new_vertex_count) { Proxies::VertexProxy *new_vertex = Proxies::VertexProxy::MakeProxy(); Check_Object(new_vertex); Stuff::Point3D pos; Stuff::Normal3D normal; Stuff::RGBAColor color; Stuff::DynamicArrayOf > uvs; vertex->GetPosition(&pos); new_vertex->SetPosition(pos); if (vertex->GetNormal(&normal)) new_vertex->SetNormal(normal); if (vertex->GetColor(&color)) new_vertex->SetColor(color); if (vertex->GetUVs(&uvs)) new_vertex->SetUVs(uvs); locked[new_vertex_count] = false; new_vertices[new_vertex_count++] = new_vertex; } } // //------------------------------------------------- // Go through the poly array and start copying them //------------------------------------------------- // DynamicArrayOf poly_array; int polycount = UsePolygonArray(&poly_array); DynamicArrayOf newpoly_array(polycount); for (int p=0; pUseMultiState(&multi_state); PolygonProxy *new_polygon = Proxies::PolygonProxy::MakeProxy(); Check_Object(new_polygon); new_polygon->SetStatesToMatch(multi_state); multi_state.DetachReferences(); // //---------------------------------------------------------- // Get the indicies, then look for the best first one to use //---------------------------------------------------------- // DynamicArrayOf index_array; int indexcount = polygon->UseIndexArray(&index_array); DynamicArrayOf newvertex_array(indexcount); int roll=0; Search_For_First: IndexProxy *index = index_array[roll]; Check_Object(index); Proxies::VertexProxy *old_vertex = index->GetVertexProxy(); Check_Object(old_vertex); // //-------------------------------------------------------------------- // Search the current vertex list looking for a match that is unlocked //-------------------------------------------------------------------- // for (v=0; vIsAllButNormalEqual(new_vertices[v], 0.0f) && !locked[v]) { locked[v] = true; Stuff::Normal3D normal; if (old_vertex->GetNormal(&normal)) new_vertices[v]->SetNormal(normal); break; } if (old_vertex->IsEqualTo(new_vertices[v], 0.0f)) break; } // //---------------------------------------------------------------- // If we didn't find one, we need to see if maybe one of our other // vertices should be first //---------------------------------------------------------------- // if (v == new_vertex_count) { #if 0 if (++roll < indexcount) goto Search_For_First; #endif // //------------------------------------------------------------- // We looked at all of them, so now we have to make a new entry //------------------------------------------------------------- // Proxies::VertexProxy *new_vertex = Proxies::VertexProxy::MakeProxy(); Check_Object(new_vertex); roll = 0; Stuff::Point3D pos; Stuff::RGBAColor color; Stuff::Normal3D normal; Stuff::DynamicArrayOf > uvs; old_vertex->GetPosition(&pos); new_vertex->SetPosition(pos); if (old_vertex->GetNormal(&normal)) new_vertex->SetNormal(normal); if (old_vertex->GetColor(&color)) new_vertex->SetColor(color); if (old_vertex->GetUVs(&uvs)) new_vertex->SetUVs(uvs); v = new_vertex_count; locked[new_vertex_count] = true; new_vertices[new_vertex_count++] = new_vertex; } // //---------------- // Set the indices //---------------- // newvertex_array[0] = new_vertices[v]; for (int k=1; k=indexcount) t -= indexcount; old_vertex = index_array[t]->GetVertexProxy(); Check_Object(old_vertex); for (v=0; vIsAllButNormalEqual(new_vertices[v], 0.0f)) break; } Verify(v < new_vertex_count); newvertex_array[k] = new_vertices[v]; } new_polygon->SetPolygonIndices(newvertex_array); newpoly_array[p] = new_polygon; polygon->DetachArrayReferences(&index_array); } Proxies::Process a_process; mesh->AddPolygons(&a_process,newpoly_array); mesh->DetachReference(); DetachArrayReferences(&newpoly_array); DetachArrayReferences(&poly_array); DetachArrayReferences(&original_vertices); Destroy(); return false; }