Merge branch 'master' into blender2.8
[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
41 #include "BLI_utildefines.h"
42
43 #include "BKE_cdderivedmesh.h"
44 #include "BKE_mesh.h"
45 #include "BKE_multires.h"
46 #include "BKE_modifier.h"
47 #include "BKE_subsurf.h"
48
49 #include "MOD_modifiertypes.h"
50
51 static void initData(ModifierData *md)
52 {
53         MultiresModifierData *mmd = (MultiresModifierData *)md;
54
55         mmd->lvl = 0;
56         mmd->sculptlvl = 0;
57         mmd->renderlvl = 0;
58         mmd->totlvl = 0;
59 }
60
61 static DerivedMesh *applyModifier(ModifierData *md, const ModifierEvalContext *ctx,
62                                   DerivedMesh *dm)
63 {
64         MultiresModifierData *mmd = (MultiresModifierData *)md;
65         DerivedMesh *result;
66         Mesh *me = (Mesh *)ctx->object->data;
67         const bool useRenderParams = (ctx->flag & MOD_APPLY_RENDER) != 0;
68         const bool ignore_simplify = (ctx->flag & MOD_APPLY_IGNORE_SIMPLIFY) != 0;
69         MultiresFlags flags = 0;
70         const bool has_mask = CustomData_has_layer(&me->ldata, CD_GRID_PAINT_MASK);
71
72         if (mmd->totlvl) {
73                 if (!CustomData_get_layer(&me->ldata, CD_MDISPS)) {
74                         /* multires always needs a displacement layer */
75                         CustomData_add_layer(&me->ldata, CD_MDISPS, CD_CALLOC, NULL, me->totloop);
76                 }
77         }
78
79         if (has_mask)
80                 flags |= MULTIRES_ALLOC_PAINT_MASK;
81
82         if (useRenderParams)
83                 flags |= MULTIRES_USE_RENDER_PARAMS;
84
85         if (ignore_simplify)
86                 flags |= MULTIRES_IGNORE_SIMPLIFY;
87
88         result = multires_make_derived_from_derived(dm, mmd, ctx->object, flags);
89
90         if (result == dm)
91                 return dm;
92
93         if (useRenderParams || !(ctx->flag & MOD_APPLY_USECACHE)) {
94                 DerivedMesh *cddm;
95                 
96                 cddm = CDDM_copy(result);
97
98                 /* copy hidden/masks to vertices */
99                 if (!useRenderParams) {
100                         struct MDisps *mdisps;
101                         struct GridPaintMask *grid_paint_mask;
102                         
103                         mdisps = CustomData_get_layer(&me->ldata, CD_MDISPS);
104                         grid_paint_mask = CustomData_get_layer(&me->ldata, CD_GRID_PAINT_MASK);
105                         
106                         if (mdisps) {
107                                 subsurf_copy_grid_hidden(result, me->mpoly,
108                                                          cddm->getVertArray(cddm),
109                                                          mdisps);
110
111                                 BKE_mesh_flush_hidden_from_verts_ex(cddm->getVertArray(cddm),
112                                                                     cddm->getLoopArray(cddm),
113                                                                     cddm->getEdgeArray(cddm),
114                                                                     cddm->getNumEdges(cddm),
115                                                                     cddm->getPolyArray(cddm),
116                                                                     cddm->getNumPolys(cddm));
117                         }
118                         if (grid_paint_mask) {
119                                 float *paint_mask = CustomData_add_layer(&cddm->vertData,
120                                                                          CD_PAINT_MASK,
121                                                                          CD_CALLOC, NULL,
122                                                                          cddm->getNumVerts(cddm));
123
124                                 subsurf_copy_grid_paint_mask(result, me->mpoly,
125                                                              paint_mask, grid_paint_mask);
126                         }
127                 }
128
129                 result->release(result);
130                 result = cddm;
131         }
132
133         return result;
134 }
135
136
137 ModifierTypeInfo modifierType_Multires = {
138         /* name */              "Multires",
139         /* structName */        "MultiresModifierData",
140         /* structSize */        sizeof(MultiresModifierData),
141         /* type */              eModifierTypeType_Constructive,
142         /* flags */             eModifierTypeFlag_AcceptsMesh |
143                                 eModifierTypeFlag_SupportsMapping |
144                                 eModifierTypeFlag_RequiresOriginalData,
145
146         /* copyData */          modifier_copyData_generic,
147
148         /* deformVerts_DM */    NULL,
149         /* deformMatrices_DM */ NULL,
150         /* deformVertsEM_DM */  NULL,
151         /* deformMatricesEM_DM*/NULL,
152         /* applyModifier_DM */  applyModifier,
153         /* applyModifierEM_DM */NULL,
154
155         /* deformVerts */       NULL,
156         /* deformMatrices */    NULL,
157         /* deformVertsEM */     NULL,
158         /* deformMatricesEM */  NULL,
159         /* applyModifier */     NULL,
160         /* applyModifierEM */   NULL,
161
162         /* initData */          initData,
163         /* requiredDataMask */  NULL,
164         /* freeData */          NULL,
165         /* isDisabled */        NULL,
166         /* updateDepsgraph */   NULL,
167         /* dependsOnTime */     NULL,
168         /* dependsOnNormals */  NULL,
169         /* foreachObjectLink */ NULL,
170         /* foreachIDLink */     NULL,
171         /* foreachTexLink */    NULL,
172 };