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