4 * ***** BEGIN GPL LICENSE BLOCK *****
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.
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.
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
21 * All rights reserved.
23 * Contributor(s): Blender Foundation
25 * ***** END GPL LICENSE BLOCK *****
32 #include "MEM_guardedalloc.h"
34 #include "BLI_blenlib.h"
35 #include "BLI_arithb.h"
37 #include "DNA_curve_types.h"
38 #include "DNA_key_types.h"
39 #include "DNA_lattice_types.h"
40 #include "DNA_meshdata_types.h"
41 #include "DNA_object_types.h"
42 #include "DNA_scene_types.h"
43 #include "DNA_view3d_types.h"
45 #include "BKE_armature.h"
46 #include "BKE_context.h"
47 #include "BKE_depsgraph.h"
48 #include "BKE_global.h"
50 #include "BKE_lattice.h"
52 #include "BKE_utildefines.h"
54 #include "ED_object.h"
55 #include "ED_screen.h"
56 #include "ED_view3d.h"
62 #include "object_intern.h"
64 /********************** Load/Make/Free ********************/
66 void free_editLatt(Object *ob)
68 Lattice *lt= ob->data;
72 MEM_freeN(lt->editlatt->def);
73 if(lt->editlatt->dvert)
74 free_dverts(lt->editlatt->dvert, lt->editlatt->pntsu*lt->editlatt->pntsv*lt->editlatt->pntsw);
76 MEM_freeN(lt->editlatt);
81 void make_editLatt(Object *obedit)
83 Lattice *lt= obedit->data;
86 free_editLatt(obedit);
90 actkey= ob_get_keyblock(obedit);
92 key_to_latt(actkey, lt);
94 lt->editlatt= MEM_dupallocN(lt);
95 lt->editlatt->def= MEM_dupallocN(lt->def);
98 int tot= lt->pntsu*lt->pntsv*lt->pntsw;
99 lt->editlatt->dvert = MEM_mallocN (sizeof (MDeformVert)*tot, "Lattice MDeformVert");
100 copy_dverts(lt->editlatt->dvert, lt->dvert, tot);
104 void load_editLatt(Object *obedit)
114 actkey= ob_get_keyblock(obedit);
117 /* active key: vertices */
118 tot= lt->editlatt->pntsu*lt->editlatt->pntsv*lt->editlatt->pntsw;
120 if(actkey->data) MEM_freeN(actkey->data);
122 fp=actkey->data= MEM_callocN(lt->key->elemsize*tot, "actkey->data");
123 actkey->totelem= tot;
125 bp= lt->editlatt->def;
127 VECCOPY(fp, bp->vec);
135 lt->def= MEM_dupallocN(lt->editlatt->def);
137 lt->flag= lt->editlatt->flag;
139 lt->pntsu= lt->editlatt->pntsu;
140 lt->pntsv= lt->editlatt->pntsv;
141 lt->pntsw= lt->editlatt->pntsw;
143 lt->typeu= lt->editlatt->typeu;
144 lt->typev= lt->editlatt->typev;
145 lt->typew= lt->editlatt->typew;
149 free_dverts(lt->dvert, lt->pntsu*lt->pntsv*lt->pntsw);
153 if(lt->editlatt->dvert) {
154 int tot= lt->pntsu*lt->pntsv*lt->pntsw;
156 lt->dvert = MEM_mallocN (sizeof (MDeformVert)*tot, "Lattice MDeformVert");
157 copy_dverts(lt->dvert, lt->editlatt->dvert, tot);
161 /************************** Operators *************************/
163 static void setflagsLatt(Object *obedit, int flag)
165 Lattice *lt= obedit->data;
169 bp= lt->editlatt->def;
171 a= lt->editlatt->pntsu*lt->editlatt->pntsv*lt->editlatt->pntsw;
181 int de_select_all_exec(bContext *C, wmOperator *op)
183 Object *obedit= CTX_data_edit_object(C);
184 Lattice *lt= obedit->data;
188 bp= lt->editlatt->def;
189 a= lt->editlatt->pntsu*lt->editlatt->pntsv*lt->editlatt->pntsw;
202 setflagsLatt(obedit, 0);
204 setflagsLatt(obedit, 1);
206 WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, obedit);
208 return OPERATOR_FINISHED;
211 void LATTICE_OT_select_all_toggle(wmOperatorType *ot)
214 ot->name= "Select or Deselect All";
215 ot->idname= "LATTICE_OT_select_all_toggle";
218 ot->exec= de_select_all_exec;
219 ot->poll= ED_operator_editlattice;
222 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
225 int make_regular_poll(bContext *C)
229 if(ED_operator_editlattice(C)) return 1;
231 ob= CTX_data_active_object(C);
232 return (ob && ob->type==OB_LATTICE);
235 int make_regular_exec(bContext *C, wmOperator *op)
237 Scene *scene= CTX_data_scene(C);
238 Object *ob= CTX_data_edit_object(C);
243 resizelattice(lt->editlatt, lt->pntsu, lt->pntsv, lt->pntsw, NULL);
246 ob= CTX_data_active_object(C);
248 resizelattice(lt, lt->pntsu, lt->pntsv, lt->pntsw, NULL);
251 DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
252 WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_DATA, ob);
254 return OPERATOR_FINISHED;
257 void LATTICE_OT_make_regular(wmOperatorType *ot)
260 ot->name= "Make Regular";
261 ot->idname= "LATTICE_OT_make_regular";
264 ot->exec= make_regular_exec;
265 ot->poll= make_regular_poll;
268 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
271 /****************************** Mouse Selection *************************/
273 static void findnearestLattvert__doClosest(void *userData, BPoint *bp, int x, int y)
275 struct { BPoint *bp; short dist, select, mval[2]; } *data = userData;
276 float temp = abs(data->mval[0]-x) + abs(data->mval[1]-y);
278 if((bp->f1 & SELECT)==data->select)
281 if(temp<data->dist) {
288 static BPoint *findnearestLattvert(ViewContext *vc, short mval[2], int sel)
290 /* sel==1: selected gets a disadvantage */
291 /* in nurb and bezt or bp the nearest is written */
292 /* return 0 1 2: handlepunt */
293 struct { BPoint *bp; short dist, select, mval[2]; } data = {0};
297 data.mval[0]= mval[0];
298 data.mval[1]= mval[1];
300 lattice_foreachScreenVert(vc, findnearestLattvert__doClosest, &data);
305 void mouse_lattice(bContext *C, short mval[2], int extend)
310 view3d_set_viewcontext(C, &vc);
311 bp= findnearestLattvert(&vc, mval, 1);
315 setflagsLatt(vc.obedit, 0);
319 bp->f1 ^= SELECT; /* swap */
321 WM_event_add_notifier(C, NC_OBJECT|ND_GEOM_SELECT, vc.obedit);
325 /******************************** Undo *************************/
327 typedef struct UndoLattice {
329 int pntsu, pntsv, pntsw;
332 static void undoLatt_to_editLatt(void *data, void *edata)
334 UndoLattice *ult= (UndoLattice*)data;
335 Lattice *editlatt= (Lattice *)edata;
336 int a= editlatt->pntsu*editlatt->pntsv*editlatt->pntsw;
338 memcpy(editlatt->def, ult->def, a*sizeof(BPoint));
341 static void *editLatt_to_undoLatt(void *edata)
343 UndoLattice *ult= MEM_callocN(sizeof(UndoLattice), "UndoLattice");
344 Lattice *editlatt= (Lattice *)edata;
346 ult->def= MEM_dupallocN(editlatt->def);
347 ult->pntsu= editlatt->pntsu;
348 ult->pntsv= editlatt->pntsv;
349 ult->pntsw= editlatt->pntsw;
354 static void free_undoLatt(void *data)
356 UndoLattice *ult= (UndoLattice*)data;
358 if(ult->def) MEM_freeN(ult->def);
362 static int validate_undoLatt(void *data, void *edata)
364 UndoLattice *ult= (UndoLattice*)data;
365 Lattice *editlatt= (Lattice *)edata;
367 return (ult->pntsu == editlatt->pntsu &&
368 ult->pntsv == editlatt->pntsv &&
369 ult->pntsw == editlatt->pntsw);
372 static void *get_editlatt(bContext *C)
374 Object *obedit= CTX_data_edit_object(C);
376 if(obedit && obedit->type==OB_LATTICE) {
377 Lattice *lt= obedit->data;
384 /* and this is all the undo system needs to know */
385 void undo_push_lattice(bContext *C, char *name)
387 undo_editmode_push(C, name, get_editlatt, free_undoLatt, undoLatt_to_editLatt, editLatt_to_undoLatt, validate_undoLatt);