From e0c83d03ba3200c704d82fb1ae175914ef514f44 Mon Sep 17 00:00:00 2001 From: Nicholas Bishop Date: Thu, 14 Aug 2008 01:14:46 +0000 Subject: Removed *yet more!* old crufty multires stuff. I think this is all of it now. --- source/blender/blenkernel/BKE_multires.h | 1 - source/blender/blenkernel/intern/mesh.c | 6 - source/blender/blenkernel/intern/modifier.c | 9 - .../blenkernel/intern/multires-firstlevel.c | 409 ------------ source/blender/blenkernel/intern/multires.c | 703 +-------------------- source/blender/makesdna/DNA_meshdata_types.h | 3 - .../blender/render/intern/include/render_types.h | 1 - .../blender/render/intern/source/convertblender.c | 9 - source/blender/src/buttons_editing.c | 2 - source/blender/src/editface.c | 11 +- source/blender/src/editkey.c | 37 +- source/blender/src/editmesh_mods.c | 4 +- source/blender/src/editobject.c | 3 - source/blender/src/meshtools.c | 10 +- 14 files changed, 21 insertions(+), 1187 deletions(-) delete mode 100644 source/blender/blenkernel/intern/multires-firstlevel.c diff --git a/source/blender/blenkernel/BKE_multires.h b/source/blender/blenkernel/BKE_multires.h index 46ba254a012..355e1d21e7c 100644 --- a/source/blender/blenkernel/BKE_multires.h +++ b/source/blender/blenkernel/BKE_multires.h @@ -37,7 +37,6 @@ struct Mesh; struct Object; /* Level access */ -struct MultiresLevel *current_level(struct Multires *mr); struct MultiresLevel *multires_level_n(struct Multires *mr, int n); /* Level control */ diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c index 43e48c3bacd..3846403e5d7 100644 --- a/source/blender/blenkernel/intern/mesh.c +++ b/source/blender/blenkernel/intern/mesh.c @@ -58,7 +58,6 @@ #include "BKE_DerivedMesh.h" #include "BKE_global.h" #include "BKE_mesh.h" -#include "BKE_multires.h" #include "BKE_subsurf.h" #include "BKE_displist.h" #include "BKE_library.h" @@ -182,8 +181,6 @@ void free_mesh(Mesh *me) if(me->bb) MEM_freeN(me->bb); if(me->mselect) MEM_freeN(me->mselect); - - if(me->mr) multires_free(me->mr); } void copy_dverts(MDeformVert *dst, MDeformVert *src, int copycount) @@ -271,9 +268,6 @@ Mesh *copy_mesh(Mesh *me) } } - if(me->mr) - men->mr= multires_copy(me->mr); - men->mselect= NULL; men->bb= MEM_dupallocN(men->bb); diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index 4f0960c73f2..c64605ab0d9 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -5709,7 +5709,6 @@ static void particleSystemModifier_deformVerts( DerivedMesh *dm = derivedData; ParticleSystemModifierData *psmd= (ParticleSystemModifierData*) md; ParticleSystem * psys=0; - Mesh *me; int needsFree=0; if(ob->particlesystem.first) @@ -5717,14 +5716,6 @@ static void particleSystemModifier_deformVerts( else return; - /* multires check */ - if(ob->type == OB_MESH) { - me= (Mesh*)ob->data; - if(me->mr && me->mr->current != 1) - modifier_setError(md, - "Particles only supported on first multires level."); - } - if(!psys_check_enabled(ob, psys)) return; diff --git a/source/blender/blenkernel/intern/multires-firstlevel.c b/source/blender/blenkernel/intern/multires-firstlevel.c deleted file mode 100644 index 3d417565eb1..00000000000 --- a/source/blender/blenkernel/intern/multires-firstlevel.c +++ /dev/null @@ -1,409 +0,0 @@ -/* - * $Id$ - * - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * 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. - * - * The Original Code is Copyright (C) 2006 by Nicholas Bishop - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - * - * Deals with the first-level data in multires (edge flags, weights, and UVs) - * - * multires.h - * - */ - -#include "DNA_customdata_types.h" -#include "DNA_mesh_types.h" -#include "DNA_meshdata_types.h" -#include "DNA_object_types.h" -#include "DNA_scene_types.h" - -#include "BIF_editmesh.h" - -#include "BKE_customdata.h" -#include "BKE_global.h" -#include "BKE_mesh.h" -#include "BKE_multires.h" - -#include "BLI_editVert.h" - -#include "MEM_guardedalloc.h" - -#include "blendef.h" - -#include - -MDeformVert *subdivide_dverts(MDeformVert *src, MultiresLevel *lvl); -MTFace *subdivide_mtfaces(MTFace *src, MultiresLevel *lvl); -void multires_update_edge_flags(Mesh *me, EditMesh *em); -void eed_to_medge_flag(EditEdge *eed, short *flag, char *crease); - -/*********** Generic ***********/ - -CustomDataMask cdmask(const int type) -{ - if(type == CD_MDEFORMVERT) - return CD_MASK_MDEFORMVERT; - else if(type == CD_MTFACE) - return CD_MASK_MTFACE; - return -1; -} - -char type_ok(const int type) -{ - return (type == CD_MDEFORMVERT) || (type == CD_MTFACE); -} - -/* Copy vdata or fdata from Mesh or EditMesh to Multires. */ -void multires_update_customdata(MultiresLevel *lvl1, EditMesh *em, CustomData *src, CustomData *dst, const int type) -{ - if(src && dst && type_ok(type)) { - const int tot= (type == CD_MDEFORMVERT ? lvl1->totvert : lvl1->totface); - int i; - - CustomData_free(dst, tot); - - if(CustomData_has_layer(src, type)) { - if(em) { - EditVert *eve= G.editMesh->verts.first; - EditFace *efa= G.editMesh->faces.first; - CustomData_copy(src, dst, cdmask(type), CD_CALLOC, tot); - for(i=0; ivdata, dst, eve->data, i); - eve= eve->next; - } - else if(type == CD_MTFACE) { - CustomData_from_em_block(&G.editMesh->fdata, dst, efa->data, i); - efa= efa->next; - } - } - } - else - CustomData_copy(src, dst, cdmask(type), CD_DUPLICATE, tot); - } - } -} - -/* Uses subdivide_dverts or subdivide_mtfaces to subdivide src to match lvl_end. Does not free src. */ -void *subdivide_customdata_to_level(void *src, MultiresLevel *lvl_start, - MultiresLevel *lvl_end, const int type) -{ - if(src && lvl_start && lvl_end && type_ok(type)) { - MultiresLevel *lvl; - void *cr_data= NULL, *pr_data= NULL; - - pr_data= src; - for(lvl= lvl_start; lvl && lvl != lvl_end; lvl= lvl->next) { - if(type == CD_MDEFORMVERT) - cr_data= subdivide_dverts(pr_data, lvl); - else if(type == CD_MTFACE) - cr_data= subdivide_mtfaces(pr_data, lvl); - - /* Free previous subdivision level's data */ - if(lvl != lvl_start) { - if(type == CD_MDEFORMVERT) - free_dverts(pr_data, lvl->totvert); - else if(type == CD_MTFACE) - MEM_freeN(pr_data); - } - - pr_data= cr_data; - cr_data= NULL; - } - - return pr_data; - } - - return NULL; -} - -/* Directly copy src into dst (handles both Mesh and EditMesh) */ -void customdata_to_mesh(Mesh *me, EditMesh *em, CustomData *src, CustomData *dst, const int tot, const int type) -{ - if(me && me->mr && src && dst && type_ok(type)) { - if(em) { - int i; - EditVert *eve= em->verts.first; - EditFace *efa= em->faces.first; - CustomData_copy(src, dst, cdmask(type), CD_CALLOC, 0); - - for(i=0; idata); - eve= eve->next; - } - else if(type == CD_MTFACE) { - CustomData_to_em_block(src, dst, i, &efa->data); - efa= efa->next; - } - } - } else { - CustomData_merge(src, dst, cdmask(type), CD_DUPLICATE, tot); - } - } -} - -/* Subdivide vdata or fdata from Multires into either Mesh or EditMesh. */ -void multires_customdata_to_mesh(Mesh *me, EditMesh *em, MultiresLevel *lvl, CustomData *src, - CustomData *dst, const int type) -{ - if(me && me->mr && lvl && src && dst && type_ok(type) && - CustomData_has_layer(src, type)) { - const int tot= (type == CD_MDEFORMVERT ? lvl->totvert : lvl->totface); - if(lvl == me->mr->levels.first) { - customdata_to_mesh(me, em, src, dst, tot, type); - } - else { - CustomData cdf; - const int count = CustomData_number_of_layers(src, type); - int i; - - /* Construct a new CustomData containing the subdivided data */ - CustomData_copy(src, &cdf, cdmask(type), CD_ASSIGN, tot); - for(i=0; imr->levels.first, lvl, type)); - } - - customdata_to_mesh(me, em, &cdf, dst, tot, type); - CustomData_free(&cdf, tot); - } - } -} - -/* Subdivide the first-level customdata up to cr_lvl, then delete the original data */ -void multires_del_lower_customdata(Multires *mr, MultiresLevel *cr_lvl) -{ - MultiresLevel *lvl1= mr->levels.first; - MDeformVert *dverts= NULL; - CustomData cdf; - int i; - - /* dverts */ - dverts= subdivide_customdata_to_level(CustomData_get(&mr->vdata, 0, CD_MDEFORMVERT), - lvl1, cr_lvl, CD_MDEFORMVERT); - if(dverts) { - CustomData_free_layers(&mr->vdata, CD_MDEFORMVERT, lvl1->totvert); - CustomData_add_layer(&mr->vdata, CD_MDEFORMVERT, CD_ASSIGN, dverts, cr_lvl->totvert); - } - - /* mtfaces */ - CustomData_copy(&mr->fdata, &cdf, CD_MASK_MTFACE, CD_ASSIGN, cr_lvl->totface); - for(i=0; ifdata, CD_MTFACE); ++i) { - MTFace *mtfaces= - subdivide_customdata_to_level(CustomData_get_layer_n(&mr->fdata, CD_MTFACE, i), - lvl1, cr_lvl, CD_MTFACE); - if(mtfaces) - CustomData_set_layer_n(&cdf, CD_MTFACE, i, mtfaces); - } - - CustomData_free(&mr->fdata, lvl1->totface); - mr->fdata= cdf; -} - -/* Update all special first-level data, if the first-level is active */ -void multires_update_first_level(Mesh *me, EditMesh *em) -{ - if(me && me->mr && me->mr->current == 1) { - multires_update_customdata(me->mr->levels.first, em, em ? &em->vdata : &me->vdata, - &me->mr->vdata, CD_MDEFORMVERT); - multires_update_customdata(me->mr->levels.first, em, em ? &em->fdata : &me->fdata, - &me->mr->fdata, CD_MTFACE); - multires_update_edge_flags(me, em); - } -} - -/*********** Multires.edge_flags ***********/ -void multires_update_edge_flags(Mesh *me, EditMesh *em) -{ - MultiresLevel *lvl= me->mr->levels.first; - EditEdge *eed= NULL; - int i; - - if(em) eed= em->edges.first; - for(i=0; itotedge; ++i) { - if(em) { - me->mr->edge_flags[i]= 0; - eed_to_medge_flag(eed, &me->mr->edge_flags[i], &me->mr->edge_creases[i]); - eed= eed->next; - } - else { - me->mr->edge_flags[i]= me->medge[i].flag; - me->mr->edge_creases[i]= me->medge[i].crease; - } - } -} - - - -/*********** Multires.vdata ***********/ - -/* MDeformVert */ - -/* Add each weight from in to out. Scale each weight by w. */ -void multires_add_dvert(MDeformVert *out, const MDeformVert *in, const float w) -{ - if(out && in) { - int i, j; - char found; - - for(i=0; itotweight; ++i) { - found= 0; - for(j=0; jtotweight; ++j) { - if(out->dw[j].def_nr==in->dw[i].def_nr) { - out->dw[j].weight += in->dw[i].weight * w; - found= 1; - } - } - if(!found) { - MDeformWeight *newdw= MEM_callocN(sizeof(MDeformWeight)*(out->totweight+1), - "multires dvert"); - if(out->dw) { - memcpy(newdw, out->dw, sizeof(MDeformWeight)*out->totweight); - MEM_freeN(out->dw); - } - - out->dw= newdw; - out->dw[out->totweight].weight= in->dw[i].weight * w; - out->dw[out->totweight].def_nr= in->dw[i].def_nr; - - ++out->totweight; - } - } - } -} - -/* Takes an input array of dverts and subdivides them (linear) using the topology of lvl */ -MDeformVert *subdivide_dverts(MDeformVert *src, MultiresLevel *lvl) -{ - if(lvl && lvl->next) { - MDeformVert *out = MEM_callocN(sizeof(MDeformVert)*lvl->next->totvert, "dvert prop array"); - int i, j; - - /* Copy lower level */ - for(i=0; itotvert; ++i) - multires_add_dvert(&out[i], &src[i], 1); - /* Edge verts */ - for(i=0; itotedge; ++i) { - for(j=0; j<2; ++j) - multires_add_dvert(&out[lvl->totvert+i], &src[lvl->edges[i].v[j]],0.5); - } - - /* Face verts */ - for(i=0; itotface; ++i) { - for(j=0; j<(lvl->faces[i].v[3]?4:3); ++j) - multires_add_dvert(&out[lvl->totvert + lvl->totedge + i], - &src[lvl->faces[i].v[j]], - lvl->faces[i].v[3]?0.25:(1.0f/3.0f)); - } - - return out; - } - - return NULL; -} - - - -/*********** Multires.fdata ***********/ - -/* MTFace */ - -void multires_uv_avg2(float out[2], const float a[2], const float b[2]) -{ - int i; - for(i=0; i<2; ++i) - out[i] = (a[i] + b[i]) / 2.0f; -} - -/* Takes an input array of mtfaces and subdivides them (linear) using the topology of lvl */ -MTFace *subdivide_mtfaces(MTFace *src, MultiresLevel *lvl) -{ - if(lvl && lvl->next) { - MTFace *out= MEM_callocN(sizeof(MultiresColFace)*lvl->next->totface,"Multirescolfaces"); - int i, j, curf; - - for(i=0, curf=0; itotface; ++i) { - const char sides= lvl->faces[i].v[3]?4:3; - float cntr[2]= {0, 0}; - - /* Find average uv coord of the current face */ - for(j=0; jmr && cd) { - MultiresLevel *lvl1= me->mr->levels.first; - - multires_update_levels(me, 0); - - CustomData_set_layer_active(cd, type, n); - CustomData_free_layer_active(cd, type, lvl1->totface); - - multires_level_to_mesh(OBACT, me, 0); - } -} - -void multires_add_layer(Mesh *me, CustomData *cd, const int type, const int n) -{ - if(me && me->mr && cd) { - multires_update_levels(me, 0); - - if(CustomData_has_layer(cd, type)) - CustomData_add_layer(cd, type, CD_DUPLICATE, CustomData_get_layer(cd, type), - current_level(me->mr)->totface); - else - CustomData_add_layer(cd, type, CD_DEFAULT, NULL, current_level(me->mr)->totface); - - CustomData_set_layer_active(cd, type, n); - multires_level_to_mesh(OBACT, me, 0); - } -} diff --git a/source/blender/blenkernel/intern/multires.c b/source/blender/blenkernel/intern/multires.c index f62cff8fc0d..cfa60c04127 100644 --- a/source/blender/blenkernel/intern/multires.c +++ b/source/blender/blenkernel/intern/multires.c @@ -35,46 +35,27 @@ #include "DNA_modifier_types.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" -#include "DNA_vec_types.h" #include "DNA_view3d_types.h" -#include "BIF_editmesh.h" - #include "BLI_arithb.h" #include "BLI_blenlib.h" -#include "BLI_editVert.h" #include "BKE_cdderivedmesh.h" #include "BKE_customdata.h" #include "BKE_depsgraph.h" #include "BKE_DerivedMesh.h" #include "BKE_global.h" +#include "BKE_mesh.h" #include "BKE_modifier.h" #include "BKE_multires.h" #include "BKE_object.h" #include "BKE_subsurf.h" #include "blendef.h" -#include "editmesh.h" #include #include -/* Returns the active multires level (currently applied to the mesh) */ -MultiresLevel *current_level(Multires *mr) -{ - return BLI_findlink(&mr->levels, mr->current - 1); -} - -/* Returns the nth multires level, starting at 1 */ -MultiresLevel *multires_level_n(Multires *mr, int n) -{ - if(mr) - return BLI_findlink(&mr->levels, n - 1); - else - return NULL; -} - /* Does not actually free lvl itself */ void multires_free_level(MultiresLevel *lvl) { @@ -111,688 +92,6 @@ void multires_free(Multires *mr) } } -static MultiresLevel *multires_level_copy(MultiresLevel *orig) -{ - if(orig) { - MultiresLevel *lvl= MEM_dupallocN(orig); - - lvl->next= lvl->prev= NULL; - lvl->faces= MEM_dupallocN(orig->faces); - lvl->colfaces= MEM_dupallocN(orig->colfaces); - lvl->edges= MEM_dupallocN(orig->edges); - - return lvl; - } - return NULL; -} - -Multires *multires_copy(Multires *orig) -{ - const CustomDataMask vdata_mask= CD_MASK_MDEFORMVERT; - - if(orig) { - Multires *mr= MEM_dupallocN(orig); - MultiresLevel *lvl; - - mr->levels.first= mr->levels.last= NULL; - - for(lvl= orig->levels.first; lvl; lvl= lvl->next) - BLI_addtail(&mr->levels, multires_level_copy(lvl)); - - mr->verts= MEM_dupallocN(orig->verts); - - lvl= mr->levels.first; - if(lvl) { - CustomData_copy(&orig->vdata, &mr->vdata, vdata_mask, CD_DUPLICATE, lvl->totvert); - CustomData_copy(&orig->fdata, &mr->fdata, CD_MASK_MTFACE, CD_DUPLICATE, lvl->totface); - mr->edge_flags= MEM_dupallocN(orig->edge_flags); - mr->edge_creases= MEM_dupallocN(orig->edge_creases); - } - - return mr; - } - return NULL; -} - -static void multires_get_vert(MVert *out, EditVert *eve, MVert *m, int i) -{ - if(eve) { - VecCopyf(out->co, eve->co); - out->flag= 0; - if(eve->f & SELECT) out->flag |= 1; - if(eve->h) out->flag |= ME_HIDE; - eve->tmp.l= i; - } - else - *out= *m; -} - -void eed_to_medge_flag(EditEdge *eed, short *flag, char *crease) -{ - if(!eed || !flag) return; - - /* Would be nice if EditMesh edge flags could be unified with Mesh flags! */ - *flag= (eed->f & SELECT) | ME_EDGERENDER; - if(eed->f2<2) *flag |= ME_EDGEDRAW; - if(eed->f2==0) *flag |= ME_LOOSEEDGE; - if(eed->sharp) *flag |= ME_SHARP; - if(eed->seam) *flag |= ME_SEAM; - if(eed->h & EM_FGON) *flag |= ME_FGON; - if(eed->h & 1) *flag |= ME_HIDE; - - *crease= (char)(255.0*eed->crease); -} - -static void multires_get_edge(MultiresEdge *e, EditEdge *eed, MEdge *m, short *flag, char *crease) -{ - if(eed) { - e->v[0]= eed->v1->tmp.l; - e->v[1]= eed->v2->tmp.l; - eed_to_medge_flag(eed, flag, crease); - } else { - e->v[0]= m->v1; - e->v[1]= m->v2; - *flag= m->flag; - *crease= m->crease; - } -} - -static void multires_get_face(MultiresFace *f, EditFace *efa, MFace *m) -{ - if(efa) { - MFace tmp; - int j; - tmp.v1= efa->v1->tmp.l; - tmp.v2= efa->v2->tmp.l; - tmp.v3= efa->v3->tmp.l; - tmp.v4= 0; - if(efa->v4) tmp.v4= efa->v4->tmp.l; - test_index_face(&tmp, NULL, 0, efa->v4?4:3); - for(j=0; j<4; ++j) f->v[j]= (&tmp.v1)[j]; - - /* Flags */ - f->flag= efa->flag; - if(efa->f & 1) f->flag |= ME_FACE_SEL; - else f->flag &= ~ME_FACE_SEL; - if(efa->h) f->flag |= ME_HIDE; - f->mat_nr= efa->mat_nr; - } else { - f->v[0]= m->v1; - f->v[1]= m->v2; - f->v[2]= m->v3; - f->v[3]= m->v4; - f->flag= m->flag; - f->mat_nr= m->mat_nr; - } -} - -/* For manipulating vertex colors / uvs */ -static void mcol_to_multires(MultiresColFace *mrf, MCol *mcol) -{ - char i; - for(i=0; i<4; ++i) { - mrf->col[i].a= mcol[i].a; - mrf->col[i].r= mcol[i].r; - mrf->col[i].g= mcol[i].g; - mrf->col[i].b= mcol[i].b; - } -} - -/* 1 <= count <= 4 */ -static void multires_col_avg(MultiresCol *avg, MultiresCol cols[4], char count) -{ - unsigned i; - avg->a= avg->r= avg->g= avg->b= 0; - for(i=0; ia+= cols[i].a; - avg->r+= cols[i].r; - avg->g+= cols[i].g; - avg->b+= cols[i].b; - } - avg->a/= count; - avg->r/= count; - avg->g/= count; - avg->b/= count; -} - -static void multires_col_avg2(MultiresCol *avg, MultiresCol *c1, MultiresCol *c2) -{ - MultiresCol in[2]; - in[0]= *c1; - in[1]= *c2; - multires_col_avg(avg,in,2); -} - -void multires_load_cols(Mesh *me) -{ - MultiresLevel *lvl= BLI_findlink(&me->mr->levels,me->mr->current-1), *cur; - EditMesh *em= G.obedit ? G.editMesh : NULL; - CustomData *src= em ? &em->fdata : &me->fdata; - EditFace *efa= NULL; - unsigned i,j; - - if(!CustomData_has_layer(src, CD_MCOL) && !CustomData_has_layer(src, CD_MTFACE)) return; - - /* Add texcol data */ - for(cur= me->mr->levels.first; cur; cur= cur->next) - if(!cur->colfaces) - cur->colfaces= MEM_callocN(sizeof(MultiresColFace)*cur->totface,"ColFaces"); - - me->mr->use_col= CustomData_has_layer(src, CD_MCOL); - - if(em) efa= em->faces.first; - for(i=0; itotface; ++i) { - MultiresColFace *f= &lvl->colfaces[i]; - - if(me->mr->use_col) - mcol_to_multires(f, em ? CustomData_em_get(src, efa->data, CD_MCOL) : &me->mcol[i*4]); - - if(em) efa= efa->next; - } - - /* Update higher levels */ - lvl= lvl->next; - while(lvl) { - MultiresColFace *cf= lvl->colfaces; - for(i=0; iprev->totface; ++i) { - const char sides= lvl->prev->faces[i].v[3]?4:3; - MultiresCol cntr; - - /* Find average color of 4 (or 3 for triangle) verts */ - multires_col_avg(&cntr,lvl->prev->colfaces[i].col,sides); - - for(j=0; jprev->colfaces[i]; - - multires_col_avg2(&cf->col[0], - &pf->col[j], - &pf->col[j==0?sides-1:j-1]); - cf->col[1]= pf->col[j]; - multires_col_avg2(&cf->col[2], - &pf->col[j], - &pf->col[j==sides-1?0:j+1]); - cf->col[3]= cntr; - - ++cf; - } - } - lvl= lvl->next; - } - - /* Update lower levels */ - lvl= me->mr->levels.last; - lvl= lvl->prev; - while(lvl) { - unsigned curf= 0; - for(i=0; itotface; ++i) { - MultiresFace *f= &lvl->faces[i]; - for(j=0; j<(f->v[3]?4:3); ++j) { - lvl->colfaces[i].col[j]= lvl->next->colfaces[curf].col[1]; - ++curf; - } - } - lvl= lvl->prev; - } -} - -void multires_create(Object *ob, Mesh *me) -{ - MultiresLevel *lvl; - EditMesh *em= G.obedit ? G.editMesh : NULL; - EditVert *eve= NULL; - EditFace *efa= NULL; - EditEdge *eed= NULL; - int i; - - lvl= MEM_callocN(sizeof(MultiresLevel), "multires level"); - - if(me->pv) mesh_pmv_off(ob, me); - - me->mr= MEM_callocN(sizeof(Multires), "multires data"); - - BLI_addtail(&me->mr->levels,lvl); - me->mr->current= 1; - me->mr->level_count= 1; - me->mr->edgelvl= 1; - me->mr->pinlvl= 1; - me->mr->renderlvl= 1; - - /* Load mesh (or editmesh) into multires data */ - - /* Load vertices and vdata (MDeformVerts) */ - lvl->totvert= em ? BLI_countlist(&em->verts) : me->totvert; - me->mr->verts= MEM_callocN(sizeof(MVert)*lvl->totvert,"multires verts"); - multires_update_customdata(me->mr->levels.first, em, em ? &em->vdata : &me->vdata, - &me->mr->vdata, CD_MDEFORMVERT); - if(em) eve= em->verts.first; - for(i=0; itotvert; ++i) { - multires_get_vert(&me->mr->verts[i], eve, &me->mvert[i], i); - if(em) eve= eve->next; - } - - /* Load faces and fdata (MTFaces) */ - lvl->totface= em ? BLI_countlist(&em->faces) : me->totface; - lvl->faces= MEM_callocN(sizeof(MultiresFace)*lvl->totface,"multires faces"); - multires_update_customdata(me->mr->levels.first, em, em ? &em->fdata : &me->fdata, - &me->mr->fdata, CD_MTFACE); - if(em) efa= em->faces.first; - for(i=0; itotface; ++i) { - multires_get_face(&lvl->faces[i], efa, &me->mface[i]); - if(em) efa= efa->next; - } - - /* Load edges and edge_flags */ - lvl->totedge= em ? BLI_countlist(&em->edges) : me->totedge; - lvl->edges= MEM_callocN(sizeof(MultiresEdge)*lvl->totedge,"multires edges"); - me->mr->edge_flags= MEM_callocN(sizeof(short)*lvl->totedge, "multires edge flags"); - me->mr->edge_creases= MEM_callocN(sizeof(short)*lvl->totedge, "multires edge creases"); - if(em) eed= em->edges.first; - for(i=0; itotedge; ++i) { - multires_get_edge(&lvl->edges[i], eed, &me->medge[i], &me->mr->edge_flags[i], &me->mr->edge_creases[i]); - if(em) eed= eed->next; - } - - multires_load_cols(me); -} - -typedef struct MultiresMapNode { - struct MultiresMapNode *next, *prev; - unsigned Index; -} MultiresMapNode; - -/* CATMULL-CLARK - ============= */ - -typedef struct MultiApplyData { - /* Smooth faces */ - float *corner1, *corner2, *corner3, *corner4; - char quad; - - /* Smooth edges */ - char boundary; - float edge_face_neighbor_midpoints_accum[3]; - unsigned edge_face_neighbor_midpoints_total; - float *endpoint1, *endpoint2; - - /* Smooth verts */ - /* uses 'char boundary' */ - float *original; - int edge_count; - float vert_face_neighbor_midpoints_average[3]; - float vert_edge_neighbor_midpoints_average[3]; - float boundary_edges_average[3]; -} MultiApplyData; - -/* END CATMULL-CLARK - ================= */ - -static void multires_update_faces(Mesh *me, EditMesh *em) -{ - MultiresLevel *cr_lvl= current_level(me->mr), *pr_lvl= NULL, - *last_lvl= me->mr->levels.last; - char *pr_flag_damaged= NULL, *cr_flag_damaged= NULL, *or_flag_damaged= NULL, - *pr_mat_damaged= NULL, *cr_mat_damaged= NULL, *or_mat_damaged= NULL, *swap= NULL; - EditFace *efa= NULL; - unsigned i,j,curf; - - /* Find for each face whether flag/mat has changed */ - pr_flag_damaged= MEM_callocN(sizeof(char) * last_lvl->totface, "flag_damaged 1"); - cr_flag_damaged= MEM_callocN(sizeof(char) * last_lvl->totface, "flag_damaged 1"); - pr_mat_damaged= MEM_callocN(sizeof(char) * last_lvl->totface, "mat_damaged 1"); - cr_mat_damaged= MEM_callocN(sizeof(char) * last_lvl->totface, "mat_damaged 1"); - if(em) efa= em->faces.first; - for(i=0; itotface; ++i) { - MultiresFace mftmp; - multires_get_face(&mftmp, efa, &me->mface[i]); - if(cr_lvl->faces[i].flag != mftmp.flag) - cr_flag_damaged[i]= 1; - if(cr_lvl->faces[i].mat_nr != mftmp.mat_nr) - cr_mat_damaged[i]= 1; - - /* Update current level */ - cr_lvl->faces[i].flag= mftmp.flag; - cr_lvl->faces[i].mat_nr= mftmp.mat_nr; - - if(em) efa= efa->next; - } - or_flag_damaged= MEM_dupallocN(cr_flag_damaged); - or_mat_damaged= MEM_dupallocN(cr_mat_damaged); - - /* Update lower levels */ - cr_lvl= cr_lvl->prev; - while(cr_lvl) { - swap= pr_flag_damaged; - pr_flag_damaged= cr_flag_damaged; - cr_flag_damaged= swap; - - swap= pr_mat_damaged; - pr_mat_damaged= cr_mat_damaged; - cr_mat_damaged= swap; - - curf= 0; - for(i=0; itotface; ++i) { - const int sides= cr_lvl->faces[i].v[3] ? 4 : 3; - - /* Check damages */ - for(j=0; jfaces[i].flag= cr_lvl->next->faces[curf].flag; - cr_flag_damaged[i]= 1; - } - if(pr_mat_damaged[curf]) { - cr_lvl->faces[i].mat_nr= cr_lvl->next->faces[curf].mat_nr; - cr_mat_damaged[i]= 1; - } - } - } - - cr_lvl= cr_lvl->prev; - } - - /* Clear to original damages */ - if(cr_flag_damaged) MEM_freeN(cr_flag_damaged); - if(cr_mat_damaged) MEM_freeN(cr_mat_damaged); - cr_flag_damaged= or_flag_damaged; - cr_mat_damaged= or_mat_damaged; - - /* Update higher levels */ - pr_lvl= current_level(me->mr); - cr_lvl= pr_lvl->next; - while(cr_lvl) { - swap= pr_flag_damaged; - pr_flag_damaged= cr_flag_damaged; - cr_flag_damaged= swap; - - swap= pr_mat_damaged; - pr_mat_damaged= cr_mat_damaged; - cr_mat_damaged= swap; - - /* Update faces */ - for(i=0, curf= 0; itotface; ++i) { - const int sides= cr_lvl->prev->faces[i].v[3] ? 4 : 3; - for(j=0; jfaces[curf].flag= pr_lvl->faces[i].flag; - cr_flag_damaged[curf]= 1; - } - if(pr_mat_damaged[i]) { - cr_lvl->faces[curf].mat_nr= pr_lvl->faces[i].mat_nr; - cr_mat_damaged[curf]= 1; - } - } - } - - pr_lvl= pr_lvl->next; - cr_lvl= cr_lvl->next; - } - - if(pr_flag_damaged) MEM_freeN(pr_flag_damaged); - if(cr_flag_damaged) MEM_freeN(cr_flag_damaged); - if(pr_mat_damaged) MEM_freeN(pr_mat_damaged); - if(cr_mat_damaged) MEM_freeN(cr_mat_damaged); -} - -static void multires_update_colors(Mesh *me, EditMesh *em) -{ - MultiresLevel *lvl= BLI_findlink(&me->mr->levels,me->mr->current-1); - MultiresCol *pr_deltas= NULL, *cr_deltas= NULL; - CustomData *src= em ? &em->fdata : &me->fdata; - EditFace *efa= NULL; - unsigned i,j,curf= 0; - - if(me->mr->use_col) { - /* Calc initial deltas */ - cr_deltas= MEM_callocN(sizeof(MultiresCol)*lvl->totface*4,"initial color/uv deltas"); - - if(em) efa= em->faces.first; - for(i=0; itotface; ++i) { - MCol *col= em ? CustomData_em_get(src, efa->data, CD_MCOL) : &me->mcol[i*4]; - for(j=0; j<4; ++j) { - if(me->mr->use_col) { - cr_deltas[i*4+j].a= col[j].a - lvl->colfaces[i].col[j].a; - cr_deltas[i*4+j].r= col[j].r - lvl->colfaces[i].col[j].r; - cr_deltas[i*4+j].g= col[j].g - lvl->colfaces[i].col[j].g; - cr_deltas[i*4+j].b= col[j].b - lvl->colfaces[i].col[j].b; - } - } - if(em) efa= efa->next; - } - - /* Update current level */ - if(em) efa= em->faces.first; - for(i=0; itotface; ++i) { - MultiresColFace *f= &lvl->colfaces[i]; - - if(me->mr->use_col) - mcol_to_multires(f, em ? CustomData_em_get(src, efa->data, CD_MCOL) : &me->mcol[i*4]); - - if(em) efa= efa->next; - } - - /* Update higher levels */ - lvl= lvl->next; - while(lvl) { - /* Set up new deltas, but keep the ones from the previous level */ - if(pr_deltas) MEM_freeN(pr_deltas); - pr_deltas= cr_deltas; - cr_deltas= MEM_callocN(sizeof(MultiresCol)*lvl->totface*4,"color deltas"); - - curf= 0; - for(i=0; iprev->totface; ++i) { - const char sides= lvl->prev->faces[i].v[3]?4:3; - MultiresCol cntr; - - /* Find average color of 4 (or 3 for triangle) verts */ - multires_col_avg(&cntr,&pr_deltas[i*4],sides); - - for(j=0; jtotface; ++i) { - for(j=0; j<4; ++j) { - lvl->colfaces[i].col[j].a+= cr_deltas[i*4+j].a; - lvl->colfaces[i].col[j].r+= cr_deltas[i*4+j].r; - lvl->colfaces[i].col[j].g+= cr_deltas[i*4+j].g; - lvl->colfaces[i].col[j].b+= cr_deltas[i*4+j].b; - } - } - - lvl= lvl->next; - } - if(pr_deltas) MEM_freeN(pr_deltas); - if(cr_deltas) MEM_freeN(cr_deltas); - - /* Update lower levels */ - lvl= me->mr->levels.last; - lvl= lvl->prev; - while(lvl) { - MultiresColFace *nf= lvl->next->colfaces; - for(i=0; itotface; ++i) { - MultiresFace *f= &lvl->faces[i]; - for(j=0; j<(f->v[3]?4:3); ++j) { - lvl->colfaces[i].col[j]= nf->col[1]; - ++nf; - } - } - lvl= lvl->prev; - } - } -} - -void multires_update_levels(Mesh *me, const int render) -{ - EditMesh *em= (!render && G.obedit) ? G.editMesh : NULL; - - multires_update_first_level(me, em); - multires_update_faces(me, em); - multires_update_colors(me, em); -} - -static void check_colors(Mesh *me) -{ - CustomData *src= G.obedit ? &G.editMesh->fdata : &me->fdata; - const char col= CustomData_has_layer(src, CD_MCOL); - - /* Check if vertex colors have been deleted or added */ - if(me->mr->use_col && !col) - me->mr->use_col= 0; - else if(!me->mr->use_col && col) { - me->mr->use_col= 1; - multires_load_cols(me); - } -} - -static float clamp_component(const float c) -{ - if(c<0) return 0; - else if(c>255) return 255; - else return c; -} - -void multires_to_mcol(MultiresColFace *f, MCol mcol[4]) -{ - unsigned char j; - for(j=0; j<4; ++j) { - mcol->a= clamp_component(f->col[j].a); - mcol->r= clamp_component(f->col[j].r); - mcol->g= clamp_component(f->col[j].g); - mcol->b= clamp_component(f->col[j].b); - ++mcol; - } -} - -void multires_level_to_mesh(Object *ob, Mesh *me, const int render) -{ - MultiresLevel *lvl= BLI_findlink(&me->mr->levels,me->mr->current-1); - int i; - EditMesh *em= (!render && G.obedit) ? G.editMesh : NULL; - - if(em) - return; - - CustomData_free_layer_active(&me->vdata, CD_MVERT, me->totvert); - CustomData_free_layer_active(&me->edata, CD_MEDGE, me->totedge); - CustomData_free_layer_active(&me->fdata, CD_MFACE, me->totface); - CustomData_free_layer_active(&me->vdata, CD_MDEFORMVERT, me->totvert); - CustomData_free_layers(&me->fdata, CD_MTFACE, me->totface); - CustomData_free_layers(&me->fdata, CD_MCOL, me->totface); - - me->totvert= lvl->totvert; - me->totface= lvl->totface; - me->totedge= lvl->totedge; - - CustomData_add_layer(&me->vdata, CD_MVERT, CD_CALLOC, NULL, me->totvert); - CustomData_add_layer(&me->edata, CD_MEDGE, CD_CALLOC, NULL, me->totedge); - CustomData_add_layer(&me->fdata, CD_MFACE, CD_CALLOC, NULL, me->totface); - mesh_update_customdata_pointers(me); - - /* Vertices/Edges/Faces */ - - for(i=0; itotvert; ++i) { - me->mvert[i]= me->mr->verts[i]; - } - for(i=0; itotedge; ++i) { - me->medge[i].v1= lvl->edges[i].v[0]; - me->medge[i].v2= lvl->edges[i].v[1]; - me->medge[i].flag &= ~ME_HIDE; - } - for(i=0; itotface; ++i) { - me->mface[i].v1= lvl->faces[i].v[0]; - me->mface[i].v2= lvl->faces[i].v[1]; - me->mface[i].v3= lvl->faces[i].v[2]; - me->mface[i].v4= lvl->faces[i].v[3]; - me->mface[i].flag= lvl->faces[i].flag; - me->mface[i].flag &= ~ME_HIDE; - me->mface[i].mat_nr= lvl->faces[i].mat_nr; - } - - /* Edge flags */ - if(lvl==me->mr->levels.first) { - for(i=0; itotedge; ++i) { - me->medge[i].flag= me->mr->edge_flags[i]; - me->medge[i].crease= me->mr->edge_creases[i]; - } - } else { - MultiresLevel *lvl1= me->mr->levels.first; - const int last= lvl1->totedge * pow(2, me->mr->current-1); - for(i=0; imr->current-1); - - me->medge[i].flag= me->mr->edge_flags[ndx]; - me->medge[i].crease= me->mr->edge_creases[ndx]; - } - } - - multires_customdata_to_mesh(me, em, lvl, &me->mr->vdata, em ? &em->vdata : &me->vdata, CD_MDEFORMVERT); - multires_customdata_to_mesh(me, em, lvl, &me->mr->fdata, em ? &em->fdata : &me->fdata, CD_MTFACE); - - /* Colors */ - if(me->mr->use_col) { - CustomData *src= &me->fdata; - - if(me->mr->use_col) me->mcol= CustomData_add_layer(src, CD_MCOL, CD_CALLOC, NULL, me->totface); - - for(i=0; itotface; ++i) { - if(me->mr->use_col) - multires_to_mcol(&lvl->colfaces[i], &me->mcol[i*4]); - } - - } - - mesh_update_customdata_pointers(me); - - multires_edge_level_update(ob,me); - DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); - mesh_calc_normals(me->mvert, me->totvert, me->mface, me->totface, NULL); -} - -void multires_set_level(Object *ob, Mesh *me, const int render) -{ - if(me->pv) mesh_pmv_off(ob, me); - - check_colors(me); - multires_update_levels(me, render); - - me->mr->current= me->mr->newlvl; - if(me->mr->current<1) me->mr->current= 1; - else if(me->mr->current>me->mr->level_count) me->mr->current= me->mr->level_count; - - multires_level_to_mesh(ob, me, render); -} - -/* Update the edge visibility flags to only show edges on or below the edgelvl */ -void multires_edge_level_update(Object *ob, Mesh *me) -{ - if(!G.obedit) { - MultiresLevel *cr_lvl= BLI_findlink(&me->mr->levels,me->mr->current-1); - MultiresLevel *edge_lvl= BLI_findlink(&me->mr->levels,me->mr->edgelvl-1); - const int threshold= edge_lvl->totedge * pow(2, me->mr->current - me->mr->edgelvl); - unsigned i; - - for(i=0; itotedge; ++i) { - const int ndx= me->pv ? me->pv->edge_map[i] : i; - if(ndx != -1) { /* -1= hidden edge */ - if(me->mr->edgelvl >= me->mr->current || imedge[ndx].flag |= ME_EDGEDRAW | ME_EDGERENDER; - else - me->medge[ndx].flag &= ~ME_EDGEDRAW & ~ME_EDGERENDER; - } - } - - DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); - } -} - void create_vert_face_map(ListBase **map, IndexNode **mem, const MFace *mface, const int totvert, const int totface) { int i,j; diff --git a/source/blender/makesdna/DNA_meshdata_types.h b/source/blender/makesdna/DNA_meshdata_types.h index 0dc3b76d4cf..1b8a7037724 100644 --- a/source/blender/makesdna/DNA_meshdata_types.h +++ b/source/blender/makesdna/DNA_meshdata_types.h @@ -267,7 +267,4 @@ typedef struct PartialVisibility { #define TF_PIN3 64 #define TF_PIN4 128 -/* multires->flag */ -#define MULTIRES_NO_RENDER 1 - #endif diff --git a/source/blender/render/intern/include/render_types.h b/source/blender/render/intern/include/render_types.h index 2f97b19f75c..4c00ecac0fa 100644 --- a/source/blender/render/intern/include/render_types.h +++ b/source/blender/render/intern/include/render_types.h @@ -501,7 +501,6 @@ typedef struct LampRen { #define R_LAMPHALO 8 #define R_GLOB_NOPUNOFLIP 16 #define R_NEED_TANGENT 32 -#define R_SKIP_MULTIRES 64 #define R_BAKE_TRACE 128 #define R_BAKING 256 diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c index 5dddc216b59..765a24409fa 100644 --- a/source/blender/render/intern/source/convertblender.c +++ b/source/blender/render/intern/source/convertblender.c @@ -3152,13 +3152,6 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset) if(need_orco) mask |= CD_MASK_ORCO; - if(me->mr) { - if(re->flag & R_SKIP_MULTIRES) - me->mr->flag |= MULTIRES_NO_RENDER; - else - me->mr->flag &= ~MULTIRES_NO_RENDER; - } - dm= mesh_create_derived_render(ob, mask); if(dm==NULL) return; /* in case duplicated object fails? */ @@ -5506,8 +5499,6 @@ void RE_Database_Baking(Render *re, Scene *scene, int type, Object *actob) re->flag |= R_GLOB_NOPUNOFLIP; re->flag |= R_BAKING; re->excludeob= actob; - if(type == RE_BAKE_LIGHT) - re->flag |= R_SKIP_MULTIRES; if(actob) re->flag |= R_BAKE_TRACE; diff --git a/source/blender/src/buttons_editing.c b/source/blender/src/buttons_editing.c index 7e757d4031b..5639e0116de 100644 --- a/source/blender/src/buttons_editing.c +++ b/source/blender/src/buttons_editing.c @@ -4754,8 +4754,6 @@ void do_meshbuts(unsigned short event) shadeMeshMCol(ob, me); } - if (me->mr) multires_load_cols(me); - DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); BIF_undo_push("New Vertex Color"); allqueue(REDRAWVIEW3D, 0); diff --git a/source/blender/src/editface.c b/source/blender/src/editface.c index 781210cd373..5f76e15b6c7 100644 --- a/source/blender/src/editface.c +++ b/source/blender/src/editface.c @@ -60,7 +60,6 @@ #include "BKE_displist.h" #include "BKE_global.h" #include "BKE_mesh.h" -#include "BKE_multires.h" #include "BKE_object.h" #include "BKE_texture.h" #include "BKE_utildefines.h" @@ -643,14 +642,8 @@ void default_uv(float uv[][2], float size) void make_tfaces(Mesh *me) { if(!me->mtface) { - if(me->mr) { - multires_add_layer(me, &me->mr->fdata, CD_MTFACE, - CustomData_number_of_layers(&me->fdata, CD_MTFACE)); - } - else { - me->mtface= CustomData_add_layer(&me->fdata, CD_MTFACE, CD_DEFAULT, - NULL, me->totface); - } + me->mtface= CustomData_add_layer(&me->fdata, CD_MTFACE, CD_DEFAULT, + NULL, me->totface); } } diff --git a/source/blender/src/editkey.c b/source/blender/src/editkey.c index 1f24fb07667..d58427f2338 100644 --- a/source/blender/src/editkey.c +++ b/source/blender/src/editkey.c @@ -597,27 +597,22 @@ void insert_curvekey(Curve *cu, short rel) void insert_shapekey(Object *ob) { - if(get_mesh(ob) && get_mesh(ob)->mr) { - error("Cannot create shape keys on a multires mesh."); - } - else { - Key *key; - - if(ob->type==OB_MESH) insert_meshkey(ob->data, 1); - else if ELEM(ob->type, OB_CURVE, OB_SURF) insert_curvekey(ob->data, 1); - else if(ob->type==OB_LATTICE) insert_lattkey(ob->data, 1); - - key= ob_get_key(ob); - ob->shapenr= BLI_countlist(&key->block); - - BIF_undo_push("Add Shapekey"); - allspace(REMAKEIPO, 0); - allqueue(REDRAWIPO, 0); - allqueue(REDRAWACTION, 0); - allqueue(REDRAWNLA, 0); - allqueue(REDRAWBUTSOBJECT, 0); - allqueue(REDRAWBUTSEDIT, 0); - } + Key *key; + + if(ob->type==OB_MESH) insert_meshkey(ob->data, 1); + else if ELEM(ob->type, OB_CURVE, OB_SURF) insert_curvekey(ob->data, 1); + else if(ob->type==OB_LATTICE) insert_lattkey(ob->data, 1); + + key= ob_get_key(ob); + ob->shapenr= BLI_countlist(&key->block); + + BIF_undo_push("Add Shapekey"); + allspace(REMAKEIPO, 0); + allqueue(REDRAWIPO, 0); + allqueue(REDRAWACTION, 0); + allqueue(REDRAWNLA, 0); + allqueue(REDRAWBUTSOBJECT, 0); + allqueue(REDRAWBUTSEDIT, 0); } void delete_key(Object *ob) diff --git a/source/blender/src/editmesh_mods.c b/source/blender/src/editmesh_mods.c index 25d60c3001b..448a1019d29 100644 --- a/source/blender/src/editmesh_mods.c +++ b/source/blender/src/editmesh_mods.c @@ -132,9 +132,7 @@ void EM_select_mirrored(void) void EM_automerge(int update) { int len; if ((G.scene->automerge) && - (G.obedit && G.obedit->type==OB_MESH) && - (((Mesh*)G.obedit->data)->mr==NULL) - ) { + (G.obedit && G.obedit->type==OB_MESH)) { len = removedoublesflag(1, 1, G.scene->toolsettings->doublimit); if (len) { G.totvert -= len; /* saves doing a countall */ diff --git a/source/blender/src/editobject.c b/source/blender/src/editobject.c index 2f9addb106e..b2b66deeb8a 100644 --- a/source/blender/src/editobject.c +++ b/source/blender/src/editobject.c @@ -1799,9 +1799,6 @@ void exit_editmode(int flag) /* freedata==0 at render, 1= freedata, 2= do undo b /* for example; displist make is different in editmode */ if(freedata) G.obedit= NULL; - if(ob->type==OB_MESH && get_mesh(ob)->mr) - multires_edge_level_update(ob, get_mesh(ob)); - /* also flush ob recalc, doesn't take much overhead, but used for particles */ DAG_object_flush_update(G.scene, ob, OB_RECALC_OB|OB_RECALC_DATA); diff --git a/source/blender/src/meshtools.c b/source/blender/src/meshtools.c index 7e292e10ff8..a716ff7de7c 100644 --- a/source/blender/src/meshtools.c +++ b/source/blender/src/meshtools.c @@ -126,7 +126,7 @@ int join_mesh(void) MFace *mface = NULL, *mfacemain; float imat[4][4], cmat[4][4]; int a, b, totcol, totedge=0, totvert=0, totface=0, ok=0, vertofs, map[MAXMAT]; - int i, j, index, haskey=0, hasmulti=0, edgeofs, faceofs; + int i, j, index, haskey=0, edgeofs, faceofs; bDeformGroup *dg, *odg; MDeformVert *dvert; CustomData vdata, edata, fdata; @@ -177,10 +177,6 @@ int join_mesh(void) haskey= 1; break; } - if(me->mr) { - hasmulti= 1; - break; - } } } base= base->next; @@ -190,10 +186,6 @@ int join_mesh(void) error("Can't join meshes with vertex keys"); return 0; } - if(hasmulti) { - error("Can't join meshes with Multires"); - return 0; - } /* that way the active object is always selected */ if(ok==0) return 0; -- cgit v1.2.3