2010-04-11 22:12:30 +00:00
|
|
|
/*
|
2011-10-23 17:52:20 +00:00
|
|
|
* ***** 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
*
|
|
|
|
* The Original Code is Copyright (C) 2005 by the Blender Foundation.
|
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
* Contributor(s): Daniel Dunbar
|
|
|
|
* Ton Roosendaal,
|
|
|
|
* Ben Batt,
|
|
|
|
* Brecht Van Lommel,
|
|
|
|
* Campbell Barton
|
|
|
|
*
|
|
|
|
* ***** END GPL LICENSE BLOCK *****
|
|
|
|
*
|
|
|
|
*/
|
2010-04-11 22:12:30 +00:00
|
|
|
|
2011-02-25 13:57:17 +00:00
|
|
|
/** \file blender/modifiers/intern/MOD_decimate.c
|
|
|
|
* \ingroup modifiers
|
|
|
|
*/
|
|
|
|
|
2012-10-22 15:39:06 +00:00
|
|
|
#include "DNA_object_types.h"
|
2010-04-11 22:12:30 +00:00
|
|
|
|
2010-04-12 22:33:43 +00:00
|
|
|
#include "BLI_math.h"
|
2012-10-22 15:39:06 +00:00
|
|
|
#include "BLI_string.h"
|
2011-01-07 18:36:47 +00:00
|
|
|
#include "BLI_utildefines.h"
|
2010-04-11 22:12:30 +00:00
|
|
|
|
2012-03-17 14:27:46 +00:00
|
|
|
#include "BLF_translation.h"
|
|
|
|
|
2011-12-24 03:03:42 +00:00
|
|
|
#include "MEM_guardedalloc.h"
|
2010-04-11 22:12:30 +00:00
|
|
|
|
|
|
|
#include "BKE_mesh.h"
|
|
|
|
#include "BKE_modifier.h"
|
2012-10-22 15:39:06 +00:00
|
|
|
#include "BKE_deform.h"
|
2010-04-11 22:12:30 +00:00
|
|
|
#include "BKE_particle.h"
|
2011-12-24 03:03:42 +00:00
|
|
|
#include "BKE_cdderivedmesh.h"
|
2010-04-11 22:12:30 +00:00
|
|
|
|
2012-10-19 10:40:32 +00:00
|
|
|
#include "BKE_tessmesh.h"
|
2012-10-22 02:39:26 +00:00
|
|
|
#include "bmesh.h"
|
2012-10-19 10:40:32 +00:00
|
|
|
|
2012-10-22 03:25:53 +00:00
|
|
|
// #define USE_TIMEIT
|
|
|
|
|
2012-10-22 02:09:41 +00:00
|
|
|
#ifdef USE_TIMEIT
|
|
|
|
# include "PIL_time.h"
|
|
|
|
#endif
|
2010-04-11 22:12:30 +00:00
|
|
|
|
2011-02-13 14:16:36 +00:00
|
|
|
#include "MOD_util.h"
|
2010-04-11 22:12:30 +00:00
|
|
|
|
|
|
|
static void initData(ModifierData *md)
|
|
|
|
{
|
2012-05-06 13:38:33 +00:00
|
|
|
DecimateModifierData *dmd = (DecimateModifierData *) md;
|
2010-04-11 22:12:30 +00:00
|
|
|
|
|
|
|
dmd->percent = 1.0;
|
2012-10-23 05:20:02 +00:00
|
|
|
dmd->angle = DEG2RADF(15.0f);
|
2010-04-11 22:12:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void copyData(ModifierData *md, ModifierData *target)
|
|
|
|
{
|
2012-05-06 13:38:33 +00:00
|
|
|
DecimateModifierData *dmd = (DecimateModifierData *) md;
|
|
|
|
DecimateModifierData *tdmd = (DecimateModifierData *) target;
|
2010-04-11 22:12:30 +00:00
|
|
|
|
|
|
|
tdmd->percent = dmd->percent;
|
2012-10-23 04:26:39 +00:00
|
|
|
tdmd->iter = dmd->iter;
|
2012-10-23 05:20:02 +00:00
|
|
|
tdmd->angle = dmd->angle;
|
2012-10-22 15:39:06 +00:00
|
|
|
BLI_strncpy(tdmd->defgrp_name, dmd->defgrp_name, sizeof(tdmd->defgrp_name));
|
|
|
|
tdmd->flag = dmd->flag;
|
2012-10-23 04:26:39 +00:00
|
|
|
tdmd->mode = dmd->mode;
|
2010-04-11 22:12:30 +00:00
|
|
|
}
|
|
|
|
|
2012-10-22 15:39:06 +00:00
|
|
|
static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md)
|
|
|
|
{
|
|
|
|
DecimateModifierData *dmd = (DecimateModifierData *) md;
|
|
|
|
CustomDataMask dataMask = 0;
|
|
|
|
|
|
|
|
/* ask for vertexgroups if we need them */
|
|
|
|
if (dmd->defgrp_name[0]) dataMask |= CD_MASK_MDEFORMVERT;
|
|
|
|
|
|
|
|
return dataMask;
|
|
|
|
}
|
|
|
|
|
|
|
|
static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
|
2012-10-19 10:40:32 +00:00
|
|
|
DerivedMesh *derivedData,
|
|
|
|
ModifierApplyFlag UNUSED(flag))
|
|
|
|
{
|
|
|
|
DecimateModifierData *dmd = (DecimateModifierData *) md;
|
|
|
|
DerivedMesh *dm = derivedData, *result = NULL;
|
|
|
|
BMEditMesh *em;
|
|
|
|
BMesh *bm;
|
|
|
|
|
2012-10-22 15:39:06 +00:00
|
|
|
float *vweights = NULL;
|
|
|
|
|
2012-10-22 02:09:41 +00:00
|
|
|
#ifdef USE_TIMEIT
|
2012-10-21 05:46:41 +00:00
|
|
|
TIMEIT_START(decim);
|
2012-10-22 02:09:41 +00:00
|
|
|
#endif
|
2012-10-20 17:31:07 +00:00
|
|
|
|
|
|
|
if (dmd->percent == 1.0f) {
|
|
|
|
return dm;
|
|
|
|
}
|
|
|
|
else if (dm->getNumPolys(dm) <= 3) {
|
2012-10-21 14:02:30 +00:00
|
|
|
modifier_setError(md, "%s", TIP_("Modifier requires more than 3 input faces"));
|
2012-10-20 17:31:07 +00:00
|
|
|
return dm;
|
|
|
|
}
|
|
|
|
|
2012-10-23 04:26:39 +00:00
|
|
|
if (dmd->mode == MOD_DECIM_MODE_COLLAPSE) {
|
|
|
|
if (dmd->defgrp_name[0]) {
|
|
|
|
MDeformVert *dvert;
|
|
|
|
int defgrp_index;
|
2012-10-22 15:39:06 +00:00
|
|
|
|
2012-10-23 04:26:39 +00:00
|
|
|
modifier_get_vgroup(ob, dm, dmd->defgrp_name, &dvert, &defgrp_index);
|
2012-10-22 15:39:06 +00:00
|
|
|
|
2012-10-23 04:26:39 +00:00
|
|
|
if (dvert) {
|
|
|
|
const unsigned int vert_tot = dm->getNumVerts(dm);
|
|
|
|
unsigned int i;
|
2012-10-22 15:39:06 +00:00
|
|
|
|
2012-10-23 04:26:39 +00:00
|
|
|
vweights = MEM_mallocN(vert_tot * sizeof(float), __func__);
|
2012-10-22 15:39:06 +00:00
|
|
|
|
2012-10-23 04:26:39 +00:00
|
|
|
if (dmd->flag & MOD_DECIM_FLAG_INVERT_VGROUP) {
|
|
|
|
for (i = 0; i < vert_tot; i++) {
|
|
|
|
vweights[i] = 1.0f - defvert_find_weight(&dvert[i], defgrp_index);
|
|
|
|
}
|
2012-10-22 15:39:06 +00:00
|
|
|
}
|
2012-10-23 04:26:39 +00:00
|
|
|
else {
|
|
|
|
for (i = 0; i < vert_tot; i++) {
|
|
|
|
vweights[i] = defvert_find_weight(&dvert[i], defgrp_index);
|
|
|
|
}
|
2012-10-22 15:39:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-10-19 10:40:32 +00:00
|
|
|
em = DM_to_editbmesh(dm, NULL, FALSE);
|
|
|
|
bm = em->bm;
|
|
|
|
|
2012-10-23 04:26:39 +00:00
|
|
|
switch (dmd->mode) {
|
|
|
|
case MOD_DECIM_MODE_COLLAPSE:
|
2012-10-23 06:13:56 +00:00
|
|
|
{
|
|
|
|
const int do_triangulate = (dmd->flag & MOD_DECIM_FLAG_TRIANGULATE) != 0;
|
2012-10-23 05:30:10 +00:00
|
|
|
BM_mesh_decimate_collapse(bm, dmd->percent, vweights, do_triangulate);
|
2012-10-23 04:26:39 +00:00
|
|
|
break;
|
2012-10-23 06:13:56 +00:00
|
|
|
}
|
2012-10-23 04:26:39 +00:00
|
|
|
case MOD_DECIM_MODE_UNSUBDIV:
|
2012-10-23 06:13:56 +00:00
|
|
|
{
|
2012-10-23 04:26:39 +00:00
|
|
|
BM_mesh_decimate_unsubdivide(bm, dmd->iter);
|
|
|
|
break;
|
2012-10-23 06:13:56 +00:00
|
|
|
}
|
2012-10-23 05:20:02 +00:00
|
|
|
case MOD_DECIM_MODE_DISSOLVE:
|
2012-10-23 06:13:56 +00:00
|
|
|
{
|
|
|
|
const int do_dissolve_boundaries = (dmd->flag & MOD_DECIM_FLAG_ALL_BOUNDARY_VERTS) != 0;
|
|
|
|
BM_mesh_decimate_dissolve(bm, dmd->angle, do_dissolve_boundaries);
|
2012-10-23 05:20:02 +00:00
|
|
|
break;
|
2012-10-23 06:13:56 +00:00
|
|
|
}
|
2012-10-23 04:26:39 +00:00
|
|
|
}
|
|
|
|
|
2012-10-22 15:39:06 +00:00
|
|
|
if (vweights) {
|
|
|
|
MEM_freeN(vweights);
|
|
|
|
}
|
2012-10-19 10:40:32 +00:00
|
|
|
|
2012-10-23 04:26:39 +00:00
|
|
|
/* update for display only */
|
|
|
|
dmd->face_count = bm->totface;
|
2012-10-20 17:31:07 +00:00
|
|
|
|
2012-10-19 10:40:32 +00:00
|
|
|
BLI_assert(em->looptris == NULL);
|
|
|
|
result = CDDM_from_BMEditMesh(em, NULL, TRUE, FALSE);
|
|
|
|
BMEdit_Free(em);
|
|
|
|
MEM_freeN(em);
|
|
|
|
|
2012-10-22 02:09:41 +00:00
|
|
|
#ifdef USE_TIMEIT
|
2012-10-21 05:46:41 +00:00
|
|
|
TIMEIT_END(decim);
|
2012-10-22 02:09:41 +00:00
|
|
|
#endif
|
2012-10-20 17:31:07 +00:00
|
|
|
|
2012-10-19 10:40:32 +00:00
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2010-04-11 22:12:30 +00:00
|
|
|
ModifierTypeInfo modifierType_Decimate = {
|
|
|
|
/* name */ "Decimate",
|
|
|
|
/* structName */ "DecimateModifierData",
|
|
|
|
/* structSize */ sizeof(DecimateModifierData),
|
|
|
|
/* type */ eModifierTypeType_Nonconstructive,
|
|
|
|
/* flags */ eModifierTypeFlag_AcceptsMesh,
|
|
|
|
/* copyData */ copyData,
|
2011-03-05 10:29:10 +00:00
|
|
|
/* deformVerts */ NULL,
|
|
|
|
/* deformMatrices */ NULL,
|
|
|
|
/* deformVertsEM */ NULL,
|
|
|
|
/* deformMatricesEM */ NULL,
|
2010-04-11 22:12:30 +00:00
|
|
|
/* applyModifier */ applyModifier,
|
2011-03-05 10:29:10 +00:00
|
|
|
/* applyModifierEM */ NULL,
|
2010-04-11 22:12:30 +00:00
|
|
|
/* initData */ initData,
|
2012-10-22 15:39:06 +00:00
|
|
|
/* requiredDataMask */ requiredDataMask,
|
2011-03-05 10:29:10 +00:00
|
|
|
/* freeData */ NULL,
|
|
|
|
/* isDisabled */ NULL,
|
|
|
|
/* updateDepgraph */ NULL,
|
|
|
|
/* dependsOnTime */ NULL,
|
|
|
|
/* dependsOnNormals */ NULL,
|
|
|
|
/* foreachObjectLink */ NULL,
|
|
|
|
/* foreachIDLink */ NULL,
|
2011-08-12 18:11:22 +00:00
|
|
|
/* foreachTexLink */ NULL,
|
2010-04-11 22:12:30 +00:00
|
|
|
};
|