Index: source/blender/blenkernel/intern/modifier.c =================================================================== --- source/blender/blenkernel/intern/modifier.c (revision 10949) +++ source/blender/blenkernel/intern/modifier.c (working copy) @@ -3190,6 +3190,11 @@ DecimateModifierData *dmd = (DecimateModifierData*) md; dmd->percent = 1.0; + dmd->start_dist = 10.0; + dmd->end_dist = 20.0; + dmd->prev_dist = 0.0; + dmd->current_dist = 0.0; + dmd->tolerance = 5.0; } static void decimateModifier_copyData(ModifierData *md, ModifierData *target) @@ -3197,9 +3202,19 @@ DecimateModifierData *dmd = (DecimateModifierData*) md; DecimateModifierData *tdmd = (DecimateModifierData*) target; + tdmd->flag = dmd->flag; tdmd->percent = dmd->percent; + tdmd->start_dist = dmd->start_dist; + tdmd->end_dist = dmd->end_dist; + tdmd->tolerance = dmd->tolerance; + } +static int decimateModifier_dependsOnTime(ModifierData *md) +{ + return 1; +} + static DerivedMesh *decimateModifier_applyModifier( ModifierData *md, Object *ob, DerivedMesh *derivedData, int useRenderParams, int isFinalCalc) @@ -3209,112 +3224,141 @@ MVert *mvert; MFace *mface; LOD_Decimation_Info lod; + float tmp_vec[3]; + float work_dist,actual_dist; int totvert, totface; int a, numTris; + + /* get distance from camera*/ + + dmd->current_dist = VecLenf(ob->obmat[3],G.scene->camera->obmat[3]); + /*printf("vec_length = %f \n",vec_length);*/ + + + + if (dmd->flag & MOD_DECIMATE_DIST && dmd->current_dist> dmd->start_dist){ - mvert = dm->getVertArray(dm); - mface = dm->getFaceArray(dm); - totvert = dm->getNumVerts(dm); - totface = dm->getNumFaces(dm); - numTris = 0; - for (a=0; av4) numTris++; + /*get difference difference between start and end*/ + work_dist = dmd->end_dist - dmd->start_dist; + /*printf("work_dist = %f \n",work_dist);*/ + + actual_dist = dmd->current_dist - dmd->start_dist; + + /*see if the distance is changed outside the tolerance range*/ + if ((abs(dmd->prev_dist - dmd->current_dist)) > dmd->tolerance) + { + dmd->percent = 1-(actual_dist/work_dist); + dmd->prev_dist = dmd->current_dist; + } + } - if(numTris<3) { - modifier_setError(md, - "There must be more than 3 input faces (triangles)."); - goto exit; - } + if (!(dmd->flag & MOD_DECIMATE_DIST) || ((dmd->flag & MOD_DECIMATE_DIST) && (dmd->current_dist > dmd->start_dist))){ + + mvert = dm->getVertArray(dm); + mface = dm->getFaceArray(dm); + totvert = dm->getNumVerts(dm); + totface = dm->getNumFaces(dm); - lod.vertex_buffer= MEM_mallocN(3*sizeof(float)*totvert, "vertices"); - lod.vertex_normal_buffer= MEM_mallocN(3*sizeof(float)*totvert, "normals"); - lod.triangle_index_buffer= MEM_mallocN(3*sizeof(int)*numTris, "trias"); - lod.vertex_num= totvert; - lod.face_num= numTris; + numTris = 0; + for (a=0; av4) numTris++; + } - for(a=0; aco); + lod.vertex_buffer= MEM_mallocN(3*sizeof(float)*totvert, "vertices"); + lod.vertex_normal_buffer= MEM_mallocN(3*sizeof(float)*totvert, "normals"); + lod.triangle_index_buffer= MEM_mallocN(3*sizeof(int)*numTris, "trias"); + lod.vertex_num= totvert; + lod.face_num= numTris; - vbNo[0] = mv->no[0]/32767.0f; - vbNo[1] = mv->no[1]/32767.0f; - vbNo[2] = mv->no[2]/32767.0f; - } + for(a=0; av1; - tri[1]= mf->v2; - tri[2]= mf->v3; + VECCOPY(vbCo, mv->co); - if(mf->v4) { - tri = &lod.triangle_index_buffer[3*numTris++]; - tri[0]= mf->v1; - tri[1]= mf->v3; - tri[2]= mf->v4; + vbNo[0] = mv->no[0]/32767.0f; + vbNo[1] = mv->no[1]/32767.0f; + vbNo[2] = mv->no[2]/32767.0f; } - } - dmd->faceCount = 0; - if(LOD_LoadMesh(&lod) ) { - if( LOD_PreprocessMesh(&lod) ) { - /* we assume the decim_faces tells how much to reduce */ + numTris = 0; + for(a=0; av1; + tri[1]= mf->v2; + tri[2]= mf->v3; - while(lod.face_num > numTris*dmd->percent) { - if( LOD_CollapseEdge(&lod)==0) break; + if(mf->v4) { + tri = &lod.triangle_index_buffer[3*numTris++]; + tri[0]= mf->v1; + tri[1]= mf->v3; + tri[2]= mf->v4; } + } - if(lod.vertex_num>2) { - result = CDDM_new(lod.vertex_num, 0, lod.face_num); - dmd->faceCount = lod.face_num; - } - else - result = CDDM_new(lod.vertex_num, 0, 0); + dmd->faceCount = 0; + if(LOD_LoadMesh(&lod) ) { + if( LOD_PreprocessMesh(&lod) ) { + /* we assume the decim_faces tells how much to reduce */ - mvert = CDDM_get_verts(result); - for(a=0; aco, vbCo); - } + while(lod.face_num > numTris*dmd->percent) { + if( LOD_CollapseEdge(&lod)==0) break; + } - if(lod.vertex_num>2) { - mface = CDDM_get_faces(result); - for(a=0; av1 = tri[0]; - mf->v2 = tri[1]; - mf->v3 = tri[2]; - test_index_face(mf, NULL, 0, 3); + if(lod.vertex_num>2) { + result = CDDM_new(lod.vertex_num, 0, lod.face_num); + dmd->faceCount = lod.face_num; } + else + result = CDDM_new(lod.vertex_num, 0, 0); + + mvert = CDDM_get_verts(result); + for(a=0; aco, vbCo); + } + + if(lod.vertex_num>2) { + mface = CDDM_get_faces(result); + for(a=0; av1 = tri[0]; + mf->v2 = tri[1]; + mf->v3 = tri[2]; + test_index_face(mf, NULL, 0, 3); + } + } + + CDDM_calc_edges(result); + CDDM_calc_normals(result); } + else + modifier_setError(md, "Out of memory."); - CDDM_calc_edges(result); - CDDM_calc_normals(result); + LOD_FreeDecimationData(&lod); } else - modifier_setError(md, "Out of memory."); + modifier_setError(md, "Non-manifold mesh as input."); - LOD_FreeDecimationData(&lod); + MEM_freeN(lod.vertex_buffer); + MEM_freeN(lod.vertex_normal_buffer); + MEM_freeN(lod.triangle_index_buffer); } - else - modifier_setError(md, "Non-manifold mesh as input."); - - MEM_freeN(lod.vertex_buffer); - MEM_freeN(lod.vertex_normal_buffer); - MEM_freeN(lod.triangle_index_buffer); - exit: return result; } @@ -5011,6 +5055,7 @@ mti->initData = decimateModifier_initData; mti->copyData = decimateModifier_copyData; mti->applyModifier = decimateModifier_applyModifier; + mti->dependsOnTime = decimateModifier_dependsOnTime; mti = INIT_TYPE(Smooth); mti->type = eModifierTypeType_OnlyDeform; Index: source/blender/makesdna/DNA_modifier_types.h =================================================================== --- source/blender/makesdna/DNA_modifier_types.h (revision 10949) +++ source/blender/makesdna/DNA_modifier_types.h (working copy) @@ -230,11 +231,19 @@ typedef struct DecimateModifierData { ModifierData modifier; - + + short flag,pad; + + float start_dist, end_dist, pad01; + float prev_dist, current_dist, tolerance, pad02; + float percent; int faceCount; } DecimateModifierData; +/*decimate modifier flags*/ +#define MOD_DECIMATE_DIST (1<<1) + /* Smooth modifier flags */ #define MOD_SMOOTH_X (1<<1) #define MOD_SMOOTH_Y (1<<2) Index: source/blender/src/buttons_editing.c =================================================================== --- source/blender/src/buttons_editing.c (revision 10949) +++ source/blender/src/buttons_editing.c (working copy) @@ -1578,7 +1578,13 @@ } else if (md->type==eModifierType_UVProject) { height = 114 + ((UVProjectModifierData *)md)->num_projectors * 19; } else if (md->type==eModifierType_Decimate) { - height = 48; + DecimateModifierData *dmd = (DecimateModifierData *)md; + height = 68; + if (dmd->flag & MOD_DECIMATE_DIST) + { + height = 148; + } + } else if (md->type==eModifierType_Smooth) { height = 86; } else if (md->type==eModifierType_Cast) { @@ -1807,11 +1813,18 @@ } else if (md->type==eModifierType_Decimate) { DecimateModifierData *dmd = (DecimateModifierData*) md; uiDefButF(block, NUM, B_MODIFIER_RECALC, "Ratio:", lx,(cy-=19),buttonWidth,19, &dmd->percent, 0.0, 1.0, 10, 0, "Defines the percentage of triangles to reduce to"); + uiDefButBitS(block, TOG, MOD_DECIMATE_DIST, B_MODIFIER_RECALC, "Use Distance", lx,(cy-=19),buttonWidth,19, &dmd->flag, 0, 0, 0, 0, "Enable Distance Functionality"); + if (dmd->flag & MOD_DECIMATE_DIST){ + uiDefButF(block, NUM, B_MODIFIER_RECALC, "Start Dist:", lx,(cy-=19),buttonWidth,19, &dmd->start_dist, 0.0, 500.0, 10, 0, "distance to start decimating"); + uiDefButF(block, NUM, B_MODIFIER_RECALC, "End Dist:", lx,(cy-=19),buttonWidth,19, &dmd->end_dist, 0.0, 500.0, 10, 0, "distance to end decimating"); + uiDefButF(block, NUM, B_MODIFIER_RECALC, "Tolerance:", lx,(cy-=19),buttonWidth,19, &dmd->tolerance, 0.0, 500.0, 10, 0, "how far the object has to have moved from last calculation to recalculate"); + sprintf(str, "Current Dist: %f", dmd->current_dist); + uiDefBut(block, LABEL, 1, str, lx, (cy-=19), 160,19, NULL, 0.0, 0.0, 0, 0, "Displays the current distance"); + } sprintf(str, "Face Count: %d", dmd->faceCount); uiDefBut(block, LABEL, 1, str, lx, (cy-=19), 160,19, NULL, 0.0, 0.0, 0, 0, "Displays the current number of faces in the decimated mesh"); } else if (md->type==eModifierType_Smooth) { SmoothModifierData *smd = (SmoothModifierData*) md; - uiDefButBitS(block, TOG, MOD_SMOOTH_X, B_MODIFIER_RECALC, "X", lx,(cy-=19),45,19, &smd->flag, 0, 0, 0, 0, "Enable X axis smoothing"); uiDefButBitS(block, TOG, MOD_SMOOTH_Y, B_MODIFIER_RECALC, "Y", lx+45,cy,45,19, &smd->flag, 0, 0, 0, 0, "Enable Y axis smoothing"); uiDefButBitS(block, TOG, MOD_SMOOTH_Z, B_MODIFIER_RECALC, "Z", lx+90,cy,45,19, &smd->flag, 0, 0, 0, 0, "Enable Z axis smoothing");