// msGLExport - OpenGL exporter for Milkshape // // Copyright (C) 2005 Ian Cowburn (ianc@noddybox.demon.co.uk) // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // ------------------------------------------------------------------------- // static const char rcs_id[]="$Id$"; #include #include #include #include #include "mingwms.h" #include "msLib.h" #include "dialog.h" #include "config.h" // ---------------------------------------------------------------------- // TYPES // typedef std::vector IntList; typedef std::vector TriangleList; class IndexMap : public std::map { public: IndexMap() : std::map () {} bool Has(int key) { return find(key)!=end(); } }; // ---------------------------------------------------------------------- // UTILS // static bool VecMatch(const msVec3 v1, const msVec3 v2) { for(int f=0;f<3;f++) { if (v1[f]!=v2[f]) { return false; } } return true; } static void CopyVec3(msVec3 to, const msVec3 from) { for(int f=0;f<3;f++) { to[f]=from[f]; } } static bool VertexNormalsMatch(msMesh *m, int t1, int t2) { msVec3 v1; msVec3 v2; for(int f=0;f<3;f++) { msMesh_GetVertexNormalAt(m,(m->pTriangles+t1)->nNormalIndices[f],v1); msMesh_GetVertexNormalAt(m,(m->pTriangles+t2)->nNormalIndices[f],v2); if (!VecMatch(v1,v2)) { return false; } } return true; } static void SetName(char *name, const char *base, int num) { int len=std::min(static_cast(std::strlen(base)),MS_MAX_NAME-10); std::sprintf(name,"%*.*s_%d",len,len,base,num); } static void DEBUG(const char *fmt, ...) { static char buff[4096]; va_list va; va_start(va,fmt); std::vsprintf(buff,fmt,va); va_end(va); W32DLib::Common::Message(0,"DEBUG",buff); } // ---------------------------------------------------------------------- // GROUP SPLITTER -- This is *very* ugly code, so look away if you're of // a nervous disposition. // static void SplitGroup(msModel *model, int group) { TriangleList list; msMesh *orig_mesh=msModel_GetMeshAt(model,group); int num=orig_mesh->nNumTriangles; bool *used=new bool[num]; std::string name=orig_mesh->szName; for(int f=0;fszName,name.c_str(),num++); mesh->nMaterialIndex=orig_mesh->nMaterialIndex; for(j=i->begin();j!=i->end();++j) { msTriangle *old_tri=msMesh_GetTriangleAt(orig_mesh,*j); msTriangle *new_tri=msMesh_GetTriangleAt (mesh,msMesh_AddTriangle(mesh)); CopyVec3(new_tri->Normal,old_tri->Normal); new_tri->nFlags=old_tri->nFlags; for(int f=0;f<3;f++) { int old_vi=old_tri->nVertexIndices[f]; int new_vi; int old_ni=old_tri->nNormalIndices[f]; int new_ni; if (vmap.Has(old_vi)) { new_vi=vmap[old_vi]; } else { new_vi=msMesh_AddVertex(mesh); vmap[old_vi]=new_vi; } if (nmap.Has(old_ni)) { new_ni=nmap[old_ni]; } else { new_ni=msMesh_AddVertexNormal(mesh); nmap[old_ni]=new_ni; } msVertex *old_ver=msMesh_GetVertexAt(orig_mesh,old_vi); msVertex *new_ver=msMesh_GetVertexAt(mesh,new_vi); *new_ver=*old_ver; msVec3 normal; msMesh_GetVertexNormalAt(orig_mesh,old_ni,normal); msMesh_SetVertexNormalAt(mesh,new_ni,normal); new_tri->nVertexIndices[f]=new_vi; new_tri->nNormalIndices[f]=new_ni; } } } if (Config::RemoveOriginal()) { msMesh_Destroy(orig_mesh); for(int f=group;fnNumMeshes-1;f++) { model->pMeshes[f]=model->pMeshes[f+1]; } model->nNumMeshes--; model->nNumAllocedMeshes--; } } // ---------------------------------------------------------------------- // MINGW WRAPPER FUNCTIONS // static const char* GetTitle() { return "Group Exploder"; } static int Execute(msModel* model) { W32DLib::Common::Initialise(); W32DLib::Common::MessageTitle("Group Exploder"); HWND parent=GetForegroundWindow(); if (!model) { return -1; } if (msModel_GetMeshCount(model)<1) { W32DLib::Common::Error(parent,NULL,"No meshes in the model!"); return 0; } StringList grps; for(int m=0;mnNumMeshes;m++) { msMesh *mesh=model->pMeshes+m; grps.push_back(mesh->szName); } Dialog dlg(grps); if (dlg.ShowModal(W32DLib::Common::GetInstance(),parent)==IDOK) { SetCursor(LoadCursor(NULL,IDC_WAIT)); SplitGroup(model,dlg.GetSelectedGroup()); SetCursor(LoadCursor(NULL,IDC_ARROW)); return MS_MODEL_CHANGED; } return MS_MODEL_UNCHANGED; } PLUGIN_SPEC void* CreatePlugIn() { return CreateMINGWPlugin(MS_TYPE_TOOL, GetTitle, Execute); } // END OF FILE