style cleanup: also rename bmesh_decimate.c --> bmesh_decimate_collapse.c
[blender.git] / source / blender / editors / object / object_lattice.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) 2001-2002 by NaN Holding BV.
19  * All rights reserved.
20  *
21  * Contributor(s): Blender Foundation
22  *
23  * ***** END GPL LICENSE BLOCK *****
24  */
25
26 /** \file blender/editors/object/object_lattice.c
27  *  \ingroup edobj
28  */
29
30
31 #include <stdlib.h>
32 #include <string.h>
33 #include <math.h>
34
35 #include "MEM_guardedalloc.h"
36
37 #include "BLI_listbase.h"
38 #include "BLI_math.h"
39 #include "BLI_utildefines.h"
40
41 #include "DNA_curve_types.h"
42 #include "DNA_key_types.h"
43 #include "DNA_lattice_types.h"
44 #include "DNA_meshdata_types.h"
45 #include "DNA_object_types.h"
46 #include "DNA_scene_types.h"
47
48 #include "RNA_access.h"
49 #include "RNA_define.h"
50
51 #include "BKE_context.h"
52 #include "BKE_depsgraph.h"
53 #include "BKE_key.h"
54 #include "BKE_lattice.h"
55 #include "BKE_mesh.h"
56
57 #include "ED_lattice.h"
58 #include "ED_object.h"
59 #include "ED_screen.h"
60 #include "ED_view3d.h"
61 #include "ED_util.h"
62
63 #include "WM_api.h"
64 #include "WM_types.h"
65
66 #include "object_intern.h"
67
68 /********************** Load/Make/Free ********************/
69
70 void free_editLatt(Object *ob)
71 {
72         Lattice *lt = ob->data;
73         
74         if (lt->editlatt) {
75                 Lattice *editlt = lt->editlatt->latt;
76
77                 if (editlt->def)
78                         MEM_freeN(editlt->def);
79                 if (editlt->dvert)
80                         free_dverts(editlt->dvert, editlt->pntsu * editlt->pntsv * editlt->pntsw);
81
82                 MEM_freeN(editlt);
83                 MEM_freeN(lt->editlatt);
84
85                 lt->editlatt = NULL;
86         }
87 }
88
89 void make_editLatt(Object *obedit)
90 {
91         Lattice *lt = obedit->data;
92         KeyBlock *actkey;
93
94         free_editLatt(obedit);
95
96         actkey = BKE_keyblock_from_object(obedit);
97         if (actkey)
98                 BKE_key_convert_to_lattice(actkey, lt);
99
100         lt->editlatt = MEM_callocN(sizeof(EditLatt), "editlatt");
101         lt->editlatt->latt = MEM_dupallocN(lt);
102         lt->editlatt->latt->def = MEM_dupallocN(lt->def);
103
104         if (lt->dvert) {
105                 int tot = lt->pntsu * lt->pntsv * lt->pntsw;
106                 lt->editlatt->latt->dvert = MEM_mallocN(sizeof(MDeformVert) * tot, "Lattice MDeformVert");
107                 copy_dverts(lt->editlatt->latt->dvert, lt->dvert, tot);
108         }
109
110         if (lt->key) lt->editlatt->shapenr = obedit->shapenr;
111 }
112
113 void load_editLatt(Object *obedit)
114 {
115         Lattice *lt, *editlt;
116         KeyBlock *actkey;
117         BPoint *bp;
118         float *fp;
119         int tot;
120
121         lt = obedit->data;
122         editlt = lt->editlatt->latt;
123
124         if (lt->editlatt->shapenr) {
125                 actkey = BLI_findlink(&lt->key->block, lt->editlatt->shapenr - 1);
126
127                 /* active key: vertices */
128                 tot = editlt->pntsu * editlt->pntsv * editlt->pntsw;
129                 
130                 if (actkey->data) MEM_freeN(actkey->data);
131                 
132                 fp = actkey->data = MEM_callocN(lt->key->elemsize * tot, "actkey->data");
133                 actkey->totelem = tot;
134
135                 bp = editlt->def;
136                 while (tot--) {
137                         copy_v3_v3(fp, bp->vec);
138                         fp += 3;
139                         bp++;
140                 }
141         }
142         else {
143                 MEM_freeN(lt->def);
144
145                 lt->def = MEM_dupallocN(editlt->def);
146
147                 lt->flag = editlt->flag;
148
149                 lt->pntsu = editlt->pntsu;
150                 lt->pntsv = editlt->pntsv;
151                 lt->pntsw = editlt->pntsw;
152                 
153                 lt->typeu = editlt->typeu;
154                 lt->typev = editlt->typev;
155                 lt->typew = editlt->typew;
156         }
157
158         if (lt->dvert) {
159                 free_dverts(lt->dvert, lt->pntsu * lt->pntsv * lt->pntsw);
160                 lt->dvert = NULL;
161         }
162
163         if (editlt->dvert) {
164                 tot = lt->pntsu * lt->pntsv * lt->pntsw;
165
166                 lt->dvert = MEM_mallocN(sizeof(MDeformVert) * tot, "Lattice MDeformVert");
167                 copy_dverts(lt->dvert, editlt->dvert, tot);
168         }
169 }
170
171 /************************** Select All Operator *************************/
172
173 void ED_setflagsLatt(Object *obedit, int flag)
174 {
175         Lattice *lt = obedit->data;
176         BPoint *bp;
177         int a;
178         
179         bp = lt->editlatt->latt->def;
180         
181         a = lt->editlatt->latt->pntsu * lt->editlatt->latt->pntsv * lt->editlatt->latt->pntsw;
182         
183         while (a--) {
184                 if (bp->hide == 0) {
185                         bp->f1 = flag;
186                 }
187                 bp++;
188         }
189 }
190
191 static int lattice_select_all_exec(bContext *C, wmOperator *op)
192 {
193         Object *obedit = CTX_data_edit_object(C);
194         Lattice *lt = obedit->data;
195         BPoint *bp;
196         int a;
197         int action = RNA_enum_get(op->ptr, "action");
198
199         if (action == SEL_TOGGLE) {
200                 action = SEL_SELECT;
201
202                 bp = lt->editlatt->latt->def;
203                 a = lt->editlatt->latt->pntsu * lt->editlatt->latt->pntsv * lt->editlatt->latt->pntsw;
204
205                 while (a--) {
206                         if (bp->hide == 0) {
207                                 if (bp->f1 & SELECT) {
208                                         action = SEL_DESELECT;
209                                         break;
210                                 }
211                         }
212                         bp++;
213                 }
214         }
215
216         switch (action) {
217                 case SEL_SELECT:
218                         ED_setflagsLatt(obedit, 1);
219                         break;
220                 case SEL_DESELECT:
221                         ED_setflagsLatt(obedit, 0);
222                         break;
223                 case SEL_INVERT:
224                         bp = lt->editlatt->latt->def;
225                         a = lt->editlatt->latt->pntsu * lt->editlatt->latt->pntsv * lt->editlatt->latt->pntsw;
226
227                         while (a--) {
228                                 if (bp->hide == 0) {
229                                         bp->f1 ^= SELECT;
230                                 }
231                                 bp++;
232                         }
233                         break;
234         }
235
236         WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
237
238         return OPERATOR_FINISHED;
239 }
240
241 void LATTICE_OT_select_all(wmOperatorType *ot)
242 {
243         /* identifiers */
244         ot->name = "(De)select All";
245         ot->description = "Change selection of all UVW control points";
246         ot->idname = "LATTICE_OT_select_all";
247         
248         /* api callbacks */
249         ot->exec = lattice_select_all_exec;
250         ot->poll = ED_operator_editlattice;
251         
252         /* flags */
253         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
254
255         WM_operator_properties_select_all(ot);
256 }
257
258 /************************** Make Regular Operator *************************/
259
260 static int make_regular_poll(bContext *C)
261 {
262         Object *ob;
263
264         if (ED_operator_editlattice(C)) return 1;
265
266         ob = CTX_data_active_object(C);
267         return (ob && ob->type == OB_LATTICE);
268 }
269
270 static int make_regular_exec(bContext *C, wmOperator *UNUSED(op))
271 {
272         Object *ob = CTX_data_edit_object(C);
273         Lattice *lt;
274         
275         if (ob) {
276                 lt = ob->data;
277                 BKE_lattice_resize(lt->editlatt->latt, lt->pntsu, lt->pntsv, lt->pntsw, NULL);
278         }
279         else {
280                 ob = CTX_data_active_object(C);
281                 lt = ob->data;
282                 BKE_lattice_resize(lt, lt->pntsu, lt->pntsv, lt->pntsw, NULL);
283         }
284         
285         DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
286         WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data);
287
288         return OPERATOR_FINISHED;
289 }
290
291 void LATTICE_OT_make_regular(wmOperatorType *ot)
292 {
293         /* identifiers */
294         ot->name = "Make Regular";
295         ot->description = "Set UVW control points a uniform distance apart";
296         ot->idname = "LATTICE_OT_make_regular";
297         
298         /* api callbacks */
299         ot->exec = make_regular_exec;
300         ot->poll = make_regular_poll;
301         
302         /* flags */
303         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
304 }
305
306 /************************** Flip Verts Operator *************************/
307
308 /* flipping options */
309 typedef enum eLattice_FlipAxes {
310         LATTICE_FLIP_U = 0,
311         LATTICE_FLIP_V = 1,
312         LATTICE_FLIP_W = 2
313 } eLattice_FlipAxes;
314
315 /* Helper macro for accessing item at index (u, v, w) 
316  * < lt: (Lattice)
317  * < U: (int) u-axis coordinate of point
318  * < V: (int) v-axis coordinate of point
319  * < W: (int) w-axis coordinate of point
320  * < dimU: (int) number of points per row or number of columns (U-Axis)
321  * < dimV: (int) number of rows (V-Axis)
322  * > returns: (BPoint *) pointer to BPoint at this index
323  */
324 #define LATTICE_PT(lt, U, V, W, dimU, dimV)       \
325         ( (lt)->def               +                   \
326           ((dimU) * (dimV)) * (W) +                   \
327           (dimU) * (V)            +                   \
328           (U)                                         \
329         )
330         
331 /* Flip midpoint value so that relative distances between midpoint and neighbour-pair is maintained
332  * ! Assumes that uvw <=> xyz (i.e. axis-aligned index-axes with coordinate-axes)
333  * - Helper for lattice_flip_exec()
334  */
335 static void lattice_flip_point_value(Lattice *lt, int u, int v, int w, float mid, eLattice_FlipAxes axis)
336 {
337         BPoint *bp;
338         float diff;
339         
340         /* just the point in the middle (unpaired) */
341         bp = LATTICE_PT(lt, u, v, w, lt->pntsu, lt->pntsv);
342         
343         /* flip over axis */
344         diff = mid - bp->vec[axis];
345         bp->vec[axis] = mid + diff;
346 }
347
348 /* Swap pairs of lattice points along a specified axis
349  * - Helper for lattice_flip_exec()
350  */
351 static void lattice_swap_point_pairs(Lattice *lt, int u, int v, int w, float mid, eLattice_FlipAxes axis)
352 {
353         BPoint *bpA, *bpB;
354         
355         int numU = lt->pntsu;
356         int numV = lt->pntsv;
357         int numW = lt->pntsw;
358         
359         int u0 = u, u1 = u;
360         int v0 = v, v1 = v;
361         int w0 = w, w1 = w;
362         
363         /* get pair index by just overriding the relevant pair-value
364          * - "-1" else buffer overflow
365          */
366         switch (axis) {
367                 case LATTICE_FLIP_U:
368                         u1 = numU - u - 1;
369                         break;
370                 case LATTICE_FLIP_V:
371                         v1 = numV - v - 1;
372                         break;
373                 case LATTICE_FLIP_W:
374                         w1 = numW - w - 1;
375                         break;
376         }
377         
378         /* get points to operate on */
379         bpA = LATTICE_PT(lt, u0, v0, w0, numU, numV);
380         bpB = LATTICE_PT(lt, u1, v1, w1, numU, numV);
381         
382         /* Swap all coordinates, so that flipped coordinates belong to
383          * the indices on the correct side of the lattice.
384          *
385          *   Coords:  (-2 4) |0| (3 4)   --> (3 4) |0| (-2 4) 
386          *   Indices:  (0,L)     (1,R)   --> (0,L)     (1,R)
387          */
388         swap_v3_v3(bpA->vec, bpB->vec);
389         
390         /* However, we need to mirror the coordinate values on the axis we're dealing with,
391          * otherwise we'd have effectively only rotated the points around. If we don't do this,
392          * we'd just be reimplementing the naive mirroring algorithm, which causes unwanted deforms
393          * such as flipped normals, etc.
394          *
395          *   Coords:  (3 4) |0| (-2 4)  --\   
396          *                                 \-> (-3 4) |0| (2 4)
397          *   Indices: (0,L)     (1,R)   -->     (0,L)     (1,R)
398          */
399         lattice_flip_point_value(lt, u0, v0, w0, mid, axis);
400         lattice_flip_point_value(lt, u1, v1, w1, mid, axis);
401 }
402         
403 static int lattice_flip_exec(bContext *C, wmOperator *op)
404 {
405         Object *obedit = CTX_data_edit_object(C);
406         Lattice *lt;
407         
408         eLattice_FlipAxes axis = RNA_enum_get(op->ptr, "axis");
409         int numU, numV, numW;
410         int totP;
411         
412         float mid = 0.0f;
413         short isOdd = 0;
414         
415         /* get lattice - we need the "edit lattice" from the lattice... confusing... */
416         lt = (Lattice *)obedit->data;
417         lt = lt->editlatt->latt;
418         
419         numU = lt->pntsu;
420         numV = lt->pntsv;
421         numW = lt->pntsw;
422         totP = numU * numV * numW;
423         
424         /* First Pass: determine midpoint - used for flipping center verts if there are odd number of points on axis */
425         switch (axis) {
426                 case LATTICE_FLIP_U:
427                         isOdd = numU & 1;
428                         break;
429                 case LATTICE_FLIP_V:
430                         isOdd = numV & 1;
431                         break;
432                 case LATTICE_FLIP_W:
433                         isOdd = numW & 1;
434                         break;
435                         
436                 default:
437                         printf("lattice_flip(): Unknown flipping axis (%d)\n", axis);
438                         return OPERATOR_CANCELLED;
439         }
440         
441         if (isOdd) {
442                 BPoint *bp;
443                 float avgInv = 1.0f / (float)totP;
444                 int i;
445                 
446                 /* midpoint calculation - assuming that u/v/w are axis-aligned */
447                 for (i = 0, bp = lt->def; i < totP; i++, bp++) {
448                         mid += bp->vec[axis] * avgInv;
449                 }
450         }
451         
452         /* Second Pass: swap pairs of vertices per axis, assuming they are all sorted */
453         switch (axis) {
454                 case LATTICE_FLIP_U:
455                 {
456                         int u, v, w;
457                         
458                         /* v/w strips - front to back, top to bottom */
459                         for (w = 0; w < numW; w++) {
460                                 for (v = 0; v < numV; v++) {
461                                         /* swap coordinates of pairs of vertices on u */
462                                         for (u = 0; u < (numU / 2); u++) {
463                                                 lattice_swap_point_pairs(lt, u, v, w, mid, axis);
464                                         }
465                                         
466                                         /* flip u-coordinate of midpoint (i.e. unpaired point on u) */
467                                         if (isOdd) {
468                                                 u = (numU / 2);
469                                                 lattice_flip_point_value(lt, u, v, w, mid, axis);
470                                         }
471                                 }
472                         }
473                 }
474                 break;
475                 case LATTICE_FLIP_V:
476                 {
477                         int u, v, w;
478                         
479                         /* u/w strips - front to back, left to right */
480                         for (w = 0; w < numW; w++) {
481                                 for (u = 0; u < numU; u++) {
482                                         /* swap coordinates of pairs of vertices on v */
483                                         for (v = 0; v < (numV / 2); v++) {
484                                                 lattice_swap_point_pairs(lt, u, v, w, mid, axis);
485                                         }
486                                         
487                                         /* flip v-coordinate of midpoint (i.e. unpaired point on v) */
488                                         if (isOdd) {
489                                                 v = (numV / 2);
490                                                 lattice_flip_point_value(lt, u, v, w, mid, axis);
491                                         }
492                                 }
493                         }
494                 }
495                 break;
496                 case LATTICE_FLIP_W:
497                 {
498                         int u, v, w;
499                         
500                         for (v = 0; v < numV; v++) {
501                                 for (u = 0; u < numU; u++) {
502                                         /* swap coordinates of pairs of vertices on w */
503                                         for (w = 0; w < (numW / 2); w++) {
504                                                 lattice_swap_point_pairs(lt, u, v, w, mid, axis);
505                                         }
506                                         
507                                         /* flip w-coordinate of midpoint (i.e. unpaired point on w) */
508                                         if (isOdd) {
509                                                 w = (numW / 2);
510                                                 lattice_flip_point_value(lt, u, v, w, mid, axis);
511                                         }
512                                 }
513                         }
514                 }
515                 break;
516                 
517                 default: /* shouldn't happen, but just in case */
518                         break;
519         }
520         
521         /* updates */
522         DAG_id_tag_update(&obedit->id, OB_RECALC_DATA);
523         WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
524         
525         return OPERATOR_FINISHED;
526 }
527
528 void LATTICE_OT_flip(wmOperatorType *ot)
529 {
530         static EnumPropertyItem flip_items[] = {
531                 {LATTICE_FLIP_U, "U", 0, "U (X) Axis", ""},
532                 {LATTICE_FLIP_V, "V", 0, "V (Y) Axis", ""},
533                 {LATTICE_FLIP_W, "W", 0, "W (Z) Axis", ""},
534                 {0, NULL, 0, NULL, NULL}};
535         
536         /* identifiers */
537         ot->name = "Flip (Distortion Free)";
538         ot->description = "Mirror all control points without inverting the lattice deform";
539         ot->idname = "LATTICE_OT_flip";
540         
541         /* api callbacks */
542         ot->poll = ED_operator_editlattice;
543         ot->invoke = WM_menu_invoke;
544         ot->exec = lattice_flip_exec;
545         
546         /* flags */
547         ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
548         
549         /* properties */
550         ot->prop = RNA_def_enum(ot->srna, "axis", flip_items, LATTICE_FLIP_U, "Flip Axis", "Coordinates along this axis get flipped");
551 }
552
553 /****************************** Mouse Selection *************************/
554
555 static void findnearestLattvert__doClosest(void *userData, BPoint *bp, const float screen_co[2])
556 {
557         struct { BPoint *bp; float dist; int select; float mval_fl[2]; } *data = userData;
558         float dist_test = len_manhattan_v2v2(data->mval_fl, screen_co);
559         
560         if ((bp->f1 & SELECT) && data->select)
561                 dist_test += 5.0f;
562
563         if (dist_test < data->dist) {
564                 data->dist = dist_test;
565
566                 data->bp = bp;
567         }
568 }
569
570 static BPoint *findnearestLattvert(ViewContext *vc, const int mval[2], int sel)
571 {
572         /* (sel == 1): selected gets a disadvantage */
573         /* in nurb and bezt or bp the nearest is written */
574         /* return 0 1 2: handlepunt */
575         struct { BPoint *bp; float dist; int select; float mval_fl[2]; } data = {NULL};
576
577         data.dist = 100;
578         data.select = sel;
579         data.mval_fl[0] = mval[0];
580         data.mval_fl[1] = mval[1];
581
582         ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d);
583         lattice_foreachScreenVert(vc, findnearestLattvert__doClosest, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
584
585         return data.bp;
586 }
587
588 int mouse_lattice(bContext *C, const int mval[2], int extend, int deselect, int toggle)
589 {
590         ViewContext vc;
591         BPoint *bp = NULL;
592
593         view3d_set_viewcontext(C, &vc);
594         bp = findnearestLattvert(&vc, mval, TRUE);
595
596         if (bp) {
597                 if (extend) {
598                         bp->f1 |= SELECT;
599                 }
600                 else if (deselect) {
601                         bp->f1 &= ~SELECT;
602                 }
603                 else if (toggle) {
604                         bp->f1 ^= SELECT;  /* swap */
605                 }
606                 else {
607                         ED_setflagsLatt(vc.obedit, 0);
608                         bp->f1 |= SELECT;
609                 }
610
611                 WM_event_add_notifier(C, NC_GEOM | ND_SELECT, vc.obedit->data);
612
613                 return 1;
614         }
615
616         return 0;
617 }
618
619 /******************************** Undo *************************/
620
621 typedef struct UndoLattice {
622         BPoint *def;
623         int pntsu, pntsv, pntsw;
624 } UndoLattice;
625
626 static void undoLatt_to_editLatt(void *data, void *edata, void *UNUSED(obdata))
627 {
628         UndoLattice *ult = (UndoLattice *)data;
629         EditLatt *editlatt = (EditLatt *)edata;
630         int a = editlatt->latt->pntsu * editlatt->latt->pntsv * editlatt->latt->pntsw;
631
632         memcpy(editlatt->latt->def, ult->def, a * sizeof(BPoint));
633 }
634
635 static void *editLatt_to_undoLatt(void *edata, void *UNUSED(obdata))
636 {
637         UndoLattice *ult = MEM_callocN(sizeof(UndoLattice), "UndoLattice");
638         EditLatt *editlatt = (EditLatt *)edata;
639         
640         ult->def = MEM_dupallocN(editlatt->latt->def);
641         ult->pntsu = editlatt->latt->pntsu;
642         ult->pntsv = editlatt->latt->pntsv;
643         ult->pntsw = editlatt->latt->pntsw;
644         
645         return ult;
646 }
647
648 static void free_undoLatt(void *data)
649 {
650         UndoLattice *ult = (UndoLattice *)data;
651
652         if (ult->def) MEM_freeN(ult->def);
653         MEM_freeN(ult);
654 }
655
656 static int validate_undoLatt(void *data, void *edata)
657 {
658         UndoLattice *ult = (UndoLattice *)data;
659         EditLatt *editlatt = (EditLatt *)edata;
660
661         return (ult->pntsu == editlatt->latt->pntsu &&
662                 ult->pntsv == editlatt->latt->pntsv &&
663                 ult->pntsw == editlatt->latt->pntsw);
664 }
665
666 static void *get_editlatt(bContext *C)
667 {
668         Object *obedit = CTX_data_edit_object(C);
669
670         if (obedit && obedit->type == OB_LATTICE) {
671                 Lattice *lt = obedit->data;
672                 return lt->editlatt;
673         }
674
675         return NULL;
676 }
677
678 /* and this is all the undo system needs to know */
679 void undo_push_lattice(bContext *C, const char *name)
680 {
681         undo_editmode_push(C, name, get_editlatt, free_undoLatt, undoLatt_to_editLatt, editLatt_to_undoLatt, validate_undoLatt);
682 }
683