code cleanup: remove editmesh code left hanging around thats already been ported...
[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_mesh_types.h"
39 #include "DNA_meshdata_types.h"
40
41 #include "BLI_utildefines.h"
42 #include "BLI_math.h"
43
44 #include "BKE_DerivedMesh.h"
45 #include "BKE_modifier.h"
46 #include "BKE_multires.h"
47 #include "BKE_mesh.h"
48 #include "BKE_tessmesh.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, const float co[3],
76                                     const float UNUSED(no_f[3]), const short UNUSED(no_s[3]))
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                 copy_v3_v3(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_btmesh->bm->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_btmesh, CD_MASK_BAREMESH, 0);
119         }
120
121         /* now get the cage */
122         dm = editbmesh_get_derived_cage(scene, obedit, me->edit_btmesh, 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(BMEditMesh *em, float *origcos, float *mappedcos, float *quats)
142 {
143         BMVert *v;
144         BMIter iter, liter;
145         BMLoop *l;
146         float *v1, *v2, *v3, *co1, *co2, *co3;
147         int *vert_table = MEM_callocN(sizeof(int) * em->bm->totvert, "vert_table");
148         int index = 0;
149
150         BM_mesh_elem_index_ensure(em->bm, BM_VERT);
151
152         BM_ITER_MESH (v, &iter, em->bm, BM_VERTS_OF_MESH) {
153                 if (!BM_elem_flag_test(v, BM_ELEM_SELECT) || BM_elem_flag_test(v, BM_ELEM_HIDDEN))
154                         continue;
155                 
156                 BM_ITER_ELEM (l, &liter, v, BM_LOOPS_OF_VERT) {
157                         BMLoop *l2 = BM_face_other_edge_loop(l->f, l->e, v);
158                         
159                         /* retrieve mapped coordinates */
160                         v1 = mappedcos + 3 * BM_elem_index_get(l->v);
161                         v2 = mappedcos + 3 * BM_elem_index_get(BM_edge_other_vert(l2->e, l->v));
162                         v3 = mappedcos + 3 * BM_elem_index_get(BM_edge_other_vert(l->e, l->v));
163
164                         co1 = (origcos) ? origcos + 3 * BM_elem_index_get(l->v) : l->v->co;
165                         co2 = (origcos) ? origcos + 3 * BM_elem_index_get(BM_edge_other_vert(l2->e, l->v)) : BM_edge_other_vert(l2->e, l->v)->co;
166                         co3 = (origcos) ? origcos + 3 * BM_elem_index_get(BM_edge_other_vert(l->e, l->v)) : BM_edge_other_vert(l->e, l->v)->co;
167                         
168                         set_crazy_vertex_quat(quats, v1, v2, v3, co1, co2, co3);
169                         quats += 4;
170                         
171                         vert_table[BM_elem_index_get(l->v)] = index + 1;
172                         
173                         index++;
174                         break; /*just do one corner*/
175                 }
176         }
177
178         index = 0;
179         BM_ITER_MESH (v, &iter, em->bm, BM_VERTS_OF_MESH) {
180                 if (vert_table[index] != 0)
181                         BM_elem_index_set(v, vert_table[index] - 1);  /* set_dirty! */
182                 else
183                         BM_elem_index_set(v, -1);  /* set_dirty! */
184                 
185                 index++;
186         }
187         em->bm->elem_index_dirty |= BM_VERT;
188
189         MEM_freeN(vert_table);
190 }
191
192 /* BMESH_TODO - use MPolys over MFace's */
193
194 void crazyspace_set_quats_mesh(Mesh *me, float *origcos, float *mappedcos, float *quats)
195 {
196         int i;
197         MVert *mvert;
198         MFace *mface;
199         float *v1, *v2, *v3, *v4, *co1, *co2, *co3, *co4;
200
201         mvert = me->mvert;
202         for (i = 0; i < me->totvert; i++, mvert++)
203                 mvert->flag &= ~ME_VERT_TMP_TAG;
204
205         /* first store two sets of tangent vectors in vertices, we derive it just from the face-edges */
206         mvert = me->mvert;
207         mface = me->mface;
208         for (i = 0; i < me->totface; i++, mface++) {
209
210                 /* retrieve mapped coordinates */
211                 v1 = mappedcos + 3 * mface->v1;
212                 v2 = mappedcos + 3 * mface->v2;
213                 v3 = mappedcos + 3 * mface->v3;
214
215                 co1 = (origcos) ? origcos + 3 * mface->v1 : mvert[mface->v1].co;
216                 co2 = (origcos) ? origcos + 3 * mface->v2 : mvert[mface->v2].co;
217                 co3 = (origcos) ? origcos + 3 * mface->v3 : mvert[mface->v3].co;
218
219                 if ((mvert[mface->v2].flag & ME_VERT_TMP_TAG) == 0) {
220                         set_crazy_vertex_quat(&quats[mface->v2 * 4], co2, co3, co1, v2, v3, v1);
221                         mvert[mface->v2].flag |= ME_VERT_TMP_TAG;
222                 }
223
224                 if (mface->v4) {
225                         v4 = mappedcos + 3 * mface->v4;
226                         co4 = (origcos) ? origcos + 3 * mface->v4 : mvert[mface->v4].co;
227
228                         if ((mvert[mface->v1].flag & ME_VERT_TMP_TAG) == 0) {
229                                 set_crazy_vertex_quat(&quats[mface->v1 * 4], co1, co2, co4, v1, v2, v4);
230                                 mvert[mface->v1].flag |= ME_VERT_TMP_TAG;
231                         }
232                         if ((mvert[mface->v3].flag & ME_VERT_TMP_TAG) == 0) {
233                                 set_crazy_vertex_quat(&quats[mface->v3 * 4], co3, co4, co2, v3, v4, v2);
234                                 mvert[mface->v3].flag |= ME_VERT_TMP_TAG;
235                         }
236                         if ((mvert[mface->v4].flag & ME_VERT_TMP_TAG) == 0) {
237                                 set_crazy_vertex_quat(&quats[mface->v4 * 4], co4, co1, co3, v4, v1, v3);
238                                 mvert[mface->v4].flag |= ME_VERT_TMP_TAG;
239                         }
240                 }
241                 else {
242                         if ((mvert[mface->v1].flag & ME_VERT_TMP_TAG) == 0) {
243                                 set_crazy_vertex_quat(&quats[mface->v1 * 4], co1, co2, co3, v1, v2, v3);
244                                 mvert[mface->v1].flag |= ME_VERT_TMP_TAG;
245                         }
246                         if ((mvert[mface->v3].flag & ME_VERT_TMP_TAG) == 0) {
247                                 set_crazy_vertex_quat(&quats[mface->v3 * 4], co3, co1, co2, v3, v1, v2);
248                                 mvert[mface->v3].flag |= ME_VERT_TMP_TAG;
249                         }
250                 }
251         }
252 }
253
254 int editbmesh_get_first_deform_matrices(Scene *scene, Object *ob, BMEditMesh *em, 
255                                         float (**deformmats)[3][3], float (**deformcos)[3])
256 {
257         ModifierData *md;
258         DerivedMesh *dm;
259         int i, a, numleft = 0, numVerts = 0;
260         int cageIndex = modifiers_getCageIndex(scene, ob, NULL, 1);
261         float (*defmats)[3][3] = NULL, (*deformedVerts)[3] = NULL;
262
263         modifiers_clearErrors(ob);
264
265         dm = NULL;
266         md = modifiers_getVirtualModifierList(ob);
267
268         /* compute the deformation matrices and coordinates for the first
269          * modifiers with on cage editing that are enabled and support computing
270          * deform matrices */
271         for (i = 0; md && i <= cageIndex; i++, md = md->next) {
272                 ModifierTypeInfo *mti = modifierType_getInfo(md->type);
273
274                 if (!editbmesh_modifier_is_enabled(scene, md, dm))
275                         continue;
276
277                 if (mti->type == eModifierTypeType_OnlyDeform && mti->deformMatricesEM) {
278                         if (!defmats) {
279                                 dm = getEditDerivedBMesh(em, ob, NULL);
280                                 deformedVerts = editbmesh_get_vertex_cos(em, &numVerts);
281                                 defmats = MEM_callocN(sizeof(*defmats) * numVerts, "defmats");
282
283                                 for (a = 0; a < numVerts; a++)
284                                         unit_m3(defmats[a]);
285                         }
286
287                         mti->deformMatricesEM(md, ob, em, dm, deformedVerts, defmats,
288                                               numVerts);
289                 }
290                 else
291                         break;
292         }
293
294         for (; md && i <= cageIndex; md = md->next, i++)
295                 if (editbmesh_modifier_is_enabled(scene, md, dm) && modifier_isCorrectableDeformed(md))
296                         numleft++;
297
298         if (dm)
299                 dm->release(dm);
300
301         *deformmats = defmats;
302         *deformcos = deformedVerts;
303
304         return numleft;
305 }
306
307 int sculpt_get_first_deform_matrices(Scene *scene, Object *ob, float (**deformmats)[3][3], float (**deformcos)[3])
308 {
309         ModifierData *md;
310         DerivedMesh *dm;
311         int a, numVerts = 0;
312         float (*defmats)[3][3] = NULL, (*deformedVerts)[3] = NULL;
313         MultiresModifierData *mmd = get_multires_modifier(scene, ob, 0);
314         int has_multires = mmd != NULL && mmd->sculptlvl > 0;
315         int numleft = 0;
316
317         if (has_multires) {
318                 *deformmats = NULL;
319                 *deformcos = NULL;
320                 return numleft;
321         }
322
323         dm = NULL;
324         md = modifiers_getVirtualModifierList(ob);
325
326         for (; md; md = md->next) {
327                 ModifierTypeInfo *mti = modifierType_getInfo(md->type);
328
329                 if (!modifier_isEnabled(scene, md, eModifierMode_Realtime)) continue;
330
331                 if (mti->type == eModifierTypeType_OnlyDeform) {
332                         if (!defmats) {
333                                 Mesh *me = (Mesh *)ob->data;
334                                 dm = mesh_create_derived(me, ob, NULL);
335                                 deformedVerts = mesh_getVertexCos(me, &numVerts);
336                                 defmats = MEM_callocN(sizeof(*defmats) * numVerts, "defmats");
337
338                                 for (a = 0; a < numVerts; a++)
339                                         unit_m3(defmats[a]);
340                         }
341
342                         if (mti->deformMatrices) mti->deformMatrices(md, ob, dm, deformedVerts, defmats, numVerts);
343                         else break;
344                 }
345         }
346
347         for (; md; md = md->next) {
348                 ModifierTypeInfo *mti = modifierType_getInfo(md->type);
349
350                 if (!modifier_isEnabled(scene, md, eModifierMode_Realtime)) continue;
351
352                 if (mti->type == eModifierTypeType_OnlyDeform)
353                         numleft++;
354         }
355
356         if (dm)
357                 dm->release(dm);
358
359         *deformmats = defmats;
360         *deformcos = deformedVerts;
361
362         return numleft;
363 }
364
365 void crazyspace_build_sculpt(Scene *scene, Object *ob, float (**deformmats)[3][3], float (**deformcos)[3])
366 {
367         int totleft = sculpt_get_first_deform_matrices(scene, ob, deformmats, deformcos);
368
369         if (totleft) {
370                 /* there are deformation modifier which doesn't support deformation matrices
371                  * calculation. Need additional crazyspace correction */
372
373                 float (*deformedVerts)[3] = *deformcos;
374                 float (*origVerts)[3] = MEM_dupallocN(deformedVerts);
375                 float *quats = NULL;
376                 int i, deformed = 0;
377                 ModifierData *md = modifiers_getVirtualModifierList(ob);
378                 Mesh *me = (Mesh *)ob->data;
379
380                 for (; md; md = md->next) {
381                         ModifierTypeInfo *mti = modifierType_getInfo(md->type);
382
383                         if (!modifier_isEnabled(scene, md, eModifierMode_Realtime)) continue;
384
385                         if (mti->type == eModifierTypeType_OnlyDeform) {
386                                 /* skip leading modifiers which have been already
387                                  * handled in sculpt_get_first_deform_matrices */
388                                 if (mti->deformMatrices && !deformed)
389                                         continue;
390
391                                 mti->deformVerts(md, ob, NULL, deformedVerts, me->totvert, 0, 0);
392                                 deformed = 1;
393                         }
394                 }
395
396                 quats = MEM_mallocN(me->totvert * sizeof(float) * 4, "crazy quats");
397
398                 crazyspace_set_quats_mesh(me, (float *)origVerts, (float *)deformedVerts, quats);
399
400                 for (i = 0; i < me->totvert; i++) {
401                         float qmat[3][3], tmat[3][3];
402
403                         quat_to_mat3(qmat, &quats[i * 4]);
404                         mul_m3_m3m3(tmat, qmat, (*deformmats)[i]);
405                         copy_m3_m3((*deformmats)[i], tmat);
406                 }
407
408                 MEM_freeN(origVerts);
409                 MEM_freeN(quats);
410         }
411
412         if (!*deformmats) {
413                 int a, numVerts;
414                 Mesh *me = (Mesh *)ob->data;
415
416                 *deformcos = mesh_getVertexCos(me, &numVerts);
417                 *deformmats = MEM_callocN(sizeof(*(*deformmats)) * numVerts, "defmats");
418
419                 for (a = 0; a < numVerts; a++)
420                         unit_m3((*deformmats)[a]);
421         }
422 }