void CEditableMesh::Clear() { #ifdef _EDITOR UnloadRenderBuffers (); #endif UnloadAdjacency (); UnloadCForm (); UnloadFNormals (); UnloadVNormals (); UnloadSVertices (); VERIFY (m_FNormalsRefs==0 && m_VNormalsRefs==0 && m_AdjsRefs==0 && m_SVertRefs==0); xr_free (m_Verts); xr_free (m_Faces); for (VMapIt vm_it=m_VMaps.begin(); vm_it!=m_VMaps.end(); vm_it++) xr_delete (*vm_it); m_VMaps.clear (); m_SurfFaces.clear (); for (VMRefsIt ref_it=m_VMRefs.begin(); ref_it!=m_VMRefs.end(); ref_it++) xr_free (ref_it->pts); m_VMRefs.clear (); }
bool CEditableMesh::LoadMesh(IReader& F){ u32 version=0; R_ASSERT(F.r_chunk(EMESH_CHUNK_VERSION,&version)); if (version!=EMESH_CURRENT_VERSION){ ELog.DlgMsg( mtError, "CEditableMesh: unsuported file version. Mesh can't load."); return false; } R_ASSERT(F.find_chunk(EMESH_CHUNK_MESHNAME)); F.r_stringZ (m_Name); R_ASSERT(F.r_chunk(EMESH_CHUNK_BBOX,&m_Box)); R_ASSERT(F.r_chunk(EMESH_CHUNK_FLAGS,&m_Flags)); F.r_chunk(EMESH_CHUNK_BOP,&m_Ops); R_ASSERT(F.find_chunk(EMESH_CHUNK_VERTS)); m_VertCount = F.r_u32(); if (m_VertCount<3){ Log ("!CEditableMesh: Vertices<3."); return false; } m_Verts = xr_alloc<Fvector>(m_VertCount); F.r (m_Verts, m_VertCount*sizeof(Fvector)); R_ASSERT(F.find_chunk(EMESH_CHUNK_FACES)); m_FaceCount = F.r_u32(); m_Faces = xr_alloc<st_Face>(m_FaceCount); if (m_FaceCount==0){ Log ("!CEditableMesh: Faces==0."); return false; } F.r (m_Faces, m_FaceCount*sizeof(st_Face)); m_SGs = xr_alloc<u32>(m_FaceCount); Memory.mem_fill32 (m_SGs,m_Flags.is(flSGMask)?0:u32(-1),m_FaceCount); u32 sg_chunk_size = F.find_chunk(EMESH_CHUNK_SG); if (sg_chunk_size){ VERIFY (m_FaceCount*sizeof(u32)==sg_chunk_size); F.r (m_SGs, m_FaceCount*sizeof(u32)); } R_ASSERT(F.find_chunk(EMESH_CHUNK_VMREFS)); m_VMRefs.resize (F.r_u32()); int sz_vmpt = sizeof(st_VMapPt); for (VMRefsIt r_it=m_VMRefs.begin(); r_it!=m_VMRefs.end(); r_it++){ r_it->count = F.r_u8(); r_it->pts = xr_alloc<st_VMapPt>(r_it->count); F.r (r_it->pts, sz_vmpt*r_it->count); } R_ASSERT(F.find_chunk(EMESH_CHUNK_SFACE)); string128 surf_name; u32 sface_cnt = F.r_u16(); // surface-face count for (u32 sp_i=0; sp_i<sface_cnt; sp_i++){ F.r_stringZ (surf_name,sizeof(surf_name)); int surf_id; CSurface* surf = m_Parent->FindSurfaceByName(surf_name, &surf_id); VERIFY(surf); IntVec& face_lst = m_SurfFaces[surf]; face_lst.resize (F.r_u32()); if (face_lst.empty()){ Log ("!Empty surface found: %s",surf->_Name()); return false; } F.r (&*face_lst.begin(), face_lst.size()*sizeof(int)); std::sort (face_lst.begin(),face_lst.end()); } if(F.find_chunk(EMESH_CHUNK_VMAPS_2)){ m_VMaps.resize (F.r_u32()); for (VMapIt vm_it=m_VMaps.begin(); vm_it!=m_VMaps.end(); vm_it++){ *vm_it = xr_new<st_VMap>(); F.r_stringZ ((*vm_it)->name); (*vm_it)->dim = F.r_u8(); (*vm_it)->polymap=F.r_u8(); (*vm_it)->type = F.r_u8(); (*vm_it)->resize(F.r_u32()); F.r ((*vm_it)->getVMdata(), (*vm_it)->VMdatasize()); F.r ((*vm_it)->getVIdata(), (*vm_it)->VIdatasize()); if ((*vm_it)->polymap) F.r ((*vm_it)->getPIdata(), (*vm_it)->PIdatasize()); } }else{ if(F.find_chunk(EMESH_CHUNK_VMAPS_1)){ m_VMaps.resize (F.r_u32()); for (VMapIt vm_it=m_VMaps.begin(); vm_it!=m_VMaps.end(); vm_it++){ *vm_it = xr_new<st_VMap>(); F.r_stringZ ((*vm_it)->name); (*vm_it)->dim = F.r_u8(); (*vm_it)->type = F.r_u8(); (*vm_it)->resize(F.r_u32()); F.r ((*vm_it)->getVMdata(), (*vm_it)->VMdatasize() ); } }else{ R_ASSERT(F.find_chunk(EMESH_CHUNK_VMAPS_0)); m_VMaps.resize (F.r_u32()); for (VMapIt vm_it=m_VMaps.begin(); vm_it!=m_VMaps.end(); vm_it++){ *vm_it = xr_new<st_VMap>(); F.r_stringZ ((*vm_it)->name); (*vm_it)->dim = 2; (*vm_it)->type = vmtUV; (*vm_it)->resize(F.r_u32()); F.r ((*vm_it)->getVMdata(), (*vm_it)->VMdatasize() ); } } // update vmaps RebuildVMaps(); } #ifdef _EDITOR if (!EPrefs->object_flags.is(epoDeffLoadRB)){ GenerateFNormals (); GenerateAdjacency (); GenerateVNormals (); GenerateRenderBuffers(); UnloadFNormals (); UnloadAdjacency (); UnloadVNormals (); } if (!EPrefs->object_flags.is(epoDeffLoadCF)) GenerateCFModel(); #endif Optimize(false); RebuildVMaps(); return true; }
void CEditableMesh::GenerateVNormals() { m_VNormalsRefs++; if (m_VNormals) return; m_VNormals = xr_alloc<Fvector>(m_FaceCount*3); // gen req GenerateFNormals (); GenerateAdjacency (); // vertex normals if (m_Flags.is(flSGMask)){ for (u32 f_i=0; f_i<m_FaceCount; f_i++ ){ u32 sg = m_SGs[f_i]; Fvector& FN = m_FNormals[f_i]; for (int k=0; k<3; k++){ Fvector& N = m_VNormals[f_i*3+k]; if (sg){ N.set (0,0,0); IntVec& a_lst=(*m_Adjs)[m_Faces[f_i].pv[k].pindex]; VERIFY(a_lst.size()); for (IntIt i_it=a_lst.begin(); i_it!=a_lst.end(); i_it++) if (sg&m_SGs[*i_it]) N.add (m_FNormals[*i_it]); float len = N.magnitude(); if (len>EPS_S){ N.div (len); }else{ Msg ("!Invalid smooth group found (MAX type). Object: '%s'. Vertex: [%3.2f, %3.2f, %3.2f]",m_Parent->GetName(),VPUSH(m_Verts[m_Faces[f_i].pv[k].pindex])); N.set (m_FNormals[a_lst.front()]); } }else{ N.set (FN); } } } }else{ for (u32 f_i=0; f_i<m_FaceCount; f_i++ ){ u32 sg = m_SGs[f_i]; Fvector& FN = m_FNormals[f_i]; for (int k=0; k<3; k++){ Fvector& N = m_VNormals[f_i*3+k]; if (sg!=-1){ N.set (0,0,0); IntVec& a_lst=(*m_Adjs)[m_Faces[f_i].pv[k].pindex]; VERIFY (a_lst.size()); for (IntIt i_it=a_lst.begin(); i_it!=a_lst.end(); i_it++){ if (sg != m_SGs[*i_it]) continue; N.add (m_FNormals[*i_it]); } float len = N.magnitude(); if (len>EPS_S){ N.div (len); }else{ Msg ("!Invalid smooth group found (Maya type). Object: '%s'. Vertex: [%3.2f, %3.2f, %3.2f]",m_Parent->GetName(),VPUSH(m_Verts[m_Faces[f_i].pv[k].pindex])); N.set (m_FNormals[a_lst.front()]); } }else{ N.set (FN); /* IntVec& a_lst=(*m_Adjs)[m_Faces[f_i].pv[k].pindex]; VERIFY(a_lst.size()); for (IntIt i_it=a_lst.begin(); i_it!=a_lst.end(); i_it++) N.add (m_FNormals[*i_it]); float len = N.magnitude(); if (len>EPS_S){ N.div (len); }else{ Msg ("!Invalid smooth group found (No smooth). Object: '%s'. Vertex: [%3.2f, %3.2f, %3.2f]",m_Parent->GetName(),VPUSH(m_Verts[m_Faces[f_i].pv[k].pindex])); N.set (m_FNormals[a_lst.front()]); } */ } } } } UnloadFNormals (); UnloadAdjacency (); }
void CEditableMesh::Optimize(BOOL NoOpt) { if (!NoOpt){ #ifdef _EDITOR UnloadRenderBuffers (); UnloadCForm (); #endif UnloadFNormals (true); UnloadVNormals (true); UnloadSVertices (true); UnloadAdjacency (true); // clear static data for (int x=0; x<MX+1; x++) for (int y=0; y<MY+1; y++) for (int z=0; z<MZ+1; z++) VM[x][y][z].clear(); VMscale.set(m_Box.max.x-m_Box.min.x+EPS_S, m_Box.max.y-m_Box.min.y+EPS_S, m_Box.max.z-m_Box.min.z+EPS_S); VMmin.set(m_Box.min.x, m_Box.min.y, m_Box.min.z); VMeps.set(VMscale.x/MX/2,VMscale.y/MY/2,VMscale.z/MZ/2); VMeps.x = (VMeps.x<EPS_L)?VMeps.x:EPS_L; VMeps.y = (VMeps.y<EPS_L)?VMeps.y:EPS_L; VMeps.z = (VMeps.z<EPS_L)?VMeps.z:EPS_L; m_NewPoints.clear(); m_NewPoints.reserve(m_VertCount); boolVec faces_mark; faces_mark.resize(m_FaceCount,false); int i_del_face = 0; for (u32 k=0; k<m_FaceCount; k++){ if (!OptimizeFace(m_Faces[k])){ faces_mark[k] = true; i_del_face ++; } } m_VertCount = m_NewPoints.size(); xr_free (m_Verts); m_Verts = xr_alloc<Fvector>(m_VertCount); Memory.mem_copy (m_Verts,&*m_NewPoints.begin(),m_NewPoints.size()*sizeof(Fvector)); if (i_del_face){ st_Face* old_faces = m_Faces; u32* old_sg = m_SGs; m_Faces = xr_alloc<st_Face> (m_FaceCount-i_del_face); m_SGs = xr_alloc<u32> (m_FaceCount-i_del_face); u32 new_dk = 0; for (u32 dk=0; dk<m_FaceCount; dk++){ if (faces_mark[dk]){ for (SurfFacesPairIt plp_it=m_SurfFaces.begin(); plp_it!=m_SurfFaces.end(); plp_it++){ IntVec& pol_lst = plp_it->second; for (int k=0; k<int(pol_lst.size()); k++){ int& f = pol_lst[k]; if (f>(int)dk){ f--; }else if (f==(int)dk){ pol_lst.erase(pol_lst.begin()+k); k--; } } } continue; } m_Faces[new_dk] = old_faces[dk]; m_SGs[new_dk] = old_sg[dk]; new_dk++; } m_FaceCount = m_FaceCount-i_del_face; xr_free (old_faces); xr_free (old_sg); } } }