remove unused vars
[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         BMLoop *l;
147         float *v1, *v2, *v3, *co1, *co2, *co3;
148         int *vert_table = MEM_callocN(sizeof(int)*em->bm->totvert, "vert_table");
149         int index = 0;
150         
151         BM_ITER(v, &iter, em->bm, BM_VERTS_OF_MESH, NULL) {
152                 BM_SetIndex(v, index);
153                 index++;
154         }
155         
156         index = 0;
157         BM_ITER(v, &iter, em->bm, BM_VERTS_OF_MESH, NULL) {
158                 if (!BM_TestHFlag(v, BM_SELECT) || BM_TestHFlag(v, BM_HIDDEN))
159                         continue;
160                 
161                 BM_ITER(l, &liter, em->bm, BM_LOOPS_OF_VERT, v) {
162                         BMLoop *l2 = BM_OtherFaceLoop(l->e, l->f, v);
163                         
164                         /* retrieve mapped coordinates */
165                         v1= mappedcos + 3*BM_GetIndex(l->v);
166                         v2= mappedcos + 3*BM_GetIndex(BM_OtherEdgeVert(l2->e, l->v));
167                         v3= mappedcos + 3*BM_GetIndex(BM_OtherEdgeVert(l->e, l->v));
168                         
169                         co1= (origcos)? origcos + 3*BM_GetIndex(l->v) : l->v->co;
170                         co2= (origcos)? origcos + 3*BM_GetIndex(BM_OtherEdgeVert(l2->e, l->v)) : BM_OtherEdgeVert(l2->e, l->v)->co;
171                         co3= (origcos)? origcos + 3*BM_GetIndex(BM_OtherEdgeVert(l->e, l->v)) : BM_OtherEdgeVert(l->e, l->v)->co;
172                         
173                         set_crazy_vertex_quat(quats, v1, v2, v3, co1, co2, co3);
174                         quats+= 4;
175                         
176                         vert_table[BM_GetIndex(l->v)] = index+1;
177                         
178                         index++;
179                         break; /*just do one corner*/
180                 }
181         }
182         
183         index = 0;
184         BM_ITER(v, &iter, em->bm, BM_VERTS_OF_MESH, NULL) {
185                 if (vert_table[index] != 0)
186                         BM_SetIndex(v, vert_table[index]-1);
187                 else
188                         BM_SetIndex(v, -1);
189                 
190                 index++;
191         }
192
193         MEM_freeN(vert_table);
194 #if 0
195         BMEditVert *eve, *prev;
196         BMEditFace *efa;
197         BMIter iter;
198         float *v1, *v2, *v3, *v4, *co1, *co2, *co3, *co4;
199         intptr_t index= 0;
200
201         /* two abused locations in vertices */
202         for(eve= em->verts.first; eve; eve= eve->next, index++) {
203                 eve->tmp.p = NULL;
204                 eve->prev= (EditVert *)index;
205         }
206
207         /* first store two sets of tangent vectors in vertices, we derive it just from the face-edges */
208         for(efa= em->faces.first; efa; efa= efa->next) {
209
210                 /* retrieve mapped coordinates */
211                 v1= mappedcos + 3*(intptr_t)(efa->v1->prev);
212                 v2= mappedcos + 3*(intptr_t)(efa->v2->prev);
213                 v3= mappedcos + 3*(intptr_t)(efa->v3->prev);
214
215                 co1= (origcos)? origcos + 3*(intptr_t)(efa->v1->prev): efa->v1->co;
216                 co2= (origcos)? origcos + 3*(intptr_t)(efa->v2->prev): efa->v2->co;
217                 co3= (origcos)? origcos + 3*(intptr_t)(efa->v3->prev): efa->v3->co;
218
219                 if(efa->v2->tmp.p==NULL && efa->v2->f1) {
220                         set_crazy_vertex_quat(quats, co2, co3, co1, v2, v3, v1);
221                         efa->v2->tmp.p= (void*)quats;
222                         quats+= 4;
223                 }
224
225                 if(efa->v4) {
226                         v4= mappedcos + 3*(intptr_t)(efa->v4->prev);
227                         co4= (origcos)? origcos + 3*(intptr_t)(efa->v4->prev): efa->v4->co;
228
229                         if(efa->v1->tmp.p==NULL && efa->v1->f1) {
230                                 set_crazy_vertex_quat(quats, co1, co2, co4, v1, v2, v4);
231                                 efa->v1->tmp.p= (void*)quats;
232                                 quats+= 4;
233                         }
234                         if(efa->v3->tmp.p==NULL && efa->v3->f1) {
235                                 set_crazy_vertex_quat(quats, co3, co4, co2, v3, v4, v2);
236                                 efa->v3->tmp.p= (void*)quats;
237                                 quats+= 4;
238                         }
239                         if(efa->v4->tmp.p==NULL && efa->v4->f1) {
240                                 set_crazy_vertex_quat(quats, co4, co1, co3, v4, v1, v3);
241                                 efa->v4->tmp.p= (void*)quats;
242                                 quats+= 4;
243                         }
244                 }
245                 else {
246                         if(efa->v1->tmp.p==NULL && efa->v1->f1) {
247                                 set_crazy_vertex_quat(quats, co1, co2, co3, v1, v2, v3);
248                                 efa->v1->tmp.p= (void*)quats;
249                                 quats+= 4;
250                         }
251                         if(efa->v3->tmp.p==NULL && efa->v3->f1) {
252                                 set_crazy_vertex_quat(quats, co3, co1, co2, v3, v1, v2);
253                                 efa->v3->tmp.p= (void*)quats;
254                                 quats+= 4;
255                         }
256                 }
257         }
258
259         /* restore abused prev pointer */
260         for(prev= NULL, eve= em->verts.first; eve; prev= eve, eve= eve->next)
261                 eve->prev= prev;
262 #endif
263 }
264
265 void crazyspace_set_quats_mesh(Mesh *me, float *origcos, float *mappedcos, float *quats)
266 {
267         int i;
268         MVert *mvert;
269         MFace *mface;
270         float *v1, *v2, *v3, *v4, *co1, *co2, *co3, *co4;
271
272         mvert= me->mvert;
273         for(i=0; i<me->totvert; i++, mvert++)
274                 mvert->flag&= ~ME_VERT_TMP_TAG;
275
276         /* first store two sets of tangent vectors in vertices, we derive it just from the face-edges */
277         mvert= me->mvert;
278         mface= me->mface;
279         for(i=0; i<me->totface; i++, mface++) {
280
281                 /* retrieve mapped coordinates */
282                 v1= mappedcos + 3*mface->v1;
283                 v2= mappedcos + 3*mface->v2;
284                 v3= mappedcos + 3*mface->v3;
285
286                 co1= (origcos)? origcos + 3*mface->v1: mvert[mface->v1].co;
287                 co2= (origcos)? origcos + 3*mface->v2: mvert[mface->v2].co;
288                 co3= (origcos)? origcos + 3*mface->v3: mvert[mface->v3].co;
289
290                 if((mvert[mface->v2].flag&ME_VERT_TMP_TAG)==0) {
291                         set_crazy_vertex_quat(&quats[mface->v2*4], co2, co3, co1, v2, v3, v1);
292                         mvert[mface->v2].flag|= ME_VERT_TMP_TAG;
293                 }
294
295                 if(mface->v4) {
296                         v4= mappedcos + 3*mface->v4;
297                         co4= (origcos)? origcos + 3*mface->v4: mvert[mface->v4].co;
298
299                         if((mvert[mface->v1].flag&ME_VERT_TMP_TAG)==0) {
300                                 set_crazy_vertex_quat(&quats[mface->v1*4], co1, co2, co4, v1, v2, v4);
301                                 mvert[mface->v1].flag|= ME_VERT_TMP_TAG;
302                         }
303                         if((mvert[mface->v3].flag&ME_VERT_TMP_TAG)==0) {
304                                 set_crazy_vertex_quat(&quats[mface->v3*4], co3, co4, co2, v3, v4, v2);
305                                 mvert[mface->v3].flag|= ME_VERT_TMP_TAG;
306                         }
307                         if((mvert[mface->v4].flag&ME_VERT_TMP_TAG)==0) {
308                                 set_crazy_vertex_quat(&quats[mface->v4*4], co4, co1, co3, v4, v1, v3);
309                                 mvert[mface->v4].flag|= ME_VERT_TMP_TAG;
310                         }
311                 }
312                 else {
313                         if((mvert[mface->v1].flag&ME_VERT_TMP_TAG)==0) {
314                                 set_crazy_vertex_quat(&quats[mface->v1*4], co1, co2, co3, v1, v2, v3);
315                                 mvert[mface->v1].flag|= ME_VERT_TMP_TAG;
316                         }
317                         if((mvert[mface->v3].flag&ME_VERT_TMP_TAG)==0) {
318                                 set_crazy_vertex_quat(&quats[mface->v3*4], co3, co1, co2, v3, v1, v2);
319                                 mvert[mface->v3].flag|= ME_VERT_TMP_TAG;
320                         }
321                 }
322         }
323 }
324
325 int editbmesh_get_first_deform_matrices(Scene *scene, Object *ob, BMEditMesh *em, 
326                                                                                 float (**deformmats)[3][3], float (**deformcos)[3])
327 {
328         ModifierData *md;
329         DerivedMesh *dm;
330         int i, a, numleft = 0, numVerts = 0;
331         int cageIndex = modifiers_getCageIndex(scene, ob, NULL, 1);
332         float (*defmats)[3][3] = NULL, (*deformedVerts)[3] = NULL;
333
334         modifiers_clearErrors(ob);
335
336         dm = NULL;
337         md = modifiers_getVirtualModifierList(ob);
338
339         /* compute the deformation matrices and coordinates for the first
340            modifiers with on cage editing that are enabled and support computing
341            deform matrices */
342         for(i = 0; md && i <= cageIndex; i++, md = md->next) {
343                 ModifierTypeInfo *mti = modifierType_getInfo(md->type);
344
345                 if(!editbmesh_modifier_is_enabled(scene, md, dm))
346                         continue;
347
348                 if(mti->type==eModifierTypeType_OnlyDeform && mti->deformMatricesEM) {
349                         if(!defmats) {
350                                 dm= getEditDerivedBMesh(em, ob, NULL);
351                                 deformedVerts= editbmesh_get_vertex_cos(em, &numVerts);
352                                 defmats= MEM_callocN(sizeof(*defmats)*numVerts, "defmats");
353
354                                 for(a=0; a<numVerts; a++)
355                                         unit_m3(defmats[a]);
356                         }
357
358                         mti->deformMatricesEM(md, ob, em, dm, deformedVerts, defmats,
359                                 numVerts);
360                 }
361                 else
362                         break;
363         }
364
365         for(; md && i <= cageIndex; md = md->next, i++)
366                 if(editbmesh_modifier_is_enabled(scene, md, dm) && modifier_isCorrectableDeformed(md))
367                         numleft++;
368
369         if(dm)
370                 dm->release(dm);
371
372         *deformmats= defmats;
373         *deformcos= deformedVerts;
374
375         return numleft;
376 }
377
378 int sculpt_get_first_deform_matrices(Scene *scene, Object *ob, float (**deformmats)[3][3], float (**deformcos)[3])
379 {
380         ModifierData *md;
381         DerivedMesh *dm;
382         int a, numVerts= 0;
383         float (*defmats)[3][3]= NULL, (*deformedVerts)[3]= NULL;
384         MultiresModifierData *mmd= get_multires_modifier(scene, ob, 0);
385         int has_multires = mmd != NULL && mmd->sculptlvl > 0;
386         int numleft= 0;
387
388         if(has_multires) {
389                 *deformmats= NULL;
390                 *deformcos= NULL;
391                 return numleft;
392         }
393
394         dm= NULL;
395         md= modifiers_getVirtualModifierList(ob);
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                         if(!defmats) {
404                                 Mesh *me= (Mesh*)ob->data;
405                                 dm= mesh_create_derived(me, ob, NULL);
406                                 deformedVerts= mesh_getVertexCos(me, &numVerts);
407                                 defmats= MEM_callocN(sizeof(*defmats)*numVerts, "defmats");
408
409                                 for(a=0; a<numVerts; a++)
410                                         unit_m3(defmats[a]);
411                         }
412
413                         if(mti->deformMatrices) mti->deformMatrices(md, ob, dm, deformedVerts, defmats, numVerts);
414                         else break;
415                 }
416         }
417
418         for(; md; md= md->next) {
419                 ModifierTypeInfo *mti= modifierType_getInfo(md->type);
420
421                 if(!modifier_isEnabled(scene, md, eModifierMode_Realtime)) continue;
422
423                 if(mti->type==eModifierTypeType_OnlyDeform)
424                         numleft++;
425         }
426
427         if(dm)
428                 dm->release(dm);
429
430         *deformmats= defmats;
431         *deformcos= deformedVerts;
432
433         return numleft;
434 }
435
436 void crazyspace_build_sculpt(Scene *scene, Object *ob, float (**deformmats)[3][3], float (**deformcos)[3])
437 {
438         int totleft= sculpt_get_first_deform_matrices(scene, ob, deformmats, deformcos);
439
440         if(totleft) {
441                 /* there are deformation modifier which doesn't support deformation matricies
442                    calculation. Need additional crazyspace correction */
443
444                 float (*deformedVerts)[3]= *deformcos;
445                 float (*origVerts)[3]= MEM_dupallocN(deformedVerts);
446                 float *quats= NULL;
447                 int i, deformed= 0;
448                 ModifierData *md= modifiers_getVirtualModifierList(ob);
449                 Mesh *me= (Mesh*)ob->data;
450
451                 for(; md; md= md->next) {
452                         ModifierTypeInfo *mti= modifierType_getInfo(md->type);
453
454                         if(!modifier_isEnabled(scene, md, eModifierMode_Realtime)) continue;
455
456                         if(mti->type==eModifierTypeType_OnlyDeform) {
457                                 /* skip leading modifiers which have been already
458                                    handled in sculpt_get_first_deform_matrices */
459                                 if(mti->deformMatrices && !deformed)
460                                         continue;
461
462                                 mti->deformVerts(md, ob, NULL, deformedVerts, me->totvert, 0, 0);
463                                 deformed= 1;
464                         }
465                 }
466
467                 quats= MEM_mallocN(me->totvert*sizeof(float)*4, "crazy quats");
468
469                 crazyspace_set_quats_mesh(me, (float*)origVerts, (float*)deformedVerts, quats);
470
471                 for(i=0; i<me->totvert; i++) {
472                         float qmat[3][3], tmat[3][3];
473
474                         quat_to_mat3(qmat, &quats[i*4]);
475                         mul_m3_m3m3(tmat, qmat, (*deformmats)[i]);
476                         copy_m3_m3((*deformmats)[i], tmat);
477                 }
478
479                 MEM_freeN(origVerts);
480                 MEM_freeN(quats);
481         }
482
483         if(!*deformmats) {
484                 int a, numVerts;
485                 Mesh *me= (Mesh*)ob->data;
486
487                 *deformcos= mesh_getVertexCos(me, &numVerts);
488                 *deformmats= MEM_callocN(sizeof(*(*deformmats))*numVerts, "defmats");
489
490                 for(a=0; a<numVerts; a++)
491                         unit_m3((*deformmats)[a]);
492         }
493 }