Changeset View
Changeset View
Standalone View
Standalone View
source/blender/bmesh/intern/bmesh_mesh_convert.cc
| Show First 20 Lines • Show All 92 Lines • ▼ Show 20 Lines | |||||
| using blender::float3; | using blender::float3; | ||||
| using blender::IndexRange; | using blender::IndexRange; | ||||
| using blender::MutableSpan; | using blender::MutableSpan; | ||||
| using blender::Span; | using blender::Span; | ||||
| using blender::StringRef; | using blender::StringRef; | ||||
| /* Static function for alloc (duplicate in modifiers_bmesh.c) */ | /* Static function for alloc (duplicate in modifiers_bmesh.c) */ | ||||
| static BMFace *bm_face_create_from_mpoly(BMesh &bm, | static BMFace *bm_face_create_from_mpoly(BMesh &bm, | ||||
| Span<MLoop> loops, | Span<int> poly_verts, | ||||
| Span<int> poly_edges, | |||||
| Span<BMVert *> vtable, | Span<BMVert *> vtable, | ||||
| Span<BMEdge *> etable) | Span<BMEdge *> etable) | ||||
| { | { | ||||
| Array<BMVert *, BM_DEFAULT_NGON_STACK_SIZE> verts(loops.size()); | const int size = poly_verts.size(); | ||||
| Array<BMEdge *, BM_DEFAULT_NGON_STACK_SIZE> edges(loops.size()); | Array<BMVert *, BM_DEFAULT_NGON_STACK_SIZE> verts(size); | ||||
| Array<BMEdge *, BM_DEFAULT_NGON_STACK_SIZE> edges(size); | |||||
| for (const int i : loops.index_range()) { | for (const int i : IndexRange(size)) { | ||||
| verts[i] = vtable[loops[i].v]; | verts[i] = vtable[poly_verts[i]]; | ||||
| edges[i] = etable[loops[i].e]; | edges[i] = etable[poly_edges[i]]; | ||||
| } | } | ||||
| return BM_face_create(&bm, verts.data(), edges.data(), loops.size(), nullptr, BM_CREATE_SKIP_CD); | return BM_face_create(&bm, verts.data(), edges.data(), size, nullptr, BM_CREATE_SKIP_CD); | ||||
| } | } | ||||
| void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshParams *params) | void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const struct BMeshFromMeshParams *params) | ||||
| { | { | ||||
| if (!me) { | if (!me) { | ||||
| /* Sanity check. */ | /* Sanity check. */ | ||||
| return; | return; | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 184 Lines • ▼ Show 20 Lines | |||||
| /* Copy Custom Data */ | /* Copy Custom Data */ | ||||
| CustomData_to_bmesh_block(&mesh_edata, &bm->edata, i, &e->head.data, true); | CustomData_to_bmesh_block(&mesh_edata, &bm->edata, i, &e->head.data, true); | ||||
| } | } | ||||
| if (is_new) { | if (is_new) { | ||||
| bm->elem_index_dirty &= ~BM_EDGE; /* Added in order, clear dirty flag. */ | bm->elem_index_dirty &= ~BM_EDGE; /* Added in order, clear dirty flag. */ | ||||
| } | } | ||||
| const Span<MPoly> mpoly = me->polys(); | const Span<MPoly> mpoly = me->polys(); | ||||
| const Span<MLoop> mloop = me->loops(); | const Span<int> corner_verts = me->corner_verts(); | ||||
| const Span<int> corner_edges = me->corner_edges(); | |||||
| /* Only needed for selection. */ | /* Only needed for selection. */ | ||||
| Array<BMFace *> ftable; | Array<BMFace *> ftable; | ||||
| if (me->mselect && me->totselect != 0) { | if (me->mselect && me->totselect != 0) { | ||||
| ftable.reinitialize(me->totpoly); | ftable.reinitialize(me->totpoly); | ||||
| } | } | ||||
| int totloops = 0; | int totloops = 0; | ||||
| for (const int i : mpoly.index_range()) { | for (const int i : mpoly.index_range()) { | ||||
| BMFace *f = bm_face_create_from_mpoly( | BMFace *f = bm_face_create_from_mpoly(*bm, | ||||
| *bm, mloop.slice(mpoly[i].loopstart, mpoly[i].totloop), vtable, etable); | corner_verts.slice(mpoly[i].loopstart, mpoly[i].totloop), | ||||
| corner_edges.slice(mpoly[i].loopstart, mpoly[i].totloop), | |||||
| vtable, | |||||
| etable); | |||||
| if (!ftable.is_empty()) { | if (!ftable.is_empty()) { | ||||
| ftable[i] = f; | ftable[i] = f; | ||||
| } | } | ||||
| if (UNLIKELY(f == nullptr)) { | if (UNLIKELY(f == nullptr)) { | ||||
| printf( | printf( | ||||
| "%s: Warning! Bad face in mesh" | "%s: Warning! Bad face in mesh" | ||||
| " \"%s\" at index %d!, skipping\n", | " \"%s\" at index %d!, skipping\n", | ||||
| Show All 22 Lines | |||||
| int j = mpoly[i].loopstart; | int j = mpoly[i].loopstart; | ||||
| BMLoop *l_first = BM_FACE_FIRST_LOOP(f); | BMLoop *l_first = BM_FACE_FIRST_LOOP(f); | ||||
| BMLoop *l_iter = l_first; | BMLoop *l_iter = l_first; | ||||
| do { | do { | ||||
| /* Don't use 'j' since we may have skipped some faces, hence some loops. */ | /* Don't use 'j' since we may have skipped some faces, hence some loops. */ | ||||
| BM_elem_index_set(l_iter, totloops++); /* set_ok */ | BM_elem_index_set(l_iter, totloops++); /* set_ok */ | ||||
| /* Save index of corresponding #MLoop. */ | /* Save index of corresponding corner. */ | ||||
| CustomData_to_bmesh_block(&mesh_ldata, &bm->ldata, j++, &l_iter->head.data, true); | CustomData_to_bmesh_block(&mesh_ldata, &bm->ldata, j++, &l_iter->head.data, true); | ||||
| } while ((l_iter = l_iter->next) != l_first); | } while ((l_iter = l_iter->next) != l_first); | ||||
| /* Copy Custom Data */ | /* Copy Custom Data */ | ||||
| CustomData_to_bmesh_block(&mesh_pdata, &bm->pdata, i, &f->head.data, true); | CustomData_to_bmesh_block(&mesh_pdata, &bm->pdata, i, &f->head.data, true); | ||||
| if (params->calc_face_normal) { | if (params->calc_face_normal) { | ||||
| BM_face_normal_update(f); | BM_face_normal_update(f); | ||||
| ▲ Show 20 Lines • Show All 184 Lines • ▼ Show 20 Lines | |||||
| }); | }); | ||||
| attribute.finish(); | attribute.finish(); | ||||
| } | } | ||||
| static void assert_bmesh_has_no_mesh_only_attributes(const BMesh &bm) | static void assert_bmesh_has_no_mesh_only_attributes(const BMesh &bm) | ||||
| { | { | ||||
| (void)bm; /* Unused in the release builds. */ | (void)bm; /* Unused in the release builds. */ | ||||
| BLI_assert(CustomData_get_layer_named(&bm.vdata, CD_PROP_FLOAT3, "position") == nullptr); | BLI_assert(CustomData_get_layer_named(&bm.vdata, CD_PROP_FLOAT3, "position") == nullptr); | ||||
| BLI_assert(CustomData_get_layer_named(&bm.ldata, CD_PROP_FLOAT3, ".corner_vert") == nullptr); | |||||
| BLI_assert(CustomData_get_layer_named(&bm.ldata, CD_PROP_FLOAT3, ".corner_edge") == nullptr); | |||||
| /* The "hide" attributes are stored as flags on #BMesh. */ | /* The "hide" attributes are stored as flags on #BMesh. */ | ||||
| BLI_assert(CustomData_get_layer_named(&bm.vdata, CD_PROP_BOOL, ".hide_vert") == nullptr); | BLI_assert(CustomData_get_layer_named(&bm.vdata, CD_PROP_BOOL, ".hide_vert") == nullptr); | ||||
| BLI_assert(CustomData_get_layer_named(&bm.edata, CD_PROP_BOOL, ".hide_edge") == nullptr); | BLI_assert(CustomData_get_layer_named(&bm.edata, CD_PROP_BOOL, ".hide_edge") == nullptr); | ||||
| BLI_assert(CustomData_get_layer_named(&bm.pdata, CD_PROP_BOOL, ".hide_poly") == nullptr); | BLI_assert(CustomData_get_layer_named(&bm.pdata, CD_PROP_BOOL, ".hide_poly") == nullptr); | ||||
| /* The "selection" attributes are stored as flags on #BMesh. */ | /* The "selection" attributes are stored as flags on #BMesh. */ | ||||
| BLI_assert(CustomData_get_layer_named(&bm.vdata, CD_PROP_BOOL, ".select_vert") == nullptr); | BLI_assert(CustomData_get_layer_named(&bm.vdata, CD_PROP_BOOL, ".select_vert") == nullptr); | ||||
| BLI_assert(CustomData_get_layer_named(&bm.edata, CD_PROP_BOOL, ".select_edge") == nullptr); | BLI_assert(CustomData_get_layer_named(&bm.edata, CD_PROP_BOOL, ".select_edge") == nullptr); | ||||
| ▲ Show 20 Lines • Show All 152 Lines • ▼ Show 20 Lines | |||||
| CustomData_copy(&bm->edata, &me->edata, mask.emask, CD_SET_DEFAULT, me->totedge); | CustomData_copy(&bm->edata, &me->edata, mask.emask, CD_SET_DEFAULT, me->totedge); | ||||
| CustomData_copy(&bm->ldata, &me->ldata, mask.lmask, CD_SET_DEFAULT, me->totloop); | CustomData_copy(&bm->ldata, &me->ldata, mask.lmask, CD_SET_DEFAULT, me->totloop); | ||||
| CustomData_copy(&bm->pdata, &me->pdata, mask.pmask, CD_SET_DEFAULT, me->totpoly); | CustomData_copy(&bm->pdata, &me->pdata, mask.pmask, CD_SET_DEFAULT, me->totpoly); | ||||
| } | } | ||||
| CustomData_add_layer_named( | CustomData_add_layer_named( | ||||
| &me->vdata, CD_PROP_FLOAT3, CD_CONSTRUCT, nullptr, me->totvert, "position"); | &me->vdata, CD_PROP_FLOAT3, CD_CONSTRUCT, nullptr, me->totvert, "position"); | ||||
| CustomData_add_layer(&me->edata, CD_MEDGE, CD_SET_DEFAULT, nullptr, me->totedge); | CustomData_add_layer(&me->edata, CD_MEDGE, CD_SET_DEFAULT, nullptr, me->totedge); | ||||
| CustomData_add_layer(&me->ldata, CD_MLOOP, CD_SET_DEFAULT, nullptr, me->totloop); | CustomData_add_layer_named( | ||||
| &me->ldata, CD_PROP_INT32, CD_CONSTRUCT, nullptr, me->totloop, ".corner_vert"); | |||||
| CustomData_add_layer_named( | |||||
| &me->ldata, CD_PROP_INT32, CD_CONSTRUCT, nullptr, me->totloop, ".corner_edge"); | |||||
| CustomData_add_layer(&me->pdata, CD_MPOLY, CD_SET_DEFAULT, nullptr, me->totpoly); | CustomData_add_layer(&me->pdata, CD_MPOLY, CD_SET_DEFAULT, nullptr, me->totpoly); | ||||
| MutableSpan<float3> positions = me->vert_positions_for_write(); | MutableSpan<float3> positions = me->vert_positions_for_write(); | ||||
| MutableSpan<MEdge> medge = me->edges_for_write(); | MutableSpan<MEdge> medge = me->edges_for_write(); | ||||
| MutableSpan<MPoly> mpoly = me->polys_for_write(); | MutableSpan<MPoly> mpoly = me->polys_for_write(); | ||||
| MutableSpan<MLoop> mloop = me->loops_for_write(); | MutableSpan<int> corner_verts = me->corner_verts_for_write(); | ||||
| MutableSpan<int> corner_edges = me->corner_edges_for_write(); | |||||
| bool need_select_vert = false; | bool need_select_vert = false; | ||||
| bool need_select_edge = false; | bool need_select_edge = false; | ||||
| bool need_select_poly = false; | bool need_select_poly = false; | ||||
| bool need_hide_vert = false; | bool need_hide_vert = false; | ||||
| bool need_hide_edge = false; | bool need_hide_edge = false; | ||||
| bool need_hide_poly = false; | bool need_hide_poly = false; | ||||
| bool need_material_index = false; | bool need_material_index = false; | ||||
| ▲ Show 20 Lines • Show All 61 Lines • ▼ Show 20 Lines | |||||
| need_hide_poly = true; | need_hide_poly = true; | ||||
| } | } | ||||
| if (BM_elem_flag_test(f, BM_ELEM_SELECT)) { | if (BM_elem_flag_test(f, BM_ELEM_SELECT)) { | ||||
| need_select_poly = true; | need_select_poly = true; | ||||
| } | } | ||||
| l_iter = l_first = BM_FACE_FIRST_LOOP(f); | l_iter = l_first = BM_FACE_FIRST_LOOP(f); | ||||
| do { | do { | ||||
| mloop[j].e = BM_elem_index_get(l_iter->e); | corner_verts[j] = BM_elem_index_get(l_iter->v); | ||||
| mloop[j].v = BM_elem_index_get(l_iter->v); | corner_edges[j] = BM_elem_index_get(l_iter->e); | ||||
| /* Copy over custom-data. */ | /* Copy over custom-data. */ | ||||
| CustomData_from_bmesh_block(&bm->ldata, &me->ldata, l_iter->head.data, j); | CustomData_from_bmesh_block(&bm->ldata, &me->ldata, l_iter->head.data, j); | ||||
| j++; | j++; | ||||
| BM_CHECK_ELEMENT(l_iter); | BM_CHECK_ELEMENT(l_iter); | ||||
| BM_CHECK_ELEMENT(l_iter->e); | BM_CHECK_ELEMENT(l_iter->e); | ||||
| BM_CHECK_ELEMENT(l_iter->v); | BM_CHECK_ELEMENT(l_iter->v); | ||||
| ▲ Show 20 Lines • Show All 155 Lines • ▼ Show 20 Lines | |||||
| me->totloop = bm->totloop; | me->totloop = bm->totloop; | ||||
| me->totpoly = bm->totface; | me->totpoly = bm->totface; | ||||
| if (!CustomData_get_layer_named(&me->vdata, CD_PROP_FLOAT3, "position")) { | if (!CustomData_get_layer_named(&me->vdata, CD_PROP_FLOAT3, "position")) { | ||||
| CustomData_add_layer_named( | CustomData_add_layer_named( | ||||
| &me->vdata, CD_PROP_FLOAT3, CD_CONSTRUCT, nullptr, bm->totvert, "position"); | &me->vdata, CD_PROP_FLOAT3, CD_CONSTRUCT, nullptr, bm->totvert, "position"); | ||||
| } | } | ||||
| CustomData_add_layer(&me->edata, CD_MEDGE, CD_SET_DEFAULT, nullptr, bm->totedge); | CustomData_add_layer(&me->edata, CD_MEDGE, CD_SET_DEFAULT, nullptr, bm->totedge); | ||||
| CustomData_add_layer(&me->ldata, CD_MLOOP, CD_SET_DEFAULT, nullptr, bm->totloop); | if (!CustomData_get_layer_named(&me->ldata, CD_PROP_INT32, ".corner_vert")) { | ||||
| CustomData_add_layer_named( | |||||
| &me->ldata, CD_PROP_INT32, CD_CONSTRUCT, nullptr, bm->totloop, ".corner_vert"); | |||||
| } | |||||
| if (!CustomData_get_layer_named(&me->ldata, CD_PROP_INT32, ".corner_edge")) { | |||||
| CustomData_add_layer_named( | |||||
| &me->ldata, CD_PROP_INT32, CD_CONSTRUCT, nullptr, bm->totloop, ".corner_edge"); | |||||
| } | |||||
| CustomData_add_layer(&me->pdata, CD_MPOLY, CD_SET_DEFAULT, nullptr, bm->totface); | CustomData_add_layer(&me->pdata, CD_MPOLY, CD_SET_DEFAULT, nullptr, bm->totface); | ||||
| /* Don't process shape-keys, we only feed them through the modifier stack as needed, | /* Don't process shape-keys, we only feed them through the modifier stack as needed, | ||||
| * e.g. for applying modifiers or the like. */ | * e.g. for applying modifiers or the like. */ | ||||
| CustomData_MeshMasks mask = CD_MASK_DERIVEDMESH; | CustomData_MeshMasks mask = CD_MASK_DERIVEDMESH; | ||||
| if (cd_mask_extra != nullptr) { | if (cd_mask_extra != nullptr) { | ||||
| CustomData_MeshMasks_update(&mask, cd_mask_extra); | CustomData_MeshMasks_update(&mask, cd_mask_extra); | ||||
| } | } | ||||
| mask.vmask &= ~CD_MASK_SHAPEKEY; | mask.vmask &= ~CD_MASK_SHAPEKEY; | ||||
| CustomData_merge(&bm->vdata, &me->vdata, mask.vmask, CD_SET_DEFAULT, me->totvert); | CustomData_merge(&bm->vdata, &me->vdata, mask.vmask, CD_SET_DEFAULT, me->totvert); | ||||
| CustomData_merge(&bm->edata, &me->edata, mask.emask, CD_SET_DEFAULT, me->totedge); | CustomData_merge(&bm->edata, &me->edata, mask.emask, CD_SET_DEFAULT, me->totedge); | ||||
| CustomData_merge(&bm->ldata, &me->ldata, mask.lmask, CD_SET_DEFAULT, me->totloop); | CustomData_merge(&bm->ldata, &me->ldata, mask.lmask, CD_SET_DEFAULT, me->totloop); | ||||
| CustomData_merge(&bm->pdata, &me->pdata, mask.pmask, CD_SET_DEFAULT, me->totpoly); | CustomData_merge(&bm->pdata, &me->pdata, mask.pmask, CD_SET_DEFAULT, me->totpoly); | ||||
| BMIter iter; | BMIter iter; | ||||
| BMVert *eve; | BMVert *eve; | ||||
| BMEdge *eed; | BMEdge *eed; | ||||
| BMFace *efa; | BMFace *efa; | ||||
| MutableSpan<float3> positions = me->vert_positions_for_write(); | MutableSpan<float3> positions = me->vert_positions_for_write(); | ||||
| MutableSpan<MEdge> medge = me->edges_for_write(); | MutableSpan<MEdge> medge = me->edges_for_write(); | ||||
| MutableSpan<MPoly> mpoly = me->polys_for_write(); | MutableSpan<MPoly> mpoly = me->polys_for_write(); | ||||
| MutableSpan<MLoop> loops = me->loops_for_write(); | MutableSpan<int> corner_verts = me->corner_verts_for_write(); | ||||
| MLoop *mloop = loops.data(); | MutableSpan<int> corner_edges = me->corner_edges_for_write(); | ||||
| uint i, j; | uint i, j; | ||||
| me->runtime->deformed_only = true; | me->runtime->deformed_only = true; | ||||
| bke::MutableAttributeAccessor mesh_attributes = me->attributes_for_write(); | bke::MutableAttributeAccessor mesh_attributes = me->attributes_for_write(); | ||||
| bke::SpanAttributeWriter<bool> hide_vert_attribute; | bke::SpanAttributeWriter<bool> hide_vert_attribute; | ||||
| bke::SpanAttributeWriter<bool> select_vert_attribute; | bke::SpanAttributeWriter<bool> select_vert_attribute; | ||||
| ▲ Show 20 Lines • Show All 93 Lines • ▼ Show 20 Lines | |||||
| material_index_attribute = mesh_attributes.lookup_or_add_for_write_span<int>( | material_index_attribute = mesh_attributes.lookup_or_add_for_write_span<int>( | ||||
| "material_index", ATTR_DOMAIN_FACE); | "material_index", ATTR_DOMAIN_FACE); | ||||
| } | } | ||||
| material_index_attribute.span[i] = efa->mat_nr; | material_index_attribute.span[i] = efa->mat_nr; | ||||
| } | } | ||||
| l_iter = l_first = BM_FACE_FIRST_LOOP(efa); | l_iter = l_first = BM_FACE_FIRST_LOOP(efa); | ||||
| do { | do { | ||||
| mloop->v = BM_elem_index_get(l_iter->v); | corner_verts[j] = BM_elem_index_get(l_iter->v); | ||||
| mloop->e = BM_elem_index_get(l_iter->e); | corner_edges[j] = BM_elem_index_get(l_iter->e); | ||||
| CustomData_from_bmesh_block(&bm->ldata, &me->ldata, l_iter->head.data, j); | CustomData_from_bmesh_block(&bm->ldata, &me->ldata, l_iter->head.data, j); | ||||
| BM_elem_index_set(l_iter, j); /* set_inline */ | BM_elem_index_set(l_iter, j); /* set_inline */ | ||||
| j++; | j++; | ||||
| mloop++; | |||||
| } while ((l_iter = l_iter->next) != l_first); | } while ((l_iter = l_iter->next) != l_first); | ||||
| CustomData_from_bmesh_block(&bm->pdata, &me->pdata, efa->head.data, i); | CustomData_from_bmesh_block(&bm->pdata, &me->pdata, efa->head.data, i); | ||||
| } | } | ||||
| bm->elem_index_dirty &= ~(BM_FACE | BM_LOOP); | bm->elem_index_dirty &= ~(BM_FACE | BM_LOOP); | ||||
| assert_bmesh_has_no_mesh_only_attributes(*bm); | assert_bmesh_has_no_mesh_only_attributes(*bm); | ||||
| Show All 9 Lines | |||||