69
70
void free_editLatt(Object *ob)
71
Lattice *lt= ob->data;
72
Lattice *lt = ob->data;
73
74
if (lt->editlatt) {
74
Lattice *editlt= lt->editlatt->latt;
75
Lattice *editlt = lt->editlatt->latt;
77
78
MEM_freeN(editlt->def);
79
free_dverts(editlt->dvert, editlt->pntsu*editlt->pntsv*editlt->pntsw);
80
BKE_defvert_array_free(editlt->dvert, editlt->pntsu * editlt->pntsv * editlt->pntsw);
82
83
MEM_freeN(lt->editlatt);
88
89
void make_editLatt(Object *obedit)
90
Lattice *lt= obedit->data;
91
Lattice *lt = obedit->data;
93
94
free_editLatt(obedit);
95
actkey= ob_get_keyblock(obedit);
96
actkey = BKE_keyblock_from_object(obedit);
97
key_to_latt(actkey, lt);
98
BKE_key_convert_to_lattice(actkey, lt);
99
lt->editlatt= MEM_callocN(sizeof(EditLatt), "editlatt");
100
lt->editlatt->latt= MEM_dupallocN(lt);
101
lt->editlatt->latt->def= MEM_dupallocN(lt->def);
100
lt->editlatt = MEM_callocN(sizeof(EditLatt), "editlatt");
101
lt->editlatt->latt = MEM_dupallocN(lt);
102
lt->editlatt->latt->def = MEM_dupallocN(lt->def);
104
int tot= lt->pntsu*lt->pntsv*lt->pntsw;
105
lt->editlatt->latt->dvert = MEM_mallocN (sizeof (MDeformVert)*tot, "Lattice MDeformVert");
106
copy_dverts(lt->editlatt->latt->dvert, lt->dvert, tot);
105
int tot = lt->pntsu * lt->pntsv * lt->pntsw;
106
lt->editlatt->latt->dvert = MEM_mallocN(sizeof(MDeformVert) * tot, "Lattice MDeformVert");
107
BKE_defvert_array_copy(lt->editlatt->latt->dvert, lt->dvert, tot);
109
if (lt->key) lt->editlatt->shapenr= obedit->shapenr;
110
if (lt->key) lt->editlatt->shapenr = obedit->shapenr;
112
113
void load_editLatt(Object *obedit)
121
editlt= lt->editlatt->latt;
122
editlt = lt->editlatt->latt;
123
124
if (lt->editlatt->shapenr) {
124
actkey= BLI_findlink(<->key->block, lt->editlatt->shapenr-1);
125
actkey = BLI_findlink(<->key->block, lt->editlatt->shapenr - 1);
126
127
/* active key: vertices */
127
tot= editlt->pntsu*editlt->pntsv*editlt->pntsw;
128
tot = editlt->pntsu * editlt->pntsv * editlt->pntsw;
129
130
if (actkey->data) MEM_freeN(actkey->data);
131
fp=actkey->data= MEM_callocN(lt->key->elemsize*tot, "actkey->data");
132
actkey->totelem= tot;
132
fp = actkey->data = MEM_callocN(lt->key->elemsize * tot, "actkey->data");
133
actkey->totelem = tot;
136
137
copy_v3_v3(fp, bp->vec);
142
143
MEM_freeN(lt->def);
144
lt->def= MEM_dupallocN(editlt->def);
146
lt->flag= editlt->flag;
148
lt->pntsu= editlt->pntsu;
149
lt->pntsv= editlt->pntsv;
150
lt->pntsw= editlt->pntsw;
145
lt->def = MEM_dupallocN(editlt->def);
147
lt->flag = editlt->flag;
149
lt->pntsu = editlt->pntsu;
150
lt->pntsv = editlt->pntsv;
151
lt->pntsw = editlt->pntsw;
152
lt->typeu= editlt->typeu;
153
lt->typev= editlt->typev;
154
lt->typew= editlt->typew;
153
lt->typeu = editlt->typeu;
154
lt->typev = editlt->typev;
155
lt->typew = editlt->typew;
158
free_dverts(lt->dvert, lt->pntsu*lt->pntsv*lt->pntsw);
159
BKE_defvert_array_free(lt->dvert, lt->pntsu * lt->pntsv * lt->pntsw);
162
163
if (editlt->dvert) {
163
tot= lt->pntsu*lt->pntsv*lt->pntsw;
164
tot = lt->pntsu * lt->pntsv * lt->pntsw;
165
lt->dvert = MEM_mallocN (sizeof (MDeformVert)*tot, "Lattice MDeformVert");
166
copy_dverts(lt->dvert, editlt->dvert, tot);
166
lt->dvert = MEM_mallocN(sizeof(MDeformVert) * tot, "Lattice MDeformVert");
167
BKE_defvert_array_copy(lt->dvert, editlt->dvert, tot);
170
/************************** Operators *************************/
171
/************************** Select All Operator *************************/
172
173
void ED_setflagsLatt(Object *obedit, int flag)
174
Lattice *lt= obedit->data;
175
Lattice *lt = obedit->data;
178
bp= lt->editlatt->latt->def;
179
bp = lt->editlatt->latt->def;
180
a= lt->editlatt->latt->pntsu*lt->editlatt->latt->pntsv*lt->editlatt->latt->pntsw;
181
a = lt->editlatt->latt->pntsu * lt->editlatt->latt->pntsv * lt->editlatt->latt->pntsw;
249
250
ot->poll = ED_operator_editlattice;
252
ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
253
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
254
255
WM_operator_properties_select_all(ot);
258
/************************** Make Regular Operator *************************/
257
260
static int make_regular_poll(bContext *C)
261
264
if (ED_operator_editlattice(C)) return 1;
263
ob= CTX_data_active_object(C);
264
return (ob && ob->type==OB_LATTICE);
266
ob = CTX_data_active_object(C);
267
return (ob && ob->type == OB_LATTICE);
267
270
static int make_regular_exec(bContext *C, wmOperator *UNUSED(op))
269
Object *ob= CTX_data_edit_object(C);
272
Object *ob = CTX_data_edit_object(C);
274
resizelattice(lt->editlatt->latt, lt->pntsu, lt->pntsv, lt->pntsw, NULL);
277
BKE_lattice_resize(lt->editlatt->latt, lt->pntsu, lt->pntsv, lt->pntsw, NULL);
277
ob= CTX_data_active_object(C);
279
resizelattice(lt, lt->pntsu, lt->pntsv, lt->pntsw, NULL);
280
ob = CTX_data_active_object(C);
282
BKE_lattice_resize(lt, lt->pntsu, lt->pntsv, lt->pntsw, NULL);
282
285
DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
283
WM_event_add_notifier(C, NC_GEOM|ND_DATA, ob->data);
286
WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data);
285
288
return OPERATOR_FINISHED;
297
300
ot->poll = make_regular_poll;
300
ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO;
303
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
306
/************************** Flip Verts Operator *************************/
308
/* flipping options */
309
typedef enum eLattice_FlipAxes {
315
/* Helper macro for accessing item at index (u, v, w)
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
324
#define LATTICE_PT(lt, U, V, W, dimU, dimV) \
326
((dimU) * (dimV)) * (W) + \
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()
335
static void lattice_flip_point_value(Lattice *lt, int u, int v, int w, float mid, eLattice_FlipAxes axis)
340
/* just the point in the middle (unpaired) */
341
bp = LATTICE_PT(lt, u, v, w, lt->pntsu, lt->pntsv);
344
diff = mid - bp->vec[axis];
345
bp->vec[axis] = mid + diff;
348
/* Swap pairs of lattice points along a specified axis
349
* - Helper for lattice_flip_exec()
351
static void lattice_swap_point_pairs(Lattice *lt, int u, int v, int w, float mid, eLattice_FlipAxes axis)
355
int numU = lt->pntsu;
356
int numV = lt->pntsv;
357
int numW = lt->pntsw;
363
/* get pair index by just overriding the relevant pair-value
364
* - "-1" else buffer overflow
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);
382
/* Swap all coordinates, so that flipped coordinates belong to
383
* the indices on the correct side of the lattice.
385
* Coords: (-2 4) |0| (3 4) --> (3 4) |0| (-2 4)
386
* Indices: (0,L) (1,R) --> (0,L) (1,R)
388
swap_v3_v3(bpA->vec, bpB->vec);
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.
395
* Coords: (3 4) |0| (-2 4) --\
396
* \-> (-3 4) |0| (2 4)
397
* Indices: (0,L) (1,R) --> (0,L) (1,R)
399
lattice_flip_point_value(lt, u0, v0, w0, mid, axis);
400
lattice_flip_point_value(lt, u1, v1, w1, mid, axis);
403
static int lattice_flip_exec(bContext *C, wmOperator *op)
405
Object *obedit = CTX_data_edit_object(C);
408
eLattice_FlipAxes axis = RNA_enum_get(op->ptr, "axis");
409
int numU, numV, numW;
415
/* get lattice - we need the "edit lattice" from the lattice... confusing... */
416
lt = (Lattice *)obedit->data;
417
lt = lt->editlatt->latt;
422
totP = numU * numV * numW;
424
/* First Pass: determine midpoint - used for flipping center verts if there are odd number of points on axis */
437
printf("lattice_flip(): Unknown flipping axis (%d)\n", axis);
438
return OPERATOR_CANCELLED;
443
float avgInv = 1.0f / (float)totP;
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;
452
/* Second Pass: swap pairs of vertices per axis, assuming they are all sorted */
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);
466
/* flip u-coordinate of midpoint (i.e. unpaired point on u) */
469
lattice_flip_point_value(lt, u, v, w, mid, axis);
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);
487
/* flip v-coordinate of midpoint (i.e. unpaired point on v) */
490
lattice_flip_point_value(lt, u, v, w, mid, axis);
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);
507
/* flip w-coordinate of midpoint (i.e. unpaired point on w) */
510
lattice_flip_point_value(lt, u, v, w, mid, axis);
517
default: /* shouldn't happen, but just in case */
522
DAG_id_tag_update(&obedit->id, OB_RECALC_DATA);
523
WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
525
return OPERATOR_FINISHED;
528
void LATTICE_OT_flip(wmOperatorType *ot)
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}};
537
ot->name = "Flip (Distortion Free)";
538
ot->description = "Mirror all control points without inverting the lattice deform";
539
ot->idname = "LATTICE_OT_flip";
542
ot->poll = ED_operator_editlattice;
543
ot->invoke = WM_menu_invoke;
544
ot->exec = lattice_flip_exec;
547
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
550
ot->prop = RNA_def_enum(ot->srna, "axis", flip_items, LATTICE_FLIP_U, "Flip Axis", "Coordinates along this axis get flipped");
303
553
/****************************** Mouse Selection *************************/
305
static void findnearestLattvert__doClosest(void *userData, BPoint *bp, int x, int y)
555
static void findnearestLattvert__doClosest(void *userData, BPoint *bp, const float screen_co[2])
307
struct { BPoint *bp; short dist, select; int mval[2]; } *data = userData;
308
float temp = abs(data->mval[0]-x) + abs(data->mval[1]-y);
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);
310
if ((bp->f1 & SELECT)==data->select)
560
if ((bp->f1 & SELECT) && data->select)
313
if (temp<data->dist) {
563
if (dist_test < data->dist) {
564
data->dist = dist_test;
320
570
static BPoint *findnearestLattvert(ViewContext *vc, const int mval[2], int sel)
322
/* sel==1: selected gets a disadvantage */
323
/* in nurb and bezt or bp the nearest is written */
324
/* return 0 1 2: handlepunt */
325
struct { BPoint *bp; short dist, select; int mval[2]; } data = {NULL};
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};
328
578
data.select = sel;
329
data.mval[0]= mval[0];
330
data.mval[1]= mval[1];
579
data.mval_fl[0] = mval[0];
580
data.mval_fl[1] = mval[1];
332
582
ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d);
333
lattice_foreachScreenVert(vc, findnearestLattvert__doClosest, &data);
583
lattice_foreachScreenVert(vc, findnearestLattvert__doClosest, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
338
int mouse_lattice(bContext *C, const int mval[2], int extend)
588
int mouse_lattice(bContext *C, const int mval[2], int extend, int deselect, int toggle)
343
593
view3d_set_viewcontext(C, &vc);
344
bp= findnearestLattvert(&vc, mval, 1);
594
bp = findnearestLattvert(&vc, mval, TRUE);
604
bp->f1 ^= SELECT; /* swap */
348
607
ED_setflagsLatt(vc.obedit, 0);
349
608
bp->f1 |= SELECT;
352
bp->f1 ^= SELECT; /* swap */
354
WM_event_add_notifier(C, NC_GEOM|ND_SELECT, vc.obedit->data);
611
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, vc.obedit->data);
369
626
static void undoLatt_to_editLatt(void *data, void *edata, void *UNUSED(obdata))
371
UndoLattice *ult= (UndoLattice*)data;
372
EditLatt *editlatt= (EditLatt *)edata;
373
int a= editlatt->latt->pntsu*editlatt->latt->pntsv*editlatt->latt->pntsw;
628
UndoLattice *ult = (UndoLattice *)data;
629
EditLatt *editlatt = (EditLatt *)edata;
630
int a = editlatt->latt->pntsu * editlatt->latt->pntsv * editlatt->latt->pntsw;
375
memcpy(editlatt->latt->def, ult->def, a*sizeof(BPoint));
632
memcpy(editlatt->latt->def, ult->def, a * sizeof(BPoint));
378
635
static void *editLatt_to_undoLatt(void *edata, void *UNUSED(obdata))
380
UndoLattice *ult= MEM_callocN(sizeof(UndoLattice), "UndoLattice");
381
EditLatt *editlatt= (EditLatt *)edata;
637
UndoLattice *ult = MEM_callocN(sizeof(UndoLattice), "UndoLattice");
638
EditLatt *editlatt = (EditLatt *)edata;
383
ult->def= MEM_dupallocN(editlatt->latt->def);
384
ult->pntsu= editlatt->latt->pntsu;
385
ult->pntsv= editlatt->latt->pntsv;
386
ult->pntsw= editlatt->latt->pntsw;
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;
391
648
static void free_undoLatt(void *data)
393
UndoLattice *ult= (UndoLattice*)data;
650
UndoLattice *ult = (UndoLattice *)data;
395
652
if (ult->def) MEM_freeN(ult->def);