void BakeRadiosity::DoIt(void) { DebugPrint(_T("Plug-in Start\n")); RadiosityInterface *ri; RadiosityEffect *re; RadiosityMesh *rm; INode *node; Tab<INode *> selNodes; int nbSel; // Gets core interface ri = static_cast<RadiosityInterface*>( GetCOREInterface(RADIOSITY_INTERFACE)); if(ri == NULL){ DebugPrint(_T("RadiosityInterface error\n")); return; } // Returns a pointer to the currently active Advanced Lighting plug-in. if((re = ri->GetRadiosity()) == NULL){ DebugPrint(_T("RadiosityEffect error\n")); return; } // Gets Radiosity Mesh if((rm = GetRadiosityMesh(re)) == NULL){ DebugPrint(_T("RadiosityMesh error\n")); return; } // Resets the container for INode pointers. selNodes.ZeroCount(); // Returns the number of nodes in the selection set. nbSel = ip->GetSelNodeCount(); // The loop will continue until handling all seletecd nodes... for(int i=0; i<nbSel; i++){ // Returns a pointer to the 'i-th' node in the selection set. if((node = ip->GetSelNode(i)) == NULL){ continue; } // Gets the mesh for a node. Mesh *mesh = NULL; if(!rm->GetMesh(node, mesh)||(mesh == NULL)){ DebugPrint(_T("GetMesh error\n")); continue; } // Gets the TM for the node. // TM is the mesh to world space transform. Matrix3 mtx(1); if(!rm->GetMeshTM(node, mtx)){ DebugPrint(_T("GetMeshTM error\n")); continue; } // Creates a new mesh if(!CreateNewMesh(node, mesh, mtx)){ DebugPrint(_T("CreateMesh error\n")); continue; } // Appends a INode pointer to the container selNodes.Append(1, &node); } // Deletes original nodes if the flag is set. if(keepOrgFlag != true){ nbSel = selNodes.Count(); // The loop will continue until handling all appended nodes... for(int i=0; i<nbSel; i++){ if(selNodes[i] == NULL){ continue; } // Removes it from the hierarchy, and handle undo. // The position of any children of this node are kept the same. selNodes[i]->Delete(ip->GetTime(), TRUE); } } DebugPrint(_T("Plug-in End\n")); }
/* FbxMesh pMesh : the original mesh load from fbx file FbxScene pScene : the FbxScene load from fbx file float threshold : */ void GenerateLOD::Reduction_EdgesCollapse_UV(FbxNode *node, FbxMesh *pMesh, FbxManager *pManager, FbxScene *pScene) { // Clear the ralated data structure (*ControlP).clear(); (*Triangles).clear(); (*Edges).clear(); (*CostToEdge).clear(); // Clear the HeapCost while (!HeapCost->empty()) HeapCost->pop(); FbxVector4 *pControlPoints = pMesh->GetControlPoints(); int AddTriangleIndex = pMesh->GetPolygonCount(); int AddEdgeIndex = pMesh->GetMeshEdgeCount(); int threshold_1 = static_cast<int>(AddTriangleIndex * model_1.GetReductionRate()); int threshold_2 = static_cast<int>(AddTriangleIndex * model_2.GetReductionRate()); int threshold_3 = static_cast<int>(AddTriangleIndex * model_3.GetReductionRate()); double start = GetTickCount(); //# Init the ditc of (*Triangles) and the dict of (*ControlP) Init_Triangles_And_ControlP_EdgeCollapse(pMesh, pControlPoints);///////////////////////////// //Before Reduction, Now Init the Original VertexBuffer Init_Buffer(pMesh, model_0); //# Init the ditc of (*Edges) InitEdges(pMesh); ////////////////////////////////// // Now, Simplify Iterator int Ring = 0; bool flag1 = true; bool flag2 = true; while (true) { int idx; if (0 == HeapCost->size()) idx = -1; else { //First Get the top element, namely the minmum cost //Second pop the minmum cost from HeapCost FbxDouble PopCost = HeapCost->top(); HeapCost->pop(); if (0 == (*CostToEdge)[PopCost].size()) continue; idx = (*CostToEdge)[PopCost][0]; } //int idx = GetMinEdgeCost(); if (-1 == idx) { MessageBox(NULL, "When execute Simplification, there has No any edges should be collapse.", "The title", 0); break; } // Execute the current Edge Collapse and Update the (*ControlP), (*Triangles), (*Edges). CollapseEdge_And_UpdateCost(idx, pControlPoints, AddTriangleIndex, AddEdgeIndex); Ring += 1; if (flag1 && (int)(*Triangles).size() < threshold_1) { // After Reduction, Now Init Reduction VertexBuffer Init_Buffer(pMesh, model_1); model = model_1; FbxMesh *newMesh = CreateNewMesh(pControlPoints, pMesh, pScene); // Update the Node Atrribute node->RemoveNodeAttribute(pMesh); node->SetNodeAttribute(newMesh); // Export new Mesh std::string tmp = std::string(".\\LODs\\") + std::string("Save") + srcFbxName.substr(0, srcFbxName.size() - 4) + "_(" + std::to_string(int(model_1.GetReductionRate() * 100)) + "%)" + ".FBX"; saveScene(tmp.c_str(), pManager, pScene, true); node->RemoveNodeAttribute(newMesh); node->SetNodeAttribute(pMesh); flag1 = false; } if (flag2 && (int)(*Triangles).size() < threshold_2) { // After Reduction, Now Init Reduction VertexBuffer Init_Buffer(pMesh, model_2); FbxMesh *newMesh = CreateNewMesh(pControlPoints, pMesh, pScene); // Update the Node Atrribute node->RemoveNodeAttribute(pMesh); node->SetNodeAttribute(newMesh); // Export new Mesh std::string tmp = std::string(".\\LODs\\") + std::string("Save") + srcFbxName.substr(0, srcFbxName.size() - 4) + "_(" + std::to_string(int(model_2.GetReductionRate() * 100)) + "%)" + ".FBX"; saveScene(tmp.c_str(), pManager, pScene, true); node->RemoveNodeAttribute(newMesh); node->SetNodeAttribute(pMesh); flag2 = false; } if ((int)(*Triangles).size() < threshold_3) { // After Reduction, Now Init Reduction VertexBuffer Init_Buffer(pMesh, model_3); FbxMesh *newMesh = CreateNewMesh(pControlPoints, pMesh, pScene); // Update the Node Atrribute node->RemoveNodeAttribute(pMesh); node->SetNodeAttribute(newMesh); // Export new Mesh std::string tmp = std::string(".\\LODs\\") + std::string("Save") + srcFbxName.substr(0, srcFbxName.size() - 4) + "_(" + std::to_string(int(model_3.GetReductionRate() * 100)) + "%)" + ".FBX"; saveScene(tmp.c_str(), pManager, pScene, true); node->RemoveNodeAttribute(newMesh); node->SetNodeAttribute(pMesh); break; } } }