af17bd7d53c2974f11a0a30f02a011c9cfdb00c5
[blender.git] / source / blender / modifiers / intern / MOD_multires.c
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) 2005 by the Blender Foundation.
17  * All rights reserved.
18  */
19
20 /** \file
21  * \ingroup modifiers
22  */
23
24
25 #include <stddef.h>
26
27 #include "MEM_guardedalloc.h"
28
29 #include "BLI_utildefines.h"
30
31 #include "DNA_mesh_types.h"
32 #include "DNA_object_types.h"
33 #include "DNA_scene_types.h"
34
35 #include "BKE_cdderivedmesh.h"
36 #include "BKE_mesh.h"
37 #include "BKE_multires.h"
38 #include "BKE_modifier.h"
39 #include "BKE_paint.h"
40 #include "BKE_subdiv.h"
41 #include "BKE_subdiv_ccg.h"
42 #include "BKE_subdiv_mesh.h"
43 #include "BKE_subsurf.h"
44
45 #include "DEG_depsgraph_query.h"
46
47 #include "MOD_modifiertypes.h"
48
49 typedef struct MultiresRuntimeData {
50         /* Cached subdivision surface descriptor, with topology and settings. */
51         struct Subdiv *subdiv;
52 } MultiresRuntimeData;
53
54 static void initData(ModifierData *md)
55 {
56         MultiresModifierData *mmd = (MultiresModifierData *)md;
57
58         mmd->lvl = 0;
59         mmd->sculptlvl = 0;
60         mmd->renderlvl = 0;
61         mmd->totlvl = 0;
62         mmd->uv_smooth = SUBSURF_UV_SMOOTH_PRESERVE_CORNERS;
63         mmd->quality = 3;
64 }
65
66 static void copyData(const ModifierData *md_src, ModifierData *md_dst, const int flag)
67 {
68         modifier_copyData_generic(md_src, md_dst, flag);
69 }
70
71 static void freeRuntimeData(void *runtime_data_v)
72 {
73         if (runtime_data_v == NULL) {
74                 return;
75         }
76         MultiresRuntimeData *runtime_data = (MultiresRuntimeData *)runtime_data_v;
77         if (runtime_data->subdiv != NULL) {
78                 BKE_subdiv_free(runtime_data->subdiv);
79         }
80         MEM_freeN(runtime_data);
81 }
82
83 static void freeData(ModifierData *md)
84 {
85         MultiresModifierData *mmd = (MultiresModifierData *) md;
86         freeRuntimeData(mmd->modifier.runtime);
87 }
88
89 static MultiresRuntimeData *multires_ensure_runtime(MultiresModifierData *mmd)
90 {
91         MultiresRuntimeData *runtime_data =
92                 (MultiresRuntimeData *)mmd->modifier.runtime;
93         if (runtime_data == NULL) {
94                 runtime_data = MEM_callocN(sizeof(*runtime_data), "subsurf runtime");
95                 mmd->modifier.runtime = runtime_data;
96         }
97         return runtime_data;
98 }
99
100 /* Main goal of this function is to give usable subdivision surface descriptor
101  * which matches settings and topology. */
102 static Subdiv *subdiv_descriptor_ensure(MultiresModifierData *mmd,
103                                         const SubdivSettings *subdiv_settings,
104                                         const Mesh *mesh)
105 {
106         MultiresRuntimeData *runtime_data =
107                 (MultiresRuntimeData *)mmd->modifier.runtime;
108         Subdiv *subdiv = BKE_subdiv_update_from_mesh(
109                 runtime_data->subdiv, subdiv_settings, mesh);
110         runtime_data->subdiv = subdiv;
111         return subdiv;
112 }
113
114 /* Subdivide into fully qualified mesh. */
115
116 static Mesh *multires_as_mesh(MultiresModifierData *mmd,
117                               const ModifierEvalContext *ctx,
118                               Mesh *mesh,
119                               Subdiv *subdiv)
120 {
121         Mesh *result = mesh;
122         const bool use_render_params = (ctx->flag & MOD_APPLY_RENDER);
123         const bool ignore_simplify = (ctx->flag & MOD_APPLY_IGNORE_SIMPLIFY);
124         const Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph);
125         Object *object = ctx->object;
126         SubdivToMeshSettings mesh_settings;
127         BKE_multires_subdiv_mesh_settings_init(
128                 &mesh_settings, scene, object, mmd, use_render_params, ignore_simplify);
129         if (mesh_settings.resolution < 3) {
130                 return result;
131         }
132         BKE_subdiv_displacement_attach_from_multires(subdiv, mesh, mmd);
133         result = BKE_subdiv_to_mesh(subdiv, &mesh_settings, mesh);
134         return result;
135 }
136
137 /* Subdivide into CCG. */
138
139 static void multires_ccg_settings_init(SubdivToCCGSettings *settings,
140                                        const MultiresModifierData *mmd,
141                                        const ModifierEvalContext *ctx,
142                                        Mesh *mesh)
143 {
144         const bool has_mask =
145                 CustomData_has_layer(&mesh->ldata, CD_GRID_PAINT_MASK);
146         const bool use_render_params = (ctx->flag & MOD_APPLY_RENDER);
147         const bool ignore_simplify = (ctx->flag & MOD_APPLY_IGNORE_SIMPLIFY);
148         const Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph);
149         Object *object = ctx->object;
150         const int level = multires_get_level(
151                 scene, object, mmd, use_render_params, ignore_simplify);
152         settings->resolution = (1 << level) + 1;
153         settings->need_normal = true;
154         settings->need_mask = has_mask;
155 }
156
157 static Mesh *multires_as_ccg(MultiresModifierData *mmd,
158                              const ModifierEvalContext *ctx,
159                              Mesh *mesh,
160                              Subdiv *subdiv)
161 {
162         Mesh *result = mesh;
163         SubdivToCCGSettings ccg_settings;
164         multires_ccg_settings_init(&ccg_settings, mmd, ctx, mesh);
165         if (ccg_settings.resolution < 3) {
166                 return result;
167         }
168         BKE_subdiv_displacement_attach_from_multires(subdiv, mesh, mmd);
169         result = BKE_subdiv_to_ccg_mesh(subdiv, &ccg_settings, mesh);
170         return result;
171 }
172
173 static Mesh *applyModifier(ModifierData *md,
174                            const ModifierEvalContext *ctx,
175                            Mesh *mesh)
176 {
177         Mesh *result = mesh;
178         MultiresModifierData *mmd = (MultiresModifierData *)md;
179         SubdivSettings subdiv_settings;
180         BKE_multires_subdiv_settings_init(&subdiv_settings, mmd);
181         if (subdiv_settings.level == 0) {
182                 return result;
183         }
184         BKE_subdiv_settings_validate_for_mesh(&subdiv_settings, mesh);
185         MultiresRuntimeData *runtime_data = multires_ensure_runtime(mmd);
186         Subdiv *subdiv = subdiv_descriptor_ensure(mmd, &subdiv_settings, mesh);
187         if (subdiv == NULL) {
188                 /* Happens on bad topology, ut also on empty input mesh. */
189                 return result;
190         }
191         /* NOTE: Orco needs final coordinates on CPU side, which are expected to be
192          * accessible via MVert. For this reason we do not evaluate multires to
193          * grids when orco is requested. */
194         const bool for_orco = (ctx->flag & MOD_APPLY_ORCO) != 0;
195         if ((ctx->object->mode & OB_MODE_SCULPT) && !for_orco) {
196                 /* NOTE: CCG takes ownership over Subdiv. */
197                 result = multires_as_ccg(mmd, ctx, mesh, subdiv);
198                 result->runtime.subdiv_ccg_tot_level = mmd->totlvl;
199                 /* TODO(sergey): Usually it is sculpt stroke's update variants which
200                  * takes care of this, but is possible that we need this before the
201                  * stroke: i.e. when exiting blender right after stroke is done.
202                  * Annoying and not so much black-boxed as far as sculpting goes, and
203                  * surely there is a better way of solving this. */
204                 if (ctx->object->sculpt != NULL) {
205                         ctx->object->sculpt->subdiv_ccg = result->runtime.subdiv_ccg;
206                 }
207                 /* NOTE: CCG becomes an owner of Subdiv descriptor, so can not share
208                  * this pointer. Not sure if it's needed, but might have a second look
209                  * on the ownership model here. */
210                 runtime_data->subdiv = NULL;
211                 // BKE_subdiv_stats_print(&subdiv->stats);
212         }
213         else {
214                 result = multires_as_mesh(mmd, ctx, mesh, subdiv);
215                 // BKE_subdiv_stats_print(&subdiv->stats);
216                 if (subdiv != runtime_data->subdiv) {
217                         BKE_subdiv_free(subdiv);
218                 }
219         }
220         return result;
221 }
222
223 ModifierTypeInfo modifierType_Multires = {
224         /* name */              "Multires",
225         /* structName */        "MultiresModifierData",
226         /* structSize */        sizeof(MultiresModifierData),
227         /* type */              eModifierTypeType_Constructive,
228         /* flags */             eModifierTypeFlag_AcceptsMesh |
229                                 eModifierTypeFlag_SupportsMapping |
230                                 eModifierTypeFlag_RequiresOriginalData,
231
232         /* copyData */          copyData,
233
234         /* deformVerts */       NULL,
235         /* deformMatrices */    NULL,
236         /* deformVertsEM */     NULL,
237         /* deformMatricesEM */  NULL,
238         /* applyModifier */     applyModifier,
239
240         /* initData */          initData,
241         /* requiredDataMask */  NULL,
242         /* freeData */          freeData,
243         /* isDisabled */        NULL,
244         /* updateDepsgraph */   NULL,
245         /* dependsOnTime */     NULL,
246         /* dependsOnNormals */  NULL,
247         /* foreachObjectLink */ NULL,
248         /* foreachIDLink */     NULL,
249         /* foreachTexLink */    NULL,
250         /* freeRuntimeData */   freeRuntimeData,
251 };