static DerivedMesh *triangulate_dm(DerivedMesh *dm, const int quad_method, const int ngon_method) { DerivedMesh *result; BMesh *bm; int total_edges, i; MEdge *me; bm = DM_to_bmesh(dm, true); BM_mesh_triangulate(bm, quad_method, ngon_method, false, NULL, NULL); result = CDDM_from_bmesh(bm, false); BM_mesh_free(bm); total_edges = result->getNumEdges(result); me = CDDM_get_edges(result); /* force drawing of all edges (seems to be omitted in CDDM_from_bmesh) */ for (i = 0; i < total_edges; i++, me++) me->flag |= ME_EDGEDRAW | ME_EDGERENDER; result->dirty |= DM_DIRTY_NORMALS; return result; }
static DerivedMesh *WireframeModifier_do(WireframeModifierData *wmd, Object *ob, DerivedMesh *dm) { DerivedMesh *result; BMesh *bm; const int defgrp_index = defgroup_name_index(ob, wmd->defgrp_name); bm = DM_to_bmesh(dm, true); BM_mesh_wireframe( bm, wmd->offset, wmd->offset_fac, wmd->offset_fac_vg, (wmd->flag & MOD_WIREFRAME_REPLACE) != 0, (wmd->flag & MOD_WIREFRAME_BOUNDARY) != 0, (wmd->flag & MOD_WIREFRAME_OFS_EVEN) != 0, (wmd->flag & MOD_WIREFRAME_OFS_RELATIVE) != 0, (wmd->flag & MOD_WIREFRAME_CREASE) != 0, wmd->crease_weight, defgrp_index, (wmd->flag & MOD_WIREFRAME_INVERT_VGROUP) != 0, wmd->mat_ofs, MAX2(ob->totcol - 1, 0), false); result = CDDM_from_bmesh(bm, true); BM_mesh_free(bm); result->dirty |= DM_DIRTY_NORMALS; return result; }
static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *derivedData, ModifierApplyFlag UNUSED(flag)) { DecimateModifierData *dmd = (DecimateModifierData *) md; DerivedMesh *dm = derivedData, *result = NULL; BMesh *bm; bool calc_face_normal; float *vweights = NULL; #ifdef USE_TIMEIT TIMEIT_START(decim); #endif /* set up front so we dont show invalid info in the UI */ dmd->face_count = dm->getNumPolys(dm); switch (dmd->mode) { case MOD_DECIM_MODE_COLLAPSE: if (dmd->percent == 1.0f) { return dm; } calc_face_normal = true; break; case MOD_DECIM_MODE_UNSUBDIV: if (dmd->iter == 0) { return dm; } calc_face_normal = false; break; case MOD_DECIM_MODE_DISSOLVE: if (dmd->angle == 0.0f) { return dm; } calc_face_normal = true; break; default: return dm; } if (dmd->face_count <= 3) { modifier_setError(md, "Modifier requires more than 3 input faces"); return dm; } if (dmd->mode == MOD_DECIM_MODE_COLLAPSE) { if (dmd->defgrp_name[0]) { MDeformVert *dvert; int defgrp_index; modifier_get_vgroup(ob, dm, dmd->defgrp_name, &dvert, &defgrp_index); if (dvert) { const unsigned int vert_tot = dm->getNumVerts(dm); unsigned int i; vweights = MEM_mallocN(vert_tot * sizeof(float), __func__); if (dmd->flag & MOD_DECIM_FLAG_INVERT_VGROUP) { for (i = 0; i < vert_tot; i++) { const float f = 1.0f - defvert_find_weight(&dvert[i], defgrp_index); vweights[i] = f > BM_MESH_DECIM_WEIGHT_EPS ? (1.0f / f) : BM_MESH_DECIM_WEIGHT_MAX; } } else { for (i = 0; i < vert_tot; i++) { const float f = defvert_find_weight(&dvert[i], defgrp_index); vweights[i] = f > BM_MESH_DECIM_WEIGHT_EPS ? (1.0f / f) : BM_MESH_DECIM_WEIGHT_MAX; } } } } } bm = DM_to_bmesh(dm, calc_face_normal); switch (dmd->mode) { case MOD_DECIM_MODE_COLLAPSE: { const int do_triangulate = (dmd->flag & MOD_DECIM_FLAG_TRIANGULATE) != 0; BM_mesh_decimate_collapse(bm, dmd->percent, vweights, do_triangulate); break; } case MOD_DECIM_MODE_UNSUBDIV: { BM_mesh_decimate_unsubdivide(bm, dmd->iter); break; } case MOD_DECIM_MODE_DISSOLVE: { const int do_dissolve_boundaries = (dmd->flag & MOD_DECIM_FLAG_ALL_BOUNDARY_VERTS) != 0; BM_mesh_decimate_dissolve(bm, dmd->angle, do_dissolve_boundaries, (BMO_Delimit)dmd->delimit); break; } } if (vweights) { MEM_freeN(vweights); } /* update for display only */ dmd->face_count = bm->totface; result = CDDM_from_bmesh(bm, false); BLI_assert(bm->vtoolflagpool == NULL && bm->etoolflagpool == NULL && bm->ftoolflagpool == NULL); /* make sure we never alloc'd these */ BLI_assert(bm->vtable == NULL && bm->etable == NULL && bm->ftable == NULL); BM_mesh_free(bm); #ifdef USE_TIMEIT TIMEIT_END(decim); #endif result->dirty = DM_DIRTY_NORMALS; return result; }