commit before doing some hefty shapekey change, will break compilation
This commit is contained in:
parent
672c8926d7
commit
2d0d4e7de4
|
@ -67,6 +67,7 @@ struct KeyingSet *BKE_keyingset_add(struct ListBase *list, const char name[], sh
|
|||
/* Add a destination to a KeyingSet */
|
||||
void BKE_keyingset_add_destination(struct KeyingSet *ks, struct ID *id, const char group_name[], const char rna_path[], int array_index, short flag, short groupmode);
|
||||
|
||||
/* Find the destination matching the criteria given */
|
||||
struct KS_Path *BKE_keyingset_find_destination(struct KeyingSet *ks, struct ID *id, const char group_name[], const char rna_path[], int array_index, int group_mode);
|
||||
|
||||
/* Copy all KeyingSets in the given list */
|
||||
|
@ -78,6 +79,15 @@ void BKE_keyingset_free(struct KeyingSet *ks);
|
|||
/* Free all the KeyingSets in the given list */
|
||||
void BKE_keyingsets_free(struct ListBase *list);
|
||||
|
||||
/* ************************************* */
|
||||
/* Path Fixing API */
|
||||
|
||||
/* Fix all the paths for the given ID+AnimData */
|
||||
void BKE_animdata_fix_paths_rename(struct ID *owner_id, struct AnimData *adt, char *prefix, char *oldName, char *newName);
|
||||
|
||||
/* Fix all the paths for the entire database... */
|
||||
void BKE_all_animdata_fix_paths_rename(char *prefix, char *oldName, char *newName);
|
||||
|
||||
/* ************************************* */
|
||||
// TODO: overrides, remapping, and path-finding api's
|
||||
|
||||
|
|
|
@ -43,7 +43,7 @@ struct bContext;
|
|||
struct ReportList;
|
||||
|
||||
#define BLENDER_VERSION 250
|
||||
#define BLENDER_SUBVERSION 6
|
||||
#define BLENDER_SUBVERSION 7
|
||||
|
||||
#define BLENDER_MINVERSION 250
|
||||
#define BLENDER_MINSUBVERSION 0
|
||||
|
|
|
@ -92,6 +92,9 @@ void switchdirectionNurb( struct Nurb *nu);
|
|||
float (*curve_getVertexCos(struct Curve *cu, struct ListBase *lb, int *numVerts_r))[3];
|
||||
void curve_applyVertexCos(struct Curve *cu, struct ListBase *lb, float (*vertexCos)[3]);
|
||||
|
||||
float (*curve_getKeyVertexCos(struct Curve *cu, struct ListBase *lb, float *key))[3];
|
||||
void curve_applyKeyVertexTilts(struct Curve *cu, struct ListBase *lb, float *key);
|
||||
|
||||
/* nurb checks if they can be drawn, also clamp order func */
|
||||
int check_valid_nurb_u( struct Nurb *nu);
|
||||
int check_valid_nurb_v( struct Nurb *nu);
|
||||
|
|
|
@ -110,7 +110,7 @@ typedef struct Global {
|
|||
#define G_BACKBUFSEL (1 << 4)
|
||||
#define G_PICKSEL (1 << 5)
|
||||
|
||||
#define G_FACESELECT (1 << 8)
|
||||
/* #define G_FACESELECT (1 << 8) use (mesh->editflag & ME_EDIT_PAINT_MASK) */
|
||||
|
||||
#define G_DEBUG (1 << 12)
|
||||
#define G_DOSCRIPTLINKS (1 << 13)
|
||||
|
@ -145,6 +145,7 @@ typedef struct Global {
|
|||
#define G_FILE_GLSL_NO_NODES (1 << 20) /* deprecated */
|
||||
#define G_FILE_GLSL_NO_EXTRA_TEX (1 << 21) /* deprecated */
|
||||
#define G_FILE_IGNORE_DEPRECATION_WARNINGS (1 << 22) /* deprecated */
|
||||
#define G_FILE_RECOVER (1 << 23)
|
||||
|
||||
/* G.windowstate */
|
||||
#define G_WINDOWSTATE_USERDEF 0
|
||||
|
|
|
@ -56,17 +56,15 @@ void key_curve_position_weights(float t, float *data, int type);
|
|||
void key_curve_tangent_weights(float t, float *data, int type);
|
||||
void key_curve_normal_weights(float t, float *data, int type);
|
||||
|
||||
/* only exported to curve.c! */
|
||||
void cp_cu_key(struct Curve *cu, struct KeyBlock *kb, int start, int end);
|
||||
|
||||
int do_ob_key(struct Scene *scene, struct Object *ob);
|
||||
float *do_ob_key(struct Scene *scene, struct Object *ob);
|
||||
|
||||
struct Key *ob_get_key(struct Object *ob);
|
||||
struct KeyBlock *ob_get_keyblock(struct Object *ob);
|
||||
struct KeyBlock *key_get_keyblock(struct Key *key, int index);
|
||||
struct KeyBlock *key_get_named_keyblock(struct Key *key, const char name[]);
|
||||
char *key_get_curValue_rnaPath(struct Key *key, struct KeyBlock *kb);
|
||||
// needed for the GE
|
||||
void do_rel_key(int start, int end, int tot, char *basispoin, struct Key *key, int mode);
|
||||
void do_rel_key(int start, int end, int tot, char *basispoin, struct Key *key, struct KeyBlock *actkb, int mode);
|
||||
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
|
|
|
@ -47,6 +47,7 @@ void test_object_materials(struct ID *id);
|
|||
void init_material(struct Material *ma);
|
||||
struct Material *add_material(char *name);
|
||||
struct Material *copy_material(struct Material *ma);
|
||||
struct Material *give_node_material(struct Material *ma); /* returns node material or self */
|
||||
void make_local_material(struct Material *ma);
|
||||
|
||||
void automatname(struct Material *);
|
||||
|
|
|
@ -55,7 +55,7 @@ extern "C" {
|
|||
|
||||
struct EditMesh *BKE_mesh_get_editmesh(struct Mesh *me);
|
||||
void BKE_mesh_end_editmesh(struct Mesh *me, struct EditMesh *em);
|
||||
struct BMesh *BKE_mesh_to_bmesh(struct Mesh *me);
|
||||
struct BMesh *BKE_mesh_to_bmesh(struct Mesh *me, struct Object *ob);
|
||||
|
||||
/*
|
||||
this function recreates a tesselation.
|
||||
|
@ -111,7 +111,6 @@ void mesh_calc_normals(struct MVert *mverts, int numVerts, struct MFace *mfaces,
|
|||
/* Return a newly MEM_malloc'd array of all the mesh vertex locations
|
||||
* (_numVerts_r_ may be NULL) */
|
||||
float (*mesh_getVertexCos(struct Mesh *me, int *numVerts_r))[3];
|
||||
float (*mesh_getRefKeyCos(struct Mesh *me, int *numVerts_r))[3];
|
||||
|
||||
/* map from uv vertex to face (for select linked, stitch, uv suburf) */
|
||||
|
||||
|
|
|
@ -294,7 +294,7 @@ void modifiers_foreachIDLink(struct Object *ob,
|
|||
struct ModifierData *modifiers_findByType(struct Object *ob, ModifierType type);
|
||||
void modifiers_clearErrors(struct Object *ob);
|
||||
int modifiers_getCageIndex(struct Object *ob,
|
||||
int *lastPossibleCageIndex_r);
|
||||
int *lastPossibleCageIndex_r, int virtual_);
|
||||
|
||||
int modifiers_isSoftbodyEnabled(struct Object *ob);
|
||||
int modifiers_isClothEnabled(struct Object *ob);
|
||||
|
|
|
@ -135,6 +135,7 @@ struct SeqEffectHandle {
|
|||
/* ********************* prototypes *************** */
|
||||
|
||||
/* sequence.c */
|
||||
void printf_strip(struct Sequence *seq);
|
||||
|
||||
// extern
|
||||
void seq_free_sequence(struct Scene *scene, struct Sequence *seq);
|
||||
|
@ -181,6 +182,7 @@ int check_single_seq(struct Sequence *seq);
|
|||
void fix_single_seq(struct Sequence *seq);
|
||||
int seq_test_overlap(struct ListBase * seqbasep, struct Sequence *test);
|
||||
int shuffle_seq(struct ListBase * seqbasep, struct Sequence *test);
|
||||
int shuffle_seq_time(ListBase * seqbasep);
|
||||
void free_imbuf_seq(struct ListBase * seqbasep, int check_mem_usage);
|
||||
|
||||
void seq_update_sound(struct Sequence *seq);
|
||||
|
|
|
@ -1990,9 +1990,7 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
|
|||
*final_r = NULL;
|
||||
|
||||
if(useDeform) {
|
||||
if(useDeform > 0 && do_ob_key(scene, ob)) /* shape key makes deform verts */
|
||||
deformedVerts = mesh_getVertexCos(me, &numVerts);
|
||||
else if(inputVertexCos)
|
||||
if(inputVertexCos)
|
||||
deformedVerts = inputVertexCos;
|
||||
|
||||
/* Apply all leading deforming modifiers */
|
||||
|
@ -2035,7 +2033,7 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
|
|||
if(inputVertexCos)
|
||||
deformedVerts = inputVertexCos;
|
||||
else
|
||||
deformedVerts = mesh_getRefKeyCos(me, &numVerts);
|
||||
deformedVerts = mesh_getVertexCos(me, &numVerts);
|
||||
}
|
||||
|
||||
|
||||
|
@ -2248,7 +2246,7 @@ static void editbmesh_calc_modifiers(Scene *scene, Object *ob, BMEditMesh *em, D
|
|||
float (*deformedVerts)[3] = NULL;
|
||||
CustomDataMask mask;
|
||||
DerivedMesh *dm, *orcodm = NULL;
|
||||
int i, numVerts = 0, cageIndex = modifiers_getCageIndex(ob, NULL);
|
||||
int i, numVerts = 0, cageIndex = modifiers_getCageIndex(ob, NULL, 1);
|
||||
LinkNode *datamasks, *curr;
|
||||
int required_mode = eModifierMode_Realtime | eModifierMode_Editmode;
|
||||
|
||||
|
@ -2259,7 +2257,7 @@ static void editbmesh_calc_modifiers(Scene *scene, Object *ob, BMEditMesh *em, D
|
|||
}
|
||||
|
||||
dm = NULL;
|
||||
md = ob->modifiers.first;
|
||||
md = modifiers_getVirtualModifierList(ob);
|
||||
|
||||
/* we always want to keep original indices */
|
||||
dataMask |= CD_MASK_ORIGINDEX;
|
||||
|
@ -2695,13 +2693,13 @@ int editbmesh_get_first_deform_matrices(Object *ob, BMEditMesh *em, float (**def
|
|||
ModifierData *md;
|
||||
DerivedMesh *dm;
|
||||
int i, a, numleft = 0, numVerts = 0;
|
||||
int cageIndex = modifiers_getCageIndex(ob, NULL);
|
||||
int cageIndex = modifiers_getCageIndex(ob, NULL, 1);
|
||||
float (*defmats)[3][3] = NULL, (*deformedVerts)[3] = NULL;
|
||||
|
||||
modifiers_clearErrors(ob);
|
||||
|
||||
dm = NULL;
|
||||
md = ob->modifiers.first;
|
||||
md = modifiers_getVirtualModifierList(ob);
|
||||
|
||||
/* compute the deformation matrices and coordinates for the first
|
||||
modifiers with on cage editing that are enabled and support computing
|
||||
|
|
|
@ -238,24 +238,88 @@ void BKE_animdata_make_local(AnimData *adt)
|
|||
|
||||
/* Path Validation -------------------------------------------- */
|
||||
|
||||
#if 0
|
||||
/* Check if some given RNA Path needs fixing - free the given path and set a new one as appropriate */
|
||||
static char *rna_path_rename_fix (ID *owner_id, PointerRNA *modPtr, char *newName, char *oldpath)
|
||||
/* Check if a given RNA Path is valid, by tracing it from the given ID, and seeing if we can resolve it */
|
||||
static short check_rna_path_is_valid (ID *owner_id, char *path)
|
||||
{
|
||||
PointerRNA id_ptr, ptr;
|
||||
PropertyRNA *prop=NULL;
|
||||
|
||||
/* make initial RNA pointer to start resolving from */
|
||||
RNA_id_pointer_create(owner_id, &id_ptr);
|
||||
|
||||
return oldpath; // FIXME!!!
|
||||
/* try to resolve */
|
||||
return RNA_path_resolve(&id_ptr, path, &ptr, &prop);
|
||||
}
|
||||
|
||||
/* Check if some given RNA Path needs fixing - free the given path and set a new one as appropriate
|
||||
* NOTE: we assume that oldName and newName have [" "] padding around them
|
||||
*/
|
||||
static char *rna_path_rename_fix (ID *owner_id, char *prefix, char *oldName, char *newName, char *oldpath)
|
||||
{
|
||||
char *prefixPtr= strstr(oldpath, prefix);
|
||||
char *oldNamePtr= strstr(oldpath, oldName);
|
||||
int prefixLen= strlen(prefix);
|
||||
int oldNameLen= strlen(oldName);
|
||||
|
||||
/* only start fixing the path if the prefix and oldName feature in the path,
|
||||
* and prefix occurs immediately before oldName
|
||||
*/
|
||||
if ( (prefixPtr && oldNamePtr) && (prefixPtr+prefixLen == oldNamePtr) ) {
|
||||
/* if we haven't aren't able to resolve the path now, try again after fixing it */
|
||||
if (check_rna_path_is_valid(owner_id, oldpath) == 0) {
|
||||
DynStr *ds= BLI_dynstr_new();
|
||||
char *postfixPtr= oldNamePtr+oldNameLen;
|
||||
char *newPath = NULL;
|
||||
char oldChar;
|
||||
|
||||
/* add the part of the string that goes up to the start of the prefix */
|
||||
if (prefixPtr > oldpath) {
|
||||
oldChar= prefixPtr[0];
|
||||
prefixPtr[0]= 0;
|
||||
BLI_dynstr_append(ds, oldpath);
|
||||
prefixPtr[0]= oldChar;
|
||||
}
|
||||
|
||||
/* add the prefix */
|
||||
BLI_dynstr_append(ds, prefix);
|
||||
|
||||
/* add the new name (complete with brackets) */
|
||||
BLI_dynstr_append(ds, newName);
|
||||
|
||||
/* add the postfix */
|
||||
BLI_dynstr_append(ds, postfixPtr);
|
||||
|
||||
/* create new path, and cleanup old data */
|
||||
newPath= BLI_dynstr_get_cstring(ds);
|
||||
BLI_dynstr_free(ds);
|
||||
|
||||
/* check if the new path will solve our problems */
|
||||
// TODO: will need to check whether this step really helps in practice
|
||||
if (check_rna_path_is_valid(owner_id, newPath)) {
|
||||
/* free the old path, and return the new one, since we've solved the issues */
|
||||
MEM_freeN(oldpath);
|
||||
return newPath;
|
||||
}
|
||||
else {
|
||||
/* still couldn't resolve the path... so, might as well just leave it alone */
|
||||
MEM_freeN(newPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* the old path doesn't need to be changed */
|
||||
return oldpath;
|
||||
}
|
||||
|
||||
/* Check RNA-Paths for a list of F-Curves */
|
||||
static void fcurves_path_rename_fix (ID *owner_id, PointerRNA *modPtr, char *newName, ListBase *curves)
|
||||
static void fcurves_path_rename_fix (ID *owner_id, char *prefix, char *oldName, char *newName, ListBase *curves)
|
||||
{
|
||||
FCurve *fcu;
|
||||
|
||||
/* we need to check every curve... */
|
||||
for (fcu= curves->first; fcu; fcu= fcu->next) {
|
||||
/* firstly, handle the F-Curve's own path */
|
||||
fcu->rna_path= rna_path_rename_fix(owner_id, modPtr, newName, fcu->rna_path);
|
||||
fcu->rna_path= rna_path_rename_fix(owner_id, prefix, oldName, newName, fcu->rna_path);
|
||||
|
||||
/* driver? */
|
||||
if (fcu->driver) {
|
||||
|
@ -264,14 +328,14 @@ static void fcurves_path_rename_fix (ID *owner_id, PointerRNA *modPtr, char *new
|
|||
|
||||
/* driver targets */
|
||||
for (dtar= driver->targets.first; dtar; dtar=dtar->next) {
|
||||
dtat->rna_path= rna_path_rename_fix(dtar->id, modPtr, newName, dtar->rna_path);
|
||||
dtar->rna_path= rna_path_rename_fix(dtar->id, prefix, oldName, newName, dtar->rna_path);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Fix all RNA-Paths for Actions linked to NLA Strips */
|
||||
static void nlastrips_path_rename_fix (ID *owner_id, PointerRNA *modPtr, char *newName, ListBase *strips)
|
||||
static void nlastrips_path_rename_fix (ID *owner_id, char *prefix, char *oldName, char *newName, ListBase *strips)
|
||||
{
|
||||
NlaStrip *strip;
|
||||
|
||||
|
@ -279,42 +343,122 @@ static void nlastrips_path_rename_fix (ID *owner_id, PointerRNA *modPtr, char *n
|
|||
for (strip= strips->first; strip; strip= strip->next) {
|
||||
/* fix strip's action */
|
||||
if (strip->act)
|
||||
fcurves_path_rename_fix(owner_id, modPtr, newName, &strip->act->curves);
|
||||
fcurves_path_rename_fix(owner_id, prefix, oldName, newName, &strip->act->curves);
|
||||
/* ignore own F-Curves, since those are local... */
|
||||
|
||||
/* check sub-strips (if metas) */
|
||||
nlastrips_path_rename_fix(owner_id, modPtr, newName, &strip->strips);
|
||||
nlastrips_path_rename_fix(owner_id, prefix, oldName, newName, &strip->strips);
|
||||
}
|
||||
}
|
||||
|
||||
/* Fix all RNA-Paths in the AnimData block used by the given ID block
|
||||
* - the pointer of interest must not have had its new name assigned already, otherwise
|
||||
* path matching for this will never work
|
||||
* NOTE: it is assumed that the structure we're replacing is <prefix><["><name><"]>
|
||||
* i.e. pose.pose_channels["Bone"]
|
||||
*/
|
||||
void BKE_animdata_fix_paths_rename (ID *owner_id, PointerRNA *modPtr, char *newName)
|
||||
void BKE_animdata_fix_paths_rename (ID *owner_id, AnimData *adt, char *prefix, char *oldName, char *newName)
|
||||
{
|
||||
AnimData *adt= BKE_animdata_from_id(owner_id);
|
||||
NlaTrack *nlt;
|
||||
char *oldN, *newN;
|
||||
|
||||
/* if no AnimData, no need to proceed */
|
||||
if (ELEM4(NULL, owner_id, adt, modPtr, newName))
|
||||
if (ELEM4(NULL, owner_id, adt, oldName, newName))
|
||||
return;
|
||||
|
||||
/* pad the names with [" "] so that only exact matches are made */
|
||||
oldN= BLI_sprintfN("[\"%s\"]", oldName);
|
||||
newN= BLI_sprintfN("[\"%s\"]", newName);
|
||||
|
||||
/* Active action and temp action */
|
||||
if (adt->action)
|
||||
fcurves_path_rename_fix(owner_id, modPtr, newName, &adt->action->curves);
|
||||
fcurves_path_rename_fix(owner_id, prefix, oldN, newN, &adt->action->curves);
|
||||
if (adt->tmpact)
|
||||
fcurves_path_rename_fix(owner_id, modPtr, newName, &adt->tmpact->curves);
|
||||
fcurves_path_rename_fix(owner_id, prefix, oldN, newN, &adt->tmpact->curves);
|
||||
|
||||
/* Drivers - Drivers are really F-Curves */
|
||||
fcurves_path_rename_fix(owner_id, modPtr, newName, &adt->drivers);
|
||||
fcurves_path_rename_fix(owner_id, prefix, oldN, newN, &adt->drivers);
|
||||
|
||||
/* NLA Data - Animation Data for Strips */
|
||||
for (nlt= adt->nla_tracks.first; nlt; nlt= nlt->next) {
|
||||
for (nlt= adt->nla_tracks.first; nlt; nlt= nlt->next)
|
||||
nlastrips_path_rename_fix(owner_id, prefix, oldN, newN, &nlt->strips);
|
||||
|
||||
/* free the temp names */
|
||||
MEM_freeN(oldN);
|
||||
MEM_freeN(newN);
|
||||
}
|
||||
|
||||
/* Fix all RNA-Paths throughout the database (directly access the Global.main version)
|
||||
* NOTE: it is assumed that the structure we're replacing is <prefix><["><name><"]>
|
||||
* i.e. pose.pose_channels["Bone"]
|
||||
*/
|
||||
void BKE_all_animdata_fix_paths_rename (char *prefix, char *oldName, char *newName)
|
||||
{
|
||||
Main *mainptr= G.main;
|
||||
ID *id;
|
||||
|
||||
/* macro for less typing
|
||||
* - whether animdata exists is checked for by the main renaming callback, though taking
|
||||
* this outside of the function may make things slightly faster?
|
||||
*/
|
||||
#define RENAMEFIX_ANIM_IDS(first) \
|
||||
for (id= first; id; id= id->next) { \
|
||||
AnimData *adt= BKE_animdata_from_id(id); \
|
||||
BKE_animdata_fix_paths_rename(id, adt, prefix, oldName, newName);\
|
||||
}
|
||||
|
||||
/* nodes */
|
||||
RENAMEFIX_ANIM_IDS(mainptr->nodetree.first);
|
||||
|
||||
/* textures */
|
||||
RENAMEFIX_ANIM_IDS(mainptr->tex.first);
|
||||
|
||||
/* lamps */
|
||||
RENAMEFIX_ANIM_IDS(mainptr->lamp.first);
|
||||
|
||||
/* materials */
|
||||
RENAMEFIX_ANIM_IDS(mainptr->mat.first);
|
||||
|
||||
/* cameras */
|
||||
RENAMEFIX_ANIM_IDS(mainptr->camera.first);
|
||||
|
||||
/* shapekeys */
|
||||
RENAMEFIX_ANIM_IDS(mainptr->key.first);
|
||||
|
||||
/* metaballs */
|
||||
RENAMEFIX_ANIM_IDS(mainptr->mball.first);
|
||||
|
||||
/* curves */
|
||||
RENAMEFIX_ANIM_IDS(mainptr->curve.first);
|
||||
|
||||
/* armatures */
|
||||
RENAMEFIX_ANIM_IDS(mainptr->armature.first);
|
||||
|
||||
/* meshes */
|
||||
// TODO...
|
||||
|
||||
/* particles */
|
||||
RENAMEFIX_ANIM_IDS(mainptr->particle.first);
|
||||
|
||||
/* objects */
|
||||
RENAMEFIX_ANIM_IDS(mainptr->object.first);
|
||||
|
||||
/* worlds */
|
||||
RENAMEFIX_ANIM_IDS(mainptr->world.first);
|
||||
|
||||
/* scenes */
|
||||
for (id= mainptr->scene.first; id; id= id->next) {
|
||||
AnimData *adt= BKE_animdata_from_id(id);
|
||||
Scene *scene= (Scene *)id;
|
||||
|
||||
/* do compositing nodes first (since these aren't included in main tree) */
|
||||
if (scene->nodetree) {
|
||||
AnimData *adt2= BKE_animdata_from_id((ID *)scene->nodetree);
|
||||
BKE_animdata_fix_paths_rename((ID *)scene->nodetree, adt2, prefix, oldName, newName);
|
||||
}
|
||||
|
||||
/* now fix scene animation data as per normal */
|
||||
BKE_animdata_fix_paths_rename((ID *)id, adt, prefix, oldName, newName);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* *********************************** */
|
||||
/* KeyingSet API */
|
||||
|
|
|
@ -1287,7 +1287,7 @@ void armature_mat_pose_to_delta(float delta_mat[][4], float pose_mat[][4], float
|
|||
* - the result should be that the rotations given in the provided pointers have had conversions
|
||||
* applied (as appropriate), such that the rotation of the element hasn't 'visually' changed
|
||||
*/
|
||||
void BKE_rotMode_change_values (float quat[4], float eul[3], float *axis, float angle[3], short oldMode, short newMode)
|
||||
void BKE_rotMode_change_values (float quat[4], float eul[3], float axis[3], float *angle, short oldMode, short newMode)
|
||||
{
|
||||
/* check if any change - if so, need to convert data */
|
||||
if (newMode > 0) { /* to euler */
|
||||
|
|
|
@ -226,8 +226,6 @@ static void clear_global(void)
|
|||
// free_vertexpaint();
|
||||
|
||||
G.main= NULL;
|
||||
|
||||
G.f &= ~(G_FACESELECT);
|
||||
}
|
||||
|
||||
/* make sure path names are correct for OS */
|
||||
|
@ -281,12 +279,15 @@ static void setup_app_data(bContext *C, BlendFileData *bfd, char *filename)
|
|||
Object *ob;
|
||||
bScreen *curscreen= NULL;
|
||||
Scene *curscene= NULL;
|
||||
int recover;
|
||||
char mode;
|
||||
|
||||
|
||||
/* 'u' = undo save, 'n' = no UI load */
|
||||
if(bfd->main->screen.first==NULL) mode= 'u';
|
||||
else if(G.fileflags & G_FILE_NO_UI) mode= 'n';
|
||||
else mode= 0;
|
||||
|
||||
recover= (G.fileflags & G_FILE_RECOVER);
|
||||
|
||||
clean_paths(bfd->main);
|
||||
|
||||
|
@ -371,6 +372,16 @@ static void setup_app_data(bContext *C, BlendFileData *bfd, char *filename)
|
|||
if(G.main->versionfile < 250)
|
||||
do_versions_ipos_to_animato(G.main); // XXX fixme... complicated versionpatching
|
||||
|
||||
/* in case of autosave or quit.blend, use original filename instead */
|
||||
if(recover && bfd->filename[0])
|
||||
filename= bfd->filename;
|
||||
|
||||
/* these are the same at times, should never copy to the same location */
|
||||
if(G.sce != filename)
|
||||
BLI_strncpy(G.sce, filename, FILE_MAX);
|
||||
|
||||
BLI_strncpy(G.main->name, filename, FILE_MAX); /* is guaranteed current file */
|
||||
|
||||
/* baseflags, groups, make depsgraph, etc */
|
||||
set_scene_bg(CTX_data_scene(C));
|
||||
|
||||
|
@ -383,11 +394,6 @@ static void setup_app_data(bContext *C, BlendFileData *bfd, char *filename)
|
|||
/* now tag update flags, to ensure deformers get calculated on redraw */
|
||||
DAG_scene_update_flags(CTX_data_scene(C), CTX_data_scene(C)->lay);
|
||||
|
||||
if (G.sce != filename) /* these are the same at times, should never copy to the same location */
|
||||
strcpy(G.sce, filename);
|
||||
|
||||
BLI_strncpy(G.main->name, filename, FILE_MAX); /* is guaranteed current file */
|
||||
|
||||
MEM_freeN(bfd);
|
||||
}
|
||||
|
||||
|
|
|
@ -1099,8 +1099,7 @@ float *make_orco_curve(Scene *scene, Object *ob)
|
|||
float *fp, *coord_array;
|
||||
int remakeDisp = 0;
|
||||
|
||||
if (!(cu->flag&CU_UV_ORCO) && cu->key && cu->key->refkey) {
|
||||
cp_cu_key(cu, cu->key->refkey, 0, count_curveverts(&cu->nurb));
|
||||
if (!(cu->flag&CU_UV_ORCO) && cu->key && cu->key->block.first) {
|
||||
makeDispListCurveTypes(scene, ob, 1);
|
||||
remakeDisp = 1;
|
||||
}
|
||||
|
@ -1922,7 +1921,7 @@ void makeBevelList(Object *ob)
|
|||
BevPoint *bevp, *bevp2, *bevp1 = NULL, *bevp0;
|
||||
float min, inp, x1, x2, y1, y2;
|
||||
struct bevelsort *sortdata, *sd, *sd1;
|
||||
int a, b, nr, poly, resolu, len=0;
|
||||
int a, b, nr, poly, resolu = 0, len = 0;
|
||||
int do_tilt, do_radius;
|
||||
|
||||
/* this function needs an object, because of tflag and upflag */
|
||||
|
@ -2905,6 +2904,64 @@ void curve_applyVertexCos(Curve *cu, ListBase *lb, float (*vertexCos)[3])
|
|||
}
|
||||
}
|
||||
|
||||
float (*curve_getKeyVertexCos(Curve *cu, ListBase *lb, float *key))[3]
|
||||
{
|
||||
int i, numVerts;
|
||||
float *co, (*cos)[3] = MEM_mallocN(sizeof(*cos)*numVerts, "cu_vcos");
|
||||
Nurb *nu;
|
||||
|
||||
co = cos[0];
|
||||
for (nu=lb->first; nu; nu=nu->next) {
|
||||
if (nu->type == CU_BEZIER) {
|
||||
BezTriple *bezt = nu->bezt;
|
||||
|
||||
for (i=0; i<nu->pntsu; i++,bezt++) {
|
||||
VECCOPY(co, key); co+=3; key+=3;
|
||||
VECCOPY(co, key); co+=3; key+=3;
|
||||
VECCOPY(co, key); co+=3; key+=3;
|
||||
key++; /* skip tilt */
|
||||
}
|
||||
}
|
||||
else {
|
||||
BPoint *bp = nu->bp;
|
||||
|
||||
for(i=0; i<nu->pntsu*nu->pntsv; i++,bp++) {
|
||||
VECCOPY(co, key); co+=3; key+=3;
|
||||
key++; /* skip tilt */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return cos;
|
||||
}
|
||||
|
||||
void curve_applyKeyVertexTilts(Curve *cu, ListBase *lb, float *key)
|
||||
{
|
||||
Nurb *nu;
|
||||
int i;
|
||||
|
||||
for(nu=lb->first; nu; nu=nu->next) {
|
||||
if(nu->type == CU_BEZIER) {
|
||||
BezTriple *bezt = nu->bezt;
|
||||
|
||||
for(i=0; i<nu->pntsu; i++,bezt++) {
|
||||
key+=3*3;
|
||||
bezt->alfa= *key;
|
||||
key++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
BPoint *bp = nu->bp;
|
||||
|
||||
for(i=0; i<nu->pntsu*nu->pntsv; i++,bp++) {
|
||||
key+=3;
|
||||
bp->alfa= *key;
|
||||
key++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int check_valid_nurb_u( struct Nurb *nu )
|
||||
{
|
||||
if (nu==NULL) return 0;
|
||||
|
|
|
@ -829,7 +829,27 @@ static void layerDefault_mcol(void *data, int count)
|
|||
mcol[i] = default_mcol;
|
||||
}
|
||||
|
||||
static void layerInterp_shapekey(void **sources, float *weights,
|
||||
float *sub_weights, int count, void *dest)
|
||||
{
|
||||
float *co = dest, *src;
|
||||
float **in = sources;
|
||||
int i, j, k;
|
||||
|
||||
if(count <= 0) return;
|
||||
|
||||
memset(co, 0, sizeof(float)*3);
|
||||
|
||||
sub_weight = sub_weights;
|
||||
for(i = 0; i < count; ++i) {
|
||||
float weight = weights ? weights[i] : 1.0f;
|
||||
|
||||
src = in[i];
|
||||
co[0] += src[0] * weight;
|
||||
co[1] += src[1] * weight;
|
||||
co[2] += src[2] * weight;
|
||||
}
|
||||
}
|
||||
|
||||
const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = {
|
||||
{sizeof(MVert), "MVert", 1, NULL, NULL, NULL, NULL, NULL, NULL},
|
||||
|
@ -875,13 +895,16 @@ const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = {
|
|||
layerSwap_mcol, layerDefault_mcol},
|
||||
{sizeof(MCol)*4, "MCol", 4, "TextureCol", NULL, NULL, layerInterp_mcol,
|
||||
layerSwap_mcol, layerDefault_mcol},
|
||||
{sizeof(int), "", 0, NULL, NULL, NULL, NULL, NULL, NULL},
|
||||
{sizeof(float), "", 3, "ShapeKey", layerInterp_shapekey},
|
||||
};
|
||||
|
||||
const char *LAYERTYPENAMES[CD_NUMTYPES] = {
|
||||
"CDMVert", "CDMSticky", "CDMDeformVert", "CDMEdge", "CDMFace", "CDMTFace",
|
||||
"CDMCol", "CDOrigIndex", "CDNormal", "CDFlags","CDMFloatProperty",
|
||||
"CDMIntProperty","CDMStringProperty", "CDOrigSpace", "CDOrco", "CDMTexPoly", "CDMLoopUV",
|
||||
"CDMloopCol", "CDTangent", "CDMDisps", "CDWeightMCol"};
|
||||
"CDMloopCol", "CDTangent", "CDMDisps", "CDWeightMCol", "CDMPoly",
|
||||
"CDMLoop", "CDMLoopCol", "CDIDCol", "CDTextureCol", "CDShapeKeyIndex"};
|
||||
|
||||
const CustomDataMask CD_MASK_BAREMESH =
|
||||
CD_MASK_MVERT | CD_MASK_MEDGE | CD_MASK_MFACE | CD_MASK_MLOOP | CD_MASK_MPOLY;
|
||||
|
@ -893,15 +916,17 @@ const CustomDataMask CD_MASK_MESH =
|
|||
CD_MASK_MTEXPOLY;
|
||||
const CustomDataMask CD_MASK_EDITMESH =
|
||||
CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_MTFACE | CD_MASK_MLOOPUV |
|
||||
CD_MASK_MLOOPCOL | CD_MASK_MTEXPOLY |
|
||||
CD_MASK_MCOL|CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_PROP_STR | CD_MASK_MDISPS;
|
||||
CD_MASK_MLOOPCOL | CD_MASK_MTEXPOLY | CD_MASK_SHAPE_KEYINDEX |
|
||||
CD_MASK_MCOL|CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_PROP_STR |
|
||||
CD_MASK_MDISPS | CD_MASK_SHAPEKEY;
|
||||
const CustomDataMask CD_MASK_DERIVEDMESH =
|
||||
CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_MTFACE |
|
||||
CD_MASK_MCOL | CD_MASK_ORIGINDEX | CD_MASK_PROP_FLT | CD_MASK_PROP_INT |
|
||||
CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL | CD_MASK_MTEXPOLY | CD_MASK_WEIGHT_MLOOPCOL |
|
||||
CD_MASK_PROP_STR | CD_MASK_ORIGSPACE | CD_MASK_ORCO | CD_MASK_TANGENT | CD_MASK_WEIGHT_MCOL;
|
||||
const CustomDataMask CD_MASK_BMESH = CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL | CD_MASK_MTEXPOLY |
|
||||
CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_PROP_STR;
|
||||
CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_PROP_FLT | CD_MASK_PROP_INT |
|
||||
CD_MASK_PROP_STR | CD_MASK_SHAPEKEY | CD_MASK_SHAPE_KEYINDEX;
|
||||
const CustomDataMask CD_MASK_FACECORNERS =
|
||||
CD_MASK_MTFACE | CD_MASK_MCOL | CD_MASK_MTEXPOLY | CD_MASK_MLOOPUV |
|
||||
CD_MASK_MLOOPCOL;
|
||||
|
|
|
@ -2235,7 +2235,18 @@ void DAG_id_flush_update(ID *id, short flag)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* set flags based on ShapeKey */
|
||||
if(idtype == ID_KE) {
|
||||
for(obt=bmain->object.first; obt; obt= obt->id.next) {
|
||||
Key *key= ob_get_key(obt);
|
||||
if(!(ob && obt == ob) && ((ID *)key == id)) {
|
||||
obt->flag |= (OB_RECALC|OB_RECALC_DATA);
|
||||
BKE_ptcache_object_reset(sce, obt, PTCACHE_RESET_DEPSGRAPH);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* set flags based on particle settings */
|
||||
if(idtype == ID_PA) {
|
||||
ParticleSystem *psys;
|
||||
|
|
|
@ -1245,6 +1245,7 @@ static void curve_calc_modifiers_pre(Scene *scene, Object *ob, int forRender, fl
|
|||
int editmode = (!forRender && cu->editnurb);
|
||||
float (*originalVerts)[3] = NULL;
|
||||
float (*deformedVerts)[3] = NULL;
|
||||
float *keyVerts= NULL;
|
||||
int required_mode;
|
||||
|
||||
if(forRender) required_mode = eModifierMode_Render;
|
||||
|
@ -1254,9 +1255,17 @@ static void curve_calc_modifiers_pre(Scene *scene, Object *ob, int forRender, fl
|
|||
|
||||
if(editmode) required_mode |= eModifierMode_Editmode;
|
||||
|
||||
if(cu->editnurb==NULL && do_ob_key(scene, ob)) {
|
||||
deformedVerts = curve_getVertexCos(ob->data, nurb, &numVerts);
|
||||
originalVerts = MEM_dupallocN(deformedVerts);
|
||||
if(cu->editnurb==NULL) {
|
||||
keyVerts= do_ob_key(scene, ob);
|
||||
|
||||
if(keyVerts) {
|
||||
/* split coords from key data, the latter also includes
|
||||
tilts, which is passed through in the modifier stack.
|
||||
this is also the reason curves do not use a virtual
|
||||
shape key modifier yet. */
|
||||
deformedVerts= curve_getKeyVertexCos(cu, nurb, keyVerts);
|
||||
originalVerts= MEM_dupallocN(deformedVerts);
|
||||
}
|
||||
}
|
||||
|
||||
if (preTesselatePoint) {
|
||||
|
@ -1270,7 +1279,7 @@ static void curve_calc_modifiers_pre(Scene *scene, Object *ob, int forRender, fl
|
|||
if (mti->type!=eModifierTypeType_OnlyDeform) continue;
|
||||
|
||||
if (!deformedVerts) {
|
||||
deformedVerts = curve_getVertexCos(ob->data, nurb, &numVerts);
|
||||
deformedVerts = curve_getVertexCos(cu, nurb, &numVerts);
|
||||
originalVerts = MEM_dupallocN(deformedVerts);
|
||||
}
|
||||
|
||||
|
@ -1281,9 +1290,13 @@ static void curve_calc_modifiers_pre(Scene *scene, Object *ob, int forRender, fl
|
|||
}
|
||||
}
|
||||
|
||||
if (deformedVerts) {
|
||||
curve_applyVertexCos(ob->data, nurb, deformedVerts);
|
||||
}
|
||||
if (deformedVerts)
|
||||
curve_applyVertexCos(cu, nurb, deformedVerts);
|
||||
if (keyVerts) /* these are not passed through modifier stack */
|
||||
curve_applyKeyVertexTilts(cu, nurb, keyVerts);
|
||||
|
||||
if(keyVerts)
|
||||
MEM_freeN(keyVerts);
|
||||
|
||||
*originalVerts_r = originalVerts;
|
||||
*deformedVerts_r = deformedVerts;
|
||||
|
|
|
@ -35,6 +35,9 @@
|
|||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "BLI_blenlib.h"
|
||||
#include "BLI_editVert.h"
|
||||
|
||||
#include "DNA_anim_types.h"
|
||||
#include "DNA_curve_types.h"
|
||||
#include "DNA_key_types.h"
|
||||
|
@ -53,11 +56,12 @@
|
|||
#include "BKE_lattice.h"
|
||||
#include "BKE_library.h"
|
||||
#include "BKE_mesh.h"
|
||||
#include "BKE_tessmesh.h"
|
||||
#include "BKE_main.h"
|
||||
#include "BKE_object.h"
|
||||
#include "BKE_utildefines.h"
|
||||
|
||||
#include "BLI_blenlib.h"
|
||||
#include "RNA_access.h"
|
||||
#include "BLI_cellalloc.h"
|
||||
|
||||
|
||||
|
@ -167,7 +171,7 @@ Key *copy_key(Key *key)
|
|||
while(kbn) {
|
||||
|
||||
if(kbn->data) kbn->data= MEM_dupallocN(kbn->data);
|
||||
if( kb==key->refkey ) keyn->refkey= kbn;
|
||||
if(kb==key->refkey) keyn->refkey= kbn;
|
||||
|
||||
kbn= kbn->next;
|
||||
kb= kb->next;
|
||||
|
@ -496,48 +500,80 @@ static void rel_flerp(int aantal, float *in, float *ref, float *out, float fac)
|
|||
}
|
||||
}
|
||||
|
||||
static void cp_key(int start, int end, int tot, char *poin, Key *key, KeyBlock *k, float *weights, int mode)
|
||||
static char *key_block_get_data(Key *key, KeyBlock *actkb, KeyBlock *kb, char **freedata)
|
||||
{
|
||||
if(kb == actkb) {
|
||||
/* this hack makes it possible to edit shape keys in
|
||||
edit mode with shape keys blending applied */
|
||||
if(GS(key->from->name) == ID_ME) {
|
||||
Mesh *me;
|
||||
BMVert *eve;
|
||||
BMIter iter;
|
||||
float (*co)[3];
|
||||
int a;
|
||||
|
||||
me= (Mesh*)key->from;
|
||||
|
||||
if(me->edit_btmesh && me->edit_btmesh->bm->totvert == kb->totelem) {
|
||||
a= 0;
|
||||
co= MEM_callocN(sizeof(float)*3*me->edit_btmesh->bm->totvert, "key_block_get_data");
|
||||
|
||||
BM_ITER(eve, &iter, me->edit_btmesh->bm, BM_VERTS_OF_MESH, NULL) {
|
||||
VECCOPY(co[a], eve->co);
|
||||
a++;
|
||||
}
|
||||
|
||||
*freedata= (char*)co;
|
||||
return (char*)co;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*freedata= NULL;
|
||||
return kb->data;
|
||||
}
|
||||
|
||||
static void cp_key(int start, int end, int tot, char *poin, Key *key, KeyBlock *actkb, KeyBlock *kb, float *weights, int mode)
|
||||
{
|
||||
float ktot = 0.0, kd = 0.0;
|
||||
int elemsize, poinsize = 0, a, *ofsp, ofs[32], flagflo=0;
|
||||
char *k1, *kref;
|
||||
char *k1, *kref, *freek1, *freekref;
|
||||
char *cp, elemstr[8];
|
||||
|
||||
if(key->from==NULL) return;
|
||||
|
||||
if( GS(key->from->name)==ID_ME ) {
|
||||
ofs[0]= sizeof(MVert);
|
||||
ofs[0]= sizeof(float)*3;
|
||||
ofs[1]= 0;
|
||||
poinsize= ofs[0];
|
||||
}
|
||||
else if( GS(key->from->name)==ID_LT ) {
|
||||
ofs[0]= sizeof(BPoint);
|
||||
ofs[0]= sizeof(float)*3;
|
||||
ofs[1]= 0;
|
||||
poinsize= ofs[0];
|
||||
}
|
||||
else if( GS(key->from->name)==ID_CU ) {
|
||||
if(mode==KEY_BPOINT) ofs[0]= sizeof(BPoint);
|
||||
else ofs[0]= sizeof(BezTriple);
|
||||
if(mode==KEY_BPOINT) ofs[0]= sizeof(float)*4;
|
||||
else ofs[0]= sizeof(float)*10;
|
||||
|
||||
ofs[1]= 0;
|
||||
poinsize= ofs[0];
|
||||
}
|
||||
|
||||
|
||||
if(end>tot) end= tot;
|
||||
|
||||
k1= k->data;
|
||||
kref= key->refkey->data;
|
||||
|
||||
if(tot != k->totelem) {
|
||||
if(tot != kb->totelem) {
|
||||
ktot= 0.0;
|
||||
flagflo= 1;
|
||||
if(k->totelem) {
|
||||
kd= k->totelem/(float)tot;
|
||||
if(kb->totelem) {
|
||||
kd= kb->totelem/(float)tot;
|
||||
}
|
||||
else return;
|
||||
}
|
||||
|
||||
k1= key_block_get_data(key, actkb, kb, &freek1);
|
||||
kref= key_block_get_data(key, actkb, key->refkey, &freekref);
|
||||
|
||||
/* this exception is needed for slurphing */
|
||||
if(start!=0) {
|
||||
|
||||
|
@ -574,33 +610,24 @@ static void cp_key(int start, int end, int tot, char *poin, Key *key, KeyBlock *
|
|||
|
||||
switch(cp[1]) {
|
||||
case IPO_FLOAT:
|
||||
|
||||
if(weights) {
|
||||
memcpy(poin, kref, sizeof(float)*cp[0]);
|
||||
memcpy(poin, kref, sizeof(float)*3);
|
||||
if(*weights!=0.0f)
|
||||
rel_flerp(cp[0], (float *)poin, (float *)kref, (float *)k1, *weights);
|
||||
weights++;
|
||||
}
|
||||
else
|
||||
memcpy(poin, k1, sizeof(float)*cp[0]);
|
||||
|
||||
poin+= ofsp[0];
|
||||
|
||||
memcpy(poin, k1, sizeof(float)*3);
|
||||
break;
|
||||
case IPO_BPOINT:
|
||||
memcpy(poin, k1, 3*sizeof(float));
|
||||
memcpy(poin+4*sizeof(float), k1+3*sizeof(float), sizeof(float));
|
||||
|
||||
poin+= ofsp[0];
|
||||
|
||||
memcpy(poin, k1, sizeof(float)*4);
|
||||
break;
|
||||
case IPO_BEZTRIPLE:
|
||||
memcpy(poin, k1, sizeof(float)*10);
|
||||
poin+= ofsp[0];
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
poin+= ofsp[0];
|
||||
cp+= 2; ofsp++;
|
||||
}
|
||||
|
||||
|
@ -620,71 +647,63 @@ static void cp_key(int start, int end, int tot, char *poin, Key *key, KeyBlock *
|
|||
|
||||
if(mode==KEY_BEZTRIPLE) a+=2;
|
||||
}
|
||||
|
||||
if(freek1) MEM_freeN(freek1);
|
||||
if(freekref) MEM_freeN(freekref);
|
||||
}
|
||||
|
||||
void cp_cu_key(Curve *cu, KeyBlock *kb, int start, int end)
|
||||
static void cp_cu_key(Curve *cu, Key *key, KeyBlock *actkb, KeyBlock *kb, int start, int end, char *out, int tot)
|
||||
{
|
||||
Nurb *nu;
|
||||
int a, step = 0, tot, a1, a2;
|
||||
char *poin;
|
||||
int a, step, a1, a2;
|
||||
|
||||
tot= count_curveverts(&cu->nurb);
|
||||
nu= cu->nurb.first;
|
||||
a= 0;
|
||||
while(nu) {
|
||||
for(a=0, nu=cu->nurb.first; nu; nu=nu->next, a+=step) {
|
||||
if(nu->bp) {
|
||||
|
||||
step= nu->pntsu*nu->pntsv;
|
||||
|
||||
/* exception because keys prefer to work with complete blocks */
|
||||
poin= (char *)nu->bp->vec;
|
||||
poin -= a*sizeof(BPoint);
|
||||
|
||||
poin= out - a*sizeof(float)*4;
|
||||
a1= MAX2(a, start);
|
||||
a2= MIN2(a+step, end);
|
||||
|
||||
if(a1<a2) cp_key(a1, a2, tot, poin, cu->key, kb, NULL, KEY_BPOINT);
|
||||
if(a1<a2) cp_key(a1, a2, tot, poin, key, actkb, kb, NULL, KEY_BPOINT);
|
||||
}
|
||||
else if(nu->bezt) {
|
||||
|
||||
step= 3*nu->pntsu;
|
||||
|
||||
poin= (char *)nu->bezt->vec;
|
||||
poin -= a*sizeof(BezTriple);
|
||||
|
||||
poin= out - a*sizeof(float)*10;
|
||||
a1= MAX2(a, start);
|
||||
a2= MIN2(a+step, end);
|
||||
|
||||
if(a1<a2) cp_key(a1, a2, tot, poin, cu->key, kb, NULL, KEY_BEZTRIPLE);
|
||||
|
||||
if(a1<a2) cp_key(a1, a2, tot, poin, key, actkb, kb, NULL, KEY_BEZTRIPLE);
|
||||
}
|
||||
a+= step;
|
||||
nu=nu->next;
|
||||
else
|
||||
step= 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void do_rel_key(int start, int end, int tot, char *basispoin, Key *key, int mode)
|
||||
void do_rel_key(int start, int end, int tot, char *basispoin, Key *key, KeyBlock *actkb, int mode)
|
||||
{
|
||||
KeyBlock *kb;
|
||||
int *ofsp, ofs[3], elemsize, b;
|
||||
char *cp, *poin, *reffrom, *from, elemstr[8];
|
||||
char *freefrom, *freereffrom;
|
||||
|
||||
if(key->from==NULL) return;
|
||||
|
||||
if (G.f & G_DEBUG) printf("do_rel_key() \n");
|
||||
|
||||
if( GS(key->from->name)==ID_ME ) {
|
||||
ofs[0]= sizeof(MVert);
|
||||
ofs[0]= sizeof(float)*3;
|
||||
ofs[1]= 0;
|
||||
}
|
||||
else if( GS(key->from->name)==ID_LT ) {
|
||||
ofs[0]= sizeof(BPoint);
|
||||
ofs[0]= sizeof(float)*3;
|
||||
ofs[1]= 0;
|
||||
}
|
||||
else if( GS(key->from->name)==ID_CU ) {
|
||||
if(mode==KEY_BPOINT) ofs[0]= sizeof(BPoint);
|
||||
else ofs[0]= sizeof(BezTriple);
|
||||
if(mode==KEY_BPOINT) ofs[0]= sizeof(float)*4;
|
||||
else ofs[0]= sizeof(float)*10;
|
||||
|
||||
ofs[1]= 0;
|
||||
}
|
||||
|
@ -701,7 +720,7 @@ void do_rel_key(int start, int end, int tot, char *basispoin, Key *key, int mode
|
|||
if(mode==KEY_BEZTRIPLE) elemsize*= 3;
|
||||
|
||||
/* step 1 init */
|
||||
cp_key(start, end, tot, basispoin, key, key->refkey, NULL, mode);
|
||||
cp_key(start, end, tot, basispoin, key, actkb, key->refkey, NULL, mode);
|
||||
|
||||
/* step 2: do it */
|
||||
|
||||
|
@ -709,21 +728,18 @@ void do_rel_key(int start, int end, int tot, char *basispoin, Key *key, int mode
|
|||
if(kb!=key->refkey) {
|
||||
float icuval= kb->curval;
|
||||
|
||||
if (G.f & G_DEBUG) printf("\tdo rel key %s : %s = %f \n", key->id.name+2, kb->name, icuval);
|
||||
|
||||
/* only with value, and no difference allowed */
|
||||
if(!(kb->flag & KEYBLOCK_MUTE) && icuval!=0.0f && kb->totelem==tot) {
|
||||
KeyBlock *refb;
|
||||
float weight, *weights= kb->weights;
|
||||
|
||||
if (G.f & G_DEBUG) printf("\t\tnot skipped \n");
|
||||
|
||||
poin= basispoin;
|
||||
from= kb->data;
|
||||
|
||||
/* reference now can be any block */
|
||||
refb= BLI_findlink(&key->block, kb->relative);
|
||||
if(refb==NULL) continue;
|
||||
reffrom= refb->data;
|
||||
|
||||
poin= basispoin;
|
||||
from= key_block_get_data(key, actkb, kb, &freefrom);
|
||||
reffrom= key_block_get_data(key, actkb, refb, &freereffrom);
|
||||
|
||||
poin+= start*ofs[0];
|
||||
reffrom+= key->elemsize*start; // key elemsize yes!
|
||||
|
@ -745,17 +761,13 @@ void do_rel_key(int start, int end, int tot, char *basispoin, Key *key, int mode
|
|||
|
||||
switch(cp[1]) {
|
||||
case IPO_FLOAT:
|
||||
rel_flerp(cp[0], (float *)poin, (float *)reffrom, (float *)from, weight);
|
||||
|
||||
rel_flerp(3, (float *)poin, (float *)reffrom, (float *)from, weight);
|
||||
break;
|
||||
case IPO_BPOINT:
|
||||
rel_flerp(3, (float *)poin, (float *)reffrom, (float *)from, icuval);
|
||||
rel_flerp(1, (float *)(poin+16), (float *)(reffrom+16), (float *)(from+16), icuval);
|
||||
|
||||
rel_flerp(4, (float *)poin, (float *)reffrom, (float *)from, weight);
|
||||
break;
|
||||
case IPO_BEZTRIPLE:
|
||||
rel_flerp(9, (float *)poin, (float *)reffrom, (float *)from, icuval);
|
||||
|
||||
rel_flerp(10, (float *)poin, (float *)reffrom, (float *)from, weight);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -771,38 +783,39 @@ void do_rel_key(int start, int end, int tot, char *basispoin, Key *key, int mode
|
|||
if(mode==KEY_BEZTRIPLE) b+= 2;
|
||||
if(weights) weights++;
|
||||
}
|
||||
|
||||
if(freefrom) MEM_freeN(freefrom);
|
||||
if(freereffrom) MEM_freeN(freereffrom);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void do_key(int start, int end, int tot, char *poin, Key *key, KeyBlock **k, float *t, int mode)
|
||||
static void do_key(int start, int end, int tot, char *poin, Key *key, KeyBlock *actkb, KeyBlock **k, float *t, int mode)
|
||||
{
|
||||
float k1tot = 0.0, k2tot = 0.0, k3tot = 0.0, k4tot = 0.0;
|
||||
float k1d = 0.0, k2d = 0.0, k3d = 0.0, k4d = 0.0;
|
||||
int a, ofs[32], *ofsp;
|
||||
int flagdo= 15, flagflo=0, elemsize, poinsize=0;
|
||||
char *k1, *k2, *k3, *k4;
|
||||
char *k1, *k2, *k3, *k4, *freek1, *freek2, *freek3, *freek4;
|
||||
char *cp, elemstr[8];;
|
||||
|
||||
if(key->from==0) return;
|
||||
|
||||
if (G.f & G_DEBUG) printf("do_key() \n");
|
||||
|
||||
if( GS(key->from->name)==ID_ME ) {
|
||||
ofs[0]= sizeof(MVert);
|
||||
ofs[0]= sizeof(float)*3;
|
||||
ofs[1]= 0;
|
||||
poinsize= ofs[0];
|
||||
}
|
||||
else if( GS(key->from->name)==ID_LT ) {
|
||||
ofs[0]= sizeof(BPoint);
|
||||
ofs[0]= sizeof(float)*3;
|
||||
ofs[1]= 0;
|
||||
poinsize= ofs[0];
|
||||
}
|
||||
else if( GS(key->from->name)==ID_CU ) {
|
||||
if(mode==KEY_BPOINT) ofs[0]= sizeof(BPoint);
|
||||
else ofs[0]= sizeof(BezTriple);
|
||||
if(mode==KEY_BPOINT) ofs[0]= sizeof(float)*4;
|
||||
else ofs[0]= sizeof(float)*10;
|
||||
|
||||
ofs[1]= 0;
|
||||
poinsize= ofs[0];
|
||||
|
@ -810,10 +823,10 @@ static void do_key(int start, int end, int tot, char *poin, Key *key, KeyBlock *
|
|||
|
||||
if(end>tot) end= tot;
|
||||
|
||||
k1= k[0]->data;
|
||||
k2= k[1]->data;
|
||||
k3= k[2]->data;
|
||||
k4= k[3]->data;
|
||||
k1= key_block_get_data(key, actkb, k[0], &freek1);
|
||||
k2= key_block_get_data(key, actkb, k[1], &freek2);
|
||||
k3= key_block_get_data(key, actkb, k[2], &freek3);
|
||||
k4= key_block_get_data(key, actkb, k[3], &freek4);
|
||||
|
||||
/* test for more or less points (per key!) */
|
||||
if(tot != k[0]->totelem) {
|
||||
|
@ -921,26 +934,17 @@ static void do_key(int start, int end, int tot, char *poin, Key *key, KeyBlock *
|
|||
|
||||
switch(cp[1]) {
|
||||
case IPO_FLOAT:
|
||||
flerp(cp[0], (float *)poin, (float *)k1, (float *)k2, (float *)k3, (float *)k4, t);
|
||||
poin+= ofsp[0];
|
||||
|
||||
flerp(3, (float *)poin, (float *)k1, (float *)k2, (float *)k3, (float *)k4, t);
|
||||
break;
|
||||
case IPO_BPOINT:
|
||||
flerp(3, (float *)poin, (float *)k1, (float *)k2, (float *)k3, (float *)k4, t);
|
||||
flerp(1, (float *)(poin+16), (float *)(k1+12), (float *)(k2+12), (float *)(k3+12), (float *)(k4+12), t);
|
||||
|
||||
poin+= ofsp[0];
|
||||
|
||||
flerp(4, (float *)poin, (float *)k1, (float *)k2, (float *)k3, (float *)k4, t);
|
||||
break;
|
||||
case IPO_BEZTRIPLE:
|
||||
flerp(9, (void *)poin, (void *)k1, (void *)k2, (void *)k3, (void *)k4, t);
|
||||
flerp(1, (float *)(poin+36), (float *)(k1+36), (float *)(k2+36), (float *)(k3+36), (float *)(k4+36), t);
|
||||
poin+= ofsp[0];
|
||||
|
||||
flerp(10, (void *)poin, (void *)k1, (void *)k2, (void *)k3, (void *)k4, t);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
poin+= ofsp[0];
|
||||
cp+= 2;
|
||||
ofsp++;
|
||||
}
|
||||
|
@ -988,6 +992,11 @@ static void do_key(int start, int end, int tot, char *poin, Key *key, KeyBlock *
|
|||
|
||||
if(mode==KEY_BEZTRIPLE) a+= 2;
|
||||
}
|
||||
|
||||
if(freek1) MEM_freeN(freek1);
|
||||
if(freek2) MEM_freeN(freek2);
|
||||
if(freek3) MEM_freeN(freek3);
|
||||
if(freek4) MEM_freeN(freek4);
|
||||
}
|
||||
|
||||
static float *get_weights_array(Object *ob, char *vgroup)
|
||||
|
@ -1037,41 +1046,30 @@ static float *get_weights_array(Object *ob, char *vgroup)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static int do_mesh_key(Scene *scene, Object *ob, Mesh *me)
|
||||
static void do_mesh_key(Scene *scene, Object *ob, Key *key, char *out, int tot)
|
||||
{
|
||||
KeyBlock *k[4];
|
||||
float cfra, ctime, t[4], delta, loc[3], size[3];
|
||||
KeyBlock *k[4], *actkb= ob_get_keyblock(ob);
|
||||
float cfra, ctime, t[4], delta;
|
||||
int a, flag = 0, step;
|
||||
|
||||
if(me->totvert==0) return 0;
|
||||
if(me->key==NULL) return 0;
|
||||
if(me->key->block.first==NULL) return 0;
|
||||
|
||||
/* prevent python from screwing this up? anyhoo, the from pointer could be dropped */
|
||||
me->key->from= (ID *)me;
|
||||
|
||||
if (G.f & G_DEBUG) printf("do mesh key ob:%s me:%s ke:%s \n", ob->id.name+2, me->id.name+2, me->key->id.name+2);
|
||||
|
||||
if(me->key->slurph && me->key->type!=KEY_RELATIVE ) {
|
||||
if (G.f & G_DEBUG) printf("\tslurph key\n");
|
||||
|
||||
delta= me->key->slurph;
|
||||
delta/= me->totvert;
|
||||
if(key->slurph && key->type!=KEY_RELATIVE ) {
|
||||
delta= key->slurph;
|
||||
delta/= tot;
|
||||
|
||||
step= 1;
|
||||
if(me->totvert>100 && slurph_opt) {
|
||||
step= me->totvert/50;
|
||||
if(tot>100 && slurph_opt) {
|
||||
step= tot/50;
|
||||
delta*= step;
|
||||
/* in do_key and cp_key the case a>tot is handled */
|
||||
}
|
||||
|
||||
cfra= (float)scene->r.cfra;
|
||||
|
||||
for(a=0; a<me->totvert; a+=step, cfra+= delta) {
|
||||
for(a=0; a<tot; a+=step, cfra+= delta) {
|
||||
|
||||
ctime= bsystem_time(scene, 0, cfra, 0.0); // xxx ugly cruft!
|
||||
#if 0 // XXX old animation system
|
||||
if(calc_ipo_spec(me->key->ipo, KEY_SPEED, &ctime)==0) {
|
||||
if(calc_ipo_spec(key->ipo, KEY_SPEED, &ctime)==0) {
|
||||
ctime /= 100.0;
|
||||
CLAMP(ctime, 0.0, 1.0);
|
||||
}
|
||||
|
@ -1080,42 +1078,33 @@ static int do_mesh_key(Scene *scene, Object *ob, Mesh *me)
|
|||
ctime /= 100.0f;
|
||||
CLAMP(ctime, 0.0f, 1.0f); // XXX for compat, we use this, but this clamping was confusing
|
||||
|
||||
flag= setkeys(ctime, &me->key->block, k, t, 0);
|
||||
if(flag==0) {
|
||||
|
||||
do_key(a, a+step, me->totvert, (char *)me->mvert->co, me->key, k, t, 0);
|
||||
}
|
||||
else {
|
||||
cp_key(a, a+step, me->totvert, (char *)me->mvert->co, me->key, k[2], NULL, 0);
|
||||
}
|
||||
flag= setkeys(ctime, &key->block, k, t, 0);
|
||||
|
||||
if(flag==0)
|
||||
do_key(a, a+step, tot, (char *)out, key, actkb, k, t, 0);
|
||||
else
|
||||
cp_key(a, a+step, tot, (char *)out, key, actkb, k[2], NULL, 0);
|
||||
}
|
||||
|
||||
if(flag && k[2]==me->key->refkey) tex_space_mesh(me);
|
||||
else boundbox_mesh(me, loc, size);
|
||||
}
|
||||
else {
|
||||
if(me->key->type==KEY_RELATIVE) {
|
||||
if(key->type==KEY_RELATIVE) {
|
||||
KeyBlock *kb;
|
||||
|
||||
if (G.f & G_DEBUG) printf("\tdo relative \n");
|
||||
|
||||
for(kb= me->key->block.first; kb; kb= kb->next)
|
||||
for(kb= key->block.first; kb; kb= kb->next)
|
||||
kb->weights= get_weights_array(ob, kb->vgroup);
|
||||
|
||||
do_rel_key(0, me->totvert, me->totvert, (char *)me->mvert->co, me->key, 0);
|
||||
do_rel_key(0, tot, tot, (char *)out, key, actkb, 0);
|
||||
|
||||
for(kb= me->key->block.first; kb; kb= kb->next) {
|
||||
for(kb= key->block.first; kb; kb= kb->next) {
|
||||
if(kb->weights) MEM_freeN(kb->weights);
|
||||
kb->weights= NULL;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (G.f & G_DEBUG) printf("\tdo absolute \n");
|
||||
|
||||
ctime= bsystem_time(scene, ob, (float)scene->r.cfra, 0.0f); // xxx old cruft
|
||||
|
||||
#if 0 // XXX old animation system
|
||||
if(calc_ipo_spec(me->key->ipo, KEY_SPEED, &ctime)==0) {
|
||||
if(calc_ipo_spec(key->ipo, KEY_SPEED, &ctime)==0) {
|
||||
ctime /= 100.0;
|
||||
CLAMP(ctime, 0.0, 1.0);
|
||||
}
|
||||
|
@ -1124,106 +1113,69 @@ static int do_mesh_key(Scene *scene, Object *ob, Mesh *me)
|
|||
ctime /= 100.0f;
|
||||
CLAMP(ctime, 0.0f, 1.0f); // XXX for compat, we use this, but this clamping was confusing
|
||||
|
||||
flag= setkeys(ctime, &me->key->block, k, t, 0);
|
||||
if(flag==0) {
|
||||
do_key(0, me->totvert, me->totvert, (char *)me->mvert->co, me->key, k, t, 0);
|
||||
}
|
||||
else {
|
||||
cp_key(0, me->totvert, me->totvert, (char *)me->mvert->co, me->key, k[2], NULL, 0);
|
||||
}
|
||||
|
||||
if(flag && k[2]==me->key->refkey) tex_space_mesh(me);
|
||||
else boundbox_mesh(me, loc, size);
|
||||
flag= setkeys(ctime, &key->block, k, t, 0);
|
||||
|
||||
if(flag==0)
|
||||
do_key(0, tot, tot, (char *)out, key, actkb, k, t, 0);
|
||||
else
|
||||
cp_key(0, tot, tot, (char *)out, key, actkb, k[2], NULL, 0);
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void do_cu_key(Curve *cu, KeyBlock **k, float *t)
|
||||
static void do_cu_key(Curve *cu, Key *key, KeyBlock *actkb, KeyBlock **k, float *t, char *out, int tot)
|
||||
{
|
||||
Nurb *nu;
|
||||
int a, step = 0, tot;
|
||||
char *poin;
|
||||
int a, step;
|
||||
|
||||
tot= count_curveverts(&cu->nurb);
|
||||
nu= cu->nurb.first;
|
||||
a= 0;
|
||||
|
||||
while(nu) {
|
||||
for(a=0, nu=cu->nurb.first; nu; nu=nu->next, a+=step) {
|
||||
if(nu->bp) {
|
||||
|
||||
step= nu->pntsu*nu->pntsv;
|
||||
|
||||
/* exception because keys prefer to work with complete blocks */
|
||||
poin= (char *)nu->bp->vec;
|
||||
poin -= a*sizeof(BPoint);
|
||||
|
||||
do_key(a, a+step, tot, poin, cu->key, k, t, KEY_BPOINT);
|
||||
poin= out - a*sizeof(float)*4;
|
||||
do_key(a, a+step, tot, poin, key, actkb, k, t, KEY_BPOINT);
|
||||
}
|
||||
else if(nu->bezt) {
|
||||
|
||||
step= 3*nu->pntsu;
|
||||
|
||||
poin= (char *)nu->bezt->vec;
|
||||
poin -= a*sizeof(BezTriple);
|
||||
|
||||
do_key(a, a+step, tot, poin, cu->key, k, t, KEY_BEZTRIPLE);
|
||||
|
||||
poin= out - a*sizeof(float)*10;
|
||||
do_key(a, a+step, tot, poin, key, actkb, k, t, KEY_BEZTRIPLE);
|
||||
}
|
||||
a+= step;
|
||||
nu=nu->next;
|
||||
else
|
||||
step= 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void do_rel_cu_key(Curve *cu, float ctime)
|
||||
static void do_rel_cu_key(Curve *cu, Key *key, KeyBlock *actkb, float ctime, char *out, int tot)
|
||||
{
|
||||
Nurb *nu;
|
||||
int a, step = 0, tot;
|
||||
char *poin;
|
||||
int a, step;
|
||||
|
||||
tot= count_curveverts(&cu->nurb);
|
||||
nu= cu->nurb.first;
|
||||
a= 0;
|
||||
while(nu) {
|
||||
for(a=0, nu=cu->nurb.first; nu; nu=nu->next, a+=step) {
|
||||
if(nu->bp) {
|
||||
|
||||
step= nu->pntsu*nu->pntsv;
|
||||
|
||||
/* exception because keys prefer to work with complete blocks */
|
||||
poin= (char *)nu->bp->vec;
|
||||
poin -= a*sizeof(BPoint);
|
||||
|
||||
do_rel_key(a, a+step, tot, poin, cu->key, KEY_BPOINT);
|
||||
poin= out - a*sizeof(float)*3;
|
||||
do_rel_key(a, a+step, tot, out, key, actkb, KEY_BPOINT);
|
||||
}
|
||||
else if(nu->bezt) {
|
||||
|
||||
step= 3*nu->pntsu;
|
||||
|
||||
poin= (char *)nu->bezt->vec;
|
||||
poin -= a*sizeof(BezTriple);
|
||||
|
||||
do_rel_key(a, a+step, tot, poin, cu->key, KEY_BEZTRIPLE);
|
||||
poin= out - a*sizeof(float)*10;
|
||||
do_rel_key(a, a+step, tot, poin, key, actkb, KEY_BEZTRIPLE);
|
||||
}
|
||||
a+= step;
|
||||
|
||||
nu=nu->next;
|
||||
else
|
||||
step= 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int do_curve_key(Scene *scene, Curve *cu)
|
||||
static void do_curve_key(Scene *scene, Object *ob, Key *key, char *out, int tot)
|
||||
{
|
||||
KeyBlock *k[4];
|
||||
Curve *cu= ob->data;
|
||||
KeyBlock *k[4], *actkb= ob_get_keyblock(ob);
|
||||
float cfra, ctime, t[4], delta;
|
||||
int a, flag = 0, step = 0, tot;
|
||||
int a, flag = 0, step = 0;
|
||||
|
||||
tot= count_curveverts(&cu->nurb);
|
||||
|
||||
if(tot==0) return 0;
|
||||
if(cu->key==NULL) return 0;
|
||||
if(cu->key->block.first==NULL) return 0;
|
||||
|
||||
if(cu->key->slurph) {
|
||||
delta= cu->key->slurph;
|
||||
if(key->slurph) {
|
||||
delta= key->slurph;
|
||||
delta/= tot;
|
||||
|
||||
step= 1;
|
||||
|
@ -1238,66 +1190,52 @@ static int do_curve_key(Scene *scene, Curve *cu)
|
|||
for(a=0; a<tot; a+=step, cfra+= delta) {
|
||||
ctime= bsystem_time(scene, 0, cfra, 0.0f); // XXX old cruft
|
||||
#if 0 // XXX old animation system
|
||||
if(calc_ipo_spec(cu->key->ipo, KEY_SPEED, &ctime)==0) {
|
||||
if(calc_ipo_spec(key->ipo, KEY_SPEED, &ctime)==0) {
|
||||
ctime /= 100.0;
|
||||
CLAMP(ctime, 0.0, 1.0);
|
||||
}
|
||||
#endif // XXX old animation system
|
||||
|
||||
flag= setkeys(ctime, &cu->key->block, k, t, 0);
|
||||
if(flag==0) {
|
||||
|
||||
/* do_key(a, a+step, tot, (char *)cu->mvert->co, cu->key, k, t, 0); */
|
||||
}
|
||||
else {
|
||||
/* cp_key(a, a+step, tot, (char *)cu->mvert->co, cu->key, k[2],0); */
|
||||
}
|
||||
}
|
||||
flag= setkeys(ctime, &key->block, k, t, 0);
|
||||
|
||||
if(flag && k[2]==cu->key->refkey) tex_space_curve(cu);
|
||||
|
||||
|
||||
if(flag==0)
|
||||
; /* do_key(a, a+step, tot, (char *)out, key, k, t, 0); */
|
||||
else
|
||||
; /* cp_key(a, a+step, tot, (char *)out, key, k[2],0); */
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
ctime= bsystem_time(scene, NULL, (float)scene->r.cfra, 0.0);
|
||||
|
||||
if(cu->key->type==KEY_RELATIVE) {
|
||||
do_rel_cu_key(cu, ctime);
|
||||
if(key->type==KEY_RELATIVE) {
|
||||
do_rel_cu_key(cu, cu->key, actkb, ctime, out, tot);
|
||||
}
|
||||
else {
|
||||
#if 0 // XXX old animation system
|
||||
if(calc_ipo_spec(cu->key->ipo, KEY_SPEED, &ctime)==0) {
|
||||
if(calc_ipo_spec(key->ipo, KEY_SPEED, &ctime)==0) {
|
||||
ctime /= 100.0;
|
||||
CLAMP(ctime, 0.0, 1.0);
|
||||
}
|
||||
#endif // XXX old animation system
|
||||
|
||||
flag= setkeys(ctime, &cu->key->block, k, t, 0);
|
||||
flag= setkeys(ctime, &key->block, k, t, 0);
|
||||
|
||||
if(flag==0) do_cu_key(cu, k, t);
|
||||
else cp_cu_key(cu, k[2], 0, tot);
|
||||
|
||||
if(flag && k[2]==cu->key->refkey) tex_space_curve(cu);
|
||||
if(flag==0) do_cu_key(cu, key, actkb, k, t, out, tot);
|
||||
else cp_cu_key(cu, key, actkb, k[2], 0, tot, out, tot);
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int do_latt_key(Scene *scene, Object *ob, Lattice *lt)
|
||||
static void do_latt_key(Scene *scene, Object *ob, Key *key, char *out, int tot)
|
||||
{
|
||||
KeyBlock *k[4];
|
||||
Lattice *lt= ob->data;
|
||||
KeyBlock *k[4], *actkb= ob_get_keyblock(ob);
|
||||
float delta, cfra, ctime, t[4];
|
||||
int a, tot, flag;
|
||||
int a, flag;
|
||||
|
||||
if(lt->key==NULL) return 0;
|
||||
if(lt->key->block.first==NULL) return 0;
|
||||
|
||||
tot= lt->pntsu*lt->pntsv*lt->pntsw;
|
||||
|
||||
if(lt->key->slurph) {
|
||||
delta= lt->key->slurph;
|
||||
if(key->slurph) {
|
||||
delta= key->slurph;
|
||||
delta/= (float)tot;
|
||||
|
||||
cfra= (float)scene->r.cfra;
|
||||
|
@ -1306,74 +1244,110 @@ static int do_latt_key(Scene *scene, Object *ob, Lattice *lt)
|
|||
|
||||
ctime= bsystem_time(scene, 0, cfra, 0.0); // XXX old cruft
|
||||
#if 0 // XXX old animation system
|
||||
if(calc_ipo_spec(lt->key->ipo, KEY_SPEED, &ctime)==0) {
|
||||
if(calc_ipo_spec(key->ipo, KEY_SPEED, &ctime)==0) {
|
||||
ctime /= 100.0;
|
||||
CLAMP(ctime, 0.0, 1.0);
|
||||
}
|
||||
#endif // XXX old animation system
|
||||
|
||||
flag= setkeys(ctime, <->key->block, k, t, 0);
|
||||
if(flag==0) {
|
||||
|
||||
do_key(a, a+1, tot, (char *)lt->def->vec, lt->key, k, t, 0);
|
||||
}
|
||||
else {
|
||||
cp_key(a, a+1, tot, (char *)lt->def->vec, lt->key, k[2], NULL, 0);
|
||||
}
|
||||
flag= setkeys(ctime, &key->block, k, t, 0);
|
||||
|
||||
if(flag==0)
|
||||
do_key(a, a+1, tot, (char *)out, key, actkb, k, t, 0);
|
||||
else
|
||||
cp_key(a, a+1, tot, (char *)out, key, actkb, k[2], NULL, 0);
|
||||
}
|
||||
}
|
||||
else {
|
||||
ctime= bsystem_time(scene, NULL, (float)scene->r.cfra, 0.0);
|
||||
|
||||
if(lt->key->type==KEY_RELATIVE) {
|
||||
if(key->type==KEY_RELATIVE) {
|
||||
KeyBlock *kb;
|
||||
|
||||
for(kb= lt->key->block.first; kb; kb= kb->next)
|
||||
for(kb= key->block.first; kb; kb= kb->next)
|
||||
kb->weights= get_weights_array(ob, kb->vgroup);
|
||||
|
||||
do_rel_key(0, tot, tot, (char *)lt->def->vec, lt->key, 0);
|
||||
do_rel_key(0, tot, tot, (char *)out, key, actkb, 0);
|
||||
|
||||
for(kb= lt->key->block.first; kb; kb= kb->next) {
|
||||
for(kb= key->block.first; kb; kb= kb->next) {
|
||||
if(kb->weights) MEM_freeN(kb->weights);
|
||||
kb->weights= NULL;
|
||||
}
|
||||
}
|
||||
else {
|
||||
ctime= bsystem_time(scene, NULL, (float)scene->r.cfra, 0.0);
|
||||
|
||||
#if 0 // XXX old animation system
|
||||
if(calc_ipo_spec(lt->key->ipo, KEY_SPEED, &ctime)==0) {
|
||||
if(calc_ipo_spec(key->ipo, KEY_SPEED, &ctime)==0) {
|
||||
ctime /= 100.0;
|
||||
CLAMP(ctime, 0.0, 1.0);
|
||||
}
|
||||
#endif // XXX old animation system
|
||||
|
||||
flag= setkeys(ctime, <->key->block, k, t, 0);
|
||||
if(flag==0) {
|
||||
do_key(0, tot, tot, (char *)lt->def->vec, lt->key, k, t, 0);
|
||||
}
|
||||
else {
|
||||
cp_key(0, tot, tot, (char *)lt->def->vec, lt->key, k[2], NULL, 0);
|
||||
}
|
||||
flag= setkeys(ctime, &key->block, k, t, 0);
|
||||
|
||||
if(flag==0)
|
||||
do_key(0, tot, tot, (char *)out, key, actkb, k, t, 0);
|
||||
else
|
||||
cp_key(0, tot, tot, (char *)out, key, actkb, k[2], NULL, 0);
|
||||
}
|
||||
}
|
||||
|
||||
if(lt->flag & LT_OUTSIDE) outside_lattice(lt);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* returns 1 when key applied */
|
||||
int do_ob_key(Scene *scene, Object *ob)
|
||||
/* returns key coordinates (+ tilt) when key applied, NULL otherwise */
|
||||
float *do_ob_key(Scene *scene, Object *ob)
|
||||
{
|
||||
Key *key= ob_get_key(ob);
|
||||
KeyBlock *actkb= ob_get_keyblock(ob);
|
||||
char *out;
|
||||
int tot= 0, size= 0;
|
||||
|
||||
if(key==NULL)
|
||||
return 0;
|
||||
if(key==NULL || key->block.first==NULL)
|
||||
return NULL;
|
||||
|
||||
/* compute size of output array */
|
||||
if(ob->type == OB_MESH) {
|
||||
Mesh *me= ob->data;
|
||||
|
||||
tot= me->totvert;
|
||||
size= tot*3*sizeof(float);
|
||||
}
|
||||
else if(ob->type == OB_LATTICE) {
|
||||
Lattice *lt= ob->data;
|
||||
|
||||
tot= lt->pntsu*lt->pntsv*lt->pntsw;
|
||||
size= tot*3*sizeof(float);
|
||||
}
|
||||
else if(ELEM(ob->type, OB_CURVE, OB_SURF)) {
|
||||
Curve *cu= ob->data;
|
||||
Nurb *nu;
|
||||
|
||||
for(nu=cu->nurb.first; nu; nu=nu->next) {
|
||||
if(nu->bezt) {
|
||||
tot += 3*nu->pntsu;
|
||||
size += nu->pntsu*10*sizeof(float);
|
||||
}
|
||||
else if(nu->bp) {
|
||||
tot += nu->pntsu*nu->pntsv;
|
||||
size += nu->pntsu*nu->pntsv*10*sizeof(float);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* if nothing to interpolate, cancel */
|
||||
if(tot == 0 || size == 0)
|
||||
return NULL;
|
||||
|
||||
/* allocate array */
|
||||
out= MEM_callocN(size, "do_ob_key out");
|
||||
|
||||
/* prevent python from screwing this up? anyhoo, the from pointer could be dropped */
|
||||
key->from= (ID *)ob->data;
|
||||
|
||||
if(ob->shapeflag & OB_SHAPE_LOCK) {
|
||||
/* shape locked, copy the locked shape instead of blending */
|
||||
KeyBlock *kb= BLI_findlink(&key->block, ob->shapenr-1);
|
||||
|
||||
if (G.f & G_DEBUG) printf("ob %s, key %s locked \n", ob->id.name+2, key->id.name+2);
|
||||
|
||||
if(kb && (kb->flag & KEYBLOCK_MUTE))
|
||||
kb= key->refkey;
|
||||
|
||||
|
@ -1382,46 +1356,29 @@ int do_ob_key(Scene *scene, Object *ob)
|
|||
ob->shapenr= 1;
|
||||
}
|
||||
|
||||
if(ob->type==OB_MESH) {
|
||||
Mesh *me= ob->data;
|
||||
if(ELEM(ob->type, OB_MESH, OB_LATTICE)) {
|
||||
float *weights= get_weights_array(ob, kb->vgroup);
|
||||
|
||||
cp_key(0, me->totvert, me->totvert, (char *)me->mvert->co, key, kb, weights, 0);
|
||||
|
||||
cp_key(0, tot, tot, (char*)out, key, actkb, kb, weights, 0);
|
||||
|
||||
if(weights) MEM_freeN(weights);
|
||||
}
|
||||
else if(ob->type==OB_LATTICE) {
|
||||
Lattice *lt= ob->data;
|
||||
float *weights= get_weights_array(ob, kb->vgroup);
|
||||
int tot= lt->pntsu*lt->pntsv*lt->pntsw;
|
||||
|
||||
cp_key(0, tot, tot, (char *)lt->def->vec, key, kb, weights, 0);
|
||||
|
||||
if(weights) MEM_freeN(weights);
|
||||
}
|
||||
else if ELEM(ob->type, OB_CURVE, OB_SURF) {
|
||||
Curve *cu= ob->data;
|
||||
int tot= count_curveverts(&cu->nurb);
|
||||
|
||||
cp_cu_key(cu, kb, 0, tot);
|
||||
}
|
||||
return 1;
|
||||
else if(ELEM(ob->type, OB_CURVE, OB_SURF))
|
||||
cp_cu_key(ob->data, key, actkb, kb, 0, tot, out, tot);
|
||||
}
|
||||
else {
|
||||
/* do shapekey local drivers */
|
||||
float ctime= (float)scene->r.cfra; // XXX this needs to be checked
|
||||
|
||||
if (G.f & G_DEBUG)
|
||||
printf("ob %s - do shapekey (%s) drivers \n", ob->id.name+2, key->id.name+2);
|
||||
BKE_animsys_evaluate_animdata(&key->id, key->adt, ctime, ADT_RECALC_DRIVERS);
|
||||
|
||||
if(ob->type==OB_MESH) return do_mesh_key(scene, ob, ob->data);
|
||||
else if(ob->type==OB_CURVE) return do_curve_key(scene, ob->data);
|
||||
else if(ob->type==OB_SURF) return do_curve_key(scene, ob->data);
|
||||
else if(ob->type==OB_LATTICE) return do_latt_key(scene, ob, ob->data);
|
||||
if(ob->type==OB_MESH) do_mesh_key(scene, ob, key, out, tot);
|
||||
else if(ob->type==OB_LATTICE) do_latt_key(scene, ob, key, out, tot);
|
||||
else if(ob->type==OB_CURVE) do_curve_key(scene, ob, key, out, tot);
|
||||
else if(ob->type==OB_SURF) do_curve_key(scene, ob, key, out, tot);
|
||||
}
|
||||
|
||||
return 0;
|
||||
return (float*)out;
|
||||
}
|
||||
|
||||
Key *ob_get_key(Object *ob)
|
||||
|
@ -1490,3 +1447,24 @@ KeyBlock *key_get_named_keyblock(Key *key, const char name[])
|
|||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Get RNA-Path for 'value' setting of the given ShapeKey
|
||||
* NOTE: the user needs to free the returned string once they're finishe with it
|
||||
*/
|
||||
char *key_get_curValue_rnaPath(Key *key, KeyBlock *kb)
|
||||
{
|
||||
PointerRNA ptr;
|
||||
PropertyRNA *prop;
|
||||
|
||||
/* sanity checks */
|
||||
if ELEM(NULL, key, kb)
|
||||
return NULL;
|
||||
|
||||
/* create the RNA pointer */
|
||||
RNA_pointer_create(&key->id, &RNA_ShapeKey, kb, &ptr);
|
||||
/* get pointer to the property too */
|
||||
prop= RNA_struct_find_property(&ptr, "value");
|
||||
|
||||
/* return the path */
|
||||
return RNA_path_from_ID_to_property(&ptr, prop);
|
||||
}
|
||||
|
|
|
@ -996,10 +996,6 @@ void lattice_calc_modifiers(Scene *scene, Object *ob)
|
|||
|
||||
freedisplist(&ob->disp);
|
||||
|
||||
if (!editmode) {
|
||||
do_ob_key(scene, ob);
|
||||
}
|
||||
|
||||
for (; md; md=md->next) {
|
||||
ModifierTypeInfo *mti = modifierType_getInfo(md->type);
|
||||
|
||||
|
|
|
@ -485,6 +485,18 @@ ID *material_from(Object *ob, int act)
|
|||
else return ob->data;
|
||||
}
|
||||
|
||||
Material *give_node_material(Material *ma)
|
||||
{
|
||||
if(ma && ma->use_nodes && ma->nodetree) {
|
||||
bNode *node= nodeGetActiveID(ma->nodetree, ID_MA);
|
||||
|
||||
if(node)
|
||||
return (Material *)node->id;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* GS reads the memory pointed at in a specific ordering. There are,
|
||||
* however two definitions for it. I have jotted them down here, both,
|
||||
* but I think the first one is actually used. The thing is that
|
||||
|
@ -982,7 +994,7 @@ int object_remove_material_slot(Object *ob)
|
|||
/* if g==NULL, it only does r channel */
|
||||
void ramp_blend(int type, float *r, float *g, float *b, float fac, float *col)
|
||||
{
|
||||
float tmp, facm= 1.0-fac;
|
||||
float tmp, facm= 1.0f-fac;
|
||||
|
||||
switch (type) {
|
||||
case MA_RAMP_BLEND:
|
||||
|
@ -1007,26 +1019,26 @@ void ramp_blend(int type, float *r, float *g, float *b, float fac, float *col)
|
|||
}
|
||||
break;
|
||||
case MA_RAMP_SCREEN:
|
||||
*r = 1.0 - (facm + fac*(1.0 - col[0])) * (1.0 - *r);
|
||||
*r = 1.0f - (facm + fac*(1.0f - col[0])) * (1.0f - *r);
|
||||
if(g) {
|
||||
*g = 1.0 - (facm + fac*(1.0 - col[1])) * (1.0 - *g);
|
||||
*b = 1.0 - (facm + fac*(1.0 - col[2])) * (1.0 - *b);
|
||||
*g = 1.0f - (facm + fac*(1.0f - col[1])) * (1.0f - *g);
|
||||
*b = 1.0f - (facm + fac*(1.0f - col[2])) * (1.0f - *b);
|
||||
}
|
||||
break;
|
||||
case MA_RAMP_OVERLAY:
|
||||
if(*r < 0.5f)
|
||||
*r *= (facm + 2.0f*fac*col[0]);
|
||||
else
|
||||
*r = 1.0 - (facm + 2.0f*fac*(1.0 - col[0])) * (1.0 - *r);
|
||||
*r = 1.0f - (facm + 2.0f*fac*(1.0f - col[0])) * (1.0f - *r);
|
||||
if(g) {
|
||||
if(*g < 0.5f)
|
||||
*g *= (facm + 2.0f*fac*col[1]);
|
||||
else
|
||||
*g = 1.0 - (facm + 2.0f*fac*(1.0 - col[1])) * (1.0 - *g);
|
||||
*g = 1.0f - (facm + 2.0f*fac*(1.0f - col[1])) * (1.0f - *g);
|
||||
if(*b < 0.5f)
|
||||
*b *= (facm + 2.0f*fac*col[2]);
|
||||
else
|
||||
*b = 1.0 - (facm + 2.0f*fac*(1.0 - col[2])) * (1.0 - *b);
|
||||
*b = 1.0f - (facm + 2.0f*fac*(1.0f - col[2])) * (1.0f - *b);
|
||||
}
|
||||
break;
|
||||
case MA_RAMP_SUB:
|
||||
|
@ -1037,12 +1049,12 @@ void ramp_blend(int type, float *r, float *g, float *b, float fac, float *col)
|
|||
}
|
||||
break;
|
||||
case MA_RAMP_DIV:
|
||||
if(col[0]!=0.0)
|
||||
if(col[0]!=0.0f)
|
||||
*r = facm*(*r) + fac*(*r)/col[0];
|
||||
if(g) {
|
||||
if(col[1]!=0.0)
|
||||
if(col[1]!=0.0f)
|
||||
*g = facm*(*g) + fac*(*g)/col[1];
|
||||
if(col[2]!=0.0)
|
||||
if(col[2]!=0.0f)
|
||||
*b = facm*(*b) + fac*(*b)/col[2];
|
||||
}
|
||||
break;
|
||||
|
@ -1076,31 +1088,31 @@ void ramp_blend(int type, float *r, float *g, float *b, float fac, float *col)
|
|||
case MA_RAMP_DODGE:
|
||||
|
||||
|
||||
if(*r !=0.0){
|
||||
tmp = 1.0 - fac*col[0];
|
||||
if(tmp <= 0.0)
|
||||
*r = 1.0;
|
||||
else if ((tmp = (*r) / tmp)> 1.0)
|
||||
*r = 1.0;
|
||||
if(*r !=0.0f){
|
||||
tmp = 1.0f - fac*col[0];
|
||||
if(tmp <= 0.0f)
|
||||
*r = 1.0f;
|
||||
else if ((tmp = (*r) / tmp)> 1.0f)
|
||||
*r = 1.0f;
|
||||
else
|
||||
*r = tmp;
|
||||
}
|
||||
if(g) {
|
||||
if(*g !=0.0){
|
||||
tmp = 1.0 - fac*col[1];
|
||||
if(tmp <= 0.0 )
|
||||
*g = 1.0;
|
||||
else if ((tmp = (*g) / tmp) > 1.0 )
|
||||
*g = 1.0;
|
||||
if(*g !=0.0f){
|
||||
tmp = 1.0f - fac*col[1];
|
||||
if(tmp <= 0.0f )
|
||||
*g = 1.0f;
|
||||
else if ((tmp = (*g) / tmp) > 1.0f )
|
||||
*g = 1.0f;
|
||||
else
|
||||
*g = tmp;
|
||||
}
|
||||
if(*b !=0.0){
|
||||
tmp = 1.0 - fac*col[2];
|
||||
if(tmp <= 0.0)
|
||||
*b = 1.0;
|
||||
else if ((tmp = (*b) / tmp) > 1.0 )
|
||||
*b = 1.0;
|
||||
if(*b !=0.0f){
|
||||
tmp = 1.0f - fac*col[2];
|
||||
if(tmp <= 0.0f)
|
||||
*b = 1.0f;
|
||||
else if ((tmp = (*b) / tmp) > 1.0f )
|
||||
*b = 1.0f;
|
||||
else
|
||||
*b = tmp;
|
||||
}
|
||||
|
@ -1111,33 +1123,33 @@ void ramp_blend(int type, float *r, float *g, float *b, float fac, float *col)
|
|||
|
||||
tmp = facm + fac*col[0];
|
||||
|
||||
if(tmp <= 0.0)
|
||||
*r = 0.0;
|
||||
else if (( tmp = (1.0 - (1.0 - (*r)) / tmp )) < 0.0)
|
||||
*r = 0.0;
|
||||
else if (tmp > 1.0)
|
||||
*r=1.0;
|
||||
if(tmp <= 0.0f)
|
||||
*r = 0.0f;
|
||||
else if (( tmp = (1.0f - (1.0f - (*r)) / tmp )) < 0.0f)
|
||||
*r = 0.0f;
|
||||
else if (tmp > 1.0f)
|
||||
*r=1.0f;
|
||||
else
|
||||
*r = tmp;
|
||||
|
||||
if(g) {
|
||||
tmp = facm + fac*col[1];
|
||||
if(tmp <= 0.0)
|
||||
*g = 0.0;
|
||||
else if (( tmp = (1.0 - (1.0 - (*g)) / tmp )) < 0.0 )
|
||||
*g = 0.0;
|
||||
else if(tmp >1.0)
|
||||
*g=1.0;
|
||||
if(tmp <= 0.0f)
|
||||
*g = 0.0f;
|
||||
else if (( tmp = (1.0f - (1.0f - (*g)) / tmp )) < 0.0f )
|
||||
*g = 0.0f;
|
||||
else if(tmp >1.0f)
|
||||
*g=1.0f;
|
||||
else
|
||||
*g = tmp;
|
||||
|
||||
tmp = facm + fac*col[2];
|
||||
if(tmp <= 0.0)
|
||||
*b = 0.0;
|
||||
else if (( tmp = (1.0 - (1.0 - (*b)) / tmp )) < 0.0 )
|
||||
*b = 0.0;
|
||||
else if(tmp >1.0)
|
||||
*b= 1.0;
|
||||
if(tmp <= 0.0f)
|
||||
*b = 0.0f;
|
||||
else if (( tmp = (1.0f - (1.0f - (*b)) / tmp )) < 0.0f )
|
||||
*b = 0.0f;
|
||||
else if(tmp >1.0f)
|
||||
*b= 1.0f;
|
||||
else
|
||||
*b = tmp;
|
||||
}
|
||||
|
@ -1197,29 +1209,29 @@ void ramp_blend(int type, float *r, float *g, float *b, float fac, float *col)
|
|||
float scr, scg, scb;
|
||||
|
||||
/* first calculate non-fac based Screen mix */
|
||||
scr = 1.0 - ((1.0 - col[0])) * (1.0 - *r);
|
||||
scg = 1.0 - ((1.0 - col[1])) * (1.0 - *g);
|
||||
scb = 1.0 - ((1.0 - col[2])) * (1.0 - *b);
|
||||
scr = 1.0f - (1.0f - col[0]) * (1.0f - *r);
|
||||
scg = 1.0f - (1.0f - col[1]) * (1.0f - *g);
|
||||
scb = 1.0f - (1.0f - col[2]) * (1.0f - *b);
|
||||
|
||||
*r = facm*(*r) + fac*(((1.0 - *r) * col[0] * (*r)) + (*r * scr));
|
||||
*g = facm*(*g) + fac*(((1.0 - *g) * col[1] * (*g)) + (*g * scg));
|
||||
*b = facm*(*b) + fac*(((1.0 - *b) * col[2] * (*b)) + (*b * scb));
|
||||
*r = facm*(*r) + fac*(((1.0f - *r) * col[0] * (*r)) + (*r * scr));
|
||||
*g = facm*(*g) + fac*(((1.0f - *g) * col[1] * (*g)) + (*g * scg));
|
||||
*b = facm*(*b) + fac*(((1.0f - *b) * col[2] * (*b)) + (*b * scb));
|
||||
}
|
||||
break;
|
||||
case MA_RAMP_LINEAR:
|
||||
if (col[0] > 0.5)
|
||||
*r = *r + fac*(2*(col[0]-0.5));
|
||||
if (col[0] > 0.5f)
|
||||
*r = *r + fac*(2.0f*(col[0]-0.5f));
|
||||
else
|
||||
*r = *r + fac*(2*(col[0]) - 1);
|
||||
*r = *r + fac*(2.0f*(col[0]) - 1.0f);
|
||||
if (g){
|
||||
if (col[1] > 0.5)
|
||||
*g = *g + fac*(2*(col[1]-0.5));
|
||||
if (col[1] > 0.5f)
|
||||
*g = *g + fac*(2.0f*(col[1]-0.5f));
|
||||
else
|
||||
*g = *g + fac*(2*(col[1]) -1);
|
||||
if (col[2] > 0.5)
|
||||
*b = *b + fac*(2*(col[2]-0.5));
|
||||
*g = *g + fac*(2.0f*(col[1]) -1.0f);
|
||||
if (col[2] > 0.5f)
|
||||
*b = *b + fac*(2.0f*(col[2]-0.5f));
|
||||
else
|
||||
*b = *b + fac*(2*(col[2]) - 1);
|
||||
*b = *b + fac*(2.0f*(col[2]) - 1.0f);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -345,14 +345,14 @@ Mesh *copy_mesh(Mesh *me)
|
|||
return men;
|
||||
}
|
||||
|
||||
BMesh *BKE_mesh_to_bmesh(Mesh *me)
|
||||
BMesh *BKE_mesh_to_bmesh(Mesh *me, Object *ob)
|
||||
{
|
||||
BMesh *bm;
|
||||
int allocsize[4] = {512,512,2048,512};
|
||||
|
||||
bm = BM_Make_Mesh(allocsize);
|
||||
|
||||
BMO_CallOpf(bm, "mesh_to_bmesh mesh=%p", me);
|
||||
BMO_CallOpf(bm, "mesh_to_bmesh mesh=%p object=%p", me, ob);
|
||||
|
||||
return bm;
|
||||
}
|
||||
|
@ -496,35 +496,12 @@ void boundbox_mesh(Mesh *me, float *loc, float *size)
|
|||
|
||||
void tex_space_mesh(Mesh *me)
|
||||
{
|
||||
KeyBlock *kb;
|
||||
float *fp, loc[3], size[3], min[3], max[3];
|
||||
float loc[3], size[3];
|
||||
int a;
|
||||
|
||||
boundbox_mesh(me, loc, size);
|
||||
|
||||
if(me->texflag & AUTOSPACE) {
|
||||
if(me->key) {
|
||||
kb= me->key->refkey;
|
||||
if (kb) {
|
||||
|
||||
INIT_MINMAX(min, max);
|
||||
|
||||
fp= kb->data;
|
||||
for(a=0; a<kb->totelem; a++, fp+=3) {
|
||||
DO_MINMAX(fp, min, max);
|
||||
}
|
||||
if(kb->totelem) {
|
||||
loc[0]= (min[0]+max[0])/2.0f; loc[1]= (min[1]+max[1])/2.0f; loc[2]= (min[2]+max[2])/2.0f;
|
||||
size[0]= (max[0]-min[0])/2.0f; size[1]= (max[1]-min[1])/2.0f; size[2]= (max[2]-min[2])/2.0f;
|
||||
}
|
||||
else {
|
||||
loc[0]= loc[1]= loc[2]= 0.0;
|
||||
size[0]= size[1]= size[2]= 0.0;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
for (a=0; a<3; a++) {
|
||||
if(size[a]==0.0) size[a]= 1.0;
|
||||
else if(size[a]>0.0 && size[a]<0.00001) size[a]= 0.00001;
|
||||
|
@ -564,26 +541,20 @@ void mesh_get_texspace(Mesh *me, float *loc_r, float *rot_r, float *size_r)
|
|||
float *get_mesh_orco_verts(Object *ob)
|
||||
{
|
||||
Mesh *me = ob->data;
|
||||
MVert *mvert = NULL;
|
||||
Mesh *tme = me->texcomesh?me->texcomesh:me;
|
||||
int a, totvert;
|
||||
float (*vcos)[3] = NULL;
|
||||
|
||||
/* Get appropriate vertex coordinates */
|
||||
if(me->key && me->texcomesh==0 && me->key->refkey) {
|
||||
vcos= mesh_getRefKeyCos(me, &totvert);
|
||||
}
|
||||
else {
|
||||
MVert *mvert = NULL;
|
||||
Mesh *tme = me->texcomesh?me->texcomesh:me;
|
||||
vcos = MEM_callocN(sizeof(*vcos)*me->totvert, "orco mesh");
|
||||
mvert = tme->mvert;
|
||||
totvert = MIN2(tme->totvert, me->totvert);
|
||||
|
||||
vcos = MEM_callocN(sizeof(*vcos)*me->totvert, "orco mesh");
|
||||
mvert = tme->mvert;
|
||||
totvert = MIN2(tme->totvert, me->totvert);
|
||||
|
||||
for(a=0; a<totvert; a++, mvert++) {
|
||||
vcos[a][0]= mvert->co[0];
|
||||
vcos[a][1]= mvert->co[1];
|
||||
vcos[a][2]= mvert->co[2];
|
||||
}
|
||||
for(a=0; a<totvert; a++, mvert++) {
|
||||
vcos[a][0]= mvert->co[0];
|
||||
vcos[a][1]= mvert->co[1];
|
||||
vcos[a][2]= mvert->co[2];
|
||||
}
|
||||
|
||||
return (float*)vcos;
|
||||
|
@ -1354,29 +1325,6 @@ float (*mesh_getVertexCos(Mesh *me, int *numVerts_r))[3]
|
|||
return cos;
|
||||
}
|
||||
|
||||
float (*mesh_getRefKeyCos(Mesh *me, int *numVerts_r))[3]
|
||||
{
|
||||
KeyBlock *kb;
|
||||
float (*cos)[3] = NULL;
|
||||
int totvert;
|
||||
|
||||
if(me->key && me->key->refkey) {
|
||||
if(numVerts_r) *numVerts_r= me->totvert;
|
||||
|
||||
kb= me->key->refkey;
|
||||
|
||||
/* prevent accessing invalid memory */
|
||||
if (me->totvert > kb->totelem) cos= MEM_callocN(sizeof(*cos)*me->totvert, "vertexcos1");
|
||||
else cos= MEM_mallocN(sizeof(*cos)*me->totvert, "vertexcos1");
|
||||
|
||||
totvert= MIN2(kb->totelem, me->totvert);
|
||||
|
||||
memcpy(cos, kb->data, sizeof(*cos)*totvert);
|
||||
}
|
||||
|
||||
return cos;
|
||||
}
|
||||
|
||||
UvVertMap *make_uv_vert_map(struct MFace *mface, struct MTFace *tface, unsigned int totface, unsigned int totvert, int selected, float *limit)
|
||||
{
|
||||
UvVertMap *vmap;
|
||||
|
|
|
@ -64,6 +64,7 @@
|
|||
#include "DNA_curve_types.h"
|
||||
#include "DNA_effect_types.h"
|
||||
#include "DNA_group_types.h"
|
||||
#include "DNA_key_types.h"
|
||||
#include "DNA_material_types.h"
|
||||
#include "DNA_mesh_types.h"
|
||||
#include "DNA_meshdata_types.h"
|
||||
|
@ -96,6 +97,7 @@
|
|||
#include "BKE_fluidsim.h"
|
||||
#include "BKE_global.h"
|
||||
#include "BKE_multires.h"
|
||||
#include "BKE_key.h"
|
||||
#include "BKE_lattice.h"
|
||||
#include "BKE_library.h"
|
||||
#include "BKE_material.h"
|
||||
|
@ -1196,9 +1198,9 @@ static DerivedMesh *arrayModifier_doArray(ArrayModifierData *amd,
|
|||
|
||||
/* need to avoid infinite recursion here */
|
||||
if(amd->start_cap && amd->start_cap != ob)
|
||||
start_cap = mesh_get_derived_final(scene, amd->start_cap, CD_MASK_MESH);
|
||||
start_cap = amd->start_cap->derivedFinal;
|
||||
if(amd->end_cap && amd->end_cap != ob)
|
||||
end_cap = mesh_get_derived_final(scene, amd->end_cap, CD_MASK_MESH);
|
||||
end_cap = amd->end_cap->derivedFinal;
|
||||
|
||||
Mat4One(offset);
|
||||
|
||||
|
@ -5549,7 +5551,7 @@ static DerivedMesh *booleanModifier_applyModifier(
|
|||
{
|
||||
// XXX doesn't handle derived data
|
||||
BooleanModifierData *bmd = (BooleanModifierData*) md;
|
||||
DerivedMesh *dm = mesh_get_derived_final(md->scene, bmd->object, CD_MASK_BAREMESH);
|
||||
DerivedMesh *dm = bmd->object->derivedFinal;
|
||||
|
||||
/* we do a quick sanity check */
|
||||
if(dm && (derivedData->getNumTessFaces(derivedData) > 3)
|
||||
|
@ -7536,6 +7538,52 @@ static void simpledeformModifier_deformVertsEM(ModifierData *md, Object *ob, BME
|
|||
dm->release(dm);
|
||||
}
|
||||
|
||||
/* Shape Key */
|
||||
|
||||
static void shapekeyModifier_deformVerts(
|
||||
ModifierData *md, Object *ob, DerivedMesh *derivedData,
|
||||
float (*vertexCos)[3], int numVerts, int useRenderParams, int isFinalCalc)
|
||||
{
|
||||
KeyBlock *kb= ob_get_keyblock(ob);
|
||||
float (*deformedVerts)[3];
|
||||
|
||||
if(kb && kb->totelem == numVerts) {
|
||||
deformedVerts= (float(*)[3])do_ob_key(md->scene, ob);
|
||||
if(deformedVerts) {
|
||||
memcpy(vertexCos, deformedVerts, sizeof(float)*3*numVerts);
|
||||
MEM_freeN(deformedVerts);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void shapekeyModifier_deformVertsEM(
|
||||
ModifierData *md, Object *ob, EditMesh *editData,
|
||||
DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts)
|
||||
{
|
||||
Key *key= ob_get_key(ob);
|
||||
|
||||
if(key && key->type == KEY_RELATIVE)
|
||||
shapekeyModifier_deformVerts(md, ob, derivedData, vertexCos, numVerts, 0, 0);
|
||||
}
|
||||
|
||||
static void shapekeyModifier_deformMatricesEM(
|
||||
ModifierData *md, Object *ob, EditMesh *editData,
|
||||
DerivedMesh *derivedData, float (*vertexCos)[3],
|
||||
float (*defMats)[3][3], int numVerts)
|
||||
{
|
||||
Key *key= ob_get_key(ob);
|
||||
KeyBlock *kb= ob_get_keyblock(ob);
|
||||
float scale[3][3];
|
||||
int a;
|
||||
|
||||
if(kb && kb->totelem==numVerts && kb!=key->refkey) {
|
||||
Mat3Scale(scale, kb->curval);
|
||||
|
||||
for(a=0; a<numVerts; a++)
|
||||
Mat3CpyMat3(defMats[a], scale);
|
||||
}
|
||||
}
|
||||
|
||||
/***/
|
||||
|
||||
static ModifierTypeInfo typeArr[NUM_MODIFIER_TYPES];
|
||||
|
@ -7940,6 +7988,14 @@ ModifierTypeInfo *modifierType_getInfo(ModifierType type)
|
|||
mti->copyData = multiresModifier_copyData;
|
||||
mti->applyModifier = multiresModifier_applyModifier;
|
||||
|
||||
mti = INIT_TYPE(ShapeKey);
|
||||
mti->type = eModifierTypeType_OnlyDeform;
|
||||
mti->flags = eModifierTypeFlag_AcceptsCVs
|
||||
| eModifierTypeFlag_SupportsEditmode;
|
||||
mti->deformVerts = shapekeyModifier_deformVerts;
|
||||
mti->deformVertsEM = shapekeyModifier_deformVertsEM;
|
||||
mti->deformMatricesEM = shapekeyModifier_deformMatricesEM;
|
||||
|
||||
typeArrInit = 0;
|
||||
#undef INIT_TYPE
|
||||
}
|
||||
|
@ -8104,9 +8160,9 @@ void modifier_setError(ModifierData *md, char *format, ...)
|
|||
* also used in transform_conversion.c, to detect CrazySpace [tm] (2nd arg
|
||||
* then is NULL)
|
||||
*/
|
||||
int modifiers_getCageIndex(Object *ob, int *lastPossibleCageIndex_r)
|
||||
int modifiers_getCageIndex(Object *ob, int *lastPossibleCageIndex_r, int virtual_)
|
||||
{
|
||||
ModifierData *md = ob->modifiers.first;
|
||||
ModifierData *md = (virtual_)? modifiers_getVirtualModifierList(ob): ob->modifiers.first;
|
||||
int i, cageIndex = -1;
|
||||
|
||||
/* Find the last modifier acting on the cage. */
|
||||
|
@ -8215,11 +8271,11 @@ ModifierData *modifiers_getVirtualModifierList(Object *ob)
|
|||
static ArmatureModifierData amd;
|
||||
static CurveModifierData cmd;
|
||||
static LatticeModifierData lmd;
|
||||
static ShapeKeyModifierData smd;
|
||||
static int init = 1;
|
||||
ModifierData *md;
|
||||
|
||||
if (init) {
|
||||
ModifierData *md;
|
||||
|
||||
md = modifier_new(eModifierType_Armature);
|
||||
amd = *((ArmatureModifierData*) md);
|
||||
modifier_free(md);
|
||||
|
@ -8232,32 +8288,50 @@ ModifierData *modifiers_getVirtualModifierList(Object *ob)
|
|||
lmd = *((LatticeModifierData*) md);
|
||||
modifier_free(md);
|
||||
|
||||
md = modifier_new(eModifierType_ShapeKey);
|
||||
smd = *((ShapeKeyModifierData*) md);
|
||||
modifier_free(md);
|
||||
|
||||
amd.modifier.mode |= eModifierMode_Virtual;
|
||||
cmd.modifier.mode |= eModifierMode_Virtual;
|
||||
lmd.modifier.mode |= eModifierMode_Virtual;
|
||||
smd.modifier.mode |= eModifierMode_Virtual;
|
||||
|
||||
init = 0;
|
||||
}
|
||||
|
||||
if (ob->parent) {
|
||||
md = ob->modifiers.first;
|
||||
|
||||
if(ob->parent) {
|
||||
if(ob->parent->type==OB_ARMATURE && ob->partype==PARSKEL) {
|
||||
amd.object = ob->parent;
|
||||
amd.modifier.next = ob->modifiers.first;
|
||||
amd.modifier.next = md;
|
||||
amd.deformflag= ((bArmature *)(ob->parent->data))->deformflag;
|
||||
return &amd.modifier;
|
||||
md = &amd.modifier;
|
||||
} else if(ob->parent->type==OB_CURVE && ob->partype==PARSKEL) {
|
||||
cmd.object = ob->parent;
|
||||
cmd.defaxis = ob->trackflag + 1;
|
||||
cmd.modifier.next = ob->modifiers.first;
|
||||
return &cmd.modifier;
|
||||
cmd.modifier.next = md;
|
||||
md = &cmd.modifier;
|
||||
} else if(ob->parent->type==OB_LATTICE && ob->partype==PARSKEL) {
|
||||
lmd.object = ob->parent;
|
||||
lmd.modifier.next = ob->modifiers.first;
|
||||
return &lmd.modifier;
|
||||
lmd.modifier.next = md;
|
||||
md = &lmd.modifier;
|
||||
}
|
||||
}
|
||||
|
||||
return ob->modifiers.first;
|
||||
/* shape key modifier, not yet for curves */
|
||||
if(ELEM(ob->type, OB_MESH, OB_LATTICE) && ob_get_key(ob)) {
|
||||
if(ob->type == OB_MESH && (ob->shapeflag & OB_SHAPE_EDIT_MODE))
|
||||
smd.modifier.mode |= eModifierMode_Editmode|eModifierMode_OnCage;
|
||||
else
|
||||
smd.modifier.mode &= ~eModifierMode_Editmode|eModifierMode_OnCage;
|
||||
|
||||
smd.modifier.next = md;
|
||||
md = &smd.modifier;
|
||||
}
|
||||
|
||||
return md;
|
||||
}
|
||||
/* Takes an object and returns its first selected armature, else just its
|
||||
* armature
|
||||
|
@ -8334,6 +8408,8 @@ int modifier_isDeformer(ModifierData *md)
|
|||
return 1;
|
||||
if (md->type==eModifierType_Lattice)
|
||||
return 1;
|
||||
if (md->type==eModifierType_ShapeKey)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1198,6 +1198,8 @@ static void node_init_preview(bNode *node, int xsize, int ysize)
|
|||
node->preview->xsize= xsize;
|
||||
node->preview->ysize= ysize;
|
||||
}
|
||||
else
|
||||
memset(node->preview->rect, 0, 4*xsize + xsize*ysize*sizeof(float)*4);
|
||||
}
|
||||
|
||||
void ntreeInitPreview(bNodeTree *ntree, int xsize, int ysize)
|
||||
|
|
|
@ -1134,6 +1134,8 @@ ParticleSystem *copy_particlesystem(ParticleSystem *psys)
|
|||
psysn->pathcache= NULL;
|
||||
psysn->childcache= NULL;
|
||||
psysn->edit= NULL;
|
||||
psysn->frand= NULL;
|
||||
psysn->pdd= NULL;
|
||||
|
||||
psysn->pathcachebufs.first = psysn->pathcachebufs.last = NULL;
|
||||
psysn->childcachebufs.first = psysn->childcachebufs.last = NULL;
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
|
||||
#include "DNA_brush_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
#include "DNA_mesh_types.h"
|
||||
#include "DNA_scene_types.h"
|
||||
|
||||
#include "BKE_brush.h"
|
||||
|
@ -160,8 +161,7 @@ void paint_brush_slot_remove(Paint *p)
|
|||
|
||||
int paint_facesel_test(Object *ob)
|
||||
{
|
||||
return (G.f&G_FACESELECT) && (ob && (ob->mode & (OB_MODE_VERTEX_PAINT|OB_MODE_WEIGHT_PAINT|OB_MODE_TEXTURE_PAINT)));
|
||||
|
||||
return (ob && ob->data && (((Mesh *)ob->data)->editflag & ME_EDIT_PAINT_MASK) && (ob->mode & (OB_MODE_VERTEX_PAINT|OB_MODE_WEIGHT_PAINT|OB_MODE_TEXTURE_PAINT)));
|
||||
}
|
||||
|
||||
void paint_init(Paint *p, const char col[3])
|
||||
|
|
|
@ -2278,15 +2278,20 @@ static int psys_threads_init_path(ParticleThread *threads, Scene *scene, float c
|
|||
ParticleSettings *part = psys->part;
|
||||
ParticleEditSettings *pset = &scene->toolsettings->particle;
|
||||
int totparent=0, between=0;
|
||||
int steps = (int)pow(2.0,(double)part->draw_step);
|
||||
int steps = (int)pow(2.0, (double)part->draw_step);
|
||||
int totchild = psys->totchild;
|
||||
int i, seed, totthread= threads[0].tot;
|
||||
|
||||
/*---start figuring out what is actually wanted---*/
|
||||
if(psys_in_edit_mode(scene, psys))
|
||||
if(psys_in_edit_mode(scene, psys)) {
|
||||
ParticleEditSettings *pset = &scene->toolsettings->particle;
|
||||
|
||||
if(psys->renderdata==0 && (psys->edit==NULL || pset->flag & PE_DRAW_PART)==0)
|
||||
totchild=0;
|
||||
|
||||
steps = (int)pow(2.0, (double)pset->draw_step);
|
||||
}
|
||||
|
||||
if(totchild && part->from!=PART_FROM_PARTICLE && part->childtype==PART_CHILD_FACES){
|
||||
totparent=(int)(totchild*part->parents*0.3);
|
||||
|
||||
|
@ -2361,7 +2366,7 @@ static void psys_thread_create_path(ParticleThread *thread, struct ChildParticle
|
|||
ParticleSystem *psys = ctx->sim.psys;
|
||||
ParticleSettings *part = psys->part;
|
||||
ParticleCacheKey **cache= psys->childcache;
|
||||
ParticleCacheKey **pcache= psys->pathcache;
|
||||
ParticleCacheKey **pcache= psys_in_edit_mode(ctx->sim.scene, psys) ? psys->edit->pathcache : psys->pathcache;
|
||||
ParticleCacheKey *state, *par = NULL, *key[4];
|
||||
ParticleData *pa=NULL;
|
||||
ParticleTexture ptex;
|
||||
|
@ -2373,6 +2378,9 @@ static void psys_thread_create_path(ParticleThread *thread, struct ChildParticle
|
|||
int k, cpa_num;
|
||||
short cpa_from;
|
||||
|
||||
if(!pcache)
|
||||
return;
|
||||
|
||||
if(part->flag & PART_BRANCHING) {
|
||||
branch_begin=rng_getFloat(thread->rng_path);
|
||||
branch_end=branch_begin+(1.0f-branch_begin)*rng_getFloat(thread->rng_path);
|
||||
|
@ -2955,7 +2963,7 @@ void psys_cache_edit_paths(Scene *scene, Object *ob, PTCacheEdit *edit, float cf
|
|||
|
||||
float birthtime = 0.0, dietime = 0.0;
|
||||
float t, time = 0.0, keytime = 0.0, frs_sec;
|
||||
float hairmat[4][4];
|
||||
float hairmat[4][4], rotmat[3][3], prev_tangent[3];
|
||||
int k,i;
|
||||
int steps = (int)pow(2.0, (double)pset->draw_step);
|
||||
int totpart = edit->totpoint;
|
||||
|
@ -2999,8 +3007,12 @@ void psys_cache_edit_paths(Scene *scene, Object *ob, PTCacheEdit *edit, float cf
|
|||
/*--get the first data points--*/
|
||||
init_particle_interpolation(ob, psys, pa, &pind);
|
||||
|
||||
if(psys)
|
||||
if(psys) {
|
||||
psys_mat_hair_to_global(ob, psmd->dm, psys->part->from, pa, hairmat);
|
||||
VECCOPY(rotmat[0], hairmat[2]);
|
||||
VECCOPY(rotmat[1], hairmat[1]);
|
||||
VECCOPY(rotmat[2], hairmat[0]);
|
||||
}
|
||||
|
||||
birthtime = pind.birthtime;
|
||||
dietime = pind.dietime;
|
||||
|
@ -3021,9 +3033,55 @@ void psys_cache_edit_paths(Scene *scene, Object *ob, PTCacheEdit *edit, float cf
|
|||
do_particle_interpolation(psys, i, pa, t, frs_sec, &pind, &result);
|
||||
|
||||
/* non-hair points are allready in global space */
|
||||
if(psys && !(psys->flag & PSYS_GLOBAL_HAIR))
|
||||
if(psys && !(psys->flag & PSYS_GLOBAL_HAIR)) {
|
||||
Mat4MulVecfl(hairmat, result.co);
|
||||
|
||||
/* create rotations for proper creation of children */
|
||||
if(k) {
|
||||
float cosangle, angle, tangent[3], normal[3], q[4];
|
||||
|
||||
if(k == 1) {
|
||||
/* calculate initial tangent for incremental rotations */
|
||||
VECSUB(tangent, ca->co, (ca - 1)->co);
|
||||
VECCOPY(prev_tangent, tangent);
|
||||
Normalize(prev_tangent);
|
||||
|
||||
/* First rotation is based on emitting face orientation. */
|
||||
/* This is way better than having flipping rotations resulting */
|
||||
/* from using a global axis as a rotation pole (vec_to_quat()). */
|
||||
/* It's not an ideal solution though since it disregards the */
|
||||
/* initial tangent, but taking that in to account will allow */
|
||||
/* the possibility of flipping again. -jahka */
|
||||
Mat3ToQuat_is_ok(rotmat, (ca-1)->rot);
|
||||
}
|
||||
else {
|
||||
VECSUB(tangent, ca->co, (ca - 1)->co);
|
||||
Normalize(tangent);
|
||||
|
||||
cosangle= Inpf(tangent, prev_tangent);
|
||||
|
||||
/* note we do the comparison on cosangle instead of
|
||||
* angle, since floating point accuracy makes it give
|
||||
* different results across platforms */
|
||||
if(cosangle > 0.999999f) {
|
||||
QUATCOPY((ca - 1)->rot, (ca - 2)->rot);
|
||||
}
|
||||
else {
|
||||
angle= saacos(cosangle);
|
||||
Crossf(normal, prev_tangent, tangent);
|
||||
VecRotToQuat(normal, angle, q);
|
||||
QuatMul((ca - 1)->rot, q, (ca - 2)->rot);
|
||||
}
|
||||
|
||||
VECCOPY(prev_tangent, tangent);
|
||||
}
|
||||
|
||||
if(k == steps)
|
||||
QUATCOPY(ca->rot, (ca - 1)->rot);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
VECCOPY(ca->co, result.co);
|
||||
|
||||
ca->vel[0] = ca->vel[1] = 0.0f;
|
||||
|
@ -3054,6 +3112,11 @@ void psys_cache_edit_paths(Scene *scene, Object *ob, PTCacheEdit *edit, float cf
|
|||
}
|
||||
|
||||
edit->totcached = totpart;
|
||||
|
||||
if(psys && psys->part->type == PART_HAIR) {
|
||||
ParticleSimulationData sim = {scene, ob, psys, psys_get_modifier(ob, psys), NULL};
|
||||
psys_cache_child_paths(&sim, cfra, 1);
|
||||
}
|
||||
}
|
||||
/************************************************/
|
||||
/* Particle Key handling */
|
||||
|
@ -3766,6 +3829,7 @@ void psys_get_particle_on_path(ParticleSimulationData *sim, int p, ParticleKey *
|
|||
pind.keyed = keyed;
|
||||
pind.cache = cached ? psys->pointcache : NULL;
|
||||
pind.epoint = NULL;
|
||||
pind.bspline = (psys->part->flag & PART_HAIR_BSPLINE);
|
||||
pind.dm = psys->hair_out_dm;
|
||||
init_particle_interpolation(sim->ob, psys, pa, &pind);
|
||||
do_particle_interpolation(psys, p, pa, t, frs_sec, &pind, state);
|
||||
|
|
|
@ -3504,8 +3504,6 @@ static void psys_changed_physics(ParticleSimulationData *sim)
|
|||
if(part->phystype == PART_PHYS_BOIDS && part->boids == NULL) {
|
||||
BoidState *state;
|
||||
|
||||
psys_check_boid_data(sim->psys);
|
||||
|
||||
part->boids = MEM_callocN(sizeof(BoidSettings), "Boid Settings");
|
||||
boid_default_settings(part->boids);
|
||||
|
||||
|
@ -3518,6 +3516,8 @@ static void psys_changed_physics(ParticleSimulationData *sim)
|
|||
state->flag |= BOIDSTATE_CURRENT;
|
||||
BLI_addtail(&part->boids->states, state);
|
||||
}
|
||||
|
||||
psys_check_boid_data(sim->psys);
|
||||
}
|
||||
static void particles_fluid_step(ParticleSimulationData *sim, int cfra)
|
||||
{
|
||||
|
|
|
@ -69,6 +69,13 @@ static int blender_test_break() {return 0;}
|
|||
/* **** XXX ******** */
|
||||
|
||||
|
||||
void printf_strip(Sequence *seq)
|
||||
{
|
||||
fprintf(stderr, "name: '%s', len:%d, start:%d, (startofs:%d, endofs:%d), (startstill:%d, endstill:%d), machine:%d, (startdisp:%d, enddisp:%d)\n",
|
||||
seq->name, seq->len, seq->start, seq->startofs, seq->endofs, seq->startstill, seq->endstill, seq->machine, seq->startdisp, seq->enddisp);
|
||||
fprintf(stderr, "\tseq_tx_set_final_left: %d %d\n\n", seq_tx_get_final_left(seq, 0), seq_tx_get_final_right(seq, 0));
|
||||
}
|
||||
|
||||
/* **********************************************************************
|
||||
alloc / free functions
|
||||
********************************************************************** */
|
||||
|
@ -3238,7 +3245,7 @@ void seq_tx_set_final_left(Sequence *seq, int val)
|
|||
{
|
||||
if (val < (seq)->start) {
|
||||
seq->startstill = abs(val - (seq)->start);
|
||||
(seq)->startofs = 0;
|
||||
seq->startofs = 0;
|
||||
} else {
|
||||
seq->startofs = abs(val - (seq)->start);
|
||||
seq->startstill = 0;
|
||||
|
@ -3249,7 +3256,7 @@ void seq_tx_set_final_right(Sequence *seq, int val)
|
|||
{
|
||||
if (val > (seq)->start + (seq)->len) {
|
||||
seq->endstill = abs(val - (seq->start + (seq)->len));
|
||||
(seq)->endofs = 0;
|
||||
seq->endofs = 0;
|
||||
} else {
|
||||
seq->endofs = abs(val - ((seq)->start + (seq)->len));
|
||||
seq->endstill = 0;
|
||||
|
@ -3334,18 +3341,25 @@ int seq_tx_test(Sequence * seq)
|
|||
return (seq->type < SEQ_EFFECT) || (get_sequence_effect_num_inputs(seq->type) == 0);
|
||||
}
|
||||
|
||||
static int seq_overlap(Sequence *seq1, Sequence *seq2)
|
||||
{
|
||||
if(seq1 != seq2)
|
||||
if(seq1->machine==seq2->machine)
|
||||
if(((seq1->enddisp <= seq2->startdisp) || (seq1->startdisp >= seq2->enddisp))==0)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int seq_test_overlap(ListBase * seqbasep, Sequence *test)
|
||||
{
|
||||
Sequence *seq;
|
||||
|
||||
seq= seqbasep->first;
|
||||
while(seq) {
|
||||
if(seq!=test) {
|
||||
if(test->machine==seq->machine) {
|
||||
if( (test->enddisp <= seq->startdisp) || (test->startdisp >= seq->enddisp) );
|
||||
else return 1;
|
||||
}
|
||||
}
|
||||
if(seq_overlap(test, seq))
|
||||
return 1;
|
||||
|
||||
seq= seq->next;
|
||||
}
|
||||
return 0;
|
||||
|
@ -3403,6 +3417,76 @@ int shuffle_seq(ListBase * seqbasep, Sequence *test)
|
|||
}
|
||||
}
|
||||
|
||||
static int shuffle_seq_time_offset_test(ListBase * seqbasep, char dir)
|
||||
{
|
||||
int offset= 0;
|
||||
Sequence *seq, *seq_other;
|
||||
|
||||
for(seq= seqbasep->first; seq; seq= seq->next) {
|
||||
if(seq->tmp) {
|
||||
for(seq_other= seqbasep->first; seq_other; seq_other= seq_other->next) {
|
||||
if(seq_overlap(seq, seq_other)) {
|
||||
if(dir=='L') {
|
||||
offset= MIN2(offset, seq_other->startdisp - seq->enddisp);
|
||||
}
|
||||
else {
|
||||
offset= MAX2(offset, seq_other->enddisp - seq->startdisp);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return offset;
|
||||
}
|
||||
|
||||
static int shuffle_seq_time_offset(ListBase * seqbasep, char dir)
|
||||
{
|
||||
int ofs= 0;
|
||||
int tot_ofs= 0;
|
||||
Sequence *seq;
|
||||
while( (ofs= shuffle_seq_time_offset_test(seqbasep, dir)) ) {
|
||||
for(seq= seqbasep->first; seq; seq= seq->next) {
|
||||
if(seq->tmp) {
|
||||
/* seq_test_overlap only tests display values */
|
||||
seq->startdisp += ofs;
|
||||
seq->enddisp += ofs;
|
||||
}
|
||||
}
|
||||
|
||||
tot_ofs+= ofs;
|
||||
}
|
||||
|
||||
for(seq= seqbasep->first; seq; seq= seq->next) {
|
||||
if(seq->tmp)
|
||||
calc_sequence_disp(seq); /* corrects dummy startdisp/enddisp values */
|
||||
}
|
||||
|
||||
return tot_ofs;
|
||||
}
|
||||
|
||||
int shuffle_seq_time(ListBase * seqbasep)
|
||||
{
|
||||
/* note: seq->tmp is used to tag strips to move */
|
||||
|
||||
Sequence *seq;
|
||||
|
||||
int offset_l = shuffle_seq_time_offset(seqbasep, 'L');
|
||||
int offset_r = shuffle_seq_time_offset(seqbasep, 'R');
|
||||
int offset = (-offset_l < offset_r) ? offset_l:offset_r;
|
||||
|
||||
if(offset) {
|
||||
for(seq= seqbasep->first; seq; seq= seq->next) {
|
||||
if(seq->tmp) {
|
||||
seq_translate(seq, offset);
|
||||
seq->flag &= ~SEQ_OVERLAP;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return offset? 0:1;
|
||||
}
|
||||
|
||||
|
||||
void seq_update_sound(struct Sequence *seq)
|
||||
{
|
||||
if(seq->type == SEQ_SOUND)
|
||||
|
|
|
@ -1027,7 +1027,7 @@ static void smoke_calc_domain(Scene *scene, Object *ob, SmokeModifierData *smd)
|
|||
{
|
||||
SmokeModifierData *smd2 = (SmokeModifierData *)md;
|
||||
|
||||
if((smd2->type & MOD_SMOKE_TYPE_COLL) && smd2->coll)
|
||||
if((smd2->type & MOD_SMOKE_TYPE_COLL) && smd2->coll && smd2->coll->points)
|
||||
{
|
||||
// we got nice collision object
|
||||
SmokeCollSettings *scs = smd2->coll;
|
||||
|
|
|
@ -1706,7 +1706,7 @@ static int sb_detect_vertex_collisionCached(float opco[3], float facenormal[3],
|
|||
GHash *hash;
|
||||
GHashIterator *ihash;
|
||||
float nv1[3], nv2[3], nv3[3], nv4[3], edge1[3], edge2[3],d_nvect[3], dv1[3],ve[3],avel[3]={0.0,0.0,0.0},
|
||||
vv1[3], vv2[3], vv3[3], vv4[3], coledge[3], mindistedge = 1000.0f,
|
||||
vv1[3], vv2[3], vv3[3], vv4[3], coledge[3]={0.0f, 0.0f, 0.0f}, mindistedge = 1000.0f,
|
||||
outerforceaccu[3],innerforceaccu[3],
|
||||
facedist,n_mag,force_mag_norm,minx,miny,minz,maxx,maxy,maxz,
|
||||
innerfacethickness = -0.5f, outerfacethickness = 0.2f,
|
||||
|
|
|
@ -454,6 +454,7 @@ void i_window(
|
|||
#define BLI_CS_CIE 2
|
||||
|
||||
#define RAD2DEG(_rad) ((_rad)*(180.0/M_PI))
|
||||
#define DEG2RAD(_deg) ((_deg)*(M_PI/180.0))
|
||||
|
||||
void hsv_to_rgb(float h, float s, float v, float *r, float *g, float *b);
|
||||
void hex_to_rgb(char *hexcol, float *r, float *g, float *b);
|
||||
|
|
|
@ -38,9 +38,9 @@
|
|||
#define BFILE_NORMAL (0)
|
||||
/* No supervision, just translate // if needed, RISKY */
|
||||
#define BFILE_RAW (1<<0)
|
||||
/* Path is relative to config dirs */
|
||||
/* Path is based in env vars specified by "envvars" */
|
||||
#define BFILE_CONFIG (1<<1)
|
||||
/* Path is for current session temp file */
|
||||
/* Path is for current session temp files */
|
||||
#define BFILE_TEMP (1<<2)
|
||||
|
||||
/* Config handling, special cases: */
|
||||
|
@ -50,6 +50,17 @@
|
|||
/* Compression to apply on close: */
|
||||
#define BFILE_GZIP (1<<5)
|
||||
|
||||
/**
|
||||
For the envvars param.
|
||||
*/
|
||||
typedef enum BEnvVarFamilies {
|
||||
BENV_NONE,
|
||||
BENV_BASE,
|
||||
BENV_DATAFILES,
|
||||
BENV_PYTHON,
|
||||
BENV_PLUGINS
|
||||
} BEnvVarFam;
|
||||
|
||||
/**
|
||||
File descriptor for Blender abstracted file access.
|
||||
*/
|
||||
|
@ -58,22 +69,23 @@ typedef struct {
|
|||
int fd;
|
||||
|
||||
/* Anything below should not be touched directly */
|
||||
int uflags; /* Special options requested by upper level, copy of bflags */
|
||||
char *fpath; /* Final/requested path name */
|
||||
char *tpath; /* Temp path name if applicable */
|
||||
int type; /* Own flags, common classification of open and fopen */
|
||||
int error; /* An op caused an error, unsafe to replace older files */
|
||||
int uflags; /* Special options requested by upper level, copy of bflags */
|
||||
BEnvVarFam evars; /* What kind of file, describe the env vars to use */
|
||||
char *fpath; /* Final/requested path name */
|
||||
char *tpath; /* Temp path name if applicable */
|
||||
int classf; /* Own flags, common classification of open and fopen */
|
||||
int error; /* An op caused an error, unsafe to replace older files */
|
||||
} BFILE;
|
||||
|
||||
/**
|
||||
Open a BFILE* with fopen()-like syntax.
|
||||
*/
|
||||
BFILE *BLI_bfile_fopen(const char *path, const char *mode, int bflags);
|
||||
BFILE *BLI_bfile_fopen(const char *path, const char *mode, int bflags, BEnvVarFam envvars);
|
||||
|
||||
/**
|
||||
Open a BFILE* with open()-like syntax.
|
||||
*/
|
||||
BFILE *BLI_bfile_open(const char *pathname, int flags, int bflags);
|
||||
BFILE *BLI_bfile_open(const char *pathname, int flags, int bflags, BEnvVarFam envvars);
|
||||
|
||||
/**
|
||||
Get the FILE* associated with the BFILE*.
|
||||
|
|
|
@ -176,6 +176,8 @@ typedef struct EditMesh
|
|||
short mat_nr;
|
||||
/* stats */
|
||||
int totvert, totedge, totface, totvertsel, totedgesel, totfacesel;
|
||||
/* shape key being edited */
|
||||
int shapenr;
|
||||
|
||||
struct DerivedMesh *derivedCage, *derivedFinal;
|
||||
/* the custom data layer mask that was last used to calculate
|
||||
|
|
|
@ -178,7 +178,7 @@ extern unsigned int hashsizes[];
|
|||
/*---------inlined functions---------*/
|
||||
BM_INLINE void BLI_ghash_insert(GHash *gh, void *key, void *val) {
|
||||
unsigned int hash= gh->hashfp(key)%gh->nbuckets;
|
||||
Entry *e= BLI_mempool_alloc(gh->entrypool);
|
||||
Entry *e= (Entry*) BLI_mempool_alloc(gh->entrypool);
|
||||
|
||||
e->key= key;
|
||||
e->val= val;
|
||||
|
|
|
@ -66,6 +66,9 @@ int BLI_exist(char *name);
|
|||
* @param name The name of the file to read.
|
||||
* @retval A list of strings representing the file lines.
|
||||
*/
|
||||
|
||||
int BLI_is_dir(char *file);
|
||||
|
||||
struct LinkNode *BLI_read_file_as_lines(char *name);
|
||||
|
||||
/**
|
||||
|
|
|
@ -51,6 +51,7 @@ char *BLI_gethome_folder(char *folder_name, int flag);
|
|||
#define BLI_GETHOME_ALL (BLI_GETHOME_SYSTEM|BLI_GETHOME_LOCAL|BLI_GETHOME_USER)
|
||||
|
||||
void BLI_setenv(const char *env, const char *val);
|
||||
void BLI_setenv_if_new(const char *env, const char* val);
|
||||
|
||||
void BLI_make_file_string(const char *relabase, char *string, const char *dir, const char *file);
|
||||
void BLI_make_exist(char *dir);
|
||||
|
|
|
@ -129,6 +129,7 @@ struct dirent *readdir(DIR *dp);
|
|||
int closedir (DIR *dp);
|
||||
void get_default_root(char *root);
|
||||
int check_file_chars(char *filename);
|
||||
char *dirname(char *path);
|
||||
|
||||
#ifdef WIN32
|
||||
int BLI_getInstallationDir(char *str);
|
||||
|
|
|
@ -25,89 +25,70 @@
|
|||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#ifndef WIN32
|
||||
#include <unistd.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/param.h>
|
||||
// #include <libgen.h>
|
||||
#else
|
||||
#include <io.h>
|
||||
#include "BLI_winstuff.h"
|
||||
#include <io.h>
|
||||
#include "BLI_winstuff.h"
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "BKE_utildefines.h"
|
||||
#include "BKE_blender.h"
|
||||
#include "BLI_util.h"
|
||||
#include "BLI_fileops.h"
|
||||
#include "BLI_storage.h"
|
||||
#include "BLI_bfile.h"
|
||||
|
||||
// This would provide config paths and their oldest viable version
|
||||
// so if there is an uncompatible change, user's old versions are not loaded
|
||||
//#include "bfile_tables.h"
|
||||
/* Internal bfile classification flags */
|
||||
#define BCF_OPEN (0)
|
||||
#define BCF_FOPEN (1<<0)
|
||||
#define BCF_READ (1<<1)
|
||||
#define BCF_WRITE (1<<2)
|
||||
#define BCF_AT_END (1<<3)
|
||||
#define BCF_DISCARD (1<<4)
|
||||
|
||||
/* Internal bfile type flags */
|
||||
#define BTF_OPEN (0)
|
||||
#define BTF_FOPEN (1<<0)
|
||||
#define BTF_READ (1<<1)
|
||||
#define BTF_WRITE (1<<2)
|
||||
#define BTF_AT_END (1<<3)
|
||||
#define BTF_DISCARD (1<<4)
|
||||
/* Declaration of internal functions */
|
||||
void chomp(char* line);
|
||||
void expand_envvars(char* src, char* dst);
|
||||
void fill_paths(BFILE *bfile, const char *path);
|
||||
char* find_in_pathlist(char* filename, char* pathlist);
|
||||
void init_vars_from_file(const char* path);
|
||||
void setup_temp();
|
||||
|
||||
/*** Exported functions ***/
|
||||
|
||||
void fill_paths(BFILE *bfile, const char *path) {
|
||||
char* source_path = NULL;
|
||||
int bflags = bfile->uflags;
|
||||
|
||||
if(bflags & BFILE_NORMAL || bflags & BFILE_RAW) {
|
||||
// bfile->fpath is path with // replaced
|
||||
}
|
||||
if(bflags & BFILE_TEMP) {
|
||||
// bfile->fpath is tempdir+path
|
||||
}
|
||||
if(bflags & BFILE_CONFIG) {
|
||||
// bfile->fpath is userdir+version+path
|
||||
// source_path is first hit in (if using fallback to older versions)
|
||||
// userdir+curversion+path (... userdir+limitversion+path) sysdir+path
|
||||
// (limitversion is based in path, using some kind of regex or "tables")
|
||||
}
|
||||
|
||||
if(bfile->type & BTF_WRITE && !(bflags & BFILE_RAW)) {
|
||||
/* Generate temp path */
|
||||
// bfile->tpath is fpath+randstring
|
||||
if(!(bfile->type & BTF_DISCARD)) {
|
||||
/* Copy data to tpath */
|
||||
if(source_path) {
|
||||
// copy it from older version or sys version
|
||||
}
|
||||
}
|
||||
} else {
|
||||
bfile->tpath = bfile->fpath;
|
||||
}
|
||||
}
|
||||
|
||||
BFILE *BLI_bfile_fopen(const char *path, const char *mode, int bflags) {
|
||||
BFILE *BLI_bfile_fopen(const char *path, const char *mode, int bflags,
|
||||
BEnvVarFam envvars)
|
||||
{
|
||||
BFILE *bfile;
|
||||
|
||||
bfile = MEM_mallocN(sizeof(BFILE), "bfile-fopen");
|
||||
bfile->type = BTF_FOPEN;
|
||||
bfile->classf = BCF_FOPEN;
|
||||
bfile->uflags = bflags;
|
||||
|
||||
/* From fopen() doc, we can guess some logic:
|
||||
r BTF_READ
|
||||
r+ BTF_READ | BTF_WRITE
|
||||
w BTF_DISCARD | BTF_WRITE
|
||||
w+ BTF_DISCARD | BTF_WRITE | BTF_READ
|
||||
a BTF_AT_END | BTF_WRITE
|
||||
a+ BTF_AT_END | BTF_WRITE | BTF_READ
|
||||
r BCF_READ
|
||||
r+ BCF_READ | BCF_WRITE
|
||||
w BCF_DISCARD | BCF_WRITE
|
||||
w+ BCF_DISCARD | BCF_WRITE | BCF_READ
|
||||
a BCF_AT_END | BCF_WRITE
|
||||
a+ BCF_AT_END | BCF_WRITE | BCF_READ
|
||||
*/
|
||||
if(strchr(mode, 'r'))
|
||||
bfile->type |= BTF_READ;
|
||||
bfile->classf |= BCF_READ;
|
||||
if(strchr(mode, 'w'))
|
||||
bfile->type |= (BTF_DISCARD | BTF_WRITE);
|
||||
bfile->classf |= (BCF_DISCARD | BCF_WRITE);
|
||||
if(strchr(mode, 'a'))
|
||||
bfile->type |= (BTF_AT_END | BTF_WRITE);
|
||||
bfile->classf |= (BCF_AT_END | BCF_WRITE);
|
||||
if(strchr(mode, '+'))
|
||||
bfile->type |= (BTF_READ | BTF_WRITE);
|
||||
bfile->classf |= (BCF_READ | BCF_WRITE);
|
||||
|
||||
fill_paths(bfile, path);
|
||||
|
||||
|
@ -118,24 +99,26 @@ BFILE *BLI_bfile_fopen(const char *path, const char *mode, int bflags) {
|
|||
}
|
||||
|
||||
|
||||
BFILE *BLI_bfile_open(const char *pathname, int flags, int bflags) {
|
||||
BFILE *BLI_bfile_open(const char *pathname, int flags, int bflags,
|
||||
BEnvVarFam envvars)
|
||||
{
|
||||
BFILE *bfile;
|
||||
|
||||
bfile = MEM_mallocN(sizeof(BFILE), "bfile-open");
|
||||
bfile->type = BTF_OPEN;
|
||||
bfile->classf = BCF_OPEN;
|
||||
bfile->uflags = bflags;
|
||||
|
||||
/* Easy mapping for open() */
|
||||
if(flags & O_RDONLY)
|
||||
bfile->type |= BTF_READ;
|
||||
bfile->classf |= BCF_READ;
|
||||
if(flags & O_WRONLY)
|
||||
bfile->type |= BTF_WRITE;
|
||||
bfile->classf |= BCF_WRITE;
|
||||
if(flags & O_RDWR)
|
||||
bfile->type |= (BTF_READ | BTF_WRITE);
|
||||
bfile->classf |= (BCF_READ | BCF_WRITE);
|
||||
if(flags & O_APPEND)
|
||||
bfile->type |= BTF_AT_END;
|
||||
bfile->classf |= BCF_AT_END;
|
||||
if(flags & O_TRUNC)
|
||||
bfile->type |= BTF_DISCARD;
|
||||
bfile->classf |= BCF_DISCARD;
|
||||
|
||||
fill_paths(bfile, pathname);
|
||||
|
||||
|
@ -180,7 +163,9 @@ ssize_t BLI_bfile_read(BFILE *f, void *buf, size_t count) {
|
|||
}
|
||||
|
||||
|
||||
size_t BLI_bfile_fwrite(const void *ptr, size_t size, size_t nmemb, BFILE *f) {
|
||||
size_t BLI_bfile_fwrite(const void *ptr, size_t size, size_t nmemb,
|
||||
BFILE *f)
|
||||
{
|
||||
size_t ret;
|
||||
|
||||
ret = fwrite(ptr, size, nmemb, f->stream);
|
||||
|
@ -205,7 +190,7 @@ size_t BLI_bfile_fread(void *ptr, size_t size, size_t nmemb, BFILE *f) {
|
|||
|
||||
|
||||
void BLI_bfile_close(BFILE *bfile) {
|
||||
if((bfile->type | BTF_WRITE) &&
|
||||
if((bfile->classf | BCF_WRITE) &&
|
||||
!(bfile->uflags | BFILE_RAW)) {
|
||||
/* Make sure data is on disk */
|
||||
/* Move to final name if no errors */
|
||||
|
@ -234,3 +219,301 @@ void BLI_bfile_set_error(BFILE *bfile, int error) {
|
|||
bfile->error = error;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if defined(WIN32)
|
||||
#define LAST_SESSION_FILE "%HOME%\\Blender\\last-session FIXME FIXME FIXME"
|
||||
#define ENVIRONMENT_FILE "FIXME"
|
||||
#define SHARED_DIRECTORY "FIXME TOO"
|
||||
#elif defined(OSX)
|
||||
#define LAST_SESSION_FILE "${HOME}/Library/Application Support/Blender/last-session"
|
||||
#define ENVIRONMENT_FILE "${HOME}/Library/Application Support/Blender/${BLENDER_VERSION}/environment"
|
||||
#define SHARED_DIRECTORY "/Library/Application Support/Blender"
|
||||
#else
|
||||
#define LAST_SESSION_FILE "${HOME}/.blender/last-session"
|
||||
#define ENVIRONMENT_FILE "${HOME}/.blender/${BLENDER_VERSION}/environment"
|
||||
#define SHARED_DIRECTORY "/usr/share/blender"
|
||||
#endif
|
||||
void BLI_bfile_init_vars() {
|
||||
char file[MAXPATHLEN];
|
||||
char temp[MAXPATHLEN];
|
||||
extern char bprogname[];
|
||||
FILE* fp;
|
||||
|
||||
/* This one is unconditional */
|
||||
sprintf(temp, "%d", BLENDER_VERSION);
|
||||
BLI_setenv("BLENDER_VERSION", temp);
|
||||
|
||||
/* Is this unpack&run? */
|
||||
sprintf(temp, "%s/%d/environment", dirname(bprogname), BLENDER_VERSION);
|
||||
if(BLI_exist(temp)) {
|
||||
BLI_setenv_if_new("BLENDER_SHARE", dirname(bprogname));
|
||||
} else {
|
||||
BLI_setenv_if_new("BLENDER_SHARE", SHARED_DIRECTORY);
|
||||
}
|
||||
|
||||
expand_envvars(LAST_SESSION_FILE, file);
|
||||
fp = fopen(file, "r");
|
||||
/* 1st line, read previous version */
|
||||
if (fp && (fscanf(fp, "%3c\n", temp) == 1)) {
|
||||
temp[3] = '\0';
|
||||
BLI_setenv("BLENDER_VERSION_PREV", temp);
|
||||
/* 2nd line, read previous session path if needed */
|
||||
if(!getenv("BLENDER_TEMP")) {
|
||||
if ((fgets(temp, MAXPATHLEN, fp) != NULL)) {
|
||||
/* Clean any \n */
|
||||
chomp(temp);
|
||||
/* Check the dir is still there or generate new one */
|
||||
if(!BLI_exist(temp)) {
|
||||
setup_temp();
|
||||
}
|
||||
} else {
|
||||
/* We have to generate it for sure */
|
||||
setup_temp();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* Probably new user, or only <=249 before */
|
||||
BLI_setenv("BLENDER_VERSION_PREV", "0");
|
||||
setup_temp();
|
||||
}
|
||||
|
||||
if(fp) {
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
/* Load vars from user and system files */
|
||||
expand_envvars(ENVIRONMENT_FILE, file);
|
||||
init_vars_from_file(file);
|
||||
sprintf(temp, "/%d/environment", BLENDER_VERSION);
|
||||
BLI_make_file_string("/", file, getenv("BLENDER_SHARE"), temp);
|
||||
init_vars_from_file(file);
|
||||
}
|
||||
|
||||
|
||||
/*** Internal functions ***/
|
||||
|
||||
/**
|
||||
Eliminate trailing EOL by writing a \0 over it.
|
||||
Name taken from Perl.
|
||||
*/
|
||||
void chomp(char* line) {
|
||||
int len = strlen(line);
|
||||
#ifndef WIN32
|
||||
if (line[len - 1] == '\n') {
|
||||
line[len - 1] = '\0';
|
||||
}
|
||||
#else
|
||||
if ((line[len - 2] == '\r' ) && ((line[len - 1] == '\n'))) {
|
||||
line[len - 2] = '\0';
|
||||
}
|
||||
#endif /* WIN32 */
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Parse a file with lines like FOO=bar (comment lines have # as first
|
||||
character) assigning to envvar FOO the value bar if FOO does not
|
||||
exist yet.
|
||||
Any white space before FOO, around the = or trailing will be used,
|
||||
so beware.
|
||||
*/
|
||||
#define MAX_LINE 4096
|
||||
#define ENV_VAR 256
|
||||
#define VAR_LEN 8192
|
||||
void init_vars_from_file(const char* path) {
|
||||
char line[MAX_LINE];
|
||||
char name[ENV_VAR];
|
||||
FILE *fp;
|
||||
char* separator;
|
||||
char expanded[VAR_LEN];
|
||||
|
||||
fp = fopen(path, "r");
|
||||
if (!fp) return;
|
||||
|
||||
while (fgets(line, MAX_LINE, fp) != NULL) {
|
||||
/* Ignore comment lines */
|
||||
if (line[0] == '#')
|
||||
continue;
|
||||
|
||||
/* Split into envvar name and contents */
|
||||
separator = strchr(line, '=');
|
||||
if(separator && ((separator - line) < ENV_VAR)) {
|
||||
/* First remove EOL */
|
||||
chomp(line);
|
||||
strncpy(name, line, separator - line);
|
||||
name[separator - line] = '\0';
|
||||
expand_envvars(separator + 1, expanded);
|
||||
BLI_setenv_if_new(name, expanded);
|
||||
}
|
||||
}
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Look for ${} (or %%) env vars in src and expand if the var
|
||||
exists (even if empty value). If not exist, the name is left as is.
|
||||
The process is done all over src, and nested ${${}} is not supported.
|
||||
src must be \0 terminated, and dst must be big enough.
|
||||
*/
|
||||
#ifndef WIN32
|
||||
#define ENVVAR_PREFFIX "${"
|
||||
#define ENVVAR_P_SIZE 2
|
||||
#define ENVVAR_SUFFIX "}"
|
||||
#define ENVVAR_S_SIZE 1
|
||||
#else
|
||||
#define ENVVAR_PREFFIX "%"
|
||||
#define ENVVAR_P_SIZE 1
|
||||
#define ENVVAR_SUFFIX "%"
|
||||
#define ENVVAR_S_SIZE 1
|
||||
#endif /* WIN32 */
|
||||
void expand_envvars(char* src, char* dst) {
|
||||
char* hit1;
|
||||
char* hit2;
|
||||
char name[ENV_VAR];
|
||||
char* value;
|
||||
int prevlen;
|
||||
int done = 0;
|
||||
char* source = src;
|
||||
|
||||
dst[0] = '\0';
|
||||
while (!done) {
|
||||
hit1 = strstr(source, ENVVAR_PREFFIX);
|
||||
if (hit1) {
|
||||
hit2 = strstr(hit1 + ENVVAR_P_SIZE, ENVVAR_SUFFIX);
|
||||
if (hit2) {
|
||||
/* "Copy" the leading part, if any */
|
||||
if (hit1 != source) {
|
||||
prevlen = strlen(dst);
|
||||
strncat(dst, source, hit1 - source);
|
||||
dst[prevlen + (hit1 - source)] = '\0';
|
||||
}
|
||||
/* Figure the name of the env var we just found */
|
||||
strncpy(name, hit1 + ENVVAR_P_SIZE,
|
||||
hit2 - (hit1 + ENVVAR_P_SIZE));
|
||||
name[hit2 - (hit1 + ENVVAR_P_SIZE)] = '\0';
|
||||
/* See if we can get something with that name */
|
||||
value = getenv(name);
|
||||
if (value) {
|
||||
/* Push the var value */
|
||||
strcat(dst, value);
|
||||
} else {
|
||||
/* Leave the var name, so it is clear that it failed */
|
||||
strcat(dst, ENVVAR_PREFFIX);
|
||||
strcat(dst, name);
|
||||
strcat(dst, ENVVAR_SUFFIX);
|
||||
}
|
||||
/* Continue after closing mark, like a new string */
|
||||
source = hit2 + ENVVAR_S_SIZE;
|
||||
} else {
|
||||
/* Non terminated var so "copy as is" and finish */
|
||||
strcat(dst, source);
|
||||
done = 1;
|
||||
}
|
||||
} else {
|
||||
/* "Copy" whatever is left */
|
||||
strcat(dst, source);
|
||||
done = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Return a full path if the filename exists when combined
|
||||
with any item from pathlist. Or NULL otherwise.
|
||||
*/
|
||||
#ifdef WIN32
|
||||
#define SEPARATOR ';'
|
||||
#else
|
||||
#define SEPARATOR ':'
|
||||
#endif
|
||||
char* find_in_pathlist(char* filename, char* pathlist) {
|
||||
char first[FILE_MAX + 10];
|
||||
char* rest = NULL;
|
||||
|
||||
/* Separate first path from rest, use typical separator for current OS */
|
||||
rest = strchr(pathlist, SEPARATOR);
|
||||
if (rest) {
|
||||
strncpy(first, pathlist, rest - pathlist);
|
||||
first[rest - pathlist] = '\0';
|
||||
/* Skip the separator so it becomes a valid new pathlist */
|
||||
rest++;
|
||||
} else {
|
||||
strcpy(first, pathlist);
|
||||
}
|
||||
|
||||
/* Check if combination exists */
|
||||
BLI_add_slash(first);
|
||||
strcat(first, filename);
|
||||
if(BLI_exist(first)) {
|
||||
return strdup(first);
|
||||
}
|
||||
|
||||
/* First path failed, try with rest of paths if possible */
|
||||
if(rest) {
|
||||
return find_in_pathlist(filename, rest);
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Setup fpath and tpath based in the needs of the bfile.
|
||||
*/
|
||||
void fill_paths(BFILE *bfile, const char *path) {
|
||||
char* source_path = NULL;
|
||||
char* temp_path = NULL;
|
||||
int bflags = bfile->uflags;
|
||||
|
||||
if(bflags & BFILE_NORMAL || bflags & BFILE_RAW) {
|
||||
// bfile->fpath is path with // replaced
|
||||
}
|
||||
if(bflags & BFILE_TEMP) {
|
||||
temp_path = MEM_mallocN(MAXPATHLEN, "bfile-fpath-1");
|
||||
snprintf(temp_path, MAXPATHLEN, "%s/%s", getenv("BLENDER_TEMP"), path);
|
||||
bfile->fpath = temp_path;
|
||||
}
|
||||
if(bflags & BFILE_CONFIG) {
|
||||
// bfile->fpath is userdir+version+path
|
||||
// source_path is first hit in (if using fallback to older versions)
|
||||
// userdir+curversion+path (... userdir+limitversion+path) sysdir+path
|
||||
// (limitversion is based in path, using some kind of regex or "tables")
|
||||
}
|
||||
|
||||
if(bfile->classf & BCF_WRITE && !(bflags & BFILE_RAW)) {
|
||||
/* Generate temp path */
|
||||
temp_path = MEM_mallocN(MAXPATHLEN, "bfile-fpath-2");
|
||||
snprintf(temp_path, MAXPATHLEN, "%s.XXXXXX", path);
|
||||
bfile->tpath = mkdtemp(temp_path);
|
||||
if(!(bfile->classf & BCF_DISCARD)) {
|
||||
/* Copy data to tpath */
|
||||
if(source_path) {
|
||||
// copy it from older version or sys version
|
||||
}
|
||||
}
|
||||
} else {
|
||||
bfile->tpath = bfile->fpath;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Create a temp directory in safe and multiuser way.
|
||||
*/
|
||||
void setup_temp() {
|
||||
char template[MAXPATHLEN];
|
||||
char* tempdir;
|
||||
|
||||
if(getenv("TMPDIR")) {
|
||||
sprintf(template, "%s/blender-XXXXXX", getenv("TMPDIR"));
|
||||
} else {
|
||||
sprintf(template, "/tmp/blender-XXXXXX");
|
||||
// MacOSX NSTemporaryDirectory and WIN32 ???
|
||||
}
|
||||
tempdir = mkdtemp(template);
|
||||
BLI_setenv("BLENDER_TEMP", tempdir);
|
||||
}
|
||||
|
||||
|
|
|
@ -468,6 +468,11 @@ int BLI_exist(char *name)
|
|||
return(st.st_mode);
|
||||
}
|
||||
|
||||
/* would be better in fileops.c except that it needs stat.h so add here */
|
||||
int BLI_is_dir(char *file) {
|
||||
return S_ISDIR(BLI_exist(file));
|
||||
}
|
||||
|
||||
LinkNode *BLI_read_file_as_lines(char *name)
|
||||
{
|
||||
FILE *fp= fopen(name, "r");
|
||||
|
|
|
@ -992,6 +992,18 @@ void BLI_setenv(const char *env, const char*val)
|
|||
#endif
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Only set an env var if already not there.
|
||||
Like Unix setenv(env, val, 0);
|
||||
*/
|
||||
void BLI_setenv_if_new(const char *env, const char* val)
|
||||
{
|
||||
if(getenv(env) == NULL)
|
||||
BLI_setenv(env, val);
|
||||
}
|
||||
|
||||
|
||||
void BLI_clean(char *path)
|
||||
{
|
||||
if(path==0) return;
|
||||
|
@ -1374,10 +1386,10 @@ void BLI_where_am_i(char *fullname, const char *name)
|
|||
char *path = NULL, *temp;
|
||||
|
||||
#ifdef _WIN32
|
||||
char *seperator = ";";
|
||||
char *separator = ";";
|
||||
char slash = '\\';
|
||||
#else
|
||||
char *seperator = ":";
|
||||
char *separator = ":";
|
||||
char slash = '/';
|
||||
#endif
|
||||
|
||||
|
@ -1415,7 +1427,7 @@ void BLI_where_am_i(char *fullname, const char *name)
|
|||
path = getenv("PATH");
|
||||
if (path) {
|
||||
do {
|
||||
temp = strstr(path, seperator);
|
||||
temp = strstr(path, separator);
|
||||
if (temp) {
|
||||
strncpy(filename, path, temp - path);
|
||||
filename[temp - path] = 0;
|
||||
|
|
|
@ -217,6 +217,32 @@ int check_file_chars(char *filename)
|
|||
return 1;
|
||||
}
|
||||
|
||||
/* Copied from http://sourceware.org/ml/newlib/2005/msg00248.html */
|
||||
/* Copyright 2005 Shaun Jackman
|
||||
* Permission to use, copy, modify, and distribute this software
|
||||
* is freely granted, provided that this notice is preserved.
|
||||
*/
|
||||
#include <string.h>
|
||||
char* dirname(char *path)
|
||||
{
|
||||
char *p;
|
||||
if( path == NULL || *path == '\0' )
|
||||
return ".";
|
||||
p = path + strlen(path) - 1;
|
||||
while( *p == '/' ) {
|
||||
if( p == path )
|
||||
return path;
|
||||
*p-- = '\0';
|
||||
}
|
||||
while( p >= path && *p != '/' )
|
||||
p--;
|
||||
return
|
||||
p < path ? "." :
|
||||
p == path ? "/" :
|
||||
(*p = '\0', path);
|
||||
}
|
||||
/* End of copied part */
|
||||
|
||||
#else
|
||||
|
||||
/* intentionally empty for UNIX */
|
||||
|
|
|
@ -62,6 +62,7 @@ typedef struct BlendFileData {
|
|||
int fileflags;
|
||||
int displaymode;
|
||||
int globalf;
|
||||
char filename[240]; /* 240 = FILE_MAX */
|
||||
|
||||
struct bScreen* curscreen;
|
||||
struct Scene* curscene;
|
||||
|
|
|
@ -364,7 +364,7 @@ BlendFileData *BLO_read_from_memfile(Main *oldmain, const char *filename, MemFil
|
|||
fd = blo_openblendermemfile(memfile, reports);
|
||||
if (fd) {
|
||||
fd->reports= reports;
|
||||
strcpy(fd->filename, filename);
|
||||
strcpy(fd->relabase, filename);
|
||||
|
||||
/* clear ob->proxy_from pointers in old main */
|
||||
blo_clear_proxy_pointers_from_lib(fd, oldmain);
|
||||
|
|
|
@ -978,7 +978,7 @@ FileData *blo_openblenderfile(char *name, ReportList *reports)
|
|||
fd->read = fd_read_gzip_from_file;
|
||||
|
||||
/* needed for library_append and read_libraries */
|
||||
BLI_strncpy(fd->filename, name, sizeof(fd->filename));
|
||||
BLI_strncpy(fd->relabase, name, sizeof(fd->relabase));
|
||||
|
||||
return blo_decode_and_check(fd, reports);
|
||||
}
|
||||
|
@ -4287,7 +4287,7 @@ static void composite_patch(bNodeTree *ntree, Scene *scene)
|
|||
bNode *node;
|
||||
|
||||
for(node= ntree->nodes.first; node; node= node->next)
|
||||
if(node->id==NULL && ELEM(node->type, CMP_NODE_R_LAYERS, CMP_NODE_COMPOSITE))
|
||||
if(node->id==NULL && ELEM3(node->type, CMP_NODE_R_LAYERS, CMP_NODE_COMPOSITE, CMP_NODE_DEFOCUS))
|
||||
node->id= &scene->id;
|
||||
}
|
||||
|
||||
|
@ -4400,8 +4400,10 @@ static void link_recurs_seq(FileData *fd, ListBase *lb)
|
|||
static void direct_link_paint(FileData *fd, Paint **paint)
|
||||
{
|
||||
(*paint)= newdataadr(fd, (*paint));
|
||||
if(*paint)
|
||||
if(*paint) {
|
||||
(*paint)->paint_cursor= NULL;
|
||||
(*paint)->brushes= newdataadr(fd, (*paint)->brushes);
|
||||
}
|
||||
}
|
||||
|
||||
static void direct_link_scene(FileData *fd, Scene *sce)
|
||||
|
@ -4600,7 +4602,6 @@ static void direct_link_windowmanager(FileData *fd, wmWindowManager *wm)
|
|||
win->curswin= NULL;
|
||||
win->tweak= NULL;
|
||||
|
||||
win->timers.first= win->timers.last= NULL;
|
||||
win->queue.first= win->queue.last= NULL;
|
||||
win->handlers.first= win->handlers.last= NULL;
|
||||
win->modalhandlers.first= win->modalhandlers.last= NULL;
|
||||
|
@ -4612,6 +4613,7 @@ static void direct_link_windowmanager(FileData *fd, wmWindowManager *wm)
|
|||
win->drawfail= 0;
|
||||
}
|
||||
|
||||
wm->timers.first= wm->timers.last= NULL;
|
||||
wm->operators.first= wm->operators.last= NULL;
|
||||
wm->paintcursors.first= wm->paintcursors.last= NULL;
|
||||
wm->queue.first= wm->queue.last= NULL;
|
||||
|
@ -5302,7 +5304,7 @@ static void direct_link_library(FileData *fd, Library *lib, Main *main)
|
|||
}
|
||||
/* make sure we have full path in lib->filename */
|
||||
BLI_strncpy(lib->filename, lib->name, sizeof(lib->name));
|
||||
cleanup_path(fd->filename, lib->filename);
|
||||
cleanup_path(fd->relabase, lib->filename);
|
||||
|
||||
// printf("direct_link_library: name %s\n", lib->name);
|
||||
// printf("direct_link_library: filename %s\n", lib->filename);
|
||||
|
@ -5636,6 +5638,9 @@ static BHead *read_global(BlendFileData *bfd, FileData *fd, BHead *bhead)
|
|||
bfd->fileflags= fg->fileflags;
|
||||
bfd->displaymode= fg->displaymode;
|
||||
bfd->globalf= fg->globalf;
|
||||
BLI_strncpy(bfd->filename, fg->filename, sizeof(bfd->filename));
|
||||
if(G.fileflags & G_FILE_RECOVER)
|
||||
BLI_strncpy(fd->relabase, fg->filename, sizeof(fd->relabase));
|
||||
|
||||
bfd->curscreen= fg->curscreen;
|
||||
bfd->curscene= fg->curscene;
|
||||
|
@ -6451,7 +6456,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
|
|||
/* WATCH IT!!!: pointers from libdata have not been converted */
|
||||
|
||||
if(G.f & G_DEBUG)
|
||||
printf("read file %s\n Version %d sub %d\n", fd->filename, main->versionfile, main->subversionfile);
|
||||
printf("read file %s\n Version %d sub %d\n", fd->relabase, main->versionfile, main->subversionfile);
|
||||
|
||||
if(main->versionfile == 100) {
|
||||
/* tex->extend and tex->imageflag have changed: */
|
||||
|
@ -6598,7 +6603,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
|
|||
}
|
||||
}
|
||||
if(main->versionfile <= 140) {
|
||||
/* r-g-b-fac in texure */
|
||||
/* r-g-b-fac in texture */
|
||||
Tex *tex = main->tex.first;
|
||||
while (tex) {
|
||||
if ((tex->rfac == 0.0) &&
|
||||
|
@ -10087,7 +10092,6 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
|
|||
}
|
||||
}
|
||||
|
||||
/* put 2.50 compatibility code here until next subversion bump */
|
||||
if (main->versionfile < 250 || (main->versionfile == 250 && main->subversionfile < 6)) {
|
||||
Object *ob;
|
||||
Lamp *la;
|
||||
|
@ -10113,6 +10117,71 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
|
|||
la->compressthresh= 0.05f;
|
||||
}
|
||||
|
||||
if (main->versionfile < 250 || (main->versionfile == 250 && main->subversionfile < 7)) {
|
||||
Mesh *me;
|
||||
Nurb *nu;
|
||||
Lattice *lt;
|
||||
Curve *cu;
|
||||
Key *key;
|
||||
float *data;
|
||||
int a, tot;
|
||||
|
||||
/* shape keys are no longer applied to the mesh itself, but rather
|
||||
to the derivedmesh/displist, so here we ensure that the basis
|
||||
shape key is always set in the mesh coordinates. */
|
||||
|
||||
for(me= main->mesh.first; me; me= me->id.next) {
|
||||
if((key = newlibadr(fd, lib, me->key)) && key->refkey) {
|
||||
data= key->refkey->data;
|
||||
tot= MIN2(me->totvert, key->refkey->totelem);
|
||||
|
||||
for(a=0; a<tot; a++, data+=3)
|
||||
VECCOPY(me->mvert[a].co, data)
|
||||
}
|
||||
}
|
||||
|
||||
for(lt= main->latt.first; lt; lt= lt->id.next) {
|
||||
if((key = newlibadr(fd, lib, lt->key)) && key->refkey) {
|
||||
data= key->refkey->data;
|
||||
tot= MIN2(lt->pntsu*lt->pntsv*lt->pntsw, key->refkey->totelem);
|
||||
|
||||
for(a=0; a<tot; a++, data+=3)
|
||||
VECCOPY(lt->def[a].vec, data)
|
||||
}
|
||||
}
|
||||
|
||||
for(cu= main->curve.first; cu; cu= cu->id.next) {
|
||||
if((key = newlibadr(fd, lib, cu->key)) && key->refkey) {
|
||||
data= key->refkey->data;
|
||||
|
||||
for(nu=cu->nurb.first; nu; nu=nu->next) {
|
||||
if(nu->bezt) {
|
||||
BezTriple *bezt = nu->bezt;
|
||||
|
||||
for(a=0; a<nu->pntsu; a++, bezt++) {
|
||||
VECCOPY(bezt->vec[0], data); data+=3;
|
||||
VECCOPY(bezt->vec[1], data); data+=3;
|
||||
VECCOPY(bezt->vec[2], data); data+=3;
|
||||
bezt->alfa= *data; data++;
|
||||
}
|
||||
}
|
||||
else if(nu->bp) {
|
||||
BPoint *bp = nu->bp;
|
||||
|
||||
for(a=0; a<nu->pntsu*nu->pntsv; a++, bp++) {
|
||||
VECCOPY(bp->vec, data); data+=3;
|
||||
bp->alfa= *data; data++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* put 2.50 compatibility code here until next subversion bump */
|
||||
{
|
||||
}
|
||||
|
||||
/* WATCH IT!!!: pointers from libdata have not been converted yet here! */
|
||||
/* WATCH IT 2!: Userdef struct init has to be in src/usiblender.c! */
|
||||
|
||||
|
@ -10225,14 +10294,25 @@ BlendFileData *blo_read_file_internal(FileData *fd, char *file)
|
|||
break;
|
||||
|
||||
case ID_LI:
|
||||
bhead = read_libblock(fd, bfd->main, bhead, LIB_LOCAL, NULL);
|
||||
/* skip library datablocks in undo, this works together with
|
||||
BLO_read_from_memfile, where the old main->library is restored
|
||||
overwriting the libraries from the memory file. previously
|
||||
it did not save ID_LI/ID_ID blocks in this case, but they are
|
||||
needed to make quit.blend recover them correctly. */
|
||||
if(fd->memfile)
|
||||
bhead= blo_nextbhead(fd, bhead);
|
||||
else
|
||||
bhead= read_libblock(fd, bfd->main, bhead, LIB_LOCAL, NULL);
|
||||
break;
|
||||
case ID_ID:
|
||||
/* same as above */
|
||||
if(fd->memfile)
|
||||
bhead= blo_nextbhead(fd, bhead);
|
||||
else
|
||||
/* always adds to the most recently loaded
|
||||
* ID_LI block, see direct_link_library.
|
||||
* this is part of the file format definition.
|
||||
*/
|
||||
bhead = read_libblock(fd, fd->mainlist.last, bhead, LIB_READ+LIB_EXTERN, NULL);
|
||||
* this is part of the file format definition. */
|
||||
bhead = read_libblock(fd, fd->mainlist.last, bhead, LIB_READ+LIB_EXTERN, NULL);
|
||||
break;
|
||||
|
||||
/* in 2.50+ files, the file identifier for screens is patched, forward compatibility */
|
||||
|
@ -10254,7 +10334,7 @@ BlendFileData *blo_read_file_internal(FileData *fd, char *file)
|
|||
|
||||
lib_link_all(fd, bfd->main);
|
||||
lib_verify_nodetree(bfd->main, 1);
|
||||
fix_relpaths_library(fd->filename, bfd->main); /* make all relative paths, relative to the open blend file */
|
||||
fix_relpaths_library(fd->relabase, bfd->main); /* make all relative paths, relative to the open blend file */
|
||||
|
||||
link_global(fd, bfd); /* as last */
|
||||
|
||||
|
@ -10302,6 +10382,10 @@ static void sort_bhead_old_map(FileData *fd)
|
|||
|
||||
static BHead *find_previous_lib(FileData *fd, BHead *bhead)
|
||||
{
|
||||
/* skip library datablocks in undo, see comment in read_libblock */
|
||||
if(fd->memfile)
|
||||
return NULL;
|
||||
|
||||
for (; bhead; bhead= blo_prevbhead(fd, bhead))
|
||||
if (bhead->code==ID_LI)
|
||||
break;
|
||||
|
@ -10373,7 +10457,7 @@ static void expand_doit(FileData *fd, Main *mainvar, void *old)
|
|||
|
||||
if(bheadlib) {
|
||||
Library *lib= read_struct(fd, bheadlib, "Library");
|
||||
Main *ptr= blo_find_main(fd, &fd->mainlist, lib->name, fd->filename);
|
||||
Main *ptr= blo_find_main(fd, &fd->mainlist, lib->name, fd->relabase);
|
||||
|
||||
id= is_yet_read(fd, ptr, bhead);
|
||||
|
||||
|
@ -11631,7 +11715,7 @@ BlendFileData *blo_read_blendafterruntime(int file, char *name, int actualsize,
|
|||
fd->read = fd_read_from_file;
|
||||
|
||||
/* needed for library_append and read_libraries */
|
||||
BLI_strncpy(fd->filename, name, sizeof(fd->filename));
|
||||
BLI_strncpy(fd->relabase, name, sizeof(fd->relabase));
|
||||
|
||||
fd = blo_decode_and_check(fd, reports);
|
||||
if (!fd)
|
||||
|
|
|
@ -56,7 +56,7 @@ typedef struct FileData {
|
|||
gzFile gzfiledes;
|
||||
|
||||
// now only in use for library appending
|
||||
char filename[FILE_MAXDIR+FILE_MAXFILE];
|
||||
char relabase[FILE_MAXDIR+FILE_MAXFILE];
|
||||
|
||||
// variables needed for reading from stream
|
||||
char headerdone;
|
||||
|
|
|
@ -2310,7 +2310,7 @@ static void write_scripts(WriteData *wd, ListBase *idbase)
|
|||
/* context is usually defined by WM, two cases where no WM is available:
|
||||
* - for forward compatibility, curscreen has to be saved
|
||||
* - for undofile, curscene needs to be saved */
|
||||
static void write_global(WriteData *wd, Main *mainvar)
|
||||
static void write_global(WriteData *wd, int fileflags, Main *mainvar)
|
||||
{
|
||||
FileGlobal fg;
|
||||
bScreen *screen;
|
||||
|
@ -2323,8 +2323,9 @@ static void write_global(WriteData *wd, Main *mainvar)
|
|||
fg.curscene= screen->scene;
|
||||
fg.displaymode= G.displaymode;
|
||||
fg.winpos= G.winpos;
|
||||
fg.fileflags= (G.fileflags & ~G_FILE_NO_UI); // prevent to save this, is not good convention, and feature with concerns...
|
||||
fg.fileflags= (fileflags & ~G_FILE_NO_UI); // prevent to save this, is not good convention, and feature with concerns...
|
||||
fg.globalf= G.f;
|
||||
BLI_strncpy(fg.filename, mainvar->name, sizeof(fg.filename));
|
||||
|
||||
sprintf(subvstr, "%4d", BLENDER_SUBVERSION);
|
||||
memcpy(fg.subvstr, subvstr, 4);
|
||||
|
@ -2353,7 +2354,7 @@ static int write_file_handle(Main *mainvar, int handle, MemFile *compare, MemFil
|
|||
mywrite(wd, buf, 12);
|
||||
|
||||
write_renderinfo(wd, mainvar);
|
||||
write_global(wd, mainvar);
|
||||
write_global(wd, write_flags, mainvar);
|
||||
|
||||
/* no UI save in undo */
|
||||
if(current==NULL) {
|
||||
|
@ -2384,8 +2385,7 @@ static int write_file_handle(Main *mainvar, int handle, MemFile *compare, MemFil
|
|||
write_brushes (wd, &mainvar->brush);
|
||||
write_scripts (wd, &mainvar->script);
|
||||
write_gpencils (wd, &mainvar->gpencil);
|
||||
if(current==NULL)
|
||||
write_libraries(wd, mainvar->next); /* no library save in undo */
|
||||
write_libraries(wd, mainvar->next);
|
||||
|
||||
if (write_user_block) {
|
||||
write_userdef(wd);
|
||||
|
|
|
@ -177,6 +177,9 @@ typedef struct BMesh {
|
|||
|
||||
/*active face pointer*/
|
||||
struct BMFace *act_face;
|
||||
|
||||
/*active shape key number, should really be in BMEditMesh, not here*/
|
||||
int shapenr;
|
||||
} BMesh;
|
||||
|
||||
typedef struct BMVert {
|
||||
|
|
|
@ -468,11 +468,12 @@ BMOpDefine def_object_load_bmesh = {
|
|||
/*
|
||||
BMesh to Mesh
|
||||
|
||||
Converts a bmesh to a Mesh
|
||||
Converts a bmesh to a Mesh. This is reserved for exiting editmode.
|
||||
*/
|
||||
BMOpDefine def_bmesh_to_mesh = {
|
||||
"bmesh_to_mesh",
|
||||
{{BMOP_OPSLOT_PNT, "meshptr"}, //pointer to a mesh structure to fill in
|
||||
{{BMOP_OPSLOT_PNT, "mesh"}, //pointer to a mesh structure to fill in
|
||||
{BMOP_OPSLOT_PNT, "object"}, //pointer to an object structure
|
||||
{BMOP_OPSLOT_INT, "notesselation"}, //don't calculate mfaces
|
||||
{0, /*null-terminating sentinel*/}},
|
||||
bmesh_to_mesh_exec,
|
||||
|
@ -482,11 +483,13 @@ BMOpDefine def_bmesh_to_mesh = {
|
|||
/*
|
||||
Mesh to BMesh
|
||||
|
||||
Load the contents of a mesh into the bmesh.
|
||||
Load the contents of a mesh into the bmesh. this bmop is private, it's
|
||||
reserved exclusively for entering editmode.
|
||||
*/
|
||||
BMOpDefine def_mesh_to_bmesh = {
|
||||
"mesh_to_bmesh",
|
||||
{{BMOP_OPSLOT_PNT, "mesh"}, //pointer to a Mesh structure
|
||||
{BMOP_OPSLOT_PNT, "object"}, //pointer to an Object structure
|
||||
{0, /*null-terminating sentinel*/}},
|
||||
mesh_to_bmesh_exec,
|
||||
0
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
#include "DNA_customdata_types.h"
|
||||
#include "DNA_mesh_types.h"
|
||||
#include "DNA_meshdata_types.h"
|
||||
#include "DNA_modifier_types.h"
|
||||
#include "DNA_key_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
#include "DNA_scene_types.h"
|
||||
|
||||
|
@ -15,6 +17,8 @@
|
|||
#include "BKE_global.h"
|
||||
#include "BKE_DerivedMesh.h"
|
||||
#include "BKE_cdderivedmesh.h"
|
||||
#include "BKE_key.h"
|
||||
#include "BKE_main.h"
|
||||
|
||||
#include "BLI_blenlib.h"
|
||||
#include "BLI_edgehash.h"
|
||||
|
@ -27,6 +31,15 @@
|
|||
#include "mesh_intern.h"
|
||||
#include "bmesh.h"
|
||||
|
||||
/*
|
||||
HACK: we're using the old keyindex shape key hack for now, where each
|
||||
vertex is assigned an index on entering editmode, which is used to retrieve
|
||||
the original shapekey coordinates on exiting editmode.
|
||||
|
||||
this should be replaced by proper use of customdata layers, but I'm not
|
||||
sure if that's such a good idea before merging with trunk or not.
|
||||
*/
|
||||
|
||||
/*
|
||||
* MESH CONV.C
|
||||
*
|
||||
|
@ -37,21 +50,24 @@
|
|||
*/
|
||||
|
||||
void mesh_to_bmesh_exec(BMesh *bm, BMOperator *op) {
|
||||
Object *ob = BMO_Get_Pnt(op, "object");
|
||||
Mesh *me = BMO_Get_Pnt(op, "mesh");
|
||||
MVert *mvert;
|
||||
MEdge *medge;
|
||||
MLoop *ml;
|
||||
MPoly *mpoly;
|
||||
KeyBlock *actkey;
|
||||
BMVert *v, **vt=NULL;
|
||||
BMEdge *e, **fedges=NULL, **et = NULL;
|
||||
BLI_array_declare(fedges);
|
||||
BMFace *f;
|
||||
BLI_array_declare(fedges);
|
||||
float (*keyco)[3]= NULL;
|
||||
int *keyi;
|
||||
int i, j, li, allocsize[4] = {512, 512, 2048, 512};
|
||||
|
||||
if (!me || !me->totvert) return; /*sanity check*/
|
||||
|
||||
mvert = me->mvert;
|
||||
|
||||
vt = MEM_mallocN(sizeof(void**)*me->totvert, "mesh to bmesh vtable");
|
||||
|
||||
CustomData_copy(&me->vdata, &bm->vdata, CD_MASK_BMESH, CD_CALLOC, 0);
|
||||
|
@ -59,13 +75,23 @@ void mesh_to_bmesh_exec(BMesh *bm, BMOperator *op) {
|
|||
CustomData_copy(&me->ldata, &bm->ldata, CD_MASK_BMESH, CD_CALLOC, 0);
|
||||
CustomData_copy(&me->pdata, &bm->pdata, CD_MASK_BMESH, CD_CALLOC, 0);
|
||||
|
||||
CustomData_add_layer(&bm->vdata, CD_SHAPE_KEYINDEX, CD_ASSIGN, NULL, 0);
|
||||
|
||||
CustomData_bmesh_init_pool(&bm->vdata, allocsize[0]);
|
||||
CustomData_bmesh_init_pool(&bm->edata, allocsize[1]);
|
||||
CustomData_bmesh_init_pool(&bm->ldata, allocsize[2]);
|
||||
CustomData_bmesh_init_pool(&bm->pdata, allocsize[3]);
|
||||
|
||||
|
||||
actkey = ob_get_keyblock(ob);
|
||||
if(actkey && actkey->totelem == me->totvert) {
|
||||
keyco= actkey->data;
|
||||
bm->shapenr= ob->shapenr;
|
||||
} else if (actkey) {
|
||||
printf("shapekey<->mesh mismatch!\n");
|
||||
}
|
||||
|
||||
for (i=0; i<me->totvert; i++, mvert++) {
|
||||
v = BM_Make_Vert(bm, mvert->co, NULL);
|
||||
v = BM_Make_Vert(bm, keyco ? keyco[i] : mvert->co, NULL);
|
||||
VECCOPY(v->no, mvert->no);
|
||||
|
||||
vt[i] = v;
|
||||
|
@ -80,6 +106,10 @@ void mesh_to_bmesh_exec(BMesh *bm, BMOperator *op) {
|
|||
|
||||
/*Copy Custom Data*/
|
||||
CustomData_to_bmesh_block(&me->vdata, &bm->vdata, i, &v->head.data);
|
||||
|
||||
/*set shape key original index*/
|
||||
keyi = CustomData_bmesh_get(&bm->vdata, v->head.data, CD_SHAPE_KEYINDEX);
|
||||
*keyi = i;
|
||||
}
|
||||
|
||||
if (!me->totedge) {
|
||||
|
@ -223,24 +253,25 @@ void object_load_bmesh_exec(BMesh *bm, BMOperator *op) {
|
|||
Scene *scene = BMO_Get_Pnt(op, "scene");
|
||||
Mesh *me = ob->data;
|
||||
|
||||
BMO_CallOpf(bm, "bmesh_to_mesh meshptr=%p", me);
|
||||
BMO_CallOpf(bm, "bmesh_to_mesh mesh=%p object=%p", me, ob);
|
||||
|
||||
/*BMESH_TODO eventually we'll have to handle shapekeys here*/
|
||||
}
|
||||
|
||||
void bmesh_to_mesh_exec(BMesh *bm, BMOperator *op) {
|
||||
Mesh *me = BMO_Get_Pnt(op, "meshptr");
|
||||
Mesh *me = BMO_Get_Pnt(op, "mesh");
|
||||
Object *ob = BMO_Get_Pnt(op, "object");
|
||||
MLoop *mloop;
|
||||
MPoly *mpoly;
|
||||
MVert *mvert, *oldverts;
|
||||
MEdge *medge;
|
||||
MFace *mface;
|
||||
BMVert *v;
|
||||
BMVert *v, *eve;
|
||||
BMEdge *e;
|
||||
BMLoop *l;
|
||||
BMFace *f;
|
||||
BMIter iter, liter;
|
||||
int i, j, ototvert, totloop, totface, numTex, numCol;
|
||||
int i, j, *keyi, ototvert, totloop, totface, numTex, numCol;
|
||||
int dotess = !BMO_Get_Int(op, "notesselation");
|
||||
|
||||
numTex = CustomData_number_of_layers(&bm->pdata, CD_MTEXPOLY);
|
||||
|
@ -459,5 +490,129 @@ void bmesh_to_mesh_exec(BMesh *bm, BMOperator *op) {
|
|||
mpoly++;
|
||||
}
|
||||
|
||||
/* patch hook indices and vertex parents */
|
||||
{
|
||||
Object *ob;
|
||||
ModifierData *md;
|
||||
BMVert **vertMap = NULL;
|
||||
int i,j;
|
||||
|
||||
for (ob=G.main->object.first; ob; ob=ob->id.next) {
|
||||
if (ob->parent==ob && ELEM(ob->partype, PARVERT1,PARVERT3)) {
|
||||
|
||||
/* duplicate code from below, make it function later...? */
|
||||
if (!vertMap) {
|
||||
vertMap = MEM_callocN(sizeof(*vertMap)*ototvert, "vertMap");
|
||||
|
||||
BM_ITER(eve, &iter, bm, BM_VERTS_OF_MESH, NULL) {
|
||||
keyi = CustomData_bmesh_get(&bm->vdata, eve->head.data, CD_SHAPE_KEYINDEX);
|
||||
if (*keyi != ORIGINDEX_NONE)
|
||||
vertMap[*keyi] = eve;
|
||||
}
|
||||
}
|
||||
if(ob->par1 < ototvert) {
|
||||
eve = vertMap[ob->par1];
|
||||
if(eve) ob->par1= BMINDEX_GET(eve);
|
||||
}
|
||||
if(ob->par2 < ototvert) {
|
||||
eve = vertMap[ob->par2];
|
||||
if(eve) ob->par2= BMINDEX_GET(eve);
|
||||
}
|
||||
if(ob->par3 < ototvert) {
|
||||
eve = vertMap[ob->par3];
|
||||
if(eve) ob->par3= BMINDEX_GET(eve);
|
||||
}
|
||||
|
||||
}
|
||||
if (ob->data==me) {
|
||||
for (md=ob->modifiers.first; md; md=md->next) {
|
||||
if (md->type==eModifierType_Hook) {
|
||||
HookModifierData *hmd = (HookModifierData*) md;
|
||||
|
||||
if (!vertMap) {
|
||||
vertMap = MEM_callocN(sizeof(*vertMap)*ototvert, "vertMap");
|
||||
|
||||
BM_ITER(eve, &iter, bm, BM_VERTS_OF_MESH, NULL) {
|
||||
keyi = CustomData_bmesh_get(&bm->vdata, eve->head.data, CD_SHAPE_KEYINDEX);
|
||||
if (*keyi != ORIGINDEX_NONE)
|
||||
vertMap[*keyi] = eve;
|
||||
}
|
||||
}
|
||||
|
||||
for (i=j=0; i<hmd->totindex; i++) {
|
||||
if(hmd->indexar[i] < ototvert) {
|
||||
eve = vertMap[hmd->indexar[i]];
|
||||
|
||||
if (eve) {
|
||||
hmd->indexar[j++] = BMINDEX_GET(eve);
|
||||
}
|
||||
}
|
||||
else j++;
|
||||
}
|
||||
|
||||
hmd->totindex = j;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (vertMap) MEM_freeN(vertMap);
|
||||
}
|
||||
|
||||
mesh_update_customdata_pointers(me);
|
||||
|
||||
/* are there keys? */
|
||||
if(me->key) {
|
||||
float *fp, *newkey, *oldkey;
|
||||
KeyBlock *currkey;
|
||||
KeyBlock *actkey= BLI_findlink(&me->key->block, bm->shapenr-1);
|
||||
|
||||
/* Lets reorder the key data so that things line up roughly
|
||||
* with the way things were before editmode */
|
||||
currkey = me->key->block.first;
|
||||
while(currkey) {
|
||||
fp= newkey= MEM_callocN(me->key->elemsize*bm->totvert, "currkey->data");
|
||||
oldkey = currkey->data;
|
||||
|
||||
eve= BMIter_New(&iter, bm, BM_VERTS_OF_MESH, NULL);
|
||||
|
||||
i = 0;
|
||||
mvert = me->mvert;
|
||||
while(eve) {
|
||||
keyi = CustomData_bmesh_get(&bm->vdata, eve->head.data, CD_SHAPE_KEYINDEX);
|
||||
if (*keyi >= 0 && *keyi < currkey->totelem) { // valid old vertex
|
||||
if(currkey == actkey) {
|
||||
if(actkey == me->key->refkey) {
|
||||
VECCOPY(fp, mvert->co);
|
||||
}
|
||||
else {
|
||||
VECCOPY(fp, mvert->co);
|
||||
if(oldverts) {
|
||||
VECCOPY(mvert->co, oldverts[*keyi].co);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(oldkey) {
|
||||
VECCOPY(fp, oldkey + 3 * *keyi);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
VECCOPY(fp, mvert->co);
|
||||
}
|
||||
fp+= 3;
|
||||
++i;
|
||||
++mvert;
|
||||
eve= BMIter_Step(&iter);
|
||||
}
|
||||
currkey->totelem= bm->totvert;
|
||||
if(currkey->data) MEM_freeN(currkey->data);
|
||||
currkey->data = newkey;
|
||||
|
||||
currkey= currkey->next;
|
||||
}
|
||||
}
|
||||
|
||||
if(oldverts) MEM_freeN(oldverts);
|
||||
}
|
|
@ -1386,7 +1386,7 @@ static int acf_dsskey_setting_flag(int setting, short *neg)
|
|||
|
||||
switch (setting) {
|
||||
case ACHANNEL_SETTING_EXPAND: /* expanded */
|
||||
return KEYBLOCK_DS_EXPAND;
|
||||
return KEY_DS_EXPAND;
|
||||
|
||||
case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
|
||||
return ADT_NLA_EVAL_OFF;
|
||||
|
@ -1737,28 +1737,91 @@ static bAnimChannelType ACF_DSARM=
|
|||
|
||||
|
||||
/* ShapeKey Entry ------------------------------------------- */
|
||||
// XXX ... this is currently obsolete...
|
||||
|
||||
#if 0
|
||||
static void dummy_olddraw_shapekeys ()
|
||||
/* name for ShapeKey */
|
||||
static void acf_shapekey_name(bAnimListElem *ale, char *name)
|
||||
{
|
||||
case ANIMTYPE_SHAPEKEY: /* shapekey channel */
|
||||
{
|
||||
KeyBlock *kb = (KeyBlock *)ale->data;
|
||||
|
||||
indent = 0;
|
||||
special = -1;
|
||||
|
||||
offset= (ale->id) ? 21 : 0;
|
||||
|
||||
if (kb->name[0] == '\0')
|
||||
sprintf(name, "Key %d", ale->index);
|
||||
else
|
||||
KeyBlock *kb= (KeyBlock *)ale->data;
|
||||
|
||||
/* just copy the name... */
|
||||
if (kb && name) {
|
||||
/* if the KeyBlock had a name, use it, otherwise use the index */
|
||||
if (kb->name[0])
|
||||
strcpy(name, kb->name);
|
||||
else
|
||||
sprintf(name, "Key %d", ale->index);
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* check if some setting exists for this channel */
|
||||
static short acf_shapekey_setting_valid(bAnimContext *ac, bAnimListElem *ale, int setting)
|
||||
{
|
||||
switch (setting) {
|
||||
case ACHANNEL_SETTING_SELECT: /* selected */
|
||||
case ACHANNEL_SETTING_MUTE: /* muted */
|
||||
case ACHANNEL_SETTING_PROTECT: /* protected */
|
||||
return 1;
|
||||
|
||||
/* nothing else is supported */
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* get the appropriate flag(s) for the setting when it is valid */
|
||||
static int acf_shapekey_setting_flag(int setting, short *neg)
|
||||
{
|
||||
/* clear extra return data first */
|
||||
*neg= 0;
|
||||
|
||||
switch (setting) {
|
||||
case ACHANNEL_SETTING_MUTE: /* mute */
|
||||
return KEYBLOCK_MUTE;
|
||||
|
||||
case ACHANNEL_SETTING_SELECT: /* selected */
|
||||
return KEYBLOCK_SEL;
|
||||
|
||||
case ACHANNEL_SETTING_PROTECT: /* locked */
|
||||
return KEYBLOCK_LOCKED;
|
||||
|
||||
default: /* unsupported */
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* get pointer to the setting */
|
||||
static void *acf_shapekey_setting_ptr(bAnimListElem *ale, int setting, short *type)
|
||||
{
|
||||
KeyBlock *kb= (KeyBlock *)ale->data;
|
||||
|
||||
/* clear extra return data first */
|
||||
*type= 0;
|
||||
|
||||
switch (setting) {
|
||||
case ACHANNEL_SETTING_SELECT: /* selected */
|
||||
case ACHANNEL_SETTING_MUTE: /* muted */
|
||||
case ACHANNEL_SETTING_PROTECT: /* protected */
|
||||
GET_ACF_FLAG_PTR(kb->flag)
|
||||
|
||||
default: /* unsupported */
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* shapekey expander type define */
|
||||
static bAnimChannelType ACF_SHAPEKEY=
|
||||
{
|
||||
acf_generic_channel_backdrop, /* backdrop */
|
||||
acf_generic_indention_0, /* indent level */
|
||||
acf_generic_basic_offset, /* offset */
|
||||
|
||||
acf_shapekey_name, /* name */
|
||||
NULL, /* icon */
|
||||
|
||||
acf_shapekey_setting_valid, /* has setting */
|
||||
acf_shapekey_setting_flag, /* flag for setting */
|
||||
acf_shapekey_setting_ptr /* pointer for setting */
|
||||
};
|
||||
|
||||
/* Grease Pencil entries ------------------------------------------- */
|
||||
// XXX ... this is currently not restored yet
|
||||
|
@ -1923,7 +1986,7 @@ void ANIM_init_channel_typeinfo_data (void)
|
|||
animchannelTypeInfo[type++]= &ACF_DSMBALL; /* MetaBall Channel */
|
||||
animchannelTypeInfo[type++]= &ACF_DSARM; /* Armature Channel */
|
||||
|
||||
animchannelTypeInfo[type++]= NULL; /* ShapeKey */ // XXX this is no longer used for now...
|
||||
animchannelTypeInfo[type++]= &ACF_SHAPEKEY; /* ShapeKey */
|
||||
|
||||
// XXX not restored yet
|
||||
animchannelTypeInfo[type++]= NULL; /* Grease Pencil Datablock */
|
||||
|
@ -2084,7 +2147,7 @@ void ANIM_channel_setting_set (bAnimContext *ac, bAnimListElem *ale, int setting
|
|||
// XXX hardcoded size of icons
|
||||
#define ICON_WIDTH 17
|
||||
// XXX hardcoded width of sliders
|
||||
#define SLIDER_WIDTH 70
|
||||
#define SLIDER_WIDTH 80
|
||||
|
||||
/* Draw the given channel */
|
||||
// TODO: make this use UI controls for the buttons
|
||||
|
@ -2195,6 +2258,134 @@ static void achannel_setting_widget_cb(bContext *C, void *poin, void *poin2)
|
|||
WM_event_add_notifier(C, NC_ANIMATION|ND_ANIMCHAN_EDIT, NULL);
|
||||
}
|
||||
|
||||
/* callback for visiblility-toggle widget settings - perform value flushing (Graph Editor only) */
|
||||
static void achannel_setting_visible_widget_cb(bContext *C, void *ale_npoin, void *dummy_poin)
|
||||
{
|
||||
bAnimListElem *ale_setting= (bAnimListElem *)ale_npoin;
|
||||
int prevLevel=0, matchLevel=0;
|
||||
short vizOn = 0;
|
||||
|
||||
bAnimContext ac;
|
||||
ListBase anim_data = {NULL, NULL};
|
||||
bAnimListElem *ale, *match=NULL;
|
||||
int filter;
|
||||
|
||||
/* send notifiers before doing anything else... */
|
||||
WM_event_add_notifier(C, NC_ANIMATION|ND_ANIMCHAN_EDIT, NULL);
|
||||
|
||||
/* verify animation context */
|
||||
if (ANIM_animdata_get_context(C, &ac) == 0)
|
||||
return;
|
||||
|
||||
/* verify that we have a channel to operate on, and that it has all we need */
|
||||
if (ale_setting) {
|
||||
/* check if the setting is on... */
|
||||
vizOn= ANIM_channel_setting_get(&ac, ale_setting, ACHANNEL_SETTING_VISIBLE);
|
||||
|
||||
/* vizOn == -1 means setting not found... */
|
||||
if (vizOn == -1)
|
||||
return;
|
||||
}
|
||||
else
|
||||
return;
|
||||
|
||||
/* get all channels that can possibly be chosen
|
||||
* - therefore, the filter is simply ANIMFILTER_CHANNELS, since if we took VISIBLE too,
|
||||
* then the channels under closed expanders get ignored...
|
||||
*/
|
||||
filter= ANIMFILTER_CHANNELS;
|
||||
ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
|
||||
|
||||
/* find the channel that got changed */
|
||||
for (ale= anim_data.first; ale; ale= ale->next) {
|
||||
/* compare data, and type as main way of identifying the channel */
|
||||
if ((ale->data == ale_setting->data) && (ale->type == ale_setting->type)) {
|
||||
/* we also have to check the ID, this is assigned to, since a block may have multiple users */
|
||||
// TODO: is the owner-data more revealing?
|
||||
if (ale->id == ale_setting->id) {
|
||||
match= ale;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (match == NULL) {
|
||||
printf("ERROR: no channel matching the one changed was found \n");
|
||||
BLI_freelistN(&anim_data);
|
||||
return;
|
||||
}
|
||||
else {
|
||||
bAnimChannelType *acf= ANIM_channel_get_typeinfo(ale_setting);
|
||||
|
||||
/* get the level of the channel that was affected
|
||||
* - we define the level as simply being the offset for the start of the channel
|
||||
*/
|
||||
matchLevel= (acf->get_offset)? acf->get_offset(&ac, ale_setting) : 0;
|
||||
}
|
||||
|
||||
/* flush up?
|
||||
* - only flush up if the current state is now enabled
|
||||
* (otherwise, it's too much work to force the parents to be inactive too)
|
||||
*/
|
||||
if (vizOn) {
|
||||
/* go backwards in the list, until the highest-ranking element (by indention has been covered) */
|
||||
for (ale= match->prev; ale; ale= ale->prev) {
|
||||
bAnimChannelType *acf= ANIM_channel_get_typeinfo(ale);
|
||||
int level;
|
||||
|
||||
/* get the level of the current channel traversed
|
||||
* - we define the level as simply being the offset for the start of the channel
|
||||
*/
|
||||
level= (acf->get_offset)? acf->get_offset(&ac, ale) : 0;
|
||||
|
||||
/* if the level is 'less than' (i.e. more important) the previous channel,
|
||||
* flush the new status...
|
||||
*/
|
||||
if (level < matchLevel)
|
||||
ANIM_channel_setting_set(&ac, ale, ACHANNEL_SETTING_VISIBLE, vizOn);
|
||||
/* however, if the level is 'greater than' (i.e. less important than the previous channel,
|
||||
* stop searching, since we've already reached the bottom of another hierarchy
|
||||
*/
|
||||
else if (level > matchLevel)
|
||||
break;
|
||||
|
||||
/* store this level as the 'old' level now */
|
||||
prevLevel= level;
|
||||
}
|
||||
}
|
||||
|
||||
/* flush down (always) */
|
||||
{
|
||||
/* go forwards in the list, until the lowest-ranking element (by indention has been covered) */
|
||||
for (ale= match->next; ale; ale= ale->next) {
|
||||
bAnimChannelType *acf= ANIM_channel_get_typeinfo(ale);
|
||||
int level;
|
||||
|
||||
/* get the level of the current channel traversed
|
||||
* - we define the level as simply being the offset for the start of the channel
|
||||
*/
|
||||
level= (acf->get_offset)? acf->get_offset(&ac, ale) : 0;
|
||||
|
||||
/* if the level is 'greater than' (i.e. less important) the channel that was changed,
|
||||
* flush the new status...
|
||||
*/
|
||||
if (level > matchLevel)
|
||||
ANIM_channel_setting_set(&ac, ale, ACHANNEL_SETTING_VISIBLE, vizOn);
|
||||
/* however, if the level is 'less than or equal to' the channel that was changed,
|
||||
* (i.e. the current channel is as important if not more important than the changed channel)
|
||||
* then we should stop, since we've found the last one of the children we should flush
|
||||
*/
|
||||
else
|
||||
break;
|
||||
|
||||
/* store this level as the 'old' level now */
|
||||
prevLevel= level;
|
||||
}
|
||||
}
|
||||
|
||||
/* free temp data */
|
||||
BLI_freelistN(&anim_data);
|
||||
}
|
||||
|
||||
/* callback for widget sliders - insert keyframes */
|
||||
static void achannel_setting_slider_cb(bContext *C, void *id_poin, void *fcu_poin)
|
||||
{
|
||||
|
@ -2237,7 +2428,57 @@ static void achannel_setting_slider_cb(bContext *C, void *id_poin, void *fcu_poi
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/* callback for shapekey widget sliders - insert keyframes */
|
||||
static void achannel_setting_slider_shapekey_cb(bContext *C, void *key_poin, void *kb_poin)
|
||||
{
|
||||
Key *key= (Key *)key_poin;
|
||||
KeyBlock *kb= (KeyBlock *)kb_poin;
|
||||
char *rna_path= key_get_curValue_rnaPath(key, kb);
|
||||
|
||||
Scene *scene= CTX_data_scene(C);
|
||||
PointerRNA id_ptr, ptr;
|
||||
PropertyRNA *prop;
|
||||
short flag=0, done=0;
|
||||
float cfra;
|
||||
|
||||
/* get current frame */
|
||||
// NOTE: this will do for now...
|
||||
cfra= (float)CFRA;
|
||||
|
||||
/* get flags for keyframing */
|
||||
if (IS_AUTOKEY_FLAG(INSERTNEEDED))
|
||||
flag |= INSERTKEY_NEEDED;
|
||||
if (IS_AUTOKEY_FLAG(AUTOMATKEY))
|
||||
flag |= INSERTKEY_MATRIX;
|
||||
if (IS_AUTOKEY_MODE(scene, EDITKEYS))
|
||||
flag |= INSERTKEY_REPLACE;
|
||||
|
||||
|
||||
/* get RNA pointer, and resolve the path */
|
||||
RNA_id_pointer_create((ID *)key, &id_ptr);
|
||||
|
||||
/* try to resolve the path stored in the F-Curve */
|
||||
if (RNA_path_resolve(&id_ptr, rna_path, &ptr, &prop)) {
|
||||
/* find or create new F-Curve */
|
||||
// XXX is the group name for this ok?
|
||||
bAction *act= verify_adt_action((ID *)key, 1);
|
||||
FCurve *fcu= verify_fcurve(act, NULL, rna_path, 0, 1);
|
||||
|
||||
/* set the special 'replace' flag if on a keyframe */
|
||||
if (fcurve_frame_has_keyframe(fcu, cfra, 0))
|
||||
flag |= INSERTKEY_REPLACE;
|
||||
|
||||
/* insert a keyframe for this F-Curve */
|
||||
done= insert_keyframe_direct(ptr, prop, fcu, cfra, flag);
|
||||
|
||||
if (done)
|
||||
WM_event_add_notifier(C, NC_ANIMATION|ND_ANIMCHAN_EDIT, NULL);
|
||||
}
|
||||
|
||||
/* free the path */
|
||||
if (rna_path)
|
||||
MEM_freeN(rna_path);
|
||||
}
|
||||
|
||||
/* Draw a widget for some setting */
|
||||
static void draw_setting_widget (bAnimContext *ac, bAnimListElem *ale, bAnimChannelType *acf, uiBlock *block, int xpos, int ypos, int setting)
|
||||
|
@ -2260,9 +2501,9 @@ static void draw_setting_widget (bAnimContext *ac, bAnimListElem *ale, bAnimChan
|
|||
icon= ICON_CHECKBOX_DEHLT;
|
||||
|
||||
if (ale->type == ANIMTYPE_FCURVE)
|
||||
tooltip= "F-Curve is visible in Graph Editor for editing.";
|
||||
tooltip= "Channel is visible in Graph Editor for editing.";
|
||||
else
|
||||
tooltip= "F-Curve(s) are visible in Graph Editor for editing.";
|
||||
tooltip= "Channel(s) are visible in Graph Editor for editing.";
|
||||
break;
|
||||
|
||||
case ACHANNEL_SETTING_EXPAND: /* expanded triangle */
|
||||
|
@ -2327,10 +2568,14 @@ static void draw_setting_widget (bAnimContext *ac, bAnimListElem *ale, bAnimChan
|
|||
break;
|
||||
}
|
||||
|
||||
/* set call to send relevant notifiers */
|
||||
// NOTE: for now, we only need to send 'edited'
|
||||
if (but)
|
||||
uiButSetFunc(but, achannel_setting_widget_cb, NULL, NULL);
|
||||
/* set call to send relevant notifiers and/or perform type-specific updates */
|
||||
if (but) {
|
||||
/* 'visibility' toggles for Graph Editor need special flushing */
|
||||
if (setting == ACHANNEL_SETTING_VISIBLE)
|
||||
uiButSetNFunc(but, achannel_setting_visible_widget_cb, MEM_dupallocN(ale), 0);
|
||||
else
|
||||
uiButSetFunc(but, achannel_setting_widget_cb, NULL, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2445,7 +2690,7 @@ void ANIM_channel_draw_widgets (bAnimContext *ac, bAnimListElem *ale, uiBlock *b
|
|||
* and wouldn't be able to auto-keyframe...
|
||||
* - slider should start before the toggles (if they're visible) to keep a clean line down the side
|
||||
*/
|
||||
if ((draw_sliders) && (ale->type == ANIMTYPE_FCURVE)) {
|
||||
if ((draw_sliders) && ELEM(ale->type, ANIMTYPE_FCURVE, ANIMTYPE_SHAPEKEY)) {
|
||||
/* adjust offset */
|
||||
offset += SLIDER_WIDTH;
|
||||
|
||||
|
@ -2453,20 +2698,49 @@ void ANIM_channel_draw_widgets (bAnimContext *ac, bAnimListElem *ale, uiBlock *b
|
|||
uiBlockSetEmboss(block, UI_EMBOSS);
|
||||
|
||||
if (ale->id) { /* Slider using RNA Access -------------------- */
|
||||
FCurve *fcu= (FCurve *)ale->data;
|
||||
PointerRNA id_ptr, ptr;
|
||||
PropertyRNA *prop;
|
||||
char *rna_path = NULL;
|
||||
int array_index = 0;
|
||||
short free_path = 0;
|
||||
|
||||
/* get RNA pointer, and resolve the path */
|
||||
RNA_id_pointer_create(ale->id, &id_ptr);
|
||||
|
||||
/* try to resolve the path */
|
||||
if (RNA_path_resolve(&id_ptr, fcu->rna_path, &ptr, &prop)) {
|
||||
uiBut *but;
|
||||
/* get destination info */
|
||||
if (ale->type == ANIMTYPE_FCURVE) {
|
||||
FCurve *fcu= (FCurve *)ale->data;
|
||||
|
||||
/* create the slider button, and assign relevant callback to ensure keyframes are inserted... */
|
||||
but= uiDefAutoButR(block, &ptr, prop, fcu->array_index, "", 0, (int)v2d->cur.xmax-offset, ymid, SLIDER_WIDTH, (int)ymaxc-yminc);
|
||||
uiButSetFunc(but, achannel_setting_slider_cb, ale->id, fcu);
|
||||
rna_path= fcu->rna_path;
|
||||
array_index= fcu->array_index;
|
||||
}
|
||||
else if (ale->type == ANIMTYPE_SHAPEKEY) {
|
||||
KeyBlock *kb= (KeyBlock *)ale->data;
|
||||
Key *key= (Key *)ale->id;
|
||||
|
||||
rna_path= key_get_curValue_rnaPath(key, kb);
|
||||
free_path= 1;
|
||||
}
|
||||
|
||||
/* only if RNA-Path found */
|
||||
if (rna_path) {
|
||||
/* get RNA pointer, and resolve the path */
|
||||
RNA_id_pointer_create(ale->id, &id_ptr);
|
||||
|
||||
/* try to resolve the path */
|
||||
if (RNA_path_resolve(&id_ptr, rna_path, &ptr, &prop)) {
|
||||
uiBut *but;
|
||||
|
||||
/* create the slider button, and assign relevant callback to ensure keyframes are inserted... */
|
||||
but= uiDefAutoButR(block, &ptr, prop, array_index, "", 0, (int)v2d->cur.xmax-offset, ymid, SLIDER_WIDTH, (int)ymaxc-yminc);
|
||||
|
||||
/* assign keyframing function according to slider type */
|
||||
if (ale->type == ANIMTYPE_SHAPEKEY)
|
||||
uiButSetFunc(but, achannel_setting_slider_shapekey_cb, ale->id, ale->data);
|
||||
else
|
||||
uiButSetFunc(but, achannel_setting_slider_cb, ale->id, ale->data);
|
||||
}
|
||||
|
||||
/* free the path if necessary */
|
||||
if (free_path)
|
||||
MEM_freeN(rna_path);
|
||||
}
|
||||
}
|
||||
else { /* Special Slider for stuff without RNA Access ---------- */
|
||||
|
|
|
@ -238,6 +238,10 @@ void ANIM_deselect_anim_channels (void *data, short datatype, short test, short
|
|||
if (ale->flag & FCURVE_SELECTED)
|
||||
sel= ACHANNEL_SETFLAG_CLEAR;
|
||||
break;
|
||||
case ANIMTYPE_SHAPEKEY:
|
||||
if (ale->flag & KEYBLOCK_SEL)
|
||||
sel= ACHANNEL_SETFLAG_CLEAR;
|
||||
break;
|
||||
case ANIMTYPE_NLATRACK:
|
||||
if (ale->flag & NLATRACK_SELECTED)
|
||||
sel= ACHANNEL_SETFLAG_CLEAR;
|
||||
|
@ -307,6 +311,13 @@ void ANIM_deselect_anim_channels (void *data, short datatype, short test, short
|
|||
fcu->flag &= ~FCURVE_ACTIVE;
|
||||
}
|
||||
break;
|
||||
case ANIMTYPE_SHAPEKEY:
|
||||
{
|
||||
KeyBlock *kb= (KeyBlock *)ale->data;
|
||||
|
||||
ACHANNEL_SET_FLAG(kb, sel, KEYBLOCK_SEL);
|
||||
}
|
||||
break;
|
||||
case ANIMTYPE_NLATRACK:
|
||||
{
|
||||
NlaTrack *nlt= (NlaTrack *)ale->data;
|
||||
|
@ -904,28 +915,14 @@ static int animchannels_visibility_toggle_exec(bContext *C, wmOperator *op)
|
|||
if (vis == ACHANNEL_SETFLAG_CLEAR)
|
||||
break;
|
||||
|
||||
if ((ale->type == ANIMTYPE_FCURVE) && (ale->flag & FCURVE_VISIBLE))
|
||||
vis= ACHANNEL_SETFLAG_CLEAR;
|
||||
else if ((ale->type == ANIMTYPE_GROUP) && !(ale->flag & AGRP_NOTVISIBLE))
|
||||
/* set the setting in the appropriate way (if available) */
|
||||
if (ANIM_channel_setting_get(&ac, ale, ACHANNEL_SETTING_VISIBLE))
|
||||
vis= ACHANNEL_SETFLAG_CLEAR;
|
||||
}
|
||||
|
||||
/* Now set the flags */
|
||||
for (ale= anim_data.first; ale; ale= ale->next) {
|
||||
switch (ale->type) {
|
||||
case ANIMTYPE_FCURVE: /* F-Curve */
|
||||
{
|
||||
FCurve *fcu= (FCurve *)ale->data;
|
||||
ACHANNEL_SET_FLAG(fcu, vis, FCURVE_VISIBLE);
|
||||
}
|
||||
break;
|
||||
case ANIMTYPE_GROUP: /* Group */
|
||||
{
|
||||
bActionGroup *agrp= (bActionGroup *)ale->data;
|
||||
ACHANNEL_SET_FLAG_NEG(agrp, vis, AGRP_NOTVISIBLE);
|
||||
}
|
||||
break;
|
||||
}
|
||||
ANIM_channel_setting_set(&ac, ale, ACHANNEL_SETTING_VISIBLE, vis);
|
||||
}
|
||||
|
||||
/* cleanup */
|
||||
|
@ -1361,7 +1358,7 @@ static int mouse_anim_channels (bAnimContext *ac, float x, int channel_index, sh
|
|||
/* get the channel that was clicked on */
|
||||
/* filter channels */
|
||||
filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CHANNELS);
|
||||
filter= ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
|
||||
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
|
||||
|
||||
/* get channel from index */
|
||||
ale= BLI_findlink(&anim_data, channel_index);
|
||||
|
@ -1531,6 +1528,24 @@ static int mouse_anim_channels (bAnimContext *ac, float x, int channel_index, sh
|
|||
if (fcu->flag & FCURVE_SELECTED)
|
||||
ANIM_set_active_channel(ac, ac->data, ac->datatype, filter, fcu, ANIMTYPE_FCURVE);
|
||||
|
||||
notifierFlags |= ND_ANIMCHAN_SELECT;
|
||||
}
|
||||
break;
|
||||
case ANIMTYPE_SHAPEKEY:
|
||||
{
|
||||
KeyBlock *kb= (KeyBlock *)ale->data;
|
||||
|
||||
/* select/deselect */
|
||||
if (selectmode == SELECT_INVERT) {
|
||||
/* inverse selection status of this ShapeKey only */
|
||||
kb->flag ^= KEYBLOCK_SEL;
|
||||
}
|
||||
else {
|
||||
/* select ShapeKey by itself */
|
||||
ANIM_deselect_anim_channels(ac->data, ac->datatype, 0, ACHANNEL_SETFLAG_CLEAR);
|
||||
kb->flag |= KEYBLOCK_SEL;
|
||||
}
|
||||
|
||||
notifierFlags |= ND_ANIMCHAN_SELECT;
|
||||
}
|
||||
break;
|
||||
|
@ -1571,9 +1586,6 @@ static int mouse_anim_channels (bAnimContext *ac, float x, int channel_index, sh
|
|||
#endif // XXX future of this is unclear
|
||||
}
|
||||
break;
|
||||
case ANIMTYPE_SHAPEKEY:
|
||||
/* TODO: shapekey channels cannot be selected atm... */
|
||||
break;
|
||||
default:
|
||||
printf("Error: Invalid channel type in mouse_anim_channels() \n");
|
||||
}
|
||||
|
|
|
@ -156,7 +156,7 @@ static void draw_cfra_number (Scene *scene, View2D *v2d, float cfra, short time)
|
|||
glScalef(xscale, 1.0, 1.0);
|
||||
}
|
||||
|
||||
/* General call for drawing current frame indicator in a */
|
||||
/* General call for drawing current frame indicator in animation editor */
|
||||
void ANIM_draw_cfra (const bContext *C, View2D *v2d, short flag)
|
||||
{
|
||||
Scene *scene= CTX_data_scene(C);
|
||||
|
|
|
@ -78,6 +78,7 @@
|
|||
|
||||
#include "BKE_animsys.h"
|
||||
#include "BKE_action.h"
|
||||
#include "BKE_fcurve.h"
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_global.h"
|
||||
#include "BKE_key.h"
|
||||
|
@ -207,8 +208,10 @@ static short actedit_get_context (bAnimContext *ac, SpaceAction *saction)
|
|||
static short graphedit_get_context (bAnimContext *ac, SpaceIpo *sipo)
|
||||
{
|
||||
/* init dopesheet data if non-existant (i.e. for old files) */
|
||||
if (sipo->ads == NULL)
|
||||
if (sipo->ads == NULL) {
|
||||
sipo->ads= MEM_callocN(sizeof(bDopeSheet), "GraphEdit DopeSheet");
|
||||
sipo->ads->source= (ID *)ac->scene;
|
||||
}
|
||||
|
||||
/* set settings for Graph Editor - "Selected = Editable" */
|
||||
if (sipo->flag & SIPO_SELCUVERTSONLY)
|
||||
|
@ -370,9 +373,18 @@ short ANIM_animdata_get_context (const bContext *C, bAnimContext *ac)
|
|||
*
|
||||
* - id: ID block which should have an AnimData pointer following it immediately, to use
|
||||
* - adtOk: line or block of code to execute for AnimData-blocks case (usually ANIMDATA_ADD_ANIMDATA)
|
||||
* - nlaOk: line or block of code to execute for NLA case
|
||||
* - nlaOk: line or block of code to execute for NLA tracks+strips case
|
||||
* - driversOk: line or block of code to execute for Drivers case
|
||||
* - keysOk: line or block of code for Keyframes case
|
||||
*
|
||||
* The checks for the various cases are as follows:
|
||||
* 0) top level: checks for animdata and also that all the F-Curves for the block will be visible
|
||||
* 1) animdata check: for filtering animdata blocks only
|
||||
* 2A) nla tracks: include animdata block's data as there are NLA tracks+strips there
|
||||
* 2B) actions to convert to nla: include animdata block's data as there is an action that can be
|
||||
* converted to a new NLA strip, and the filtering options allow this
|
||||
* 3) drivers: include drivers from animdata block (for Drivers mode in Graph Editor)
|
||||
* 4) normal keyframes: only when there is an active action
|
||||
*/
|
||||
#define ANIMDATA_FILTER_CASES(id, adtOk, nlaOk, driversOk, keysOk) \
|
||||
{\
|
||||
|
@ -647,6 +659,36 @@ bAnimListElem *make_new_animlistelem (void *data, short datatype, void *owner, s
|
|||
ale->datatype= ALE_FCURVE;
|
||||
}
|
||||
break;
|
||||
|
||||
case ANIMTYPE_SHAPEKEY:
|
||||
{
|
||||
KeyBlock *kb= (KeyBlock *)data;
|
||||
Key *key= (Key *)ale->id;
|
||||
|
||||
ale->flag= kb->flag;
|
||||
|
||||
/* whether we have keyframes depends on whether there is a Key block to find it from */
|
||||
if (key) {
|
||||
/* index of shapekey is defined by place in key's list */
|
||||
ale->index= BLI_findindex(&key->block, kb);
|
||||
|
||||
/* the corresponding keyframes are from the animdata */
|
||||
if (ale->adt && ale->adt->action) {
|
||||
bAction *act= ale->adt->action;
|
||||
char *rna_path = key_get_curValue_rnaPath(key, kb);
|
||||
|
||||
/* try to find the F-Curve which corresponds to this exactly,
|
||||
* then free the MEM_alloc'd string
|
||||
*/
|
||||
if (rna_path) {
|
||||
ale->key_data= (void *)list_find_fcurve(&act->curves, rna_path, 0);
|
||||
MEM_freeN(rna_path);
|
||||
}
|
||||
}
|
||||
ale->datatype= (ale->key_data)? ALE_FCURVE : ALE_NONE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ANIMTYPE_GPLAYER:
|
||||
{
|
||||
|
@ -892,7 +934,55 @@ static int animdata_filter_nla (ListBase *anim_data, bDopeSheet *ads, AnimData *
|
|||
/* return the number of items added to the list */
|
||||
return items;
|
||||
}
|
||||
|
||||
|
||||
/* Include ShapeKey Data for ShapeKey Editor */
|
||||
static int animdata_filter_shapekey (ListBase *anim_data, Key *key, int filter_mode)
|
||||
{
|
||||
bAnimListElem *ale;
|
||||
int items = 0;
|
||||
|
||||
/* check if channels or only F-Curves */
|
||||
if ((filter_mode & ANIMFILTER_CURVESONLY) == 0) {
|
||||
KeyBlock *kb;
|
||||
|
||||
/* loop through the channels adding ShapeKeys as appropriate */
|
||||
for (kb= key->block.first; kb; kb= kb->next) {
|
||||
/* skip the first one, since that's the non-animateable basis */
|
||||
// XXX maybe in future this may become handy?
|
||||
if (kb == key->block.first) continue;
|
||||
|
||||
/* only work with this channel and its subchannels if it is editable */
|
||||
if (!(filter_mode & ANIMFILTER_FOREDIT) || EDITABLE_SHAPEKEY(kb)) {
|
||||
/* only include this track if selected in a way consistent with the filtering requirements */
|
||||
if ( ANIMCHANNEL_SELOK(SEL_SHAPEKEY(kb)) ) {
|
||||
// TODO: consider 'active' too?
|
||||
|
||||
/* owner-id here must be key so that the F-Curve can be resolved... */
|
||||
ale= make_new_animlistelem(kb, ANIMTYPE_SHAPEKEY, NULL, ANIMTYPE_NONE, (ID *)key);
|
||||
|
||||
if (ale) {
|
||||
BLI_addtail(anim_data, ale);
|
||||
items++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* just use the action associated with the shapekey */
|
||||
// FIXME: is owner-id and having no owner/dopesheet really fine?
|
||||
if (key->adt) {
|
||||
if (filter_mode & ANIMFILTER_ANIMDATA)
|
||||
ANIMDATA_ADD_ANIMDATA(key)
|
||||
else if (key->adt->action)
|
||||
items= animdata_filter_action(anim_data, NULL, key->adt->action, filter_mode, NULL, ANIMTYPE_NONE, (ID *)key);
|
||||
}
|
||||
}
|
||||
|
||||
/* return the number of items added to the list */
|
||||
return items;
|
||||
}
|
||||
|
||||
#if 0
|
||||
// FIXME: switch this to use the bDopeSheet...
|
||||
static int animdata_filter_gpencil (ListBase *anim_data, bScreen *sc, int filter_mode)
|
||||
|
@ -1023,7 +1113,7 @@ static int animdata_filter_dopesheet_mats (ListBase *anim_data, bDopeSheet *ads,
|
|||
}
|
||||
|
||||
/* add material's animation data */
|
||||
if (FILTER_MAT_OBJD(ma) || (filter_mode & ANIMFILTER_CURVESONLY)) {
|
||||
if (!(filter_mode & ANIMFILTER_VISIBLE) || FILTER_MAT_OBJD(ma) || (filter_mode & ANIMFILTER_CURVESONLY)) {
|
||||
ANIMDATA_FILTER_CASES(ma,
|
||||
{ /* AnimData blocks - do nothing... */ },
|
||||
items += animdata_filter_nla(anim_data, ads, ma->adt, filter_mode, ma, ANIMTYPE_DSMAT, (ID *)ma);,
|
||||
|
@ -1083,7 +1173,7 @@ static int animdata_filter_dopesheet_particles (ListBase *anim_data, bDopeSheet
|
|||
}
|
||||
}
|
||||
|
||||
if (FILTER_PART_OBJD(psys->part) || (filter_mode & ANIMFILTER_CURVESONLY)) {
|
||||
if (!(filter_mode & ANIMFILTER_VISIBLE) || FILTER_PART_OBJD(psys->part) || (filter_mode & ANIMFILTER_CURVESONLY)) {
|
||||
ANIMDATA_FILTER_CASES(psys->part,
|
||||
{ /* AnimData blocks - do nothing... */ },
|
||||
items += animdata_filter_nla(anim_data, ads, psys->part->adt, filter_mode, psys->part, ANIMTYPE_DSPART, (ID *)psys->part);,
|
||||
|
@ -1164,7 +1254,7 @@ static int animdata_filter_dopesheet_obdata (ListBase *anim_data, bDopeSheet *ad
|
|||
}
|
||||
|
||||
/* add object-data animation channels? */
|
||||
if ((expanded) || (filter_mode & ANIMFILTER_CURVESONLY)) {
|
||||
if (!(filter_mode & ANIMFILTER_VISIBLE) || (expanded) || (filter_mode & ANIMFILTER_CURVESONLY)) {
|
||||
/* filtering for channels - nla, drivers, keyframes */
|
||||
ANIMDATA_FILTER_CASES(iat,
|
||||
{ /* AnimData blocks - do nothing... */ },
|
||||
|
@ -1202,7 +1292,8 @@ static int animdata_filter_dopesheet_ob (ListBase *anim_data, bDopeSheet *ads, B
|
|||
}
|
||||
|
||||
/* if collapsed, don't go any further (unless adding keyframes only) */
|
||||
if ( (EXPANDED_OBJC(ob) == 0) && !(filter_mode & (ANIMFILTER_CURVESONLY|ANIMFILTER_NLATRACKS)) )
|
||||
if ( ((filter_mode & ANIMFILTER_VISIBLE) && EXPANDED_OBJC(ob) == 0) &&
|
||||
!(filter_mode & (ANIMFILTER_CURVESONLY|ANIMFILTER_NLATRACKS)) )
|
||||
return items;
|
||||
|
||||
/* Action, Drivers, or NLA */
|
||||
|
@ -1225,7 +1316,7 @@ static int animdata_filter_dopesheet_ob (ListBase *anim_data, bDopeSheet *ads, B
|
|||
}
|
||||
|
||||
/* add F-Curve channels (drivers are F-Curves) */
|
||||
if (EXPANDED_DRVD(adt) || !(filter_mode & ANIMFILTER_CHANNELS)) {
|
||||
if (!(filter_mode & ANIMFILTER_VISIBLE) || EXPANDED_DRVD(adt) || !(filter_mode & ANIMFILTER_CHANNELS)) {
|
||||
// need to make the ownertype normal object here... (maybe type should be a separate one for clarity?)
|
||||
items += animdata_filter_fcurves(anim_data, ads, adt->drivers.first, NULL, ob, ANIMTYPE_OBJECT, filter_mode, (ID *)ob);
|
||||
}
|
||||
|
@ -1241,7 +1332,7 @@ static int animdata_filter_dopesheet_ob (ListBase *anim_data, bDopeSheet *ads, B
|
|||
}
|
||||
|
||||
/* add F-Curve channels? */
|
||||
if (EXPANDED_ACTC(adt->action) || !(filter_mode & ANIMFILTER_CHANNELS)) {
|
||||
if (!(filter_mode & ANIMFILTER_VISIBLE) || EXPANDED_ACTC(adt->action) || !(filter_mode & ANIMFILTER_CHANNELS)) {
|
||||
// need to make the ownertype normal object here... (maybe type should be a separate one for clarity?)
|
||||
items += animdata_filter_action(anim_data, ads, adt->action, filter_mode, ob, ANIMTYPE_OBJECT, (ID *)ob);
|
||||
}
|
||||
|
@ -1269,7 +1360,7 @@ static int animdata_filter_dopesheet_ob (ListBase *anim_data, bDopeSheet *ads, B
|
|||
}
|
||||
|
||||
/* add NLA tracks - only if expanded or so */
|
||||
if (FILTER_SKE_OBJD(key) || (filter_mode & ANIMFILTER_CURVESONLY))
|
||||
if (!(filter_mode & ANIMFILTER_VISIBLE) || FILTER_SKE_OBJD(key) || (filter_mode & ANIMFILTER_CURVESONLY))
|
||||
items += animdata_filter_nla(anim_data, ads, adt, filter_mode, ob, ANIMTYPE_OBJECT, (ID *)ob);
|
||||
},
|
||||
{ /* drivers */
|
||||
|
@ -1283,7 +1374,7 @@ static int animdata_filter_dopesheet_ob (ListBase *anim_data, bDopeSheet *ads, B
|
|||
}
|
||||
|
||||
/* add channels */
|
||||
if (FILTER_SKE_OBJD(key) || (filter_mode & ANIMFILTER_CURVESONLY)) {
|
||||
if (!(filter_mode & ANIMFILTER_VISIBLE) || FILTER_SKE_OBJD(key) || (filter_mode & ANIMFILTER_CURVESONLY)) {
|
||||
items += animdata_filter_fcurves(anim_data, ads, adt->drivers.first, NULL, key, ANIMTYPE_DSSKEY, filter_mode, (ID *)key);
|
||||
}
|
||||
},
|
||||
|
@ -1301,7 +1392,7 @@ static int animdata_filter_dopesheet_ob (ListBase *anim_data, bDopeSheet *ads, B
|
|||
}
|
||||
|
||||
/* add channels */
|
||||
if (FILTER_SKE_OBJD(key) || (filter_mode & ANIMFILTER_CURVESONLY)) {
|
||||
if (!(filter_mode & ANIMFILTER_VISIBLE) || FILTER_SKE_OBJD(key) || (filter_mode & ANIMFILTER_CURVESONLY)) {
|
||||
items += animdata_filter_action(anim_data, ads, adt->action, filter_mode, key, ANIMTYPE_DSSKEY, (ID *)key);
|
||||
}
|
||||
}
|
||||
|
@ -1516,7 +1607,9 @@ static int animdata_filter_dopesheet (ListBase *anim_data, bAnimContext *ac, bDo
|
|||
|
||||
/* check that we do indeed have a scene */
|
||||
if ((ads->source == NULL) || (GS(ads->source->name)!=ID_SCE)) {
|
||||
printf("DopeSheet Error: Not scene! \n");
|
||||
printf("DopeSheet Error: Not scene!\n");
|
||||
if (G.f & G_DEBUG)
|
||||
printf("\tPointer = %p, Name = '%s' \n", ads->source, (ads->source)?ads->source->name:NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1944,9 +2037,11 @@ int ANIM_animdata_filter (bAnimContext *ac, ListBase *anim_data, int filter_mode
|
|||
}
|
||||
break;
|
||||
|
||||
case ANIMCONT_SHAPEKEY:
|
||||
case ANIMCONT_SHAPEKEY: /* 'ShapeKey Editor' */
|
||||
{
|
||||
//items= animdata_filter_shapekey(anim_data, data, filter_mode, NULL, ANIMTYPE_NONE, (ID *)obact);
|
||||
/* the check for the DopeSheet summary is included here since the summary works here too */
|
||||
if (animdata_filter_dopesheet_summary(ac, anim_data, filter_mode, &items))
|
||||
items= animdata_filter_shapekey(anim_data, data, filter_mode);
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
|
@ -62,6 +62,18 @@
|
|||
|
||||
/* ********************** frame change operator ***************************/
|
||||
|
||||
/* Check if the operator can be run from the current context */
|
||||
static int change_frame_poll(bContext *C)
|
||||
{
|
||||
ScrArea *curarea= CTX_wm_area(C);
|
||||
|
||||
/* as long as there is an active area, and it isn't a Graph Editor
|
||||
* (since the Graph Editor has its own version which does extra stuff),
|
||||
* we're fine
|
||||
*/
|
||||
return ((curarea) && (curarea->spacetype != SPACE_IPO));
|
||||
}
|
||||
|
||||
/* Set any flags that are necessary to indicate modal time-changing operation */
|
||||
static int change_frame_init(bContext *C, wmOperator *op)
|
||||
{
|
||||
|
@ -85,18 +97,12 @@ static int change_frame_init(bContext *C, wmOperator *op)
|
|||
static void change_frame_apply(bContext *C, wmOperator *op)
|
||||
{
|
||||
Scene *scene= CTX_data_scene(C);
|
||||
int cfra;
|
||||
|
||||
/* get frame, and clamp to MINAFRAME
|
||||
* - not MINFRAME, since it's useful to be able to key a few-frames back
|
||||
*/
|
||||
cfra= RNA_int_get(op->ptr, "frame");
|
||||
|
||||
if (cfra < MINAFRAME) cfra= MINAFRAME;
|
||||
CFRA= cfra;
|
||||
/* set the new frame number */
|
||||
CFRA= RNA_int_get(op->ptr, "frame");
|
||||
|
||||
/* do updates */
|
||||
sound_scrub(C);
|
||||
|
||||
WM_event_add_notifier(C, NC_SCENE|ND_FRAME, scene);
|
||||
}
|
||||
|
||||
|
@ -210,12 +216,14 @@ void ANIM_OT_change_frame(wmOperatorType *ot)
|
|||
/* identifiers */
|
||||
ot->name= "Change frame";
|
||||
ot->idname= "ANIM_OT_change_frame";
|
||||
ot->description= "Interactively change the current frame number.";
|
||||
|
||||
/* api callbacks */
|
||||
ot->exec= change_frame_exec;
|
||||
ot->invoke= change_frame_invoke;
|
||||
ot->cancel= change_frame_cancel;
|
||||
ot->modal= change_frame_modal;
|
||||
ot->poll= change_frame_poll;
|
||||
|
||||
/* flags */
|
||||
ot->flag= OPTYPE_BLOCKING;
|
||||
|
|
|
@ -521,9 +521,14 @@ short bezt_calc_average(BeztEditData *bed, BezTriple *bezt)
|
|||
{
|
||||
/* only if selected */
|
||||
if (bezt->f2 & SELECT) {
|
||||
/* store average time in float (only do rounding at last step */
|
||||
/* store average time in float 1 (only do rounding at last step) */
|
||||
bed->f1 += bezt->vec[1][0];
|
||||
|
||||
/* store average value in float 2 (only do rounding at last step)
|
||||
* - this isn't always needed, but some operators may also require this
|
||||
*/
|
||||
bed->f2 += bezt->vec[1][1];
|
||||
|
||||
/* increment number of items */
|
||||
bed->i1++;
|
||||
}
|
||||
|
@ -669,7 +674,20 @@ static short mirror_bezier_marker(BeztEditData *bed, BezTriple *bezt)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* Note: for markers case, need to set global vars (eww...) */
|
||||
static short mirror_bezier_value(BeztEditData *bed, BezTriple *bezt)
|
||||
{
|
||||
float diff;
|
||||
|
||||
/* value to mirror over is stored in the custom data -> first float value slot */
|
||||
if (bezt->f2 & SELECT) {
|
||||
diff= (bed->f1 - bezt->vec[1][1]);
|
||||
bezt->vec[1][1]= (bed->f1 + diff);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Note: for markers and 'value', the values to use must be supplied as the first float value */
|
||||
// calchandles_fcurve
|
||||
BeztEditFunc ANIM_editkeyframes_mirror(short type)
|
||||
{
|
||||
|
@ -682,6 +700,8 @@ BeztEditFunc ANIM_editkeyframes_mirror(short type)
|
|||
return mirror_bezier_xaxis;
|
||||
case MIRROR_KEYS_MARKER: /* mirror over marker */
|
||||
return mirror_bezier_marker;
|
||||
case MIRROR_KEYS_VALUE: /* mirror over given value */
|
||||
return mirror_bezier_value;
|
||||
default: /* just in case */
|
||||
return mirror_bezier_yaxis;
|
||||
break;
|
||||
|
|
|
@ -1430,7 +1430,7 @@ int autokeyframe_cfra_can_key(Scene *scene, ID *id)
|
|||
short fcurve_frame_has_keyframe (FCurve *fcu, float frame, short filter)
|
||||
{
|
||||
/* quick sanity check */
|
||||
if (fcu == NULL)
|
||||
if (ELEM(NULL, fcu, fcu->bezt))
|
||||
return 0;
|
||||
|
||||
/* we either include all regardless of muting, or only non-muted */
|
||||
|
|
|
@ -142,6 +142,9 @@ static int add_default_keyingset_exec (bContext *C, wmOperator *op)
|
|||
|
||||
scene->active_keyingset= BLI_countlist(&scene->keyingsets);
|
||||
|
||||
/* send notifiers */
|
||||
WM_event_add_notifier(C, NC_SCENE|ND_KEYINGSET, NULL);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
|
@ -182,6 +185,9 @@ static int remove_active_keyingset_exec (bContext *C, wmOperator *op)
|
|||
/* the active one should now be the previously second-to-last one */
|
||||
scene->active_keyingset--;
|
||||
|
||||
/* send notifiers */
|
||||
WM_event_add_notifier(C, NC_SCENE|ND_KEYINGSET, NULL);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
|
|
|
@ -214,6 +214,22 @@ void ED_keymap_armature(wmKeyConfig *keyconf)
|
|||
keymap= WM_keymap_find(keyconf, "Armature", 0, 0);
|
||||
keymap->poll= ED_operator_editarmature;
|
||||
|
||||
/* Armature -> Etch-A-Ton ------------------------ */
|
||||
WM_keymap_add_item(keymap, "SKETCH_OT_delete", XKEY, KM_PRESS, 0, 0);
|
||||
WM_keymap_add_item(keymap, "SKETCH_OT_delete", DELKEY, KM_PRESS, 0, 0);
|
||||
WM_keymap_add_item(keymap, "SKETCH_OT_finish_stroke", SELECTMOUSE, KM_PRESS, 0, 0);
|
||||
WM_keymap_add_item(keymap, "SKETCH_OT_cancel_stroke", ESCKEY, KM_PRESS, 0, 0);
|
||||
WM_keymap_add_item(keymap, "SKETCH_OT_select", SELECTMOUSE, KM_PRESS, 0, 0);
|
||||
|
||||
/* sketch poll checks mode */
|
||||
WM_keymap_add_item(keymap, "SKETCH_OT_gesture", ACTIONMOUSE, KM_PRESS, KM_SHIFT, 0);
|
||||
WM_keymap_add_item(keymap, "SKETCH_OT_draw_stroke", ACTIONMOUSE, KM_PRESS, 0, 0);
|
||||
kmi = WM_keymap_add_item(keymap, "SKETCH_OT_draw_stroke", ACTIONMOUSE, KM_PRESS, KM_CTRL, 0);
|
||||
RNA_boolean_set(kmi->ptr, "snap", 1);
|
||||
WM_keymap_add_item(keymap, "SKETCH_OT_draw_preview", MOUSEMOVE, KM_ANY, 0, 0);
|
||||
kmi = WM_keymap_add_item(keymap, "SKETCH_OT_draw_preview", MOUSEMOVE, KM_ANY, KM_CTRL, 0);
|
||||
RNA_boolean_set(kmi->ptr, "snap", 1);
|
||||
|
||||
/* only set in editmode armature, by space_view3d listener */
|
||||
// WM_keymap_add_item(keymap, "ARMATURE_OT_hide", HKEY, KM_PRESS, 0, 0);
|
||||
WM_keymap_add_item(keymap, "ARMATURE_OT_align", AKEY, KM_PRESS, KM_CTRL|KM_ALT, 0);
|
||||
|
@ -278,22 +294,6 @@ void ED_keymap_armature(wmKeyConfig *keyconf)
|
|||
/* 2) set roll */
|
||||
kmi= WM_keymap_add_item(keymap, "TFM_OT_transform", RKEY, KM_PRESS, KM_CTRL, 0);
|
||||
RNA_enum_set(kmi->ptr, "mode", TFM_BONE_ROLL);
|
||||
|
||||
/* Armature -> Etch-A-Ton ------------------------ */
|
||||
WM_keymap_add_item(keymap, "SKETCH_OT_delete", XKEY, KM_PRESS, 0, 0);
|
||||
WM_keymap_add_item(keymap, "SKETCH_OT_delete", DELKEY, KM_PRESS, 0, 0);
|
||||
WM_keymap_add_item(keymap, "SKETCH_OT_finish_stroke", SELECTMOUSE, KM_PRESS, 0, 0);
|
||||
WM_keymap_add_item(keymap, "SKETCH_OT_cancel_stroke", ESCKEY, KM_PRESS, 0, 0);
|
||||
WM_keymap_add_item(keymap, "SKETCH_OT_select", SELECTMOUSE, KM_PRESS, 0, 0);
|
||||
|
||||
/* sketch poll checks mode */
|
||||
WM_keymap_add_item(keymap, "SKETCH_OT_gesture", ACTIONMOUSE, KM_PRESS, KM_SHIFT, 0);
|
||||
WM_keymap_add_item(keymap, "SKETCH_OT_draw_stroke", ACTIONMOUSE, KM_PRESS, 0, 0);
|
||||
kmi = WM_keymap_add_item(keymap, "SKETCH_OT_draw_stroke", ACTIONMOUSE, KM_PRESS, KM_CTRL, 0);
|
||||
RNA_boolean_set(kmi->ptr, "snap", 1);
|
||||
WM_keymap_add_item(keymap, "SKETCH_OT_draw_preview", MOUSEMOVE, KM_ANY, 0, 0);
|
||||
kmi = WM_keymap_add_item(keymap, "SKETCH_OT_draw_preview", MOUSEMOVE, KM_ANY, KM_CTRL, 0);
|
||||
RNA_boolean_set(kmi->ptr, "snap", 1);
|
||||
|
||||
/* Pose ------------------------ */
|
||||
/* only set in posemode, by space_view3d listener */
|
||||
|
|
|
@ -55,6 +55,7 @@
|
|||
#include "BLI_editVert.h"
|
||||
#include "BLI_ghash.h"
|
||||
|
||||
#include "BKE_animsys.h"
|
||||
#include "BKE_action.h"
|
||||
#include "BKE_armature.h"
|
||||
#include "BKE_constraint.h"
|
||||
|
@ -5036,11 +5037,11 @@ static int pose_de_select_all_exec(bContext *C, wmOperator *op)
|
|||
|
||||
/* Set the flags */
|
||||
CTX_DATA_BEGIN(C, bPoseChannel *, pchan, visible_pchans) {
|
||||
/* select pchan, only if selectable */
|
||||
if ((pchan->bone->flag & BONE_UNSELECTABLE) == 0) {
|
||||
if (sel==0) pchan->bone->flag &= ~(BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL|BONE_ACTIVE);
|
||||
else pchan->bone->flag |= BONE_SELECTED;
|
||||
}
|
||||
/* select pchan only if selectable, but deselect works always */
|
||||
if (sel==0)
|
||||
pchan->bone->flag &= ~(BONE_SELECTED|BONE_TIPSEL|BONE_ROOTSEL|BONE_ACTIVE);
|
||||
else if ((pchan->bone->flag & BONE_UNSELECTABLE)==0)
|
||||
pchan->bone->flag |= BONE_SELECTED;
|
||||
}
|
||||
CTX_DATA_END;
|
||||
|
||||
|
@ -5289,9 +5290,8 @@ void ED_armature_bone_rename(bArmature *arm, char *oldnamep, char *newnamep)
|
|||
|
||||
/* now check if we're in editmode, we need to find the unique name */
|
||||
if (arm->edbo) {
|
||||
EditBone *eBone;
|
||||
EditBone *eBone= editbone_name_exists(arm->edbo, oldname);
|
||||
|
||||
eBone= editbone_name_exists(arm->edbo, oldname);
|
||||
if (eBone) {
|
||||
unique_editbone_name(arm->edbo, newname, NULL);
|
||||
BLI_strncpy(eBone->name, newname, MAXBONENAME);
|
||||
|
@ -5302,7 +5302,7 @@ void ED_armature_bone_rename(bArmature *arm, char *oldnamep, char *newnamep)
|
|||
Bone *bone= get_named_bone(arm, oldname);
|
||||
|
||||
if (bone) {
|
||||
unique_bone_name (arm, newname);
|
||||
unique_bone_name(arm, newname);
|
||||
BLI_strncpy(bone->name, newname, MAXBONENAME);
|
||||
}
|
||||
else return;
|
||||
|
@ -5313,21 +5313,7 @@ void ED_armature_bone_rename(bArmature *arm, char *oldnamep, char *newnamep)
|
|||
/* we have the object using the armature */
|
||||
if (arm==ob->data) {
|
||||
Object *cob;
|
||||
//bAction *act;
|
||||
//bActionChannel *achan;
|
||||
//bActionStrip *strip;
|
||||
|
||||
/* Rename action channel if necessary */
|
||||
#if 0 // XXX old animation system
|
||||
act = ob->action;
|
||||
if (act && !act->id.lib) {
|
||||
/* Find the appropriate channel */
|
||||
achan= get_action_channel(act, oldname);
|
||||
if (achan)
|
||||
BLI_strncpy(achan->name, newname, MAXBONENAME);
|
||||
}
|
||||
#endif // XXX old animation system
|
||||
|
||||
/* Rename the pose channel, if it exists */
|
||||
if (ob->pose) {
|
||||
bPoseChannel *pchan = get_pose_channel(ob->pose, oldname);
|
||||
|
@ -5335,20 +5321,6 @@ void ED_armature_bone_rename(bArmature *arm, char *oldnamep, char *newnamep)
|
|||
BLI_strncpy(pchan->name, newname, MAXBONENAME);
|
||||
}
|
||||
|
||||
/* check all nla-strips too */
|
||||
#if 0 // XXX old animation system
|
||||
for (strip= ob->nlastrips.first; strip; strip= strip->next) {
|
||||
/* Rename action channel if necessary */
|
||||
act = strip->act;
|
||||
if (act && !act->id.lib) {
|
||||
/* Find the appropriate channel */
|
||||
achan= get_action_channel(act, oldname);
|
||||
if (achan)
|
||||
BLI_strncpy(achan->name, newname, MAXBONENAME);
|
||||
}
|
||||
}
|
||||
#endif // XXX old animation system
|
||||
|
||||
/* Update any object constraints to use the new bone name */
|
||||
for (cob= G.main->object.first; cob; cob= cob->id.next) {
|
||||
if (cob->constraints.first)
|
||||
|
@ -5379,31 +5351,14 @@ void ED_armature_bone_rename(bArmature *arm, char *oldnamep, char *newnamep)
|
|||
BLI_strncpy(dg->name, newname, MAXBONENAME);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* do entire db - ipo's for the drivers */
|
||||
#if 0 // XXX old animation system
|
||||
for (ipo= G.main->ipo.first; ipo; ipo= ipo->id.next) {
|
||||
IpoCurve *icu;
|
||||
|
||||
/* check each curve's driver */
|
||||
for (icu= ipo->curve.first; icu; icu= icu->next) {
|
||||
IpoDriver *icd= icu->driver;
|
||||
|
||||
if ((icd) && (icd->ob)) {
|
||||
ob= icd->ob;
|
||||
|
||||
if (icu->driver->type == IPO_DRIVER_TYPE_NORMAL) {
|
||||
if (!strcmp(oldname, icd->name))
|
||||
BLI_strncpy(icd->name, newname, MAXBONENAME);
|
||||
}
|
||||
else {
|
||||
/* TODO: pydrivers need to be treated differently */
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Fix animation data attached to this object */
|
||||
// TODO: should we be using the database wide version instead (since drivers may break)
|
||||
if (ob->adt) {
|
||||
/* posechannels only... */
|
||||
BKE_animdata_fix_paths_rename(&ob->id, ob->adt, "pose.pose_channels", oldname, newname);
|
||||
}
|
||||
}
|
||||
#endif // XXX old animation system
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1154,7 +1154,7 @@ void pose_adds_vgroups(Scene *scene, Object *meshobj, int heatweights)
|
|||
return;
|
||||
}
|
||||
|
||||
// XXX add_verts_to_dgroups(meshobj, poseobj, heatweights, (Gwp.flag & VP_MIRROR_X));
|
||||
// XXX add_verts_to_dgroups(meshobj, poseobj, heatweights, ((Mesh *)(meshobj->data))->editflag & ME_EDIT_MIRROR_X);
|
||||
|
||||
if(heatweights)
|
||||
BIF_undo_push("Apply Bone Heat Weights to Vertex Groups");
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -99,7 +99,7 @@ typedef struct bAnimListElem {
|
|||
void *data; /* source data this elem represents */
|
||||
int type; /* one of the ANIMTYPE_* values */
|
||||
int flag; /* copy of elem's flags for quick access */
|
||||
int index; /* copy of adrcode where applicable */
|
||||
int index; /* for un-named data, the index of the data in it's collection */
|
||||
|
||||
void *key_data; /* motion data - mostly F-Curves, but can be other types too */
|
||||
short datatype; /* type of motion data to expect */
|
||||
|
@ -144,7 +144,7 @@ typedef enum eAnim_ChannelType {
|
|||
ANIMTYPE_DSMBALL,
|
||||
ANIMTYPE_DSARM,
|
||||
|
||||
ANIMTYPE_SHAPEKEY, // XXX probably can become depreceated???
|
||||
ANIMTYPE_SHAPEKEY,
|
||||
|
||||
ANIMTYPE_GPDATABLOCK,
|
||||
ANIMTYPE_GPLAYER,
|
||||
|
@ -209,7 +209,7 @@ typedef enum eAnimFilter_Flags {
|
|||
#define FILTER_MAT_OBJC(ob) ((ob->nlaflag & OB_ADS_SHOWMATS))
|
||||
#define FILTER_PART_OBJC(ob) ((ob->nlaflag & OB_ADS_SHOWPARTS))
|
||||
/* 'Sub-object' channels (flags stored in Data block) */
|
||||
#define FILTER_SKE_OBJD(key) ((key->flag & KEYBLOCK_DS_EXPAND))
|
||||
#define FILTER_SKE_OBJD(key) ((key->flag & KEY_DS_EXPAND))
|
||||
#define FILTER_MAT_OBJD(ma) ((ma->flag & MA_DS_EXPAND))
|
||||
#define FILTER_LAM_OBJD(la) ((la->flag & LA_DS_EXPAND))
|
||||
#define FILTER_CAM_OBJD(ca) ((ca->flag & CAM_DS_EXPAND))
|
||||
|
@ -232,6 +232,10 @@ typedef enum eAnimFilter_Flags {
|
|||
#define EDITABLE_FCU(fcu) ((fcu->flag & FCURVE_PROTECTED)==0)
|
||||
#define SEL_FCU(fcu) (fcu->flag & (FCURVE_ACTIVE|FCURVE_SELECTED))
|
||||
|
||||
/* ShapeKey mode only */
|
||||
#define EDITABLE_SHAPEKEY(kb) ((kb->flag & KEYBLOCK_LOCKED)==0)
|
||||
#define SEL_SHAPEKEY(kb) (kb->flag & KEYBLOCK_SEL)
|
||||
|
||||
/* Grease Pencil only */
|
||||
/* Grease Pencil datablock settings */
|
||||
#define EXPANDED_GPD(gpd) (gpd->flag & GP_DATA_EXPAND)
|
||||
|
|
|
@ -82,6 +82,7 @@ typedef enum eEditKeyframes_Mirror {
|
|||
MIRROR_KEYS_YAXIS,
|
||||
MIRROR_KEYS_XAXIS,
|
||||
MIRROR_KEYS_MARKER,
|
||||
MIRROR_KEYS_VALUE,
|
||||
} eEditKeyframes_Mirror;
|
||||
|
||||
/* ************************************************ */
|
||||
|
|
|
@ -59,6 +59,7 @@ struct UvVertMap;
|
|||
struct UvMapVert;
|
||||
struct Material;
|
||||
struct Object;
|
||||
struct recti;
|
||||
|
||||
// edge and face flag both
|
||||
#define EM_FGON 2
|
||||
|
@ -212,6 +213,7 @@ void EM_free_uv_vert_map(struct UvVertMap *vmap);
|
|||
/* editmesh_mods.c */
|
||||
extern unsigned int bm_vertoffs, bm_solidoffs, bm_wireoffs;
|
||||
|
||||
void EM_cache_x_mirror_vert(struct Object *ob, struct EditMesh *em);
|
||||
void mouse_mesh(struct bContext *C, short mval[2], short extend);
|
||||
int EM_check_backbuf(unsigned int index);
|
||||
int EM_mask_init_backbuf_border(struct ViewContext *vc, short mcords[][2], short tot, short xmin, short ymin, short xmax, short ymax);
|
||||
|
@ -226,6 +228,10 @@ void EM_automerge(struct Scene *scene, struct Object *obedit, int update);
|
|||
|
||||
/* editface.c */
|
||||
struct MTFace *EM_get_active_mtface(struct EditMesh *em, struct EditFace **act_efa, struct MCol **mcol, int sloppy);
|
||||
int face_select(struct bContext *C, struct Object *ob, short mval[2], int extend);
|
||||
void face_borderselect(struct bContext *C, struct Object *ob, struct rcti *rect, int select);
|
||||
void deselectall_tface(struct Object *ob);
|
||||
void select_linked_tfaces(struct bContext *C, struct Object *ob, short mval[2], int mode);
|
||||
|
||||
/* object_vgroup.c */
|
||||
|
||||
|
@ -237,6 +243,7 @@ struct bDeformGroup *ED_vgroup_add(struct Object *ob);
|
|||
struct bDeformGroup *ED_vgroup_add_name(struct Object *ob, char *name);
|
||||
void ED_vgroup_select_by_name(struct Object *ob, char *name);
|
||||
void ED_vgroup_data_create(struct ID *id);
|
||||
int ED_vgroup_give_array(struct ID *id, struct MDeformVert **dvert_arr, int *dvert_tot);
|
||||
|
||||
void ED_vgroup_vert_add(struct Object *ob, struct bDeformGroup *dg, int vertnum, float weight, int assignmode);
|
||||
void ED_vgroup_vert_remove(struct Object *ob, struct bDeformGroup *dg, int vertnum);
|
||||
|
|
|
@ -102,8 +102,6 @@ void mouse_lattice(struct bContext *C, short mval[2], int extend);
|
|||
void undo_push_lattice(struct bContext *C, char *name);
|
||||
|
||||
/* object_shapekey.c */
|
||||
void insert_shapekey(struct Scene *scene, struct Object *ob);
|
||||
void delete_key(struct Scene *scene, struct Object *ob);
|
||||
void key_to_mesh(struct KeyBlock *kb, struct Mesh *me);
|
||||
void mesh_to_key(struct Mesh *me, struct KeyBlock *kb);
|
||||
void key_to_latt(struct KeyBlock *kb, struct Lattice *lt);
|
||||
|
|
|
@ -32,6 +32,11 @@
|
|||
|
||||
struct wmKeyConfig;
|
||||
|
||||
/* particle_edit.c */
|
||||
int PE_poll(struct bContext *C);
|
||||
int PE_hair_poll(struct bContext *C);
|
||||
int PE_poll_3dview(struct bContext *C);
|
||||
|
||||
/* operators */
|
||||
void ED_operatortypes_physics(void);
|
||||
void ED_keymap_physics(struct wmKeyConfig *keyconf);
|
||||
|
|
|
@ -60,8 +60,8 @@ void ED_spacetype_userpref(void);
|
|||
void ED_file_init(void);
|
||||
void ED_file_exit(void);
|
||||
|
||||
#define REGION_DRAW_PRE 1
|
||||
#define REGION_DRAW_POST 0
|
||||
#define REGION_DRAW_POST_VIEW 0
|
||||
#define REGION_DRAW_POST_PIXEL 1
|
||||
|
||||
void *ED_region_draw_cb_activate(struct ARegionType *,
|
||||
void (*draw)(const struct bContext *, struct ARegion *, void *),
|
||||
|
|
|
@ -523,7 +523,7 @@ DEF_ICON(ICON_MOD_UVPROJECT)
|
|||
DEF_ICON(ICON_MOD_DISPLACE)
|
||||
DEF_ICON(ICON_MOD_CURVE)
|
||||
DEF_ICON(ICON_MOD_LATTICE)
|
||||
DEF_ICON(ICON_BLANK143)
|
||||
DEF_ICON(ICON_CONSTRAINT_DATA)
|
||||
DEF_ICON(ICON_MOD_ARMATURE)
|
||||
DEF_ICON(ICON_MOD_SHRINKWRAP)
|
||||
DEF_ICON(ICON_MOD_CAST)
|
||||
|
|
|
@ -148,6 +148,7 @@ typedef struct uiLayout uiLayout;
|
|||
#define UI_BUT_LAST_ACTIVE (1<<24)
|
||||
#define UI_BUT_UNDO (1<<25)
|
||||
#define UI_BUT_IMMEDIATE (1<<26)
|
||||
#define UI_BUT_NO_TOOLTIP (1<<27)
|
||||
|
||||
#define UI_PANEL_WIDTH 340
|
||||
#define UI_COMPACT_PANEL_WIDTH 160
|
||||
|
@ -603,16 +604,17 @@ int uiLayoutGetKeepAspect(uiLayout *layout);
|
|||
int uiLayoutGetWidth(uiLayout *layout);
|
||||
float uiLayoutGetScaleX(uiLayout *layout);
|
||||
float uiLayoutGetScaleY(uiLayout *layout);
|
||||
ListBase *uiLayoutBoxGetList(uiLayout *layout);
|
||||
|
||||
/* layout specifiers */
|
||||
uiLayout *uiLayoutRow(uiLayout *layout, int align);
|
||||
uiLayout *uiLayoutColumn(uiLayout *layout, int align);
|
||||
uiLayout *uiLayoutColumnFlow(uiLayout *layout, int number, int align);
|
||||
uiLayout *uiLayoutBox(uiLayout *layout);
|
||||
uiLayout *uiLayoutListBox(uiLayout *layout);
|
||||
uiLayout *uiLayoutFree(uiLayout *layout, int align);
|
||||
uiLayout *uiLayoutListBox(uiLayout *layout, struct PointerRNA *ptr, struct PropertyRNA *prop,
|
||||
struct PointerRNA *actptr, struct PropertyRNA *actprop);
|
||||
uiLayout *uiLayoutAbsolute(uiLayout *layout, int align);
|
||||
uiLayout *uiLayoutSplit(uiLayout *layout, float percentage);
|
||||
uiLayout *uiLayoutOverlap(uiLayout *layout);
|
||||
|
||||
uiBlock *uiLayoutAbsoluteBlock(uiLayout *layout);
|
||||
|
||||
|
@ -639,14 +641,7 @@ void uiTemplateHeader3D(uiLayout *layout, struct bContext *C);
|
|||
void uiTemplate_view3d_select_faceselmenu(uiLayout *layout, struct bContext *C);
|
||||
void uiTemplateTextureImage(uiLayout *layout, struct bContext *C, struct Tex *tex);
|
||||
|
||||
typedef struct uiListItem {
|
||||
struct uiListItem *next, *prev;
|
||||
|
||||
struct PointerRNA data;
|
||||
uiLayout *layout;
|
||||
} uiListItem;
|
||||
|
||||
ListBase uiTemplateList(uiLayout *layout, struct bContext *C, struct PointerRNA *ptr, char *propname, struct PointerRNA *activeptr, char *activeprop, int rows, int type);
|
||||
void uiTemplateList(uiLayout *layout, struct bContext *C, struct PointerRNA *ptr, char *propname, struct PointerRNA *activeptr, char *activeprop, int rows, int type);
|
||||
|
||||
/* items */
|
||||
void uiItemO(uiLayout *layout, char *name, int icon, char *opname);
|
||||
|
@ -683,6 +678,7 @@ void uiIDContextProperty(struct bContext *C, struct PointerRNA *ptr, struct Prop
|
|||
/* Styled text draw */
|
||||
void uiStyleFontSet(struct uiFontStyle *fs);
|
||||
void uiStyleFontDraw(struct uiFontStyle *fs, struct rcti *rect, char *str);
|
||||
void uiStyleFontDrawRotated(struct uiFontStyle *fs, struct rcti *rect, char *str);
|
||||
|
||||
int UI_GetStringWidth(char *str); // XXX temp
|
||||
void UI_DrawString(float x, float y, char *str); // XXX temp
|
||||
|
|
|
@ -49,6 +49,7 @@ CPPFLAGS += -I../../makesrna
|
|||
CPPFLAGS += -I../../imbuf
|
||||
CPPFLAGS += -I../../blenfont
|
||||
CPPFLAGS += -I../../python
|
||||
CPPFLAGS += -I../../gpu
|
||||
|
||||
# own include
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ for source in env.Glob('*_api.c'):
|
|||
sources.remove(source)
|
||||
|
||||
incs = '../include ../../blenlib ../../blenfont ../../blenkernel ../../makesdna ../../imbuf'
|
||||
incs += ' ../../makesrna ../../windowmanager #/intern/guardedalloc'
|
||||
incs += ' ../../makesrna ../../windowmanager #/intern/guardedalloc ../../gpu'
|
||||
incs += ' #/extern/glew/include'
|
||||
incs += ' ../../python/' # python button eval
|
||||
|
||||
|
|
|
@ -92,6 +92,7 @@ typedef enum uiHandleButtonState {
|
|||
} uiHandleButtonState;
|
||||
|
||||
typedef struct uiHandleButtonData {
|
||||
wmWindowManager *wm;
|
||||
wmWindow *window;
|
||||
ARegion *region;
|
||||
|
||||
|
@ -1943,8 +1944,11 @@ static int ui_do_but_TEX(bContext *C, uiBlock *block, uiBut *but, uiHandleButton
|
|||
{
|
||||
if(data->state == BUTTON_STATE_HIGHLIGHT) {
|
||||
if(ELEM4(event->type, LEFTMOUSE, PADENTER, RETKEY, EVT_BUT_OPEN) && event->val==KM_PRESS) {
|
||||
button_activate_state(C, but, BUTTON_STATE_TEXT_EDITING);
|
||||
return WM_UI_HANDLER_BREAK;
|
||||
if(but->dt == UI_EMBOSSN && !event->ctrl);
|
||||
else {
|
||||
button_activate_state(C, but, BUTTON_STATE_TEXT_EDITING);
|
||||
return WM_UI_HANDLER_BREAK;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(data->state == BUTTON_STATE_TEXT_EDITING) {
|
||||
|
@ -2056,9 +2060,21 @@ static int ui_numedit_but_NUM(uiBut *but, uiHandleButtonData *data, float fac, i
|
|||
/* Mouse location isn't screen clamped to the screen so use a linear mapping
|
||||
* 2px == 1-int, or 1px == 1-ClickStep */
|
||||
if(ui_is_but_float(but)) {
|
||||
tempf = data->startvalue + ((mx - data->dragstartx) * fac * 0.01*but->a1);
|
||||
fac *= 0.01*but->a1;
|
||||
tempf = data->startvalue + ((mx - data->dragstartx) * fac);
|
||||
tempf= ui_numedit_apply_snapf(tempf, softmin, softmax, softrange, snap);
|
||||
|
||||
#if 1 /* fake moving the click start, nicer for dragging back after passing the limit */
|
||||
if(tempf < softmin) {
|
||||
data->dragstartx -= (softmin-tempf) / fac;
|
||||
tempf= softmin;
|
||||
} else if (tempf > softmax) {
|
||||
data->dragstartx += (tempf-softmax) / fac;
|
||||
tempf= softmax;
|
||||
}
|
||||
#else
|
||||
CLAMP(tempf, softmin, softmax);
|
||||
#endif
|
||||
|
||||
if(tempf != data->value) {
|
||||
data->dragchange= 1;
|
||||
|
@ -2067,9 +2083,22 @@ static int ui_numedit_but_NUM(uiBut *but, uiHandleButtonData *data, float fac, i
|
|||
}
|
||||
}
|
||||
else {
|
||||
temp= data->startvalue + (mx - data->dragstartx)/2; /* simple 2px == 1 */
|
||||
fac = 0.5; /* simple 2px == 1 */
|
||||
|
||||
temp= data->startvalue + ((mx - data->dragstartx) * fac);
|
||||
temp= ui_numedit_apply_snap(temp, softmin, softmax, snap);
|
||||
|
||||
#if 1 /* fake moving the click start, nicer for dragging back after passing the limit */
|
||||
if(temp < softmin) {
|
||||
data->dragstartx -= (softmin-temp) / fac;
|
||||
temp= softmin;
|
||||
} else if (temp > softmax) {
|
||||
data->dragstartx += (temp-softmax) / fac;
|
||||
temp= softmax;
|
||||
}
|
||||
#else
|
||||
CLAMP(temp, softmin, softmax);
|
||||
#endif
|
||||
|
||||
if(temp != data->value) {
|
||||
data->dragchange= 1;
|
||||
|
@ -2077,6 +2106,8 @@ static int ui_numedit_but_NUM(uiBut *but, uiHandleButtonData *data, float fac, i
|
|||
changed= 1;
|
||||
}
|
||||
}
|
||||
|
||||
data->draglastx= mx;
|
||||
}
|
||||
else {
|
||||
/* Use a non-linear mapping of the mouse drag especially for large floats (normal behavior) */
|
||||
|
@ -3625,15 +3656,35 @@ static uiBut *ui_but_find_mouse_over(ARegion *ar, int x, int y)
|
|||
if(but->flag & UI_HIDDEN)
|
||||
continue;
|
||||
if(ui_but_contains_pt(but, mx, my))
|
||||
/* give precedence to already activated buttons */
|
||||
if(!butover || (!butover->active && but->active))
|
||||
butover= but;
|
||||
butover= but;
|
||||
}
|
||||
}
|
||||
|
||||
return butover;
|
||||
}
|
||||
|
||||
static uiBut *ui_list_find_mouse_over(ARegion *ar, int x, int y)
|
||||
{
|
||||
uiBlock *block;
|
||||
uiBut *but;
|
||||
int mx, my;
|
||||
|
||||
if(!ui_mouse_inside_region(ar, x, y))
|
||||
return NULL;
|
||||
|
||||
for(block=ar->uiblocks.first; block; block=block->next) {
|
||||
mx= x;
|
||||
my= y;
|
||||
ui_window_to_block(ar, block, &mx, &my);
|
||||
|
||||
for(but=block->buttons.last; but; but= but->prev)
|
||||
if(but->type == LISTBOX && ui_but_contains_pt(but, mx, my))
|
||||
return but;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* ****************** button state handling **************************/
|
||||
|
||||
static int button_modal_state(uiHandleButtonState state)
|
||||
|
@ -3650,7 +3701,7 @@ static void button_timers_tooltip_remove(bContext *C, uiBut *but)
|
|||
data= but->active;
|
||||
|
||||
if(data->tooltiptimer) {
|
||||
WM_event_remove_window_timer(data->window, data->tooltiptimer);
|
||||
WM_event_remove_timer(data->wm, data->window, data->tooltiptimer);
|
||||
data->tooltiptimer= NULL;
|
||||
}
|
||||
if(data->tooltip) {
|
||||
|
@ -3659,7 +3710,7 @@ static void button_timers_tooltip_remove(bContext *C, uiBut *but)
|
|||
}
|
||||
|
||||
if(data->autoopentimer) {
|
||||
WM_event_remove_window_timer(data->window, data->autoopentimer);
|
||||
WM_event_remove_timer(data->wm, data->window, data->autoopentimer);
|
||||
data->autoopentimer= NULL;
|
||||
}
|
||||
}
|
||||
|
@ -3671,13 +3722,13 @@ static void button_tooltip_timer_reset(uiBut *but)
|
|||
data= but->active;
|
||||
|
||||
if(data->tooltiptimer) {
|
||||
WM_event_remove_window_timer(data->window, data->tooltiptimer);
|
||||
WM_event_remove_timer(data->wm, data->window, data->tooltiptimer);
|
||||
data->tooltiptimer= NULL;
|
||||
}
|
||||
|
||||
if(U.flag & USER_TOOLTIPS)
|
||||
if(!but->block->tooltipdisabled)
|
||||
data->tooltiptimer= WM_event_add_window_timer(data->window, TIMER, BUTTON_TOOLTIP_DELAY);
|
||||
data->tooltiptimer= WM_event_add_timer(data->wm, data->window, TIMER, BUTTON_TOOLTIP_DELAY);
|
||||
}
|
||||
|
||||
static void button_activate_state(bContext *C, uiBut *but, uiHandleButtonState state)
|
||||
|
@ -3705,7 +3756,7 @@ static void button_activate_state(bContext *C, uiBut *but, uiHandleButtonState s
|
|||
else time= -1;
|
||||
|
||||
if(time >= 0)
|
||||
data->autoopentimer= WM_event_add_window_timer(data->window, TIMER, 0.02*(double)time);
|
||||
data->autoopentimer= WM_event_add_timer(data->wm, data->window, TIMER, 0.02*(double)time);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3723,12 +3774,12 @@ static void button_activate_state(bContext *C, uiBut *but, uiHandleButtonState s
|
|||
/* number editing */
|
||||
if(state == BUTTON_STATE_NUM_EDITING) {
|
||||
if(ui_is_a_warp_but(but))
|
||||
WM_cursor_grab(CTX_wm_window(C), TRUE);
|
||||
WM_cursor_grab(CTX_wm_window(C), TRUE, TRUE, NULL);
|
||||
ui_numedit_begin(but, data);
|
||||
} else if(data->state == BUTTON_STATE_NUM_EDITING) {
|
||||
ui_numedit_end(but, data);
|
||||
if(ui_is_a_warp_but(but))
|
||||
WM_cursor_ungrab(CTX_wm_window(C), FALSE);
|
||||
WM_cursor_ungrab(CTX_wm_window(C));
|
||||
}
|
||||
/* menu open */
|
||||
if(state == BUTTON_STATE_MENU_OPEN)
|
||||
|
@ -3738,10 +3789,10 @@ static void button_activate_state(bContext *C, uiBut *but, uiHandleButtonState s
|
|||
|
||||
/* add a short delay before exiting, to ensure there is some feedback */
|
||||
if(state == BUTTON_STATE_WAIT_FLASH) {
|
||||
data->flashtimer= WM_event_add_window_timer(data->window, TIMER, BUTTON_FLASH_DELAY);
|
||||
data->flashtimer= WM_event_add_timer(data->wm, data->window, TIMER, BUTTON_FLASH_DELAY);
|
||||
}
|
||||
else if(data->flashtimer) {
|
||||
WM_event_remove_window_timer(data->window, data->flashtimer);
|
||||
WM_event_remove_timer(data->wm, data->window, data->flashtimer);
|
||||
data->flashtimer= NULL;
|
||||
}
|
||||
|
||||
|
@ -3772,6 +3823,7 @@ static void button_activate_init(bContext *C, ARegion *ar, uiBut *but, uiButtonA
|
|||
|
||||
/* setup struct */
|
||||
data= MEM_callocN(sizeof(uiHandleButtonData), "uiHandleButtonData");
|
||||
data->wm= CTX_wm_manager(C);
|
||||
data->window= CTX_wm_window(C);
|
||||
data->region= ar;
|
||||
if( ELEM(but->type, BUT_CURVE, SEARCH_MENU) ); // XXX curve is temp
|
||||
|
@ -3999,6 +4051,10 @@ static int ui_handle_button_event(bContext *C, wmEvent *event, uiBut *but)
|
|||
data->cancel= 1;
|
||||
button_activate_state(C, but, BUTTON_STATE_EXIT);
|
||||
}
|
||||
else if(ui_but_find_mouse_over(ar, event->x, event->y) != but) {
|
||||
data->cancel= 1;
|
||||
button_activate_state(C, but, BUTTON_STATE_EXIT);
|
||||
}
|
||||
else if(event->x!=event->prevx || event->y!=event->prevy) {
|
||||
/* re-enable tooltip on mouse move */
|
||||
ui_blocks_set_tooltips(ar, 1);
|
||||
|
@ -4009,7 +4065,7 @@ static int ui_handle_button_event(bContext *C, wmEvent *event, uiBut *but)
|
|||
case TIMER: {
|
||||
/* handle tooltip timer */
|
||||
if(event->customdata == data->tooltiptimer) {
|
||||
WM_event_remove_window_timer(data->window, data->tooltiptimer);
|
||||
WM_event_remove_timer(data->wm, data->window, data->tooltiptimer);
|
||||
data->tooltiptimer= NULL;
|
||||
|
||||
if(!data->tooltip)
|
||||
|
@ -4017,7 +4073,7 @@ static int ui_handle_button_event(bContext *C, wmEvent *event, uiBut *but)
|
|||
}
|
||||
/* handle menu auto open timer */
|
||||
else if(event->customdata == data->autoopentimer) {
|
||||
WM_event_remove_window_timer(data->window, data->autoopentimer);
|
||||
WM_event_remove_timer(data->wm, data->window, data->autoopentimer);
|
||||
data->autoopentimer= NULL;
|
||||
|
||||
if(ui_mouse_inside_button(ar, but, event->x, event->y))
|
||||
|
@ -4031,7 +4087,7 @@ static int ui_handle_button_event(bContext *C, wmEvent *event, uiBut *but)
|
|||
case MIDDLEMOUSE:
|
||||
/* XXX hardcoded keymap check... but anyway, while view changes, tooltips should be removed */
|
||||
if(data->tooltiptimer) {
|
||||
WM_event_remove_window_timer(data->window, data->tooltiptimer);
|
||||
WM_event_remove_timer(data->wm, data->window, data->tooltiptimer);
|
||||
data->tooltiptimer= NULL;
|
||||
}
|
||||
/* pass on purposedly */
|
||||
|
@ -4122,6 +4178,71 @@ static int ui_handle_button_event(bContext *C, wmEvent *event, uiBut *but)
|
|||
return retval;
|
||||
}
|
||||
|
||||
static int ui_handle_list_event(bContext *C, wmEvent *event, ARegion *ar)
|
||||
{
|
||||
uiBut *but= ui_list_find_mouse_over(ar, event->x, event->y);
|
||||
int retval= WM_UI_HANDLER_CONTINUE;
|
||||
int value, min, max;
|
||||
|
||||
if(but && (event->val == KM_PRESS)) {
|
||||
Panel *pa= but->block->panel;
|
||||
|
||||
if(ELEM(event->type, UPARROWKEY, DOWNARROWKEY) ||
|
||||
((ELEM(event->type, WHEELUPMOUSE, WHEELDOWNMOUSE) && event->alt))) {
|
||||
/* activate up/down the list */
|
||||
value= RNA_property_int_get(&but->rnapoin, but->rnaprop);
|
||||
|
||||
if(ELEM(event->type, UPARROWKEY, WHEELUPMOUSE))
|
||||
value--;
|
||||
else
|
||||
value++;
|
||||
|
||||
if(value < pa->list_scroll)
|
||||
pa->list_scroll= value;
|
||||
else if(value >= pa->list_scroll+pa->list_size)
|
||||
pa->list_scroll= value - pa->list_size + 1;
|
||||
|
||||
RNA_property_int_range(&but->rnapoin, but->rnaprop, &min, &max);
|
||||
value= CLAMPIS(value, min, max);
|
||||
|
||||
RNA_property_int_set(&but->rnapoin, but->rnaprop, value);
|
||||
RNA_property_update(C, &but->rnapoin, but->rnaprop);
|
||||
ED_region_tag_redraw(ar);
|
||||
|
||||
retval= WM_UI_HANDLER_BREAK;
|
||||
}
|
||||
else if(ELEM(event->type, WHEELUPMOUSE, WHEELDOWNMOUSE) && event->shift) {
|
||||
/* silly replacement for proper grip */
|
||||
if(pa->list_grip_size == 0)
|
||||
pa->list_grip_size= pa->list_size;
|
||||
|
||||
if(event->type == WHEELUPMOUSE)
|
||||
pa->list_grip_size--;
|
||||
else
|
||||
pa->list_grip_size++;
|
||||
|
||||
pa->list_grip_size= MAX2(pa->list_grip_size, 1);
|
||||
|
||||
ED_region_tag_redraw(ar);
|
||||
|
||||
retval= WM_UI_HANDLER_BREAK;
|
||||
}
|
||||
else if(ELEM(event->type, WHEELUPMOUSE, WHEELDOWNMOUSE)) {
|
||||
/* list template will clamp */
|
||||
if(event->type == WHEELUPMOUSE)
|
||||
pa->list_scroll--;
|
||||
else
|
||||
pa->list_scroll++;
|
||||
|
||||
ED_region_tag_redraw(ar);
|
||||
|
||||
retval= WM_UI_HANDLER_BREAK;
|
||||
}
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static void ui_handle_button_return_submenu(bContext *C, wmEvent *event, uiBut *but)
|
||||
{
|
||||
uiHandleButtonData *data;
|
||||
|
@ -4586,6 +4707,9 @@ static int ui_handler_region(bContext *C, wmEvent *event, void *userdata)
|
|||
if(!but || !button_modal_state(but->active->state))
|
||||
retval= ui_handler_panel_region(C, event);
|
||||
|
||||
if(retval == WM_UI_HANDLER_CONTINUE)
|
||||
retval= ui_handle_list_event(C, event, ar);
|
||||
|
||||
if(retval == WM_UI_HANDLER_CONTINUE) {
|
||||
if(but)
|
||||
retval= ui_handle_button_event(C, event, but);
|
||||
|
|
|
@ -38,6 +38,8 @@
|
|||
#endif
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "GPU_extensions.h"
|
||||
|
||||
#include "BLI_arithb.h"
|
||||
#include "BLI_blenlib.h"
|
||||
#include "BLI_storage_types.h"
|
||||
|
@ -489,7 +491,7 @@ static void init_internal_icons()
|
|||
}
|
||||
|
||||
/* we only use a texture for cards with non-power of two */
|
||||
if(GLEW_ARB_texture_non_power_of_two) {
|
||||
if(GPU_non_power_of_two_support()) {
|
||||
glGenTextures(1, &icongltex.id);
|
||||
|
||||
if(icongltex.id) {
|
||||
|
|
|
@ -98,6 +98,7 @@ typedef enum uiItemType {
|
|||
ITEM_LAYOUT_BOX,
|
||||
ITEM_LAYOUT_ABSOLUTE,
|
||||
ITEM_LAYOUT_SPLIT,
|
||||
ITEM_LAYOUT_OVERLAP,
|
||||
|
||||
ITEM_LAYOUT_ROOT
|
||||
#if 0
|
||||
|
@ -148,7 +149,6 @@ typedef struct uiLayoutItemFlow {
|
|||
typedef struct uiLayoutItemBx {
|
||||
uiLayout litem;
|
||||
uiBut *roundbox;
|
||||
ListBase items;
|
||||
} uiLayoutItemBx;
|
||||
|
||||
typedef struct uiLayoutItemSplt {
|
||||
|
@ -286,6 +286,7 @@ static int ui_layout_local_dir(uiLayout *layout)
|
|||
switch(layout->item.type) {
|
||||
case ITEM_LAYOUT_ROW:
|
||||
case ITEM_LAYOUT_ROOT:
|
||||
case ITEM_LAYOUT_OVERLAP:
|
||||
return UI_LAYOUT_HORIZONTAL;
|
||||
case ITEM_LAYOUT_COLUMN:
|
||||
case ITEM_LAYOUT_COLUMN_FLOW:
|
||||
|
@ -362,7 +363,7 @@ static void ui_item_array(uiLayout *layout, uiBlock *block, char *name, int icon
|
|||
int cols= (len >= 20)? 2: 1;
|
||||
int colbuts= len/(2*cols);
|
||||
|
||||
uiBlockSetCurLayout(block, uiLayoutFree(layout, 0));
|
||||
uiBlockSetCurLayout(block, uiLayoutAbsolute(layout, 0));
|
||||
|
||||
unit= UI_UNIT_X*0.75;
|
||||
butw= unit;
|
||||
|
@ -390,7 +391,7 @@ static void ui_item_array(uiLayout *layout, uiBlock *block, char *name, int icon
|
|||
/* matrix layout */
|
||||
int row, col;
|
||||
|
||||
uiBlockSetCurLayout(block, uiLayoutFree(layout, 1));
|
||||
uiBlockSetCurLayout(block, uiLayoutAbsolute(layout, 1));
|
||||
|
||||
len= ceil(sqrt(len));
|
||||
|
||||
|
@ -892,10 +893,13 @@ void uiItemFullR(uiLayout *layout, char *name, int icon, PointerRNA *ptr, Proper
|
|||
name= ui_item_name_add_colon(name, namestr);
|
||||
|
||||
if(layout->root->type == UI_LAYOUT_MENU) {
|
||||
if(type == PROP_BOOLEAN)
|
||||
icon= (RNA_property_boolean_get(ptr, prop))? ICON_CHECKBOX_HLT: ICON_CHECKBOX_DEHLT;
|
||||
else if(type == PROP_ENUM && index == RNA_ENUM_VALUE)
|
||||
icon= (RNA_property_enum_get(ptr, prop) == value)? ICON_CHECKBOX_HLT: ICON_CHECKBOX_DEHLT;
|
||||
/* whether the property is actually enabled doesn't matter,
|
||||
* since the widget code for drawing toggles takes care of the
|
||||
* rest (i.e. given the deactivated icon, it finds the active one
|
||||
* based on the state of the setting)
|
||||
*/
|
||||
if ( (type == PROP_BOOLEAN) || (type==PROP_ENUM && index==RNA_ENUM_VALUE) )
|
||||
icon= ICON_CHECKBOX_DEHLT; /* ICON_CHECKBOX_HLT when on... */
|
||||
}
|
||||
|
||||
slider= (flag & UI_ITEM_R_SLIDER);
|
||||
|
@ -1051,10 +1055,14 @@ static void rna_search_cb(const struct bContext *C, void *arg_but, char *str, ui
|
|||
{
|
||||
uiBut *but= arg_but;
|
||||
char *name;
|
||||
int i, iconid;
|
||||
int i, iconid, flag= RNA_property_flag(but->rnaprop);
|
||||
|
||||
i = 0;
|
||||
RNA_PROP_BEGIN(&but->rnasearchpoin, itemptr, but->rnasearchprop) {
|
||||
if(flag & PROP_ID_SELF_CHECK)
|
||||
if(itemptr.data == but->rnapoin.id.data)
|
||||
continue;
|
||||
|
||||
iconid= 0;
|
||||
if(RNA_struct_is_ID(itemptr.type))
|
||||
iconid= ui_id_icon_get((bContext*)C, itemptr.data);
|
||||
|
@ -1495,11 +1503,11 @@ static void ui_litem_layout_row(uiLayout *litem)
|
|||
/* align right/center */
|
||||
offset= 0;
|
||||
if(litem->alignment == UI_LAYOUT_ALIGN_RIGHT) {
|
||||
if(fixedw == 0 && freew < w-fixedw)
|
||||
if(freew > 0 && freew < w-fixedw)
|
||||
offset= (w - fixedw) - freew;
|
||||
}
|
||||
else if(litem->alignment == UI_LAYOUT_ALIGN_CENTER) {
|
||||
if(fixedw == 0 && freew < w-fixedw)
|
||||
if(freew > 0 && freew < w-fixedw)
|
||||
offset= ((w - fixedw) - freew)/2;
|
||||
}
|
||||
|
||||
|
@ -1862,6 +1870,42 @@ static void ui_litem_layout_split(uiLayout *litem)
|
|||
litem->y= y;
|
||||
}
|
||||
|
||||
/* overlap layout */
|
||||
static void ui_litem_estimate_overlap(uiLayout *litem)
|
||||
{
|
||||
uiItem *item;
|
||||
int itemw, itemh;
|
||||
|
||||
litem->w= 0;
|
||||
litem->h= 0;
|
||||
|
||||
for(item=litem->items.first; item; item=item->next) {
|
||||
ui_item_size(item, &itemw, &itemh);
|
||||
|
||||
litem->w= MAX2(itemw, litem->w);
|
||||
litem->h= MAX2(itemh, litem->h);
|
||||
}
|
||||
}
|
||||
|
||||
static void ui_litem_layout_overlap(uiLayout *litem)
|
||||
{
|
||||
uiItem *item;
|
||||
int itemw, itemh, x, y;
|
||||
|
||||
x= litem->x;
|
||||
y= litem->y;
|
||||
|
||||
for(item=litem->items.first; item; item=item->next) {
|
||||
ui_item_size(item, &itemw, &itemh);
|
||||
ui_item_position(item, x, y-itemh, litem->w, itemh);
|
||||
|
||||
litem->h= MAX2(litem->h, itemh);
|
||||
}
|
||||
|
||||
litem->x= x;
|
||||
litem->y= y - litem->h;
|
||||
}
|
||||
|
||||
/* layout create functions */
|
||||
uiLayout *uiLayoutRow(uiLayout *layout, int align)
|
||||
{
|
||||
|
@ -1921,7 +1965,7 @@ uiLayout *uiLayoutColumnFlow(uiLayout *layout, int number, int align)
|
|||
return &flow->litem;
|
||||
}
|
||||
|
||||
static uiLayout *ui_layout_box(uiLayout *layout, int type)
|
||||
static uiLayoutItemBx *ui_layout_box(uiLayout *layout, int type)
|
||||
{
|
||||
uiLayoutItemBx *box;
|
||||
|
||||
|
@ -1938,30 +1982,32 @@ static uiLayout *ui_layout_box(uiLayout *layout, int type)
|
|||
|
||||
box->roundbox= uiDefBut(layout->root->block, type, 0, "", 0, 0, 0, 0, NULL, 0.0, 0.0, 0, 0, "");
|
||||
|
||||
return &box->litem;
|
||||
return box;
|
||||
}
|
||||
|
||||
uiLayout *uiLayoutBox(uiLayout *layout)
|
||||
{
|
||||
return ui_layout_box(layout, ROUNDBOX);
|
||||
return (uiLayout*)ui_layout_box(layout, ROUNDBOX);
|
||||
}
|
||||
|
||||
uiLayout *uiLayoutListBox(uiLayout *layout)
|
||||
uiLayout *uiLayoutListBox(uiLayout *layout, PointerRNA *ptr, PropertyRNA *prop, PointerRNA *actptr, PropertyRNA *actprop)
|
||||
{
|
||||
return ui_layout_box(layout, LISTBOX);
|
||||
uiLayoutItemBx *box= ui_layout_box(layout, LISTBOX);
|
||||
uiBut *but= box->roundbox;
|
||||
|
||||
but->rnasearchpoin= *ptr;
|
||||
but->rnasearchprop= prop;
|
||||
but->rnapoin= *actptr;
|
||||
but->rnaprop= actprop;
|
||||
|
||||
return (uiLayout*)box;
|
||||
}
|
||||
|
||||
ListBase *uiLayoutBoxGetList(uiLayout *layout)
|
||||
{
|
||||
uiLayoutItemBx *box= (uiLayoutItemBx*)layout;
|
||||
return &box->items;
|
||||
}
|
||||
|
||||
uiLayout *uiLayoutFree(uiLayout *layout, int align)
|
||||
uiLayout *uiLayoutAbsolute(uiLayout *layout, int align)
|
||||
{
|
||||
uiLayout *litem;
|
||||
|
||||
litem= MEM_callocN(sizeof(uiLayout), "uiLayoutFree");
|
||||
litem= MEM_callocN(sizeof(uiLayout), "uiLayoutAbsolute");
|
||||
litem->item.type= ITEM_LAYOUT_ABSOLUTE;
|
||||
litem->root= layout->root;
|
||||
litem->align= align;
|
||||
|
@ -1980,11 +2026,28 @@ uiBlock *uiLayoutAbsoluteBlock(uiLayout *layout)
|
|||
uiBlock *block;
|
||||
|
||||
block= uiLayoutGetBlock(layout);
|
||||
uiLayoutFree(layout, 0);
|
||||
uiLayoutAbsolute(layout, 0);
|
||||
|
||||
return block;
|
||||
}
|
||||
|
||||
uiLayout *uiLayoutOverlap(uiLayout *layout)
|
||||
{
|
||||
uiLayout *litem;
|
||||
|
||||
litem= MEM_callocN(sizeof(uiLayout), "uiLayoutOverlap");
|
||||
litem->item.type= ITEM_LAYOUT_OVERLAP;
|
||||
litem->root= layout->root;
|
||||
litem->active= 1;
|
||||
litem->enabled= 1;
|
||||
litem->context= layout->context;
|
||||
BLI_addtail(&layout->items, litem);
|
||||
|
||||
uiBlockSetCurLayout(layout->root->block, litem);
|
||||
|
||||
return litem;
|
||||
}
|
||||
|
||||
uiLayout *uiLayoutSplit(uiLayout *layout, float percentage)
|
||||
{
|
||||
uiLayoutItemSplt *split;
|
||||
|
@ -2142,6 +2205,9 @@ static void ui_item_estimate(uiItem *item)
|
|||
case ITEM_LAYOUT_SPLIT:
|
||||
ui_litem_estimate_split(litem);
|
||||
break;
|
||||
case ITEM_LAYOUT_OVERLAP:
|
||||
ui_litem_estimate_overlap(litem);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -2162,6 +2228,7 @@ static void ui_item_align(uiLayout *litem, int nr)
|
|||
bitem->but->alignnr= nr;
|
||||
}
|
||||
else if(item->type == ITEM_LAYOUT_ABSOLUTE);
|
||||
else if(item->type == ITEM_LAYOUT_OVERLAP);
|
||||
else if(item->type == ITEM_LAYOUT_BOX) {
|
||||
box= (uiLayoutItemBx*)item;
|
||||
box->roundbox->alignnr= nr;
|
||||
|
@ -2227,6 +2294,9 @@ static void ui_item_layout(uiItem *item)
|
|||
case ITEM_LAYOUT_SPLIT:
|
||||
ui_litem_layout_split(litem);
|
||||
break;
|
||||
case ITEM_LAYOUT_OVERLAP:
|
||||
ui_litem_layout_overlap(litem);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -2261,9 +2331,6 @@ static void ui_layout_free(uiLayout *layout)
|
|||
ui_layout_free((uiLayout*)item);
|
||||
}
|
||||
|
||||
if(layout->item.type == ITEM_LAYOUT_BOX)
|
||||
BLI_freelistN(&((uiLayoutItemBx*)layout)->items);
|
||||
|
||||
MEM_freeN(layout);
|
||||
}
|
||||
|
||||
|
|
|
@ -309,20 +309,6 @@ void uiPanelToMouse(const bContext *C, Panel *pa)
|
|||
}
|
||||
#endif
|
||||
|
||||
static int panel_has_tabs(ARegion *ar, Panel *panel)
|
||||
{
|
||||
Panel *pa= ar->panels.first;
|
||||
|
||||
if(panel==NULL) return 0;
|
||||
|
||||
while(pa) {
|
||||
if((pa->runtime_flag & PNL_ACTIVE) && pa->paneltab==panel) {
|
||||
return 1;
|
||||
}
|
||||
pa= pa->next;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ui_offset_panel_block(uiBlock *block)
|
||||
{
|
||||
|
@ -465,62 +451,32 @@ static void ui_draw_panel_dragwidget(rctf *rect)
|
|||
}
|
||||
|
||||
|
||||
static void ui_draw_aligned_panel_header(ARegion *ar, uiStyle *style, uiBlock *block, rcti *rect)
|
||||
static void ui_draw_aligned_panel_header(ARegion *ar, uiStyle *style, uiBlock *block, rcti *rect, char dir)
|
||||
{
|
||||
Panel *panel= block->panel;
|
||||
Panel *pa;
|
||||
rcti hrect;
|
||||
float width;
|
||||
int a, nr= 1, pnl_icons;
|
||||
int pnl_icons;
|
||||
char *activename= panel->drawname[0]?panel->drawname:panel->panelname;
|
||||
char *panelname;
|
||||
|
||||
/* count */
|
||||
for(pa= ar->panels.first; pa; pa=pa->next)
|
||||
if(pa->runtime_flag & PNL_ACTIVE)
|
||||
if(pa->paneltab==panel)
|
||||
nr++;
|
||||
|
||||
/* + 0.001f to avoid flirting with float inaccuracy */
|
||||
if(panel->control & UI_PNL_CLOSE) pnl_icons=(panel->labelofs+2*PNL_ICON+5)/block->aspect + 0.001f;
|
||||
else pnl_icons= (panel->labelofs+PNL_ICON+5)/block->aspect + 0.001f;
|
||||
|
||||
if(nr==1) {
|
||||
|
||||
/* active tab */
|
||||
/* draw text label */
|
||||
UI_ThemeColor(TH_TITLE);
|
||||
|
||||
hrect= *rect;
|
||||
/* active tab */
|
||||
/* draw text label */
|
||||
UI_ThemeColor(TH_TITLE);
|
||||
|
||||
hrect= *rect;
|
||||
if(dir == 'h') {
|
||||
hrect.xmin= rect->xmin+pnl_icons;
|
||||
uiStyleFontDraw(&style->paneltitle, &hrect, activename);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
a= 0;
|
||||
width= (rect->xmax-rect->xmin - 3 - pnl_icons - PNL_ICON)/nr;
|
||||
for(pa= ar->panels.first; pa; pa=pa->next) {
|
||||
panelname= pa->drawname[0]?pa->drawname:pa->panelname;
|
||||
|
||||
if((pa->runtime_flag & PNL_ACTIVE) && (pa==panel || pa->paneltab==panel)) {
|
||||
float col[3];
|
||||
|
||||
UI_GetThemeColor3fv(TH_TITLE, col);
|
||||
|
||||
/* active tab */
|
||||
if(pa==panel)
|
||||
glColor4f(col[0], col[1], col[2], 1.0f);
|
||||
else
|
||||
glColor4f(col[0], col[1], col[2], 0.5f);
|
||||
|
||||
hrect= *rect;
|
||||
hrect.xmin= rect->xmin+pnl_icons + a*width;
|
||||
hrect.xmax= hrect.xmin + width;
|
||||
uiStyleFontDraw(&style->paneltitle, &hrect, panelname);
|
||||
|
||||
a++;
|
||||
}
|
||||
else {
|
||||
/* ignore 'pnl_icons', otherwise the text gets offset horizontally
|
||||
* + 0.001f to avoid flirting with float inaccuracy
|
||||
*/
|
||||
hrect.xmin= rect->xmin + (PNL_ICON+5)/block->aspect + 0.001f;
|
||||
uiStyleFontDrawRotated(&style->paneltitle, &hrect, activename);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -567,9 +523,9 @@ void ui_draw_aligned_panel(ARegion *ar, uiStyle *style, uiBlock *block, rcti *re
|
|||
glDisable(GL_BLEND);
|
||||
}
|
||||
|
||||
/* title */
|
||||
/* horizontal title */
|
||||
if(!(panel->flag & PNL_CLOSEDX)) {
|
||||
ui_draw_aligned_panel_header(ar, style, block, &headrect);
|
||||
ui_draw_aligned_panel_header(ar, style, block, &headrect, 'h');
|
||||
|
||||
/* itemrect smaller */
|
||||
itemrect.xmax= headrect.xmax - 5.0f/block->aspect;
|
||||
|
@ -585,16 +541,10 @@ void ui_draw_aligned_panel(ARegion *ar, uiStyle *style, uiBlock *block, rcti *re
|
|||
*/
|
||||
if(panel->flag & PNL_CLOSEDY) {
|
||||
|
||||
|
||||
/* if it's being overlapped by a panel being dragged */
|
||||
if(panel->flag & PNL_OVERLAP) {
|
||||
UI_ThemeColor(TH_TEXT_HI);
|
||||
uiRoundRect(rect->xmin, rect->ymax, rect->xmax, rect->ymax+PNL_HEADER, 8);
|
||||
}
|
||||
|
||||
}
|
||||
else if(panel->flag & PNL_CLOSEDX) {
|
||||
|
||||
/* draw vertical title */
|
||||
ui_draw_aligned_panel_header(ar, style, block, &headrect, 'v');
|
||||
}
|
||||
/* an open panel */
|
||||
else {
|
||||
|
@ -607,13 +557,6 @@ void ui_draw_aligned_panel(ARegion *ar, uiStyle *style, uiBlock *block, rcti *re
|
|||
UI_ThemeColorShade(TH_BACK, -120);
|
||||
uiRoundRect(0.5f + rect->xmin, 0.5f + rect->ymin, 0.5f + rect->xmax, 0.5f + headrect.ymax+1, 8);
|
||||
}
|
||||
if(panel->flag & PNL_OVERLAP) {
|
||||
if(panel->control & UI_PNL_SOLID) uiSetRoundBox(15);
|
||||
else uiSetRoundBox(3);
|
||||
|
||||
UI_ThemeColor(TH_TEXT_HI);
|
||||
uiRoundRect(rect->xmin, rect->ymin, rect->xmax, headrect.ymax+1, 8);
|
||||
}
|
||||
|
||||
if(panel->control & UI_PNL_SCALE)
|
||||
ui_draw_panel_scalewidget(rect);
|
||||
|
@ -963,62 +906,6 @@ static void check_panel_overlap(ARegion *ar, Panel *panel)
|
|||
}
|
||||
}
|
||||
|
||||
#if 0 // XXX panel docking/tabbing code that's no longer used
|
||||
static void test_add_new_tabs(ARegion *ar)
|
||||
{
|
||||
Panel *pa, *pasel=NULL, *palap=NULL;
|
||||
/* search selected and overlapped panel */
|
||||
|
||||
pa= ar->panels.first;
|
||||
while(pa) {
|
||||
if(pa->runtime_flag & PNL_ACTIVE) {
|
||||
if(pa->flag & PNL_SELECT) pasel= pa;
|
||||
if(pa->flag & PNL_OVERLAP) palap= pa;
|
||||
}
|
||||
pa= pa->next;
|
||||
}
|
||||
|
||||
if(pasel && palap==NULL) {
|
||||
|
||||
/* copy locations */
|
||||
pa= ar->panels.first;
|
||||
while(pa) {
|
||||
if(pa->paneltab==pasel) {
|
||||
ui_panel_copy_offset(pa, pasel);
|
||||
}
|
||||
pa= pa->next;
|
||||
}
|
||||
}
|
||||
|
||||
if(pasel==NULL || palap==NULL) return;
|
||||
if(palap->type && palap->type->flag & PNL_NO_HEADER) return;
|
||||
|
||||
/* the overlapped panel becomes a tab */
|
||||
palap->paneltab= pasel;
|
||||
|
||||
/* the selected panel gets coords of overlapped one */
|
||||
ui_panel_copy_offset(pasel, palap);
|
||||
|
||||
/* and its tabs */
|
||||
pa= ar->panels.first;
|
||||
while(pa) {
|
||||
if(pa->paneltab == pasel) {
|
||||
ui_panel_copy_offset(pa, palap);
|
||||
}
|
||||
pa= pa->next;
|
||||
}
|
||||
|
||||
/* but, the overlapped panel already can have tabs too! */
|
||||
pa= ar->panels.first;
|
||||
while(pa) {
|
||||
if(pa->paneltab == palap) {
|
||||
pa->paneltab = pasel;
|
||||
}
|
||||
pa= pa->next;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/************************ panel dragging ****************************/
|
||||
|
||||
static void ui_do_drag(const bContext *C, wmEvent *event, Panel *panel)
|
||||
|
@ -1061,99 +948,8 @@ static void ui_do_drag(const bContext *C, wmEvent *event, Panel *panel)
|
|||
ED_region_tag_redraw(ar);
|
||||
}
|
||||
|
||||
static void ui_do_untab(const bContext *C, wmEvent *event, Panel *panel)
|
||||
{
|
||||
uiHandlePanelData *data= panel->activedata;
|
||||
ARegion *ar= CTX_wm_region(C);
|
||||
Panel *pa, *panew= NULL;
|
||||
int nr;
|
||||
|
||||
/* wait until a threshold is passed to untab */
|
||||
if(abs(event->x-data->startx) + abs(event->y-data->starty) > 6) {
|
||||
/* find new parent panel */
|
||||
nr= 0;
|
||||
for(pa= ar->panels.first; pa; pa=pa->next) {
|
||||
if(pa->paneltab==panel) {
|
||||
panew= pa;
|
||||
nr++;
|
||||
}
|
||||
}
|
||||
|
||||
/* make old tabs point to panew */
|
||||
panew->paneltab= NULL;
|
||||
|
||||
for(pa= ar->panels.first; pa; pa=pa->next)
|
||||
if(pa->paneltab==panel)
|
||||
pa->paneltab= panew;
|
||||
|
||||
panel_activate_state(C, panel, PANEL_STATE_DRAG);
|
||||
}
|
||||
}
|
||||
|
||||
/******************* region level panel interaction *****************/
|
||||
|
||||
static void panel_clicked_tabs(const bContext *C, ScrArea *sa, ARegion *ar, uiBlock *block, int mousex)
|
||||
{
|
||||
Panel *pa, *tabsel=NULL, *panel= block->panel;
|
||||
int nr= 1, a, width, ofsx;
|
||||
|
||||
ofsx= PNL_ICON;
|
||||
if(block->panel->type && (block->panel->control & UI_PNL_CLOSE)) ofsx+= PNL_ICON;
|
||||
|
||||
/* count */
|
||||
for(pa= ar->panels.first; pa; pa=pa->next)
|
||||
if(pa!=panel)
|
||||
if((pa->runtime_flag & PNL_ACTIVE) && pa->paneltab==panel)
|
||||
nr++;
|
||||
|
||||
if(nr==1) return;
|
||||
|
||||
/* find clicked tab, mouse in panel coords */
|
||||
a= 0;
|
||||
width= (int)((float)(panel->sizex - ofsx-10)/nr);
|
||||
pa= ar->panels.first;
|
||||
while(pa) {
|
||||
if(pa==panel || ((pa->runtime_flag & PNL_ACTIVE) && pa->paneltab==panel)) {
|
||||
if((mousex > ofsx+a*width) && (mousex < ofsx+(a+1)*width)) {
|
||||
tabsel= pa;
|
||||
break;
|
||||
}
|
||||
a++;
|
||||
}
|
||||
pa= pa->next;
|
||||
}
|
||||
|
||||
if(tabsel) {
|
||||
if(tabsel == panel) {
|
||||
panel_activate_state(C, panel, PANEL_STATE_WAIT_UNTAB);
|
||||
}
|
||||
else {
|
||||
/* tabsel now becomes parent for all others */
|
||||
panel->paneltab= tabsel;
|
||||
tabsel->paneltab= NULL;
|
||||
|
||||
pa= ar->panels.first;
|
||||
while(pa) {
|
||||
if(pa->paneltab == panel) pa->paneltab = tabsel;
|
||||
pa= pa->next;
|
||||
}
|
||||
|
||||
/* copy locations to tabs */
|
||||
for(pa= ar->panels.first; pa; pa= pa->next) {
|
||||
if(pa->paneltab && pa->runtime_flag & PNL_ACTIVE) {
|
||||
ui_panel_copy_offset(pa, pa->paneltab);
|
||||
}
|
||||
}
|
||||
|
||||
/* panels now differ size.. */
|
||||
if(panel_aligned(sa, ar))
|
||||
panel_activate_state(C, tabsel, PANEL_STATE_ANIMATION);
|
||||
|
||||
ED_region_tag_redraw(ar);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* this function is supposed to call general window drawing too */
|
||||
/* also it supposes a block has panel, and isnt a menu */
|
||||
|
@ -1217,10 +1013,6 @@ static void ui_handle_panel_header(const bContext *C, uiBlock *block, int mx, in
|
|||
else if(block->panel->flag & PNL_CLOSED) {
|
||||
panel_activate_state(C, block->panel, PANEL_STATE_DRAG);
|
||||
}
|
||||
/* check if clicked in tabbed area */
|
||||
else if(mx < block->maxx-PNL_ICON-3 && panel_has_tabs(ar, block->panel)) {
|
||||
panel_clicked_tabs(C, sa, ar, block, mx);
|
||||
}
|
||||
else {
|
||||
panel_activate_state(C, block->panel, PANEL_STATE_DRAG);
|
||||
}
|
||||
|
@ -1346,9 +1138,7 @@ static int ui_handler_panel(bContext *C, wmEvent *event, void *userdata)
|
|||
panel_activate_state(C, panel, PANEL_STATE_EXIT);
|
||||
}
|
||||
else if(event->type == MOUSEMOVE) {
|
||||
if(data->state == PANEL_STATE_WAIT_UNTAB)
|
||||
ui_do_untab(C, event, panel);
|
||||
else if(data->state == PANEL_STATE_DRAG)
|
||||
if(data->state == PANEL_STATE_DRAG)
|
||||
ui_do_drag(C, event, panel);
|
||||
}
|
||||
else if(event->type == TIMER && event->customdata == data->animtimer) {
|
||||
|
@ -1399,7 +1189,7 @@ static void panel_activate_state(const bContext *C, Panel *pa, uiHandlePanelStat
|
|||
pa->flag |= PNL_SELECT;
|
||||
|
||||
if(data && data->animtimer) {
|
||||
WM_event_remove_window_timer(win, data->animtimer);
|
||||
WM_event_remove_timer(CTX_wm_manager(C), win, data->animtimer);
|
||||
data->animtimer= NULL;
|
||||
}
|
||||
|
||||
|
@ -1418,7 +1208,7 @@ static void panel_activate_state(const bContext *C, Panel *pa, uiHandlePanelStat
|
|||
}
|
||||
|
||||
if(ELEM(state, PANEL_STATE_ANIMATION, PANEL_STATE_DRAG))
|
||||
data->animtimer= WM_event_add_window_timer(win, TIMER, ANIMATION_INTERVAL);
|
||||
data->animtimer= WM_event_add_timer(CTX_wm_manager(C), win, TIMER, ANIMATION_INTERVAL);
|
||||
|
||||
data->state= state;
|
||||
data->startx= win->eventstate->x;
|
||||
|
|
|
@ -357,6 +357,9 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but)
|
|||
float x1f, x2f, y1f, y2f;
|
||||
int x1, x2, y1, y2, winx, winy, ofsx, ofsy, w, h, a;
|
||||
|
||||
if(but->flag & UI_BUT_NO_TOOLTIP)
|
||||
return NULL;
|
||||
|
||||
/* create tooltip data */
|
||||
data= MEM_callocN(sizeof(uiTooltipData), "uiTooltipData");
|
||||
|
||||
|
|
|
@ -184,6 +184,60 @@ void uiStyleFontDraw(uiFontStyle *fs, rcti *rect, char *str)
|
|||
BLF_disable(BLF_KERNING_DEFAULT);
|
||||
}
|
||||
|
||||
/* drawn same as above, but at 90 degree angle */
|
||||
void uiStyleFontDrawRotated(uiFontStyle *fs, rcti *rect, char *str)
|
||||
{
|
||||
float height;
|
||||
int xofs, yofs;
|
||||
float angle;
|
||||
rcti txtrect;
|
||||
|
||||
uiStyleFontSet(fs);
|
||||
|
||||
height= BLF_height("2"); /* correct offset is on baseline, the j is below that */
|
||||
/* becomes x-offset when rotated */
|
||||
xofs= floor( 0.5f*(rect->ymax - rect->ymin - height)) + 1;
|
||||
|
||||
/* ignore UI_STYLE, always aligned to top */
|
||||
|
||||
/* rotate counter-clockwise for now (assumes left-to-right language)*/
|
||||
xofs+= height;
|
||||
yofs= BLF_width(str) + 5;
|
||||
angle= 90.0f;
|
||||
|
||||
/* translate rect to vertical */
|
||||
txtrect.xmin= rect->xmin - (rect->ymax - rect->ymin);
|
||||
txtrect.ymin= rect->ymin - (rect->xmax - rect->xmin);
|
||||
txtrect.xmax= rect->xmin;
|
||||
txtrect.ymax= rect->ymin;
|
||||
|
||||
/* clip is very strict, so we give it some space */
|
||||
/* clipping is done without rotation, so make rect big enough to contain both positions */
|
||||
BLF_clipping(txtrect.xmin-1, txtrect.ymin-yofs-xofs-4, rect->xmax+1, rect->ymax+4);
|
||||
BLF_enable(BLF_CLIPPING);
|
||||
BLF_position(txtrect.xmin+xofs, txtrect.ymax-yofs, 0.0f);
|
||||
|
||||
BLF_enable(BLF_ROTATION);
|
||||
BLF_rotation(angle);
|
||||
|
||||
if (fs->shadow) {
|
||||
BLF_enable(BLF_SHADOW);
|
||||
BLF_shadow(fs->shadow, fs->shadowcolor, fs->shadowcolor, fs->shadowcolor, fs->shadowalpha);
|
||||
BLF_shadow_offset(fs->shadx, fs->shady);
|
||||
}
|
||||
|
||||
if (fs->kerning == 1)
|
||||
BLF_enable(BLF_KERNING_DEFAULT);
|
||||
|
||||
BLF_draw(str);
|
||||
BLF_disable(BLF_ROTATION);
|
||||
BLF_disable(BLF_CLIPPING);
|
||||
if (fs->shadow)
|
||||
BLF_disable(BLF_SHADOW);
|
||||
if (fs->kerning == 1)
|
||||
BLF_disable(BLF_KERNING_DEFAULT);
|
||||
}
|
||||
|
||||
/* ************** helpers ************************ */
|
||||
|
||||
/* temporarily, does widget font */
|
||||
|
|
|
@ -506,7 +506,7 @@ static void modifiers_setOnCage(bContext *C, void *ob_v, void *md_v)
|
|||
{
|
||||
Object *ob = ob_v;
|
||||
ModifierData *md= md_v;
|
||||
int i, cageIndex = modifiers_getCageIndex(ob, NULL );
|
||||
int i, cageIndex = modifiers_getCageIndex(ob, NULL, 0);
|
||||
|
||||
/* undo button operation */
|
||||
md->mode ^= eModifierMode_OnCage;
|
||||
|
@ -715,7 +715,7 @@ uiLayout *uiTemplateModifier(uiLayout *layout, PointerRNA *ptr)
|
|||
uiBlockSetButLock(uiLayoutGetBlock(layout), (ob && ob->id.lib), ERROR_LIBDATA_MESSAGE);
|
||||
|
||||
/* find modifier and draw it */
|
||||
cageIndex = modifiers_getCageIndex(ob, &lastCageIndex);
|
||||
cageIndex = modifiers_getCageIndex(ob, &lastCageIndex, 0);
|
||||
|
||||
// XXX virtual modifiers are not accesible for python
|
||||
vmd = modifiers_getVirtualModifierList(ob);
|
||||
|
@ -1925,25 +1925,6 @@ void uiTemplateLayers(uiLayout *layout, PointerRNA *ptr, char *propname)
|
|||
|
||||
/************************* List Template **************************/
|
||||
|
||||
#if 0
|
||||
static void list_item_add(ListBase *lb, ListBase *itemlb, uiLayout *layout, PointerRNA *data)
|
||||
{
|
||||
CollectionPointerLink *link;
|
||||
uiListItem *item;
|
||||
|
||||
/* add to list to store in box */
|
||||
item= MEM_callocN(sizeof(uiListItem), "uiListItem");
|
||||
item->layout= layout;
|
||||
item->data= *data;
|
||||
BLI_addtail(itemlb, item);
|
||||
|
||||
/* add to list to return from function */
|
||||
link= MEM_callocN(sizeof(CollectionPointerLink), "uiTemplateList return");
|
||||
RNA_pointer_create(NULL, &RNA_UIListItem, item, &link->ptr);
|
||||
BLI_addtail(lb, link);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int list_item_icon_get(bContext *C, PointerRNA *itemptr, int rnaicon)
|
||||
{
|
||||
ID *id= NULL;
|
||||
|
@ -1974,60 +1955,126 @@ static int list_item_icon_get(bContext *C, PointerRNA *itemptr, int rnaicon)
|
|||
return rnaicon;
|
||||
}
|
||||
|
||||
ListBase uiTemplateList(uiLayout *layout, bContext *C, PointerRNA *ptr, char *propname, PointerRNA *activeptr, char *activepropname, int rows, int listtype)
|
||||
static void list_item_row(bContext *C, uiLayout *layout, PointerRNA *ptr, PointerRNA *itemptr, int i, int rnaicon, PointerRNA *activeptr, char *activepropname)
|
||||
{
|
||||
Object *ob;
|
||||
uiBlock *block= uiLayoutGetBlock(layout);
|
||||
uiBut *but;
|
||||
uiLayout *split, *overlap, *sub, *row;
|
||||
char *name, *namebuf;
|
||||
int icon;
|
||||
|
||||
overlap= uiLayoutOverlap(layout);
|
||||
|
||||
/* list item behind label & other buttons */
|
||||
sub= uiLayoutRow(overlap, 0);
|
||||
|
||||
if(itemptr->type == &RNA_ShapeKey) {
|
||||
ob= (Object*)activeptr->data;
|
||||
if(ob->mode == OB_MODE_EDIT && !(ob->type == OB_MESH))
|
||||
uiLayoutSetEnabled(sub, 0);
|
||||
}
|
||||
|
||||
but= uiDefButR(block, LISTROW, 0, "", 0,0, UI_UNIT_X*10,UI_UNIT_Y, activeptr, activepropname, 0, 0, i, 0, 0, "");
|
||||
uiButSetFlag(but, UI_BUT_NO_TOOLTIP);
|
||||
|
||||
sub= uiLayoutRow(overlap, 0);
|
||||
|
||||
/* retrieve icon and name */
|
||||
icon= list_item_icon_get(C, itemptr, rnaicon);
|
||||
if(!icon || icon == ICON_DOT)
|
||||
icon= 0;
|
||||
|
||||
namebuf= RNA_struct_name_get_alloc(itemptr, NULL, 0);
|
||||
name= (namebuf)? namebuf: "";
|
||||
|
||||
/* hardcoded types */
|
||||
uiBlockSetEmboss(block, UI_EMBOSSN);
|
||||
|
||||
if(itemptr->type == &RNA_MeshTextureFaceLayer || itemptr->type == &RNA_MeshColorLayer) {
|
||||
uiItemL(sub, name, icon);
|
||||
uiDefIconButR(block, TOG, 0, ICON_SCENE, 0, 0, UI_UNIT_X, UI_UNIT_Y, itemptr, "active_render", 0, 0, 0, 0, 0, NULL);
|
||||
}
|
||||
else if(itemptr->type == &RNA_MaterialTextureSlot) {
|
||||
uiItemL(sub, name, icon);
|
||||
uiDefButR(block, OPTION, 0, "", 0, 0, UI_UNIT_X, UI_UNIT_Y, ptr, "use_textures", i, 0, 0, 0, 0, NULL);
|
||||
}
|
||||
else if(itemptr->type == &RNA_ShapeKey) {
|
||||
ob= (Object*)activeptr->data;
|
||||
|
||||
split= uiLayoutSplit(sub, 0.75f);
|
||||
|
||||
uiItemL(split, name, icon);
|
||||
|
||||
row= uiLayoutRow(split, 1);
|
||||
if(i == 0) uiItemL(row, "", 0);
|
||||
else uiItemR(row, "", 0, itemptr, "value", 0);
|
||||
|
||||
if(ob->mode == OB_MODE_EDIT && !((ob->shapeflag & OB_SHAPE_EDIT_MODE) && ob->type == OB_MESH))
|
||||
uiLayoutSetActive(row, 0);
|
||||
//uiItemR(row, "", ICON_MUTE_IPO_OFF, itemptr, "mute", 0);
|
||||
}
|
||||
else
|
||||
uiItemL(sub, name, icon);
|
||||
|
||||
uiBlockSetEmboss(block, UI_EMBOSS);
|
||||
|
||||
/* free name */
|
||||
if(namebuf)
|
||||
MEM_freeN(namebuf);
|
||||
}
|
||||
|
||||
void uiTemplateList(uiLayout *layout, bContext *C, PointerRNA *ptr, char *propname, PointerRNA *activeptr, char *activepropname, int rows, int listtype)
|
||||
{
|
||||
//Scene *scene= CTX_data_scene(C);
|
||||
PropertyRNA *prop= NULL, *activeprop;
|
||||
PropertyType type, activetype;
|
||||
StructRNA *ptype;
|
||||
uiLayout *box, *row, *col, *subrow;
|
||||
uiLayout *box, *row, *col;
|
||||
uiBlock *block;
|
||||
uiBut *but;
|
||||
Panel *pa;
|
||||
ListBase lb, *itemlb;
|
||||
char *name, str[32];
|
||||
int rnaicon=0, icon=0, i= 0, activei= 0, len= 0, items, found, min, max;
|
||||
|
||||
lb.first= lb.last= NULL;
|
||||
|
||||
/* validate arguments */
|
||||
block= uiLayoutGetBlock(layout);
|
||||
pa= block->panel;
|
||||
|
||||
if(!pa) {
|
||||
printf("uiTemplateList: only works inside a panel.\n");
|
||||
return lb;
|
||||
return;
|
||||
}
|
||||
|
||||
if(!activeptr->data)
|
||||
return lb;
|
||||
return;
|
||||
|
||||
if(ptr->data) {
|
||||
prop= RNA_struct_find_property(ptr, propname);
|
||||
if(!prop) {
|
||||
printf("uiTemplateList: property not found: %s\n", propname);
|
||||
return lb;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
activeprop= RNA_struct_find_property(activeptr, activepropname);
|
||||
if(!activeprop) {
|
||||
printf("uiTemplateList: property not found: %s\n", activepropname);
|
||||
return lb;
|
||||
return;
|
||||
}
|
||||
|
||||
if(prop) {
|
||||
type= RNA_property_type(prop);
|
||||
if(type != PROP_COLLECTION) {
|
||||
printf("uiTemplateList: expected collection property.\n");
|
||||
return lb;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
activetype= RNA_property_type(activeprop);
|
||||
if(activetype != PROP_INT) {
|
||||
printf("uiTemplateList: expected integer property.\n");
|
||||
return lb;
|
||||
return;
|
||||
}
|
||||
|
||||
/* get icon */
|
||||
|
@ -2040,12 +2087,10 @@ ListBase uiTemplateList(uiLayout *layout, bContext *C, PointerRNA *ptr, char *pr
|
|||
activei= RNA_property_int_get(activeptr, activeprop);
|
||||
|
||||
if(listtype == 'i') {
|
||||
box= uiLayoutListBox(layout);
|
||||
box= uiLayoutListBox(layout, ptr, prop, activeptr, activeprop);
|
||||
col= uiLayoutColumn(box, 1);
|
||||
row= uiLayoutRow(col, 0);
|
||||
|
||||
itemlb= uiLayoutBoxGetList(box);
|
||||
|
||||
if(ptr->data && prop) {
|
||||
/* create list items */
|
||||
RNA_PROP_BEGIN(ptr, itemptr, prop) {
|
||||
|
@ -2054,9 +2099,8 @@ ListBase uiTemplateList(uiLayout *layout, bContext *C, PointerRNA *ptr, char *pr
|
|||
row= uiLayoutRow(col, 0);
|
||||
|
||||
icon= list_item_icon_get(C, &itemptr, rnaicon);
|
||||
uiDefIconButR(block, LISTROW, 0, icon, 0,0,UI_UNIT_X*10,UI_UNIT_Y, activeptr, activepropname, 0, 0, i, 0, 0, "");
|
||||
|
||||
//list_item_add(&lb, itemlb, uiLayoutRow(row, 1), &itemptr);
|
||||
but= uiDefIconButR(block, LISTROW, 0, icon, 0,0,UI_UNIT_X*10,UI_UNIT_Y, activeptr, activepropname, 0, 0, i, 0, 0, "");
|
||||
uiButSetFlag(but, UI_BUT_NO_TOOLTIP);
|
||||
|
||||
i++;
|
||||
}
|
||||
|
@ -2082,9 +2126,6 @@ ListBase uiTemplateList(uiLayout *layout, bContext *C, PointerRNA *ptr, char *pr
|
|||
|
||||
if(name)
|
||||
MEM_freeN(name);
|
||||
|
||||
/* add to list to return */
|
||||
//list_item_add(&lb, itemlb, uiLayoutRow(row, 1), &itemptr);
|
||||
}
|
||||
|
||||
i++;
|
||||
|
@ -2106,9 +2147,11 @@ ListBase uiTemplateList(uiLayout *layout, bContext *C, PointerRNA *ptr, char *pr
|
|||
/* default rows */
|
||||
if(rows == 0)
|
||||
rows= 5;
|
||||
if(pa->list_grip_size != 0)
|
||||
rows= pa->list_grip_size;
|
||||
|
||||
/* layout */
|
||||
box= uiLayoutListBox(layout);
|
||||
box= uiLayoutListBox(layout, ptr, prop, activeptr, activeprop);
|
||||
row= uiLayoutRow(box, 0);
|
||||
col = uiLayoutColumn(row, 1);
|
||||
|
||||
|
@ -2117,47 +2160,23 @@ ListBase uiTemplateList(uiLayout *layout, bContext *C, PointerRNA *ptr, char *pr
|
|||
|
||||
if(prop)
|
||||
len= RNA_property_collection_length(ptr, prop);
|
||||
items= CLAMPIS(len, rows, 5);
|
||||
items= CLAMPIS(len, rows, MAX2(rows, 5));
|
||||
|
||||
/* if list length changes and active is out of view, scroll to it */
|
||||
if(pa->list_last_len != len)
|
||||
if((activei < pa->list_scroll || activei >= pa->list_scroll+items))
|
||||
pa->list_scroll= activei;
|
||||
|
||||
pa->list_scroll= MIN2(pa->list_scroll, len-items);
|
||||
pa->list_scroll= MAX2(pa->list_scroll, 0);
|
||||
|
||||
itemlb= uiLayoutBoxGetList(box);
|
||||
pa->list_size= items;
|
||||
pa->list_last_len= len;
|
||||
|
||||
if(ptr->data && prop) {
|
||||
/* create list items */
|
||||
RNA_PROP_BEGIN(ptr, itemptr, prop) {
|
||||
if(i >= pa->list_scroll && i<pa->list_scroll+items) {
|
||||
name= RNA_struct_name_get_alloc(&itemptr, NULL, 0);
|
||||
|
||||
subrow= uiLayoutRow(col, 0);
|
||||
|
||||
icon= list_item_icon_get(C, &itemptr, rnaicon);
|
||||
|
||||
/* create button */
|
||||
if(!icon || icon == ICON_DOT)
|
||||
but= uiDefButR(block, LISTROW, 0, (name)? name: "", 0,0,UI_UNIT_X*10,UI_UNIT_Y, activeptr, activepropname, 0, 0, i, 0, 0, "");
|
||||
else
|
||||
but= uiDefIconTextButR(block, LISTROW, 0, icon, (name)? name: "", 0,0,UI_UNIT_X*10,UI_UNIT_Y, activeptr, activepropname, 0, 0, i, 0, 0, "");
|
||||
uiButSetFlag(but, UI_ICON_LEFT|UI_TEXT_LEFT);
|
||||
|
||||
/* XXX hardcoded */
|
||||
if(itemptr.type == &RNA_MeshTextureFaceLayer || itemptr.type == &RNA_MeshColorLayer) {
|
||||
uiBlockSetEmboss(block, UI_EMBOSSN);
|
||||
uiDefIconButR(block, TOG, 0, ICON_SCENE, 0, 0, UI_UNIT_X, UI_UNIT_Y, &itemptr, "active_render", 0, 0, 0, 0, 0, NULL);
|
||||
uiBlockSetEmboss(block, UI_EMBOSS);
|
||||
}
|
||||
else if (itemptr.type == &RNA_MaterialTextureSlot) {
|
||||
uiDefButR(block, OPTION, 0, "", 0, 0, UI_UNIT_X, UI_UNIT_Y, ptr, "use_textures", i, 0, 0, 0, 0, NULL);
|
||||
}
|
||||
/* XXX - end hardcoded cruft */
|
||||
|
||||
if(name)
|
||||
MEM_freeN(name);
|
||||
|
||||
/* add to list to return */
|
||||
//list_item_add(&lb, itemlb, subrow, &itemptr);
|
||||
}
|
||||
if(i >= pa->list_scroll && i<pa->list_scroll+items)
|
||||
list_item_row(C, col, ptr, &itemptr, i, rnaicon, activeptr, activepropname);
|
||||
|
||||
i++;
|
||||
}
|
||||
|
@ -2177,9 +2196,6 @@ ListBase uiTemplateList(uiLayout *layout, bContext *C, PointerRNA *ptr, char *pr
|
|||
uiDefButI(block, SCROLL, 0, "", 0,0,UI_UNIT_X*0.75,UI_UNIT_Y*items, &pa->list_scroll, 0, len-items, items, 0, "");
|
||||
}
|
||||
}
|
||||
|
||||
/* return items in list */
|
||||
return lb;
|
||||
}
|
||||
|
||||
/************************* Operator Search Template **************************/
|
||||
|
|
|
@ -255,12 +255,14 @@ void EDBM_MakeEditBMesh(ToolSettings *ts, Scene *scene, Object *ob)
|
|||
BMesh *bm;
|
||||
|
||||
if (!me->mpoly && me->totface) {
|
||||
printf("yeek!! bmesh conversion issue! may lose shapekeys!\n");
|
||||
|
||||
em = make_editMesh(scene, ob);
|
||||
bm = editmesh_to_bmesh(em);
|
||||
|
||||
free_editMesh(em);
|
||||
} else {
|
||||
bm = BKE_mesh_to_bmesh(me);
|
||||
bm = BKE_mesh_to_bmesh(me, ob);
|
||||
}
|
||||
|
||||
me->edit_btmesh = BMEdit_Create(bm);
|
||||
|
|
|
@ -60,6 +60,7 @@
|
|||
#include "BKE_texture.h"
|
||||
#include "BKE_utildefines.h"
|
||||
#include "BKE_customdata.h"
|
||||
#include "BKE_context.h"
|
||||
|
||||
#include "BIF_gl.h"
|
||||
#include "BIF_glutil.h"
|
||||
|
@ -72,6 +73,7 @@
|
|||
#endif
|
||||
|
||||
#include "ED_mesh.h"
|
||||
#include "ED_screen.h"
|
||||
#include "ED_object.h"
|
||||
#include "ED_view3d.h"
|
||||
|
||||
|
@ -82,9 +84,6 @@
|
|||
#include "mesh_intern.h"
|
||||
|
||||
/* ***************** XXX **************** */
|
||||
static int sample_backbuf_rect() {return 0;}
|
||||
static int sample_backbuf() {return 0;}
|
||||
static void error() {}
|
||||
static int pupmenu() {return 0;}
|
||||
/* ***************** XXX **************** */
|
||||
|
||||
|
@ -118,25 +117,30 @@ void object_facesel_flush_dm(Object *ob)
|
|||
}
|
||||
|
||||
/* returns 0 if not found, otherwise 1 */
|
||||
int facesel_face_pick(View3D *v3d, Mesh *me, short *mval, unsigned int *index, short rect)
|
||||
int facesel_face_pick(struct bContext *C, Mesh *me, short *mval, unsigned int *index, short rect)
|
||||
{
|
||||
ViewContext vc;
|
||||
view3d_set_viewcontext(C, &vc);
|
||||
|
||||
if (!me || me->totface==0)
|
||||
return 0;
|
||||
|
||||
if (v3d->flag & V3D_NEEDBACKBUFDRAW) {
|
||||
// XXX if (v3d->flag & V3D_NEEDBACKBUFDRAW) {
|
||||
// XXX drawview.c! check_backbuf();
|
||||
// XXX persp(PERSP_VIEW);
|
||||
}
|
||||
// XXX }
|
||||
|
||||
if (rect) {
|
||||
/* sample rect to increase changes of selecting, so that when clicking
|
||||
on an edge in the backbuf, we can still select a face */
|
||||
|
||||
int dist;
|
||||
*index = sample_backbuf_rect(mval, 3, 1, me->totface+1, &dist,0,NULL);
|
||||
*index = view3d_sample_backbuf_rect(&vc, mval, 3, 1, me->totface+1, &dist,0,NULL, NULL);
|
||||
}
|
||||
else
|
||||
else {
|
||||
/* sample only on the exact position */
|
||||
*index = sample_backbuf(mval[0], mval[1]);
|
||||
*index = view3d_sample_backbuf(&vc, mval[0], mval[1]);
|
||||
}
|
||||
|
||||
if ((*index)<=0 || (*index)>(unsigned int)me->totface)
|
||||
return 0;
|
||||
|
@ -231,35 +235,156 @@ void hide_tface(Scene *scene)
|
|||
// XXX notifier! object_tface_flags_changed(OBACT, 0);
|
||||
}
|
||||
|
||||
void select_linked_tfaces(Scene *scene, View3D *v3d, int mode)
|
||||
/* Set tface seams based on edge data, uses hash table to find seam edges. */
|
||||
|
||||
static void hash_add_face(EdgeHash *ehash, MFace *mf)
|
||||
{
|
||||
BLI_edgehash_insert(ehash, mf->v1, mf->v2, NULL);
|
||||
BLI_edgehash_insert(ehash, mf->v2, mf->v3, NULL);
|
||||
if(mf->v4) {
|
||||
BLI_edgehash_insert(ehash, mf->v3, mf->v4, NULL);
|
||||
BLI_edgehash_insert(ehash, mf->v4, mf->v1, NULL);
|
||||
}
|
||||
else
|
||||
BLI_edgehash_insert(ehash, mf->v3, mf->v1, NULL);
|
||||
}
|
||||
|
||||
|
||||
void select_linked_tfaces_with_seams(int mode, Mesh *me, unsigned int index)
|
||||
{
|
||||
MFace *mf;
|
||||
int a, doit=1, mark=0;
|
||||
char *linkflag;
|
||||
EdgeHash *ehash, *seamhash;
|
||||
MEdge *med;
|
||||
|
||||
ehash= BLI_edgehash_new();
|
||||
seamhash = BLI_edgehash_new();
|
||||
linkflag= MEM_callocN(sizeof(char)*me->totface, "linkflaguv");
|
||||
|
||||
for(med=me->medge, a=0; a < me->totedge; a++, med++)
|
||||
if(med->flag & ME_SEAM)
|
||||
BLI_edgehash_insert(seamhash, med->v1, med->v2, NULL);
|
||||
|
||||
if (mode==0 || mode==1) {
|
||||
/* only put face under cursor in array */
|
||||
mf= ((MFace*)me->mface) + index;
|
||||
hash_add_face(ehash, mf);
|
||||
linkflag[index]= 1;
|
||||
}
|
||||
else {
|
||||
/* fill array by selection */
|
||||
mf= me->mface;
|
||||
for(a=0; a<me->totface; a++, mf++) {
|
||||
if(mf->flag & ME_HIDE);
|
||||
else if(mf->flag & ME_FACE_SEL) {
|
||||
hash_add_face(ehash, mf);
|
||||
linkflag[a]= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while(doit) {
|
||||
doit= 0;
|
||||
|
||||
/* expand selection */
|
||||
mf= me->mface;
|
||||
for(a=0; a<me->totface; a++, mf++) {
|
||||
if(mf->flag & ME_HIDE)
|
||||
continue;
|
||||
|
||||
if(!linkflag[a]) {
|
||||
mark= 0;
|
||||
|
||||
if(!BLI_edgehash_haskey(seamhash, mf->v1, mf->v2))
|
||||
if(BLI_edgehash_haskey(ehash, mf->v1, mf->v2))
|
||||
mark= 1;
|
||||
if(!BLI_edgehash_haskey(seamhash, mf->v2, mf->v3))
|
||||
if(BLI_edgehash_haskey(ehash, mf->v2, mf->v3))
|
||||
mark= 1;
|
||||
if(mf->v4) {
|
||||
if(!BLI_edgehash_haskey(seamhash, mf->v3, mf->v4))
|
||||
if(BLI_edgehash_haskey(ehash, mf->v3, mf->v4))
|
||||
mark= 1;
|
||||
if(!BLI_edgehash_haskey(seamhash, mf->v4, mf->v1))
|
||||
if(BLI_edgehash_haskey(ehash, mf->v4, mf->v1))
|
||||
mark= 1;
|
||||
}
|
||||
else if(!BLI_edgehash_haskey(seamhash, mf->v3, mf->v1))
|
||||
if(BLI_edgehash_haskey(ehash, mf->v3, mf->v1))
|
||||
mark = 1;
|
||||
|
||||
if(mark) {
|
||||
linkflag[a]= 1;
|
||||
hash_add_face(ehash, mf);
|
||||
doit= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
BLI_edgehash_free(ehash, NULL);
|
||||
BLI_edgehash_free(seamhash, NULL);
|
||||
|
||||
if(mode==0 || mode==2) {
|
||||
for(a=0, mf=me->mface; a<me->totface; a++, mf++)
|
||||
if(linkflag[a])
|
||||
mf->flag |= ME_FACE_SEL;
|
||||
else
|
||||
mf->flag &= ~ME_FACE_SEL;
|
||||
}
|
||||
else if(mode==1) {
|
||||
for(a=0, mf=me->mface; a<me->totface; a++, mf++)
|
||||
if(linkflag[a] && (mf->flag & ME_FACE_SEL))
|
||||
break;
|
||||
|
||||
if (a<me->totface) {
|
||||
for(a=0, mf=me->mface; a<me->totface; a++, mf++)
|
||||
if(linkflag[a])
|
||||
mf->flag &= ~ME_FACE_SEL;
|
||||
}
|
||||
else {
|
||||
for(a=0, mf=me->mface; a<me->totface; a++, mf++)
|
||||
if(linkflag[a])
|
||||
mf->flag |= ME_FACE_SEL;
|
||||
}
|
||||
}
|
||||
|
||||
MEM_freeN(linkflag);
|
||||
|
||||
// BIF_undo_push("Select linked UV face");
|
||||
// object_tface_flags_changed(OBACT, 0);
|
||||
}
|
||||
|
||||
void select_linked_tfaces(bContext *C, Object *ob, short mval[2], int mode)
|
||||
{
|
||||
Object *ob;
|
||||
Mesh *me;
|
||||
short mval[2];
|
||||
unsigned int index=0;
|
||||
|
||||
ob = OBACT;
|
||||
me = get_mesh(ob);
|
||||
if(me==0 || me->totface==0) return;
|
||||
|
||||
if (mode==0 || mode==1) {
|
||||
if (!(ob->lay & v3d->lay))
|
||||
error("The active object is not in this layer");
|
||||
|
||||
// XXX getmouseco_areawin(mval);
|
||||
if (!facesel_face_pick(v3d, me, mval, &index, 1)) return;
|
||||
// XXX - Causes glitches, not sure why
|
||||
/*
|
||||
if (!facesel_face_pick(C, me, mval, &index, 1))
|
||||
return;
|
||||
*/
|
||||
}
|
||||
|
||||
// XXX unwrapper.c select_linked_tfaces_with_seams(mode, me, index);
|
||||
select_linked_tfaces_with_seams(mode, me, index);
|
||||
|
||||
object_facesel_flush_dm(ob);
|
||||
}
|
||||
|
||||
void deselectall_tface(Scene *scene)
|
||||
void deselectall_tface(Object *ob)
|
||||
{
|
||||
Mesh *me;
|
||||
MFace *mface;
|
||||
int a, sel;
|
||||
|
||||
me= get_mesh(OBACT);
|
||||
|
||||
me= get_mesh(ob);
|
||||
if(me==0) return;
|
||||
|
||||
mface= me->mface;
|
||||
|
@ -285,7 +410,7 @@ void deselectall_tface(Scene *scene)
|
|||
mface++;
|
||||
}
|
||||
|
||||
object_facesel_flush_dm(OBACT);
|
||||
object_facesel_flush_dm(ob);
|
||||
// XXX notifier! object_tface_flags_changed(OBACT, 0);
|
||||
}
|
||||
|
||||
|
@ -646,32 +771,25 @@ void seam_mark_clear_tface(Scene *scene, short mode)
|
|||
// XXX notifier! object_tface_flags_changed(OBACT, 1);
|
||||
}
|
||||
|
||||
void face_select(Scene *scene, View3D *v3d)
|
||||
int face_select(struct bContext *C, Object *ob, short mval[2], int extend)
|
||||
{
|
||||
Object *ob;
|
||||
Mesh *me;
|
||||
MFace *mface, *msel;
|
||||
short mval[2];
|
||||
unsigned int a, index;
|
||||
int shift= 0; // XXX
|
||||
|
||||
/* Get the face under the cursor */
|
||||
ob = OBACT;
|
||||
if (!(ob->lay & v3d->lay)) {
|
||||
error("The active object is not in this layer");
|
||||
}
|
||||
me = get_mesh(ob);
|
||||
// XXX getmouseco_areawin(mval);
|
||||
|
||||
if (!facesel_face_pick(v3d, me, mval, &index, 1)) return;
|
||||
if (!facesel_face_pick(C, me, mval, &index, 1))
|
||||
return 0;
|
||||
|
||||
msel= (((MFace*)me->mface)+index);
|
||||
if (msel->flag & ME_HIDE) return;
|
||||
if (msel->flag & ME_HIDE) return 0;
|
||||
|
||||
/* clear flags */
|
||||
mface = me->mface;
|
||||
a = me->totface;
|
||||
if ((shift)==0) {
|
||||
if (!extend) {
|
||||
while (a--) {
|
||||
mface->flag &= ~ME_FACE_SEL;
|
||||
mface++;
|
||||
|
@ -680,7 +798,7 @@ void face_select(Scene *scene, View3D *v3d)
|
|||
|
||||
me->act_face = (int)index;
|
||||
|
||||
if (shift) {
|
||||
if (extend) {
|
||||
if (msel->flag & ME_FACE_SEL)
|
||||
msel->flag &= ~ME_FACE_SEL;
|
||||
else
|
||||
|
@ -690,77 +808,70 @@ void face_select(Scene *scene, View3D *v3d)
|
|||
|
||||
/* image window redraw */
|
||||
|
||||
object_facesel_flush_dm(OBACT);
|
||||
object_facesel_flush_dm(ob);
|
||||
// XXX notifier! object_tface_flags_changed(OBACT, 1);
|
||||
WM_event_add_notifier(C, NC_GEOM|ND_SELECT, ob->data);
|
||||
ED_region_tag_redraw(CTX_wm_region(C)); // XXX - should redraw all 3D views
|
||||
return 1;
|
||||
}
|
||||
|
||||
void face_borderselect(Scene *scene, ScrArea *sa, ARegion *ar)
|
||||
void face_borderselect(struct bContext *C, Object *ob, rcti *rect, int select)
|
||||
{
|
||||
Mesh *me;
|
||||
MFace *mface;
|
||||
rcti rect;
|
||||
struct ImBuf *ibuf;
|
||||
unsigned int *rt;
|
||||
int a, sx, sy, index, val= 0;
|
||||
int a, sx, sy, index;
|
||||
char *selar;
|
||||
|
||||
me= get_mesh(OBACT);
|
||||
ViewContext vc;
|
||||
view3d_set_viewcontext(C, &vc);
|
||||
|
||||
me= get_mesh(ob);
|
||||
if(me==0) return;
|
||||
if(me->totface==0) return;
|
||||
|
||||
// XXX val= get_border(&rect, 3);
|
||||
|
||||
if(val) {
|
||||
/* without this border select often fails */
|
||||
#if 0 /* XXX untested in 2.5 */
|
||||
if (v3d->flag & V3D_NEEDBACKBUFDRAW) {
|
||||
check_backbuf();
|
||||
persp(PERSP_VIEW);
|
||||
}
|
||||
#endif
|
||||
|
||||
selar= MEM_callocN(me->totface+1, "selar");
|
||||
|
||||
sx= (rect.xmax-rect.xmin+1);
|
||||
sy= (rect.ymax-rect.ymin+1);
|
||||
if(sx*sy<=0) return;
|
||||
|
||||
ibuf = IMB_allocImBuf(sx,sy,32,IB_rect,0);
|
||||
rt = ibuf->rect;
|
||||
glReadPixels(rect.xmin+ar->winrct.xmin, rect.ymin+ar->winrct.ymin, sx, sy, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect);
|
||||
if(ENDIAN_ORDER==B_ENDIAN) IMB_convert_rgba_to_abgr(ibuf);
|
||||
selar= MEM_callocN(me->totface+1, "selar");
|
||||
|
||||
a= sx*sy;
|
||||
while(a--) {
|
||||
if(*rt) {
|
||||
index= WM_framebuffer_to_index(*rt);
|
||||
if(index<=me->totface) selar[index]= 1;
|
||||
}
|
||||
rt++;
|
||||
sx= (rect->xmax-rect->xmin+1);
|
||||
sy= (rect->ymax-rect->ymin+1);
|
||||
if(sx*sy<=0) return;
|
||||
|
||||
view3d_validate_backbuf(&vc);
|
||||
|
||||
ibuf = IMB_allocImBuf(sx,sy,32,IB_rect,0);
|
||||
rt = ibuf->rect;
|
||||
glReadPixels(rect->xmin+vc.ar->winrct.xmin, rect->ymin+vc.ar->winrct.ymin, sx, sy, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect);
|
||||
if(ENDIAN_ORDER==B_ENDIAN) IMB_convert_rgba_to_abgr(ibuf);
|
||||
|
||||
a= sx*sy;
|
||||
while(a--) {
|
||||
if(*rt) {
|
||||
index= WM_framebuffer_to_index(*rt);
|
||||
if(index<=me->totface) selar[index]= 1;
|
||||
}
|
||||
|
||||
mface= me->mface;
|
||||
for(a=1; a<=me->totface; a++, mface++) {
|
||||
if(selar[a]) {
|
||||
if(mface->flag & ME_HIDE);
|
||||
else {
|
||||
if(val==LEFTMOUSE) mface->flag |= ME_FACE_SEL;
|
||||
else mface->flag &= ~ME_FACE_SEL;
|
||||
}
|
||||
rt++;
|
||||
}
|
||||
|
||||
mface= me->mface;
|
||||
for(a=1; a<=me->totface; a++, mface++) {
|
||||
if(selar[a]) {
|
||||
if(mface->flag & ME_HIDE);
|
||||
else {
|
||||
if(select) mface->flag |= ME_FACE_SEL;
|
||||
else mface->flag &= ~ME_FACE_SEL;
|
||||
}
|
||||
}
|
||||
|
||||
IMB_freeImBuf(ibuf);
|
||||
MEM_freeN(selar);
|
||||
}
|
||||
|
||||
IMB_freeImBuf(ibuf);
|
||||
MEM_freeN(selar);
|
||||
|
||||
|
||||
// XXX notifier! object_tface_flags_changed(OBACT, 0);
|
||||
}
|
||||
#ifdef __APPLE__
|
||||
glReadBuffer(GL_BACK);
|
||||
#endif
|
||||
|
||||
object_facesel_flush_dm(OBACT);
|
||||
object_facesel_flush_dm(ob);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -719,7 +719,7 @@ EditMesh *make_editMesh(Scene *scene, Object *ob)
|
|||
EditFace *efa;
|
||||
EditEdge *eed;
|
||||
EditSelection *ese;
|
||||
float *co;
|
||||
float *co, (*keyco)[3]= NULL;
|
||||
int tot, a, eekadoodle= 0;
|
||||
|
||||
em= MEM_callocN(sizeof(EditMesh), "editmesh");
|
||||
|
@ -732,7 +732,8 @@ EditMesh *make_editMesh(Scene *scene, Object *ob)
|
|||
|
||||
actkey = ob_get_keyblock(ob);
|
||||
if(actkey) {
|
||||
tot= actkey->totelem;
|
||||
keyco= actkey->data;
|
||||
em->shapenr= ob->shapenr;
|
||||
}
|
||||
|
||||
/* make editverts */
|
||||
|
@ -745,8 +746,8 @@ EditMesh *make_editMesh(Scene *scene, Object *ob)
|
|||
co= mvert->co;
|
||||
|
||||
/* edit the shape key coordinate if available */
|
||||
if(actkey && a < actkey->totelem)
|
||||
co= (float*)actkey->data + 3*a;
|
||||
if(keyco && a < actkey->totelem)
|
||||
co= keyco[a];
|
||||
|
||||
eve= addvertlist(em, co, NULL);
|
||||
evlist[a]= eve;
|
||||
|
@ -1129,7 +1130,8 @@ void load_editMesh(Scene *scene, Object *ob, EditMesh *em)
|
|||
|
||||
/* are there keys? */
|
||||
if(me->key) {
|
||||
KeyBlock *currkey, *actkey = ob_get_keyblock(ob);
|
||||
KeyBlock *currkey;
|
||||
KeyBlock *actkey= BLI_findlink(&me->key->block, em->shapenr-1);
|
||||
|
||||
/* Lets reorder the key data so that things line up roughly
|
||||
* with the way things were before editmode */
|
||||
|
@ -1146,7 +1148,7 @@ void load_editMesh(Scene *scene, Object *ob, EditMesh *em)
|
|||
while(eve) {
|
||||
if (eve->keyindex >= 0 && eve->keyindex < currkey->totelem) { // valid old vertex
|
||||
if(currkey == actkey) {
|
||||
if (actkey == me->key->refkey) {
|
||||
if(actkey == me->key->refkey) {
|
||||
VECCOPY(fp, mvert->co);
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -1208,7 +1208,7 @@ static void make_prim_ext(bContext *C, int type, int tot, int seg,
|
|||
int subdiv, float dia, float depth, int ext, int fill)
|
||||
{
|
||||
Object *obedit= CTX_data_edit_object(C);
|
||||
int newob;
|
||||
int newob = 0;
|
||||
float mat[4][4];
|
||||
|
||||
if(obedit==NULL || obedit->type!=OB_MESH) {
|
||||
|
@ -1308,49 +1308,21 @@ void MESH_OT_primitive_circle_add(wmOperatorType *ot)
|
|||
RNA_def_boolean(ot->srna, "fill", 0, "Fill", "");
|
||||
}
|
||||
|
||||
static int add_primitive_cylinder_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
make_prim_ext(C, PRIM_CYLINDER, RNA_int_get(op->ptr, "vertices"), 0, 0,
|
||||
RNA_float_get(op->ptr,"radius"),
|
||||
RNA_float_get(op->ptr, "depth"), 1, 1);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
void MESH_OT_primitive_cylinder_add(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name= "Add Cylinder";
|
||||
ot->description= "Construct a cylindrical mesh (ends filled).";
|
||||
ot->idname= "MESH_OT_primitive_cylinder_add";
|
||||
|
||||
/* api callbacks */
|
||||
ot->exec= add_primitive_cylinder_exec;
|
||||
ot->poll= ED_operator_scene_editable;
|
||||
|
||||
/* flags */
|
||||
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
||||
|
||||
/* props */
|
||||
RNA_def_int(ot->srna, "vertices", 32, INT_MIN, INT_MAX, "Vertices", "", 2, 500);
|
||||
RNA_def_float(ot->srna, "radius", 1.0f, 0.0, FLT_MAX, "Radius", "", 0.001, 100.00);
|
||||
RNA_def_float(ot->srna, "depth", 1.0f, 0.0, FLT_MAX, "Depth", "", 0.001, 100.00);
|
||||
}
|
||||
|
||||
static int add_primitive_tube_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
make_prim_ext(C, PRIM_CYLINDER, RNA_int_get(op->ptr, "vertices"), 0, 0,
|
||||
RNA_float_get(op->ptr,"radius"),
|
||||
RNA_float_get(op->ptr, "depth"), 1, 0);
|
||||
RNA_float_get(op->ptr, "depth"), 1,
|
||||
RNA_boolean_get(op->ptr, "cap_ends"));
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
void MESH_OT_primitive_tube_add(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name= "Add Tube";
|
||||
ot->description= "Construct a cylindrical mesh (ends not filled).";
|
||||
ot->description= "Construct a tube mesh.";
|
||||
ot->idname= "MESH_OT_primitive_tube_add";
|
||||
|
||||
/* api callbacks */
|
||||
|
@ -1364,6 +1336,7 @@ void MESH_OT_primitive_tube_add(wmOperatorType *ot)
|
|||
RNA_def_int(ot->srna, "vertices", 32, INT_MIN, INT_MAX, "Vertices", "", 2, 500);
|
||||
RNA_def_float(ot->srna, "radius", 1.0f, 0.0, FLT_MAX, "Radius", "", 0.001, 100.00);
|
||||
RNA_def_float(ot->srna, "depth", 1.0f, 0.0, FLT_MAX, "Depth", "", 0.001, 100.00);
|
||||
RNA_def_boolean(ot->srna, "cap_ends", 1, "Cap Ends", "");
|
||||
}
|
||||
|
||||
static int add_primitive_cone_exec(bContext *C, wmOperator *op)
|
||||
|
|
|
@ -210,7 +210,7 @@ void CutEdgeloop(Object *obedit, wmOperator *op, EditMesh *em, int numcuts)
|
|||
EditEdge *nearest=NULL, *eed;
|
||||
float fac;
|
||||
int keys = 0, holdnum=0, selectmode, dist;
|
||||
short mvalo[2] = {0,0}, mval[2];
|
||||
short mvalo[2] = {0, 0}, mval[2] = {0, 0};
|
||||
short event=0, val, choosing=1, cancel=0, cuthalf = 0, smooth=0;
|
||||
short hasHidden = 0;
|
||||
char msg[128];
|
||||
|
@ -254,7 +254,7 @@ void CutEdgeloop(Object *obedit, wmOperator *op, EditMesh *em, int numcuts)
|
|||
// }
|
||||
#endif
|
||||
}
|
||||
else PIL_sleep_ms(10); // idle
|
||||
else PIL_sleep_ms(10); // idle
|
||||
|
||||
|
||||
while(qtest())
|
||||
|
|
|
@ -99,41 +99,43 @@ static int pupmenu() {return 0;}
|
|||
|
||||
/* ****************************** MIRROR **************** */
|
||||
|
||||
void EM_select_mirrored(Object *obedit, EditMesh *em)
|
||||
void EM_cache_x_mirror_vert(struct Object *ob, struct EditMesh *em)
|
||||
{
|
||||
#if 0
|
||||
if(em->selectmode & SCE_SELECT_VERTEX) {
|
||||
EditVert *eve, *v1;
|
||||
|
||||
for(eve= em->verts.first; eve; eve= eve->next) {
|
||||
if(eve->f & SELECT) {
|
||||
v1= editmesh_get_x_mirror_vert(obedit, em, eve->co);
|
||||
if(v1) {
|
||||
eve->f &= ~SELECT;
|
||||
v1->f |= SELECT;
|
||||
}
|
||||
EditVert *eve, *eve_mirror;
|
||||
|
||||
for(eve= em->verts.first; eve; eve= eve->next) {
|
||||
eve->tmp.v= NULL;
|
||||
}
|
||||
|
||||
for(eve= em->verts.first; eve; eve= eve->next) {
|
||||
if(eve->tmp.v==NULL) {
|
||||
eve_mirror = editmesh_get_x_mirror_vert(ob, em, eve->co);
|
||||
if(eve_mirror) {
|
||||
eve->tmp.v= eve_mirror;
|
||||
eve_mirror->tmp.v = eve;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void EM_automerge(int update)
|
||||
void EM_select_mirrored(Object *obedit, EditMesh *em, int extend)
|
||||
{
|
||||
// XXX int len;
|
||||
|
||||
// if ((scene->automerge) &&
|
||||
// (obedit && obedit->type==OB_MESH) &&
|
||||
// (((Mesh*)obedit->data)->mr==NULL)
|
||||
// ) {
|
||||
// len = removedoublesflag(1, 1, scene->toolsettings->doublimit);
|
||||
// if (len) {
|
||||
// em->totvert -= len; /* saves doing a countall */
|
||||
// if (update) {
|
||||
// DAG_id_flush_update(obedit->data, OB_RECALC_DATA);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
EditVert *eve;
|
||||
|
||||
EM_cache_x_mirror_vert(obedit, em);
|
||||
|
||||
for(eve= em->verts.first; eve; eve= eve->next) {
|
||||
if(eve->f & SELECT && eve->tmp.v) {
|
||||
eve->tmp.v->f |= SELECT;
|
||||
|
||||
if(extend==FALSE)
|
||||
eve->f &= ~SELECT;
|
||||
|
||||
/* remove the interference */
|
||||
eve->tmp.v->tmp.v= eve->tmp.v= NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ****************************** SELECTION ROUTINES **************** */
|
||||
|
@ -1247,6 +1249,39 @@ void MESH_OT_select_by_number_vertices(wmOperatorType *ot)
|
|||
RNA_def_enum(ot->srna, "type", type_items, 3, "Type", "Type of elements to select.");
|
||||
}
|
||||
|
||||
|
||||
int select_mirror_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
Object *obedit= CTX_data_edit_object(C);
|
||||
EditMesh *em= BKE_mesh_get_editmesh(((Mesh *)obedit->data));
|
||||
|
||||
int extend= RNA_boolean_get(op->ptr, "extend");
|
||||
|
||||
EM_select_mirrored(obedit, em, extend);
|
||||
|
||||
WM_event_add_notifier(C, NC_GEOM|ND_SELECT, obedit->data);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
void MESH_OT_select_mirror(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name= "Select Mirror";
|
||||
ot->description= "Select mesh items at mirrored locations.";
|
||||
ot->idname= "MESH_OT_select_mirror";
|
||||
|
||||
/* api callbacks */
|
||||
ot->exec= select_mirror_exec;
|
||||
ot->poll= ED_operator_editmesh;
|
||||
|
||||
/* flags */
|
||||
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
||||
|
||||
/* props */
|
||||
RNA_def_boolean(ot->srna, "extend", 0, "Extend", "Extend the existing selection");
|
||||
}
|
||||
|
||||
static int select_sharp_edges_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
/* Find edges that have exactly two neighboring faces,
|
||||
|
@ -2295,99 +2330,6 @@ void vertexnoise(Object *obedit, EditMesh *em)
|
|||
|
||||
}
|
||||
|
||||
static void vertices_to_sphere(Scene *scene, View3D *v3d, Object *obedit, EditMesh *em, float perc)
|
||||
{
|
||||
EditVert *eve;
|
||||
float *curs, len, vec[3], cent[3], fac, facm, imat[3][3], bmat[3][3];
|
||||
int tot;
|
||||
|
||||
// XXX if(button(&perc, 1, 100, "Percentage:")==0) return;
|
||||
|
||||
fac= perc/100.0f;
|
||||
facm= 1.0f-fac;
|
||||
|
||||
Mat3CpyMat4(bmat, obedit->obmat);
|
||||
Mat3Inv(imat, bmat);
|
||||
|
||||
/* center */
|
||||
curs= give_cursor(scene, v3d);
|
||||
cent[0]= curs[0]-obedit->obmat[3][0];
|
||||
cent[1]= curs[1]-obedit->obmat[3][1];
|
||||
cent[2]= curs[2]-obedit->obmat[3][2];
|
||||
Mat3MulVecfl(imat, cent);
|
||||
|
||||
len= 0.0;
|
||||
tot= 0;
|
||||
eve= em->verts.first;
|
||||
while(eve) {
|
||||
if(eve->f & SELECT) {
|
||||
tot++;
|
||||
len+= VecLenf(cent, eve->co);
|
||||
}
|
||||
eve= eve->next;
|
||||
}
|
||||
len/=tot;
|
||||
|
||||
if(len==0.0) len= 10.0;
|
||||
|
||||
eve= em->verts.first;
|
||||
while(eve) {
|
||||
if(eve->f & SELECT) {
|
||||
vec[0]= eve->co[0]-cent[0];
|
||||
vec[1]= eve->co[1]-cent[1];
|
||||
vec[2]= eve->co[2]-cent[2];
|
||||
|
||||
Normalize(vec);
|
||||
|
||||
eve->co[0]= fac*(cent[0]+vec[0]*len) + facm*eve->co[0];
|
||||
eve->co[1]= fac*(cent[1]+vec[1]*len) + facm*eve->co[1];
|
||||
eve->co[2]= fac*(cent[2]+vec[2]*len) + facm*eve->co[2];
|
||||
|
||||
}
|
||||
eve= eve->next;
|
||||
}
|
||||
|
||||
recalc_editnormals(em);
|
||||
// DAG_id_flush_update(obedit->data, OB_RECALC_DATA);
|
||||
|
||||
}
|
||||
|
||||
static int vertices_to_sphere_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
Scene *scene= CTX_data_scene(C);
|
||||
Object *obedit= CTX_data_edit_object(C);
|
||||
View3D *v3d = CTX_wm_view3d(C);
|
||||
EditMesh *em= BKE_mesh_get_editmesh(((Mesh *)obedit->data));
|
||||
|
||||
vertices_to_sphere(scene, v3d, obedit, em, RNA_float_get(op->ptr,"percent"));
|
||||
|
||||
BKE_mesh_end_editmesh(obedit->data, em);
|
||||
|
||||
DAG_id_flush_update(obedit->data, OB_RECALC_DATA);
|
||||
WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
void MESH_OT_vertices_transform_to_sphere(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name= "Vertices to Sphere";
|
||||
//added "around cursor" to differentiate between "TFM_OT_tosphere()"
|
||||
ot->description= "Move selected vertices outward in a spherical shape around cursor.";
|
||||
ot->idname= "MESH_OT_vertices_transform_to_sphere";
|
||||
|
||||
/* api callbacks */
|
||||
ot->exec= vertices_to_sphere_exec;
|
||||
ot->poll= ED_operator_editmesh;
|
||||
|
||||
/* flags */
|
||||
ot->flag= OPTYPE_REGISTER/*|OPTYPE_UNDO*/;
|
||||
|
||||
/* props */
|
||||
RNA_def_float(ot->srna, "percent", 100.0f, 0.0f, 100.0f, "Percent", "DOC_BROKEN", 0.01f, 100.0f);
|
||||
}
|
||||
|
||||
void flipface(EditMesh *em, EditFace *efa)
|
||||
{
|
||||
if(efa->v4) {
|
||||
|
|
|
@ -69,6 +69,7 @@ editmesh_tool.c: UI called tools for editmesh, geometry changes here, otherwise
|
|||
#include "BKE_customdata.h"
|
||||
#include "BKE_depsgraph.h"
|
||||
#include "BKE_global.h"
|
||||
#include "BKE_key.h"
|
||||
#include "BKE_library.h"
|
||||
#include "BKE_mesh.h"
|
||||
#include "BKE_object.h"
|
||||
|
@ -96,10 +97,8 @@ editmesh_tool.c: UI called tools for editmesh, geometry changes here, otherwise
|
|||
#include "bmesh.h"
|
||||
|
||||
/* XXX */
|
||||
static int extern_qread() {return 0;}
|
||||
static void waitcursor(int val) {}
|
||||
static int pupmenu() {return 0;}
|
||||
static int qtest() {return 0;}
|
||||
#define add_numbut(a, b, c, d, e, f, g) {}
|
||||
|
||||
/* XXX */
|
||||
|
@ -4245,6 +4244,7 @@ void mesh_set_face_flags(EditMesh *em, short mode)
|
|||
|
||||
/************************ Shape Operators *************************/
|
||||
|
||||
#if 0
|
||||
void shape_propagate(Scene *scene, Object *obedit, EditMesh *em, wmOperator *op)
|
||||
{
|
||||
EditVert *ev = NULL;
|
||||
|
@ -4286,8 +4286,9 @@ void shape_propagate(Scene *scene, Object *obedit, EditMesh *em, wmOperator *op)
|
|||
DAG_id_flush_update(obedit->data, OB_RECALC_DATA);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
void shape_copy_from_lerp(EditMesh *em, KeyBlock* thisBlock, KeyBlock* fromBlock)
|
||||
static int blend_from_shape_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
#if 0 //BMESH_TODO
|
||||
EditVert *ev = NULL;
|
||||
|
@ -4295,65 +4296,34 @@ void shape_copy_from_lerp(EditMesh *em, KeyBlock* thisBlock, KeyBlock* fromBlock
|
|||
float perc = 0;
|
||||
char str[64];
|
||||
float *data, *odata;
|
||||
Object *obedit= CTX_data_edit_object(C);
|
||||
Mesh *me= obedit->data;
|
||||
Key *key= me->key;
|
||||
EditMesh *em= BKE_mesh_get_editmesh(me);
|
||||
EditVert *eve;
|
||||
KeyBlock *kb;
|
||||
float *data, co[3];
|
||||
float blend= RNA_float_get(op->ptr, "blend");
|
||||
int shape= RNA_enum_get(op->ptr, "shape");
|
||||
int add= RNA_int_get(op->ptr, "add");
|
||||
int blended= 0;
|
||||
|
||||
data = fromBlock->data;
|
||||
odata = thisBlock->data;
|
||||
if(key && (kb= BLI_findlink(&key->block, shape))) {
|
||||
data= kb->data;
|
||||
|
||||
// XXX getmouseco_areawin(mval);
|
||||
curval[0] = mval[0] + 1; curval[1] = mval[1] + 1;
|
||||
for(eve=em->verts.first; eve; eve=eve->next){
|
||||
if(eve->f & SELECT) {
|
||||
if(eve->keyindex >= 0 && eve->keyindex < kb->totelem) {
|
||||
VECCOPY(co, data + eve->keyindex*3);
|
||||
|
||||
while (finished == 0)
|
||||
{
|
||||
// XXX getmouseco_areawin(mval);
|
||||
if (mval[0] != curval[0] || mval[1] != curval[1])
|
||||
{
|
||||
if(add) {
|
||||
VecMulf(co, blend);
|
||||
VecAddf(eve->co, eve->co, co);
|
||||
}
|
||||
else
|
||||
VecLerpf(eve->co, eve->co, co, blend);
|
||||
|
||||
if(mval[0] > curval[0])
|
||||
perc += 0.1;
|
||||
else if(mval[0] < curval[0])
|
||||
perc -= 0.1;
|
||||
|
||||
if(perc < 0) perc = 0;
|
||||
if(perc > 1) perc = 1;
|
||||
|
||||
curval[0] = mval[0];
|
||||
curval[1] = mval[1];
|
||||
|
||||
if(fullcopy == 1){
|
||||
perc = 1;
|
||||
}
|
||||
|
||||
for(ev = em->verts.first; ev ; ev = ev->next){
|
||||
if(ev->f & SELECT){
|
||||
VecLerpf(ev->co,odata+(ev->keyindex*3),data+(ev->keyindex*3),perc);
|
||||
}
|
||||
}
|
||||
sprintf(str,"Blending at %d%c MMB to Copy at 100%c",(int)(perc*100),'%','%');
|
||||
// DAG_id_flush_update(obedit->data, OB_RECALC_DATA);
|
||||
// headerprint(str);
|
||||
// force_draw(0);
|
||||
|
||||
if(fullcopy == 1){
|
||||
break;
|
||||
}
|
||||
|
||||
} else {
|
||||
PIL_sleep_ms(10);
|
||||
}
|
||||
|
||||
while(qtest()) {
|
||||
short val=0;
|
||||
event= extern_qread(&val);
|
||||
if(val){
|
||||
if(ELEM3(event, PADENTER, LEFTMOUSE, RETKEY)){
|
||||
finished = 1;
|
||||
}
|
||||
else if (event == MIDDLEMOUSE){
|
||||
fullcopy = 1;
|
||||
}
|
||||
else if (ELEM3(event,ESCKEY,RIGHTMOUSE,RIGHTMOUSE)){
|
||||
canceled = 1;
|
||||
finished = 1;
|
||||
blended= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4367,73 +4337,63 @@ void shape_copy_from_lerp(EditMesh *em, KeyBlock* thisBlock, KeyBlock* fromBlock
|
|||
}
|
||||
return;
|
||||
#endif
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
static EnumPropertyItem *shape_itemf(bContext *C, PointerRNA *ptr, int *free)
|
||||
{
|
||||
Object *obedit= CTX_data_edit_object(C);
|
||||
Mesh *me= (obedit) ? obedit->data : NULL;
|
||||
Key *key;
|
||||
KeyBlock *kb, *actkb;
|
||||
EnumPropertyItem tmp= {0, "", 0, "", ""}, *item= NULL;
|
||||
int totitem= 0, a;
|
||||
|
||||
if(obedit && obedit->type == OB_MESH) {
|
||||
key= me->key;
|
||||
actkb= ob_get_keyblock(obedit);
|
||||
|
||||
void shape_copy_select_from(Object *obedit, EditMesh *em, wmOperator *op)
|
||||
if(key && actkb) {
|
||||
for(kb=key->block.first, a=0; kb; kb=kb->next, a++) {
|
||||
if(kb != actkb) {
|
||||
tmp.value= a;
|
||||
tmp.identifier= kb->name;
|
||||
tmp.name= kb->name;
|
||||
RNA_enum_item_add(&item, &totitem, &tmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RNA_enum_item_end(&item, &totitem);
|
||||
*free= 1;
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
void MESH_OT_blend_from_shape(wmOperatorType *ot)
|
||||
{
|
||||
Mesh* me = (Mesh*)obedit->data;
|
||||
EditVert *ev = NULL;
|
||||
int totverts = 0,curshape = obedit->shapenr;
|
||||
PropertyRNA *prop;
|
||||
static EnumPropertyItem shape_items[]= {{0, NULL, 0, NULL, NULL}};
|
||||
|
||||
Key* ky = NULL;
|
||||
KeyBlock *kb = NULL,*thisBlock = NULL;
|
||||
int maxlen=32, nr=0, a=0;
|
||||
char *menu;
|
||||
/* identifiers */
|
||||
ot->name= "Blend From Shape";
|
||||
ot->description= "Blend in shape from a shape key.";
|
||||
ot->idname= "MESH_OT_blend_from_shape";
|
||||
|
||||
if(me->key){
|
||||
ky = me->key;
|
||||
} else {
|
||||
BKE_report(op->reports, RPT_ERROR, "Object Has No Key");
|
||||
return;
|
||||
}
|
||||
/* api callbacks */
|
||||
ot->exec= blend_from_shape_exec;
|
||||
ot->invoke= WM_operator_props_popup;
|
||||
ot->poll= ED_operator_editmesh;
|
||||
|
||||
if(ky->block.first){
|
||||
for(kb=ky->block.first;kb;kb = kb->next){
|
||||
maxlen += 40; // Size of a block name
|
||||
if(a == curshape-1){
|
||||
thisBlock = kb;
|
||||
}
|
||||
/* flags */
|
||||
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
||||
|
||||
a++;
|
||||
}
|
||||
a=0;
|
||||
menu = MEM_callocN(maxlen, "Copy Shape Menu Text");
|
||||
strcpy(menu, "Copy Vert Positions from Shape %t|");
|
||||
for(kb=ky->block.first;kb;kb = kb->next){
|
||||
if(a != curshape-1){
|
||||
sprintf(menu,"%s %s %cx%d|",menu,kb->name,'%',a);
|
||||
}
|
||||
a++;
|
||||
}
|
||||
// XXX nr = pupmenu_col(menu, 20);
|
||||
MEM_freeN(menu);
|
||||
} else {
|
||||
BKE_report(op->reports, RPT_ERROR, "Object Has No Blendshapes");
|
||||
return;
|
||||
}
|
||||
|
||||
a = 0;
|
||||
|
||||
for(kb=ky->block.first;kb;kb = kb->next){
|
||||
if(a == nr){
|
||||
|
||||
for(ev = em->verts.first;ev;ev = ev->next){
|
||||
totverts++;
|
||||
}
|
||||
|
||||
if(me->totvert != totverts){
|
||||
BKE_report(op->reports, RPT_ERROR, "Shape Has had Verts Added/Removed, please cycle editmode before copying");
|
||||
return;
|
||||
}
|
||||
shape_copy_from_lerp(em, thisBlock,kb);
|
||||
|
||||
return;
|
||||
}
|
||||
a++;
|
||||
}
|
||||
return;
|
||||
/* properties */
|
||||
prop= RNA_def_enum(ot->srna, "shape", shape_items, 0, "Shape", "Shape key to use for blending.");
|
||||
RNA_def_enum_funcs(prop, shape_itemf);
|
||||
RNA_def_float(ot->srna, "blend", 1.0f, -FLT_MAX, FLT_MAX, "Blend", "Blending factor.", -2.0f, 2.0f);
|
||||
RNA_def_boolean(ot->srna, "add", 1, "Add", "Add rather then blend between shapes.");
|
||||
}
|
||||
|
||||
/************************ Merge Operator *************************/
|
||||
|
|
|
@ -301,7 +301,7 @@ static int ringsel_init (bContext *C, wmOperator *op, int do_cut)
|
|||
|
||||
/* assign the drawing handle for drawing preview line... */
|
||||
lcd->ar= CTX_wm_region(C);
|
||||
lcd->draw_handle= ED_region_draw_cb_activate(lcd->ar->type, ringsel_draw, lcd, REGION_DRAW_POST);
|
||||
lcd->draw_handle= ED_region_draw_cb_activate(lcd->ar->type, ringsel_draw, lcd, REGION_DRAW_POST_VIEW);
|
||||
lcd->ob = CTX_data_edit_object(C);
|
||||
lcd->em= ((Mesh *)lcd->ob->data)->edit_btmesh;
|
||||
lcd->extend = do_cut ? 0 : RNA_boolean_get(op->ptr, "extend");
|
||||
|
@ -480,5 +480,5 @@ void MESH_OT_loopcut (wmOperatorType *ot)
|
|||
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING;
|
||||
|
||||
/* properties */
|
||||
RNA_def_int(ot->srna, "number_cuts", 1, 1, 10, "Number of Cuts", "", 1, INT_MAX);
|
||||
RNA_def_int(ot->srna, "number_cuts", 1, 1, INT_MAX, "Number of Cuts", "", 1, 10);
|
||||
}
|
||||
|
|
|
@ -118,7 +118,6 @@ void MESH_OT_separate(struct wmOperatorType *ot);
|
|||
void MESH_OT_primitive_plane_add(struct wmOperatorType *ot);
|
||||
void MESH_OT_primitive_cube_add(struct wmOperatorType *ot);
|
||||
void MESH_OT_primitive_circle_add(struct wmOperatorType *ot);
|
||||
void MESH_OT_primitive_cylinder_add(struct wmOperatorType *ot);
|
||||
void MESH_OT_primitive_tube_add(struct wmOperatorType *ot);
|
||||
void MESH_OT_primitive_cone_add(struct wmOperatorType *ot);
|
||||
void MESH_OT_primitive_grid_add(struct wmOperatorType *ot);
|
||||
|
@ -204,13 +203,13 @@ void MESH_OT_unpin(struct wmOperatorType *ot);
|
|||
void MESH_OT_hide(struct wmOperatorType *ot);
|
||||
void MESH_OT_reveal(struct wmOperatorType *ot);
|
||||
void MESH_OT_select_by_number_vertices(struct wmOperatorType *ot);
|
||||
void MESH_OT_select_mirror(struct wmOperatorType *ot);
|
||||
void MESH_OT_normals_make_consistent(struct wmOperatorType *ot);
|
||||
void MESH_OT_faces_select_linked_flat(struct wmOperatorType *ot);
|
||||
void MESH_OT_edges_select_sharp(struct wmOperatorType *ot);
|
||||
void MESH_OT_select_shortest_path(struct wmOperatorType *ot);
|
||||
void MESH_OT_select_similar(struct wmOperatorType *ot);
|
||||
void MESH_OT_select_random(struct wmOperatorType *ot);
|
||||
void MESH_OT_vertices_transform_to_sphere(struct wmOperatorType *ot);
|
||||
void MESH_OT_selection_type(struct wmOperatorType *ot);
|
||||
void MESH_OT_loop_multi_select(struct wmOperatorType *ot);
|
||||
void MESH_OT_mark_seam(struct wmOperatorType *ot);
|
||||
|
@ -282,6 +281,8 @@ void MESH_OT_colors_reverse(struct wmOperatorType *ot);
|
|||
void MESH_OT_delete(struct wmOperatorType *ot);
|
||||
void MESH_OT_rip(struct wmOperatorType *ot);
|
||||
|
||||
void MESH_OT_blend_from_shape(struct wmOperatorType *ot);
|
||||
|
||||
/* ******************* mesh_layers.c */
|
||||
|
||||
void MESH_OT_uv_texture_add(struct wmOperatorType *ot);
|
||||
|
|
|
@ -82,6 +82,7 @@ void ED_operatortypes_mesh(void)
|
|||
WM_operatortype_append(MESH_OT_hide);
|
||||
WM_operatortype_append(MESH_OT_reveal);
|
||||
WM_operatortype_append(MESH_OT_select_by_number_vertices);
|
||||
WM_operatortype_append(MESH_OT_select_mirror);
|
||||
WM_operatortype_append(MESH_OT_normals_make_consistent);
|
||||
WM_operatortype_append(MESH_OT_merge);
|
||||
WM_operatortype_append(MESH_OT_subdivide);
|
||||
|
@ -90,7 +91,6 @@ void ED_operatortypes_mesh(void)
|
|||
WM_operatortype_append(MESH_OT_primitive_plane_add);
|
||||
WM_operatortype_append(MESH_OT_primitive_cube_add);
|
||||
WM_operatortype_append(MESH_OT_primitive_circle_add);
|
||||
WM_operatortype_append(MESH_OT_primitive_cylinder_add);
|
||||
WM_operatortype_append(MESH_OT_primitive_tube_add);
|
||||
WM_operatortype_append(MESH_OT_primitive_cone_add);
|
||||
WM_operatortype_append(MESH_OT_primitive_grid_add);
|
||||
|
@ -105,7 +105,6 @@ void ED_operatortypes_mesh(void)
|
|||
WM_operatortype_append(MESH_OT_spin);
|
||||
WM_operatortype_append(MESH_OT_screw);
|
||||
|
||||
WM_operatortype_append(MESH_OT_vertices_transform_to_sphere);
|
||||
WM_operatortype_append(MESH_OT_split);
|
||||
WM_operatortype_append(MESH_OT_extrude_repeat);
|
||||
WM_operatortype_append(MESH_OT_edge_rotate);
|
||||
|
@ -143,6 +142,7 @@ void ED_operatortypes_mesh(void)
|
|||
WM_operatortype_append(MESH_OT_flip_normals);
|
||||
WM_operatortype_append(MESH_OT_knife_cut);
|
||||
WM_operatortype_append(MESH_OT_rip);
|
||||
WM_operatortype_append(MESH_OT_blend_from_shape);
|
||||
|
||||
WM_operatortype_append(MESH_OT_uv_texture_add);
|
||||
WM_operatortype_append(MESH_OT_uv_texture_remove);
|
||||
|
@ -236,8 +236,6 @@ void ED_keymap_mesh(wmKeyConfig *keyconf)
|
|||
|
||||
RNA_float_set(WM_keymap_add_item(keymap, "MESH_OT_faces_select_linked_flat", FKEY, KM_PRESS, (KM_CTRL|KM_SHIFT|KM_ALT), 0)->ptr,"sharpness",135.0);
|
||||
RNA_float_set(WM_keymap_add_item(keymap, "MESH_OT_edges_select_sharp", SKEY, KM_PRESS, (KM_CTRL|KM_SHIFT|KM_ALT), 0)->ptr,"sharpness",135.0);
|
||||
|
||||
WM_keymap_add_item(keymap, "MESH_OT_vertices_transform_to_sphere", SKEY, KM_PRESS, KM_CTRL|KM_SHIFT , 0);
|
||||
WM_keymap_add_item(keymap, "MESH_OT_select_similar", GKEY, KM_PRESS, KM_SHIFT, 0);
|
||||
|
||||
WM_keymap_add_item(keymap, "MESH_OT_edge_split", MKEY, KM_PRESS, 0, 0);
|
||||
|
@ -299,8 +297,10 @@ void ED_keymap_mesh(wmKeyConfig *keyconf)
|
|||
RNA_string_set(kmi->ptr, "name", "INFO_MT_mesh_add");
|
||||
|
||||
WM_keymap_add_item(keymap, "MESH_OT_separate", PKEY, KM_PRESS, 0, 0);
|
||||
/* use KM_RELEASE because same key is used for tweaks */
|
||||
WM_keymap_add_item(keymap, "MESH_OT_dupli_extrude_cursor", LEFTMOUSE, KM_RELEASE, KM_CTRL, 0);
|
||||
/* use KM_RELEASE because same key is used for tweaks
|
||||
* TEMPORARY REMAP TO ALT+CTRL TO AVOID CONFLICT
|
||||
* */
|
||||
WM_keymap_add_item(keymap, "MESH_OT_dupli_extrude_cursor", LEFTMOUSE, KM_RELEASE, KM_CTRL|KM_ALT, 0);
|
||||
|
||||
WM_keymap_add_item(keymap, "MESH_OT_delete", XKEY, KM_PRESS, 0, 0);
|
||||
WM_keymap_add_item(keymap, "MESH_OT_delete", DELKEY, KM_PRESS, 0, 0);
|
||||
|
|
|
@ -850,7 +850,7 @@ static void mesh_octree_add_nodes(MocNode **basetable, float *co, float *offs, f
|
|||
|
||||
}
|
||||
|
||||
static intptr_t mesh_octree_find_index(MocNode **bt, float (*orco)[3], MVert *mvert, float *co)
|
||||
static intptr_t mesh_octree_find_index(MocNode **bt, MVert *mvert, float *co)
|
||||
{
|
||||
float *vec;
|
||||
int a;
|
||||
|
@ -861,12 +861,7 @@ static intptr_t mesh_octree_find_index(MocNode **bt, float (*orco)[3], MVert *mv
|
|||
for(a=0; a<MOC_NODE_RES; a++) {
|
||||
if((*bt)->index[a]) {
|
||||
/* does mesh verts and editmode, code looks potential dangerous, octree should really be filled OK! */
|
||||
if(orco) {
|
||||
vec= orco[(*bt)->index[a]-1];
|
||||
if(FloatCompare(vec, co, MOC_THRESH))
|
||||
return (*bt)->index[a]-1;
|
||||
}
|
||||
else if(mvert) {
|
||||
if(mvert) {
|
||||
vec= (mvert+(*bt)->index[a]-1)->co;
|
||||
if(FloatCompare(vec, co, MOC_THRESH))
|
||||
return (*bt)->index[a]-1;
|
||||
|
@ -880,7 +875,7 @@ static intptr_t mesh_octree_find_index(MocNode **bt, float (*orco)[3], MVert *mv
|
|||
else return -1;
|
||||
}
|
||||
if( (*bt)->next)
|
||||
return mesh_octree_find_index(&(*bt)->next, orco, mvert, co);
|
||||
return mesh_octree_find_index(&(*bt)->next, mvert, co);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
@ -888,9 +883,7 @@ static intptr_t mesh_octree_find_index(MocNode **bt, float (*orco)[3], MVert *mv
|
|||
static struct {
|
||||
MocNode **table;
|
||||
float offs[3], div[3];
|
||||
float (*orco)[3];
|
||||
float orcoloc[3];
|
||||
} MeshOctree = {NULL, {0, 0, 0}, {0, 0, 0}, NULL};
|
||||
} MeshOctree = {NULL, {0, 0, 0}, {0, 0, 0}};
|
||||
|
||||
/* mode is 's' start, or 'e' end, or 'u' use */
|
||||
/* if end, ob can be NULL */
|
||||
|
@ -906,9 +899,9 @@ intptr_t mesh_octree_table(Object *ob, BMEditMesh *em, float *co, char mode)
|
|||
Mesh *me= ob->data;
|
||||
bt= MeshOctree.table + mesh_octree_get_base_offs(co, MeshOctree.offs, MeshOctree.div);
|
||||
if(em)
|
||||
return mesh_octree_find_index(bt, NULL, NULL, co);
|
||||
return mesh_octree_find_index(bt, NULL, co);
|
||||
else
|
||||
return mesh_octree_find_index(bt, MeshOctree.orco, me->mvert, co);
|
||||
return mesh_octree_find_index(bt, me->mvert, co);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
@ -930,16 +923,10 @@ intptr_t mesh_octree_table(Object *ob, BMEditMesh *em, float *co, char mode)
|
|||
}
|
||||
else {
|
||||
MVert *mvert;
|
||||
float *vco;
|
||||
int a, totvert;
|
||||
int a;
|
||||
|
||||
MeshOctree.orco= mesh_getRefKeyCos(me, &totvert);
|
||||
mesh_get_texspace(me, MeshOctree.orcoloc, NULL, NULL);
|
||||
|
||||
for(a=0, mvert= me->mvert; a<me->totvert; a++, mvert++) {
|
||||
vco= (MeshOctree.orco)? MeshOctree.orco[a]: mvert->co;
|
||||
DO_MINMAX(vco, min, max);
|
||||
}
|
||||
for(a=0, mvert= me->mvert; a<me->totvert; a++, mvert++)
|
||||
DO_MINMAX(mvert->co, min, max);
|
||||
}
|
||||
|
||||
/* for quick unit coordinate calculus */
|
||||
|
@ -974,13 +961,10 @@ intptr_t mesh_octree_table(Object *ob, BMEditMesh *em, float *co, char mode)
|
|||
}
|
||||
else {
|
||||
MVert *mvert;
|
||||
float *vco;
|
||||
int a;
|
||||
|
||||
for(a=0, mvert= me->mvert; a<me->totvert; a++, mvert++) {
|
||||
vco= (MeshOctree.orco)? MeshOctree.orco[a]: mvert->co;
|
||||
mesh_octree_add_nodes(MeshOctree.table, vco, MeshOctree.offs, MeshOctree.div, a+1);
|
||||
}
|
||||
for(a=0, mvert= me->mvert; a<me->totvert; a++, mvert++)
|
||||
mesh_octree_add_nodes(MeshOctree.table, mvert->co, MeshOctree.offs, MeshOctree.div, a+1);
|
||||
}
|
||||
}
|
||||
else if(mode=='e') { /* end table */
|
||||
|
@ -993,10 +977,6 @@ intptr_t mesh_octree_table(Object *ob, BMEditMesh *em, float *co, char mode)
|
|||
MEM_freeN(MeshOctree.table);
|
||||
MeshOctree.table= NULL;
|
||||
}
|
||||
if(MeshOctree.orco) {
|
||||
MEM_freeN(MeshOctree.orco);
|
||||
MeshOctree.orco= NULL;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -1007,19 +987,10 @@ int mesh_get_x_mirror_vert(Object *ob, int index)
|
|||
MVert *mvert;
|
||||
float vec[3];
|
||||
|
||||
if(MeshOctree.orco) {
|
||||
float *loc= MeshOctree.orcoloc;
|
||||
|
||||
vec[0]= -(MeshOctree.orco[index][0] + loc[0]) - loc[0];
|
||||
vec[1]= MeshOctree.orco[index][1];
|
||||
vec[2]= MeshOctree.orco[index][2];
|
||||
}
|
||||
else {
|
||||
mvert= me->mvert+index;
|
||||
vec[0]= -mvert->co[0];
|
||||
vec[1]= mvert->co[1];
|
||||
vec[2]= mvert->co[2];
|
||||
}
|
||||
mvert= me->mvert+index;
|
||||
vec[0]= -mvert->co[0];
|
||||
vec[1]= mvert->co[1];
|
||||
vec[2]= mvert->co[2];
|
||||
|
||||
return mesh_octree_table(ob, NULL, vec, 'u');
|
||||
}
|
||||
|
|
|
@ -293,17 +293,20 @@ static int object_add_curve_exec(bContext *C, wmOperator *op)
|
|||
Object *obedit= CTX_data_edit_object(C);
|
||||
ListBase *editnurb;
|
||||
Nurb *nu;
|
||||
int newob= 0;
|
||||
int newob= 0, type= RNA_enum_get(op->ptr, "type");
|
||||
|
||||
if(obedit==NULL || obedit->type!=OB_CURVE) {
|
||||
ED_object_add_type(C, OB_CURVE);
|
||||
ED_object_enter_editmode(C, 0);
|
||||
newob = 1;
|
||||
obedit= CTX_data_edit_object(C);
|
||||
|
||||
if(type & CU_PRIM_PATH)
|
||||
((Curve*)obedit->data)->flag |= CU_PATH|CU_3D;
|
||||
}
|
||||
else DAG_id_flush_update(&obedit->id, OB_RECALC_DATA);
|
||||
|
||||
obedit= CTX_data_edit_object(C);
|
||||
nu= add_nurbs_primitive(C, RNA_enum_get(op->ptr, "type"), newob);
|
||||
nu= add_nurbs_primitive(C, type, newob);
|
||||
editnurb= curve_get_editcurve(obedit);
|
||||
BLI_addtail(editnurb, nu);
|
||||
|
||||
|
|
|
@ -471,7 +471,6 @@ void ED_object_enter_editmode(bContext *C, int flag)
|
|||
|
||||
static int editmode_toggle_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
|
||||
if(!CTX_data_edit_object(C))
|
||||
ED_object_enter_editmode(C, EM_WAITCURSOR);
|
||||
else
|
||||
|
|
|
@ -58,6 +58,7 @@ void OBJECT_OT_track_clear(struct wmOperatorType *ot);
|
|||
void OBJECT_OT_slow_parent_set(struct wmOperatorType *ot);
|
||||
void OBJECT_OT_slow_parent_clear(struct wmOperatorType *ot);
|
||||
void OBJECT_OT_make_local(struct wmOperatorType *ot);
|
||||
void OBJECT_OT_make_single_user(struct wmOperatorType *ot);
|
||||
void OBJECT_OT_move_to_layer(struct wmOperatorType *ot);
|
||||
|
||||
/* object_edit.c */
|
||||
|
@ -165,6 +166,11 @@ void OBJECT_OT_vertex_group_select(struct wmOperatorType *ot);
|
|||
void OBJECT_OT_vertex_group_deselect(struct wmOperatorType *ot);
|
||||
void OBJECT_OT_vertex_group_copy_to_linked(struct wmOperatorType *ot);
|
||||
void OBJECT_OT_vertex_group_copy(struct wmOperatorType *ot);
|
||||
void OBJECT_OT_vertex_group_normalize(struct wmOperatorType *ot);
|
||||
void OBJECT_OT_vertex_group_normalize_all(struct wmOperatorType *ot);
|
||||
void OBJECT_OT_vertex_group_invert(struct wmOperatorType *ot);
|
||||
void OBJECT_OT_vertex_group_blend(struct wmOperatorType *ot);
|
||||
void OBJECT_OT_vertex_group_clean(struct wmOperatorType *ot);
|
||||
void OBJECT_OT_vertex_group_menu(struct wmOperatorType *ot);
|
||||
void OBJECT_OT_vertex_group_set_active(struct wmOperatorType *ot);
|
||||
|
||||
|
@ -174,6 +180,9 @@ void OBJECT_OT_game_property_remove(struct wmOperatorType *ot);
|
|||
/* object_shapekey.c */
|
||||
void OBJECT_OT_shape_key_add(struct wmOperatorType *ot);
|
||||
void OBJECT_OT_shape_key_remove(struct wmOperatorType *ot);
|
||||
void OBJECT_OT_shape_key_clear(struct wmOperatorType *ot);
|
||||
void OBJECT_OT_shape_key_mirror(struct wmOperatorType *ot);
|
||||
void OBJECT_OT_shape_key_move(struct wmOperatorType *ot);
|
||||
|
||||
/* object_group.c */
|
||||
void OBJECT_OT_group_add(struct wmOperatorType *ot);
|
||||
|
|
|
@ -349,10 +349,10 @@ int ED_object_modifier_apply(ReportList *reports, Scene *scene, Object *ob, Modi
|
|||
|
||||
mesh_pmv_off(ob, me);
|
||||
|
||||
/* Multires: ensure that recent sculpting is applied */
|
||||
if(md->type == eModifierType_Multires)
|
||||
multires_force_update(ob);
|
||||
|
||||
/* Multires: ensure that recent sculpting is applied */
|
||||
if(md->type == eModifierType_Multires)
|
||||
multires_force_update(ob);
|
||||
|
||||
dm = mesh_create_derived_for_modifier(scene, ob, md);
|
||||
if (!dm) {
|
||||
BKE_report(reports, RPT_ERROR, "Modifier is disabled or returned error, skipping apply");
|
||||
|
|
|
@ -90,6 +90,7 @@ void ED_operatortypes_object(void)
|
|||
WM_operatortype_append(OBJECT_OT_slow_parent_set);
|
||||
WM_operatortype_append(OBJECT_OT_slow_parent_clear);
|
||||
WM_operatortype_append(OBJECT_OT_make_local);
|
||||
WM_operatortype_append(OBJECT_OT_make_single_user);
|
||||
WM_operatortype_append(OBJECT_OT_move_to_layer);
|
||||
|
||||
WM_operatortype_append(OBJECT_OT_select_inverse);
|
||||
|
@ -162,6 +163,11 @@ void ED_operatortypes_object(void)
|
|||
WM_operatortype_append(OBJECT_OT_vertex_group_deselect);
|
||||
WM_operatortype_append(OBJECT_OT_vertex_group_copy_to_linked);
|
||||
WM_operatortype_append(OBJECT_OT_vertex_group_copy);
|
||||
WM_operatortype_append(OBJECT_OT_vertex_group_normalize);
|
||||
WM_operatortype_append(OBJECT_OT_vertex_group_normalize_all);
|
||||
WM_operatortype_append(OBJECT_OT_vertex_group_invert);
|
||||
WM_operatortype_append(OBJECT_OT_vertex_group_blend);
|
||||
WM_operatortype_append(OBJECT_OT_vertex_group_clean);
|
||||
WM_operatortype_append(OBJECT_OT_vertex_group_menu);
|
||||
WM_operatortype_append(OBJECT_OT_vertex_group_set_active);
|
||||
|
||||
|
@ -170,6 +176,9 @@ void ED_operatortypes_object(void)
|
|||
|
||||
WM_operatortype_append(OBJECT_OT_shape_key_add);
|
||||
WM_operatortype_append(OBJECT_OT_shape_key_remove);
|
||||
WM_operatortype_append(OBJECT_OT_shape_key_clear);
|
||||
WM_operatortype_append(OBJECT_OT_shape_key_mirror);
|
||||
WM_operatortype_append(OBJECT_OT_shape_key_move);
|
||||
|
||||
WM_operatortype_append(LATTICE_OT_select_all_toggle);
|
||||
WM_operatortype_append(LATTICE_OT_make_regular);
|
||||
|
@ -181,12 +190,21 @@ void ED_operatortypes_object(void)
|
|||
void ED_operatormacros_object(void)
|
||||
{
|
||||
wmOperatorType *ot;
|
||||
wmOperatorTypeMacro *otmacro;
|
||||
|
||||
ot= WM_operatortype_append_macro("OBJECT_OT_duplicate_move", "Duplicate", OPTYPE_UNDO|OPTYPE_REGISTER);
|
||||
if(ot) {
|
||||
WM_operatortype_macro_define(ot, "OBJECT_OT_duplicate");
|
||||
WM_operatortype_macro_define(ot, "TFM_OT_translate");
|
||||
}
|
||||
|
||||
/* grr, should be able to pass options on... */
|
||||
ot= WM_operatortype_append_macro("OBJECT_OT_duplicate_move_linked", "Duplicate", OPTYPE_UNDO|OPTYPE_REGISTER);
|
||||
if(ot) {
|
||||
otmacro= WM_operatortype_macro_define(ot, "OBJECT_OT_duplicate");
|
||||
RNA_boolean_set(otmacro->ptr, "linked", 1);
|
||||
WM_operatortype_macro_define(ot, "TFM_OT_translate");
|
||||
}
|
||||
}
|
||||
|
||||
static int object_mode_poll(bContext *C)
|
||||
|
@ -249,15 +267,22 @@ void ED_keymap_object(wmKeyConfig *keyconf)
|
|||
kmi= WM_keymap_add_item(keymap, "WM_OT_call_menu", AKEY, KM_PRESS, KM_SHIFT, 0);
|
||||
RNA_string_set(kmi->ptr, "name", "INFO_MT_add");
|
||||
|
||||
WM_keymap_add_item(keymap, "OBJECT_OT_duplicates_make_real", AKEY, KM_PRESS, KM_SHIFT|KM_CTRL, 0);
|
||||
|
||||
kmi= WM_keymap_add_item(keymap, "WM_OT_call_menu", AKEY, KM_PRESS, KM_CTRL, 0);
|
||||
RNA_string_set(kmi->ptr, "name", "VIEW3D_MT_object_apply");
|
||||
|
||||
kmi= WM_keymap_add_item(keymap, "WM_OT_call_menu", UKEY, KM_PRESS, 0, 0);
|
||||
RNA_string_set(kmi->ptr, "name", "VIEW3D_MT_make_single_user");
|
||||
|
||||
WM_keymap_add_item(keymap, "OBJECT_OT_duplicate_move", DKEY, KM_PRESS, KM_SHIFT, 0);
|
||||
RNA_boolean_set(WM_keymap_add_item(keymap, "OBJECT_OT_duplicate", DKEY, KM_PRESS, KM_ALT, 0)->ptr, "linked", 1);
|
||||
WM_keymap_add_item(keymap, "OBJECT_OT_duplicate_move_linked", DKEY, KM_PRESS, KM_ALT, 0);
|
||||
|
||||
WM_keymap_add_item(keymap, "OBJECT_OT_join", JKEY, KM_PRESS, KM_CTRL, 0);
|
||||
WM_keymap_add_item(keymap, "OBJECT_OT_convert", CKEY, KM_PRESS, KM_ALT, 0);
|
||||
WM_keymap_add_item(keymap, "OBJECT_OT_proxy_make", PKEY, KM_PRESS, KM_CTRL|KM_ALT, 0);
|
||||
|
||||
WM_keymap_add_item(keymap, "OBJECT_OT_make_local", LKEY, KM_PRESS, 0, 0);
|
||||
|
||||
// XXX this should probably be in screen instead... here for testing purposes in the meantime... - Aligorith
|
||||
WM_keymap_verify_item(keymap, "ANIM_OT_insert_keyframe_menu", IKEY, KM_PRESS, 0, 0);
|
||||
WM_keymap_verify_item(keymap, "ANIM_OT_delete_keyframe_v3d", IKEY, KM_PRESS, KM_ALT, 0);
|
||||
|
@ -272,6 +297,8 @@ void ED_keymap_object(wmKeyConfig *keyconf)
|
|||
keymap->poll= ED_operator_editlattice;
|
||||
|
||||
WM_keymap_add_item(keymap, "LATTICE_OT_select_all_toggle", AKEY, KM_PRESS, 0, 0);
|
||||
|
||||
ED_object_generic_keymap(keyconf, keymap, TRUE);
|
||||
}
|
||||
|
||||
void ED_object_generic_keymap(struct wmKeyConfig *keyconf, struct wmKeyMap *keymap, int do_pet)
|
||||
|
|
|
@ -1456,7 +1456,7 @@ void single_ipo_users(Scene *scene, int flag)
|
|||
#endif // XXX old animation system
|
||||
}
|
||||
|
||||
void single_mat_users(Scene *scene, int flag)
|
||||
static void single_mat_users(Scene *scene, int flag, int do_textures)
|
||||
{
|
||||
Object *ob;
|
||||
Base *base;
|
||||
|
@ -1486,17 +1486,17 @@ void single_mat_users(Scene *scene, int flag)
|
|||
ipo_idnew(ma->ipo); /* drivers */
|
||||
}
|
||||
#endif // XXX old animation system
|
||||
|
||||
for(b=0; b<MAX_MTEX; b++) {
|
||||
if(ma->mtex[b] && ma->mtex[b]->tex) {
|
||||
tex= ma->mtex[b]->tex;
|
||||
if(tex->id.us>1) {
|
||||
ma->mtex[b]->tex= copy_texture(tex);
|
||||
tex->id.us--;
|
||||
if(do_textures) {
|
||||
for(b=0; b<MAX_MTEX; b++) {
|
||||
if(ma->mtex[b] && ma->mtex[b]->tex) {
|
||||
tex= ma->mtex[b]->tex;
|
||||
if(tex->id.us>1) {
|
||||
ma->mtex[b]->tex= copy_texture(tex);
|
||||
tex->id.us--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1599,42 +1599,6 @@ static void single_mat_users_expand(void)
|
|||
ID_NEW(ma->mtex[a]->object);
|
||||
}
|
||||
|
||||
void single_user(Scene *scene, View3D *v3d)
|
||||
{
|
||||
int nr;
|
||||
|
||||
if(scene->id.lib) return;
|
||||
|
||||
clear_id_newpoins();
|
||||
|
||||
nr= pupmenu("Make Single User%t|Object|Object & ObData|Object & ObData & Materials+Tex|Materials+Tex|Ipos");
|
||||
if(nr>0) {
|
||||
|
||||
if(nr==1) single_object_users(scene, v3d, 1);
|
||||
|
||||
else if(nr==2) {
|
||||
single_object_users(scene, v3d, 1);
|
||||
single_obdata_users(scene, 1);
|
||||
}
|
||||
else if(nr==3) {
|
||||
single_object_users(scene, v3d, 1);
|
||||
single_obdata_users(scene, 1);
|
||||
single_mat_users(scene, 1); /* also tex */
|
||||
|
||||
}
|
||||
else if(nr==4) {
|
||||
single_mat_users(scene, 1);
|
||||
}
|
||||
else if(nr==5) {
|
||||
single_ipo_users(scene, 1);
|
||||
}
|
||||
|
||||
|
||||
clear_id_newpoins();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/* used for copying scenes */
|
||||
void ED_object_single_users(Scene *scene, int full)
|
||||
{
|
||||
|
@ -1676,7 +1640,7 @@ static int make_local_exec(bContext *C, wmOperator *op)
|
|||
Material *ma, ***matarar;
|
||||
Lamp *la;
|
||||
ID *id;
|
||||
int a, b, mode= RNA_boolean_get(op->ptr, "type");
|
||||
int a, b, mode= RNA_enum_get(op->ptr, "type");;
|
||||
|
||||
if(mode==3) {
|
||||
all_local(NULL, 0); /* NULL is all libs */
|
||||
|
@ -1777,3 +1741,59 @@ void OBJECT_OT_make_local(wmOperatorType *ot)
|
|||
RNA_def_enum(ot->srna, "type", type_items, 0, "Type", "");
|
||||
}
|
||||
|
||||
static int make_single_user_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
Scene *scene= CTX_data_scene(C);
|
||||
View3D *v3d= CTX_wm_view3d(C); /* ok if this is NULL */
|
||||
int flag= RNA_enum_get(op->ptr, "type"); /* 0==ALL, SELECTED==selected objecs */
|
||||
|
||||
if(RNA_boolean_get(op->ptr, "object"))
|
||||
single_object_users(scene, v3d, flag);
|
||||
|
||||
if(RNA_boolean_get(op->ptr, "obdata"))
|
||||
single_obdata_users(scene, flag);
|
||||
|
||||
if(RNA_boolean_get(op->ptr, "material"))
|
||||
single_mat_users(scene, flag, FALSE);
|
||||
|
||||
if(RNA_boolean_get(op->ptr, "texture"))
|
||||
single_mat_users(scene, flag, TRUE);
|
||||
|
||||
if(RNA_boolean_get(op->ptr, "animation"))
|
||||
single_ipo_users(scene, flag);
|
||||
|
||||
clear_id_newpoins();
|
||||
|
||||
WM_event_add_notifier(C, NC_WINDOW, NULL);
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
void OBJECT_OT_make_single_user(wmOperatorType *ot)
|
||||
{
|
||||
static EnumPropertyItem type_items[]= {
|
||||
{SELECT, "SELECTED_OBJECTS", 0, "Selected Objects", ""},
|
||||
{0, "ALL", 0, "All", ""},
|
||||
{0, NULL, 0, NULL, NULL}};
|
||||
|
||||
/* identifiers */
|
||||
ot->name= "Make Single User";
|
||||
ot->description = "Make linked data local to each object.";
|
||||
ot->idname= "OBJECT_OT_make_single_user";
|
||||
|
||||
/* api callbacks */
|
||||
ot->invoke= WM_menu_invoke;
|
||||
ot->exec= make_single_user_exec;
|
||||
ot->poll= ED_operator_scene_editable;
|
||||
|
||||
/* flags */
|
||||
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
||||
|
||||
/* properties */
|
||||
RNA_def_enum(ot->srna, "type", type_items, 0, "Type", "");
|
||||
|
||||
RNA_def_boolean(ot->srna, "object", 0, "Object", "Make single user objects");
|
||||
RNA_def_boolean(ot->srna, "obdata", 0, "Object Data", "Make single user object data");
|
||||
RNA_def_boolean(ot->srna, "material", 0, "Materials", "Make materials local to each datablock");
|
||||
RNA_def_boolean(ot->srna, "texture", 0, "Textures", "Make textures local to each material");
|
||||
RNA_def_boolean(ot->srna, "animation", 0, "Animation Data", "Make animation data local to each object");
|
||||
}
|
||||
|
|
|
@ -95,7 +95,6 @@ void ED_base_object_select(Base *base, short mode)
|
|||
void ED_base_object_activate(bContext *C, Base *base)
|
||||
{
|
||||
Scene *scene= CTX_data_scene(C);
|
||||
Base *tbase;
|
||||
|
||||
/* sets scene->basact */
|
||||
BASACT= base;
|
||||
|
|
|
@ -70,49 +70,16 @@
|
|||
#include "BLO_sys_types.h" // for intptr_t support
|
||||
|
||||
#include "ED_object.h"
|
||||
#include "ED_mesh.h"
|
||||
|
||||
#include "RNA_access.h"
|
||||
#include "RNA_define.h"
|
||||
|
||||
#include "WM_api.h"
|
||||
#include "WM_types.h"
|
||||
|
||||
#include "object_intern.h"
|
||||
|
||||
#if 0 // XXX old animation system
|
||||
static void default_key_ipo(Scene *scene, Key *key)
|
||||
{
|
||||
IpoCurve *icu;
|
||||
BezTriple *bezt;
|
||||
|
||||
key->ipo= add_ipo(scene, "KeyIpo", ID_KE);
|
||||
|
||||
icu= MEM_callocN(sizeof(IpoCurve), "ipocurve");
|
||||
|
||||
icu->blocktype= ID_KE;
|
||||
icu->adrcode= KEY_SPEED;
|
||||
icu->flag= IPO_VISIBLE|IPO_SELECT|IPO_AUTO_HORIZ;
|
||||
set_icu_vars(icu);
|
||||
|
||||
BLI_addtail( &(key->ipo->curve), icu);
|
||||
|
||||
icu->bezt= bezt= MEM_callocN(2*sizeof(BezTriple), "defaultipo");
|
||||
icu->totvert= 2;
|
||||
|
||||
bezt->hide= IPO_BEZ;
|
||||
bezt->f1=bezt->f2= bezt->f3= SELECT;
|
||||
bezt->h1= bezt->h2= HD_AUTO;
|
||||
bezt++;
|
||||
bezt->vec[1][0]= 100.0;
|
||||
bezt->vec[1][1]= 1.0;
|
||||
bezt->hide= IPO_BEZ;
|
||||
bezt->f1=bezt->f2= bezt->f3= SELECT;
|
||||
bezt->h1= bezt->h2= HD_AUTO;
|
||||
|
||||
calchandles_ipocurve(icu);
|
||||
}
|
||||
#endif // XXX old animation system
|
||||
|
||||
|
||||
/************************* Mesh ************************/
|
||||
|
||||
void mesh_to_key(Mesh *me, KeyBlock *kb)
|
||||
|
@ -195,24 +162,30 @@ static KeyBlock *add_keyblock(Scene *scene, Key *key)
|
|||
return kb;
|
||||
}
|
||||
|
||||
void insert_meshkey(Scene *scene, Mesh *me, short rel)
|
||||
static void insert_meshkey(Scene *scene, Object *ob)
|
||||
{
|
||||
Key *key;
|
||||
Mesh *me= ob->data;
|
||||
Key *key= me->key;
|
||||
KeyBlock *kb;
|
||||
int newkey= 0;
|
||||
|
||||
if(me->key==NULL) {
|
||||
me->key= add_key( (ID *)me);
|
||||
|
||||
if(rel)
|
||||
me->key->type = KEY_RELATIVE;
|
||||
// else
|
||||
// default_key_ipo(scene, me->key); // XXX old animation system
|
||||
if(key == NULL) {
|
||||
key= me->key= add_key((ID *)me);
|
||||
key->type= KEY_RELATIVE;
|
||||
newkey= 1;
|
||||
}
|
||||
key= me->key;
|
||||
|
||||
kb= add_keyblock(scene, key);
|
||||
|
||||
mesh_to_key(me, kb);
|
||||
if(newkey) {
|
||||
/* create from mesh */
|
||||
mesh_to_key(me, kb);
|
||||
}
|
||||
else {
|
||||
/* copy from current values */
|
||||
kb->data= do_ob_key(scene, ob);
|
||||
kb->totelem= me->totvert;
|
||||
}
|
||||
}
|
||||
|
||||
/************************* Lattice ************************/
|
||||
|
@ -253,24 +226,31 @@ void key_to_latt(KeyBlock *kb, Lattice *lt)
|
|||
for(a=0; a<tot; a++, fp+=3, bp++) {
|
||||
VECCOPY(bp->vec, fp);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* exported to python... hrms, should not, use object levels! (ton) */
|
||||
void insert_lattkey(Scene *scene, Lattice *lt, short rel)
|
||||
static void insert_lattkey(Scene *scene, Object *ob)
|
||||
{
|
||||
Key *key;
|
||||
Lattice *lt= ob->data;
|
||||
Key *key= lt->key;
|
||||
KeyBlock *kb;
|
||||
int newkey= 0;
|
||||
|
||||
if(lt->key==NULL) {
|
||||
lt->key= add_key( (ID *)lt);
|
||||
// default_key_ipo(scene, lt->key); // XXX old animation system
|
||||
if(key==NULL) {
|
||||
key= lt->key= add_key( (ID *)lt);
|
||||
key->type= KEY_RELATIVE;
|
||||
}
|
||||
key= lt->key;
|
||||
|
||||
|
||||
kb= add_keyblock(scene, key);
|
||||
|
||||
latt_to_key(lt, kb);
|
||||
if(newkey) {
|
||||
/* create from lattice */
|
||||
latt_to_key(lt, kb);
|
||||
}
|
||||
else {
|
||||
/* copy from current values */
|
||||
kb->totelem= lt->pntsu*lt->pntsv*lt->pntsw;
|
||||
kb->data= do_ob_key(scene, ob);
|
||||
}
|
||||
}
|
||||
|
||||
/************************* Curve ************************/
|
||||
|
@ -377,36 +357,43 @@ void key_to_curve(KeyBlock *kb, Curve *cu, ListBase *nurb)
|
|||
}
|
||||
|
||||
|
||||
void insert_curvekey(Scene *scene, Curve *cu, short rel)
|
||||
static void insert_curvekey(Scene *scene, Object *ob)
|
||||
{
|
||||
Key *key;
|
||||
Curve *cu= ob->data;
|
||||
Key *key= cu->key;
|
||||
KeyBlock *kb;
|
||||
ListBase *lb= (cu->editnurb)? cu->editnurb: &cu->nurb;
|
||||
int newkey= 0;
|
||||
|
||||
if(cu->key==NULL) {
|
||||
cu->key= add_key( (ID *)cu);
|
||||
|
||||
if(rel)
|
||||
cu->key->type = KEY_RELATIVE;
|
||||
// else
|
||||
// default_key_ipo(scene, cu->key); // XXX old animation system
|
||||
if(key==NULL) {
|
||||
key= cu->key= add_key( (ID *)cu);
|
||||
key->type = KEY_RELATIVE;
|
||||
newkey= 1;
|
||||
}
|
||||
key= cu->key;
|
||||
|
||||
kb= add_keyblock(scene, key);
|
||||
|
||||
if(cu->editnurb->first) curve_to_key(cu, kb, cu->editnurb);
|
||||
else curve_to_key(cu, kb, &cu->nurb);
|
||||
if(newkey) {
|
||||
/* create from curve */
|
||||
curve_to_key(cu, kb, lb);
|
||||
}
|
||||
else {
|
||||
/* copy from current values */
|
||||
kb->totelem= count_curveverts(lb);
|
||||
kb->data= do_ob_key(scene, ob);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*********************** add shape key ***********************/
|
||||
|
||||
void ED_object_shape_key_add(bContext *C, Scene *scene, Object *ob)
|
||||
static void ED_object_shape_key_add(bContext *C, Scene *scene, Object *ob)
|
||||
{
|
||||
Key *key;
|
||||
|
||||
if(ob->type==OB_MESH) insert_meshkey(scene, ob->data, 1);
|
||||
else if ELEM(ob->type, OB_CURVE, OB_SURF) insert_curvekey(scene, ob->data, 1);
|
||||
else if(ob->type==OB_LATTICE) insert_lattkey(scene, ob->data, 1);
|
||||
if(ob->type==OB_MESH) insert_meshkey(scene, ob);
|
||||
else if ELEM(ob->type, OB_CURVE, OB_SURF) insert_curvekey(scene, ob);
|
||||
else if(ob->type==OB_LATTICE) insert_lattkey(scene, ob);
|
||||
|
||||
key= ob_get_key(ob);
|
||||
ob->shapenr= BLI_countlist(&key->block);
|
||||
|
@ -416,7 +403,7 @@ void ED_object_shape_key_add(bContext *C, Scene *scene, Object *ob)
|
|||
|
||||
/*********************** remove shape key ***********************/
|
||||
|
||||
int ED_object_shape_key_remove(bContext *C, Scene *scene, Object *ob)
|
||||
static int ED_object_shape_key_remove(bContext *C, Object *ob)
|
||||
{
|
||||
Main *bmain= CTX_data_main(C);
|
||||
KeyBlock *kb, *rkb;
|
||||
|
@ -479,8 +466,76 @@ int ED_object_shape_key_remove(bContext *C, Scene *scene, Object *ob)
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int ED_object_shape_key_mirror(bContext *C, Scene *scene, Object *ob)
|
||||
{
|
||||
KeyBlock *kb;
|
||||
Key *key;
|
||||
|
||||
key= ob_get_key(ob);
|
||||
if(key==NULL)
|
||||
return 0;
|
||||
|
||||
kb= BLI_findlink(&key->block, ob->shapenr-1);
|
||||
|
||||
if(kb) {
|
||||
int i1, i2;
|
||||
float *fp1, *fp2;
|
||||
float tvec[3];
|
||||
char *tag_elem= MEM_callocN(sizeof(char) * kb->totelem, "shape_key_mirror");
|
||||
|
||||
|
||||
if(ob->type==OB_MESH) {
|
||||
Mesh *me= ob->data;
|
||||
MVert *mv;
|
||||
|
||||
mesh_octree_table(ob, NULL, NULL, 's');
|
||||
|
||||
for(i1=0, mv=me->mvert; i1<me->totvert; i1++, mv++) {
|
||||
i2= mesh_get_x_mirror_vert(ob, i1);
|
||||
if(i2==i1) {
|
||||
fp1= ((float *)kb->data) + i1*3;
|
||||
fp1[0] = -fp1[0];
|
||||
tag_elem[i1]= 1;
|
||||
}
|
||||
else if(i2 != -1) {
|
||||
if(tag_elem[i1]==0 && tag_elem[i2]==0) {
|
||||
fp1= ((float *)kb->data) + i1*3;
|
||||
fp2= ((float *)kb->data) + i2*3;
|
||||
|
||||
VECCOPY(tvec, fp1);
|
||||
VECCOPY(fp1, fp2);
|
||||
VECCOPY(fp2, tvec);
|
||||
|
||||
/* flip x axis */
|
||||
fp1[0] = -fp1[0];
|
||||
fp2[0] = -fp2[0];
|
||||
}
|
||||
tag_elem[i1]= tag_elem[i2]= 1;
|
||||
}
|
||||
}
|
||||
|
||||
mesh_octree_table(ob, NULL, NULL, 'e');
|
||||
}
|
||||
/* todo, other types? */
|
||||
|
||||
MEM_freeN(tag_elem);
|
||||
}
|
||||
|
||||
DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
|
||||
WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/********************** shape key operators *********************/
|
||||
|
||||
static int shape_key_mode_poll(bContext *C)
|
||||
{
|
||||
Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
|
||||
ID *data= (ob)? ob->data: NULL;
|
||||
return (ob && !ob->id.lib && data && !data->lib && ob->mode != OB_MODE_EDIT);
|
||||
}
|
||||
|
||||
static int shape_key_poll(bContext *C)
|
||||
{
|
||||
Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
|
||||
|
@ -502,10 +557,11 @@ void OBJECT_OT_shape_key_add(wmOperatorType *ot)
|
|||
{
|
||||
/* identifiers */
|
||||
ot->name= "Add Shape Key";
|
||||
ot->name= "Add shape key to the object.";
|
||||
ot->idname= "OBJECT_OT_shape_key_add";
|
||||
|
||||
/* api callbacks */
|
||||
ot->poll= shape_key_poll;
|
||||
ot->poll= shape_key_mode_poll;
|
||||
ot->exec= shape_key_add_exec;
|
||||
|
||||
/* flags */
|
||||
|
@ -514,10 +570,9 @@ void OBJECT_OT_shape_key_add(wmOperatorType *ot)
|
|||
|
||||
static int shape_key_remove_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
Scene *scene= CTX_data_scene(C);
|
||||
Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
|
||||
|
||||
if(!ED_object_shape_key_remove(C, scene, ob))
|
||||
if(!ED_object_shape_key_remove(C, ob))
|
||||
return OPERATOR_CANCELLED;
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
|
@ -527,13 +582,132 @@ void OBJECT_OT_shape_key_remove(wmOperatorType *ot)
|
|||
{
|
||||
/* identifiers */
|
||||
ot->name= "Remove Shape Key";
|
||||
ot->name= "Remove shape key from the object.";
|
||||
ot->idname= "OBJECT_OT_shape_key_remove";
|
||||
|
||||
/* api callbacks */
|
||||
ot->poll= shape_key_poll;
|
||||
ot->poll= shape_key_mode_poll;
|
||||
ot->exec= shape_key_remove_exec;
|
||||
|
||||
/* flags */
|
||||
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
||||
}
|
||||
|
||||
static int shape_key_clear_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
|
||||
Key *key= ob_get_key(ob);
|
||||
KeyBlock *kb= ob_get_keyblock(ob);
|
||||
|
||||
if(!key || !kb)
|
||||
return OPERATOR_CANCELLED;
|
||||
|
||||
for(kb=key->block.first; kb; kb=kb->next)
|
||||
kb->curval= 0.0f;
|
||||
|
||||
DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
|
||||
WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
void OBJECT_OT_shape_key_clear(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name= "Clear Shape Keys";
|
||||
ot->description= "Clear weights for all shape keys.";
|
||||
ot->idname= "OBJECT_OT_shape_key_clear";
|
||||
|
||||
/* api callbacks */
|
||||
ot->poll= shape_key_poll;
|
||||
ot->exec= shape_key_clear_exec;
|
||||
|
||||
/* flags */
|
||||
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
||||
}
|
||||
|
||||
static int shape_key_mirror_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
Scene *scene= CTX_data_scene(C);
|
||||
Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
|
||||
|
||||
if(!ED_object_shape_key_mirror(C, scene, ob))
|
||||
return OPERATOR_CANCELLED;
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
void OBJECT_OT_shape_key_mirror(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name= "Mirror Shape Key";
|
||||
ot->idname= "OBJECT_OT_shape_key_mirror";
|
||||
|
||||
/* api callbacks */
|
||||
ot->poll= shape_key_mode_poll;
|
||||
ot->exec= shape_key_mirror_exec;
|
||||
|
||||
/* flags */
|
||||
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
||||
}
|
||||
|
||||
|
||||
static int shape_key_move_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
|
||||
|
||||
int type= RNA_enum_get(op->ptr, "type");
|
||||
Key *key= ob_get_key(ob);
|
||||
|
||||
if(key) {
|
||||
KeyBlock *kb, *kb_other;
|
||||
kb= BLI_findlink(&key->block, ob->shapenr-1);
|
||||
|
||||
if(type==-1) {
|
||||
/* move back */
|
||||
if(kb->prev) {
|
||||
kb_other= kb->prev;
|
||||
BLI_remlink(&key->block, kb);
|
||||
BLI_insertlinkbefore(&key->block, kb_other, kb);
|
||||
ob->shapenr--;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* move next */
|
||||
if(kb->next) {
|
||||
kb_other= kb->next;
|
||||
BLI_remlink(&key->block, kb);
|
||||
BLI_insertlinkafter(&key->block, kb_other, kb);
|
||||
ob->shapenr++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
|
||||
WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
void OBJECT_OT_shape_key_move(wmOperatorType *ot)
|
||||
{
|
||||
static EnumPropertyItem slot_move[] = {
|
||||
{-1, "UP", 0, "Up", ""},
|
||||
{1, "DOWN", 0, "Down", ""},
|
||||
{0, NULL, 0, NULL, NULL}
|
||||
};
|
||||
|
||||
/* identifiers */
|
||||
ot->name= "Move Shape Key";
|
||||
ot->idname= "OBJECT_OT_shape_key_move";
|
||||
|
||||
/* api callbacks */
|
||||
ot->poll= shape_key_mode_poll;
|
||||
ot->exec= shape_key_move_exec;
|
||||
|
||||
/* flags */
|
||||
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
||||
|
||||
RNA_def_enum(ot->srna, "type", slot_move, 0, "Type", "");
|
||||
}
|
||||
|
||||
|
|
|
@ -167,6 +167,33 @@ void ED_vgroup_data_create(ID *id)
|
|||
}
|
||||
}
|
||||
|
||||
/* returns true if the id type supports weights */
|
||||
int ED_vgroup_give_array(ID *id, MDeformVert **dvert_arr, int *dvert_tot)
|
||||
{
|
||||
if(id) {
|
||||
switch(GS(id->name)) {
|
||||
case ID_ME:
|
||||
{
|
||||
Mesh *me = (Mesh *)id;
|
||||
*dvert_arr= me->dvert;
|
||||
*dvert_tot= me->totvert;
|
||||
return TRUE;
|
||||
}
|
||||
case ID_LT:
|
||||
{
|
||||
Lattice *lt= (Lattice *)id;
|
||||
lt= (lt->editlatt)? lt->editlatt: lt;
|
||||
*dvert_arr= lt->dvert;
|
||||
*dvert_tot= lt->pntsu*lt->pntsv*lt->pntsw;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*dvert_arr= NULL;
|
||||
*dvert_tot= 0;
|
||||
return FALSE;
|
||||
}
|
||||
/* for mesh in object mode
|
||||
lattice can be in editmode */
|
||||
void ED_vgroup_nr_vert_remove(Object *ob, int def_nr, int vertnum)
|
||||
|
@ -183,25 +210,18 @@ void ED_vgroup_nr_vert_remove(Object *ob, int def_nr, int vertnum)
|
|||
|
||||
MDeformWeight *newdw;
|
||||
MDeformVert *dvert= NULL;
|
||||
int i;
|
||||
int i, tot;
|
||||
|
||||
/* get the deform vertices corresponding to the
|
||||
* vertnum
|
||||
*/
|
||||
if(ob->type==OB_MESH) {
|
||||
if(((Mesh*)ob->data)->dvert)
|
||||
dvert = ((Mesh*)ob->data)->dvert + vertnum;
|
||||
}
|
||||
else if(ob->type==OB_LATTICE) {
|
||||
Lattice *lt= vgroup_edit_lattice(ob);
|
||||
|
||||
if(lt->dvert)
|
||||
dvert = lt->dvert + vertnum;
|
||||
}
|
||||
|
||||
ED_vgroup_give_array(ob->data, &dvert, &tot);
|
||||
|
||||
if(dvert==NULL)
|
||||
return;
|
||||
|
||||
dvert+= vertnum;
|
||||
|
||||
/* for all of the deform weights in the
|
||||
* deform vert
|
||||
*/
|
||||
|
@ -251,23 +271,16 @@ void ED_vgroup_nr_vert_add(Object *ob, int def_nr, int vertnum, float weight, in
|
|||
*/
|
||||
MDeformVert *dv= NULL;
|
||||
MDeformWeight *newdw;
|
||||
int i;
|
||||
int i, tot;
|
||||
|
||||
/* get the vert */
|
||||
if(ob->type==OB_MESH) {
|
||||
if(((Mesh*)ob->data)->dvert)
|
||||
dv = ((Mesh*)ob->data)->dvert + vertnum;
|
||||
}
|
||||
else if(ob->type==OB_LATTICE) {
|
||||
Lattice *lt= vgroup_edit_lattice(ob);
|
||||
|
||||
if(lt->dvert)
|
||||
dv = lt->dvert + vertnum;
|
||||
}
|
||||
ED_vgroup_give_array(ob->data, &dv, &tot);
|
||||
|
||||
if(dv==NULL)
|
||||
return;
|
||||
|
||||
dv+= vertnum;
|
||||
|
||||
/* Lets first check to see if this vert is
|
||||
* already in the weight group -- if so
|
||||
* lets update it
|
||||
|
@ -342,23 +355,19 @@ void ED_vgroup_vert_add(Object *ob, bDeformGroup *dg, int vertnum, float weight,
|
|||
*/
|
||||
int def_nr;
|
||||
|
||||
MDeformVert *dv= NULL;
|
||||
int tot;
|
||||
|
||||
/* get the deform group number, exit if
|
||||
* it can't be found
|
||||
*/
|
||||
def_nr = get_defgroup_num(ob, dg);
|
||||
if(def_nr < 0) return;
|
||||
|
||||
/* if there's no deform verts then
|
||||
* create some
|
||||
/* if there's no deform verts then create some,
|
||||
*/
|
||||
if(ob->type==OB_MESH) {
|
||||
if(!((Mesh*)ob->data)->dvert)
|
||||
ED_vgroup_data_create(ob->data);
|
||||
}
|
||||
else if(ob->type==OB_LATTICE) {
|
||||
if(!((Lattice*)ob->data)->dvert)
|
||||
ED_vgroup_data_create(ob->data);
|
||||
}
|
||||
if(ED_vgroup_give_array(ob->data, &dv, &tot) && dv==NULL)
|
||||
ED_vgroup_data_create(ob->data);
|
||||
|
||||
/* call another function to do the work
|
||||
*/
|
||||
|
@ -549,16 +558,7 @@ static void vgroup_duplicate(Object *ob)
|
|||
ob->actdef = BLI_countlist(&ob->defbase);
|
||||
icdg = (ob->actdef-1);
|
||||
|
||||
if(ob->type == OB_MESH) {
|
||||
Mesh *me = get_mesh(ob);
|
||||
dvert_array= me->dvert;
|
||||
dvert_tot= me->totvert;
|
||||
}
|
||||
else if(ob->type == OB_LATTICE) {
|
||||
Lattice *lt= (Lattice *)ob->data;
|
||||
dvert_array= lt->dvert;
|
||||
dvert_tot= lt->pntsu*lt->pntsv*lt->pntsw;
|
||||
}
|
||||
ED_vgroup_give_array(ob->data, &dvert_array, &dvert_tot);
|
||||
|
||||
if(!dvert_array)
|
||||
return;
|
||||
|
@ -575,6 +575,306 @@ static void vgroup_duplicate(Object *ob)
|
|||
}
|
||||
}
|
||||
|
||||
static void vgroup_normalize(Object *ob)
|
||||
{
|
||||
bDeformGroup *dg;
|
||||
MDeformWeight *dw;
|
||||
MDeformVert *dvert, *dvert_array=NULL;
|
||||
int i, def_nr, dvert_tot=0;
|
||||
|
||||
ED_vgroup_give_array(ob->data, &dvert_array, &dvert_tot);
|
||||
|
||||
dg = BLI_findlink(&ob->defbase, (ob->actdef-1));
|
||||
|
||||
if(dg) {
|
||||
float weight_max;
|
||||
|
||||
def_nr= ob->actdef-1;
|
||||
|
||||
for(i = 0; i < dvert_tot; i++) {
|
||||
dvert = dvert_array+i;
|
||||
dw = ED_vgroup_weight_get(dvert, def_nr);
|
||||
if(dw) {
|
||||
weight_max = MAX2(dw->weight, weight_max);
|
||||
}
|
||||
}
|
||||
|
||||
if(weight_max > 0.0f) {
|
||||
for(i = 0; i < dvert_tot; i++) {
|
||||
dvert = dvert_array+i;
|
||||
dw = ED_vgroup_weight_get(dvert, def_nr);
|
||||
if(dw) {
|
||||
dw->weight /= weight_max;
|
||||
|
||||
/* incase of division errors with very low weights */
|
||||
CLAMP(dw->weight, 0.0f, 1.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO - select between groups */
|
||||
static void vgroup_normalize_all(Object *ob, int lock_active)
|
||||
{
|
||||
MDeformWeight *dw, *dw_act;
|
||||
MDeformVert *dvert, *dvert_array=NULL;
|
||||
int i, dvert_tot=0;
|
||||
float tot_weight;
|
||||
|
||||
ED_vgroup_give_array(ob->data, &dvert_array, &dvert_tot);
|
||||
|
||||
if(dvert_array) {
|
||||
if(lock_active) {
|
||||
int def_nr= ob->actdef-1;
|
||||
|
||||
for(i = 0; i < dvert_tot; i++) {
|
||||
float lock_iweight= 1.0f;
|
||||
int j;
|
||||
|
||||
tot_weight= 0.0f;
|
||||
dw_act= NULL;
|
||||
dvert = dvert_array+i;
|
||||
|
||||
j= dvert->totweight;
|
||||
while(j--) {
|
||||
dw= dvert->dw + j;
|
||||
|
||||
if(dw->def_nr==def_nr) {
|
||||
dw_act= dw;
|
||||
lock_iweight = (1.0f - dw_act->weight);
|
||||
}
|
||||
else {
|
||||
tot_weight += dw->weight;
|
||||
}
|
||||
}
|
||||
|
||||
if(tot_weight) {
|
||||
j= dvert->totweight;
|
||||
while(j--) {
|
||||
dw= dvert->dw + j;
|
||||
if(dw == dw_act) {
|
||||
if (dvert->totweight==1) {
|
||||
dw_act->weight= 1.0f; /* no other weights, set to 1.0 */
|
||||
}
|
||||
} else {
|
||||
if(dw->weight > 0.0f)
|
||||
dw->weight = (dw->weight / tot_weight) * lock_iweight;
|
||||
}
|
||||
|
||||
/* incase of division errors with very low weights */
|
||||
CLAMP(dw->weight, 0.0f, 1.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
for(i = 0; i < dvert_tot; i++) {
|
||||
int j;
|
||||
tot_weight= 0.0f;
|
||||
dvert = dvert_array+i;
|
||||
|
||||
j= dvert->totweight;
|
||||
while(j--) {
|
||||
dw= dvert->dw + j;
|
||||
tot_weight += dw->weight;
|
||||
}
|
||||
|
||||
if(tot_weight) {
|
||||
j= dvert->totweight;
|
||||
while(j--) {
|
||||
dw= dvert->dw + j;
|
||||
dw->weight /= tot_weight;
|
||||
|
||||
/* incase of division errors with very low weights */
|
||||
CLAMP(dw->weight, 0.0f, 1.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void vgroup_invert(Object *ob, int auto_assign, int auto_remove)
|
||||
{
|
||||
bDeformGroup *dg;
|
||||
MDeformWeight *dw;
|
||||
MDeformVert *dvert, *dvert_array=NULL;
|
||||
int i, def_nr, dvert_tot=0;
|
||||
|
||||
ED_vgroup_give_array(ob->data, &dvert_array, &dvert_tot);
|
||||
|
||||
dg = BLI_findlink(&ob->defbase, (ob->actdef-1));
|
||||
|
||||
if(dg) {
|
||||
def_nr= ob->actdef-1;
|
||||
|
||||
|
||||
for(i = 0; i < dvert_tot; i++) {
|
||||
dvert = dvert_array+i;
|
||||
|
||||
if(auto_assign) {
|
||||
dw= ED_vgroup_weight_verify(dvert, def_nr);
|
||||
} else {
|
||||
dw= ED_vgroup_weight_get(dvert, def_nr);
|
||||
}
|
||||
|
||||
if(dw) {
|
||||
dw->weight = 1.0f-dw->weight;
|
||||
|
||||
if(auto_remove && dw->weight <= 0.0f) {
|
||||
/* could have a faster function for this */
|
||||
ED_vgroup_nr_vert_remove(ob, def_nr, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void vgroup_blend(Object *ob)
|
||||
{
|
||||
BMEditMesh *em= ((Mesh *)ob->data)->edit_btmesh;
|
||||
bDeformGroup *dg;
|
||||
MDeformWeight *dw;
|
||||
MDeformVert *dvert_array=NULL, *dvert;
|
||||
int i, def_nr, dvert_tot=0;
|
||||
|
||||
// ED_vgroup_give_array(ob->data, &dvert_array, &dvert_tot);
|
||||
|
||||
if(em==NULL)
|
||||
return;
|
||||
|
||||
dg = BLI_findlink(&ob->defbase, (ob->actdef-1));
|
||||
|
||||
if(dg) {
|
||||
BMEdge *eed;
|
||||
BMVert *eve;
|
||||
BMIter iter;
|
||||
float *vg_weights;
|
||||
float *vg_users;
|
||||
int sel1, sel2;
|
||||
int i1, i2;
|
||||
|
||||
def_nr= ob->actdef-1;
|
||||
|
||||
i= 0;
|
||||
BM_ITER(eve, &iter, em->bm, BM_VERTS_OF_MESH, NULL) {
|
||||
BMINDEX_SET(eve, i);
|
||||
i++;
|
||||
}
|
||||
dvert_tot= i;
|
||||
|
||||
vg_weights= MEM_callocN(sizeof(float)*dvert_tot, "vgroup_blend_f");
|
||||
vg_users= MEM_callocN(sizeof(int)*dvert_tot, "vgroup_blend_i");
|
||||
|
||||
BM_ITER(eed, &iter, em->bm, BM_EDGES_OF_MESH, NULL) {
|
||||
sel1= BM_TestHFlag(eed->v1, BM_SELECT);
|
||||
sel2= BM_TestHFlag(eed->v2, BM_SELECT);
|
||||
|
||||
if(sel1 != sel2) {
|
||||
/* i1 is always the selected one */
|
||||
if(sel1==TRUE && sel2==FALSE) {
|
||||
i1= BMINDEX_GET(eed->v1);
|
||||
i2= BMINDEX_GET(eed->v2);
|
||||
eve= eed->v2;
|
||||
}
|
||||
else {
|
||||
i2= BMINDEX_GET(eed->v1);
|
||||
i1= BMINDEX_GET(eed->v2);
|
||||
eve= eed->v1;
|
||||
}
|
||||
|
||||
vg_users[i1]++;
|
||||
|
||||
/* TODO, we may want object mode blending */
|
||||
if(em) dvert= CustomData_bmesh_get(&em->bm->vdata, eve->head.data, CD_MDEFORMVERT);
|
||||
else dvert= dvert_array+i2;
|
||||
|
||||
dw= ED_vgroup_weight_get(dvert, def_nr);
|
||||
|
||||
if(dw) {
|
||||
vg_weights[i1] += dw->weight;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
i= 0;
|
||||
BM_ITER(eve, &iter, em->bm, BM_VERTS_OF_MESH, NULL) {
|
||||
if(BM_TestHFlag(eve, BM_SELECT) && vg_users[i] > 0) {
|
||||
/* TODO, we may want object mode blending */
|
||||
if(em) dvert= CustomData_bmesh_get(&em->bm->vdata, eve->head.data, CD_MDEFORMVERT);
|
||||
else dvert= dvert_array+i;
|
||||
|
||||
dw= ED_vgroup_weight_verify(dvert, def_nr);
|
||||
dw->weight= vg_weights[i] / (float)vg_users[i];
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
MEM_freeN(vg_weights);
|
||||
MEM_freeN(vg_users);
|
||||
}
|
||||
}
|
||||
|
||||
static void vgroup_clean(Object *ob, float eul, int keep_single)
|
||||
{
|
||||
bDeformGroup *dg;
|
||||
MDeformWeight *dw;
|
||||
MDeformVert *dvert, *dvert_array=NULL;
|
||||
int i, def_nr, dvert_tot=0;
|
||||
|
||||
ED_vgroup_give_array(ob->data, &dvert_array, &dvert_tot);
|
||||
|
||||
/* only the active group */
|
||||
dg = BLI_findlink(&ob->defbase, (ob->actdef-1));
|
||||
if(dg) {
|
||||
def_nr= ob->actdef-1;
|
||||
|
||||
for(i = 0; i < dvert_tot; i++) {
|
||||
dvert = dvert_array+i;
|
||||
|
||||
dw= ED_vgroup_weight_get(dvert, def_nr);
|
||||
|
||||
if(dw) {
|
||||
if(dw->weight <= eul)
|
||||
if(keep_single==FALSE || dvert->totweight > 1)
|
||||
ED_vgroup_nr_vert_remove(ob, def_nr, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void vgroup_clean_all(Object *ob, float eul, int keep_single)
|
||||
{
|
||||
|
||||
MDeformWeight *dw;
|
||||
MDeformVert *dvert, *dvert_array=NULL;
|
||||
int i, dvert_tot=0;
|
||||
|
||||
ED_vgroup_give_array(ob->data, &dvert_array, &dvert_tot);
|
||||
|
||||
if(dvert_array) {
|
||||
for(i = 0; i < dvert_tot; i++) {
|
||||
int j;
|
||||
dvert = dvert_array+i;
|
||||
j= dvert->totweight;
|
||||
|
||||
while(j--) {
|
||||
|
||||
if(keep_single && dvert->totweight == 1)
|
||||
break;
|
||||
|
||||
dw= dvert->dw + j;
|
||||
|
||||
if(dw->weight <= eul)
|
||||
ED_vgroup_nr_vert_remove(ob, dw->def_nr, i);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void vgroup_delete_update_users(Object *ob, int id)
|
||||
{
|
||||
ExplodeModifierData *emd;
|
||||
|
@ -640,22 +940,13 @@ static void vgroup_delete_object_mode(Object *ob)
|
|||
bDeformGroup *dg;
|
||||
MDeformVert *dvert, *dvert_array=NULL;
|
||||
int i, e, dvert_tot=0;
|
||||
|
||||
if(ob->type == OB_MESH) {
|
||||
Mesh *me = get_mesh(ob);
|
||||
dvert_array= me->dvert;
|
||||
dvert_tot= me->totvert;
|
||||
}
|
||||
else if(ob->type == OB_LATTICE) {
|
||||
Lattice *lt= (Lattice *)ob->data;
|
||||
dvert_array= lt->dvert;
|
||||
dvert_tot= lt->pntsu*lt->pntsv*lt->pntsw;
|
||||
}
|
||||
|
||||
dg = BLI_findlink(&ob->defbase, (ob->actdef-1));
|
||||
if(!dg)
|
||||
return;
|
||||
|
||||
ED_vgroup_give_array(ob->data, &dvert_array, &dvert_tot);
|
||||
|
||||
if(dvert_array) {
|
||||
for(i = 0; i < dvert_tot; i++) {
|
||||
dvert = dvert_array + i;
|
||||
|
@ -874,6 +1165,8 @@ static void vgroup_assign_verts(Object *ob, float weight)
|
|||
int i, done;
|
||||
|
||||
dg=BLI_findlink(&ob->defbase, ob->actdef-1);
|
||||
if(!dg)
|
||||
return;
|
||||
|
||||
if(ob->type == OB_MESH) {
|
||||
Mesh *me= ob->data;
|
||||
|
@ -1173,6 +1466,161 @@ void OBJECT_OT_vertex_group_copy(wmOperatorType *ot)
|
|||
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
||||
}
|
||||
|
||||
|
||||
static int vertex_group_normalize_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
|
||||
|
||||
vgroup_normalize(ob);
|
||||
|
||||
DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
|
||||
WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
|
||||
WM_event_add_notifier(C, NC_GEOM|ND_DATA, ob->data);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
void OBJECT_OT_vertex_group_normalize(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name= "Normalize Vertex Group";
|
||||
ot->idname= "OBJECT_OT_vertex_group_normalize";
|
||||
|
||||
/* api callbacks */
|
||||
ot->poll= vertex_group_poll;
|
||||
ot->exec= vertex_group_normalize_exec;
|
||||
|
||||
/* flags */
|
||||
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
||||
}
|
||||
|
||||
static int vertex_group_normalize_all_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
|
||||
int lock_active= RNA_boolean_get(op->ptr,"lock_active");
|
||||
|
||||
vgroup_normalize_all(ob, lock_active);
|
||||
|
||||
DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
|
||||
WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
|
||||
WM_event_add_notifier(C, NC_GEOM|ND_DATA, ob->data);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
void OBJECT_OT_vertex_group_normalize_all(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name= "Normalize All Vertex Groups";
|
||||
ot->idname= "OBJECT_OT_vertex_group_normalize_all";
|
||||
|
||||
/* api callbacks */
|
||||
ot->poll= vertex_group_poll;
|
||||
ot->exec= vertex_group_normalize_all_exec;
|
||||
|
||||
/* flags */
|
||||
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
||||
|
||||
RNA_def_boolean(ot->srna, "lock_active", TRUE, "Lock Active", "Keep the values of the active group while normalizing others.");
|
||||
}
|
||||
|
||||
static int vertex_group_invert_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
|
||||
int auto_assign= RNA_boolean_get(op->ptr,"auto_assign");
|
||||
int auto_remove= RNA_boolean_get(op->ptr,"auto_remove");
|
||||
|
||||
vgroup_invert(ob, auto_assign, auto_remove);
|
||||
DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
|
||||
WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
|
||||
WM_event_add_notifier(C, NC_GEOM|ND_DATA, ob->data);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
void OBJECT_OT_vertex_group_invert(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name= "Invert Vertex Group";
|
||||
ot->idname= "OBJECT_OT_vertex_group_invert";
|
||||
|
||||
/* api callbacks */
|
||||
ot->poll= vertex_group_poll;
|
||||
ot->exec= vertex_group_invert_exec;
|
||||
|
||||
/* flags */
|
||||
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
||||
|
||||
RNA_def_boolean(ot->srna, "auto_assign", TRUE, "Add Weights", "Add verts from groups that have zero weight before inverting.");
|
||||
RNA_def_boolean(ot->srna, "auto_remove", TRUE, "Remove Weights", "Remove verts from groups that have zero weight after inverting.");
|
||||
}
|
||||
|
||||
|
||||
static int vertex_group_blend_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
|
||||
|
||||
vgroup_blend(ob);
|
||||
|
||||
DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
|
||||
WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
|
||||
WM_event_add_notifier(C, NC_GEOM|ND_DATA, ob->data);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
void OBJECT_OT_vertex_group_blend(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name= "Blend Vertex Group";
|
||||
ot->idname= "OBJECT_OT_vertex_group_blend";
|
||||
|
||||
/* api callbacks */
|
||||
ot->poll= vertex_group_poll;
|
||||
ot->exec= vertex_group_blend_exec;
|
||||
|
||||
/* flags */
|
||||
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
||||
}
|
||||
|
||||
|
||||
static int vertex_group_clean_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
|
||||
|
||||
float limit= RNA_float_get(op->ptr,"limit");
|
||||
int all_groups= RNA_boolean_get(op->ptr,"all_groups");
|
||||
int keep_single= RNA_boolean_get(op->ptr,"keep_single");
|
||||
|
||||
if(all_groups) vgroup_clean_all(ob, limit, keep_single);
|
||||
else vgroup_clean(ob, limit, keep_single);
|
||||
|
||||
DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
|
||||
WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
|
||||
WM_event_add_notifier(C, NC_GEOM|ND_DATA, ob->data);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
void OBJECT_OT_vertex_group_clean(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name= "Clean Vertex Group";
|
||||
ot->idname= "OBJECT_OT_vertex_group_clean";
|
||||
|
||||
/* api callbacks */
|
||||
ot->poll= vertex_group_poll;
|
||||
ot->exec= vertex_group_clean_exec;
|
||||
|
||||
/* flags */
|
||||
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
||||
|
||||
RNA_def_float(ot->srna, "limit", 0.01f, 0.0f, 1.0, "Limit", "Remove weights under this limit.", 0.001f, 0.99f);
|
||||
RNA_def_boolean(ot->srna, "all_groups", FALSE, "All Groups", "Clean all vertex groups.");
|
||||
RNA_def_boolean(ot->srna, "keep_single", FALSE, "Keep Single", "Keep verts assigned to at least one group when cleaning.");
|
||||
}
|
||||
|
||||
|
||||
static int vertex_group_copy_to_linked_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
Scene *scene= CTX_data_scene(C);
|
||||
|
|
|
@ -851,7 +851,7 @@ static void pe_deflect_emitter(Scene *scene, Object *ob, PTCacheEdit *edit)
|
|||
ParticleSystemModifierData *psmd;
|
||||
POINT_P; KEY_K;
|
||||
int index;
|
||||
float *vec, *nor, dvec[3], dot, dist_1st;
|
||||
float *vec, *nor, dvec[3], dot, dist_1st=0.0f;
|
||||
float hairimat[4][4], hairmat[4][4];
|
||||
|
||||
if(edit==NULL || edit->psys==NULL || (pset->flag & PE_DEFLECT_EMITTER)==0 || (edit->psys->flag & PSYS_GLOBAL_HAIR))
|
||||
|
@ -2708,6 +2708,10 @@ static void brush_cut(PEData *data, int pa_index)
|
|||
/* blunt scissors */
|
||||
if(BLI_frand() > data->cutfac) return;
|
||||
|
||||
/* don't cut hidden */
|
||||
if(edit->points[pa_index].flag & PEP_HIDE)
|
||||
return;
|
||||
|
||||
rad2= data->rad * data->rad;
|
||||
|
||||
cut=0;
|
||||
|
@ -2791,7 +2795,7 @@ static void brush_length(PEData *data, int point_index)
|
|||
PTCacheEdit *edit= data->edit;
|
||||
PTCacheEditPoint *point = edit->points + point_index;
|
||||
KEY_K;
|
||||
float dvec[3],pvec[3];
|
||||
float dvec[3],pvec[3] = {0.0f, 0.0f, 0.0f};
|
||||
|
||||
LOOP_KEYS {
|
||||
if(k==0) {
|
||||
|
@ -2815,7 +2819,7 @@ static void brush_puff(PEData *data, int point_index)
|
|||
PTCacheEditPoint *point = edit->points + point_index;
|
||||
KEY_K;
|
||||
float mat[4][4], imat[4][4];
|
||||
float lastco[3], rootco[3], co[3], nor[3], kco[3], dco[3], fac, length;
|
||||
float lastco[3], rootco[3] = {0.0f, 0.0f, 0.0f}, co[3], nor[3], kco[3], dco[3], fac=0.0f, length=0.0f;
|
||||
|
||||
if(psys && !(psys->flag & PSYS_GLOBAL_HAIR)) {
|
||||
psys_mat_hair_to_global(data->ob, data->dm, psys->part->from, psys->particles + point_index, mat);
|
||||
|
@ -2897,7 +2901,7 @@ static void brush_smooth_do(PEData *data, float mat[][4], float imat[][4], int p
|
|||
(data->edit->points + point_index)->flag |= PEP_EDIT_RECALC;
|
||||
}
|
||||
|
||||
static void brush_add(PEData *data, short number)
|
||||
static int brush_add(PEData *data, short number)
|
||||
{
|
||||
Scene *scene= data->scene;
|
||||
Object *ob= data->ob;
|
||||
|
@ -2918,7 +2922,7 @@ static void brush_add(PEData *data, short number)
|
|||
Mat4Invert(imat,ob->obmat);
|
||||
|
||||
if(psys->flag & PSYS_GLOBAL_HAIR)
|
||||
return;
|
||||
return 0;
|
||||
|
||||
BLI_srandom(psys->seed+data->mval[0]+data->mval[1]);
|
||||
|
||||
|
@ -3093,6 +3097,8 @@ static void brush_add(PEData *data, short number)
|
|||
|
||||
if(!psmd->dm->deformedOnly)
|
||||
dm->release(dm);
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
/************************* brush edit operator ********************/
|
||||
|
@ -3143,7 +3149,7 @@ static void brush_edit_apply(bContext *C, wmOperator *op, PointerRNA *itemptr)
|
|||
ARegion *ar= CTX_wm_region(C);
|
||||
float vec[3], mousef[2];
|
||||
short mval[2], mvalo[2];
|
||||
int flip, mouse[2], dx, dy, removed= 0, selected= 0;
|
||||
int flip, mouse[2], dx, dy, removed= 0, added=0, selected= 0;
|
||||
int lock_root = pset->flag & PE_LOCK_FIRST;
|
||||
|
||||
if(!PE_start_edit(edit))
|
||||
|
@ -3221,6 +3227,9 @@ static void brush_edit_apply(bContext *C, wmOperator *op, PointerRNA *itemptr)
|
|||
if(pset->flag & PE_KEEP_LENGTHS)
|
||||
recalc_lengths(edit);
|
||||
}
|
||||
else
|
||||
removed= 0;
|
||||
|
||||
break;
|
||||
}
|
||||
case PE_BRUSH_LENGTH:
|
||||
|
@ -3275,11 +3284,13 @@ static void brush_edit_apply(bContext *C, wmOperator *op, PointerRNA *itemptr)
|
|||
PE_set_view3d_data(C, &data);
|
||||
data.mval= mval;
|
||||
|
||||
brush_add(&data, brush->strength);
|
||||
added= brush_add(&data, brush->strength);
|
||||
|
||||
if(pset->flag & PE_KEEP_LENGTHS)
|
||||
recalc_lengths(edit);
|
||||
}
|
||||
else
|
||||
added= 0;
|
||||
break;
|
||||
}
|
||||
case PE_BRUSH_SMOOTH:
|
||||
|
@ -3310,13 +3321,15 @@ static void brush_edit_apply(bContext *C, wmOperator *op, PointerRNA *itemptr)
|
|||
if((pset->flag & PE_KEEP_LENGTHS)==0)
|
||||
recalc_lengths(edit);
|
||||
|
||||
if(pset->brushtype == PE_BRUSH_ADD || removed) {
|
||||
if(pset->brushtype == PE_BRUSH_ADD && (pset->flag & PE_X_MIRROR))
|
||||
PE_mirror_x(scene, ob, 1);
|
||||
if(ELEM(pset->brushtype, PE_BRUSH_ADD, PE_BRUSH_CUT)) {
|
||||
if(added || removed) {
|
||||
if(pset->brushtype == PE_BRUSH_ADD && (pset->flag & PE_X_MIRROR))
|
||||
PE_mirror_x(scene, ob, 1);
|
||||
|
||||
update_world_cos(ob,edit);
|
||||
psys_free_path_cache(NULL, edit);
|
||||
DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
|
||||
update_world_cos(ob,edit);
|
||||
psys_free_path_cache(NULL, edit);
|
||||
DAG_id_flush_update(&ob->id, OB_RECALC_DATA);
|
||||
}
|
||||
}
|
||||
else
|
||||
PE_update_object(scene, ob, 1);
|
||||
|
|
|
@ -386,6 +386,90 @@ void PARTICLE_OT_dupliob_move_up(wmOperatorType *ot)
|
|||
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
||||
}
|
||||
|
||||
/********************** particle dupliweight operators *********************/
|
||||
|
||||
static int copy_particle_dupliob_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem);
|
||||
ParticleSystem *psys= ptr.data;
|
||||
ParticleSettings *part;
|
||||
ParticleDupliWeight *dw;
|
||||
|
||||
if(!psys)
|
||||
return OPERATOR_CANCELLED;
|
||||
part = psys->part;
|
||||
for(dw=part->dupliweights.first; dw; dw=dw->next) {
|
||||
if(dw->flag & PART_DUPLIW_CURRENT) {
|
||||
dw->flag &= ~PART_DUPLIW_CURRENT;
|
||||
dw = MEM_dupallocN(dw);
|
||||
dw->flag |= PART_DUPLIW_CURRENT;
|
||||
BLI_addhead(&part->dupliweights, dw);
|
||||
|
||||
WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, NULL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
void PARTICLE_OT_dupliob_copy(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name= "Copy Particle Dupliob";
|
||||
ot->idname= "PARTICLE_OT_dupliob_copy";
|
||||
ot->description="Duplicate the current dupliobject.";
|
||||
|
||||
/* api callbacks */
|
||||
ot->exec= copy_particle_dupliob_exec;
|
||||
|
||||
/* flags */
|
||||
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
||||
}
|
||||
|
||||
static int remove_particle_dupliob_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
PointerRNA ptr = CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem);
|
||||
ParticleSystem *psys= ptr.data;
|
||||
ParticleSettings *part;
|
||||
ParticleDupliWeight *dw;
|
||||
|
||||
if(!psys)
|
||||
return OPERATOR_CANCELLED;
|
||||
|
||||
part = psys->part;
|
||||
for(dw=part->dupliweights.first; dw; dw=dw->next) {
|
||||
if(dw->flag & PART_DUPLIW_CURRENT) {
|
||||
BLI_remlink(&part->dupliweights, dw);
|
||||
MEM_freeN(dw);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
dw = part->dupliweights.last;
|
||||
|
||||
if(dw)
|
||||
dw->flag |= PART_DUPLIW_CURRENT;
|
||||
|
||||
WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, NULL);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
void PARTICLE_OT_dupliob_remove(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name= "Remove Particle Dupliobject";
|
||||
ot->idname= "PARTICLE_OT_dupliob_remove";
|
||||
ot->description="Remove the selected dupliobject.";
|
||||
|
||||
/* api callbacks */
|
||||
ot->exec= remove_particle_dupliob_exec;
|
||||
|
||||
/* flags */
|
||||
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
||||
}
|
||||
|
||||
/************************ move down particle dupliweight operator *********************/
|
||||
|
||||
static int dupliob_move_down_exec(bContext *C, wmOperator *op)
|
||||
|
@ -517,7 +601,7 @@ static void connect_hair(Scene *scene, Object *ob, ParticleSystem *psys)
|
|||
ParticleData *pa;
|
||||
PTCacheEdit *edit;
|
||||
PTCacheEditPoint *point;
|
||||
PTCacheEditKey *ekey;
|
||||
PTCacheEditKey *ekey = NULL;
|
||||
HairKey *key;
|
||||
BVHTreeFromMesh bvhtree;
|
||||
BVHTreeNearest nearest;
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue