|
Blender
V2.59
|
00001 /* 00002 * $Id: object_lattice.c 36644 2011-05-12 16:47:36Z campbellbarton $ 00003 * 00004 * ***** BEGIN GPL LICENSE BLOCK ***** 00005 * 00006 * This program is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU General Public License 00008 * as published by the Free Software Foundation; either version 2 00009 * of the License, or (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software Foundation, 00018 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00019 * 00020 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. 00021 * All rights reserved. 00022 * 00023 * Contributor(s): Blender Foundation 00024 * 00025 * ***** END GPL LICENSE BLOCK ***** 00026 */ 00027 00033 #include <stdlib.h> 00034 #include <string.h> 00035 #include <math.h> 00036 00037 #include "MEM_guardedalloc.h" 00038 00039 #include "BLI_listbase.h" 00040 #include "BLI_utildefines.h" 00041 00042 #include "DNA_curve_types.h" 00043 #include "DNA_key_types.h" 00044 #include "DNA_lattice_types.h" 00045 #include "DNA_meshdata_types.h" 00046 #include "DNA_object_types.h" 00047 #include "DNA_scene_types.h" 00048 00049 #include "RNA_access.h" 00050 00051 #include "BKE_context.h" 00052 #include "BKE_depsgraph.h" 00053 #include "BKE_key.h" 00054 #include "BKE_lattice.h" 00055 #include "BKE_mesh.h" 00056 00057 #include "ED_lattice.h" 00058 #include "ED_object.h" 00059 #include "ED_screen.h" 00060 #include "ED_view3d.h" 00061 #include "ED_util.h" 00062 00063 #include "WM_api.h" 00064 #include "WM_types.h" 00065 00066 #include "object_intern.h" 00067 00068 /********************** Load/Make/Free ********************/ 00069 00070 void free_editLatt(Object *ob) 00071 { 00072 Lattice *lt= ob->data; 00073 00074 if(lt->editlatt) { 00075 Lattice *editlt= lt->editlatt->latt; 00076 00077 if(editlt->def) 00078 MEM_freeN(editlt->def); 00079 if(editlt->dvert) 00080 free_dverts(editlt->dvert, editlt->pntsu*editlt->pntsv*editlt->pntsw); 00081 00082 MEM_freeN(editlt); 00083 MEM_freeN(lt->editlatt); 00084 00085 lt->editlatt= NULL; 00086 } 00087 } 00088 00089 void make_editLatt(Object *obedit) 00090 { 00091 Lattice *lt= obedit->data; 00092 KeyBlock *actkey; 00093 00094 free_editLatt(obedit); 00095 00096 actkey= ob_get_keyblock(obedit); 00097 if(actkey) 00098 key_to_latt(actkey, lt); 00099 00100 lt->editlatt= MEM_callocN(sizeof(EditLatt), "editlatt"); 00101 lt->editlatt->latt= MEM_dupallocN(lt); 00102 lt->editlatt->latt->def= MEM_dupallocN(lt->def); 00103 00104 if(lt->dvert) { 00105 int tot= lt->pntsu*lt->pntsv*lt->pntsw; 00106 lt->editlatt->latt->dvert = MEM_mallocN (sizeof (MDeformVert)*tot, "Lattice MDeformVert"); 00107 copy_dverts(lt->editlatt->latt->dvert, lt->dvert, tot); 00108 } 00109 00110 if(lt->key) lt->editlatt->shapenr= obedit->shapenr; 00111 } 00112 00113 void load_editLatt(Object *obedit) 00114 { 00115 Lattice *lt, *editlt; 00116 KeyBlock *actkey; 00117 BPoint *bp; 00118 float *fp; 00119 int tot; 00120 00121 lt= obedit->data; 00122 editlt= lt->editlatt->latt; 00123 00124 if(lt->editlatt->shapenr) { 00125 actkey= BLI_findlink(<->key->block, lt->editlatt->shapenr-1); 00126 00127 /* active key: vertices */ 00128 tot= editlt->pntsu*editlt->pntsv*editlt->pntsw; 00129 00130 if(actkey->data) MEM_freeN(actkey->data); 00131 00132 fp=actkey->data= MEM_callocN(lt->key->elemsize*tot, "actkey->data"); 00133 actkey->totelem= tot; 00134 00135 bp= editlt->def; 00136 while(tot--) { 00137 VECCOPY(fp, bp->vec); 00138 fp+= 3; 00139 bp++; 00140 } 00141 } 00142 else { 00143 MEM_freeN(lt->def); 00144 00145 lt->def= MEM_dupallocN(editlt->def); 00146 00147 lt->flag= editlt->flag; 00148 00149 lt->pntsu= editlt->pntsu; 00150 lt->pntsv= editlt->pntsv; 00151 lt->pntsw= editlt->pntsw; 00152 00153 lt->typeu= editlt->typeu; 00154 lt->typev= editlt->typev; 00155 lt->typew= editlt->typew; 00156 } 00157 00158 if(lt->dvert) { 00159 free_dverts(lt->dvert, lt->pntsu*lt->pntsv*lt->pntsw); 00160 lt->dvert= NULL; 00161 } 00162 00163 if(editlt->dvert) { 00164 tot= lt->pntsu*lt->pntsv*lt->pntsw; 00165 00166 lt->dvert = MEM_mallocN (sizeof (MDeformVert)*tot, "Lattice MDeformVert"); 00167 copy_dverts(lt->dvert, editlt->dvert, tot); 00168 } 00169 } 00170 00171 /************************** Operators *************************/ 00172 00173 void ED_setflagsLatt(Object *obedit, int flag) 00174 { 00175 Lattice *lt= obedit->data; 00176 BPoint *bp; 00177 int a; 00178 00179 bp= lt->editlatt->latt->def; 00180 00181 a= lt->editlatt->latt->pntsu*lt->editlatt->latt->pntsv*lt->editlatt->latt->pntsw; 00182 00183 while(a--) { 00184 if(bp->hide==0) { 00185 bp->f1= flag; 00186 } 00187 bp++; 00188 } 00189 } 00190 00191 static int select_all_exec(bContext *C, wmOperator *op) 00192 { 00193 Object *obedit= CTX_data_edit_object(C); 00194 Lattice *lt= obedit->data; 00195 BPoint *bp; 00196 int a; 00197 int action = RNA_enum_get(op->ptr, "action"); 00198 00199 if (action == SEL_TOGGLE) { 00200 action = SEL_SELECT; 00201 00202 bp= lt->editlatt->latt->def; 00203 a= lt->editlatt->latt->pntsu*lt->editlatt->latt->pntsv*lt->editlatt->latt->pntsw; 00204 00205 while(a--) { 00206 if(bp->hide==0) { 00207 if(bp->f1) { 00208 action = SEL_DESELECT; 00209 break; 00210 } 00211 } 00212 bp++; 00213 } 00214 } 00215 00216 switch (action) { 00217 case SEL_SELECT: 00218 ED_setflagsLatt(obedit, 1); 00219 break; 00220 case SEL_DESELECT: 00221 ED_setflagsLatt(obedit, 0); 00222 break; 00223 case SEL_INVERT: 00224 bp= lt->editlatt->latt->def; 00225 a= lt->editlatt->latt->pntsu*lt->editlatt->latt->pntsv*lt->editlatt->latt->pntsw; 00226 00227 while(a--) { 00228 if(bp->hide==0) { 00229 bp->f1 ^= 1; 00230 } 00231 bp++; 00232 } 00233 break; 00234 } 00235 00236 WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data); 00237 00238 return OPERATOR_FINISHED; 00239 } 00240 00241 void LATTICE_OT_select_all(wmOperatorType *ot) 00242 { 00243 /* identifiers */ 00244 ot->name= "Select or Deselect All"; 00245 ot->description= "Change selection of all UVW control points"; 00246 ot->idname= "LATTICE_OT_select_all"; 00247 00248 /* api callbacks */ 00249 ot->exec= select_all_exec; 00250 ot->poll= ED_operator_editlattice; 00251 00252 /* flags */ 00253 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 00254 00255 WM_operator_properties_select_all(ot); 00256 } 00257 00258 static int make_regular_poll(bContext *C) 00259 { 00260 Object *ob; 00261 00262 if(ED_operator_editlattice(C)) return 1; 00263 00264 ob= CTX_data_active_object(C); 00265 return (ob && ob->type==OB_LATTICE); 00266 } 00267 00268 static int make_regular_exec(bContext *C, wmOperator *UNUSED(op)) 00269 { 00270 Object *ob= CTX_data_edit_object(C); 00271 Lattice *lt; 00272 00273 if(ob) { 00274 lt= ob->data; 00275 resizelattice(lt->editlatt->latt, lt->pntsu, lt->pntsv, lt->pntsw, NULL); 00276 } 00277 else { 00278 ob= CTX_data_active_object(C); 00279 lt= ob->data; 00280 resizelattice(lt, lt->pntsu, lt->pntsv, lt->pntsw, NULL); 00281 } 00282 00283 DAG_id_tag_update(&ob->id, OB_RECALC_DATA); 00284 WM_event_add_notifier(C, NC_GEOM|ND_DATA, ob->data); 00285 00286 return OPERATOR_FINISHED; 00287 } 00288 00289 void LATTICE_OT_make_regular(wmOperatorType *ot) 00290 { 00291 /* identifiers */ 00292 ot->name= "Make Regular"; 00293 ot->description= "Set UVW control points a uniform distance apart"; 00294 ot->idname= "LATTICE_OT_make_regular"; 00295 00296 /* api callbacks */ 00297 ot->exec= make_regular_exec; 00298 ot->poll= make_regular_poll; 00299 00300 /* flags */ 00301 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 00302 } 00303 00304 /****************************** Mouse Selection *************************/ 00305 00306 static void findnearestLattvert__doClosest(void *userData, BPoint *bp, int x, int y) 00307 { 00308 struct { BPoint *bp; short dist, select; int mval[2]; } *data = userData; 00309 float temp = abs(data->mval[0]-x) + abs(data->mval[1]-y); 00310 00311 if((bp->f1 & SELECT)==data->select) 00312 temp += 5; 00313 00314 if(temp<data->dist) { 00315 data->dist = temp; 00316 00317 data->bp = bp; 00318 } 00319 } 00320 00321 static BPoint *findnearestLattvert(ViewContext *vc, const int mval[2], int sel) 00322 { 00323 /* sel==1: selected gets a disadvantage */ 00324 /* in nurb and bezt or bp the nearest is written */ 00325 /* return 0 1 2: handlepunt */ 00326 struct { BPoint *bp; short dist, select; int mval[2]; } data = {NULL}; 00327 00328 data.dist = 100; 00329 data.select = sel; 00330 data.mval[0]= mval[0]; 00331 data.mval[1]= mval[1]; 00332 00333 ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); 00334 lattice_foreachScreenVert(vc, findnearestLattvert__doClosest, &data); 00335 00336 return data.bp; 00337 } 00338 00339 int mouse_lattice(bContext *C, const int mval[2], int extend) 00340 { 00341 ViewContext vc; 00342 BPoint *bp= NULL; 00343 00344 view3d_set_viewcontext(C, &vc); 00345 bp= findnearestLattvert(&vc, mval, 1); 00346 00347 if(bp) { 00348 if(extend==0) { 00349 ED_setflagsLatt(vc.obedit, 0); 00350 bp->f1 |= SELECT; 00351 } 00352 else 00353 bp->f1 ^= SELECT; /* swap */ 00354 00355 WM_event_add_notifier(C, NC_GEOM|ND_SELECT, vc.obedit->data); 00356 00357 return 1; 00358 } 00359 00360 return 0; 00361 } 00362 00363 /******************************** Undo *************************/ 00364 00365 typedef struct UndoLattice { 00366 BPoint *def; 00367 int pntsu, pntsv, pntsw; 00368 } UndoLattice; 00369 00370 static void undoLatt_to_editLatt(void *data, void *edata) 00371 { 00372 UndoLattice *ult= (UndoLattice*)data; 00373 EditLatt *editlatt= (EditLatt *)edata; 00374 int a= editlatt->latt->pntsu*editlatt->latt->pntsv*editlatt->latt->pntsw; 00375 00376 memcpy(editlatt->latt->def, ult->def, a*sizeof(BPoint)); 00377 } 00378 00379 static void *editLatt_to_undoLatt(void *edata) 00380 { 00381 UndoLattice *ult= MEM_callocN(sizeof(UndoLattice), "UndoLattice"); 00382 EditLatt *editlatt= (EditLatt *)edata; 00383 00384 ult->def= MEM_dupallocN(editlatt->latt->def); 00385 ult->pntsu= editlatt->latt->pntsu; 00386 ult->pntsv= editlatt->latt->pntsv; 00387 ult->pntsw= editlatt->latt->pntsw; 00388 00389 return ult; 00390 } 00391 00392 static void free_undoLatt(void *data) 00393 { 00394 UndoLattice *ult= (UndoLattice*)data; 00395 00396 if(ult->def) MEM_freeN(ult->def); 00397 MEM_freeN(ult); 00398 } 00399 00400 static int validate_undoLatt(void *data, void *edata) 00401 { 00402 UndoLattice *ult= (UndoLattice*)data; 00403 EditLatt *editlatt= (EditLatt *)edata; 00404 00405 return (ult->pntsu == editlatt->latt->pntsu && 00406 ult->pntsv == editlatt->latt->pntsv && 00407 ult->pntsw == editlatt->latt->pntsw); 00408 } 00409 00410 static void *get_editlatt(bContext *C) 00411 { 00412 Object *obedit= CTX_data_edit_object(C); 00413 00414 if(obedit && obedit->type==OB_LATTICE) { 00415 Lattice *lt= obedit->data; 00416 return lt->editlatt; 00417 } 00418 00419 return NULL; 00420 } 00421 00422 /* and this is all the undo system needs to know */ 00423 void undo_push_lattice(bContext *C, const char *name) 00424 { 00425 undo_editmode_push(C, name, get_editlatt, free_undoLatt, undoLatt_to_editLatt, editLatt_to_undoLatt, validate_undoLatt); 00426 } 00427