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; }
void bc_triangulate_mesh(Mesh *me) { bool use_beauty = false; bool tag_only = false; BMesh *bm = BM_mesh_create(&bm_mesh_allocsize_default); BM_mesh_bm_from_me(bm, me, FALSE, 0); BM_mesh_triangulate(bm, use_beauty, tag_only, NULL, NULL); BM_mesh_bm_to_me(bm, me, FALSE); BM_mesh_free(bm); }
/*does not free the BMEditMesh struct itself*/ void BKE_editmesh_free(BMEditMesh *em) { BKE_editmesh_free_derivedmesh(em); BKE_editmesh_color_free(em); if (em->looptris) MEM_freeN(em->looptris); if (em->bm) BM_mesh_free(em->bm); }
void bc_triangulate_mesh(Mesh *me) { bool use_beauty = false; bool tag_only = false; int quad_method = MOD_TRIANGULATE_QUAD_SHORTEDGE; /* XXX: The triangulation method selection could be offered in the UI */ BMesh *bm = BM_mesh_create(&bm_mesh_allocsize_default); BM_mesh_bm_from_me(bm, me, true, false, 0); BM_mesh_triangulate(bm, quad_method, use_beauty, tag_only, NULL, NULL); BM_mesh_bm_to_me(bm, me, false); BM_mesh_free(bm); }
/*does not free the BMEditMesh struct itself*/ void BKE_editmesh_free(BMEditMesh *em) { BKE_editmesh_free_derivedmesh(em); BKE_editmesh_color_free(em); if (em->looptris) MEM_freeN(em->looptris); /* free preselection item lists */ if (em->presel_verts) BLI_ghash_free(em->presel_verts, NULL, NULL); if (em->presel_edges) BLI_ghash_free(em->presel_edges, NULL, NULL); if (em->presel_faces) BLI_ghash_free(em->presel_faces, NULL, NULL); if (em->prop3d_faces) BLI_ghash_free(em->prop3d_faces, NULL, NULL); if (em->prop2d_faces) BLI_ghash_free(em->prop2d_faces, NULL, NULL); if (em->bm) BM_mesh_free(em->bm); }
void bc_triangulate_mesh(Mesh *me) { bool use_beauty = false; bool tag_only = false; int quad_method = MOD_TRIANGULATE_QUAD_SHORTEDGE; /* XXX: The triangulation method selection could be offered in the UI */ const struct BMeshCreateParams bm_create_params = {0}; BMesh *bm = BM_mesh_create( &bm_mesh_allocsize_default, &bm_create_params); BMeshFromMeshParams bm_from_me_params = {0}; bm_from_me_params.calc_face_normal = true; BM_mesh_bm_from_me(bm, me, &bm_from_me_params); BM_mesh_triangulate(bm, quad_method, use_beauty, tag_only, NULL, NULL, NULL); BMeshToMeshParams bm_to_me_params = {0}; BM_mesh_bm_to_me(bm, me, &bm_to_me_params); BM_mesh_free(bm); }
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; }