Blender  V2.93
multires_reshape.h
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2020 Blender Foundation.
17  * All rights reserved.
18  */
19 
24 #pragma once
25 
26 #include "BLI_sys_types.h"
27 
28 #include "BKE_multires.h"
29 
30 struct Depsgraph;
31 struct GridPaintMask;
32 struct MDisps;
33 struct Mesh;
35 struct Object;
36 struct Subdiv;
37 struct SubdivCCG;
38 
39 typedef struct MultiresReshapeContext {
40  /* NOTE: Only available when context is initialized from object. */
42  struct Object *object;
43 
45 
46  /* Base mesh from original object.
47  * NOTE: Does NOT include any leading modifiers in it. */
48  struct Mesh *base_mesh;
49 
50  /* Subdivision surface created for multires modifier.
51  *
52  * The coarse mesh of this subdivision surface is a base mesh with all deformation modifiers
53  * leading multires applied on it. */
54  struct Subdiv *subdiv;
56 
57  struct {
58  /* Level at which displacement is being assigned to.
59  * It will be propagated up from this level to top.level. */
60  int level;
61 
62  /* Grid size for reshape.level. */
63  int grid_size;
65 
66  struct {
67  /* Top level of the displacement grids.
68  * The displacement will be propagated up to this level. */
69  int level;
70 
71  /* Grid size for top.level. */
72  int grid_size;
73  } top;
74 
75  struct {
76  /* Copy of original displacement and painting masks. */
77  struct MDisps *mdisps;
79  } orig;
80 
81  /* Number of grids which are required for base_mesh. */
82  int num_grids;
83 
84  /* Destination displacement and mask.
85  * Points to a custom data on a destination mesh. */
86  struct MDisps *mdisps;
88 
89  /* Indexed by face index, gives first grid index of the face. */
91 
92  /* Indexed by grid index, contains face (poly) index in the base mesh from which the grid has
93  * been created (in other words, index of a poly which contains loop corresponding to the grid
94  * index). */
96 
97  /* Indexed by ptex face index, gives first grid index of the ptex face.
98  *
99  * For non-quad base faces ptex face is created for every face corner, so it's similar to a
100  * grid in this case. In this case start grid index will be the only one for this ptex face.
101  *
102  * For quad base faces there is a single ptex face but 4 grids. So in this case there will be
103  * 4 grids for the ptex, starting at a value stored in this mapping. */
105 
106  /* Indexed by base face index, returns first ptex face index corresponding
107  * to that base face. */
110 
115 typedef struct GridCoord {
117  float u, v;
119 
123 typedef struct PTexCoord {
125  float u, v;
127 
132 typedef struct ReshapeGridElement {
133  float *displacement;
134  float *mask;
136 
137 typedef struct ReshapeConstGridElement {
138  float displacement[3];
139  float mask;
141 
142 /* --------------------------------------------------------------------
143  * Construct/destruct reshape context.
144  */
145 
146 /* Create subdivision surface descriptor which is configured for surface evaluation at a given
147  * multires modifier. */
149  struct Object *object,
150  const struct MultiresModifierData *mmd);
151 
152 /* NOTE: Initialized base mesh to object's mesh, the Subdiv is created from the deformed
153  * mesh prior to the multires modifier if depsgraph is not NULL. If the depsgraph is NULL
154  * then Subdiv is created from base mesh (without any deformation applied). */
156  struct Depsgraph *depsgraph,
157  struct Object *object,
158  struct MultiresModifierData *mmd);
159 
161  struct Depsgraph *depsgraph,
162  struct Object *object,
163  struct MultiresModifierData *mmd);
164 
166  struct SubdivCCG *subdiv_ccg,
167  struct Mesh *base_mesh,
168  int top_level);
169 
171  struct Object *object,
172  struct MultiresModifierData *mmd,
173  int top_level);
174 
176  struct Object *object,
177  struct MultiresModifierData *mmd,
178  struct Subdiv *subdiv,
179  int top_level);
180 
183 
184 /* --------------------------------------------------------------------
185  * Helper accessors.
186  */
187 
188 /* For the given grid index get index of face it was created for. */
190  int grid_index);
191 
192 /* For the given grid index get corner of a face it was created for. */
193 int multires_reshape_grid_to_corner(const MultiresReshapeContext *reshape_context, int grid_index);
194 
195 bool multires_reshape_is_quad_face(const MultiresReshapeContext *reshape_context, int face_index);
196 
197 /* For the given grid index get index of corresponding ptex face. */
199  int grid_index);
200 
201 /* Convert normalized coordinate within a grid to a normalized coordinate within a ptex face. */
203  const GridCoord *grid_coord);
204 
205 /* Convert a normalized coordinate within a ptex face to a normalized coordinate within a grid. */
207  const PTexCoord *ptex_coord);
208 
209 /* Calculate tangent matrix which converts displacement to a object vector.
210  * Is calculated for the given surface derivatives at a given base face corner. */
212  const int face_index,
213  const int corner,
214  const float dPdu[3],
215  const float dPdv[3],
216  float r_tangent_matrix[3][3]);
217 
218 /* Get grid elements which are to be reshaped at a given or ptex coordinate.
219  * The data is coming from final custom mdata layers. */
221  const MultiresReshapeContext *reshape_context, const GridCoord *grid_coord);
223  const MultiresReshapeContext *reshape_context, const PTexCoord *ptex_coord);
224 
225 /* Get original grid element for the given coordinate. */
227  const MultiresReshapeContext *reshape_context, const GridCoord *grid_coord);
228 
229 /* --------------------------------------------------------------------
230  * Sample limit surface of the base mesh.
231  */
232 
233 /* Evaluate limit surface created from base mesh.
234  * This is the limit surface which defines tangent space for MDisps. */
236  const GridCoord *grid_coord,
237  float r_P[3],
238  float r_tangent_matrix[3][3]);
239 
240 /* --------------------------------------------------------------------
241  * Custom data preparation.
242  */
243 
244 /* Make sure custom data is allocated for the given level. */
245 void multires_reshape_ensure_grids(struct Mesh *mesh, const int level);
246 
247 /* --------------------------------------------------------------------
248  * Functions specific to reshaping from a set of vertices in a object position.
249  */
250 
251 /* Returns truth if all coordinates were assigned.
252  *
253  * False will be returned if the number of vertex coordinates did not match required number of
254  * vertices at a reshape level. */
256  const MultiresReshapeContext *reshape_context,
257  const float (*vert_coords)[3],
258  const int num_vert_coords);
259 
260 /* --------------------------------------------------------------------
261  * Functions specific to reshaping from CCG.
262  */
263 
264 /* Store final object-space coordinates in the displacement grids.
265  * The reason why displacement grids are used for storage is based on memory
266  * footprint optimization.
267  *
268  * NOTE: Displacement grids to be at least at a reshape level.
269  *
270  * Return truth if all coordinates have been updated. */
272  struct SubdivCCG *subdiv_ccg);
273 
274 /* --------------------------------------------------------------------
275  * Functions specific to reshaping from MDISPS.
276  */
277 
278 /* Reads and writes to the current mesh CD_MDISPS. */
280  const MultiresReshapeContext *reshape_context);
281 
282 /* Reads from original CD_MIDTSPS, writes to the current mesh CD_MDISPS. */
284  const MultiresReshapeContext *reshape_context);
285 
286 /* --------------------------------------------------------------------
287  * Displacement smooth.
288  */
289 
290 /* Operates on a displacement grids (CD_MDISPS) which contains object space coordinates stored for
291  * the reshape level.
292  *
293  * The result is grids which are defining mesh with a smooth surface and details starting from
294  * reshape level up to top level added back from original displacement grids. */
296  const MultiresReshapeContext *reshape_context);
297 
298 /* Operates on a displacement grids (CD_MDISPS) which contains object space-coordinates stored for
299  * the reshape level.
300  *
301  * Makes it so surface on top level looks smooth. Details are not preserved
302  */
304  const enum eMultiresSubdivideModeType mode);
305 
306 /* --------------------------------------------------------------------
307  * Displacement, space conversion.
308  */
309 
310 /* Store original grid data, so then it's possible to calculate delta from it and add
311  * high-frequency content on top of reshaped grids. */
313 
315  const MultiresReshapeContext *reshape_context);
316 
317 /* --------------------------------------------------------------------
318  * Apply base.
319  */
320 
321 /* Update mesh coordinates to the final positions of displacement in object space.
322  * This is effectively desired position of base mesh vertices after canceling out displacement.
323  *
324  * NOTE: Expects that mesh's CD_MDISPS has been set to object space positions. */
326 
327 /* Perform better fitting of the base mesh so its subdivided version brings vertices to their
328  * desired locations. */
330 
331 /* Refine subdivision surface to the new positions of the base mesh. */
333 
334 /* Refine subdivision surface to the new positions of the deformed mesh (base mesh with all
335  * modifiers leading the multires applied).
336  *
337  * NOTE: Will re-evaluate all leading modifiers, so it's not cheap. */
eMultiresSubdivideModeType
Definition: BKE_multires.h:171
struct Depsgraph Depsgraph
Definition: DEG_depsgraph.h:51
const Depsgraph * depsgraph
int multires_reshape_grid_to_face_index(const MultiresReshapeContext *reshape_context, int grid_index)
struct MultiresReshapeContext MultiresReshapeContext
void multires_reshape_assign_final_elements_from_orig_mdisps(const MultiresReshapeContext *reshape_context)
struct ReshapeConstGridElement ReshapeConstGridElement
bool multires_reshape_is_quad_face(const MultiresReshapeContext *reshape_context, int face_index)
void multires_reshape_smooth_object_grids_with_details(const MultiresReshapeContext *reshape_context)
void multires_reshape_assign_final_coords_from_mdisps(const MultiresReshapeContext *reshape_context)
void multires_reshape_apply_base_refit_base_mesh(MultiresReshapeContext *reshape_context)
ReshapeGridElement multires_reshape_grid_element_for_grid_coord(const MultiresReshapeContext *reshape_context, const GridCoord *grid_coord)
int multires_reshape_grid_to_ptex_index(const MultiresReshapeContext *reshape_context, int grid_index)
PTexCoord multires_reshape_grid_coord_to_ptex(const MultiresReshapeContext *reshape_context, const GridCoord *grid_coord)
void multires_reshape_ensure_grids(struct Mesh *mesh, const int level)
void multires_reshape_smooth_object_grids(const MultiresReshapeContext *reshape_context, const enum eMultiresSubdivideModeType mode)
void multires_reshape_context_free(MultiresReshapeContext *reshape_context)
void multires_reshape_store_original_grids(MultiresReshapeContext *reshape_context)
bool multires_reshape_context_create_from_base_mesh(MultiresReshapeContext *reshape_context, struct Depsgraph *depsgraph, struct Object *object, struct MultiresModifierData *mmd)
void multires_reshape_apply_base_refine_from_base(MultiresReshapeContext *reshape_context)
int multires_reshape_grid_to_corner(const MultiresReshapeContext *reshape_context, int grid_index)
void multires_reshape_tangent_matrix_for_corner(const MultiresReshapeContext *reshape_context, const int face_index, const int corner, const float dPdu[3], const float dPdv[3], float r_tangent_matrix[3][3])
bool multires_reshape_context_create_from_modifier(MultiresReshapeContext *reshape_context, struct Object *object, struct MultiresModifierData *mmd, int top_level)
bool multires_reshape_context_create_from_ccg(MultiresReshapeContext *reshape_context, struct SubdivCCG *subdiv_ccg, struct Mesh *base_mesh, int top_level)
void multires_reshape_free_original_grids(MultiresReshapeContext *reshape_context)
bool multires_reshape_context_create_from_object(MultiresReshapeContext *reshape_context, struct Depsgraph *depsgraph, struct Object *object, struct MultiresModifierData *mmd)
bool multires_reshape_context_create_from_subdiv(MultiresReshapeContext *reshape_context, struct Object *object, struct MultiresModifierData *mmd, struct Subdiv *subdiv, int top_level)
void multires_reshape_apply_base_update_mesh_coords(MultiresReshapeContext *reshape_context)
void multires_reshape_object_grids_to_tangent_displacement(const MultiresReshapeContext *reshape_context)
ReshapeConstGridElement multires_reshape_orig_grid_element_for_grid_coord(const MultiresReshapeContext *reshape_context, const GridCoord *grid_coord)
ReshapeGridElement multires_reshape_grid_element_for_ptex_coord(const MultiresReshapeContext *reshape_context, const PTexCoord *ptex_coord)
struct ReshapeGridElement ReshapeGridElement
GridCoord multires_reshape_ptex_coord_to_grid(const MultiresReshapeContext *reshape_context, const PTexCoord *ptex_coord)
bool multires_reshape_assign_final_coords_from_vertcos(const MultiresReshapeContext *reshape_context, const float(*vert_coords)[3], const int num_vert_coords)
struct PTexCoord PTexCoord
struct Subdiv * multires_reshape_create_subdiv(struct Depsgraph *depsgraph, struct Object *object, const struct MultiresModifierData *mmd)
void multires_reshape_apply_base_refine_from_deform(MultiresReshapeContext *reshape_context)
void multires_reshape_evaluate_limit_at_grid(const MultiresReshapeContext *reshape_context, const GridCoord *grid_coord, float r_P[3], float r_tangent_matrix[3][3])
struct GridCoord GridCoord
bool multires_reshape_assign_final_coords_from_ccg(const MultiresReshapeContext *reshape_context, struct SubdivCCG *subdiv_ccg)
struct MultiresReshapeContext::@101 orig
struct GridPaintMask * grid_paint_masks
struct MultiresModifierData * mmd
struct MultiresReshapeContext::@99 reshape
struct MDisps * mdisps
struct Object * object
struct Depsgraph * depsgraph
struct MultiresReshapeContext::@100 top
struct Subdiv * subdiv