diff options
author | Hans Lambermont <hans@lambermont.dyndns.org> | 2002-10-12 15:37:38 +0400 |
---|---|---|
committer | Hans Lambermont <hans@lambermont.dyndns.org> | 2002-10-12 15:37:38 +0400 |
commit | 12315f4d0e0ae993805f141f64cb8c73c5297311 (patch) | |
tree | 59b45827cd8293cfb727758989c7a74b40183974 /source/blender/blenkernel/intern/mesh.c |
Initial revisionv2.25
Diffstat (limited to 'source/blender/blenkernel/intern/mesh.c')
-rw-r--r-- | source/blender/blenkernel/intern/mesh.c | 1120 |
1 files changed, 1120 insertions, 0 deletions
diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c new file mode 100644 index 00000000000..720d02ee7bb --- /dev/null +++ b/source/blender/blenkernel/intern/mesh.c @@ -0,0 +1,1120 @@ + +/* mesh.c MIXED MODEL + * + * jan/maart 95 + * + * + * $Id$ + * + * ***** BEGIN GPL/BL DUAL 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. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * 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) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** + */ + +#ifdef WIN32 +#include "BLI_winstuff.h" +#endif + +#include <stdlib.h> +#include <string.h> +#include <stdio.h> +#include <math.h> + +#include "MEM_guardedalloc.h" + +#include "DNA_ID.h" +#include "DNA_curve_types.h" +#include "DNA_material_types.h" +#include "DNA_object_types.h" +#include "DNA_image_types.h" +#include "DNA_key_types.h" +#include "DNA_mesh_types.h" + +#include "BKE_main.h" +#include "BKE_global.h" +#include "BKE_mesh.h" +#include "BKE_subsurf.h" +#include "BKE_displist.h" +#include "BKE_library.h" +#include "BKE_material.h" +#include "BKE_key.h" +/* these 2 are only used by conversion functions */ +#include "BKE_curve.h" +/* -- */ +#include "BKE_object.h" +#include "BKE_utildefines.h" +#include "BKE_bad_level_calls.h" + +#include "BLI_blenlib.h" +#include "BLI_editVert.h" +#include "BLI_arithb.h" + + + +int update_realtime_texture(TFace *tface, double time) +{ + Image *ima; + int inc = 0; + float diff; + int newframe; + + ima = tface->tpage; + + if (!ima) + return 0; + + if (ima->lastupdate<0) + ima->lastupdate = 0; + + if (ima->lastupdate>time) + ima->lastupdate=(float)time; + + if(ima->tpageflag & IMA_TWINANIM) { + if(ima->twend >= ima->xrep*ima->yrep) ima->twend= ima->xrep*ima->yrep-1; + + /* check: zit de bindcode niet het array? Vrijgeven. (nog doen) */ + + diff = (float)(time-ima->lastupdate); + + inc = (int)(diff*(float)ima->animspeed); + + ima->lastupdate+=((float)inc/(float)ima->animspeed); + + newframe = ima->lastframe+inc; + + if (newframe > (int)ima->twend) + newframe = (int)ima->twsta-1 + (newframe-ima->twend)%(ima->twend-ima->twsta); + + ima->lastframe = newframe; + } + return inc; +} + +float get_mvert_weight (Object *ob, int vert, int defgroup) +{ + int i; + Mesh *me; + float result; + + me=ob->data; + + if (!me->dvert) + return 0.0F; + + result=0.0F; + + for (i=0; i<me->dvert[vert].totweight; i++){ + if (me->dvert[vert].dw[i].def_nr==defgroup) + result+=me->dvert[vert].dw[i].weight; + } + + return result; +} + +void unlink_mesh(Mesh *me) +{ + int a; + + if(me==0) return; + + for(a=0; a<me->totcol; a++) { + if(me->mat[a]) me->mat[a]->id.us--; + me->mat[a]= 0; + } + if(me->key) me->key->id.us--; + me->key= 0; + + if(me->texcomesh) me->texcomesh= 0; +} + + +/* niet mesh zelf vrijgeven */ +void free_mesh(Mesh *me) +{ + + unlink_mesh(me); + + if(me->mat) MEM_freeN(me->mat); + if(me->orco) MEM_freeN(me->orco); + if(me->mface) MEM_freeN(me->mface); + if(me->tface) MEM_freeN(me->tface); + if(me->mvert) MEM_freeN(me->mvert); + if(me->dvert) free_dverts(me->dvert, me->totvert); + if(me->mcol) MEM_freeN(me->mcol); + if(me->msticky) MEM_freeN(me->msticky); + if(me->bb) MEM_freeN(me->bb); + if(me->disp.first) freedisplist(&me->disp); +} + +void copy_dverts(MDeformVert *dst, MDeformVert *src, int copycount) +{ + /* Assumes dst is already set up */ + int i; + + if (!src || !dst) + return; + + memcpy (dst, src, copycount * sizeof(MDeformVert)); + + for (i=0; i<copycount; i++){ + if (src[i].dw){ + dst[i].dw = MEM_callocN (sizeof(MDeformWeight)*src[i].totweight, "copy_deformWeight"); + memcpy (dst[i].dw, src[i].dw, sizeof (MDeformWeight)*src[i].totweight); + } + } + +} +void free_dverts(MDeformVert *dvert, int totvert) +{ + /* Instead of freeing the verts directly, + call this function to delete any special + vert data */ + int i; + + if (!dvert) + return; + + /* Free any special data from the verts */ + for (i=0; i<totvert; i++){ + if (dvert[i].dw) MEM_freeN (dvert[i].dw); + } + MEM_freeN (dvert); +} + +Mesh *add_mesh() +{ + Mesh *me; + + me= alloc_libblock(&G.main->mesh, ID_ME, "Mesh"); + + me->size[0]= me->size[1]= me->size[2]= 1.0; + me->smoothresh= 30; + me->texflag= AUTOSPACE; + me->flag= ME_TWOSIDED; + me->subdiv= 1; + me->subdivr = 1; + me->bb= unit_boundbox(); + + return me; +} + +Mesh *copy_mesh(Mesh *me) +{ + Mesh *men; + int a; + + men= copy_libblock(me); + + men->mat= MEM_dupallocN(me->mat); + for(a=0; a<men->totcol; a++) { + id_us_plus((ID *)men->mat[a]); + } + id_us_plus((ID *)men->texcomesh); + men->mface= MEM_dupallocN(me->mface); + + men->tface= MEM_dupallocN(me->tface); + + men->dface= 0; + men->mvert= MEM_dupallocN(me->mvert); + memcpy (men->mvert, me->mvert, sizeof (MVert)*me->totvert); + if (me->dvert){ + men->dvert = MEM_mallocN (sizeof (MDeformVert)*me->totvert, "MDeformVert"); + copy_dverts(men->dvert, me->dvert, me->totvert); + } + + men->mcol= MEM_dupallocN(me->mcol); + men->msticky= MEM_dupallocN(me->msticky); + men->texcomesh= 0; + men->orco= 0; + men->bb= MEM_dupallocN(men->bb); + + copy_displist(&men->disp, &me->disp); + + men->key= copy_key(me->key); + if(men->key) men->key->from= (ID *)men; + + return men; +} + +void make_local_tface(Mesh *me) +{ + TFace *tface; + Image *ima; + int a; + + if(me->tface==0) return; + + a= me->totface; + tface= me->tface; + while(a--) { + + /* speciaal geval: ima altijd meteen lokaal */ + if(tface->tpage) { + ima= tface->tpage; + if(ima->id.lib) { + ima->id.lib= 0; + ima->id.flag= LIB_LOCAL; + new_id(0, (ID *)ima, 0); + } + } + tface++; + } + +} + +void make_local_mesh(Mesh *me) +{ + Object *ob; + Mesh *men; + int local=0, lib=0; + + /* - zijn er alleen lib users: niet doen + * - zijn er alleen locale users: flag zetten + * - mixed: copy + */ + + if(me->id.lib==0) return; + if(me->id.us==1) { + me->id.lib= 0; + me->id.flag= LIB_LOCAL; + new_id(0, (ID *)me, 0); + + if(me->tface) make_local_tface(me); + + return; + } + + ob= G.main->object.first; + while(ob) { + if( me==get_mesh(ob) ) { + if(ob->id.lib) lib= 1; + else local= 1; + } + ob= ob->id.next; + } + + if(local && lib==0) { + me->id.lib= 0; + me->id.flag= LIB_LOCAL; + new_id(0, (ID *)me, 0); + + if(me->tface) make_local_tface(me); + + } + else if(local && lib) { + men= copy_mesh(me); + men->id.us= 0; + + ob= G.main->object.first; + while(ob) { + if( me==get_mesh(ob) ) { + if(ob->id.lib==0) { + set_mesh(ob, men); + } + } + ob= ob->id.next; + } + } +} + +void boundbox_mesh(Mesh *me, float *loc, float *size) +{ + MVert *mvert; + BoundBox *bb; + float min[3], max[3]; + float mloc[3], msize[3]; + int a; + + if(me->bb==0) me->bb= MEM_callocN(sizeof(BoundBox), "boundbox"); + bb= me->bb; + + INIT_MINMAX(min, max); + + if (!loc) loc= mloc; + if (!size) size= msize; + + mvert= me->mvert; + for(a=0; a<me->totvert; a++, mvert++) { + DO_MINMAX(mvert->co, min, max); + } + + if(me->totvert) { + loc[0]= (min[0]+max[0])/2.0f; + loc[1]= (min[1]+max[1])/2.0f; + loc[2]= (min[2]+max[2])/2.0f; + + size[0]= (max[0]-min[0])/2.0f; + size[1]= (max[1]-min[1])/2.0f; + size[2]= (max[2]-min[2])/2.0f; + } + else { + loc[0]= loc[1]= loc[2]= 0.0; + size[0]= size[1]= size[2]= 0.0; + } + + bb->vec[0][0]=bb->vec[1][0]=bb->vec[2][0]=bb->vec[3][0]= loc[0]-size[0]; + bb->vec[4][0]=bb->vec[5][0]=bb->vec[6][0]=bb->vec[7][0]= loc[0]+size[0]; + + bb->vec[0][1]=bb->vec[1][1]=bb->vec[4][1]=bb->vec[5][1]= loc[1]-size[1]; + bb->vec[2][1]=bb->vec[3][1]=bb->vec[6][1]=bb->vec[7][1]= loc[1]+size[1]; + + bb->vec[0][2]=bb->vec[3][2]=bb->vec[4][2]=bb->vec[7][2]= loc[2]-size[2]; + bb->vec[1][2]=bb->vec[2][2]=bb->vec[5][2]=bb->vec[6][2]= loc[2]+size[2]; +} + +void tex_space_mesh(Mesh *me) +{ + KeyBlock *kb; + float *fp, loc[3], size[3], min[3], max[3]; + int a; + + boundbox_mesh(me, loc, size); + + if(me->texflag & AUTOSPACE) { + if(me->key) { + kb= me->key->refkey; + if (kb) { + + INIT_MINMAX(min, max); + + fp= kb->data; + for(a=0; a<kb->totelem; a++, fp+=3) { + DO_MINMAX(fp, min, max); + } + if(kb->totelem) { + loc[0]= (min[0]+max[0])/2.0f; loc[1]= (min[1]+max[1])/2.0f; loc[2]= (min[2]+max[2])/2.0f; + size[0]= (max[0]-min[0])/2.0f; size[1]= (max[1]-min[1])/2.0f; size[2]= (max[2]-min[2])/2.0f; + } + else { + loc[0]= loc[1]= loc[2]= 0.0; + size[0]= size[1]= size[2]= 0.0; + } + + } + } + + VECCOPY(me->loc, loc); + VECCOPY(me->size, size); + me->rot[0]= me->rot[1]= me->rot[2]= 0.0; + + if(me->size[0]==0.0) me->size[0]= 1.0; + else if(me->size[0]>0.0 && me->size[0]<0.00001) me->size[0]= 0.00001; + else if(me->size[0]<0.0 && me->size[0]> -0.00001) me->size[0]= -0.00001; + + if(me->size[1]==0.0) me->size[1]= 1.0; + else if(me->size[1]>0.0 && me->size[1]<0.00001) me->size[1]= 0.00001; + else if(me->size[1]<0.0 && me->size[1]> -0.00001) me->size[1]= -0.00001; + + if(me->size[2]==0.0) me->size[2]= 1.0; + else if(me->size[2]>0.0 && me->size[2]<0.00001) me->size[2]= 0.00001; + else if(me->size[2]<0.0 && me->size[2]> -0.00001) me->size[2]= -0.00001; + } + +} + +void make_orco_displist_mesh(Object *ob, int subdivlvl) +{ + Mesh *me; + DispList *dl; + DispListMesh *dlm; + int i; + + me= ob->data; + + /* if there's a key, set the first one */ + if(me->key && me->texcomesh==0) { + cp_key(0, me->totvert, me->totvert, (char*) me->mvert->co, me->key, me->key->refkey, 0); + } + + /* Rebuild the displist */ + dl= subsurf_mesh_to_displist(me, NULL, (short)subdivlvl); + + /* Restore correct key */ + do_ob_key(ob); + + /* XXX Assume dl is a DL_MESH (it is), + * should be explicit -zr + */ + dlm= dl->mesh; + + me->orco= MEM_mallocN(dlm->totvert*3*sizeof(float), "mesh displist orco"); + + for (i=0; i<dlm->totvert; i++) { + float *fp= &me->orco[i*3]; + VECCOPY(fp, dlm->mvert[i].co); + } + + for(i=0; i<dlm->totvert; i++) { + float *fp= &me->orco[i*3]; + fp[0]= (fp[0]-me->loc[0])/me->size[0]; + fp[1]= (fp[1]-me->loc[1])/me->size[1]; + fp[2]= (fp[2]-me->loc[2])/me->size[2]; + } + + free_disp_elem(dl); +} + +void make_orco_mesh(Mesh *me) +{ + MVert *mvert; + KeyBlock *kb; + float *orco, *fp; + int a, totvert; + + totvert= me->totvert; + if(totvert==0) return; + orco= me->orco= MEM_mallocN(sizeof(float)*3*totvert, "orco mesh"); + + if(me->key && me->texcomesh==0) { + kb= me->key->refkey; + if (kb) { /***** BUG *****/ + fp= kb->data; + + for(a=0; a<totvert; a++, orco+=3) { + orco[0]= (fp[0]-me->loc[0])/me->size[0]; + orco[1]= (fp[1]-me->loc[1])/me->size[1]; + orco[2]= (fp[2]-me->loc[2])/me->size[2]; + + /* mvert alleen ophogen als totvert <= kb->totelem */ + if(a<kb->totelem) fp+=3; + } + } + } + else { + if(me->texcomesh) { + me= me->texcomesh; + } + + mvert= me->mvert; + for(a=0; a<totvert; a++, orco+=3) { + orco[0]= (mvert->co[0]-me->loc[0])/me->size[0]; + orco[1]= (mvert->co[1]-me->loc[1])/me->size[1]; + orco[2]= (mvert->co[2]-me->loc[2])/me->size[2]; + + /* mvert alleen ophogen als totvert <= me->totvert */ + if(a<me->totvert) mvert++; + } + } +} + +/** rotates the vertices of a face in case v[2] or v[3] (vertex index) + * is = 0. + * Helaas, the MFace structure has no pointer to its + * texture face, therefore, texture can not be fixed inside + * this function. + * + * see also blender/src/editmesh.c, fix_faceindices() + + * THIS FUNCTION WILL BE DINOSOURCE. For the moment, another hack + is added to fix texture coordinates / vertex colors: + + void test_index_face(MFace *mface, TFace *tface, int nr) + */ + +void test_index_mface(MFace *mface, int nr) +{ + int a; + + + /* first test if the face is legal */ + + if(mface->v3 && mface->v3==mface->v4) { + mface->v4= 0; + nr--; + } + if(mface->v2 && mface->v2==mface->v3) { + mface->v3= mface->v4; + mface->v4= 0; + nr--; + } + if(mface->v1==mface->v2) { + mface->v2= mface->v3; + mface->v3= mface->v4; + mface->v4= 0; + nr--; + } + + /* voorkom dat een nul op de verkeerde plek staat */ + if(nr==2) { + if(mface->v2==0) SWAP(int, mface->v1, mface->v2); + } + else if(nr==3) { + if(mface->v3==0) { + SWAP(int, mface->v1, mface->v2); + SWAP(int, mface->v2, mface->v3); + + a= mface->edcode; + mface->edcode= 0; + if(a & ME_V1V2) mface->edcode |= ME_V3V1; + if(a & ME_V2V3) mface->edcode |= ME_V1V2; + if(a & ME_V3V1) mface->edcode |= ME_V2V3; + + a= mface->puno; + mface->puno &= ~15; + if(a & ME_FLIPV1) mface->puno |= ME_FLIPV2; + if(a & ME_FLIPV2) mface->puno |= ME_FLIPV3; + if(a & ME_FLIPV3) mface->puno |= ME_FLIPV1; + } + } + else if(nr==4) { + if(mface->v3==0 || mface->v4==0) { + SWAP(int, mface->v1, mface->v3); + SWAP(int, mface->v2, mface->v4); + a= mface->edcode; + mface->edcode= 0; + if(a & ME_V1V2) mface->edcode |= ME_V3V4; + if(a & ME_V2V3) mface->edcode |= ME_V2V3; + if(a & ME_V3V4) mface->edcode |= ME_V1V2; + if(a & ME_V4V1) mface->edcode |= ME_V4V1; + + a= mface->puno; + mface->puno &= ~15; + if(a & ME_FLIPV1) mface->puno |= ME_FLIPV3; + if(a & ME_FLIPV2) mface->puno |= ME_FLIPV4; + if(a & ME_FLIPV3) mface->puno |= ME_FLIPV1; + if(a & ME_FLIPV4) mface->puno |= ME_FLIPV2; + } + } +} + +/** This function should die as soon as there is another mesh + structure. Functionality is the same as + + void test_index_mface() + + but it fixes texture coordinates as well. +*/ + +#define UVCOPY(t, s) memcpy(t, s, 2 * sizeof(float)); +void test_index_face(MFace *mface, TFace *tface, int nr) +{ + int a; + float tmpuv[2]; + unsigned int tmpcol; + + + /* first test if the face is legal */ + + if(mface->v3 && mface->v3==mface->v4) { + mface->v4= 0; + nr--; + } + if(mface->v2 && mface->v2==mface->v3) { + mface->v3= mface->v4; + mface->v4= 0; + nr--; + } + if(mface->v1==mface->v2) { + mface->v2= mface->v3; + mface->v3= mface->v4; + mface->v4= 0; + nr--; + } + + /* voorkom dat een nul op de verkeerde plek staat */ + if(nr==2) { + if(mface->v2==0) SWAP(int, mface->v1, mface->v2); + } + else if(nr==3) { + if(mface->v3==0) { + SWAP(int, mface->v1, mface->v2); + SWAP(int, mface->v2, mface->v3); + /* rotate face UV coordinates, too */ + UVCOPY(tmpuv, tface->uv[0]); + UVCOPY(tface->uv[0], tface->uv[1]); + UVCOPY(tface->uv[1], tface->uv[2]); + UVCOPY(tface->uv[2], tmpuv); + /* same with vertex colours */ + tmpcol = tface->col[0]; + tface->col[0] = tface->col[1]; + tface->col[1] = tface->col[2]; + tface->col[2] = tmpcol; + + + a= mface->edcode; + mface->edcode= 0; + if(a & ME_V1V2) mface->edcode |= ME_V3V1; + if(a & ME_V2V3) mface->edcode |= ME_V1V2; + if(a & ME_V3V1) mface->edcode |= ME_V2V3; + + a= mface->puno; + mface->puno &= ~15; + if(a & ME_FLIPV1) mface->puno |= ME_FLIPV2; + if(a & ME_FLIPV2) mface->puno |= ME_FLIPV3; + if(a & ME_FLIPV3) mface->puno |= ME_FLIPV1; + } + } + else if(nr==4) { + if(mface->v3==0 || mface->v4==0) { + SWAP(int, mface->v1, mface->v3); + SWAP(int, mface->v2, mface->v4); + /* swap UV coordinates */ + UVCOPY(tmpuv, tface->uv[0]); + UVCOPY(tface->uv[0], tface->uv[2]); + UVCOPY(tface->uv[2], tmpuv); + UVCOPY(tmpuv, tface->uv[1]); + UVCOPY(tface->uv[1], tface->uv[3]); + UVCOPY(tface->uv[3], tmpuv); + /* swap vertex colours */ + tmpcol = tface->col[0]; + tface->col[0] = tface->col[2]; + tface->col[2] = tmpcol; + tmpcol = tface->col[1]; + tface->col[1] = tface->col[3]; + tface->col[3] = tmpcol; + + a= mface->edcode; + mface->edcode= 0; + if(a & ME_V1V2) mface->edcode |= ME_V3V4; + if(a & ME_V2V3) mface->edcode |= ME_V2V3; + if(a & ME_V3V4) mface->edcode |= ME_V1V2; + if(a & ME_V4V1) mface->edcode |= ME_V4V1; + + a= mface->puno; + mface->puno &= ~15; + if(a & ME_FLIPV1) mface->puno |= ME_FLIPV3; + if(a & ME_FLIPV2) mface->puno |= ME_FLIPV4; + if(a & ME_FLIPV3) mface->puno |= ME_FLIPV1; + if(a & ME_FLIPV4) mface->puno |= ME_FLIPV2; + } + } +} + +void flipnorm_mesh(Mesh *me) +{ + MFace *mface; + MVert *mvert; + DispList *dl; + float *fp; + int a, temp; + + mvert= me->mvert; + a= me->totvert; + while(a--) { + mvert->no[0]= -mvert->no[0]; + mvert->no[1]= -mvert->no[1]; + mvert->no[2]= -mvert->no[2]; + mvert++; + } + + mface= me->mface; + a= me->totface; + while(a--) { + if(mface->v3) { + if(mface->v4) { + SWAP(int, mface->v4, mface->v1); + SWAP(int, mface->v3, mface->v2); + test_index_mface(mface, 4); + temp= mface->puno; + mface->puno &= ~15; + if(temp & ME_FLIPV1) mface->puno |= ME_FLIPV4; + if(temp & ME_FLIPV2) mface->puno |= ME_FLIPV3; + if(temp & ME_FLIPV3) mface->puno |= ME_FLIPV2; + if(temp & ME_FLIPV4) mface->puno |= ME_FLIPV1; + } + else { + SWAP(int, mface->v3, mface->v1); + test_index_mface(mface, 3); + temp= mface->puno; + mface->puno &= ~15; + if(temp & ME_FLIPV1) mface->puno |= ME_FLIPV3; + if(temp & ME_FLIPV2) mface->puno |= ME_FLIPV2; + if(temp & ME_FLIPV3) mface->puno |= ME_FLIPV1; + } + } + mface++; + } + + if(me->disp.first) { + dl= me->disp.first; + fp= dl->nors; + if(fp) { + a= dl->nr; + while(a--) { + fp[0]= -fp[0]; + fp[1]= -fp[1]; + fp[2]= -fp[2]; + fp+= 3; + } + } + } +} + +Mesh *get_mesh(Object *ob) +{ + + if(ob==0) return 0; + if(ob->type==OB_MESH) return ob->data; + else return 0; +} + +void set_mesh(Object *ob, Mesh *me) +{ + Mesh *old=0; + + if(ob==0) return; + + if(ob->type==OB_MESH) { + old= ob->data; + old->id.us--; + ob->data= me; + id_us_plus((ID *)me); + } + + test_object_materials((ID *)me); +} + +void mball_to_mesh(ListBase *lb, Mesh *me) +{ + DispList *dl; + MVert *mvert; + MFace *mface; + float *nors, *verts; + int a, *index; + + dl= lb->first; + if(dl==0) return; + + if(dl->type==DL_INDEX4) { + me->flag= ME_NOPUNOFLIP; + me->totvert= dl->nr; + me->totface= dl->parts; + + me->mvert=mvert= MEM_callocN(dl->nr*sizeof(MVert), "mverts"); + a= dl->nr; + nors= dl->nors; + verts= dl->verts; + while(a--) { + VECCOPY(mvert->co, verts); + mvert->no[0]= (short int)(nors[0]*32767.0); + mvert->no[1]= (short int)(nors[1]*32767.0); + mvert->no[2]= (short int)(nors[2]*32767.0); + mvert++; + nors+= 3; + verts+= 3; + } + + me->mface=mface= MEM_callocN(dl->parts*sizeof(MFace), "mface"); + a= dl->parts; + index= dl->index; + while(a--) { + mface->v1= index[0]; + mface->v2= index[1]; + mface->v3= index[2]; + mface->v4= index[3]; + + mface->puno= 0; + mface->edcode= ME_V1V2+ME_V2V3; + mface->flag = ME_SMOOTH; + + mface++; + index+= 4; + } + } +} + +void nurbs_to_mesh(Object *ob) +{ + Object *ob1; + DispList *dl; + Mesh *me; + Curve *cu; + MVert *mvert; + MFace *mface; + float *data; + int a, b, ofs, vertcount, startvert, totvert=0, totvlak=0; + int p1, p2, p3, p4, *index; + + cu= ob->data; + + if(ob->type==OB_CURVE) { + /* regel: dl->type INDEX3 altijd vooraan in lijst */ + dl= cu->disp.first; + if(dl->type!=DL_INDEX3) { + curve_to_filledpoly(ob->data, &cu->disp); + } + } + + /* tellen */ + dl= cu->disp.first; + while(dl) { + if(dl->type==DL_SEGM) { + totvert+= dl->parts*dl->nr; + totvlak+= dl->parts*(dl->nr-1); + } + else if(dl->type==DL_POLY) { + /* cyclic polys are filled. except when 3D */ + if(cu->flag & CU_3D) { + totvert+= dl->parts*dl->nr; + totvlak+= dl->parts*dl->nr; + } + } + else if(dl->type==DL_SURF) { + totvert+= dl->parts*dl->nr; + totvlak+= (dl->parts-1+((dl->flag & 2)==2))*(dl->nr-1+(dl->flag & 1)); + } + else if(dl->type==DL_INDEX3) { + totvert+= dl->nr; + totvlak+= dl->parts; + } + dl= dl->next; + } + if(totvert==0) { + error("can't convert"); + return; + } + + /* mesh maken */ + me= add_mesh(); + me->totvert= totvert; + me->totface= totvlak; + + me->totcol= cu->totcol; + me->mat= cu->mat; + cu->mat= 0; + cu->totcol= 0; + + mvert=me->mvert= MEM_callocN(me->totvert*sizeof(MVert), "cumesh1"); + mface=me->mface= MEM_callocN(me->totface*sizeof(MFace), "cumesh2"); + + /* verts en vlakken */ + vertcount= 0; + + dl= cu->disp.first; + while(dl) { + if(dl->type==DL_SEGM) { + startvert= vertcount; + a= dl->parts*dl->nr; + data= dl->verts; + while(a--) { + VECCOPY(mvert->co, data); + data+=3; + vertcount++; + mvert++; + } + + for(a=0; a<dl->parts; a++) { + ofs= a*dl->nr; + for(b=1; b<dl->nr; b++) { + mface->v1= startvert+ofs+b-1; + mface->v2= startvert+ofs+b; + mface->edcode= ME_V1V2; + test_index_mface(mface, 2); + mface++; + } + } + + } + else if(dl->type==DL_POLY) { + /* cyclic polys are filled */ + /* startvert= vertcount; + a= dl->parts*dl->nr; + data= dl->verts; + while(a--) { + VECCOPY(mvert->co, data); + data+=3; + vertcount++; + mvert++; + } + + for(a=0; a<dl->parts; a++) { + ofs= a*dl->nr; + for(b=0; b<dl->nr; b++) { + mface->v1= startvert+ofs+b; + if(b==dl->nr-1) mface->v2= startvert+ofs; + else mface->v2= startvert+ofs+b+1; + mface->edcode= ME_V1V2; + test_index_mface(mface, 2); + mface++; + } + } + */ + } + else if(dl->type==DL_INDEX3) { + startvert= vertcount; + a= dl->nr; + data= dl->verts; + while(a--) { + VECCOPY(mvert->co, data); + data+=3; + vertcount++; + mvert++; + } + + a= dl->parts; + index= dl->index; + while(a--) { + mface->v1= startvert+index[0]; + mface->v2= startvert+index[1]; + mface->v3= startvert+index[2]; + mface->v4= 0; + + mface->puno= 7; + mface->edcode= ME_V1V2+ME_V2V3; + test_index_mface(mface, 3); + + mface++; + index+= 3; + } + + + } + else if(dl->type==DL_SURF) { + startvert= vertcount; + a= dl->parts*dl->nr; + data= dl->verts; + while(a--) { + VECCOPY(mvert->co, data); + data+=3; + vertcount++; + mvert++; + } + + for(a=0; a<dl->parts; a++) { + + if( (dl->flag & 2)==0 && a==dl->parts-1) break; + + if(dl->flag & 1) { /* p2 -> p1 -> */ + p1= startvert+ dl->nr*a; /* p4 -> p3 -> */ + p2= p1+ dl->nr-1; /* -----> volgende rij */ + p3= p1+ dl->nr; + p4= p2+ dl->nr; + b= 0; + } + else { + p2= startvert+ dl->nr*a; + p1= p2+1; + p4= p2+ dl->nr; + p3= p1+ dl->nr; + b= 1; + } + if( (dl->flag & 2) && a==dl->parts-1) { + p3-= dl->parts*dl->nr; + p4-= dl->parts*dl->nr; + } + + for(; b<dl->nr; b++) { + mface->v1= p1; + mface->v2= p3; + mface->v3= p4; + mface->v4= p2; + mface->mat_nr= (unsigned char)dl->col; + mface->edcode= ME_V1V2+ME_V2V3; + test_index_mface(mface, 4); + mface++; + + p4= p3; + p3++; + p2= p1; + p1++; + } + } + + } + + dl= dl->next; + } + + if(ob->data) { + free_libblock(&G.main->curve, ob->data); + } + ob->data= me; + ob->type= OB_MESH; + + tex_space_mesh(me); + + /* andere users */ + ob1= G.main->object.first; + while(ob1) { + if(ob1->data==cu) { + ob1->type= OB_MESH; + + ob1->data= ob->data; + id_us_plus((ID *)ob->data); + } + ob1= ob1->id.next; + } + +} + +void edge_drawflags_mesh(Mesh *me) +{ + MFace *mface; + int a; + + mface= me->mface; + for(a=0; a<me->totface; a++, mface++) { + mface->edcode= ME_V1V2|ME_V2V3|ME_V3V4|ME_V4V1; + } +} + +void tface_to_mcol(Mesh *me) +{ + TFace *tface; + unsigned int *mcol; + int a; + + me->mcol= MEM_mallocN(4*sizeof(int)*me->totface, "nepmcol"); + mcol= (unsigned int *)me->mcol; + + a= me->totface; + tface= me->tface; + while(a--) { + memcpy(mcol, tface->col, 16); + mcol+= 4; + tface++; + } +} + +void mcol_to_tface(Mesh *me, int freedata) +{ + TFace *tface; + unsigned int *mcol; + int a; + + a= me->totface; + tface= me->tface; + mcol= (unsigned int *)me->mcol; + while(a--) { + memcpy(tface->col, mcol, 16); + mcol+= 4; + tface++; + } + + if(freedata) { + MEM_freeN(me->mcol); + me->mcol= 0; + } +} + +int mesh_uses_displist(Mesh *me) { + return (me->flag&ME_SUBSURF && (me->subdiv>0)); +} + +int rendermesh_uses_displist(Mesh *me) { + return (me->flag&ME_SUBSURF); +} |