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