Merge branch 'blender2.7'
[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 static void freeData(ModifierData *md)
71 {
72         MultiresModifierData *mmd = (MultiresModifierData *) md;
73         if (mmd->subdiv != NULL) {
74                 BKE_subdiv_free(mmd->subdiv);
75         }
76 }
77
78 /* Main goal of this function is to give usable subdivision surface descriptor
79  * which matches settings and topology. */
80 static Subdiv *subdiv_descriptor_ensure(MultiresModifierData *mmd,
81                                         const SubdivSettings *subdiv_settings,
82                                         const Mesh *mesh)
83 {
84         Subdiv *subdiv = BKE_subdiv_update_from_mesh(
85                 mmd->subdiv, subdiv_settings, mesh);
86         if (false) {
87                 mmd->subdiv = subdiv;
88         }
89         return subdiv;
90 }
91
92 /* Subdivide into fully qualified mesh. */
93
94 static Mesh *multires_as_mesh(MultiresModifierData *mmd,
95                               const ModifierEvalContext *ctx,
96                               Mesh *mesh,
97                               Subdiv *subdiv)
98 {
99         Mesh *result = mesh;
100         const bool use_render_params = (ctx->flag & MOD_APPLY_RENDER);
101         const bool ignore_simplify = (ctx->flag & MOD_APPLY_IGNORE_SIMPLIFY);
102         const Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph);
103         Object *object = ctx->object;
104         SubdivToMeshSettings mesh_settings;
105         BKE_multires_subdiv_mesh_settings_init(
106         &mesh_settings, scene, object, mmd, use_render_params, ignore_simplify);
107         if (mesh_settings.resolution < 3) {
108                 return result;
109         }
110         BKE_subdiv_displacement_attach_from_multires(subdiv, mesh, mmd);
111         result = BKE_subdiv_to_mesh(subdiv, &mesh_settings, mesh);
112         return result;
113 }
114
115 /* Subdivide into CCG. */
116
117 static void multires_ccg_settings_init(SubdivToCCGSettings *settings,
118                                        const MultiresModifierData *mmd,
119                                        const ModifierEvalContext *ctx,
120                                        Mesh *mesh)
121 {
122         const bool has_mask =
123                 CustomData_has_layer(&mesh->ldata, CD_GRID_PAINT_MASK);
124         const bool use_render_params = (ctx->flag & MOD_APPLY_RENDER);
125         const bool ignore_simplify = (ctx->flag & MOD_APPLY_IGNORE_SIMPLIFY);
126         const Scene *scene = DEG_get_evaluated_scene(ctx->depsgraph);
127         Object *object = ctx->object;
128         const int level = multires_get_level(
129                 scene, object, mmd, use_render_params, ignore_simplify);
130         settings->resolution = (1 << level) + 1;
131         settings->need_normal = true;
132         settings->need_mask = has_mask;
133 }
134
135 static Mesh *multires_as_ccg(MultiresModifierData *mmd,
136                              const ModifierEvalContext *ctx,
137                              Mesh *mesh,
138                              Subdiv *subdiv)
139 {
140         Mesh *result = mesh;
141         SubdivToCCGSettings ccg_settings;
142         multires_ccg_settings_init(&ccg_settings, mmd, ctx, mesh);
143         if (ccg_settings.resolution < 3) {
144                 return result;
145         }
146         BKE_subdiv_displacement_attach_from_multires(subdiv, mesh, mmd);
147         result = BKE_subdiv_to_ccg_mesh(subdiv, &ccg_settings, mesh);
148         return result;
149 }
150
151 static Mesh *applyModifier(ModifierData *md,
152                            const ModifierEvalContext *ctx,
153                            Mesh *mesh)
154 {
155         Mesh *result = mesh;
156         MultiresModifierData *mmd = (MultiresModifierData *)md;
157         SubdivSettings subdiv_settings;
158         BKE_multires_subdiv_settings_init(&subdiv_settings, mmd);
159         if (subdiv_settings.level == 0) {
160                 return result;
161         }
162         BKE_subdiv_settings_validate_for_mesh(&subdiv_settings, mesh);
163         Subdiv *subdiv = subdiv_descriptor_ensure(mmd, &subdiv_settings, mesh);
164         if (subdiv == NULL) {
165                 /* Happens on bad topology, ut also on empty input mesh. */
166                 return result;
167         }
168         /* NOTE: Orco needs final coordinates on CPU side, which are expected to be
169          * accessible via MVert. For this reason we do not evaluate multires to
170          * grids when orco is requested. */
171         const bool for_orco = (ctx->flag & MOD_APPLY_ORCO) != 0;
172         if ((ctx->object->mode & OB_MODE_SCULPT) && !for_orco) {
173                 /* NOTE: CCG takes ownership over Subdiv. */
174                 result = multires_as_ccg(mmd, ctx, mesh, subdiv);
175                 result->runtime.subdiv_ccg_tot_level = mmd->totlvl;
176                 // BKE_subdiv_stats_print(&subdiv->stats);
177         }
178         else {
179                 result = multires_as_mesh(mmd, ctx, mesh, subdiv);
180                 // BKE_subdiv_stats_print(&subdiv->stats);
181                 if (subdiv != mmd->subdiv) {
182                         BKE_subdiv_free(subdiv);
183                 }
184         }
185         return result;
186 }
187
188 ModifierTypeInfo modifierType_Multires = {
189         /* name */              "Multires",
190         /* structName */        "MultiresModifierData",
191         /* structSize */        sizeof(MultiresModifierData),
192         /* type */              eModifierTypeType_Constructive,
193         /* flags */             eModifierTypeFlag_AcceptsMesh |
194                                 eModifierTypeFlag_SupportsMapping |
195                                 eModifierTypeFlag_RequiresOriginalData,
196
197         /* copyData */          modifier_copyData_generic,
198
199         /* deformVerts_DM */    NULL,
200         /* deformMatrices_DM */ NULL,
201         /* deformVertsEM_DM */  NULL,
202         /* deformMatricesEM_DM*/NULL,
203         /* applyModifier_DM */  NULL,
204
205         /* deformVerts */       NULL,
206         /* deformMatrices */    NULL,
207         /* deformVertsEM */     NULL,
208         /* deformMatricesEM */  NULL,
209         /* applyModifier */     applyModifier,
210
211         /* initData */          initData,
212         /* requiredDataMask */  NULL,
213         /* freeData */          freeData,
214         /* isDisabled */        NULL,
215         /* updateDepsgraph */   NULL,
216         /* dependsOnTime */     NULL,
217         /* dependsOnNormals */  NULL,
218         /* foreachObjectLink */ NULL,
219         /* foreachIDLink */     NULL,
220         /* foreachTexLink */    NULL,
221 };