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, shapekey support 00022 * 00023 * ***** END GPL LICENSE BLOCK ***** 00024 */ 00025 00031 #include <math.h> 00032 #include <string.h> 00033 00034 #ifndef WIN32 00035 #include <unistd.h> 00036 #else 00037 #include <io.h> 00038 #endif 00039 00040 #include "MEM_guardedalloc.h" 00041 00042 #include "BLI_blenlib.h" 00043 #include "BLI_math.h" 00044 #include "BLI_utildefines.h" 00045 00046 #include "DNA_curve_types.h" 00047 #include "DNA_key_types.h" 00048 #include "DNA_lattice_types.h" 00049 #include "DNA_mesh_types.h" 00050 #include "DNA_meshdata_types.h" 00051 #include "DNA_scene_types.h" 00052 #include "DNA_object_types.h" 00053 00054 #include "BKE_context.h" 00055 #include "BKE_depsgraph.h" 00056 #include "BKE_key.h" 00057 #include "BKE_library.h" 00058 #include "BKE_main.h" 00059 #include "BKE_object.h" 00060 #include "BKE_curve.h" 00061 00062 #include "BLO_sys_types.h" // for intptr_t support 00063 00064 #include "ED_object.h" 00065 #include "ED_mesh.h" 00066 00067 #include "RNA_access.h" 00068 #include "RNA_define.h" 00069 00070 #include "WM_api.h" 00071 #include "WM_types.h" 00072 00073 #include "object_intern.h" 00074 00075 /*********************** add shape key ***********************/ 00076 00077 static void ED_object_shape_key_add(bContext *C, Scene *scene, Object *ob, int from_mix) 00078 { 00079 if(object_insert_shape_key(scene, ob, NULL, from_mix)) { 00080 Key *key= ob_get_key(ob); 00081 ob->shapenr= BLI_countlist(&key->block); 00082 00083 WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); 00084 } 00085 } 00086 00087 /*********************** remove shape key ***********************/ 00088 00089 static int ED_object_shape_key_remove(bContext *C, Object *ob) 00090 { 00091 Main *bmain= CTX_data_main(C); 00092 KeyBlock *kb, *rkb; 00093 Key *key; 00094 //IpoCurve *icu; 00095 00096 key= ob_get_key(ob); 00097 if(key==NULL) 00098 return 0; 00099 00100 kb= BLI_findlink(&key->block, ob->shapenr-1); 00101 00102 if(kb) { 00103 for(rkb= key->block.first; rkb; rkb= rkb->next) 00104 if(rkb->relative == ob->shapenr-1) 00105 rkb->relative= 0; 00106 00107 BLI_remlink(&key->block, kb); 00108 key->totkey--; 00109 if(key->refkey== kb) { 00110 key->refkey= key->block.first; 00111 00112 if(key->refkey) { 00113 /* apply new basis key on original data */ 00114 switch(ob->type) { 00115 case OB_MESH: 00116 key_to_mesh(key->refkey, ob->data); 00117 break; 00118 case OB_CURVE: 00119 case OB_SURF: 00120 key_to_curve(key->refkey, ob->data, BKE_curve_nurbs(ob->data)); 00121 break; 00122 case OB_LATTICE: 00123 key_to_latt(key->refkey, ob->data); 00124 break; 00125 } 00126 } 00127 } 00128 00129 if(kb->data) MEM_freeN(kb->data); 00130 MEM_freeN(kb); 00131 00132 for(kb= key->block.first; kb; kb= kb->next) 00133 if(kb->adrcode>=ob->shapenr) 00134 kb->adrcode--; 00135 00136 #if 0 // XXX old animation system 00137 if(key->ipo) { 00138 00139 for(icu= key->ipo->curve.first; icu; icu= icu->next) { 00140 if(icu->adrcode==ob->shapenr-1) { 00141 BLI_remlink(&key->ipo->curve, icu); 00142 free_ipo_curve(icu); 00143 break; 00144 } 00145 } 00146 for(icu= key->ipo->curve.first; icu; icu= icu->next) 00147 if(icu->adrcode>=ob->shapenr) 00148 icu->adrcode--; 00149 } 00150 #endif // XXX old animation system 00151 00152 if(ob->shapenr>1) ob->shapenr--; 00153 } 00154 00155 if(key->totkey==0) { 00156 if(GS(key->from->name)==ID_ME) ((Mesh *)key->from)->key= NULL; 00157 else if(GS(key->from->name)==ID_CU) ((Curve *)key->from)->key= NULL; 00158 else if(GS(key->from->name)==ID_LT) ((Lattice *)key->from)->key= NULL; 00159 00160 free_libblock_us(&(bmain->key), key); 00161 } 00162 00163 DAG_id_tag_update(&ob->id, OB_RECALC_DATA); 00164 WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); 00165 00166 return 1; 00167 } 00168 00169 static int object_shape_key_mirror(bContext *C, Object *ob) 00170 { 00171 KeyBlock *kb; 00172 Key *key; 00173 00174 key= ob_get_key(ob); 00175 if(key==NULL) 00176 return 0; 00177 00178 kb= BLI_findlink(&key->block, ob->shapenr-1); 00179 00180 if(kb) { 00181 int i1, i2; 00182 float *fp1, *fp2; 00183 float tvec[3]; 00184 char *tag_elem= MEM_callocN(sizeof(char) * kb->totelem, "shape_key_mirror"); 00185 00186 00187 if(ob->type==OB_MESH) { 00188 Mesh *me= ob->data; 00189 MVert *mv; 00190 00191 mesh_octree_table(ob, NULL, NULL, 's'); 00192 00193 for(i1=0, mv=me->mvert; i1<me->totvert; i1++, mv++) { 00194 i2= mesh_get_x_mirror_vert(ob, i1); 00195 if(i2==i1) { 00196 fp1= ((float *)kb->data) + i1*3; 00197 fp1[0] = -fp1[0]; 00198 tag_elem[i1]= 1; 00199 } 00200 else if(i2 != -1) { 00201 if(tag_elem[i1]==0 && tag_elem[i2]==0) { 00202 fp1= ((float *)kb->data) + i1*3; 00203 fp2= ((float *)kb->data) + i2*3; 00204 00205 copy_v3_v3(tvec, fp1); 00206 copy_v3_v3(fp1, fp2); 00207 copy_v3_v3(fp2, tvec); 00208 00209 /* flip x axis */ 00210 fp1[0] = -fp1[0]; 00211 fp2[0] = -fp2[0]; 00212 } 00213 tag_elem[i1]= tag_elem[i2]= 1; 00214 } 00215 } 00216 00217 mesh_octree_table(ob, NULL, NULL, 'e'); 00218 } 00219 else if (ob->type == OB_LATTICE) { 00220 Lattice *lt= ob->data; 00221 int i1, i2; 00222 float *fp1, *fp2; 00223 int u, v, w; 00224 /* half but found up odd value */ 00225 const int pntsu_half = (((lt->pntsu / 2) + (lt->pntsu % 2))) ; 00226 00227 /* currently editmode isnt supported by mesh so 00228 * ignore here for now too */ 00229 00230 /* if(lt->editlatt) lt= lt->editlatt->latt; */ 00231 00232 for(w=0; w<lt->pntsw; w++) { 00233 for(v=0; v<lt->pntsv; v++) { 00234 for(u=0; u<pntsu_half; u++) { 00235 int u_inv= (lt->pntsu - 1) - u; 00236 float tvec[3]; 00237 if(u == u_inv) { 00238 i1= LT_INDEX(lt, u, v, w); 00239 fp1= ((float *)kb->data) + i1*3; 00240 fp1[0]= -fp1[0]; 00241 } 00242 else { 00243 i1= LT_INDEX(lt, u, v, w); 00244 i2= LT_INDEX(lt, u_inv, v, w); 00245 00246 fp1= ((float *)kb->data) + i1*3; 00247 fp2= ((float *)kb->data) + i2*3; 00248 00249 copy_v3_v3(tvec, fp1); 00250 copy_v3_v3(fp1, fp2); 00251 copy_v3_v3(fp2, tvec); 00252 fp1[0]= -fp1[0]; 00253 fp2[0]= -fp2[0]; 00254 } 00255 } 00256 } 00257 } 00258 } 00259 00260 MEM_freeN(tag_elem); 00261 } 00262 00263 DAG_id_tag_update(&ob->id, OB_RECALC_DATA); 00264 WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); 00265 00266 return 1; 00267 } 00268 00269 /********************** shape key operators *********************/ 00270 00271 static int shape_key_mode_poll(bContext *C) 00272 { 00273 Object *ob= ED_object_context(C); 00274 ID *data= (ob)? ob->data: NULL; 00275 return (ob && !ob->id.lib && data && !data->lib && ob->mode != OB_MODE_EDIT); 00276 } 00277 00278 static int shape_key_poll(bContext *C) 00279 { 00280 Object *ob= ED_object_context(C); 00281 ID *data= (ob)? ob->data: NULL; 00282 return (ob && !ob->id.lib && data && !data->lib); 00283 } 00284 00285 static int shape_key_add_exec(bContext *C, wmOperator *op) 00286 { 00287 Scene *scene= CTX_data_scene(C); 00288 Object *ob= ED_object_context(C); 00289 int from_mix = RNA_boolean_get(op->ptr, "from_mix"); 00290 00291 ED_object_shape_key_add(C, scene, ob, from_mix); 00292 00293 return OPERATOR_FINISHED; 00294 } 00295 00296 void OBJECT_OT_shape_key_add(wmOperatorType *ot) 00297 { 00298 /* identifiers */ 00299 ot->name= "Add Shape Key"; 00300 ot->idname= "OBJECT_OT_shape_key_add"; 00301 ot->description= "Add shape key to the object"; 00302 00303 /* api callbacks */ 00304 ot->poll= shape_key_mode_poll; 00305 ot->exec= shape_key_add_exec; 00306 00307 /* flags */ 00308 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 00309 00310 /* properties */ 00311 RNA_def_boolean(ot->srna, "from_mix", 1, "From Mix", "Create the new shape key from the existing mix of keys"); 00312 } 00313 00314 static int shape_key_remove_exec(bContext *C, wmOperator *UNUSED(op)) 00315 { 00316 Object *ob= ED_object_context(C); 00317 00318 if(!ED_object_shape_key_remove(C, ob)) 00319 return OPERATOR_CANCELLED; 00320 00321 return OPERATOR_FINISHED; 00322 } 00323 00324 void OBJECT_OT_shape_key_remove(wmOperatorType *ot) 00325 { 00326 /* identifiers */ 00327 ot->name= "Remove Shape Key"; 00328 ot->idname= "OBJECT_OT_shape_key_remove"; 00329 ot->description= "Remove shape key from the object"; 00330 00331 /* api callbacks */ 00332 ot->poll= shape_key_mode_poll; 00333 ot->exec= shape_key_remove_exec; 00334 00335 /* flags */ 00336 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 00337 } 00338 00339 static int shape_key_clear_exec(bContext *C, wmOperator *UNUSED(op)) 00340 { 00341 Object *ob= ED_object_context(C); 00342 Key *key= ob_get_key(ob); 00343 KeyBlock *kb= ob_get_keyblock(ob); 00344 00345 if(!key || !kb) 00346 return OPERATOR_CANCELLED; 00347 00348 for(kb=key->block.first; kb; kb=kb->next) 00349 kb->curval= 0.0f; 00350 00351 DAG_id_tag_update(&ob->id, OB_RECALC_DATA); 00352 WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); 00353 00354 return OPERATOR_FINISHED; 00355 } 00356 00357 void OBJECT_OT_shape_key_clear(wmOperatorType *ot) 00358 { 00359 /* identifiers */ 00360 ot->name= "Clear Shape Keys"; 00361 ot->description= "Clear weights for all shape keys"; 00362 ot->idname= "OBJECT_OT_shape_key_clear"; 00363 00364 /* api callbacks */ 00365 ot->poll= shape_key_poll; 00366 ot->exec= shape_key_clear_exec; 00367 00368 /* flags */ 00369 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 00370 } 00371 00372 static int shape_key_mirror_exec(bContext *C, wmOperator *UNUSED(op)) 00373 { 00374 Object *ob= ED_object_context(C); 00375 00376 if(!object_shape_key_mirror(C, ob)) 00377 return OPERATOR_CANCELLED; 00378 00379 return OPERATOR_FINISHED; 00380 } 00381 00382 void OBJECT_OT_shape_key_mirror(wmOperatorType *ot) 00383 { 00384 /* identifiers */ 00385 ot->name= "Mirror Shape Key"; 00386 ot->idname= "OBJECT_OT_shape_key_mirror"; 00387 00388 /* api callbacks */ 00389 ot->poll= shape_key_mode_poll; 00390 ot->exec= shape_key_mirror_exec; 00391 00392 /* flags */ 00393 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 00394 } 00395 00396 00397 static int shape_key_move_exec(bContext *C, wmOperator *op) 00398 { 00399 Object *ob= ED_object_context(C); 00400 00401 int type= RNA_enum_get(op->ptr, "type"); 00402 Key *key= ob_get_key(ob); 00403 00404 if(key) { 00405 KeyBlock *kb, *kb_other; 00406 int shapenr_act= ob->shapenr-1; 00407 int shapenr_swap= shapenr_act + type; 00408 kb= BLI_findlink(&key->block, shapenr_act); 00409 00410 if((type==-1 && kb->prev==NULL) || (type==1 && kb->next==NULL)) { 00411 return OPERATOR_CANCELLED; 00412 } 00413 00414 for(kb_other= key->block.first; kb_other; kb_other= kb_other->next) { 00415 if(kb_other->relative == shapenr_act) { 00416 kb_other->relative += type; 00417 } 00418 else if(kb_other->relative == shapenr_swap) { 00419 kb_other->relative -= type; 00420 } 00421 } 00422 00423 if(type==-1) { 00424 /* move back */ 00425 kb_other= kb->prev; 00426 BLI_remlink(&key->block, kb); 00427 BLI_insertlinkbefore(&key->block, kb_other, kb); 00428 ob->shapenr--; 00429 } 00430 else { 00431 /* move next */ 00432 kb_other= kb->next; 00433 BLI_remlink(&key->block, kb); 00434 BLI_insertlinkafter(&key->block, kb_other, kb); 00435 ob->shapenr++; 00436 } 00437 } 00438 00439 DAG_id_tag_update(&ob->id, OB_RECALC_DATA); 00440 WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob); 00441 00442 return OPERATOR_FINISHED; 00443 } 00444 00445 void OBJECT_OT_shape_key_move(wmOperatorType *ot) 00446 { 00447 static EnumPropertyItem slot_move[] = { 00448 {-1, "UP", 0, "Up", ""}, 00449 {1, "DOWN", 0, "Down", ""}, 00450 {0, NULL, 0, NULL, NULL} 00451 }; 00452 00453 /* identifiers */ 00454 ot->name= "Move Shape Key"; 00455 ot->idname= "OBJECT_OT_shape_key_move"; 00456 00457 /* api callbacks */ 00458 ot->poll= shape_key_mode_poll; 00459 ot->exec= shape_key_move_exec; 00460 00461 /* flags */ 00462 ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; 00463 00464 RNA_def_enum(ot->srna, "type", slot_move, 0, "Type", ""); 00465 } 00466