Changeset View
Changeset View
Standalone View
Standalone View
source/blender/blenkernel/intern/mesh_mirror.cc
| Show First 20 Lines • Show All 92 Lines • ▼ Show 20 Lines | |||||
| int tot_vtargetmap = 0; /* total merge vertices */ | int tot_vtargetmap = 0; /* total merge vertices */ | ||||
| const bool do_bisect = ((axis == 0 && mmd->flag & MOD_MIR_BISECT_AXIS_X) || | const bool do_bisect = ((axis == 0 && mmd->flag & MOD_MIR_BISECT_AXIS_X) || | ||||
| (axis == 1 && mmd->flag & MOD_MIR_BISECT_AXIS_Y) || | (axis == 1 && mmd->flag & MOD_MIR_BISECT_AXIS_Y) || | ||||
| (axis == 2 && mmd->flag & MOD_MIR_BISECT_AXIS_Z)); | (axis == 2 && mmd->flag & MOD_MIR_BISECT_AXIS_Z)); | ||||
| Mesh *result; | Mesh *result; | ||||
| MEdge *me; | MEdge *me; | ||||
| MLoop *ml; | |||||
| MPoly *mp; | MPoly *mp; | ||||
| float mtx[4][4]; | float mtx[4][4]; | ||||
| float plane_co[3], plane_no[3]; | float plane_co[3], plane_no[3]; | ||||
| int i; | int i; | ||||
| int a, totshape; | int a, totshape; | ||||
| int *vtargetmap = nullptr, *vtmap_a = nullptr, *vtmap_b = nullptr; | int *vtargetmap = nullptr, *vtmap_a = nullptr, *vtmap_b = nullptr; | ||||
| /* mtx is the mirror transformation */ | /* mtx is the mirror transformation */ | ||||
| ▲ Show 20 Lines • Show All 69 Lines • ▼ Show 20 Lines | |||||
| memcpy(BKE_mesh_vert_positions_for_write(result), | memcpy(BKE_mesh_vert_positions_for_write(result), | ||||
| BKE_mesh_vert_positions(mesh), | BKE_mesh_vert_positions(mesh), | ||||
| sizeof(float[3]) * mesh->totvert); | sizeof(float[3]) * mesh->totvert); | ||||
| } | } | ||||
| if (!CustomData_has_layer(&mesh->edata, CD_MEDGE)) { | if (!CustomData_has_layer(&mesh->edata, CD_MEDGE)) { | ||||
| memcpy(BKE_mesh_edges_for_write(result), BKE_mesh_edges(mesh), sizeof(MEdge) * mesh->totedge); | memcpy(BKE_mesh_edges_for_write(result), BKE_mesh_edges(mesh), sizeof(MEdge) * mesh->totedge); | ||||
| } | } | ||||
| if (!CustomData_has_layer(&mesh->pdata, CD_MPOLY)) { | if (!CustomData_has_layer(&mesh->pdata, CD_MPOLY)) { | ||||
| memcpy(BKE_mesh_loops_for_write(result), BKE_mesh_loops(mesh), sizeof(MLoop) * mesh->totloop); | result->corner_verts_for_write().copy_from(mesh->corner_verts()); | ||||
| result->corner_edges_for_write().copy_from(mesh->corner_edges()); | |||||
| memcpy(BKE_mesh_polys_for_write(result), BKE_mesh_polys(mesh), sizeof(MPoly) * mesh->totpoly); | memcpy(BKE_mesh_polys_for_write(result), BKE_mesh_polys(mesh), sizeof(MPoly) * mesh->totpoly); | ||||
| } | } | ||||
| /* Copy custom-data to new geometry, | /* Copy custom-data to new geometry, | ||||
| * copy from itself because this data may have been created in the checks above. */ | * copy from itself because this data may have been created in the checks above. */ | ||||
| CustomData_copy_data(&result->vdata, &result->vdata, 0, maxVerts, maxVerts); | CustomData_copy_data(&result->vdata, &result->vdata, 0, maxVerts, maxVerts); | ||||
| CustomData_copy_data(&result->edata, &result->edata, 0, maxEdges, maxEdges); | CustomData_copy_data(&result->edata, &result->edata, 0, maxEdges, maxEdges); | ||||
| /* loops are copied later */ | /* loops are copied later */ | ||||
| ▲ Show 20 Lines • Show All 83 Lines • ▼ Show 20 Lines | |||||
| me = BKE_mesh_edges_for_write(result) + maxEdges; | me = BKE_mesh_edges_for_write(result) + maxEdges; | ||||
| for (i = 0; i < maxEdges; i++, me++) { | for (i = 0; i < maxEdges; i++, me++) { | ||||
| me->v1 += maxVerts; | me->v1 += maxVerts; | ||||
| me->v2 += maxVerts; | me->v2 += maxVerts; | ||||
| } | } | ||||
| /* adjust mirrored poly loopstart indices, and reverse loop order (normals) */ | /* adjust mirrored poly loopstart indices, and reverse loop order (normals) */ | ||||
| mp = BKE_mesh_polys_for_write(result) + maxPolys; | mp = BKE_mesh_polys_for_write(result) + maxPolys; | ||||
| ml = BKE_mesh_loops_for_write(result); | blender::MutableSpan<int> corner_edges = result->corner_edges_for_write(); | ||||
| for (i = 0; i < maxPolys; i++, mp++) { | for (i = 0; i < maxPolys; i++, mp++) { | ||||
| MLoop *ml2; | |||||
| int j, e; | int j, e; | ||||
| /* reverse the loop, but we keep the first vertex in the face the same, | /* reverse the loop, but we keep the first vertex in the face the same, | ||||
| * to ensure that quads are split the same way as on the other side */ | * to ensure that quads are split the same way as on the other side */ | ||||
| CustomData_copy_data( | CustomData_copy_data( | ||||
| &result->ldata, &result->ldata, mp->loopstart, mp->loopstart + maxLoops, 1); | &result->ldata, &result->ldata, mp->loopstart, mp->loopstart + maxLoops, 1); | ||||
| for (j = 1; j < mp->totloop; j++) { | for (j = 1; j < mp->totloop; j++) { | ||||
| CustomData_copy_data(&result->ldata, | CustomData_copy_data(&result->ldata, | ||||
| &result->ldata, | &result->ldata, | ||||
| mp->loopstart + j, | mp->loopstart + j, | ||||
| mp->loopstart + maxLoops + mp->totloop - j, | mp->loopstart + maxLoops + mp->totloop - j, | ||||
| 1); | 1); | ||||
| } | } | ||||
| ml2 = ml + mp->loopstart + maxLoops; | int *corner_edge_2 = &corner_edges[mp->loopstart + maxLoops]; | ||||
| e = ml2[0].e; | e = corner_edge_2[0]; | ||||
| for (j = 0; j < mp->totloop - 1; j++) { | for (j = 0; j < mp->totloop - 1; j++) { | ||||
| ml2[j].e = ml2[j + 1].e; | corner_edge_2[j] = corner_edge_2[j + 1]; | ||||
| } | } | ||||
| ml2[mp->totloop - 1].e = e; | corner_edge_2[mp->totloop - 1] = e; | ||||
| mp->loopstart += maxLoops; | mp->loopstart += maxLoops; | ||||
| } | } | ||||
| /* adjust mirrored loop vertex and edge indices */ | /* adjust mirrored loop vertex and edge indices */ | ||||
| ml = BKE_mesh_loops_for_write(result) + maxLoops; | blender::MutableSpan<int> corner_verts = result->corner_verts_for_write(); | ||||
| for (i = 0; i < maxLoops; i++, ml++) { | for (i = 0; i < maxLoops; i++) { | ||||
| ml->v += maxVerts; | corner_verts[maxLoops + i] += maxVerts; | ||||
| ml->e += maxEdges; | corner_edges[maxLoops + i] += maxEdges; | ||||
| } | } | ||||
| /* handle uvs, | /* handle uvs, | ||||
| * let tessface recalc handle updating the MTFace data */ | * let tessface recalc handle updating the MTFace data */ | ||||
| if (mmd->flag & (MOD_MIR_MIRROR_U | MOD_MIR_MIRROR_V) || | if (mmd->flag & (MOD_MIR_MIRROR_U | MOD_MIR_MIRROR_V) || | ||||
| (is_zero_v2(mmd->uv_offset_copy) == false)) { | (is_zero_v2(mmd->uv_offset_copy) == false)) { | ||||
| const bool do_mirr_u = (mmd->flag & MOD_MIR_MIRROR_U) != 0; | const bool do_mirr_u = (mmd->flag & MOD_MIR_MIRROR_U) != 0; | ||||
| const bool do_mirr_v = (mmd->flag & MOD_MIR_MIRROR_V) != 0; | const bool do_mirr_v = (mmd->flag & MOD_MIR_MIRROR_V) != 0; | ||||
| ▲ Show 20 Lines • Show All 54 Lines • ▼ Show 20 Lines | |||||
| const bool *sharp_edges = static_cast<const bool *>( | const bool *sharp_edges = static_cast<const bool *>( | ||||
| CustomData_get_layer_named(&mesh->edata, CD_PROP_BOOL, "sharp_edge")); | CustomData_get_layer_named(&mesh->edata, CD_PROP_BOOL, "sharp_edge")); | ||||
| BKE_mesh_normals_loop_split(BKE_mesh_vert_positions(result), | BKE_mesh_normals_loop_split(BKE_mesh_vert_positions(result), | ||||
| BKE_mesh_vertex_normals_ensure(result), | BKE_mesh_vertex_normals_ensure(result), | ||||
| result->totvert, | result->totvert, | ||||
| BKE_mesh_edges(result), | BKE_mesh_edges(result), | ||||
| result->totedge, | result->totedge, | ||||
| BKE_mesh_loops(result), | result->corner_verts().data(), | ||||
| result->corner_edges().data(), | |||||
| loop_normals, | loop_normals, | ||||
| totloop, | totloop, | ||||
| BKE_mesh_polys(result), | BKE_mesh_polys(result), | ||||
| BKE_mesh_poly_normals_ensure(result), | BKE_mesh_poly_normals_ensure(result), | ||||
| totpoly, | totpoly, | ||||
| true, | true, | ||||
| mesh->smoothresh, | mesh->smoothresh, | ||||
| sharp_edges, | sharp_edges, | ||||
| ▲ Show 20 Lines • Show All 57 Lines • ▼ Show 20 Lines | |||||
| result, vtargetmap, tot_vtargetmap, MESH_MERGE_VERTS_DUMP_IF_MAPPED); | result, vtargetmap, tot_vtargetmap, MESH_MERGE_VERTS_DUMP_IF_MAPPED); | ||||
| } | } | ||||
| MEM_freeN(vtargetmap); | MEM_freeN(vtargetmap); | ||||
| } | } | ||||
| if (mesh_bisect != nullptr) { | if (mesh_bisect != nullptr) { | ||||
| BKE_id_free(nullptr, mesh_bisect); | BKE_id_free(nullptr, mesh_bisect); | ||||
| } | } | ||||
| return result; | return result; | ||||
| } | } | ||||
| Context not available. | |||||