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) 2005 by the Blender Foundation. 00019 * All rights reserved. 00020 * 00021 * Contributor(s): Daniel Dunbar 00022 * Ton Roosendaal, 00023 * Ben Batt, 00024 * Brecht Van Lommel, 00025 * Campbell Barton 00026 * 00027 * ***** END GPL LICENSE BLOCK ***** 00028 * 00029 * Modifier stack implementation. 00030 * 00031 * BKE_modifier.h contains the function prototypes for this file. 00032 * 00033 */ 00034 00040 #include <stddef.h> 00041 #include <string.h> 00042 #include <stdarg.h> 00043 #include <math.h> 00044 #include <float.h> 00045 00046 #include "MEM_guardedalloc.h" 00047 00048 #include "DNA_armature_types.h" 00049 #include "DNA_object_types.h" 00050 #include "DNA_meshdata_types.h" 00051 00052 #include "BLI_utildefines.h" 00053 #include "BLI_path_util.h" 00054 #include "BLI_listbase.h" 00055 #include "BLI_linklist.h" 00056 #include "BLI_string.h" 00057 00058 #include "BKE_bmesh.h" 00059 #include "BKE_cloth.h" 00060 #include "BKE_key.h" 00061 #include "BKE_multires.h" 00062 00063 /* may move these, only for modifier_path_relbase */ 00064 #include "BKE_global.h" /* ugh, G.main->name only */ 00065 #include "BKE_main.h" 00066 /* end */ 00067 00068 #include "MOD_modifiertypes.h" 00069 00070 ModifierTypeInfo *modifierType_getInfo(ModifierType type) 00071 { 00072 static ModifierTypeInfo *types[NUM_MODIFIER_TYPES]= {NULL}; 00073 static int types_init = 1; 00074 00075 if (types_init) { 00076 modifier_type_init(types); /* MOD_utils.c */ 00077 types_init= 0; 00078 } 00079 00080 /* type unsigned, no need to chech < 0 */ 00081 if(type < NUM_MODIFIER_TYPES && types[type]->name[0] != '\0') { 00082 return types[type]; 00083 } 00084 else { 00085 return NULL; 00086 } 00087 } 00088 00089 /***/ 00090 00091 ModifierData *modifier_new(int type) 00092 { 00093 ModifierTypeInfo *mti = modifierType_getInfo(type); 00094 ModifierData *md = MEM_callocN(mti->structSize, mti->structName); 00095 00096 /* note, this name must be made unique later */ 00097 BLI_strncpy(md->name, mti->name, sizeof(md->name)); 00098 00099 md->type = type; 00100 md->mode = eModifierMode_Realtime 00101 | eModifierMode_Render | eModifierMode_Expanded; 00102 00103 if (mti->flags & eModifierTypeFlag_EnableInEditmode) 00104 md->mode |= eModifierMode_Editmode; 00105 00106 if (mti->initData) mti->initData(md); 00107 00108 return md; 00109 } 00110 00111 void modifier_free(ModifierData *md) 00112 { 00113 ModifierTypeInfo *mti = modifierType_getInfo(md->type); 00114 00115 if (mti->freeData) mti->freeData(md); 00116 if (md->error) MEM_freeN(md->error); 00117 00118 MEM_freeN(md); 00119 } 00120 00121 void modifier_unique_name(ListBase *modifiers, ModifierData *md) 00122 { 00123 if (modifiers && md) { 00124 ModifierTypeInfo *mti = modifierType_getInfo(md->type); 00125 00126 BLI_uniquename(modifiers, md, mti->name, '.', offsetof(ModifierData, name), sizeof(md->name)); 00127 } 00128 } 00129 00130 int modifier_dependsOnTime(ModifierData *md) 00131 { 00132 ModifierTypeInfo *mti = modifierType_getInfo(md->type); 00133 00134 return mti->dependsOnTime && mti->dependsOnTime(md); 00135 } 00136 00137 int modifier_supportsMapping(ModifierData *md) 00138 { 00139 ModifierTypeInfo *mti = modifierType_getInfo(md->type); 00140 00141 return (mti->type==eModifierTypeType_OnlyDeform || 00142 (mti->flags & eModifierTypeFlag_SupportsMapping)); 00143 } 00144 00145 ModifierData *modifiers_findByType(Object *ob, ModifierType type) 00146 { 00147 ModifierData *md = ob->modifiers.first; 00148 00149 for (; md; md=md->next) 00150 if (md->type==type) 00151 break; 00152 00153 return md; 00154 } 00155 00156 ModifierData *modifiers_findByName(Object *ob, const char *name) 00157 { 00158 return BLI_findstring(&(ob->modifiers), name, offsetof(ModifierData, name)); 00159 } 00160 00161 void modifiers_clearErrors(Object *ob) 00162 { 00163 ModifierData *md = ob->modifiers.first; 00164 /* int qRedraw = 0; */ 00165 00166 for (; md; md=md->next) { 00167 if (md->error) { 00168 MEM_freeN(md->error); 00169 md->error = NULL; 00170 00171 /* qRedraw = 1; */ 00172 } 00173 } 00174 } 00175 00176 void modifiers_foreachObjectLink(Object *ob, ObjectWalkFunc walk, 00177 void *userData) 00178 { 00179 ModifierData *md = ob->modifiers.first; 00180 00181 for (; md; md=md->next) { 00182 ModifierTypeInfo *mti = modifierType_getInfo(md->type); 00183 00184 if (mti->foreachObjectLink) 00185 mti->foreachObjectLink(md, ob, walk, userData); 00186 } 00187 } 00188 00189 void modifiers_foreachIDLink(Object *ob, IDWalkFunc walk, void *userData) 00190 { 00191 ModifierData *md = ob->modifiers.first; 00192 00193 for (; md; md=md->next) { 00194 ModifierTypeInfo *mti = modifierType_getInfo(md->type); 00195 00196 if(mti->foreachIDLink) mti->foreachIDLink(md, ob, walk, userData); 00197 else if(mti->foreachObjectLink) { 00198 /* each Object can masquerade as an ID, so this should be OK */ 00199 ObjectWalkFunc fp = (ObjectWalkFunc)walk; 00200 mti->foreachObjectLink(md, ob, fp, userData); 00201 } 00202 } 00203 } 00204 00205 void modifiers_foreachTexLink(Object *ob, TexWalkFunc walk, void *userData) 00206 { 00207 ModifierData *md = ob->modifiers.first; 00208 00209 for (; md; md=md->next) { 00210 ModifierTypeInfo *mti = modifierType_getInfo(md->type); 00211 00212 if(mti->foreachTexLink) 00213 mti->foreachTexLink(md, ob, walk, userData); 00214 } 00215 } 00216 00217 void modifier_copyData(ModifierData *md, ModifierData *target) 00218 { 00219 ModifierTypeInfo *mti = modifierType_getInfo(md->type); 00220 00221 target->mode = md->mode; 00222 00223 if (mti->copyData) 00224 mti->copyData(md, target); 00225 } 00226 00227 int modifier_couldBeCage(struct Scene *scene, ModifierData *md) 00228 { 00229 ModifierTypeInfo *mti = modifierType_getInfo(md->type); 00230 00231 md->scene= scene; 00232 00233 return ( (md->mode & eModifierMode_Realtime) && 00234 (md->mode & eModifierMode_Editmode) && 00235 (!mti->isDisabled || !mti->isDisabled(md, 0)) && 00236 modifier_supportsMapping(md)); 00237 } 00238 00239 int modifier_sameTopology(ModifierData *md) 00240 { 00241 ModifierTypeInfo *mti = modifierType_getInfo(md->type); 00242 return ELEM3(mti->type, eModifierTypeType_OnlyDeform, eModifierTypeType_Nonconstructive, 00243 eModifierTypeType_NonGeometrical); 00244 } 00245 00246 int modifier_nonGeometrical(ModifierData *md) 00247 { 00248 ModifierTypeInfo *mti = modifierType_getInfo(md->type); 00249 return (mti->type == eModifierTypeType_NonGeometrical); 00250 } 00251 00252 void modifier_setError(ModifierData *md, const char *format, ...) 00253 { 00254 char buffer[512]; 00255 va_list ap; 00256 00257 va_start(ap, format); 00258 vsnprintf(buffer, sizeof(buffer), format, ap); 00259 va_end(ap); 00260 buffer[sizeof(buffer) - 1]= '\0'; 00261 00262 if (md->error) 00263 MEM_freeN(md->error); 00264 00265 md->error = BLI_strdup(buffer); 00266 00267 } 00268 00269 /* used for buttons, to find out if the 'draw deformed in editmode' option is 00270 * there 00271 * 00272 * also used in transform_conversion.c, to detect CrazySpace [tm] (2nd arg 00273 * then is NULL) 00274 * also used for some mesh tools to give warnings 00275 */ 00276 int modifiers_getCageIndex(struct Scene *scene, Object *ob, int *lastPossibleCageIndex_r, int virtual_) 00277 { 00278 ModifierData *md = (virtual_)? modifiers_getVirtualModifierList(ob): ob->modifiers.first; 00279 int i, cageIndex = -1; 00280 00281 if(lastPossibleCageIndex_r) { 00282 /* ensure the value is initialized */ 00283 *lastPossibleCageIndex_r= -1; 00284 } 00285 00286 /* Find the last modifier acting on the cage. */ 00287 for (i=0; md; i++,md=md->next) { 00288 ModifierTypeInfo *mti = modifierType_getInfo(md->type); 00289 00290 md->scene= scene; 00291 00292 if (!(md->mode & eModifierMode_Realtime)) continue; 00293 if (!(md->mode & eModifierMode_Editmode)) continue; 00294 if (mti->isDisabled && mti->isDisabled(md, 0)) continue; 00295 if (!(mti->flags & eModifierTypeFlag_SupportsEditmode)) continue; 00296 if (md->mode & eModifierMode_DisableTemporary) continue; 00297 00298 if (!modifier_supportsMapping(md)) 00299 break; 00300 00301 if (lastPossibleCageIndex_r) *lastPossibleCageIndex_r = i; 00302 if (md->mode & eModifierMode_OnCage) 00303 cageIndex = i; 00304 } 00305 00306 return cageIndex; 00307 } 00308 00309 00310 int modifiers_isSoftbodyEnabled(Object *ob) 00311 { 00312 ModifierData *md = modifiers_findByType(ob, eModifierType_Softbody); 00313 00314 return (md && md->mode & (eModifierMode_Realtime | eModifierMode_Render)); 00315 } 00316 00317 int modifiers_isClothEnabled(Object *ob) 00318 { 00319 ModifierData *md = modifiers_findByType(ob, eModifierType_Cloth); 00320 00321 return (md && md->mode & (eModifierMode_Realtime | eModifierMode_Render)); 00322 } 00323 00324 int modifiers_isParticleEnabled(Object *ob) 00325 { 00326 ModifierData *md = modifiers_findByType(ob, eModifierType_ParticleSystem); 00327 00328 return (md && md->mode & (eModifierMode_Realtime | eModifierMode_Render)); 00329 } 00330 00331 int modifier_isEnabled(struct Scene *scene, ModifierData *md, int required_mode) 00332 { 00333 ModifierTypeInfo *mti = modifierType_getInfo(md->type); 00334 00335 md->scene= scene; 00336 00337 if((md->mode & required_mode) != required_mode) return 0; 00338 if(mti->isDisabled && mti->isDisabled(md, required_mode == eModifierMode_Render)) return 0; 00339 if(md->mode & eModifierMode_DisableTemporary) return 0; 00340 if(required_mode & eModifierMode_Editmode) 00341 if(!(mti->flags & eModifierTypeFlag_SupportsEditmode)) return 0; 00342 00343 return 1; 00344 } 00345 00346 LinkNode *modifiers_calcDataMasks(struct Scene *scene, Object *ob, ModifierData *md, CustomDataMask dataMask, int required_mode) 00347 { 00348 LinkNode *dataMasks = NULL; 00349 LinkNode *curr, *prev; 00350 00351 /* build a list of modifier data requirements in reverse order */ 00352 for(; md; md = md->next) { 00353 ModifierTypeInfo *mti = modifierType_getInfo(md->type); 00354 CustomDataMask mask = 0; 00355 00356 if(modifier_isEnabled(scene, md, required_mode)) 00357 if(mti->requiredDataMask) 00358 mask = mti->requiredDataMask(ob, md); 00359 00360 BLI_linklist_prepend(&dataMasks, SET_INT_IN_POINTER(mask)); 00361 } 00362 00363 /* build the list of required data masks - each mask in the list must 00364 * include all elements of the masks that follow it 00365 * 00366 * note the list is currently in reverse order, so "masks that follow it" 00367 * actually means "masks that precede it" at the moment 00368 */ 00369 for(curr = dataMasks, prev = NULL; curr; prev = curr, curr = curr->next) { 00370 if(prev) { 00371 CustomDataMask prev_mask = (CustomDataMask)GET_INT_FROM_POINTER(prev->link); 00372 CustomDataMask curr_mask = (CustomDataMask)GET_INT_FROM_POINTER(curr->link); 00373 00374 curr->link = SET_INT_IN_POINTER(curr_mask | prev_mask); 00375 } else { 00376 CustomDataMask curr_mask = (CustomDataMask)GET_INT_FROM_POINTER(curr->link); 00377 00378 curr->link = SET_INT_IN_POINTER(curr_mask | dataMask); 00379 } 00380 } 00381 00382 /* reverse the list so it's in the correct order */ 00383 BLI_linklist_reverse(&dataMasks); 00384 00385 return dataMasks; 00386 } 00387 00388 ModifierData *modifiers_getVirtualModifierList(Object *ob) 00389 { 00390 /* Kinda hacky, but should be fine since we are never 00391 * reentrant and avoid free hassles. 00392 */ 00393 static ArmatureModifierData amd; 00394 static CurveModifierData cmd; 00395 static LatticeModifierData lmd; 00396 static ShapeKeyModifierData smd; 00397 static int init = 1; 00398 ModifierData *md; 00399 00400 if (init) { 00401 md = modifier_new(eModifierType_Armature); 00402 amd = *((ArmatureModifierData*) md); 00403 modifier_free(md); 00404 00405 md = modifier_new(eModifierType_Curve); 00406 cmd = *((CurveModifierData*) md); 00407 modifier_free(md); 00408 00409 md = modifier_new(eModifierType_Lattice); 00410 lmd = *((LatticeModifierData*) md); 00411 modifier_free(md); 00412 00413 md = modifier_new(eModifierType_ShapeKey); 00414 smd = *((ShapeKeyModifierData*) md); 00415 modifier_free(md); 00416 00417 amd.modifier.mode |= eModifierMode_Virtual; 00418 cmd.modifier.mode |= eModifierMode_Virtual; 00419 lmd.modifier.mode |= eModifierMode_Virtual; 00420 smd.modifier.mode |= eModifierMode_Virtual; 00421 00422 init = 0; 00423 } 00424 00425 md = ob->modifiers.first; 00426 00427 if(ob->parent) { 00428 if(ob->parent->type==OB_ARMATURE && ob->partype==PARSKEL) { 00429 amd.object = ob->parent; 00430 amd.modifier.next = md; 00431 amd.deformflag= ((bArmature *)(ob->parent->data))->deformflag; 00432 md = &amd.modifier; 00433 } else if(ob->parent->type==OB_CURVE && ob->partype==PARSKEL) { 00434 cmd.object = ob->parent; 00435 cmd.defaxis = ob->trackflag + 1; 00436 cmd.modifier.next = md; 00437 md = &cmd.modifier; 00438 } else if(ob->parent->type==OB_LATTICE && ob->partype==PARSKEL) { 00439 lmd.object = ob->parent; 00440 lmd.modifier.next = md; 00441 md = &lmd.modifier; 00442 } 00443 } 00444 00445 /* shape key modifier, not yet for curves */ 00446 if(ELEM(ob->type, OB_MESH, OB_LATTICE) && ob_get_key(ob)) { 00447 if(ob->type == OB_MESH && (ob->shapeflag & OB_SHAPE_EDIT_MODE)) 00448 smd.modifier.mode |= eModifierMode_Editmode|eModifierMode_OnCage; 00449 else 00450 smd.modifier.mode &= ~eModifierMode_Editmode|eModifierMode_OnCage; 00451 00452 smd.modifier.next = md; 00453 md = &smd.modifier; 00454 } 00455 00456 return md; 00457 } 00458 /* Takes an object and returns its first selected armature, else just its 00459 * armature 00460 * This should work for multiple armatures per object 00461 */ 00462 Object *modifiers_isDeformedByArmature(Object *ob) 00463 { 00464 ModifierData *md = modifiers_getVirtualModifierList(ob); 00465 ArmatureModifierData *amd= NULL; 00466 00467 /* return the first selected armature, this lets us use multiple armatures 00468 */ 00469 for (; md; md=md->next) { 00470 if (md->type==eModifierType_Armature) { 00471 amd = (ArmatureModifierData*) md; 00472 if (amd->object && (amd->object->flag & SELECT)) 00473 return amd->object; 00474 } 00475 } 00476 00477 if (amd) /* if were still here then return the last armature */ 00478 return amd->object; 00479 00480 return NULL; 00481 } 00482 00483 /* Takes an object and returns its first selected lattice, else just its 00484 * lattice 00485 * This should work for multiple lattics per object 00486 */ 00487 Object *modifiers_isDeformedByLattice(Object *ob) 00488 { 00489 ModifierData *md = modifiers_getVirtualModifierList(ob); 00490 LatticeModifierData *lmd= NULL; 00491 00492 /* return the first selected lattice, this lets us use multiple lattices 00493 */ 00494 for (; md; md=md->next) { 00495 if (md->type==eModifierType_Lattice) { 00496 lmd = (LatticeModifierData*) md; 00497 if (lmd->object && (lmd->object->flag & SELECT)) 00498 return lmd->object; 00499 } 00500 } 00501 00502 if (lmd) /* if were still here then return the last lattice */ 00503 return lmd->object; 00504 00505 return NULL; 00506 } 00507 00508 00509 00510 int modifiers_usesArmature(Object *ob, bArmature *arm) 00511 { 00512 ModifierData *md = modifiers_getVirtualModifierList(ob); 00513 00514 for (; md; md=md->next) { 00515 if (md->type==eModifierType_Armature) { 00516 ArmatureModifierData *amd = (ArmatureModifierData*) md; 00517 if (amd->object && amd->object->data==arm) 00518 return 1; 00519 } 00520 } 00521 00522 return 0; 00523 } 00524 00525 int modifier_isCorrectableDeformed(ModifierData *md) 00526 { 00527 if (md->type==eModifierType_Armature) 00528 return 1; 00529 if (md->type==eModifierType_ShapeKey) 00530 return 1; 00531 00532 return 0; 00533 } 00534 00535 int modifiers_isCorrectableDeformed(Object *ob) 00536 { 00537 ModifierData *md = modifiers_getVirtualModifierList(ob); 00538 00539 for (; md; md=md->next) { 00540 if(ob->mode==OB_MODE_EDIT && (md->mode & eModifierMode_Editmode)==0); 00541 else 00542 if(modifier_isCorrectableDeformed(md)) 00543 return 1; 00544 } 00545 return 0; 00546 } 00547 00548 int modifiers_indexInObject(Object *ob, ModifierData *md_seek) 00549 { 00550 int i= 0; 00551 ModifierData *md; 00552 00553 for (md=ob->modifiers.first; (md && md_seek!=md); md=md->next, i++); 00554 if (!md) return -1; /* modifier isnt in the object */ 00555 return i; 00556 } 00557 00558 void modifier_freeTemporaryData(ModifierData *md) 00559 { 00560 if(md->type == eModifierType_Armature) { 00561 ArmatureModifierData *amd= (ArmatureModifierData*)md; 00562 00563 if(amd->prevCos) { 00564 MEM_freeN(amd->prevCos); 00565 amd->prevCos= NULL; 00566 } 00567 } 00568 } 00569 00570 /* ensure modifier correctness when changing ob->data */ 00571 void test_object_modifiers(Object *ob) 00572 { 00573 ModifierData *md; 00574 00575 /* just multires checked for now, since only multires 00576 modifies mesh data */ 00577 00578 if(ob->type != OB_MESH) return; 00579 00580 for(md = ob->modifiers.first; md; md = md->next) { 00581 if(md->type == eModifierType_Multires) { 00582 MultiresModifierData *mmd = (MultiresModifierData*)md; 00583 00584 multiresModifier_set_levels_from_disps(mmd, ob); 00585 } 00586 } 00587 } 00588 00589 /* where should this go?, it doesnt fit well anywhere :S - campbell */ 00590 00591 /* elubie: changed this to default to the same dir as the render output 00592 * to prevent saving to C:\ on Windows */ 00593 00594 /* campbell: logic behind this... 00595 * 00596 * - if the ID is from a library, return library path 00597 * - else if the file has been saved return the blend file path. 00598 * - else if the file isn't saved and the ID isnt from a library, return the temp dir. 00599 */ 00600 const char *modifier_path_relbase(Object *ob) 00601 { 00602 if (G.relbase_valid || ob->id.lib) { 00603 return ID_BLEND_PATH(G.main, &ob->id); 00604 } 00605 else { 00606 /* last resort, better then using "" which resolves to the current 00607 * working directory */ 00608 return BLI_temporary_dir(); 00609 } 00610 } 00611 00612 /* initializes the path with either */ 00613 void modifier_path_init(char *path, int path_maxlen, const char *name) 00614 { 00615 /* elubie: changed this to default to the same dir as the render output 00616 * to prevent saving to C:\ on Windows */ 00617 BLI_join_dirfile(path, path_maxlen, 00618 G.relbase_valid ? "//" : BLI_temporary_dir(), 00619 name); 00620 }