Changeset View
Changeset View
Standalone View
Standalone View
source/blender/blenkernel/intern/mesh_legacy_convert.cc
| Show First 20 Lines • Show All 92 Lines • ▼ Show 20 Lines | |||||
| void BKE_mesh_calc_edges_legacy(Mesh *me, const bool use_old) | void BKE_mesh_calc_edges_legacy(Mesh *me, const bool use_old) | ||||
| { | { | ||||
| using namespace blender; | using namespace blender; | ||||
| MEdge *medge; | MEdge *medge; | ||||
| int totedge = 0; | int totedge = 0; | ||||
| const Span<MVert> verts(static_cast<const MVert *>(CustomData_get_layer(&me->vdata, CD_MVERT)), | const Span<MVert> verts(static_cast<const MVert *>(CustomData_get_layer(&me->vdata, CD_MVERT)), | ||||
| me->totvert); | me->totvert); | ||||
| const Span<MPoly> polys = me->polys(); | const Span<MPoly> polys = me->polys(); | ||||
| MutableSpan<MLoop> loops = me->loops_for_write(); | |||||
| mesh_calc_edges_mdata( | |||||
| mesh_calc_edges_mdata(verts.data(), | verts.data(), | ||||
| (MFace *)CustomData_get_layer(&me->fdata, CD_MFACE), | (MFace *)CustomData_get_layer(&me->fdata, CD_MFACE), | ||||
| loops.data(), | static_cast<MLoop *>(CustomData_get_layer_for_write(&me->ldata, CD_MLOOP, me->totloop)), | ||||
| polys.data(), | polys.data(), | ||||
| verts.size(), | verts.size(), | ||||
| me->totface, | me->totface, | ||||
| loops.size(), | me->totloop, | ||||
| polys.size(), | polys.size(), | ||||
| use_old, | use_old, | ||||
| &medge, | &medge, | ||||
| &totedge); | &totedge); | ||||
| if (totedge == 0) { | if (totedge == 0) { | ||||
| /* flag that mesh has edges */ | /* flag that mesh has edges */ | ||||
| me->totedge = 0; | me->totedge = 0; | ||||
| return; | return; | ||||
| } | } | ||||
| medge = (MEdge *)CustomData_add_layer(&me->edata, CD_MEDGE, CD_ASSIGN, medge, totedge); | medge = (MEdge *)CustomData_add_layer(&me->edata, CD_MEDGE, CD_ASSIGN, medge, totedge); | ||||
| ▲ Show 20 Lines • Show All 184 Lines • ▼ Show 20 Lines | |||||
| mesh->totloop, | mesh->totloop, | ||||
| mesh->totpoly, | mesh->totpoly, | ||||
| mesh->edges_for_write().data(), | mesh->edges_for_write().data(), | ||||
| (MFace *)CustomData_get_layer(&mesh->fdata, CD_MFACE), | (MFace *)CustomData_get_layer(&mesh->fdata, CD_MFACE), | ||||
| &mesh->totloop, | &mesh->totloop, | ||||
| &mesh->totpoly); | &mesh->totpoly); | ||||
| mesh_ensure_tessellation_customdata(mesh); | mesh_ensure_tessellation_customdata(mesh); | ||||
| BKE_mesh_legacy_convert_loops_to_corners(mesh); | |||||
| } | } | ||||
| /** | /** | ||||
| * Update active indices for active/render/clone/stencil custom data layers | * Update active indices for active/render/clone/stencil custom data layers | ||||
| * based on indices from fdata layers | * based on indices from fdata layers | ||||
| * used when creating pdata and ldata for pre-bmesh | * used when creating pdata and ldata for pre-bmesh | ||||
| * meshes and needed to preserve active/render/clone/stencil flags set in pre-bmesh files. | * meshes and needed to preserve active/render/clone/stencil flags set in pre-bmesh files. | ||||
| */ | */ | ||||
| ▲ Show 20 Lines • Show All 184 Lines • ▼ Show 20 Lines | |||||
| #define USE_TESSFACE_QUADS | #define USE_TESSFACE_QUADS | ||||
| /* We abuse #MFace.edcode to tag quad faces. See below for details. */ | /* We abuse #MFace.edcode to tag quad faces. See below for details. */ | ||||
| #define TESSFACE_IS_QUAD 1 | #define TESSFACE_IS_QUAD 1 | ||||
| const int looptri_num = poly_to_tri_count(totpoly, totloop); | const int looptri_num = poly_to_tri_count(totpoly, totloop); | ||||
| const MPoly *mp, *mpoly; | const MPoly *mp, *mpoly; | ||||
| const MLoop *ml, *mloop; | |||||
| MFace *mface, *mf; | MFace *mface, *mf; | ||||
| MemArena *arena = nullptr; | MemArena *arena = nullptr; | ||||
| int *mface_to_poly_map; | int *mface_to_poly_map; | ||||
| uint(*lindices)[4]; | uint(*lindices)[4]; | ||||
| int poly_index, mface_index; | int poly_index, mface_index; | ||||
| uint j; | uint j; | ||||
| mpoly = (const MPoly *)CustomData_get_layer(pdata, CD_MPOLY); | mpoly = (const MPoly *)CustomData_get_layer(pdata, CD_MPOLY); | ||||
| mloop = (const MLoop *)CustomData_get_layer(ldata, CD_MLOOP); | const Span<int> corner_verts = mesh.corner_verts(); | ||||
| const int *material_indices = static_cast<const int *>( | const int *material_indices = static_cast<const int *>( | ||||
| CustomData_get_layer_named(pdata, CD_PROP_INT32, "material_index")); | CustomData_get_layer_named(pdata, CD_PROP_INT32, "material_index")); | ||||
| /* Allocate the length of `totfaces`, avoid many small reallocation's, | /* Allocate the length of `totfaces`, avoid many small reallocation's, | ||||
| * if all faces are triangles it will be correct, `quads == 2x` allocations. */ | * if all faces are triangles it will be correct, `quads == 2x` allocations. */ | ||||
| /* Take care since memory is _not_ zeroed so be sure to initialize each field. */ | /* Take care since memory is _not_ zeroed so be sure to initialize each field. */ | ||||
| mface_to_poly_map = (int *)MEM_malloc_arrayN( | mface_to_poly_map = (int *)MEM_malloc_arrayN( | ||||
| size_t(looptri_num), sizeof(*mface_to_poly_map), __func__); | size_t(looptri_num), sizeof(*mface_to_poly_map), __func__); | ||||
| Show All 16 Lines | |||||
| # define ML_TO_MF(i1, i2, i3) \ | # define ML_TO_MF(i1, i2, i3) \ | ||||
| mface_to_poly_map[mface_index] = poly_index; \ | mface_to_poly_map[mface_index] = poly_index; \ | ||||
| mf = &mface[mface_index]; \ | mf = &mface[mface_index]; \ | ||||
| lidx = lindices[mface_index]; \ | lidx = lindices[mface_index]; \ | ||||
| /* Set loop indices, transformed to vert indices later. */ \ | /* Set loop indices, transformed to vert indices later. */ \ | ||||
| l1 = mp_loopstart + i1; \ | l1 = mp_loopstart + i1; \ | ||||
| l2 = mp_loopstart + i2; \ | l2 = mp_loopstart + i2; \ | ||||
| l3 = mp_loopstart + i3; \ | l3 = mp_loopstart + i3; \ | ||||
| mf->v1 = mloop[l1].v; \ | mf->v1 = corner_verts[l1]; \ | ||||
| mf->v2 = mloop[l2].v; \ | mf->v2 = corner_verts[l2]; \ | ||||
| mf->v3 = mloop[l3].v; \ | mf->v3 = corner_verts[l3]; \ | ||||
| mf->v4 = 0; \ | mf->v4 = 0; \ | ||||
| lidx[0] = l1; \ | lidx[0] = l1; \ | ||||
| lidx[1] = l2; \ | lidx[1] = l2; \ | ||||
| lidx[2] = l3; \ | lidx[2] = l3; \ | ||||
| lidx[3] = 0; \ | lidx[3] = 0; \ | ||||
| mf->mat_nr = material_indices ? material_indices[poly_index] : 0; \ | mf->mat_nr = material_indices ? material_indices[poly_index] : 0; \ | ||||
| mf->flag = mp->flag; \ | mf->flag = mp->flag; \ | ||||
| mf->edcode = 0; \ | mf->edcode = 0; \ | ||||
| (void)0 | (void)0 | ||||
| /* ALMOST IDENTICAL TO DEFINE ABOVE (see EXCEPTION) */ | /* ALMOST IDENTICAL TO DEFINE ABOVE (see EXCEPTION) */ | ||||
| # define ML_TO_MF_QUAD() \ | # define ML_TO_MF_QUAD() \ | ||||
| mface_to_poly_map[mface_index] = poly_index; \ | mface_to_poly_map[mface_index] = poly_index; \ | ||||
| mf = &mface[mface_index]; \ | mf = &mface[mface_index]; \ | ||||
| lidx = lindices[mface_index]; \ | lidx = lindices[mface_index]; \ | ||||
| /* Set loop indices, transformed to vert indices later. */ \ | /* Set loop indices, transformed to vert indices later. */ \ | ||||
| l1 = mp_loopstart + 0; /* EXCEPTION */ \ | l1 = mp_loopstart + 0; /* EXCEPTION */ \ | ||||
| l2 = mp_loopstart + 1; /* EXCEPTION */ \ | l2 = mp_loopstart + 1; /* EXCEPTION */ \ | ||||
| l3 = mp_loopstart + 2; /* EXCEPTION */ \ | l3 = mp_loopstart + 2; /* EXCEPTION */ \ | ||||
| l4 = mp_loopstart + 3; /* EXCEPTION */ \ | l4 = mp_loopstart + 3; /* EXCEPTION */ \ | ||||
| mf->v1 = mloop[l1].v; \ | mf->v1 = corner_verts[l1]; \ | ||||
| mf->v2 = mloop[l2].v; \ | mf->v2 = corner_verts[l2]; \ | ||||
| mf->v3 = mloop[l3].v; \ | mf->v3 = corner_verts[l3]; \ | ||||
| mf->v4 = mloop[l4].v; \ | mf->v4 = corner_verts[l4]; \ | ||||
| lidx[0] = l1; \ | lidx[0] = l1; \ | ||||
| lidx[1] = l2; \ | lidx[1] = l2; \ | ||||
| lidx[2] = l3; \ | lidx[2] = l3; \ | ||||
| lidx[3] = l4; \ | lidx[3] = l4; \ | ||||
| mf->mat_nr = material_indices ? material_indices[poly_index] : 0; \ | mf->mat_nr = material_indices ? material_indices[poly_index] : 0; \ | ||||
| mf->flag = mp->flag; \ | mf->flag = mp->flag; \ | ||||
| mf->edcode = TESSFACE_IS_QUAD; \ | mf->edcode = TESSFACE_IS_QUAD; \ | ||||
| (void)0 | (void)0 | ||||
| Show All 30 Lines | |||||
| } | } | ||||
| tris = (uint(*)[3])BLI_memarena_alloc(arena, sizeof(*tris) * size_t(totfilltri)); | tris = (uint(*)[3])BLI_memarena_alloc(arena, sizeof(*tris) * size_t(totfilltri)); | ||||
| projverts = (float(*)[2])BLI_memarena_alloc(arena, sizeof(*projverts) * size_t(mp_totloop)); | projverts = (float(*)[2])BLI_memarena_alloc(arena, sizeof(*projverts) * size_t(mp_totloop)); | ||||
| zero_v3(normal); | zero_v3(normal); | ||||
| /* Calculate the normal, flipped: to get a positive 2D cross product. */ | /* Calculate the normal, flipped: to get a positive 2D cross product. */ | ||||
| ml = mloop + mp_loopstart; | co_prev = positions[corner_verts[mp_loopstart + mp_totloop - 1]]; | ||||
| co_prev = positions[ml[mp_totloop - 1].v]; | for (j = 0; j < mp_totloop; j++) { | ||||
| for (j = 0; j < mp_totloop; j++, ml++) { | const int vert_i = corner_verts[mp_loopstart + j]; | ||||
| co_curr = positions[ml->v]; | co_curr = positions[vert_i]; | ||||
| add_newell_cross_v3_v3v3(normal, co_prev, co_curr); | add_newell_cross_v3_v3v3(normal, co_prev, co_curr); | ||||
| co_prev = co_curr; | co_prev = co_curr; | ||||
| } | } | ||||
| if (UNLIKELY(normalize_v3(normal) == 0.0f)) { | if (UNLIKELY(normalize_v3(normal) == 0.0f)) { | ||||
| normal[2] = 1.0f; | normal[2] = 1.0f; | ||||
| } | } | ||||
| /* Project verts to 2D. */ | /* Project verts to 2D. */ | ||||
| axis_dominant_v3_to_m3_negate(axis_mat, normal); | axis_dominant_v3_to_m3_negate(axis_mat, normal); | ||||
| ml = mloop + mp_loopstart; | for (j = 0; j < mp_totloop; j++) { | ||||
| for (j = 0; j < mp_totloop; j++, ml++) { | const int vert_i = corner_verts[mp_loopstart + j]; | ||||
| mul_v2_m3v3(projverts[j], axis_mat, positions[ml->v]); | mul_v2_m3v3(projverts[j], axis_mat, positions[vert_i]); | ||||
| } | } | ||||
| BLI_polyfill_calc_arena(projverts, mp_totloop, 1, tris, arena); | BLI_polyfill_calc_arena(projverts, mp_totloop, 1, tris, arena); | ||||
| /* Apply fill. */ | /* Apply fill. */ | ||||
| for (j = 0; j < totfilltri; j++) { | for (j = 0; j < totfilltri; j++) { | ||||
| uint *tri = tris[j]; | uint *tri = tris[j]; | ||||
| lidx = lindices[mface_index]; | lidx = lindices[mface_index]; | ||||
| mface_to_poly_map[mface_index] = poly_index; | mface_to_poly_map[mface_index] = poly_index; | ||||
| mf = &mface[mface_index]; | mf = &mface[mface_index]; | ||||
| /* Set loop indices, transformed to vert indices later. */ | /* Set loop indices, transformed to vert indices later. */ | ||||
| l1 = mp_loopstart + tri[0]; | l1 = mp_loopstart + tri[0]; | ||||
| l2 = mp_loopstart + tri[1]; | l2 = mp_loopstart + tri[1]; | ||||
| l3 = mp_loopstart + tri[2]; | l3 = mp_loopstart + tri[2]; | ||||
| mf->v1 = mloop[l1].v; | mf->v1 = corner_verts[l1]; | ||||
| mf->v2 = mloop[l2].v; | mf->v2 = corner_verts[l2]; | ||||
| mf->v3 = mloop[l3].v; | mf->v3 = corner_verts[l3]; | ||||
| mf->v4 = 0; | mf->v4 = 0; | ||||
| lidx[0] = l1; | lidx[0] = l1; | ||||
| lidx[1] = l2; | lidx[1] = l2; | ||||
| lidx[2] = l3; | lidx[2] = l3; | ||||
| lidx[3] = 0; | lidx[3] = 0; | ||||
| mf->mat_nr = material_indices ? material_indices[poly_index] : 0; | mf->mat_nr = material_indices ? material_indices[poly_index] : 0; | ||||
| ▲ Show 20 Lines • Show All 184 Lines • ▼ Show 20 Lines | |||||
| else if ((i = CustomData_get_named_layer_index(ldata, CD_PROP_COLOR, name)) != -1) { | else if ((i = CustomData_get_named_layer_index(ldata, CD_PROP_COLOR, name)) != -1) { | ||||
| CustomData_set_layer_render_index(ldata, CD_PROP_COLOR, i); | CustomData_set_layer_render_index(ldata, CD_PROP_COLOR, i); | ||||
| ldata->layers[i].flag |= CD_FLAG_COLOR_RENDER; | ldata->layers[i].flag |= CD_FLAG_COLOR_RENDER; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| /** \} */ | /** \} */ | ||||
| /* -------------------------------------------------------------------- */ | |||||
| /** \name Face Corner Conversion | |||||
| * \{ */ | |||||
| MLoop *BKE_mesh_legacy_convert_corners_to_loops( | |||||
| Mesh *mesh, | |||||
| blender::ResourceScope &temp_arrays_for_convert, | |||||
| blender::Vector<CustomDataLayer, 16> &loop_layers_to_write) | |||||
| { | |||||
| using namespace blender; | |||||
| const Span<int> corner_verts = mesh->corner_verts(); | |||||
| const Span<int> corner_edges = mesh->corner_edges(); | |||||
| CustomDataLayer mloop_layer{}; | |||||
| mloop_layer.type = CD_MLOOP; | |||||
| MutableSpan<MLoop> loops = temp_arrays_for_convert.construct<Array<MLoop>>(mesh->totloop); | |||||
| mloop_layer.data = loops.data(); | |||||
| threading::parallel_for(loops.index_range(), 2048, [&](IndexRange range) { | |||||
| for (const int i : range) { | |||||
| loops[i].v = corner_verts[i]; | |||||
| loops[i].e = corner_edges[i]; | |||||
| } | |||||
| }); | |||||
| loop_layers_to_write.append(mloop_layer); | |||||
| return loops.data(); | |||||
| } | |||||
| void BKE_mesh_legacy_convert_loops_to_corners(Mesh *mesh) | |||||
| { | |||||
| using namespace blender; | |||||
| if (CustomData_get_layer_named(&mesh->ldata, CD_PROP_INT32, ".corner_vert") && | |||||
| CustomData_get_layer_named(&mesh->ldata, CD_PROP_INT32, ".corner_edge")) { | |||||
| return; | |||||
| } | |||||
| const Span<MLoop> loops(static_cast<const MLoop *>(CustomData_get_layer(&mesh->ldata, CD_MLOOP)), | |||||
| mesh->totloop); | |||||
| MutableSpan<int> corner_verts( | |||||
| static_cast<int *>(CustomData_add_layer_named( | |||||
| &mesh->ldata, CD_PROP_INT32, CD_CONSTRUCT, nullptr, mesh->totloop, ".corner_vert")), | |||||
| mesh->totloop); | |||||
| MutableSpan<int> corner_edges( | |||||
| static_cast<int *>(CustomData_add_layer_named( | |||||
| &mesh->ldata, CD_PROP_INT32, CD_CONSTRUCT, nullptr, mesh->totloop, ".corner_edge")), | |||||
| mesh->totloop); | |||||
| threading::parallel_for(loops.index_range(), 2048, [&](IndexRange range) { | |||||
| for (const int i : range) { | |||||
| corner_verts[i] = loops[i].v; | |||||
| corner_edges[i] = loops[i].e; | |||||
| } | |||||
| }); | |||||
| CustomData_free_layers(&mesh->ldata, CD_MLOOP, mesh->totloop); | |||||
| } | |||||
| /** \} */ | |||||
| Context not available. | |||||