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