7a661a94c04f351b836fdf123afa833d69a82ea2
[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 #include "BKE_tessmesh.h"
47
48 #include "BLI_utildefines.h"
49 #include "BLI_math.h"
50 #include "BLI_editVert.h"
51
52 #include "ED_util.h"
53
54 typedef struct {
55         float *vertexcos;
56         short *flags;
57 } MappedUserData;
58
59 #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])
60 static void set_crazy_vertex_quat(float *quat, float *v1, float *v2, float *v3, float *def1, float *def2, float *def3)
61 {
62         float vecu[3], vecv[3];
63         float q1[4], q2[4];
64
65         TAN_MAKE_VEC(vecu, v1, v2);
66         TAN_MAKE_VEC(vecv, v1, v3);
67         tri_to_quat( q1,v1, vecu, vecv);
68
69         TAN_MAKE_VEC(vecu, def1, def2);
70         TAN_MAKE_VEC(vecv, def1, def3);
71         tri_to_quat( q2,def1, vecu, vecv);
72
73         sub_qt_qtqt(quat, q2, q1);
74 }
75 #undef TAN_MAKE_VEC
76
77 static void make_vertexcos__mapFunc(void *userData, int index, float *co, float *UNUSED(no_f), short *UNUSED(no_s))
78 {
79         MappedUserData *mappedData= (MappedUserData*)userData;
80         float *vec = mappedData->vertexcos;
81
82         vec+= 3*index;
83         if(!mappedData->flags[index]) {
84                 /* we need coord from prototype vertex, not it clones or images,
85                    suppose they stored in the beginning of vertex array stored in DM */
86                 VECCOPY(vec, co);
87                 mappedData->flags[index]= 1;
88         }
89 }
90
91 static int modifiers_disable_subsurf_temporary(Object *ob)
92 {
93         ModifierData *md;
94         int disabled = 0;
95
96         for(md=ob->modifiers.first; md; md=md->next)
97                 if(md->type==eModifierType_Subsurf)
98                         if(md->mode & eModifierMode_OnCage) {
99                                 md->mode ^= eModifierMode_DisableTemporary;
100                                 disabled= 1;
101                         }
102
103         return disabled;
104 }
105
106 /* disable subsurf temporal, get mapped cos, and enable it */
107 float *crazyspace_get_mapped_editverts(Scene *scene, Object *obedit)
108 {
109         Mesh *me= obedit->data;
110         DerivedMesh *dm;
111         float *vertexcos;
112         int nverts= me->edit_btmesh->bm->totvert;
113         short *flags;
114         MappedUserData userData;
115
116         /* disable subsurf temporal, get mapped cos, and enable it */
117         if(modifiers_disable_subsurf_temporary(obedit)) {
118                 /* need to make new derivemesh */
119                 makeDerivedMesh(scene, obedit, me->edit_btmesh, CD_MASK_BAREMESH, 0);
120         }
121
122         /* now get the cage */
123         dm= editbmesh_get_derived_cage(scene, obedit, me->edit_btmesh, CD_MASK_BAREMESH);
124
125         vertexcos= MEM_callocN(3*sizeof(float)*nverts, "vertexcos map");
126         flags= MEM_callocN(sizeof(short)*nverts, "vertexcos flags");
127
128         userData.vertexcos= vertexcos;
129         userData.flags= flags;
130         dm->foreachMappedVert(dm, make_vertexcos__mapFunc, &userData);
131
132         dm->release(dm);
133
134         /* set back the flag, no new cage needs to be built, transform does it */
135         modifiers_disable_subsurf_temporary(obedit);
136
137         MEM_freeN(flags);
138
139         return vertexcos;
140 }
141
142 void crazyspace_set_quats_editmesh(BMEditMesh *em, float *origcos, float *mappedcos, float *quats)
143 {
144         BMVert *v;
145         BMIter iter, liter;
146         BMEdge *e;
147         BMLoop *l;
148         float *v1, *v2, *v3, *v4, *co1, *co2, *co3, *co4;
149         int *vert_table = MEM_callocN(sizeof(int)*em->bm->totvert, "vert_table");
150         int index = 0;
151         
152         BM_ITER(v, &iter, em->bm, BM_VERTS_OF_MESH, NULL) {
153                 BM_SetIndex(v, index);
154                 index++;
155         }
156         
157         index = 0;
158         BM_ITER(v, &iter, em->bm, BM_VERTS_OF_MESH, NULL) {
159                 if (!BM_TestHFlag(v, BM_SELECT) || BM_TestHFlag(v, BM_HIDDEN))
160                         continue;
161                 
162                 BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_VERT, v) {
163                         BMLoop *l2 = BM_OtherFaceLoop(l->e, l->f, v);
164                         
165                         /* retrieve mapped coordinates */
166                         v1= mappedcos + 3*BM_GetIndex(l->v);
167                         v2= mappedcos + 3*BM_GetIndex(BM_OtherEdgeVert(l2->e, l->v));
168                         v3= mappedcos + 3*BM_GetIndex(BM_OtherEdgeVert(l->e, l->v));
169                         
170                         co1= (origcos)? origcos + 3*BM_GetIndex(l->v) : l->v->co;
171                         co2= (origcos)? origcos + 3*BM_GetIndex(BM_OtherEdgeVert(l2->e, l->v)) : BM_OtherEdgeVert(l2->e, l->v)->co;
172                         co3= (origcos)? origcos + 3*BM_GetIndex(BM_OtherEdgeVert(l->e, l->v)) : BM_OtherEdgeVert(l->e, l->v)->co;
173                         
174                         set_crazy_vertex_quat(quats, v1, v2, v3, co1, co2, co3);
175                         quats+= 4;
176                         
177                         vert_table[BM_GetIndex(l->v)] = index+1;
178                         
179                         index++;
180                         break; /*just do one corner*/
181                 }
182         }
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 matricies
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 }