Own TODO item: sculpting on constructive modifiers
[blender.git] / source / blender / editors / util / crazyspace.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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19  *
20  * The Original Code is Copyright (C) 2005 Blender Foundation.
21  * All rights reserved.
22  *
23  *
24  * Contributor(s): Blender Foundation,
25  *                 Sergey Sharybin
26  *
27  * ***** END GPL LICENSE BLOCK *****
28  */
29
30 /** \file blender/editors/util/crazyspace.c
31  *  \ingroup edutil
32  */
33
34
35 #include "MEM_guardedalloc.h"
36
37 #include "DNA_scene_types.h"
38 #include "DNA_object_types.h"
39 #include "DNA_modifier_types.h"
40 #include "DNA_meshdata_types.h"
41
42 #include "BKE_DerivedMesh.h"
43 #include "BKE_modifier.h"
44 #include "BKE_multires.h"
45 #include "BKE_mesh.h"
46
47 #include "BLI_utildefines.h"
48 #include "BLI_math.h"
49 #include "BLI_editVert.h"
50
51 #include "ED_util.h"
52
53 typedef struct {
54         float *vertexcos;
55         short *flags;
56 } MappedUserData;
57
58 #define TAN_MAKE_VEC(a, b, c)   a[0]= b[0] + 0.2f*(b[0]-c[0]); a[1]= b[1] + 0.2f*(b[1]-c[1]); a[2]= b[2] + 0.2f*(b[2]-c[2])
59 static void set_crazy_vertex_quat(float *quat, float *v1, float *v2, float *v3, float *def1, float *def2, float *def3)
60 {
61         float vecu[3], vecv[3];
62         float q1[4], q2[4];
63
64         TAN_MAKE_VEC(vecu, v1, v2);
65         TAN_MAKE_VEC(vecv, v1, v3);
66         tri_to_quat( q1,v1, vecu, vecv);
67
68         TAN_MAKE_VEC(vecu, def1, def2);
69         TAN_MAKE_VEC(vecv, def1, def3);
70         tri_to_quat( q2,def1, vecu, vecv);
71
72         sub_qt_qtqt(quat, q2, q1);
73 }
74 #undef TAN_MAKE_VEC
75
76 static void make_vertexcos__mapFunc(void *userData, int index, float *co, float *UNUSED(no_f), short *UNUSED(no_s))
77 {
78         MappedUserData *mappedData= (MappedUserData*)userData;
79         float *vec = mappedData->vertexcos;
80
81         vec+= 3*index;
82         if(!mappedData->flags[index]) {
83                 /* we need coord from prototype vertex, not it clones or images,
84                    suppose they stored in the beginning of vertex array stored in DM */
85                 VECCOPY(vec, co);
86                 mappedData->flags[index]= 1;
87         }
88 }
89
90 static int modifiers_disable_subsurf_temporary(Object *ob)
91 {
92         ModifierData *md;
93         int disabled = 0;
94
95         for(md=ob->modifiers.first; md; md=md->next)
96                 if(md->type==eModifierType_Subsurf)
97                         if(md->mode & eModifierMode_OnCage) {
98                                 md->mode ^= eModifierMode_DisableTemporary;
99                                 disabled= 1;
100                         }
101
102         return disabled;
103 }
104
105 /* disable subsurf temporal, get mapped cos, and enable it */
106 float *crazyspace_get_mapped_editverts(Scene *scene, Object *obedit)
107 {
108         Mesh *me= obedit->data;
109         DerivedMesh *dm;
110         float *vertexcos;
111         int nverts= me->edit_mesh->totvert;
112         short *flags;
113         MappedUserData userData;
114
115         /* disable subsurf temporal, get mapped cos, and enable it */
116         if(modifiers_disable_subsurf_temporary(obedit)) {
117                 /* need to make new derivemesh */
118                 makeDerivedMesh(scene, obedit, me->edit_mesh, CD_MASK_BAREMESH);
119         }
120
121         /* now get the cage */
122         dm= editmesh_get_derived_cage(scene, obedit, me->edit_mesh, CD_MASK_BAREMESH);
123
124         vertexcos= MEM_callocN(3*sizeof(float)*nverts, "vertexcos map");
125         flags= MEM_callocN(sizeof(short)*nverts, "vertexcos flags");
126
127         userData.vertexcos= vertexcos;
128         userData.flags= flags;
129         dm->foreachMappedVert(dm, make_vertexcos__mapFunc, &userData);
130
131         dm->release(dm);
132
133         /* set back the flag, no new cage needs to be built, transform does it */
134         modifiers_disable_subsurf_temporary(obedit);
135
136         MEM_freeN(flags);
137
138         return vertexcos;
139 }
140
141 void crazyspace_set_quats_editmesh(EditMesh *em, float *origcos, float *mappedcos, float *quats)
142 {
143         EditVert *eve, *prev;
144         EditFace *efa;
145         float *v1, *v2, *v3, *v4, *co1, *co2, *co3, *co4;
146         intptr_t index= 0;
147
148         /* two abused locations in vertices */
149         for(eve= em->verts.first; eve; eve= eve->next, index++) {
150                 eve->tmp.p = NULL;
151                 eve->prev= (EditVert *)index;
152         }
153
154         /* first store two sets of tangent vectors in vertices, we derive it just from the face-edges */
155         for(efa= em->faces.first; efa; efa= efa->next) {
156
157                 /* retrieve mapped coordinates */
158                 v1= mappedcos + 3*(intptr_t)(efa->v1->prev);
159                 v2= mappedcos + 3*(intptr_t)(efa->v2->prev);
160                 v3= mappedcos + 3*(intptr_t)(efa->v3->prev);
161
162                 co1= (origcos)? origcos + 3*(intptr_t)(efa->v1->prev): efa->v1->co;
163                 co2= (origcos)? origcos + 3*(intptr_t)(efa->v2->prev): efa->v2->co;
164                 co3= (origcos)? origcos + 3*(intptr_t)(efa->v3->prev): efa->v3->co;
165
166                 if(efa->v2->tmp.p==NULL && efa->v2->f1) {
167                         set_crazy_vertex_quat(quats, co2, co3, co1, v2, v3, v1);
168                         efa->v2->tmp.p= (void*)quats;
169                         quats+= 4;
170                 }
171
172                 if(efa->v4) {
173                         v4= mappedcos + 3*(intptr_t)(efa->v4->prev);
174                         co4= (origcos)? origcos + 3*(intptr_t)(efa->v4->prev): efa->v4->co;
175
176                         if(efa->v1->tmp.p==NULL && efa->v1->f1) {
177                                 set_crazy_vertex_quat(quats, co1, co2, co4, v1, v2, v4);
178                                 efa->v1->tmp.p= (void*)quats;
179                                 quats+= 4;
180                         }
181                         if(efa->v3->tmp.p==NULL && efa->v3->f1) {
182                                 set_crazy_vertex_quat(quats, co3, co4, co2, v3, v4, v2);
183                                 efa->v3->tmp.p= (void*)quats;
184                                 quats+= 4;
185                         }
186                         if(efa->v4->tmp.p==NULL && efa->v4->f1) {
187                                 set_crazy_vertex_quat(quats, co4, co1, co3, v4, v1, v3);
188                                 efa->v4->tmp.p= (void*)quats;
189                                 quats+= 4;
190                         }
191                 }
192                 else {
193                         if(efa->v1->tmp.p==NULL && efa->v1->f1) {
194                                 set_crazy_vertex_quat(quats, co1, co2, co3, v1, v2, v3);
195                                 efa->v1->tmp.p= (void*)quats;
196                                 quats+= 4;
197                         }
198                         if(efa->v3->tmp.p==NULL && efa->v3->f1) {
199                                 set_crazy_vertex_quat(quats, co3, co1, co2, v3, v1, v2);
200                                 efa->v3->tmp.p= (void*)quats;
201                                 quats+= 4;
202                         }
203                 }
204         }
205
206         /* restore abused prev pointer */
207         for(prev= NULL, eve= em->verts.first; eve; prev= eve, eve= eve->next)
208                 eve->prev= prev;
209
210 }
211
212 void crazyspace_set_quats_mesh(Mesh *me, float *origcos, float *mappedcos, float *quats)
213 {
214         int i;
215         MVert *mvert;
216         MFace *mface;
217         float *v1, *v2, *v3, *v4, *co1, *co2, *co3, *co4;
218
219         mvert= me->mvert;
220         for(i=0; i<me->totvert; i++, mvert++)
221                 mvert->flag&= ~ME_VERT_TMP_TAG;
222
223         /* first store two sets of tangent vectors in vertices, we derive it just from the face-edges */
224         mvert= me->mvert;
225         mface= me->mface;
226         for(i=0; i<me->totface; i++, mface++) {
227
228                 /* retrieve mapped coordinates */
229                 v1= mappedcos + 3*mface->v1;
230                 v2= mappedcos + 3*mface->v2;
231                 v3= mappedcos + 3*mface->v3;
232
233                 co1= (origcos)? origcos + 3*mface->v1: mvert[mface->v1].co;
234                 co2= (origcos)? origcos + 3*mface->v2: mvert[mface->v2].co;
235                 co3= (origcos)? origcos + 3*mface->v3: mvert[mface->v3].co;
236
237                 if((mvert[mface->v2].flag&ME_VERT_TMP_TAG)==0) {
238                         set_crazy_vertex_quat(&quats[mface->v2*4], co2, co3, co1, v2, v3, v1);
239                         mvert[mface->v2].flag|= ME_VERT_TMP_TAG;
240                 }
241
242                 if(mface->v4) {
243                         v4= mappedcos + 3*mface->v4;
244                         co4= (origcos)? origcos + 3*mface->v4: mvert[mface->v4].co;
245
246                         if((mvert[mface->v1].flag&ME_VERT_TMP_TAG)==0) {
247                                 set_crazy_vertex_quat(&quats[mface->v1*4], co1, co2, co4, v1, v2, v4);
248                                 mvert[mface->v1].flag|= ME_VERT_TMP_TAG;
249                         }
250                         if((mvert[mface->v3].flag&ME_VERT_TMP_TAG)==0) {
251                                 set_crazy_vertex_quat(&quats[mface->v3*4], co3, co4, co2, v3, v4, v2);
252                                 mvert[mface->v3].flag|= ME_VERT_TMP_TAG;
253                         }
254                         if((mvert[mface->v4].flag&ME_VERT_TMP_TAG)==0) {
255                                 set_crazy_vertex_quat(&quats[mface->v4*4], co4, co1, co3, v4, v1, v3);
256                                 mvert[mface->v4].flag|= ME_VERT_TMP_TAG;
257                         }
258                 }
259                 else {
260                         if((mvert[mface->v1].flag&ME_VERT_TMP_TAG)==0) {
261                                 set_crazy_vertex_quat(&quats[mface->v1*4], co1, co2, co3, v1, v2, v3);
262                                 mvert[mface->v1].flag|= ME_VERT_TMP_TAG;
263                         }
264                         if((mvert[mface->v3].flag&ME_VERT_TMP_TAG)==0) {
265                                 set_crazy_vertex_quat(&quats[mface->v3*4], co3, co1, co2, v3, v1, v2);
266                                 mvert[mface->v3].flag|= ME_VERT_TMP_TAG;
267                         }
268                 }
269         }
270 }
271
272 int editmesh_get_first_deform_matrices(Scene *scene, Object *ob, EditMesh *em, float (**deformmats)[3][3], float (**deformcos)[3])
273 {
274         ModifierData *md;
275         DerivedMesh *dm;
276         int i, a, numleft = 0, numVerts = 0;
277         int cageIndex = modifiers_getCageIndex(scene, ob, NULL, 1);
278         float (*defmats)[3][3] = NULL, (*deformedVerts)[3] = NULL;
279
280         modifiers_clearErrors(ob);
281
282         dm = NULL;
283         md = modifiers_getVirtualModifierList(ob);
284
285         /* compute the deformation matrices and coordinates for the first
286            modifiers with on cage editing that are enabled and support computing
287            deform matrices */
288         for(i = 0; md && i <= cageIndex; i++, md = md->next) {
289                 ModifierTypeInfo *mti = modifierType_getInfo(md->type);
290
291                 if(!editmesh_modifier_is_enabled(scene, md, dm))
292                         continue;
293
294                 if(mti->type==eModifierTypeType_OnlyDeform && mti->deformMatricesEM) {
295                         if(!defmats) {
296                                 dm= editmesh_get_derived(em, NULL);
297                                 deformedVerts= editmesh_get_vertex_cos(em, &numVerts);
298                                 defmats= MEM_callocN(sizeof(*defmats)*numVerts, "defmats");
299
300                                 for(a=0; a<numVerts; a++)
301                                         unit_m3(defmats[a]);
302                         }
303
304                         mti->deformMatricesEM(md, ob, em, dm, deformedVerts, defmats,
305                                 numVerts);
306                 }
307                 else
308                         break;
309         }
310
311         for(; md && i <= cageIndex; md = md->next, i++)
312                 if(editmesh_modifier_is_enabled(scene, md, dm) && modifier_isCorrectableDeformed(md))
313                         numleft++;
314
315         if(dm)
316                 dm->release(dm);
317
318         *deformmats= defmats;
319         *deformcos= deformedVerts;
320
321         return numleft;
322 }
323
324 int sculpt_get_first_deform_matrices(Scene *scene, Object *ob, float (**deformmats)[3][3], float (**deformcos)[3])
325 {
326         ModifierData *md;
327         DerivedMesh *dm;
328         int a, numVerts= 0;
329         float (*defmats)[3][3]= NULL, (*deformedVerts)[3]= NULL;
330         MultiresModifierData *mmd= get_multires_modifier(scene, ob, 0);
331         int has_multires = mmd != NULL && mmd->sculptlvl > 0;
332         int numleft= 0;
333
334         if(has_multires) {
335                 *deformmats= NULL;
336                 *deformcos= NULL;
337                 return numleft;
338         }
339
340         dm= NULL;
341         md= modifiers_getVirtualModifierList(ob);
342
343         for(; md; md= md->next) {
344                 ModifierTypeInfo *mti= modifierType_getInfo(md->type);
345
346                 if(!modifier_isEnabled(scene, md, eModifierMode_Realtime)) continue;
347
348                 if(mti->type==eModifierTypeType_OnlyDeform) {
349                         if(!defmats) {
350                                 Mesh *me= (Mesh*)ob->data;
351                                 dm= mesh_create_derived(me, ob, NULL);
352                                 deformedVerts= mesh_getVertexCos(me, &numVerts);
353                                 defmats= MEM_callocN(sizeof(*defmats)*numVerts, "defmats");
354
355                                 for(a=0; a<numVerts; a++)
356                                         unit_m3(defmats[a]);
357                         }
358
359                         if(mti->deformMatrices) mti->deformMatrices(md, ob, dm, deformedVerts, defmats, numVerts);
360                         else break;
361                 }
362         }
363
364         for(; md; md= md->next) {
365                 ModifierTypeInfo *mti= modifierType_getInfo(md->type);
366
367                 if(!modifier_isEnabled(scene, md, eModifierMode_Realtime)) continue;
368
369                 if(mti->type==eModifierTypeType_OnlyDeform)
370                         numleft++;
371         }
372
373         if(dm)
374                 dm->release(dm);
375
376         *deformmats= defmats;
377         *deformcos= deformedVerts;
378
379         return numleft;
380 }
381
382 void crazyspace_build_sculpt(Scene *scene, Object *ob, float (**deformmats)[3][3], float (**deformcos)[3])
383 {
384         int totleft= sculpt_get_first_deform_matrices(scene, ob, deformmats, deformcos);
385
386         if(totleft) {
387                 /* there are deformation modifier which doesn't support deformation matricies
388                    calculation. Need additional crazyspace correction */
389
390                 float (*deformedVerts)[3]= *deformcos;
391                 float (*origVerts)[3]= MEM_dupallocN(deformedVerts);
392                 float *quats= NULL;
393                 int i, deformed= 0;
394                 ModifierData *md= modifiers_getVirtualModifierList(ob);
395                 Mesh *me= (Mesh*)ob->data;
396
397                 for(; md; md= md->next) {
398                         ModifierTypeInfo *mti= modifierType_getInfo(md->type);
399
400                         if(!modifier_isEnabled(scene, md, eModifierMode_Realtime)) continue;
401
402                         if(mti->type==eModifierTypeType_OnlyDeform) {
403                                 /* skip leading modifiers which have been already
404                                    handled in sculpt_get_first_deform_matrices */
405                                 if(mti->deformMatrices && !deformed)
406                                         continue;
407
408                                 mti->deformVerts(md, ob, NULL, deformedVerts, me->totvert, 0, 0);
409                                 deformed= 1;
410                         }
411                 }
412
413                 quats= MEM_mallocN(me->totvert*sizeof(float)*4, "crazy quats");
414
415                 crazyspace_set_quats_mesh(me, (float*)origVerts, (float*)deformedVerts, quats);
416
417                 for(i=0; i<me->totvert; i++) {
418                         float qmat[3][3], tmat[3][3];
419
420                         quat_to_mat3(qmat, &quats[i*4]);
421                         mul_m3_m3m3(tmat, qmat, (*deformmats)[i]);
422                         copy_m3_m3((*deformmats)[i], tmat);
423                 }
424
425                 MEM_freeN(origVerts);
426                 MEM_freeN(quats);
427         }
428
429         if(!*deformmats) {
430                 int a, numVerts;
431                 Mesh *me= (Mesh*)ob->data;
432
433                 *deformcos= mesh_getVertexCos(me, &numVerts);
434                 *deformmats= MEM_callocN(sizeof(*(*deformmats))*numVerts, "defmats");
435
436                 for(a=0; a<numVerts; a++)
437                         unit_m3((*deformmats)[a]);
438         }
439 }