Blender V2.61 - r43446

MOD_decimate.c

Go to the documentation of this file.
00001 /*
00002  * ***** BEGIN GPL LICENSE BLOCK *****
00003  *
00004  * This program is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU General Public License
00006  * as published by the Free Software Foundation; either version 2
00007  * of the License, or (at your option) any later version.
00008  *
00009  * This program is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software  Foundation,
00016  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00017  *
00018  * The Original Code is Copyright (C) 2005 by the Blender Foundation.
00019  * All rights reserved.
00020  *
00021  * Contributor(s): Daniel Dunbar
00022  *                 Ton Roosendaal,
00023  *                 Ben Batt,
00024  *                 Brecht Van Lommel,
00025  *                 Campbell Barton
00026  *
00027  * ***** END GPL LICENSE BLOCK *****
00028  *
00029  */
00030 
00036 #include "DNA_meshdata_types.h"
00037 
00038 #include "BLI_math.h"
00039 #include "BLI_utildefines.h"
00040 
00041 #include "MEM_guardedalloc.h"
00042 
00043 #include "BKE_mesh.h"
00044 #include "BKE_modifier.h"
00045 #include "BKE_particle.h"
00046 #include "BKE_cdderivedmesh.h"
00047 
00048 
00049 #ifdef WITH_MOD_DECIMATE
00050 #include "LOD_decimation.h"
00051 #endif
00052 
00053 #include "MOD_util.h"
00054 
00055 static void initData(ModifierData *md)
00056 {
00057     DecimateModifierData *dmd = (DecimateModifierData*) md;
00058 
00059     dmd->percent = 1.0;
00060 }
00061 
00062 static void copyData(ModifierData *md, ModifierData *target)
00063 {
00064     DecimateModifierData *dmd = (DecimateModifierData*) md;
00065     DecimateModifierData *tdmd = (DecimateModifierData*) target;
00066 
00067     tdmd->percent = dmd->percent;
00068 }
00069 
00070 #ifdef WITH_MOD_DECIMATE
00071 static DerivedMesh *applyModifier(ModifierData *md, Object *UNUSED(ob),
00072                         DerivedMesh *derivedData,
00073                         int UNUSED(useRenderParams),
00074                         int UNUSED(isFinalCalc))
00075 {
00076     DecimateModifierData *dmd = (DecimateModifierData*) md;
00077     DerivedMesh *dm = derivedData, *result = NULL;
00078     MVert *mvert;
00079     MFace *mface;
00080     LOD_Decimation_Info lod;
00081     int totvert, totface;
00082     int a, numTris;
00083 
00084     mvert = dm->getVertArray(dm);
00085     mface = dm->getFaceArray(dm);
00086     totvert = dm->getNumVerts(dm);
00087     totface = dm->getNumFaces(dm);
00088 
00089     numTris = 0;
00090     for (a=0; a<totface; a++) {
00091         MFace *mf = &mface[a];
00092         numTris++;
00093         if (mf->v4) numTris++;
00094     }
00095 
00096     if(numTris<3) {
00097         modifier_setError(md,
00098             "Modifier requires more than 3 input faces (triangles).");
00099         goto exit;
00100     }
00101 
00102     lod.vertex_buffer= MEM_mallocN(3*sizeof(float)*totvert, "vertices");
00103     lod.vertex_normal_buffer= MEM_mallocN(3*sizeof(float)*totvert, "normals");
00104     lod.triangle_index_buffer= MEM_mallocN(3*sizeof(int)*numTris, "trias");
00105     lod.vertex_num= totvert;
00106     lod.face_num= numTris;
00107 
00108     for(a=0; a<totvert; a++) {
00109         MVert *mv = &mvert[a];
00110         float *vbCo = &lod.vertex_buffer[a*3];
00111         float *vbNo = &lod.vertex_normal_buffer[a*3];
00112 
00113         copy_v3_v3(vbCo, mv->co);
00114         normal_short_to_float_v3(vbNo, mv->no);
00115     }
00116 
00117     numTris = 0;
00118     for(a=0; a<totface; a++) {
00119         MFace *mf = &mface[a];
00120         int *tri = &lod.triangle_index_buffer[3*numTris++];
00121         tri[0]= mf->v1;
00122         tri[1]= mf->v2;
00123         tri[2]= mf->v3;
00124 
00125         if(mf->v4) {
00126             tri = &lod.triangle_index_buffer[3*numTris++];
00127             tri[0]= mf->v1;
00128             tri[1]= mf->v3;
00129             tri[2]= mf->v4;
00130         }
00131     }
00132 
00133     dmd->faceCount = 0;
00134     if(LOD_LoadMesh(&lod) ) {
00135         if( LOD_PreprocessMesh(&lod) ) {
00136             /* we assume the decim_faces tells how much to reduce */
00137 
00138             while(lod.face_num > numTris*dmd->percent) {
00139                 if( LOD_CollapseEdge(&lod)==0) break;
00140             }
00141 
00142             if(lod.vertex_num>2) {
00143                 result = CDDM_new(lod.vertex_num, 0, lod.face_num);
00144                 dmd->faceCount = lod.face_num;
00145             }
00146             else
00147                 result = CDDM_new(lod.vertex_num, 0, 0);
00148 
00149             mvert = CDDM_get_verts(result);
00150             for(a=0; a<lod.vertex_num; a++) {
00151                 MVert *mv = &mvert[a];
00152                 float *vbCo = &lod.vertex_buffer[a*3];
00153                 
00154                 copy_v3_v3(mv->co, vbCo);
00155             }
00156 
00157             if(lod.vertex_num>2) {
00158                 mface = CDDM_get_faces(result);
00159                 for(a=0; a<lod.face_num; a++) {
00160                     MFace *mf = &mface[a];
00161                     int *tri = &lod.triangle_index_buffer[a*3];
00162                     mf->v1 = tri[0];
00163                     mf->v2 = tri[1];
00164                     mf->v3 = tri[2];
00165                     test_index_face(mf, NULL, 0, 3);
00166                 }
00167             }
00168 
00169             CDDM_calc_edges(result);
00170             CDDM_calc_normals(result);
00171         }
00172         else
00173             modifier_setError(md, "Out of memory.");
00174 
00175         LOD_FreeDecimationData(&lod);
00176     }
00177     else
00178         modifier_setError(md, "Non-manifold mesh as input.");
00179 
00180     MEM_freeN(lod.vertex_buffer);
00181     MEM_freeN(lod.vertex_normal_buffer);
00182     MEM_freeN(lod.triangle_index_buffer);
00183 
00184 exit:
00185         return result;
00186 }
00187 #else // WITH_MOD_DECIMATE
00188 static DerivedMesh *applyModifier(ModifierData *UNUSED(md), Object *UNUSED(ob),
00189                         DerivedMesh *derivedData,
00190                         int UNUSED(useRenderParams),
00191                         int UNUSED(isFinalCalc))
00192 {
00193     return derivedData;
00194 }
00195 #endif // WITH_MOD_DECIMATE
00196 
00197 ModifierTypeInfo modifierType_Decimate = {
00198     /* name */              "Decimate",
00199     /* structName */        "DecimateModifierData",
00200     /* structSize */        sizeof(DecimateModifierData),
00201     /* type */              eModifierTypeType_Nonconstructive,
00202     /* flags */             eModifierTypeFlag_AcceptsMesh,
00203     /* copyData */          copyData,
00204     /* deformVerts */       NULL,
00205     /* deformMatrices */    NULL,
00206     /* deformVertsEM */     NULL,
00207     /* deformMatricesEM */  NULL,
00208     /* applyModifier */     applyModifier,
00209     /* applyModifierEM */   NULL,
00210     /* initData */          initData,
00211     /* requiredDataMask */  NULL,
00212     /* freeData */          NULL,
00213     /* isDisabled */        NULL,
00214     /* updateDepgraph */    NULL,
00215     /* dependsOnTime */     NULL,
00216     /* dependsOnNormals */  NULL,
00217     /* foreachObjectLink */ NULL,
00218     /* foreachIDLink */     NULL,
00219     /* foreachTexLink */    NULL,
00220 };