73fa7aa0e0d0f5d9998e214a2692b8eb042cb689
[blender.git] / source / blender / modifiers / intern / MOD_multires.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software  Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2005 by the Blender Foundation.
19  * All rights reserved.
20  *
21  * Contributor(s): Daniel Dunbar
22  *                 Ton Roosendaal,
23  *                 Ben Batt,
24  *                 Brecht Van Lommel,
25  *                 Campbell Barton
26  *
27  * ***** END GPL LICENSE BLOCK *****
28  *
29  */
30
31 /** \file blender/modifiers/intern/MOD_multires.c
32  *  \ingroup modifiers
33  */
34
35
36 #include <stddef.h>
37
38 #include "DNA_mesh_types.h"
39 #include "DNA_object_types.h"
40 #include "DNA_scene_types.h"
41
42 #include "BLI_utildefines.h"
43
44 #include "BKE_cdderivedmesh.h"
45 #include "BKE_global.h"
46 #include "BKE_mesh.h"
47 #include "BKE_multires.h"
48 #include "BKE_modifier.h"
49 #include "BKE_subdiv.h"
50 #include "BKE_subdiv_ccg.h"
51 #include "BKE_subdiv_mesh.h"
52 #include "BKE_subsurf.h"
53
54 #include "DEG_depsgraph_query.h"
55
56 #include "MOD_modifiertypes.h"
57
58 static void initData(ModifierData *md)
59 {
60         MultiresModifierData *mmd = (MultiresModifierData *)md;
61
62         mmd->lvl = 0;
63         mmd->sculptlvl = 0;
64         mmd->renderlvl = 0;
65         mmd->totlvl = 0;
66         mmd->uv_smooth = SUBSURF_UV_SMOOTH_PRESERVE_CORNERS;
67         mmd->quality = 3;
68 }
69
70 #ifndef WITH_OPENSUBDIV_MODIFIER
71
72 static DerivedMesh *applyModifier_DM(
73         ModifierData *md, const ModifierEvalContext *ctx,
74         DerivedMesh *dm)
75 {
76         MultiresModifierData *mmd = (MultiresModifierData *)md;
77         struct Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph);
78         DerivedMesh *result;
79         Mesh *me = (Mesh *)ctx->object->data;
80         const bool useRenderParams = (ctx->flag & MOD_APPLY_RENDER) != 0;
81         const bool ignore_simplify = (ctx->flag & MOD_APPLY_IGNORE_SIMPLIFY) != 0;
82         MultiresFlags flags = 0;
83         const bool has_mask = CustomData_has_layer(&me->ldata, CD_GRID_PAINT_MASK);
84
85         if (mmd->totlvl) {
86                 if (!CustomData_get_layer(&me->ldata, CD_MDISPS)) {
87                         /* multires always needs a displacement layer */
88                         CustomData_add_layer(&me->ldata, CD_MDISPS, CD_CALLOC, NULL, me->totloop);
89                 }
90         }
91
92         if (has_mask)
93                 flags |= MULTIRES_ALLOC_PAINT_MASK;
94
95         if (useRenderParams)
96                 flags |= MULTIRES_USE_RENDER_PARAMS;
97
98         if (ignore_simplify)
99                 flags |= MULTIRES_IGNORE_SIMPLIFY;
100
101         result = multires_make_derived_from_derived(dm, mmd, scene, ctx->object, flags);
102
103         if (result == dm)
104                 return dm;
105
106         if (useRenderParams || !(ctx->flag & MOD_APPLY_USECACHE)) {
107                 DerivedMesh *cddm;
108
109                 cddm = CDDM_copy(result);
110
111                 /* copy hidden/masks to vertices */
112                 if (!useRenderParams) {
113                         struct MDisps *mdisps;
114                         struct GridPaintMask *grid_paint_mask;
115
116                         mdisps = CustomData_get_layer(&me->ldata, CD_MDISPS);
117                         grid_paint_mask = CustomData_get_layer(&me->ldata, CD_GRID_PAINT_MASK);
118
119                         if (mdisps) {
120                                 subsurf_copy_grid_hidden(result, me->mpoly,
121                                                          cddm->getVertArray(cddm),
122                                                          mdisps);
123
124                                 BKE_mesh_flush_hidden_from_verts_ex(cddm->getVertArray(cddm),
125                                                                     cddm->getLoopArray(cddm),
126                                                                     cddm->getEdgeArray(cddm),
127                                                                     cddm->getNumEdges(cddm),
128                                                                     cddm->getPolyArray(cddm),
129                                                                     cddm->getNumPolys(cddm));
130                         }
131                         if (grid_paint_mask) {
132                                 float *paint_mask = CustomData_add_layer(&cddm->vertData,
133                                                                          CD_PAINT_MASK,
134                                                                          CD_CALLOC, NULL,
135                                                                          cddm->getNumVerts(cddm));
136
137                                 subsurf_copy_grid_paint_mask(result, me->mpoly,
138                                                              paint_mask, grid_paint_mask);
139                         }
140                 }
141
142                 result->release(result);
143                 result = cddm;
144         }
145
146         return result;
147 }
148
149 applyModifier_DM_wrapper(applyModifier, applyModifier_DM)
150
151 #endif
152
153 #ifdef WITH_OPENSUBDIV_MODIFIER
154
155 /* Subdivide into fully qualified mesh. */
156
157 static Mesh *multires_as_mesh(MultiresModifierData *mmd,
158                               const ModifierEvalContext *ctx,
159                               Mesh *mesh,
160                               Subdiv *subdiv)
161 {
162         Mesh *result = mesh;
163         const bool use_render_params = (ctx->flag & MOD_APPLY_RENDER);
164         const bool ignore_simplify = (ctx->flag & MOD_APPLY_IGNORE_SIMPLIFY);
165         const Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph);
166         Object *object = ctx->object;
167         SubdivToMeshSettings mesh_settings;
168         BKE_multires_subdiv_mesh_settings_init(
169         &mesh_settings, scene, object, mmd, use_render_params, ignore_simplify);
170         if (mesh_settings.resolution < 3) {
171                 return result;
172         }
173         BKE_subdiv_displacement_attach_from_multires(subdiv, mesh, mmd);
174         result = BKE_subdiv_to_mesh(subdiv, &mesh_settings, mesh);
175         return result;
176 }
177
178 /* Subdivide into CCG. */
179
180 static void multires_ccg_settings_init(SubdivToCCGSettings *settings,
181                                        const MultiresModifierData *mmd,
182                                        const ModifierEvalContext *ctx,
183                                        Mesh *mesh)
184 {
185         const bool has_mask =
186                 CustomData_has_layer(&mesh->ldata, CD_GRID_PAINT_MASK);
187         const bool use_render_params = (ctx->flag & MOD_APPLY_RENDER);
188         const bool ignore_simplify = (ctx->flag & MOD_APPLY_IGNORE_SIMPLIFY);
189         const Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph);
190         Object *object = ctx->object;
191         const int level = multires_get_level(
192                 scene, object, mmd, use_render_params, ignore_simplify);
193         settings->resolution = (1 << level) + 1;
194         settings->need_normal = true;
195         settings->need_mask = has_mask;
196 }
197
198 static Mesh *multires_as_ccg(MultiresModifierData *mmd,
199                              const ModifierEvalContext *ctx,
200                              Mesh *mesh,
201                              Subdiv *subdiv)
202 {
203         Mesh *result = mesh;
204         SubdivToCCGSettings ccg_settings;
205         multires_ccg_settings_init(&ccg_settings, mmd, ctx, mesh);
206         if (ccg_settings.resolution < 3) {
207                 return result;
208         }
209         BKE_subdiv_displacement_attach_from_multires(subdiv, mesh, mmd);
210         result = BKE_subdiv_to_ccg_mesh(subdiv, &ccg_settings, mesh);
211         return result;
212 }
213
214 static Mesh *applyModifier_subdiv(ModifierData *md,
215                                   const ModifierEvalContext *ctx,
216                                   Mesh *mesh)
217 {
218         Mesh *result = mesh;
219         MultiresModifierData *mmd = (MultiresModifierData *)md;
220         SubdivSettings subdiv_settings;
221         BKE_multires_subdiv_settings_init(&subdiv_settings, mmd);
222         if (subdiv_settings.level == 0) {
223                 return result;
224         }
225         /* TODO(sergey): Try to re-use subdiv when possible. */
226         Subdiv *subdiv = BKE_subdiv_new_from_mesh(&subdiv_settings, mesh);
227         if (subdiv == NULL) {
228                 /* Happens on bad topology, ut also on empty input mesh. */
229                 return result;
230         }
231         /* NOTE: Orco needs final coordinates on CPU side, which are expected to be
232          * accessible via MVert. For this reason we do not evaluate multires to
233          * grids when orco is requested.
234          */
235         const bool for_orco = (ctx->flag & MOD_APPLY_ORCO) != 0;
236         if ((ctx->object->mode & OB_MODE_SCULPT) && !for_orco) {
237                 /* NOTE: CCG takes ownership over Subdiv. */
238                 result = multires_as_ccg(mmd, ctx, mesh, subdiv);
239                 result->runtime.subdiv_ccg_tot_level = mmd->totlvl;
240                 // BKE_subdiv_stats_print(&subdiv->stats);
241         }
242         else {
243                 result = multires_as_mesh(mmd, ctx, mesh, subdiv);
244                 /* TODO(sergey): Cache subdiv somehow. */
245                 // BKE_subdiv_stats_print(&subdiv->stats);
246                 BKE_subdiv_free(subdiv);
247         }
248         return result;
249 }
250 #endif
251
252 ModifierTypeInfo modifierType_Multires = {
253         /* name */              "Multires",
254         /* structName */        "MultiresModifierData",
255         /* structSize */        sizeof(MultiresModifierData),
256         /* type */              eModifierTypeType_Constructive,
257         /* flags */             eModifierTypeFlag_AcceptsMesh |
258                                 eModifierTypeFlag_SupportsMapping |
259                                 eModifierTypeFlag_RequiresOriginalData,
260
261         /* copyData */          modifier_copyData_generic,
262
263         /* deformVerts_DM */    NULL,
264         /* deformMatrices_DM */ NULL,
265         /* deformVertsEM_DM */  NULL,
266         /* deformMatricesEM_DM*/NULL,
267         /* applyModifier_DM */  NULL,
268
269         /* deformVerts */       NULL,
270         /* deformMatrices */    NULL,
271         /* deformVertsEM */     NULL,
272         /* deformMatricesEM */  NULL,
273 #ifdef WITH_OPENSUBDIV_MODIFIER
274         /* applyModifier */     applyModifier_subdiv,
275 #else
276         /* applyModifier */     applyModifier,
277 #endif
278
279         /* initData */          initData,
280         /* requiredDataMask */  NULL,
281         /* freeData */          NULL,
282         /* isDisabled */        NULL,
283         /* updateDepsgraph */   NULL,
284         /* dependsOnTime */     NULL,
285         /* dependsOnNormals */  NULL,
286         /* foreachObjectLink */ NULL,
287         /* foreachIDLink */     NULL,
288         /* foreachTexLink */    NULL,
289 };