Blender V5.0
multires_reshape_subdivide.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2020 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
9#include "DNA_mesh_types.h"
10#include "DNA_meshdata_types.h"
11#include "DNA_modifier_types.h"
12#include "DNA_object_types.h"
13
14#include "BKE_customdata.hh"
15#include "BKE_mesh.hh"
16#include "BKE_multires.hh"
17#include "BLI_math_vector.h"
18
19#include "multires_reshape.hh"
20
22{
23 using namespace blender;
24 using namespace blender::bke;
25 const Span<float3> positions = mesh->vert_positions();
26 const blender::OffsetIndices faces = mesh->faces();
27 const blender::Span<int> corner_verts = mesh->corner_verts();
28
29 MDisps *mdisps = static_cast<MDisps *>(
30 CustomData_get_layer_for_write(&mesh->corner_data, CD_MDISPS, mesh->corners_num));
31 for (const int p : faces.index_range()) {
32 const blender::IndexRange face = faces[p];
33 const float3 face_center = mesh::face_center_calc(positions, corner_verts.slice(face));
34 for (int l = 0; l < face.size(); l++) {
35 const int loop_index = face[l];
36
37 float (*disps)[3] = mdisps[loop_index].disps;
38 mdisps[loop_index].totdisp = 4;
39 mdisps[loop_index].level = 1;
40
41 int prev_loop_index = l - 1 >= 0 ? loop_index - 1 : loop_index + face.size() - 1;
42 int next_loop_index = l + 1 < face.size() ? loop_index + 1 : face.start();
43
44 const int vert = corner_verts[loop_index];
45 const int vert_next = corner_verts[next_loop_index];
46 const int vert_prev = corner_verts[prev_loop_index];
47
48 copy_v3_v3(disps[0], face_center);
49 mid_v3_v3v3(disps[1], positions[vert], positions[vert_next]);
50 mid_v3_v3v3(disps[2], positions[vert], positions[vert_prev]);
51 copy_v3_v3(disps[3], positions[vert]);
52 }
53 }
54}
55
58{
59 Mesh *coarse_mesh = static_cast<Mesh *>(object->data);
61
62 MultiresReshapeContext reshape_context;
63
64 const int new_top_level = mmd->totlvl + 1;
65
66 const bool has_mdisps = CustomData_has_layer(&coarse_mesh->corner_data, CD_MDISPS);
67 if (!has_mdisps) {
69 &coarse_mesh->corner_data, CD_MDISPS, CD_SET_DEFAULT, coarse_mesh->corners_num);
70 }
71
72 if (new_top_level == 1) {
73 /* No MDISPS. Create new grids for level 1 using the edges mid point and face centers. */
74 multires_reshape_ensure_grids(coarse_mesh, 1);
76 }
77
78 /* Convert the new grids to tangent displacement. */
79 multires_set_tot_level(object, mmd, new_top_level);
80
81 if (!multires_reshape_context_create_from_modifier(&reshape_context, object, mmd, new_top_level))
82 {
83 return;
84 }
85
87 multires_reshape_context_free(&reshape_context);
88}
CustomData interface, see also DNA_customdata_types.h.
@ CD_SET_DEFAULT
void * CustomData_get_layer_for_write(CustomData *data, eCustomDataType type, int totelem)
bool CustomData_has_layer(const CustomData *data, eCustomDataType type)
void * CustomData_add_layer(CustomData *data, eCustomDataType type, eCDAllocType alloctype, int totelem)
void multires_force_sculpt_rebuild(Object *object)
Definition multires.cc:327
void multires_set_tot_level(Object *ob, MultiresModifierData *mmd, int lvl)
Definition multires.cc:225
MINLINE void copy_v3_v3(float r[3], const float a[3])
void mid_v3_v3v3(float r[3], const float a[3], const float b[3])
Object is a sort of wrapper for general info.
ATTR_WARN_UNUSED_RESULT const BMLoop * l
constexpr int64_t size() const
constexpr int64_t start() const
constexpr Span slice(int64_t start, int64_t size) const
Definition BLI_span.hh:137
nullptr float
static char faces[256]
void multires_reshape_context_free(MultiresReshapeContext *reshape_context)
void multires_reshape_ensure_grids(Mesh *mesh, int level)
bool multires_reshape_context_create_from_modifier(MultiresReshapeContext *reshape_context, Object *object, MultiresModifierData *mmd, int top_level)
void multires_reshape_object_grids_to_tangent_displacement(const MultiresReshapeContext *reshape_context)
static void multires_subdivide_create_object_space_linear_grids(Mesh *mesh)
void multires_subdivide_create_tangent_displacement_linear_grids(Object *object, MultiresModifierData *mmd)
float3 face_center_calc(Span< float3 > vert_positions, Span< int > face_verts)
float(* disps)[3]
int corners_num
CustomData corner_data