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