soc-2008-mxcurioni: foundations for Freestyle as a render layer - new UI buttons...
[blender.git] / source / blender / src / multires.c
1 /*
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software  Foundation,
18  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19  *
20  * The Original Code is Copyright (C) 2006 by Nicholas Bishop
21  * All rights reserved.
22  *
23  * The Original Code is: all of this file.
24  *
25  * Contributor(s): none yet.
26  *
27  * ***** END GPL LICENSE BLOCK *****
28  *
29  * Implements the multiresolution modeling tools.
30  *
31  * multires.h
32  *
33  */
34
35 #include "MEM_guardedalloc.h"
36
37 #include "BLI_blenlib.h"
38 #include "BLI_arithb.h"
39
40 #include "DNA_key_types.h"
41 #include "DNA_mesh_types.h"
42 #include "DNA_meshdata_types.h"
43 #include "DNA_modifier_types.h"
44 #include "DNA_object_types.h"
45 #include "DNA_scene_types.h"
46 #include "DNA_vec_types.h"
47 #include "DNA_view3d_types.h"
48
49 #include "BKE_customdata.h"
50 #include "BKE_depsgraph.h"
51 #include "BKE_global.h"
52 #include "BKE_key.h"
53 #include "BKE_mesh.h"
54 #include "BKE_modifier.h"
55 #include "BKE_multires.h"
56 #include "BKE_object.h"
57
58 #include "BIF_editmesh.h"
59 #include "BIF_screen.h"
60 #include "BIF_space.h"
61 #include "BIF_toolbox.h"
62
63 #include "BDR_editobject.h"
64 #include "BDR_sculptmode.h"
65
66 #include "BLI_editVert.h"
67
68 #include "BSE_edit.h"
69 #include "BSE_view.h"
70
71 #include "IMB_imbuf.h"
72 #include "IMB_imbuf_types.h"
73
74 #include "blendef.h"
75 #include "editmesh.h"
76 #include "multires.h"
77 #include "mydevice.h"
78 #include "parametrizer.h"
79
80 #include <math.h>
81
82 void multires_calc_temp_data(struct MultiresLevel *lvl);
83
84 int multires_test()
85 {
86         Mesh *me= get_mesh(OBACT);
87         if(me && me->mr) {
88                 error("Unable to complete action with multires enabled.");
89                 return 1;
90         }
91         return 0;
92 }
93 int multires_level1_test()
94 {
95         Mesh *me= get_mesh(OBACT);
96         if(me && me->mr && me->mr->current != 1) {
97                 error("Operation only available for multires level 1.");
98                 return 1;
99         }
100         return 0;
101 }
102
103 /* Sculptmode */
104
105 void multires_check_state()
106 {
107         if(G.f & G_SCULPTMODE && !G.obedit)
108                 sculptmode_correct_state();
109 }
110
111 static void medge_flag_to_eed(const short flag, const char crease, EditEdge *eed)
112 {
113         if(!eed) return;
114         
115         if(flag & ME_SEAM) eed->seam= 1;
116         if(flag & ME_SHARP) eed->sharp = 1;
117         if(flag & SELECT) eed->f |= SELECT;
118         if(flag & ME_FGON) eed->h= EM_FGON;
119         if(flag & ME_HIDE) eed->h |= 1;
120         
121         eed->crease= ((float)crease)/255.0;
122 }
123
124 void multires_level_to_editmesh(Object *ob, Mesh *me, const int render)
125 {
126         MultiresLevel *lvl= BLI_findlink(&me->mr->levels,me->mr->current-1);
127         int i;
128         EditMesh *em= (!render && G.obedit) ? G.editMesh : NULL;
129         EditVert **eves= NULL;
130         EditEdge *eed= NULL;
131
132         if(em) {
133                 /* Remove editmesh elements */
134                 free_editMesh(em);
135                 
136                 eves= MEM_callocN(sizeof(EditVert*)*lvl->totvert, "editvert pointers");
137
138                 /* Vertices/Edges/Faces */
139                 for(i=0; i<lvl->totvert; ++i) {
140                         eves[i]= addvertlist(me->mr->verts[i].co, NULL);
141                         if(me->mr->verts[i].flag & 1) eves[i]->f |= SELECT;
142                         if(me->mr->verts[i].flag & ME_HIDE) eves[i]->h= 1;
143                         eves[i]->data= NULL;
144                 }
145                 for(i=0; i<lvl->totedge; ++i) {
146                         addedgelist(eves[lvl->edges[i].v[0]], eves[lvl->edges[i].v[1]], NULL);
147                 }
148                 for(i=0; i<lvl->totface; ++i) {
149                         EditVert *eve4= lvl->faces[i].v[3] ? eves[lvl->faces[i].v[3]] : NULL;
150                         EditFace *efa= addfacelist(eves[lvl->faces[i].v[0]], eves[lvl->faces[i].v[1]],
151                                                    eves[lvl->faces[i].v[2]], eve4, NULL, NULL);
152                         efa->flag= lvl->faces[i].flag & ~ME_HIDE;
153                         efa->mat_nr= lvl->faces[i].mat_nr;
154                         if(lvl->faces[i].flag & ME_FACE_SEL)
155                                 efa->f |= SELECT;
156                         if(lvl->faces[i].flag & ME_HIDE) efa->h= 1;
157                         efa->data= NULL;
158                 }
159         
160                 /* Edge flags */
161                 eed= em->edges.first;
162                 if(lvl==me->mr->levels.first) {
163                         for(i=0; i<lvl->totedge; ++i) {
164                                 medge_flag_to_eed(me->mr->edge_flags[i], me->mr->edge_creases[i], eed);
165                                 eed= eed->next;
166                         }
167                 } else {
168                         MultiresLevel *lvl1= me->mr->levels.first;
169                         const int last= lvl1->totedge * pow(2, me->mr->current-1);
170                         for(i=0; i<last; ++i) {
171                                 const int ndx= i / pow(2, me->mr->current-1);
172                         
173                                 medge_flag_to_eed(me->mr->edge_flags[ndx], me->mr->edge_creases[ndx], eed);
174                                 eed= eed->next;
175                         }
176                 }
177
178                 eed= em->edges.first;
179                 for(i=0, eed= em->edges.first; i<lvl->totedge; ++i, eed= eed->next) {
180                         eed->h= me->mr->verts[lvl->edges[i].v[0]].flag & ME_HIDE ||
181                                 me->mr->verts[lvl->edges[i].v[1]].flag & ME_HIDE;
182                 }
183         
184                 EM_select_flush();
185
186                 multires_customdata_to_mesh(me, em, lvl, &me->mr->vdata, em ? &em->vdata : &me->vdata, CD_MDEFORMVERT);
187                 multires_customdata_to_mesh(me, em, lvl, &me->mr->fdata, em ? &em->fdata : &me->fdata, CD_MTFACE);
188
189                 /* Colors */
190                 if(me->mr->use_col) {
191                         MCol c[4];
192                         EditFace *efa= NULL;
193                         CustomData *src= &em->fdata;
194
195                         if(me->mr->use_col) EM_add_data_layer(src, CD_MCOL);
196                         efa= em->faces.first;
197                 
198                         for(i=0; i<lvl->totface; ++i) {
199                                 if(me->mr->use_col) {
200                                         multires_to_mcol(&lvl->colfaces[i], c);
201                                         CustomData_em_set(src, efa->data, CD_MCOL, c);
202                                 }
203                                 efa= efa->next;
204                         }
205                         
206                 }
207         
208                 mesh_update_customdata_pointers(me);
209         
210                 MEM_freeN(eves);
211                 DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
212                 recalc_editnormals();
213         }
214 }
215
216 void multires_make(void *ob, void *me_v)
217 {
218         Mesh *me= me_v;
219         Key *key;
220         
221         /* Check for shape keys */
222         key= me->key;
223         if(key) {
224                 int ret= okee("Adding multires will delete all shape keys, proceed?");
225                 if(ret) {
226                         free_key(key);
227                         me->key= NULL;
228                 } else
229                         return;
230         }
231         
232         waitcursor(1);
233         
234         multires_check_state();
235
236         multires_create(ob, me);
237
238         allqueue(REDRAWBUTSEDIT, 0);
239         BIF_undo_push("Make multires");
240         waitcursor(0);
241 }
242
243 void multires_delete(void *ob, void *me_v)
244 {
245         Mesh *me= me_v;
246         multires_free(me->mr);
247         me->mr= NULL;
248         
249         multires_check_state();
250
251         allqueue(REDRAWBUTSEDIT, 0);
252
253         BIF_undo_push("Apply multires");
254 }
255
256 /* Make sure that all level indices are clipped to [1, mr->level_count] */
257 void multires_clip_levels(Multires *mr)
258 {
259         if(mr) {
260                 const int cnt = mr->level_count;
261         
262                 if(mr->current < 1) mr->current = 1;
263                 if(mr->edgelvl < 1) mr->edgelvl = 1;
264                 if(mr->pinlvl < 1) mr->pinlvl = 1;
265                 if(mr->renderlvl < 1) mr->renderlvl = 1;
266                 
267                 if(mr->current > cnt) mr->current = cnt;
268                 if(mr->edgelvl > cnt) mr->edgelvl = cnt;
269                 if(mr->pinlvl > cnt) mr->pinlvl = cnt;
270                 if(mr->renderlvl > cnt) mr->renderlvl = cnt;
271         }
272 }
273
274 /* Delete all multires levels beneath current level. Subdivide special
275    first-level data up to the new lowest level. */
276 void multires_del_lower(void *ob, void *me)
277 {
278         Multires *mr= ((Mesh*)me)->mr;
279         MultiresLevel *lvl1= mr->levels.first, *cr_lvl= current_level(mr);
280         MultiresLevel *lvl= NULL, *lvlprev= NULL;
281         short *edgeflags= NULL;
282         char *edgecreases= NULL;
283         int i, last;
284         
285         if(cr_lvl == lvl1) return;
286         
287         multires_check_state();
288         
289         /* Subdivide the edge flags to the current level */
290         edgeflags= MEM_callocN(sizeof(short)*current_level(mr)->totedge, "Multires Edge Flags");
291         edgecreases= MEM_callocN(sizeof(char)*current_level(mr)->totedge, "Multires Edge Creases");
292         last= lvl1->totedge * pow(2, mr->current-1);
293         for(i=0; i<last; ++i) {
294                 edgeflags[i] = mr->edge_flags[(int)(i / pow(2, mr->current-1))];
295                 edgecreases[i] = mr->edge_creases[(int)(i / pow(2, mr->current-1))];
296         }
297         MEM_freeN(mr->edge_flags);
298         MEM_freeN(mr->edge_creases);
299         mr->edge_flags= edgeflags;
300         mr->edge_creases= edgecreases;
301         
302         multires_del_lower_customdata(mr, cr_lvl);
303         
304         lvl= cr_lvl->prev;
305         while(lvl) {
306                 lvlprev= lvl->prev;
307                 
308                 multires_free_level(lvl);
309                 BLI_freelinkN(&mr->levels, lvl);
310                 
311                 mr->current-= 1;
312                 mr->level_count-= 1;
313                 
314                 lvl= lvlprev;
315         }
316         mr->newlvl= mr->current;
317         
318         multires_clip_levels(mr);
319
320         allqueue(REDRAWBUTSEDIT, 0);
321
322         BIF_undo_push("Multires delete lower");
323 }
324
325 void multires_del_higher(void *ob, void *me)
326 {
327         Multires *mr= ((Mesh*)me)->mr;
328         MultiresLevel *lvl= BLI_findlink(&mr->levels,mr->current-1);
329         MultiresLevel *lvlnext;
330         
331         multires_check_state();
332         
333         lvl= lvl->next;
334         while(lvl) {
335                 lvlnext= lvl->next;
336                 
337                 multires_free_level(lvl);
338                 BLI_freelinkN(&mr->levels,lvl);
339
340                 mr->level_count-= 1;
341                 
342                 lvl= lvlnext;
343         }
344         
345         multires_clip_levels(mr);
346
347         allqueue(REDRAWBUTSEDIT, 0);
348
349         BIF_undo_push("Multires delete higher");
350 }
351
352 void multires_finish_mesh_update(Object *ob)
353 {
354         /* friendly check for background render */
355         if(G.background==0) {
356                 object_handle_update(ob);
357                 countall();
358                 
359                 if(G.vd && G.vd->depths) G.vd->depths->damaged= 1;
360                 allqueue(REDRAWVIEW3D, 0);
361                 allqueue(REDRAWIMAGE, 0);
362         }
363 }
364
365 void multires_subdivide(void *ob_v, void *me_v)
366 {
367         Mesh *me = me_v;
368
369         multires_check_state();
370
371         if(CustomData_number_of_layers(G.obedit ? &G.editMesh->fdata : &me->fdata, CD_MCOL) > 1) {
372                 int ret= okee("Adding a level will delete all but the active vertex color layer, proceed?");
373                 if(!ret)
374                         return;
375         }
376
377         waitcursor(1);
378         multires_add_level(ob_v, me, G.scene->toolsettings->multires_subdiv_type);
379         multires_level_to_editmesh(ob_v, me, 0);
380         multires_finish_mesh_update(ob_v);
381
382         allqueue(REDRAWBUTSEDIT, 0);
383         BIF_undo_push("Add multires level");
384         waitcursor(0);
385 }
386
387 void multires_set_level_cb(void *ob, void *me)
388 {
389         waitcursor(1);
390         
391         multires_check_state();
392
393         multires_set_level(ob, me, 0);
394         multires_level_to_editmesh(ob, me, 0);
395         multires_finish_mesh_update(ob);
396         
397         if(G.obedit || G.f & G_SCULPTMODE)
398                 BIF_undo_push("Multires set level");
399
400         allqueue(REDRAWBUTSEDIT, 0);
401         
402         waitcursor(0);
403 }
404
405 void multires_edge_level_update_cb(void *ob_v, void *me_v)
406 {
407         multires_edge_level_update(ob_v, me_v);
408         allqueue(REDRAWVIEW3D, 0);
409 }
410
411 int multires_modifier_warning()
412 {
413         ModifierData *md;
414         
415         for(md= modifiers_getVirtualModifierList(OBACT); md; md= md->next) {
416                 if(md->mode & eModifierMode_Render) {
417                         switch(md->type) {
418                         case eModifierType_Subsurf:
419                         case eModifierType_Build:
420                         case eModifierType_Mirror:
421                         case eModifierType_Decimate:
422                         case eModifierType_Boolean:
423                         case eModifierType_Array:
424                         case eModifierType_EdgeSplit:
425                                 return 1;
426                         }
427                 }
428         }
429         
430         return 0;
431 }