diff options
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/collada/AnimationCurveCache.cpp | 391 | ||||
-rw-r--r-- | source/blender/collada/AnimationCurveCache.h | 130 | ||||
-rw-r--r-- | source/blender/editors/armature/editarmature_retarget.c | 2644 | ||||
-rw-r--r-- | source/blender/editors/include/ED_keymap_templates.h | 32 | ||||
-rw-r--r-- | source/blender/editors/sculpt_paint/paint_ops.c | 1 | ||||
-rw-r--r-- | source/blender/editors/space_logic/space_logic.c | 363 | ||||
-rw-r--r-- | source/blender/editors/space_time/space_time.c | 834 | ||||
-rw-r--r-- | source/blender/editors/space_time/time_ops.c | 218 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_sensor.c | 939 | ||||
-rw-r--r-- | source/blender/render/intern/source/voxeldata.c | 571 |
10 files changed, 0 insertions, 6123 deletions
diff --git a/source/blender/collada/AnimationCurveCache.cpp b/source/blender/collada/AnimationCurveCache.cpp deleted file mode 100644 index f580ffce7bb..00000000000 --- a/source/blender/collada/AnimationCurveCache.cpp +++ /dev/null @@ -1,391 +0,0 @@ -/* -* ***** BEGIN GPL LICENSE BLOCK ***** -* -* This program is free software; you can redistribute it and/or -* modify it under the terms of the GNU General Public License -* as published by the Free Software Foundation; either version 2 -* of the License, or (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program; if not, write to the Free Software Foundation, -* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -* -* Contributor(s): Chingiz Dyussenov, Arystanbek Dyussenov, Jan Diederich, Tod Liverseed. -* -* ***** END GPL LICENSE BLOCK ***** -*/ - -#include "AnimationCurveCache.h" - -extern "C" { -#include "BKE_action.h" -#include "BLI_listbase.h" -} - -AnimationCurveCache::AnimationCurveCache(bContext *C): - mContext(C) -{ -} - -AnimationCurveCache::~AnimationCurveCache() -{ - clear_cache(); -} - -void AnimationCurveCache::clear_cache() -{ - -} - -void AnimationCurveCache::clear_cache(Object *ob) -{ - -} - -void AnimationCurveCache::create_curves(Object *ob) -{ - -} - -void AnimationCurveCache::addObject(Object *ob) -{ - cached_objects.push_back(ob); -} - -bool AnimationCurveCache::bone_matrix_local_get(Object *ob, Bone *bone, float(&mat)[4][4], bool for_opensim) -{ - - /* Ok, lets be super cautious and check if the bone exists */ - bPose *pose = ob->pose; - bPoseChannel *pchan = BKE_pose_channel_find_name(pose, bone->name); - if (!pchan) { - return false; - } - - bAction *action = bc_getSceneObjectAction(ob); - bPoseChannel *parchan = pchan->parent; - enable_fcurves(action, bone->name); - float ipar[4][4]; - - if (bone->parent) { - invert_m4_m4(ipar, parchan->pose_mat); - mul_m4_m4m4(mat, ipar, pchan->pose_mat); - } - else - copy_m4_m4(mat, pchan->pose_mat); - - /* OPEN_SIM_COMPATIBILITY - * AFAIK animation to second life is via BVH, but no - * reason to not have the collada-animation be correct - */ - if (for_opensim) { - float temp[4][4]; - copy_m4_m4(temp, bone->arm_mat); - temp[3][0] = temp[3][1] = temp[3][2] = 0.0f; - invert_m4(temp); - - mul_m4_m4m4(mat, mat, temp); - - if (bone->parent) { - copy_m4_m4(temp, bone->parent->arm_mat); - temp[3][0] = temp[3][1] = temp[3][2] = 0.0f; - - mul_m4_m4m4(mat, temp, mat); - } - } - - return true; -} - -void AnimationCurveCache::sampleMain(Scene *scene, BC_export_transformation_type atm_type, bool for_opensim) -{ - std::map<int, std::vector<SamplePoint>>::iterator frame; - for (frame = sample_frames.begin(); frame != sample_frames.end(); frame++) { - int frame_index = frame->first; - std::vector<SamplePoint> sample_points = frame->second; - - bc_update_scene(mContext, scene, frame_index); - - for (int spi = 0; spi < sample_points.size(); spi++) { - SamplePoint &point = sample_points[spi]; - Object *ob = point.get_object(); - float mat[4][4]; - - if (ob->type == OB_ARMATURE) { - /* For Armatures we need to check if this maybe is a pose sample point*/ - Bone *bone = point.get_bone(); - if (bone) { - if (bone_matrix_local_get(ob, bone, mat, for_opensim)) { - point.set_matrix(mat); - } - continue; - } - } - - /* When this SamplePoint is not for a Bone, - * then we just store the Object local matrix here - */ - - BKE_object_matrix_local_get(ob, mat); - point.set_matrix(mat); - - } - } -} - -/* -* enable fcurves driving a specific bone, disable all the rest -* if bone_name = NULL enable all fcurves -*/ -void AnimationCurveCache::enable_fcurves(bAction *act, char *bone_name) -{ - FCurve *fcu; - char prefix[200]; - - if (bone_name) - BLI_snprintf(prefix, sizeof(prefix), "pose.bones[\"%s\"]", bone_name); - - for (fcu = (FCurve *)act->curves.first; fcu; fcu = fcu->next) { - if (bone_name) { - if (STREQLEN(fcu->rna_path, prefix, strlen(prefix))) - fcu->flag &= ~FCURVE_DISABLED; - else - fcu->flag |= FCURVE_DISABLED; - } - else { - fcu->flag &= ~FCURVE_DISABLED; - } - } -} -/* -* Sample the scene at frames where object fcurves -* have defined keys. -*/ -void AnimationCurveCache::sampleScene(Scene *scene, BC_export_transformation_type atm_type, bool for_opensim, bool keyframe_at_end) -{ - create_sample_frames_from_keyframes(); - sampleMain(scene, atm_type, for_opensim); -} - -void AnimationCurveCache::sampleScene(Scene *scene, BC_export_transformation_type atm_type, int sampling_rate, bool for_opensim, bool keyframe_at_end) -{ - create_sample_frames_generated(scene->r.sfra, scene->r.efra, sampling_rate, keyframe_at_end); - sampleMain(scene, atm_type, for_opensim); -} - -std::vector<FCurve *> *AnimationCurveCache::getSampledCurves(Object *ob) -{ - std::map<Object *, std::vector<FCurve *>>::iterator fcurves; - fcurves = cached_curves.find(ob); - return (fcurves == cached_curves.end()) ? NULL : &fcurves->second; -} - -std::vector<SamplePoint> &AnimationCurveCache::getFrameInfos(int frame_index) -{ - std::map<int, std::vector<SamplePoint>>::iterator frames = sample_frames.find(frame_index); - if (frames == sample_frames.end()) { - std::vector<SamplePoint> sample_points; - sample_frames[frame_index] = sample_points; - } - return sample_frames[frame_index]; -} - - -void AnimationCurveCache::add_sample_point(SamplePoint &point) -{ - int frame_index = point.get_frame(); - std::vector<SamplePoint> &frame_infos = getFrameInfos(frame_index); - frame_infos.push_back(point); -} - -/* -* loop over all cached objects -* loop over all fcurves -* record all keyframes -* -* The vector sample_frames finally contains a list of vectors -* where each vector contains a list of SamplePoints which -* need to be processed when evaluating the animation. -*/ -void AnimationCurveCache::create_sample_frames_from_keyframes() -{ - sample_frames.clear(); - for (int i = 0; i < cached_objects.size(); i++) { - Object *ob = cached_objects[i]; - bAction *action = bc_getSceneObjectAction(ob); - FCurve *fcu = (FCurve *)action->curves.first; - - for (; fcu; fcu = fcu->next) { - for (unsigned int i = 0; i < fcu->totvert; i++) { - float f = fcu->bezt[i].vec[1][0]; - int frame_index = int(f); - SamplePoint sample_point(frame_index, ob, fcu, i); - add_sample_point(sample_point); - } - } - } -} - -/* -* loop over all cached objects -* loop over active action using a stesize of sampling_rate -* record all frames -* -* The vector sample_frames finally contains a list of vectors -* where each vector contains a list of SamplePoints which -* need to be processed when evaluating the animation. -* Note: The FCurves of the objects will not be used here. -*/ -void AnimationCurveCache::create_sample_frames_generated(float sfra, float efra, int sampling_rate, int keyframe_at_end) -{ - sample_frames.clear(); - - for (int i = 0; i < cached_objects.size(); i++) { - - Object *ob = cached_objects[i]; - float f = sfra; - - do { - int frame_index = int(f); - SamplePoint sample_point(frame_index, ob); - add_sample_point(sample_point); - - /* Depending on the Object type add more sample points here - */ - - if (ob && ob->type == OB_ARMATURE) { - LISTBASE_FOREACH(bPoseChannel *, pchan, &ob->pose->chanbase) { - SamplePoint point(frame_index, ob, pchan->bone); - add_sample_point(sample_point); - } - } - - if (f == efra) - break; - f += sampling_rate; - if (f > efra) - if (keyframe_at_end) - f = efra; // make sure the last frame is always exported - else - break; - } while (true); - } -} - -Matrix::Matrix() -{ - unit_m4(matrix); -} - -Matrix::Matrix(float (&mat)[4][4]) -{ - set_matrix(mat); -} - -void Matrix::set_matrix(float(&mat)[4][4]) -{ - copy_m4_m4(matrix, mat); -} - -void Matrix::set_matrix(Matrix &mat) -{ - copy_m4_m4(matrix, mat.matrix); -} - -void Matrix::get_matrix(float(&mat)[4][4]) -{ - copy_m4_m4(mat, matrix); -} - -SamplePoint::SamplePoint(int frame, Object *ob) -{ - this->frame = frame; - this->fcu = NULL; - this->ob = ob; - this->pose_bone = NULL; - this->index = -1; -} - -SamplePoint::SamplePoint(int frame, Object *ob, FCurve *fcu, int index) -{ - this->frame = frame; - this->fcu = fcu; - this->ob = ob; - this->pose_bone = NULL; - this->index = index; - this->path = std::string(fcu->rna_path); - - /* Further elaborate on what this Fcurve is doing by checking - * its rna_path - */ - - if (ob && ob->type == OB_ARMATURE) { - char *boneName = BLI_str_quoted_substrN(fcu->rna_path, "pose.bones["); - bPose *pose = ob->pose; - if (boneName) { - bPoseChannel *pchan = BKE_pose_channel_find_name(pose, boneName); - this->pose_bone = pchan->bone; - } - } -} - - -SamplePoint::SamplePoint(int frame, Object *ob, Bone *bone) -{ - this->frame = frame; - this->fcu = NULL; - this->ob = ob; - this->pose_bone = bone; - this->index = -1; - this->path = "pose.bones[\"" + id_name(bone) + "\"].matrix"; -} - -Matrix &SamplePoint::get_matrix() -{ - return matrix; -} - -void SamplePoint::set_matrix(Matrix &mat) -{ - this->matrix.set_matrix(mat); -} - -void SamplePoint::set_matrix(float(&mat)[4][4]) -{ - -} - -Object *SamplePoint::get_object() -{ - return this->ob; -} - -Bone *SamplePoint::get_bone() -{ - return this->pose_bone; -} - -FCurve *SamplePoint::get_fcurve() -{ - return this->fcu; -} - -int SamplePoint::get_frame() -{ - return this->frame; -} - -int SamplePoint::get_fcurve_index() -{ - return this->index; -} - -std::string &SamplePoint::get_path() -{ - return path; -} diff --git a/source/blender/collada/AnimationCurveCache.h b/source/blender/collada/AnimationCurveCache.h deleted file mode 100644 index 3d74e93758e..00000000000 --- a/source/blender/collada/AnimationCurveCache.h +++ /dev/null @@ -1,130 +0,0 @@ -/* -* ***** BEGIN GPL LICENSE BLOCK ***** -* -* This program is free software; you can redistribute it and/or -* modify it under the terms of the GNU General Public License -* as published by the Free Software Foundation; either version 2 -* of the License, or (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program; if not, write to the Free Software Foundation, -* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -* -* Contributor(s): Chingiz Dyussenov, Arystanbek Dyussenov, Jan Diederich, Tod Liverseed. -* -* ***** END GPL LICENSE BLOCK ***** -*/ - -#ifndef __ANIMATION_CURVE_CACHE_H__ -#define __ANIMATION_CURVE_CACHE_H__ - -#include <stdlib.h> -#include <stdio.h> -#include <math.h> -#include <vector> -#include <map> -#include <algorithm> // std::find - -#include "exportSettings.h" -#include "collada_utils.h" - -extern "C" -{ -#include "DNA_object_types.h" -#include "DNA_anim_types.h" -} - -class Matrix { -private: - float matrix[4][4]; -public: - Matrix(); - Matrix(float (&mat)[4][4]); - void set_matrix(float (&mat)[4][4]); - void set_matrix(Matrix &mat); - void get_matrix(float (&mat)[4][4]); -}; - -class SamplePoint { - -private: - - Object * ob; - Bone *pose_bone; - FCurve *fcu; - int frame; /* frame in timeline (not sure if we actually should store a float here) */ - int index; /* Keyframe index in fcurve (makes sense only when fcu is also set) */ - std::string path; /* Do not mixup with rna_path. It is used for different purposes! */ - - Matrix matrix; /* Local matrix, by default unit matrix, will be set when sampling */ - -public: - - SamplePoint(int frame, Object *ob); - SamplePoint(int frame, Object *ob, FCurve *fcu, int index); - SamplePoint(int frame, Object *ob, Bone *bone); - - Object *get_object(); - Bone *get_bone(); - FCurve *get_fcurve(); - int get_frame(); - int get_fcurve_index(); - Matrix &get_matrix(); - std::string &get_path(); - - void set_matrix(Matrix &matrix); - void set_matrix(float(&mat)[4][4]); -}; - - -class AnimationCurveCache { -private: - void clear_cache(); // remove all sampled FCurves - void clear_cache(Object *ob); //remove sampled FCurves for single object - void create_curves(Object *ob); - - std::vector<Object *> cached_objects; // list of objects for caching - std::map<Object *, std::vector<FCurve *>> cached_curves; //map of cached FCurves - std::map<int, std::vector<SamplePoint>> sample_frames; // list of frames where objects need to be sampled - - std::vector<SamplePoint> &getFrameInfos(int frame_index); - void add_sample_point(SamplePoint &point); - void enable_fcurves(bAction *act, char *bone_name); - bool bone_matrix_local_get(Object *ob, Bone *bone, float (&mat)[4][4], bool for_opensim); - - bContext *mContext; - -public: - - AnimationCurveCache(bContext *C); - ~AnimationCurveCache(); - - void addObject(Object *obj); - - void sampleMain(Scene *scene, - BC_export_transformation_type atm_type, - bool for_opensim); - - void sampleScene(Scene *scene, - BC_export_transformation_type atm_type, - bool for_opensim, - bool keyframe_at_end = true); // use keys from FCurves, use timeline boundaries - - void sampleScene(Scene *scene, - BC_export_transformation_type atm_type, - int sampling_rate, bool for_opensim, - bool keyframe_at_end = true ); // generate keyframes for frames use timeline boundaries - - std::vector<FCurve *> *getSampledCurves(Object *ob); - - void create_sample_frames_from_keyframes(); - void create_sample_frames_generated(float sfra, float efra, int sampling_rate, int keyframe_at_end); -}; - - -#endif diff --git a/source/blender/editors/armature/editarmature_retarget.c b/source/blender/editors/armature/editarmature_retarget.c deleted file mode 100644 index 0c770bcbcc4..00000000000 --- a/source/blender/editors/armature/editarmature_retarget.c +++ /dev/null @@ -1,2644 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * Contributor(s): Martin Poirier - * - * ***** END GPL LICENSE BLOCK ***** - * autoarmature.c: Interface for automagically manipulating armature (retarget, created, ...) - */ - -/** \file blender/editors/armature/editarmature_retarget.c - * \ingroup edarmature - */ - -#include "MEM_guardedalloc.h" - -#include "PIL_time.h" - -#include "DNA_armature_types.h" -#include "DNA_constraint_types.h" -#include "DNA_scene_types.h" -#include "DNA_object_types.h" - -#include "BLI_blenlib.h" -#include "BLI_math.h" - -#include "BKE_constraint.h" -#include "BKE_armature.h" -#include "BKE_context.h" -#include "BKE_main.h" - -#include "ED_armature.h" -#include "ED_undo.h" - -#include "BIF_retarget.h" - -#include "armature_intern.h" - -/************ RIG RETARGET DATA STRUCTURES ***************/ - -typedef struct MemoNode { - float weight; - int next; -} MemoNode; - -typedef struct RetargetParam { - RigGraph *rigg; - RigArc *iarc; - RigNode *inode_start; - bContext *context; -} RetargetParam; - -typedef enum { - RETARGET_LENGTH, - RETARGET_AGGRESSIVE -} RetargetMode; - -typedef enum { - METHOD_BRUTE_FORCE = 0, - METHOD_MEMOIZE = 1 -} RetargetMethod; - -typedef enum { - ARC_FREE = 0, - ARC_TAKEN = 1, - ARC_USED = 2 -} ArcUsageFlags; - -static RigGraph *GLOBAL_RIGG = NULL; - -/*******************************************************************************************************/ - -void exec_retargetArctoArc(TaskPool * __restrict pool, void *taskdata, int threadid); - -static void RIG_calculateEdgeAngles(RigEdge *edge_first, RigEdge *edge_second); -float rollBoneByQuat(EditBone *bone, float old_up_axis[3], float qrot[4]); - -/* two levels */ -#define SHAPE_LEVELS (SHAPE_RADIX * SHAPE_RADIX) - -/*********************************** EDITBONE UTILS ****************************************************/ - -static int countEditBoneChildren(ListBase *list, EditBone *parent) -{ - EditBone *ebone; - int count = 0; - - for (ebone = list->first; ebone; ebone = ebone->next) { - if (ebone->parent == parent) { - count++; - } - } - - return count; -} - -static EditBone *nextEditBoneChild(ListBase *list, EditBone *parent, int n) -{ - EditBone *ebone; - - for (ebone = list->first; ebone; ebone = ebone->next) { - if (ebone->parent == parent) { - if (n == 0) { - return ebone; - } - n--; - } - } - - return NULL; -} - -static void getEditBoneRollUpAxis(EditBone *bone, float roll, float up_axis[3]) -{ - float mat[3][3], nor[3]; - - sub_v3_v3v3(nor, bone->tail, bone->head); - - vec_roll_to_mat3(nor, roll, mat); - copy_v3_v3(up_axis, mat[2]); -} - -static float rollBoneByQuatAligned(EditBone *bone, float old_up_axis[3], float qrot[4], float qroll[4], float aligned_axis[3]) -{ - float nor[3], new_up_axis[3], x_axis[3], z_axis[3]; - - copy_v3_v3(new_up_axis, old_up_axis); - mul_qt_v3(qrot, new_up_axis); - - sub_v3_v3v3(nor, bone->tail, bone->head); - - cross_v3_v3v3(x_axis, nor, aligned_axis); - cross_v3_v3v3(z_axis, x_axis, nor); - - normalize_v3(new_up_axis); - normalize_v3(x_axis); - normalize_v3(z_axis); - - if (dot_v3v3(new_up_axis, x_axis) < 0) { - negate_v3(x_axis); - } - - if (dot_v3v3(new_up_axis, z_axis) < 0) { - negate_v3(z_axis); - } - - if (angle_normalized_v3v3(x_axis, new_up_axis) < angle_normalized_v3v3(z_axis, new_up_axis)) { - rotation_between_vecs_to_quat(qroll, new_up_axis, x_axis); /* set roll rotation quat */ - return ED_armature_ebone_roll_to_vector(bone, x_axis, false); - } - else { - rotation_between_vecs_to_quat(qroll, new_up_axis, z_axis); /* set roll rotation quat */ - return ED_armature_ebone_roll_to_vector(bone, z_axis, false); - } -} - -static float rollBoneByQuatJoint(RigEdge *edge, RigEdge *previous, float qrot[4], float qroll[4], float up_axis[3]) -{ - if (previous == NULL) { - /* default to up_axis if no previous */ - return rollBoneByQuatAligned(edge->bone, edge->up_axis, qrot, qroll, up_axis); - } - else { - float new_up_axis[3]; - float vec_first[3], vec_second[3], normal[3]; - - if (previous->bone) { - sub_v3_v3v3(vec_first, previous->bone->tail, previous->bone->head); - } - else if (previous->prev->bone) { - sub_v3_v3v3(vec_first, edge->bone->head, previous->prev->bone->tail); - } - else { - /* default to up_axis if first bone in the chain is an offset */ - return rollBoneByQuatAligned(edge->bone, edge->up_axis, qrot, qroll, up_axis); - } - - sub_v3_v3v3(vec_second, edge->bone->tail, edge->bone->head); - - normalize_v3(vec_first); - normalize_v3(vec_second); - - cross_v3_v3v3(normal, vec_first, vec_second); - normalize_v3(normal); - - axis_angle_to_quat(qroll, vec_second, edge->up_angle); - - mul_qt_v3(qroll, normal); - - copy_v3_v3(new_up_axis, edge->up_axis); - mul_qt_v3(qrot, new_up_axis); - - normalize_v3(new_up_axis); - - /* real qroll between normal and up_axis */ - rotation_between_vecs_to_quat(qroll, new_up_axis, normal); - - return ED_armature_ebone_roll_to_vector(edge->bone, normal, false); - } -} - -float rollBoneByQuat(EditBone *bone, float old_up_axis[3], float qrot[4]) -{ - float new_up_axis[3]; - - copy_v3_v3(new_up_axis, old_up_axis); - mul_qt_v3(qrot, new_up_axis); - - return ED_armature_ebone_roll_to_vector(bone, new_up_axis, false); -} - -/************************************ DESTRUCTORS ******************************************************/ - -static void RIG_freeRigArc(BArc *arc) -{ - BLI_freelistN(&((RigArc *)arc)->edges); -} - -void RIG_freeRigGraph(BGraph *rg) -{ - RigGraph *rigg = (RigGraph *)rg; - BNode *node; - BArc *arc; - - BLI_task_pool_free(rigg->task_pool); - BLI_task_scheduler_free(rigg->task_scheduler); - - if (rigg->link_mesh) { - REEB_freeGraph(rigg->link_mesh); - } - - for (arc = rg->arcs.first; arc; arc = arc->next) { - RIG_freeRigArc(arc); - } - BLI_freelistN(&rg->arcs); - - for (node = rg->nodes.first; node; node = node->next) { - BLI_freeNode(rg, (BNode *)node); - } - BLI_freelistN(&rg->nodes); - - BLI_freelistN(&rigg->controls); - - BLI_ghash_free(rigg->bones_map, NULL, NULL); - BLI_ghash_free(rigg->controls_map, NULL, NULL); - - if (rigg->flag & RIG_FREE_BONELIST) { - BLI_freelistN(rigg->editbones); - MEM_freeN(rigg->editbones); - } - - MEM_freeN(rg); -} - -/************************************* ALLOCATORS ******************************************************/ - -static RigGraph *newRigGraph(void) -{ - RigGraph *rg; - int totthread; - - rg = MEM_callocN(sizeof(RigGraph), "rig graph"); - - rg->head = NULL; - - rg->bones_map = BLI_ghash_str_new("newRigGraph bones gh"); - rg->controls_map = BLI_ghash_str_new("newRigGraph cont gh"); - - rg->free_arc = RIG_freeRigArc; - rg->free_node = NULL; - -#ifdef USE_THREADS - totthread = TASK_SCHEDULER_AUTO_THREADS; -#else - totthread = TASK_SCHEDULER_SINGLE_THREAD; -#endif - - rg->task_scheduler = BLI_task_scheduler_create(totthread); - rg->task_pool = BLI_task_pool_create(rg->task_scheduler, NULL); - - return rg; -} - -static RigArc *newRigArc(RigGraph *rg) -{ - RigArc *arc; - - arc = MEM_callocN(sizeof(RigArc), "rig arc"); - arc->count = 0; - BLI_addtail(&rg->arcs, arc); - - return arc; -} - -static RigControl *newRigControl(RigGraph *rg) -{ - RigControl *ctrl; - - ctrl = MEM_callocN(sizeof(RigControl), "rig control"); - - BLI_addtail(&rg->controls, ctrl); - - return ctrl; -} - -static RigNode *newRigNodeHead(RigGraph *rg, RigArc *arc, float p[3]) -{ - RigNode *node; - node = MEM_callocN(sizeof(RigNode), "rig node"); - BLI_addtail(&rg->nodes, node); - - copy_v3_v3(node->p, p); - node->degree = 1; - node->arcs = NULL; - - arc->head = node; - - return node; -} - -static void addRigNodeHead(RigGraph *UNUSED(rg), RigArc *arc, RigNode *node) -{ - node->degree++; - - arc->head = node; -} - -static RigNode *newRigNode(RigGraph *rg, float p[3]) -{ - RigNode *node; - node = MEM_callocN(sizeof(RigNode), "rig node"); - BLI_addtail(&rg->nodes, node); - - copy_v3_v3(node->p, p); - node->degree = 0; - node->arcs = NULL; - - return node; -} - -static RigNode *newRigNodeTail(RigGraph *rg, RigArc *arc, float p[3]) -{ - RigNode *node = newRigNode(rg, p); - - node->degree = 1; - arc->tail = node; - - return node; -} - -static void RIG_appendEdgeToArc(RigArc *arc, RigEdge *edge) -{ - BLI_addtail(&arc->edges, edge); - - if (edge->prev == NULL) { - copy_v3_v3(edge->head, arc->head->p); - } - else { - RigEdge *last_edge = edge->prev; - copy_v3_v3(edge->head, last_edge->tail); - RIG_calculateEdgeAngles(last_edge, edge); - } - - edge->length = len_v3v3(edge->head, edge->tail); - - arc->length += edge->length; - - arc->count += 1; -} - -static void RIG_addEdgeToArc(RigArc *arc, float tail[3], EditBone *bone) -{ - RigEdge *edge; - - edge = MEM_callocN(sizeof(RigEdge), "rig edge"); - - copy_v3_v3(edge->tail, tail); - edge->bone = bone; - - if (bone) { - getEditBoneRollUpAxis(bone, bone->roll, edge->up_axis); - } - - RIG_appendEdgeToArc(arc, edge); -} -/************************************** CLONING TEMPLATES **********************************************/ - -static void renameTemplateBone(char *name, char *template_name, ListBase *editbones, char *side_string, char *num_string) -{ - int i, j; - - for (i = 0, j = 0; i < (MAXBONENAME - 1) && j < (MAXBONENAME - 1) && template_name[i] != '\0'; i++) { - if (template_name[i] == '&') { - if (template_name[i + 1] == 'S' || template_name[i + 1] == 's') { - j += BLI_strncpy_rlen(name + j, side_string, MAXBONENAME); - i++; - } - else if (template_name[i + 1] == 'N' || template_name[i + 1] == 'n') { - j += BLI_strncpy_rlen(name + j, num_string, MAXBONENAME); - i++; - } - else { - name[j] = template_name[i]; - j++; - } - } - else { - name[j] = template_name[i]; - j++; - } - } - - name[j] = '\0'; - - ED_armature_ebone_unique_name(editbones, name, NULL); -} - -static RigControl *cloneControl(RigGraph *rg, RigGraph *src_rg, RigControl *src_ctrl, GHash *ptr_hash, char *side_string, char *num_string) -{ - RigControl *ctrl; - char name[MAXBONENAME]; - - ctrl = newRigControl(rg); - - copy_v3_v3(ctrl->head, src_ctrl->head); - copy_v3_v3(ctrl->tail, src_ctrl->tail); - copy_v3_v3(ctrl->up_axis, src_ctrl->up_axis); - copy_v3_v3(ctrl->offset, src_ctrl->offset); - - ctrl->tail_mode = src_ctrl->tail_mode; - ctrl->flag = src_ctrl->flag; - - renameTemplateBone(name, src_ctrl->bone->name, rg->editbones, side_string, num_string); - ctrl->bone = duplicateEditBoneObjects(src_ctrl->bone, name, rg->editbones, src_rg->ob, rg->ob); - ctrl->bone->flag &= ~(BONE_TIPSEL | BONE_SELECTED | BONE_ROOTSEL); - BLI_ghash_insert(ptr_hash, src_ctrl->bone, ctrl->bone); - - ctrl->link = src_ctrl->link; - ctrl->link_tail = src_ctrl->link_tail; - - return ctrl; -} - -static RigArc *cloneArc(RigGraph *rg, RigGraph *src_rg, RigArc *src_arc, GHash *ptr_hash, char *side_string, char *num_string) -{ - RigEdge *src_edge; - RigArc *arc; - - arc = newRigArc(rg); - - arc->head = BLI_ghash_lookup(ptr_hash, src_arc->head); - arc->tail = BLI_ghash_lookup(ptr_hash, src_arc->tail); - - arc->head->degree++; - arc->tail->degree++; - - arc->length = src_arc->length; - - arc->count = src_arc->count; - - for (src_edge = src_arc->edges.first; src_edge; src_edge = src_edge->next) { - RigEdge *edge; - - edge = MEM_callocN(sizeof(RigEdge), "rig edge"); - - copy_v3_v3(edge->head, src_edge->head); - copy_v3_v3(edge->tail, src_edge->tail); - copy_v3_v3(edge->up_axis, src_edge->up_axis); - - edge->length = src_edge->length; - edge->angle = src_edge->angle; - edge->up_angle = src_edge->up_angle; - - if (src_edge->bone != NULL) { - char name[MAXBONENAME]; - renameTemplateBone(name, src_edge->bone->name, rg->editbones, side_string, num_string); - edge->bone = duplicateEditBoneObjects(src_edge->bone, name, rg->editbones, src_rg->ob, rg->ob); - edge->bone->flag &= ~(BONE_TIPSEL | BONE_SELECTED | BONE_ROOTSEL); - BLI_ghash_insert(ptr_hash, src_edge->bone, edge->bone); - } - - BLI_addtail(&arc->edges, edge); - } - - return arc; -} - -static RigGraph *cloneRigGraph(RigGraph *src, ListBase *editbones, Object *ob, char *side_string, char *num_string) -{ - GHash *ptr_hash; - RigNode *node; - RigArc *arc; - RigControl *ctrl; - RigGraph *rg; - - ptr_hash = BLI_ghash_ptr_new("cloneRigGraph gh"); - - rg = newRigGraph(); - - rg->ob = ob; - rg->editbones = editbones; - - preEditBoneDuplicate(rg->editbones); /* prime bones for duplication */ - preEditBoneDuplicate(src->editbones); /* prime bones for duplication */ - - /* Clone nodes */ - for (node = src->nodes.first; node; node = node->next) { - RigNode *cloned_node = newRigNode(rg, node->p); - BLI_ghash_insert(ptr_hash, node, cloned_node); - } - - rg->head = BLI_ghash_lookup(ptr_hash, src->head); - - /* Clone arcs */ - for (arc = src->arcs.first; arc; arc = arc->next) { - cloneArc(rg, src, arc, ptr_hash, side_string, num_string); - } - - /* Clone controls */ - for (ctrl = src->controls.first; ctrl; ctrl = ctrl->next) { - cloneControl(rg, src, ctrl, ptr_hash, side_string, num_string); - } - - /* Relink bones properly */ - for (arc = rg->arcs.first; arc; arc = arc->next) { - RigEdge *edge; - - for (edge = arc->edges.first; edge; edge = edge->next) { - if (edge->bone != NULL) { - EditBone *bone; - - updateDuplicateSubtargetObjects(edge->bone, src->editbones, src->ob, rg->ob); - - if (edge->bone->parent) { - bone = BLI_ghash_lookup(ptr_hash, edge->bone->parent); - - if (bone != NULL) { - edge->bone->parent = bone; - } - else { - /* disconnect since parent isn't cloned - * this will only happen when cloning from selected bones - * */ - edge->bone->flag &= ~BONE_CONNECTED; - } - } - } - } - } - - for (ctrl = rg->controls.first; ctrl; ctrl = ctrl->next) { - EditBone *bone; - - updateDuplicateSubtargetObjects(ctrl->bone, src->editbones, src->ob, rg->ob); - - if (ctrl->bone->parent) { - bone = BLI_ghash_lookup(ptr_hash, ctrl->bone->parent); - - if (bone != NULL) { - ctrl->bone->parent = bone; - } - else { - /* disconnect since parent isn't cloned - * this will only happen when cloning from selected bones - * */ - ctrl->bone->flag &= ~BONE_CONNECTED; - } - } - - ctrl->link = BLI_ghash_lookup(ptr_hash, ctrl->link); - ctrl->link_tail = BLI_ghash_lookup(ptr_hash, ctrl->link_tail); - } - - BLI_ghash_free(ptr_hash, NULL, NULL); - - return rg; -} - - -/*******************************************************************************************************/ - -static void RIG_calculateEdgeAngles(RigEdge *edge_first, RigEdge *edge_second) -{ - float vec_first[3], vec_second[3]; - - sub_v3_v3v3(vec_first, edge_first->tail, edge_first->head); - sub_v3_v3v3(vec_second, edge_second->tail, edge_second->head); - - normalize_v3(vec_first); - normalize_v3(vec_second); - - edge_first->angle = angle_normalized_v3v3(vec_first, vec_second); - - if (edge_second->bone != NULL) { - float normal[3]; - - cross_v3_v3v3(normal, vec_first, vec_second); - normalize_v3(normal); - - edge_second->up_angle = angle_normalized_v3v3(normal, edge_second->up_axis); - } -} - -/************************************ CONTROL BONES ****************************************************/ - -static void RIG_addControlBone(RigGraph *rg, EditBone *bone) -{ - RigControl *ctrl = newRigControl(rg); - ctrl->bone = bone; - copy_v3_v3(ctrl->head, bone->head); - copy_v3_v3(ctrl->tail, bone->tail); - getEditBoneRollUpAxis(bone, bone->roll, ctrl->up_axis); - ctrl->tail_mode = TL_NONE; - - BLI_ghash_insert(rg->controls_map, bone->name, ctrl); -} - -static int RIG_parentControl(RigControl *ctrl, EditBone *link) -{ - if (link) { - float offset[3]; - int flag = 0; - - sub_v3_v3v3(offset, ctrl->bone->head, link->head); - - /* if root matches, check for direction too */ - if (dot_v3v3(offset, offset) < 0.0001f) { - float vbone[3], vparent[3]; - - flag |= RIG_CTRL_FIT_ROOT; - - sub_v3_v3v3(vbone, ctrl->bone->tail, ctrl->bone->head); - sub_v3_v3v3(vparent, link->tail, link->head); - - /* test for opposite direction */ - if (dot_v3v3(vbone, vparent) > 0) { - float nor[3]; - float len; - - cross_v3_v3v3(nor, vbone, vparent); - - len = dot_v3v3(nor, nor); - if (len < 0.0001f) { - flag |= RIG_CTRL_FIT_BONE; - } - } - } - - /* Bail out if old one is automatically better */ - if (flag < ctrl->flag) { - return 0; - } - - /* if there's already a link - * overwrite only if new link is higher in the chain */ - if (ctrl->link && flag == ctrl->flag) { - EditBone *bone = NULL; - - for (bone = ctrl->link; bone; bone = bone->parent) { - /* if link is in the chain, break and use that one */ - if (bone == link) { - break; - } - } - - /* not in chain, don't update link */ - if (bone == NULL) { - return 0; - } - } - - - ctrl->link = link; - ctrl->flag = flag; - - copy_v3_v3(ctrl->offset, offset); - - return 1; - } - - return 0; -} - -static void RIG_reconnectControlBones(RigGraph *rg) -{ - RigControl *ctrl; - bool changed = true; - - /* first pass, link to deform bones */ - for (ctrl = rg->controls.first; ctrl; ctrl = ctrl->next) { - bPoseChannel *pchan; - bConstraint *con; - int found = 0; - - /* DO SOME MAGIC HERE */ - for (pchan = rg->ob->pose->chanbase.first; pchan; pchan = pchan->next) { - for (con = pchan->constraints.first; con; con = con->next) { - const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con); - ListBase targets = {NULL, NULL}; - bConstraintTarget *ct; - - /* constraint targets */ - if (cti && cti->get_constraint_targets) { - int target_index; - - cti->get_constraint_targets(con, &targets); - - for (target_index = 0, ct = targets.first; ct; target_index++, ct = ct->next) { - if ((ct->tar == rg->ob) && STREQ(ct->subtarget, ctrl->bone->name)) { - /* SET bone link to bone corresponding to pchan */ - EditBone *link = BLI_ghash_lookup(rg->bones_map, pchan->name); - - /* Making sure bone is in this armature */ - if (link != NULL) { - /* for pole targets, link to parent bone instead, if possible */ - if (con->type == CONSTRAINT_TYPE_KINEMATIC && target_index == 1) { - if (link->parent && BLI_ghash_haskey(rg->bones_map, link->parent->name)) { - link = link->parent; - } - } - - found = RIG_parentControl(ctrl, link); - } - } - } - - if (cti->flush_constraint_targets) - cti->flush_constraint_targets(con, &targets, 0); - } - } - } - - /* if not found yet, check parent */ - if (found == 0) { - if (ctrl->bone->parent) { - /* make sure parent is a deforming bone - * NULL if not - * */ - EditBone *link = BLI_ghash_lookup(rg->bones_map, ctrl->bone->parent->name); - - found = RIG_parentControl(ctrl, link); - } - - /* check if bone is not superposed on another one */ - { - RigArc *arc; - RigArc *best_arc = NULL; - EditBone *link = NULL; - - for (arc = rg->arcs.first; arc; arc = arc->next) { - RigEdge *edge; - for (edge = arc->edges.first; edge; edge = edge->next) { - if (edge->bone) { - int fit = 0; - - fit = len_v3v3(ctrl->bone->head, edge->bone->head) < 0.0001f; - fit = fit || len_v3v3(ctrl->bone->tail, edge->bone->tail) < 0.0001f; - - if (fit) { - /* pick the bone on the arc with the lowest symmetry level - * means you connect control to the trunk of the skeleton */ - if (best_arc == NULL || arc->symmetry_level < best_arc->symmetry_level) { - best_arc = arc; - link = edge->bone; - } - } - } - } - } - - found = RIG_parentControl(ctrl, link); - } - } - - /* if not found yet, check child */ - if (found == 0) { - RigArc *arc; - RigArc *best_arc = NULL; - EditBone *link = NULL; - - for (arc = rg->arcs.first; arc; arc = arc->next) { - RigEdge *edge; - for (edge = arc->edges.first; edge; edge = edge->next) { - if (edge->bone && edge->bone->parent == ctrl->bone) { - /* pick the bone on the arc with the lowest symmetry level - * means you connect control to the trunk of the skeleton */ - if (best_arc == NULL || arc->symmetry_level < best_arc->symmetry_level) { - best_arc = arc; - link = edge->bone; - } - } - } - } - - found = RIG_parentControl(ctrl, link); - } - - } - - - /* second pass, make chains in control bones */ - while (changed) { - changed = false; - - for (ctrl = rg->controls.first; ctrl; ctrl = ctrl->next) { - /* if control is not linked yet */ - if (ctrl->link == NULL) { - bPoseChannel *pchan; - bConstraint *con; - RigControl *ctrl_parent = NULL; - RigControl *ctrl_child; - int found = 0; - - if (ctrl->bone->parent) { - ctrl_parent = BLI_ghash_lookup(rg->controls_map, ctrl->bone->parent->name); - } - - /* check constraints first */ - - /* DO SOME MAGIC HERE */ - for (pchan = rg->ob->pose->chanbase.first; pchan; pchan = pchan->next) { - for (con = pchan->constraints.first; con; con = con->next) { - const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con); - ListBase targets = {NULL, NULL}; - bConstraintTarget *ct; - - /* constraint targets */ - if (cti && cti->get_constraint_targets) { - cti->get_constraint_targets(con, &targets); - - for (ct = targets.first; ct; ct = ct->next) { - if ((ct->tar == rg->ob) && STREQ(ct->subtarget, ctrl->bone->name)) { - /* SET bone link to ctrl corresponding to pchan */ - RigControl *link = BLI_ghash_lookup(rg->controls_map, pchan->name); - - /* if owner is a control bone, link with it */ - if (link && link->link) { - RIG_parentControl(ctrl, link->bone); - found = 1; - break; - } - } - } - - if (cti->flush_constraint_targets) - cti->flush_constraint_targets(con, &targets, 0); - } - } - } - - if (found == 0) { - /* check if parent is already linked */ - if (ctrl_parent && ctrl_parent->link) { - RIG_parentControl(ctrl, ctrl_parent->bone); - changed = true; - } - else { - /* check childs */ - for (ctrl_child = rg->controls.first; ctrl_child; ctrl_child = ctrl_child->next) { - /* if a child is linked, link to that one */ - if (ctrl_child->link && ctrl_child->bone->parent == ctrl->bone) { - RIG_parentControl(ctrl, ctrl_child->bone); - changed = true; - break; - } - } - } - } - } - } - } - - /* third pass, link control tails */ - for (ctrl = rg->controls.first; ctrl; ctrl = ctrl->next) { - /* fit bone already means full match, so skip those */ - if ((ctrl->flag & RIG_CTRL_FIT_BONE) == 0) { - GHashIterator ghi; - - /* look on deform bones first */ - BLI_ghashIterator_init(&ghi, rg->bones_map); - - for (; !BLI_ghashIterator_done(&ghi); BLI_ghashIterator_step(&ghi)) { - EditBone *bone = (EditBone *)BLI_ghashIterator_getValue(&ghi); - - /* don't link with parent */ - if (bone->parent != ctrl->bone) { - if (len_v3v3(ctrl->bone->tail, bone->head) < 0.01f) { - ctrl->tail_mode = TL_HEAD; - ctrl->link_tail = bone; - break; - } - else if (len_v3v3(ctrl->bone->tail, bone->tail) < 0.01f) { - ctrl->tail_mode = TL_TAIL; - ctrl->link_tail = bone; - break; - } - } - } - - /* if we haven't found one yet, look in control bones */ - if (ctrl->tail_mode == TL_NONE) { - /* pass */ - } - } - } - -} - -/*******************************************************************************************************/ - -static void RIG_joinArcs(RigGraph *rg, RigNode *node, RigArc *joined_arc1, RigArc *joined_arc2) -{ - RigEdge *edge, *next_edge; - - /* ignore cases where joint is at start or end */ - if (joined_arc1->head == joined_arc2->head || joined_arc1->tail == joined_arc2->tail) { - return; - } - - /* swap arcs to make sure arc1 is before arc2 */ - if (joined_arc1->head == joined_arc2->tail) { - RigArc *tmp = joined_arc1; - joined_arc1 = joined_arc2; - joined_arc2 = tmp; - } - - for (edge = joined_arc2->edges.first; edge; edge = next_edge) { - next_edge = edge->next; - - RIG_appendEdgeToArc(joined_arc1, edge); - } - - joined_arc1->tail = joined_arc2->tail; - - BLI_listbase_clear(&joined_arc2->edges); - - BLI_removeArc((BGraph *)rg, (BArc *)joined_arc2); - - BLI_removeNode((BGraph *)rg, (BNode *)node); -} - -static void RIG_removeNormalNodes(RigGraph *rg) -{ - RigNode *node, *next_node; - - for (node = rg->nodes.first; node; node = next_node) { - next_node = node->next; - - if (node->degree == 2) { - RigArc *arc, *joined_arc1 = NULL, *joined_arc2 = NULL; - - for (arc = rg->arcs.first; arc; arc = arc->next) { - if (arc->head == node || arc->tail == node) { - if (joined_arc1 == NULL) { - joined_arc1 = arc; - } - else { - joined_arc2 = arc; - break; - } - } - } - - RIG_joinArcs(rg, node, joined_arc1, joined_arc2); - } - } -} - -static void RIG_removeUneededOffsets(RigGraph *rg) -{ - RigArc *arc; - - for (arc = rg->arcs.first; arc; arc = arc->next) { - RigEdge *first_edge, *last_edge; - - first_edge = arc->edges.first; - last_edge = arc->edges.last; - - if (first_edge->bone == NULL) { - if (first_edge->bone == NULL && len_v3v3(first_edge->tail, arc->head->p) <= 0.001f) { - BLI_remlink(&arc->edges, first_edge); - MEM_freeN(first_edge); - } - else if (arc->head->degree == 1) { - RigNode *new_node = (RigNode *)BLI_FindNodeByPosition((BGraph *)rg, first_edge->tail, 0.001f); - - if (new_node) { - BLI_remlink(&arc->edges, first_edge); - MEM_freeN(first_edge); - BLI_replaceNodeInArc((BGraph *)rg, (BArc *)arc, (BNode *)new_node, (BNode *)arc->head); - } - else { - RigEdge *next_edge = first_edge->next; - - if (next_edge) { - BLI_remlink(&arc->edges, first_edge); - MEM_freeN(first_edge); - - copy_v3_v3(arc->head->p, next_edge->head); - } - } - } - else { - /* check if all arc connected start with a null edge */ - RigArc *other_arc; - for (other_arc = rg->arcs.first; other_arc; other_arc = other_arc->next) { - if (other_arc != arc) { - RigEdge *test_edge; - if (other_arc->head == arc->head) { - test_edge = other_arc->edges.first; - - if (test_edge->bone != NULL) { - break; - } - } - else if (other_arc->tail == arc->head) { - test_edge = other_arc->edges.last; - - if (test_edge->bone != NULL) { - break; - } - } - } - } - - if (other_arc == NULL) { - RigNode *new_node = (RigNode *)BLI_FindNodeByPosition((BGraph *)rg, first_edge->tail, 0.001); - - if (new_node) { - /* remove null edge in other arcs too */ - for (other_arc = rg->arcs.first; other_arc; other_arc = other_arc->next) { - if (other_arc != arc) { - RigEdge *test_edge; - if (other_arc->head == arc->head) { - BLI_replaceNodeInArc((BGraph *)rg, (BArc *)other_arc, (BNode *)new_node, (BNode *)other_arc->head); - test_edge = other_arc->edges.first; - BLI_remlink(&other_arc->edges, test_edge); - MEM_freeN(test_edge); - } - else if (other_arc->tail == arc->head) { - BLI_replaceNodeInArc((BGraph *)rg, (BArc *)other_arc, (BNode *)new_node, (BNode *)other_arc->tail); - test_edge = other_arc->edges.last; - BLI_remlink(&other_arc->edges, test_edge); - MEM_freeN(test_edge); - } - } - } - - BLI_remlink(&arc->edges, first_edge); - MEM_freeN(first_edge); - BLI_replaceNodeInArc((BGraph *)rg, (BArc *)arc, (BNode *)new_node, (BNode *)arc->head); - } - else { - RigEdge *next_edge = first_edge->next; - - if (next_edge) { - BLI_remlink(&arc->edges, first_edge); - MEM_freeN(first_edge); - - copy_v3_v3(arc->head->p, next_edge->head); - - /* remove null edge in other arcs too */ - for (other_arc = rg->arcs.first; other_arc; other_arc = other_arc->next) { - if (other_arc != arc) { - RigEdge *test_edge; - if (other_arc->head == arc->head) { - test_edge = other_arc->edges.first; - BLI_remlink(&other_arc->edges, test_edge); - MEM_freeN(test_edge); - } - else if (other_arc->tail == arc->head) { - test_edge = other_arc->edges.last; - BLI_remlink(&other_arc->edges, test_edge); - MEM_freeN(test_edge); - } - } - } - } - } - } - } - } - - if (last_edge->bone == NULL) { - if (len_v3v3(last_edge->head, arc->tail->p) <= 0.001f) { - BLI_remlink(&arc->edges, last_edge); - MEM_freeN(last_edge); - } - else if (arc->tail->degree == 1) { - RigNode *new_node = (RigNode *)BLI_FindNodeByPosition((BGraph *)rg, last_edge->head, 0.001f); - - if (new_node) { - RigEdge *previous_edge = last_edge->prev; - - BLI_remlink(&arc->edges, last_edge); - MEM_freeN(last_edge); - BLI_replaceNodeInArc((BGraph *)rg, (BArc *)arc, (BNode *)new_node, (BNode *)arc->tail); - - /* set previous angle to 0, since there's no following edges */ - if (previous_edge) { - previous_edge->angle = 0; - } - } - else { - RigEdge *previous_edge = last_edge->prev; - - if (previous_edge) { - BLI_remlink(&arc->edges, last_edge); - MEM_freeN(last_edge); - - copy_v3_v3(arc->tail->p, previous_edge->tail); - previous_edge->angle = 0; - } - } - } - } - } -} - -static void RIG_arcFromBoneChain(RigGraph *rg, ListBase *list, EditBone *root_bone, RigNode *starting_node, bool selected) -{ - EditBone *bone, *last_bone = root_bone; - RigArc *arc = NULL; - int contain_head = 0; - - for (bone = root_bone; bone; bone = nextEditBoneChild(list, bone, 0)) { - int nb_children; - - if (selected == 0 || (bone->flag & BONE_SELECTED)) { - if ((bone->flag & BONE_NO_DEFORM) == 0) { - BLI_ghash_insert(rg->bones_map, bone->name, bone); - - if (arc == NULL) { - arc = newRigArc(rg); - - if (starting_node == NULL) { - starting_node = newRigNodeHead(rg, arc, root_bone->head); - } - else { - addRigNodeHead(rg, arc, starting_node); - } - } - - if (bone->parent && (bone->flag & BONE_CONNECTED) == 0) { - RIG_addEdgeToArc(arc, bone->head, NULL); - } - - RIG_addEdgeToArc(arc, bone->tail, bone); - - last_bone = bone; - - if (STREQ(bone->name, "head")) { - contain_head = 1; - } - } - else if ((bone->flag & BONE_EDITMODE_LOCKED) == 0) { /* ignore locked bones */ - RIG_addControlBone(rg, bone); - } - } - - nb_children = countEditBoneChildren(list, bone); - if (nb_children > 1) { - RigNode *end_node = NULL; - int i; - - if (arc != NULL) { - end_node = newRigNodeTail(rg, arc, bone->tail); - } - else { - end_node = newRigNode(rg, bone->tail); - } - - for (i = 0; i < nb_children; i++) { - root_bone = nextEditBoneChild(list, bone, i); - RIG_arcFromBoneChain(rg, list, root_bone, end_node, selected); - } - - /* arc ends here, break */ - break; - } - } - - /* If the loop exited without forking */ - if (arc != NULL && bone == NULL) { - newRigNodeTail(rg, arc, last_bone->tail); - } - - if (contain_head) { - rg->head = arc->tail; - } -} - -/*******************************************************************************************************/ -static void RIG_findHead(RigGraph *rg) -{ - if (rg->head == NULL) { - if (BLI_listbase_is_single(&rg->arcs)) { - RigArc *arc = rg->arcs.first; - - rg->head = (RigNode *)arc->head; - } - else { - RigArc *arc; - - for (arc = rg->arcs.first; arc; arc = arc->next) { - RigEdge *edge = arc->edges.last; - - if (edge->bone->flag & (BONE_TIPSEL | BONE_SELECTED)) { - rg->head = arc->tail; - break; - } - } - } - - if (rg->head == NULL) { - rg->head = rg->nodes.first; - } - } -} - -/*******************************************************************************************************/ - -static void RIG_printNode(RigNode *node, const char name[]) -{ - printf("%s %p %i <%0.3f, %0.3f, %0.3f>\n", name, (void *)node, node->degree, node->p[0], node->p[1], node->p[2]); - - if (node->symmetry_flag & SYM_TOPOLOGICAL) { - if (node->symmetry_flag & SYM_AXIAL) - printf("Symmetry AXIAL\n"); - else if (node->symmetry_flag & SYM_RADIAL) - printf("Symmetry RADIAL\n"); - - print_v3("symmetry axis", node->symmetry_axis); - } -} - -void RIG_printArcBones(RigArc *arc) -{ - RigEdge *edge; - - for (edge = arc->edges.first; edge; edge = edge->next) { - if (edge->bone) - printf("%s ", edge->bone->name); - else - printf("---- "); - } - printf("\n"); -} - -static void RIG_printCtrl(RigControl *ctrl, char *indent) -{ - char text[128]; - - printf("%sBone: %s\n", indent, ctrl->bone->name); - printf("%sLink: %s\n", indent, ctrl->link ? ctrl->link->name : "!NONE!"); - - BLI_snprintf(text, sizeof(text), "%soffset", indent); - print_v3(text, ctrl->offset); - - printf("%sFlag: %i\n", indent, ctrl->flag); -} - -static void RIG_printLinkedCtrl(RigGraph *rg, EditBone *bone, int tabs) -{ - RigControl *ctrl; - char indent[64]; - char *s = indent; - int i; - - for (i = 0; i < tabs; i++) { - s[0] = '\t'; - s++; - } - s[0] = 0; - - for (ctrl = rg->controls.first; ctrl; ctrl = ctrl->next) { - if (ctrl->link == bone) { - RIG_printCtrl(ctrl, indent); - RIG_printLinkedCtrl(rg, ctrl->bone, tabs + 1); - } - } -} - -void RIG_printArc(RigGraph *rg, RigArc *arc) -{ - RigEdge *edge; - - RIG_printNode((RigNode *)arc->head, "head"); - - for (edge = arc->edges.first; edge; edge = edge->next) { - printf("\tinner joints %0.3f %0.3f %0.3f\n", edge->tail[0], edge->tail[1], edge->tail[2]); - printf("\t\tlength %f\n", edge->length); - printf("\t\tangle %f\n", edge->angle * (float)(180 / M_PI)); - if (edge->bone) { - printf("\t\t%s\n", edge->bone->name); - RIG_printLinkedCtrl(rg, edge->bone, 3); - } - } - printf("symmetry level: %i flag: %i group %i\n", arc->symmetry_level, arc->symmetry_flag, arc->symmetry_group); - - RIG_printNode((RigNode *)arc->tail, "tail"); -} - -void RIG_printGraph(RigGraph *rg) -{ - RigArc *arc; - - printf("---- ARCS ----\n"); - for (arc = rg->arcs.first; arc; arc = arc->next) { - RIG_printArc(rg, arc); - printf("\n"); - } - - if (rg->head) { - RIG_printNode(rg->head, "HEAD NODE:"); - } - else { - printf("HEAD NODE: NONE\n"); - } -} - -/*******************************************************************************************************/ - -RigGraph *RIG_graphFromArmature(const bContext *C, Object *ob, bArmature *arm) -{ - Object *obedit = CTX_data_edit_object(C); - Scene *scene = CTX_data_scene(C); - EditBone *ebone; - RigGraph *rg; - - rg = newRigGraph(); - - if (obedit == ob) { - rg->editbones = ((bArmature *)obedit->data)->edbo; - } - else { - rg->editbones = MEM_callocN(sizeof(ListBase), "EditBones"); - make_boneList(rg->editbones, &arm->bonebase, NULL); - rg->flag |= RIG_FREE_BONELIST; - } - - rg->ob = ob; - - /* Do the rotations */ - for (ebone = rg->editbones->first; ebone; ebone = ebone->next) { - if (ebone->parent == NULL) { - RIG_arcFromBoneChain(rg, rg->editbones, ebone, NULL, 0); - } - } - - BLI_removeDoubleNodes((BGraph *)rg, 0.001); - - RIG_removeNormalNodes(rg); - - RIG_removeUneededOffsets(rg); - - BLI_buildAdjacencyList((BGraph *)rg); - - RIG_findHead(rg); - - BLI_markdownSymmetry((BGraph *)rg, (BNode *)rg->head, scene->toolsettings->skgen_symmetry_limit); - - RIG_reconnectControlBones(rg); /* after symmetry, because we use levels to find best match */ - - if (BLI_isGraphCyclic((BGraph *)rg)) { - printf("armature cyclic\n"); - } - - return rg; -} - -static RigGraph *armatureSelectedToGraph(bContext *C, Object *ob, bArmature *arm) -{ - Object *obedit = CTX_data_edit_object(C); - Scene *scene = CTX_data_scene(C); - EditBone *ebone; - RigGraph *rg; - - rg = newRigGraph(); - - if (obedit == ob) { - rg->editbones = arm->edbo; - } - else { - rg->editbones = MEM_callocN(sizeof(ListBase), "EditBones"); - make_boneList(rg->editbones, &arm->bonebase, NULL); - rg->flag |= RIG_FREE_BONELIST; - } - - rg->ob = ob; - - /* Do the rotations */ - for (ebone = rg->editbones->first; ebone; ebone = ebone->next) { - if (ebone->parent == NULL) { - RIG_arcFromBoneChain(rg, rg->editbones, ebone, NULL, 1); - } - } - - BLI_removeDoubleNodes((BGraph *)rg, 0.001); - - RIG_removeNormalNodes(rg); - - RIG_removeUneededOffsets(rg); - - BLI_buildAdjacencyList((BGraph *)rg); - - RIG_findHead(rg); - - BLI_markdownSymmetry((BGraph *)rg, (BNode *)rg->head, scene->toolsettings->skgen_symmetry_limit); - - RIG_reconnectControlBones(rg); /* after symmetry, because we use levels to find best match */ - - if (BLI_isGraphCyclic((BGraph *)rg)) { - printf("armature cyclic\n"); - } - - return rg; -} -/************************************ GENERATING *****************************************************/ - -#if 0 -static EditBone *add_editbonetolist(char *name, ListBase *list) -{ - EditBone *bone = MEM_callocN(sizeof(EditBone), "eBone"); - - BLI_strncpy(bone->name, name, sizeof(bone->name)); - ED_armature_ebone_unique_name(list, bone->name, NULL); - - BLI_addtail(list, bone); - - bone->flag |= BONE_TIPSEL; - bone->weight = 1.0F; - bone->dist = 0.25F; - bone->xwidth = 0.1; - bone->zwidth = 0.1; - bone->rad_head = 0.10; - bone->rad_tail = 0.05; - bone->segments = 1; - bone->layer = 1; //arm->layer; - - /* Bendy-Bone parameters */ - bone->roll1 = 0.0f; - bone->roll2 = 0.0f; - bone->curveInX = 0.0f; - bone->curveInY = 0.0f; - bone->curveOutX = 0.0f; - bone->curveOutY = 0.0f; - bone->ease1 = 1.0f; - bone->ease2 = 1.0f; - bone->scaleIn = 1.0f; - bone->scaleOut = 1.0f; - - return bone; -} -#endif - -#if 0 /* UNUSED */ -static void generateMissingArcsFromNode(RigGraph *rigg, ReebNode *node, int multi_level_limit) -{ - while (node->multi_level > multi_level_limit && node->link_up) - { - node = node->link_up; - } - - while (node->multi_level < multi_level_limit && node->link_down) - { - node = node->link_down; - } - - if (node->multi_level == multi_level_limit) - { - int i; - - for (i = 0; i < node->degree; i++) - { - ReebArc *earc = node->arcs[i]; - - if (earc->flag == ARC_FREE && earc->head == node) - { - ReebNode *other = BIF_otherNodeFromIndex(earc, node); - - earc->flag = ARC_USED; - - //generateBonesForArc(rigg, earc, node, other); - generateMissingArcsFromNode(rigg, other, multi_level_limit); - } - } - } -} - -static void generateMissingArcs(RigGraph *rigg) -{ - ReebGraph *reebg; - int multi_level_limit = 5; - - for (reebg = rigg->link_mesh; reebg; reebg = reebg->link_up) - { - ReebArc *earc; - - for (earc = reebg->arcs.first; earc; earc = earc->next) - { - if (earc->flag == ARC_USED) - { - generateMissingArcsFromNode(rigg, earc->head, multi_level_limit); - generateMissingArcsFromNode(rigg, earc->tail, multi_level_limit); - } - } - } -} -#endif - -/************************************ RETARGETTING *****************************************************/ - -static void repositionControl(RigGraph *rigg, RigControl *ctrl, float head[3], float tail[3], float qrot[4], float resize); - -static void repositionTailControl(RigGraph *rigg, RigControl *ctrl); - -static void finalizeControl(RigGraph *rigg, RigControl *ctrl, float resize) -{ - if ((ctrl->flag & RIG_CTRL_DONE) == RIG_CTRL_DONE) { - RigControl *ctrl_child; - -#if 0 - printf("CTRL: %s LINK: %s", ctrl->bone->name, ctrl->link->name); - - if (ctrl->link_tail) - { - printf(" TAIL: %s", ctrl->link_tail->name); - } - - printf("\n"); -#endif - - /* if there was a tail link: apply link, recalc resize factor and qrot */ - if (ctrl->tail_mode != TL_NONE) { - float *tail_vec = NULL; - float v1[3], v2[3], qtail[4]; - - if (ctrl->tail_mode == TL_TAIL) { - tail_vec = ctrl->link_tail->tail; - } - else if (ctrl->tail_mode == TL_HEAD) { - tail_vec = ctrl->link_tail->head; - } - - sub_v3_v3v3(v1, ctrl->bone->tail, ctrl->bone->head); - sub_v3_v3v3(v2, tail_vec, ctrl->bone->head); - - copy_v3_v3(ctrl->bone->tail, tail_vec); - - rotation_between_vecs_to_quat(qtail, v1, v2); - mul_qt_qtqt(ctrl->qrot, qtail, ctrl->qrot); - - resize = len_v3(v2) / len_v3v3(ctrl->head, ctrl->tail); - } - - ctrl->bone->roll = rollBoneByQuat(ctrl->bone, ctrl->up_axis, ctrl->qrot); - - /* Cascade to connected control bones */ - for (ctrl_child = rigg->controls.first; ctrl_child; ctrl_child = ctrl_child->next) { - if (ctrl_child->link == ctrl->bone) { - repositionControl(rigg, ctrl_child, ctrl->bone->head, ctrl->bone->tail, ctrl->qrot, resize); - } - if (ctrl_child->link_tail == ctrl->bone) { - repositionTailControl(rigg, ctrl_child); - } - } - } -} - -static void repositionTailControl(RigGraph *rigg, RigControl *ctrl) -{ - ctrl->flag |= RIG_CTRL_TAIL_DONE; - - finalizeControl(rigg, ctrl, 1); /* resize will be recalculated anyway so we don't need it */ -} - -static void repositionControl(RigGraph *rigg, RigControl *ctrl, float head[3], float UNUSED(tail[3]), float qrot[4], float resize) -{ - float parent_offset[3], tail_offset[3]; - - copy_v3_v3(parent_offset, ctrl->offset); - mul_v3_fl(parent_offset, resize); - mul_qt_v3(qrot, parent_offset); - - add_v3_v3v3(ctrl->bone->head, head, parent_offset); - - ctrl->flag |= RIG_CTRL_HEAD_DONE; - - copy_qt_qt(ctrl->qrot, qrot); - - if (ctrl->tail_mode == TL_NONE) { - sub_v3_v3v3(tail_offset, ctrl->tail, ctrl->head); - mul_v3_fl(tail_offset, resize); - mul_qt_v3(qrot, tail_offset); - - add_v3_v3v3(ctrl->bone->tail, ctrl->bone->head, tail_offset); - - ctrl->flag |= RIG_CTRL_TAIL_DONE; - } - - finalizeControl(rigg, ctrl, resize); -} - -static void repositionBone(bContext *C, RigGraph *rigg, RigEdge *edge, float vec0[3], float vec1[3], float up_axis[3]) -{ - Scene *scene = CTX_data_scene(C); - EditBone *bone; - RigControl *ctrl; - float qrot[4], resize; - float v1[3], v2[3]; - float l1, l2; - - bone = edge->bone; - - sub_v3_v3v3(v1, edge->tail, edge->head); - sub_v3_v3v3(v2, vec1, vec0); - - l1 = normalize_v3(v1); - l2 = normalize_v3(v2); - - resize = l2 / l1; - - rotation_between_vecs_to_quat(qrot, v1, v2); - - copy_v3_v3(bone->head, vec0); - copy_v3_v3(bone->tail, vec1); - - if (!is_zero_v3(up_axis)) { - float qroll[4]; - - if (scene->toolsettings->skgen_retarget_roll == SK_RETARGET_ROLL_VIEW) { - bone->roll = rollBoneByQuatAligned(bone, edge->up_axis, qrot, qroll, up_axis); - } - else if (scene->toolsettings->skgen_retarget_roll == SK_RETARGET_ROLL_JOINT) { - bone->roll = rollBoneByQuatJoint(edge, edge->prev, qrot, qroll, up_axis); - } - else { - unit_qt(qroll); - } - - mul_qt_qtqt(qrot, qroll, qrot); - } - else { - bone->roll = rollBoneByQuat(bone, edge->up_axis, qrot); - } - - for (ctrl = rigg->controls.first; ctrl; ctrl = ctrl->next) { - if (ctrl->link == bone) { - repositionControl(rigg, ctrl, vec0, vec1, qrot, resize); - } - if (ctrl->link_tail == bone) { - repositionTailControl(rigg, ctrl); - } - } -} - -static RetargetMode detectArcRetargetMode(RigArc *arc); -static void retargetArctoArcLength(bContext *C, RigGraph *rigg, RigArc *iarc, RigNode *inode_start); - - -static RetargetMode detectArcRetargetMode(RigArc *iarc) -{ - RetargetMode mode = RETARGET_AGGRESSIVE; - ReebArc *earc = iarc->link_mesh; - RigEdge *edge; - int large_angle = 0; - float avg_angle = 0; - /* float avg_length = 0; */ /* UNUSED */ - int nb_edges = 0; - - - for (edge = iarc->edges.first; edge; edge = edge->next) { - avg_angle += edge->angle; - nb_edges++; - } - - avg_angle /= nb_edges - 1; /* -1 because last edge doesn't have an angle */ - - /* avg_length = iarc->length / nb_edges; */ /* UNUSED */ - - - if (nb_edges > 2) { - for (edge = iarc->edges.first; edge; edge = edge->next) { - if (fabsf(edge->angle - avg_angle) > (float)(M_PI / 6)) { - large_angle = 1; - } - } - } - else if (nb_edges == 2 && avg_angle > 0) { - large_angle = 1; - } - - - if (large_angle == 0) { - mode = RETARGET_LENGTH; - } - - if (earc->bcount <= (iarc->count - 1)) { - mode = RETARGET_LENGTH; - } - - return mode; -} - -#ifndef USE_THREADS -static void printMovesNeeded(int *positions, int nb_positions) -{ - int moves = 0; - int i; - - for (i = 0; i < nb_positions; i++) { - moves += positions[i] - (i + 1); - } - - printf("%i moves needed\n", moves); -} - -static void printPositions(int *positions, int nb_positions) -{ - int i; - - for (i = 0; i < nb_positions; i++) { - printf("%i ", positions[i]); - } - printf("\n"); -} -#endif - -#define MAX_COST FLT_MAX /* FIX ME */ - -static float costDistance(BArcIterator *iter, float *vec0, float *vec1, int i0, int i1, float distance_weight) -{ - EmbedBucket *bucket = NULL; - float max_dist = 0; - float v1[3], v2[3], c[3]; - float v1_inpf; - - if (distance_weight > 0) { - sub_v3_v3v3(v1, vec0, vec1); - - v1_inpf = dot_v3v3(v1, v1); - - if (v1_inpf > 0) { - int j; - for (j = i0 + 1; j < i1 - 1; j++) { - float dist; - - bucket = IT_peek(iter, j); - - sub_v3_v3v3(v2, bucket->p, vec1); - - cross_v3_v3v3(c, v1, v2); - - dist = dot_v3v3(c, c) / v1_inpf; - - max_dist = dist > max_dist ? dist : max_dist; - } - - return distance_weight * max_dist; - } - else { - return MAX_COST; - } - } - else { - return 0; - } -} - -static float costAngle(float original_angle, float vec_first[3], float vec_second[3], float angle_weight) -{ - if (angle_weight > 0) { - float current_angle; - - if (!is_zero_v3(vec_first) && !is_zero_v3(vec_second)) { - current_angle = saacos(dot_v3v3(vec_first, vec_second)); - - return angle_weight * fabsf(current_angle - original_angle); - } - else { - return angle_weight * (float)M_PI; - } - } - else { - return 0; - } -} - -static float costLength(float original_length, float current_length, float length_weight) -{ - if (current_length == 0) { - return MAX_COST; - } - else { - float length_ratio = fabsf((current_length - original_length) / original_length); - return length_weight * length_ratio * length_ratio; - } -} - -#if 0 -static float calcCostLengthDistance(BArcIterator *iter, float **vec_cache, RigEdge *edge, float *vec1, float *vec2, int i1, int i2) -{ - float vec[3]; - float length; - - sub_v3_v3v3(vec, vec2, vec1); - length = normalize_v3(vec); - - return costLength(edge->length, length) + costDistance(iter, vec1, vec2, i1, i2); -} -#endif - -static float calcCostAngleLengthDistance(BArcIterator *iter, float **UNUSED(vec_cache), RigEdge *edge, - float *vec0, float *vec1, float *vec2, int i1, int i2, - float angle_weight, float length_weight, float distance_weight) -{ - float vec_second[3], vec_first[3]; - float length2; - float new_cost = 0; - - sub_v3_v3v3(vec_second, vec2, vec1); - length2 = normalize_v3(vec_second); - - - /* Angle cost */ - if (edge->prev) { - sub_v3_v3v3(vec_first, vec1, vec0); - normalize_v3(vec_first); - - new_cost += costAngle(edge->prev->angle, vec_first, vec_second, angle_weight); - } - - /* Length cost */ - new_cost += costLength(edge->length, length2, length_weight); - - /* Distance cost */ - new_cost += costDistance(iter, vec1, vec2, i1, i2, distance_weight); - - return new_cost; -} - -static int indexMemoNode(int nb_positions, int previous, int current, int joints_left) -{ - return joints_left * nb_positions * nb_positions + current * nb_positions + previous; -} - -static void copyMemoPositions(int *positions, MemoNode *table, int nb_positions, int joints_left) -{ - int previous = 0, current = 0; - int i = 0; - - for (i = 0; joints_left > 0; joints_left--, i++) { - MemoNode *node; - node = table + indexMemoNode(nb_positions, previous, current, joints_left); - - positions[i] = node->next; - - previous = current; - current = node->next; - } -} - -static MemoNode *solveJoints(MemoNode *table, BArcIterator *iter, float **vec_cache, - int nb_joints, int nb_positions, int previous, int current, RigEdge *edge, - int joints_left, float angle_weight, float length_weight, float distance_weight) -{ - MemoNode *node; - int index = indexMemoNode(nb_positions, previous, current, joints_left); - - node = table + index; - - if (node->weight != 0) { - return node; - } - else if (joints_left == 0) { - float *vec0 = vec_cache[previous]; - float *vec1 = vec_cache[current]; - float *vec2 = vec_cache[nb_positions + 1]; - - node->weight = calcCostAngleLengthDistance(iter, vec_cache, edge, vec0, vec1, vec2, current, iter->length, angle_weight, length_weight, distance_weight); - - return node; - } - else { - MemoNode *min_node = NULL; - float *vec0 = vec_cache[previous]; - float *vec1 = vec_cache[current]; - float min_weight = 0.0f; - int min_next = 0; - int next; - - for (next = current + 1; next <= nb_positions - (joints_left - 1); next++) { - MemoNode *next_node; - float *vec2 = vec_cache[next]; - float weight = 0.0f; - - /* ADD WEIGHT OF PREVIOUS - CURRENT - NEXT triple */ - weight = calcCostAngleLengthDistance(iter, vec_cache, edge, vec0, vec1, vec2, current, next, angle_weight, length_weight, distance_weight); - - if (weight >= MAX_COST) { - continue; - } - - /* add node weight */ - next_node = solveJoints(table, iter, vec_cache, nb_joints, nb_positions, current, next, edge->next, joints_left - 1, angle_weight, length_weight, distance_weight); - weight += next_node->weight; - - if (min_node == NULL || weight < min_weight) { - min_weight = weight; - min_node = next_node; - min_next = next; - } - } - - if (min_node) { - node->weight = min_weight; - node->next = min_next; - return node; - } - else { - node->weight = MAX_COST; - return node; - } - } - -} - -static int testFlipArc(RigArc *iarc, RigNode *inode_start) -{ - ReebArc *earc = iarc->link_mesh; - ReebNode *enode_start = BIF_NodeFromIndex(earc, inode_start->link_mesh); - - /* no flip needed if both nodes are the same */ - if ((enode_start == earc->head && inode_start == iarc->head) || - (enode_start == earc->tail && inode_start == iarc->tail)) - { - return 0; - } - else { - return 1; - } -} - -static void retargetArctoArcAggresive(bContext *C, RigGraph *rigg, RigArc *iarc, RigNode *inode_start) -{ - ReebArcIterator arc_iter; - BArcIterator *iter = (BArcIterator *)&arc_iter; - RigEdge *edge; - ReebNode *node_start, *node_end; - ReebArc *earc = iarc->link_mesh; - float angle_weight = 1.0; // GET FROM CONTEXT - float length_weight = 1.0; - float distance_weight = 1.0; -#ifndef USE_THREADS - float min_cost = FLT_MAX; -#endif - float *vec0, *vec1; - int *best_positions; - int nb_edges = BLI_listbase_count(&iarc->edges); - int nb_joints = nb_edges - 1; - RetargetMethod method = METHOD_MEMOIZE; - int i; - - if (nb_joints > earc->bcount) { - printf("NOT ENOUGH BUCKETS!\n"); - return; - } - - best_positions = MEM_callocN(sizeof(int) * nb_joints, "Best positions"); - - if (testFlipArc(iarc, inode_start)) { - node_start = earc->tail; - node_end = earc->head; - } - else { - node_start = earc->head; - node_end = earc->tail; - } - - /* equal number of joints and potential position, just fill them in */ - if (nb_joints == earc->bcount) { - /* init with first values */ - for (i = 0; i < nb_joints; i++) { - best_positions[i] = i + 1; - } - } - if (method == METHOD_MEMOIZE) { - int nb_positions = earc->bcount; - int nb_memo_nodes = nb_positions * nb_positions * (nb_joints + 1); - MemoNode *table = MEM_callocN(nb_memo_nodes * sizeof(MemoNode), "memoization table"); -#ifndef USE_THREADS - MemoNode *result; -#endif - float **positions_cache = MEM_callocN(sizeof(float *) * (nb_positions + 2), "positions cache"); - - positions_cache[0] = node_start->p; - positions_cache[nb_positions + 1] = node_end->p; - - initArcIterator(iter, earc, node_start); - - for (i = 1; i <= nb_positions; i++) { - EmbedBucket *bucket = IT_peek(iter, i); - positions_cache[i] = bucket->p; - } - -#ifndef USE_THREADS - result = solveJoints(table, iter, positions_cache, nb_joints, earc->bcount, 0, 0, iarc->edges.first, nb_joints, angle_weight, length_weight, distance_weight); - min_cost = result->weight; -#else - solveJoints(table, iter, positions_cache, nb_joints, earc->bcount, 0, 0, iarc->edges.first, nb_joints, angle_weight, length_weight, distance_weight); -#endif - - copyMemoPositions(best_positions, table, earc->bcount, nb_joints); - - MEM_freeN(table); - MEM_freeN(positions_cache); - } - - vec0 = node_start->p; - initArcIterator(iter, earc, node_start); - -#ifndef USE_THREADS - printPositions(best_positions, nb_joints); - printMovesNeeded(best_positions, nb_joints); - printf("min_cost %f\n", min_cost); - printf("buckets: %i\n", earc->bcount); -#endif - - /* set joints to best position */ - for (edge = iarc->edges.first, i = 0; - edge; - edge = edge->next, i++) - { - float *no = NULL; - if (i < nb_joints) { - EmbedBucket *bucket = IT_peek(iter, best_positions[i]); - vec1 = bucket->p; - no = bucket->no; - } - else { - vec1 = node_end->p; - no = node_end->no; - } - - if (edge->bone) { - repositionBone(C, rigg, edge, vec0, vec1, no); - } - - vec0 = vec1; - } - - MEM_freeN(best_positions); -} - -static void retargetArctoArcLength(bContext *C, RigGraph *rigg, RigArc *iarc, RigNode *inode_start) -{ - ReebArcIterator arc_iter; - BArcIterator *iter = (BArcIterator *)&arc_iter; - ReebArc *earc = iarc->link_mesh; - ReebNode *node_start, *node_end; - RigEdge *edge; - EmbedBucket *bucket = NULL; - float embedding_length = 0; - float *vec0 = NULL; - float *vec1 = NULL; - float *previous_vec = NULL; - - - if (testFlipArc(iarc, inode_start)) { - node_start = (ReebNode *)earc->tail; - node_end = (ReebNode *)earc->head; - } - else { - node_start = (ReebNode *)earc->head; - node_end = (ReebNode *)earc->tail; - } - - initArcIterator(iter, earc, node_start); - - bucket = IT_next(iter); - - vec0 = node_start->p; - - while (bucket != NULL) { - vec1 = bucket->p; - - embedding_length += len_v3v3(vec0, vec1); - - vec0 = vec1; - bucket = IT_next(iter); - } - - embedding_length += len_v3v3(node_end->p, vec1); - - /* fit bones */ - initArcIterator(iter, earc, node_start); - - bucket = IT_next(iter); - - vec0 = node_start->p; - previous_vec = vec0; - vec1 = bucket->p; - - for (edge = iarc->edges.first; edge; edge = edge->next) { - float new_bone_length = edge->length / iarc->length * embedding_length; - float *no = NULL; - float length = 0; - - while (bucket && new_bone_length > length) { - length += len_v3v3(previous_vec, vec1); - bucket = IT_next(iter); - previous_vec = vec1; - vec1 = bucket->p; - no = bucket->no; - } - - if (bucket == NULL) { - vec1 = node_end->p; - no = node_end->no; - } - - /* no need to move virtual edges (space between unconnected bones) */ - if (edge->bone) { - repositionBone(C, rigg, edge, vec0, vec1, no); - } - - vec0 = vec1; - previous_vec = vec1; - } -} - -static void retargetArctoArc(bContext *C, RigGraph *rigg, RigArc *iarc, RigNode *inode_start) -{ - RetargetParam *p = MEM_callocN(sizeof(RetargetParam), "RetargetParam"); - - p->rigg = rigg; - p->iarc = iarc; - p->inode_start = inode_start; - p->context = C; - - BLI_task_pool_push(rigg->task_pool, exec_retargetArctoArc, p, true, TASK_PRIORITY_HIGH); -} - -void exec_retargetArctoArc(TaskPool * __restrict UNUSED(pool), void *taskdata, int UNUSED(threadid)) -{ - RetargetParam *p = (RetargetParam *)taskdata; - RigGraph *rigg = p->rigg; - RigArc *iarc = p->iarc; - bContext *C = p->context; - RigNode *inode_start = p->inode_start; - ReebArc *earc = iarc->link_mesh; - - if (BLI_listbase_is_single(&iarc->edges)) { - RigEdge *edge = iarc->edges.first; - - if (testFlipArc(iarc, inode_start)) { - repositionBone(C, rigg, edge, earc->tail->p, earc->head->p, earc->head->no); - } - else { - repositionBone(C, rigg, edge, earc->head->p, earc->tail->p, earc->tail->no); - } - } - else { - RetargetMode mode = detectArcRetargetMode(iarc); - - if (mode == RETARGET_AGGRESSIVE) { - retargetArctoArcAggresive(C, rigg, iarc, inode_start); - } - else { - retargetArctoArcLength(C, rigg, iarc, inode_start); - } - } -} - -static void matchMultiResolutionNode(RigGraph *rigg, RigNode *inode, ReebNode *top_node) -{ - ReebNode *enode = top_node; - ReebGraph *reebg = BIF_graphForMultiNode(rigg->link_mesh, enode); - int ishape, eshape; - - ishape = BLI_subtreeShape((BGraph *)rigg, (BNode *)inode, NULL, 0) % SHAPE_LEVELS; - eshape = BLI_subtreeShape((BGraph *)reebg, (BNode *)enode, NULL, 0) % SHAPE_LEVELS; - - inode->link_mesh = enode; - - while (ishape == eshape && enode->link_down) { - inode->link_mesh = enode; - - enode = enode->link_down; - reebg = BIF_graphForMultiNode(rigg->link_mesh, enode); /* replace with call to link_down once that exists */ - eshape = BLI_subtreeShape((BGraph *)reebg, (BNode *)enode, NULL, 0) % SHAPE_LEVELS; - } -} - -static void markMultiResolutionChildArc(ReebNode *end_enode, ReebNode *enode) -{ - int i; - - for (i = 0; i < enode->degree; i++) { - ReebArc *earc = (ReebArc *)enode->arcs[i]; - - if (earc->flag == ARC_FREE) { - earc->flag = ARC_TAKEN; - - if (earc->tail->degree > 1 && earc->tail != end_enode) { - markMultiResolutionChildArc(end_enode, earc->tail); - } - break; - } - } -} - -static void markMultiResolutionArc(ReebArc *start_earc) -{ - if (start_earc->link_up) { - ReebArc *earc; - for (earc = start_earc->link_up; earc; earc = earc->link_up) { - earc->flag = ARC_TAKEN; - - if (earc->tail->index != start_earc->tail->index) { - markMultiResolutionChildArc(earc->tail, earc->tail); - } - } - } -} - -static void matchMultiResolutionArc(RigGraph *rigg, RigNode *start_node, RigArc *next_iarc, ReebArc *next_earc) -{ - ReebNode *enode = next_earc->head; - ReebGraph *reebg = BIF_graphForMultiNode(rigg->link_mesh, enode); - int ishape, eshape; - - ishape = BLI_subtreeShape((BGraph *)rigg, (BNode *)start_node, (BArc *)next_iarc, 1) % SHAPE_LEVELS; - eshape = BLI_subtreeShape((BGraph *)reebg, (BNode *)enode, (BArc *)next_earc, 1) % SHAPE_LEVELS; - - while (ishape != eshape && next_earc->link_up) { - next_earc->flag = ARC_TAKEN; // mark previous as taken, to prevent backtrack on lower levels - - next_earc = next_earc->link_up; - reebg = reebg->link_up; - enode = next_earc->head; - eshape = BLI_subtreeShape((BGraph *)reebg, (BNode *)enode, (BArc *)next_earc, 1) % SHAPE_LEVELS; - } - - next_earc->flag = ARC_USED; - next_iarc->link_mesh = next_earc; - - /* mark all higher levels as taken too */ - markMultiResolutionArc(next_earc); -// while (next_earc->link_up) -// { -// next_earc = next_earc->link_up; -// next_earc->flag = ARC_TAKEN; -// } -} - -static void matchMultiResolutionStartingNode(RigGraph *rigg, ReebGraph *reebg, RigNode *inode) -{ - ReebNode *enode; - int ishape, eshape; - - enode = reebg->nodes.first; - - ishape = BLI_subtreeShape((BGraph *)rigg, (BNode *)inode, NULL, 0) % SHAPE_LEVELS; - eshape = BLI_subtreeShape((BGraph *)rigg->link_mesh, (BNode *)enode, NULL, 0) % SHAPE_LEVELS; - - while (ishape != eshape && reebg->link_up) { - reebg = reebg->link_up; - - enode = reebg->nodes.first; - - eshape = BLI_subtreeShape((BGraph *)reebg, (BNode *)enode, NULL, 0) % SHAPE_LEVELS; - } - - inode->link_mesh = enode; -} - -static void findCorrespondingArc(RigGraph *rigg, RigArc *start_arc, RigNode *start_node, RigArc *next_iarc, int root) -{ - ReebNode *enode = start_node->link_mesh; - ReebArc *next_earc; - int symmetry_level = next_iarc->symmetry_level; - int symmetry_group = next_iarc->symmetry_group; - int symmetry_flag = next_iarc->symmetry_flag; - int i; - - next_iarc->link_mesh = NULL; - -// if (root) -// { -// printf("-----------------------\n"); -// printf("MATCHING LIMB\n"); -// RIG_printArcBones(next_iarc); -// } - - for (i = 0; i < enode->degree; i++) { - next_earc = (ReebArc *)enode->arcs[i]; - -// if (next_earc->flag == ARC_FREE) -// { -// printf("candidate (level %i ?= %i) (flag %i ?= %i) (group %i ?= %i)\n", -// symmetry_level, next_earc->symmetry_level, -// symmetry_flag, next_earc->symmetry_flag, -// symmetry_group, next_earc->symmetry_flag); -// } - - if (next_earc->flag == ARC_FREE && - next_earc->symmetry_flag == symmetry_flag && - next_earc->symmetry_group == symmetry_group && - next_earc->symmetry_level == symmetry_level) - { -// printf("CORRESPONDING ARC FOUND\n"); -// printf("flag %i -- level %i -- flag %i -- group %i\n", next_earc->flag, next_earc->symmetry_level, next_earc->symmetry_flag, next_earc->symmetry_group); - - matchMultiResolutionArc(rigg, start_node, next_iarc, next_earc); - break; - } - } - - /* not found, try at higher nodes (lower node might have filtered internal arcs, messing shape of tree */ - if (next_iarc->link_mesh == NULL) { -// printf("NO CORRESPONDING ARC FOUND - GOING TO HIGHER LEVELS\n"); - - if (enode->link_up) { - start_node->link_mesh = enode->link_up; - findCorrespondingArc(rigg, start_arc, start_node, next_iarc, 0); - } - } - - /* still not found, print debug info */ - if (root && next_iarc->link_mesh == NULL) { - start_node->link_mesh = enode; /* linking back with root node */ - -// printf("NO CORRESPONDING ARC FOUND\n"); -// RIG_printArcBones(next_iarc); -// -// printf("ON NODE %i, multilevel %i\n", enode->index, enode->multi_level); -// -// printf("LOOKING FOR\n"); -// printf("flag %i -- level %i -- flag %i -- group %i\n", ARC_FREE, symmetry_level, symmetry_flag, symmetry_group); -// -// printf("CANDIDATES\n"); -// for (i = 0; i < enode->degree; i++) -// { -// next_earc = (ReebArc *)enode->arcs[i]; -// printf("flag %i -- level %i -- flag %i -- group %i\n", next_earc->flag, next_earc->symmetry_level, next_earc->symmetry_flag, next_earc->symmetry_group); -// } - - /* Emergency matching */ - for (i = 0; i < enode->degree; i++) { - next_earc = (ReebArc *)enode->arcs[i]; - - if (next_earc->flag == ARC_FREE && next_earc->symmetry_level == symmetry_level) { -// printf("USING:\n"); -// printf("flag %i -- level %i -- flag %i -- group %i\n", next_earc->flag, next_earc->symmetry_level, next_earc->symmetry_flag, next_earc->symmetry_group); - matchMultiResolutionArc(rigg, start_node, next_iarc, next_earc); - break; - } - } - } - -} - -static void retargetSubgraph(bContext *C, RigGraph *rigg, RigArc *start_arc, RigNode *start_node) -{ - RigNode *inode = start_node; - int i; - - /* no start arc on first node */ - if (start_arc) { - ReebNode *enode = start_node->link_mesh; - ReebArc *earc = start_arc->link_mesh; - - retargetArctoArc(C, rigg, start_arc, start_node); - - enode = BIF_otherNodeFromIndex(earc, enode); - inode = (RigNode *)BLI_otherNode((BArc *)start_arc, (BNode *)inode); - - /* match with lowest node with correct shape */ - matchMultiResolutionNode(rigg, inode, enode); - } - - for (i = 0; i < inode->degree; i++) { - RigArc *next_iarc = (RigArc *)inode->arcs[i]; - - /* no back tracking */ - if (next_iarc != start_arc) { - findCorrespondingArc(rigg, start_arc, inode, next_iarc, 1); - if (next_iarc->link_mesh) { - retargetSubgraph(C, rigg, next_iarc, inode); - } - } - } -} - -static void finishRetarget(RigGraph *rigg) -{ - BLI_task_pool_work_and_wait(rigg->task_pool); -} - -static void adjustGraphs(bContext *C, RigGraph *rigg) -{ - Main *bmain = CTX_data_main(C); - bArmature *arm = rigg->ob->data; - RigArc *arc; - - for (arc = rigg->arcs.first; arc; arc = arc->next) { - if (arc->link_mesh) { - retargetArctoArc(C, rigg, arc, arc->head); - } - } - - finishRetarget(rigg); - - /* Turn the list into an armature */ - arm->edbo = rigg->editbones; - ED_armature_from_edit(bmain, arm); - - ED_undo_push(C, "Retarget Skeleton"); -} - -static void retargetGraphs(bContext *C, RigGraph *rigg) -{ - Main *bmain = CTX_data_main(C); - bArmature *arm = rigg->ob->data; - ReebGraph *reebg = rigg->link_mesh; - RigNode *inode; - - /* flag all ReebArcs as free */ - BIF_flagMultiArcs(reebg, ARC_FREE); - - /* return to first level */ - inode = rigg->head; - - matchMultiResolutionStartingNode(rigg, reebg, inode); - - retargetSubgraph(C, rigg, NULL, inode); - - //generateMissingArcs(rigg); - - finishRetarget(rigg); - - /* Turn the list into an armature */ - arm->edbo = rigg->editbones; - ED_armature_from_edit(bmain, arm); -} - -const char *RIG_nameBone(RigGraph *rg, int arc_index, int bone_index) -{ - RigArc *arc = BLI_findlink(&rg->arcs, arc_index); - RigEdge *iedge; - - if (arc == NULL) { - return "None"; - } - - if (bone_index == BLI_listbase_count(&arc->edges)) { - return "Last joint"; - } - - iedge = BLI_findlink(&arc->edges, bone_index); - - if (iedge == NULL) { - return "Done"; - } - - if (iedge->bone == NULL) { - return "Bone offset"; - } - - return iedge->bone->name; -} - -int RIG_nbJoints(RigGraph *rg) -{ - RigArc *arc; - int total = 0; - - total += BLI_listbase_count(&rg->nodes); - - for (arc = rg->arcs.first; arc; arc = arc->next) { - total += BLI_listbase_count(&arc->edges) - 1; /* -1 because end nodes are already counted */ - } - - return total; -} - -static void BIF_freeRetarget(void) -{ - if (GLOBAL_RIGG) { - RIG_freeRigGraph((BGraph *)GLOBAL_RIGG); - GLOBAL_RIGG = NULL; - } -} - -void BIF_retargetArmature(bContext *C) -{ - ReebGraph *reebg; - double start_time, end_time; - double gstart_time, gend_time; - double reeb_time, rig_time = 0.0, retarget_time = 0.0, total_time; - - gstart_time = start_time = PIL_check_seconds_timer(); - - reebg = BIF_ReebGraphMultiFromEditMesh(C); - - end_time = PIL_check_seconds_timer(); - reeb_time = end_time - start_time; - - printf("Reeb Graph created\n"); - - CTX_DATA_BEGIN (C, Base *, base, selected_editable_bases) - { - Object *ob = base->object; - - if (ob->type == OB_ARMATURE) { - RigGraph *rigg; - bArmature *arm; - - arm = ob->data; - - /* Put the armature into editmode */ - - - start_time = PIL_check_seconds_timer(); - - rigg = RIG_graphFromArmature(C, ob, arm); - - end_time = PIL_check_seconds_timer(); - rig_time = end_time - start_time; - - printf("Armature graph created\n"); - - //RIG_printGraph(rigg); - - rigg->link_mesh = reebg; - - printf("retargetting %s\n", ob->id.name); - - start_time = PIL_check_seconds_timer(); - - retargetGraphs(C, rigg); - - end_time = PIL_check_seconds_timer(); - retarget_time = end_time - start_time; - - BIF_freeRetarget(); - - GLOBAL_RIGG = rigg; - - break; /* only one armature at a time */ - } - } - CTX_DATA_END; - - - gend_time = PIL_check_seconds_timer(); - - total_time = gend_time - gstart_time; - - printf("-----------\n"); - printf("runtime: \t%.3f\n", total_time); - printf("reeb: \t\t%.3f (%.1f%%)\n", reeb_time, reeb_time / total_time * 100); - printf("rig: \t\t%.3f (%.1f%%)\n", rig_time, rig_time / total_time * 100); - printf("retarget: \t%.3f (%.1f%%)\n", retarget_time, retarget_time / total_time * 100); - printf("-----------\n"); - - ED_undo_push(C, "Retarget Skeleton"); - - // XXX -// allqueue(REDRAWVIEW3D, 0); -} - -void BIF_retargetArc(bContext *C, ReebArc *earc, RigGraph *template_rigg) -{ - Object *obedit = CTX_data_edit_object(C); - Scene *scene = CTX_data_scene(C); - bArmature *armedit = obedit->data; - Object *ob; - RigGraph *rigg; - RigArc *iarc; - char *side_string = scene->toolsettings->skgen_side_string; - char *num_string = scene->toolsettings->skgen_num_string; - int free_template = 0; - - if (template_rigg) { - ob = template_rigg->ob; - } - else { - free_template = 1; - ob = obedit; - template_rigg = armatureSelectedToGraph(C, ob, ob->data); - } - - if (BLI_listbase_is_empty(&template_rigg->arcs)) { -// XXX -// error("No Template and no deforming bones selected"); - return; - } - - rigg = cloneRigGraph(template_rigg, armedit->edbo, obedit, side_string, num_string); - - iarc = rigg->arcs.first; - - iarc->link_mesh = earc; - iarc->head->link_mesh = earc->head; - iarc->tail->link_mesh = earc->tail; - - retargetArctoArc(C, rigg, iarc, iarc->head); - - finishRetarget(rigg); - - /* free template if it comes from the edit armature */ - if (free_template) { - RIG_freeRigGraph((BGraph *)template_rigg); - } - RIG_freeRigGraph((BGraph *)rigg); - - ED_armature_edit_validate_active(armedit); - -// XXX -// allqueue(REDRAWVIEW3D, 0); -} - -void BIF_adjustRetarget(bContext *C) -{ - if (GLOBAL_RIGG) { - adjustGraphs(C, GLOBAL_RIGG); - } -} diff --git a/source/blender/editors/include/ED_keymap_templates.h b/source/blender/editors/include/ED_keymap_templates.h deleted file mode 100644 index 0a1882d005a..00000000000 --- a/source/blender/editors/include/ED_keymap_templates.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file ED_keymap_templates.h - * \ingroup editors - */ - -#ifndef __ED_KEYMAP_TEMPLATES_H__ -#define __ED_KEYMAP_TEMPLATES_H__ - -struct wmKeyMap; - -void ED_keymap_template_select_all(struct wmKeyMap *keymap, const char *idname); - -#endif /* __ED_KEYMAP_TEMPLATES_H__ */ diff --git a/source/blender/editors/sculpt_paint/paint_ops.c b/source/blender/editors/sculpt_paint/paint_ops.c index 85dc37b9838..11565d665b1 100644 --- a/source/blender/editors/sculpt_paint/paint_ops.c +++ b/source/blender/editors/sculpt_paint/paint_ops.c @@ -50,7 +50,6 @@ #include "ED_paint.h" #include "ED_screen.h" #include "ED_select_utils.h" -#include "ED_keymap_templates.h" #include "ED_image.h" #include "ED_gpencil.h" #include "UI_resources.h" diff --git a/source/blender/editors/space_logic/space_logic.c b/source/blender/editors/space_logic/space_logic.c deleted file mode 100644 index 1896d7ec3a2..00000000000 --- a/source/blender/editors/space_logic/space_logic.c +++ /dev/null @@ -1,363 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2009 Blender Foundation. - * All rights reserved. - * - * - * Contributor(s): Blender Foundation - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/editors/space_logic/space_logic.c - * \ingroup splogic - */ - - -#include <string.h> -#include <stdio.h> - - -#include "MEM_guardedalloc.h" - -#include "BLI_blenlib.h" -#include "BLI_utildefines.h" - -#include "DNA_gpencil_types.h" - -#include "BKE_context.h" -#include "BKE_screen.h" - -#include "ED_space_api.h" -#include "ED_screen.h" - -#include "BIF_gl.h" - - -#include "WM_api.h" -#include "WM_types.h" - -#include "UI_resources.h" -#include "UI_view2d.h" - -#include "logic_intern.h" - -/* ******************** manage regions ********************* */ - -ARegion *logic_has_buttons_region(ScrArea *sa) -{ - ARegion *ar, *arnew; - - ar = BKE_area_find_region_type(sa, RGN_TYPE_UI); - if (ar) return ar; - - /* add subdiv level; after header */ - ar = BKE_area_find_region_type(sa, RGN_TYPE_HEADER); - - /* is error! */ - if (ar == NULL) return NULL; - - arnew= MEM_callocN(sizeof(ARegion), "buttons for image"); - - BLI_insertlinkafter(&sa->regionbase, ar, arnew); - arnew->regiontype = RGN_TYPE_UI; - arnew->alignment = RGN_ALIGN_RIGHT; - - arnew->flag = RGN_FLAG_HIDDEN; - - return arnew; -} - -/* ******************** default callbacks for image space ***************** */ - -static SpaceLink *logic_new(const bContext *C) -{ - ScrArea *sa= CTX_wm_area(C); - ARegion *ar; - SpaceLogic *slogic; - - slogic= MEM_callocN(sizeof(SpaceLogic), "initlogic"); - slogic->spacetype= SPACE_LOGIC; - - /* default options */ - slogic->scaflag = ((BUTS_SENS_SEL|BUTS_SENS_ACT|BUTS_SENS_LINK) | - (BUTS_CONT_SEL|BUTS_CONT_ACT|BUTS_CONT_LINK) | - (BUTS_ACT_SEL|BUTS_ACT_ACT|BUTS_ACT_LINK) | - (BUTS_SENS_STATE|BUTS_ACT_STATE)); - - - /* header */ - ar= MEM_callocN(sizeof(ARegion), "header for logic"); - - BLI_addtail(&slogic->regionbase, ar); - ar->regiontype= RGN_TYPE_HEADER; - ar->alignment= RGN_ALIGN_BOTTOM; - - /* buttons/list view */ - ar= MEM_callocN(sizeof(ARegion), "buttons for logic"); - - BLI_addtail(&slogic->regionbase, ar); - ar->regiontype= RGN_TYPE_UI; - ar->alignment= RGN_ALIGN_RIGHT; - - /* main region */ - ar= MEM_callocN(sizeof(ARegion), "main region for logic"); - - BLI_addtail(&slogic->regionbase, ar); - ar->regiontype= RGN_TYPE_WINDOW; - - ar->v2d.tot.xmin = 0.0f; - ar->v2d.tot.ymax = 0.0f; - ar->v2d.tot.xmax = 1150.0f; - ar->v2d.tot.ymin = ( 1150.0f/(float)sa->winx ) * (float)-sa->winy; - - ar->v2d.cur = ar->v2d.tot; - - ar->v2d.min[0] = 1.0f; - ar->v2d.min[1] = 1.0f; - - ar->v2d.max[0] = 32000.0f; - ar->v2d.max[1] = 32000.0f; - - ar->v2d.minzoom = 0.5f; - ar->v2d.maxzoom = 1.5f; - - ar->v2d.scroll = (V2D_SCROLL_RIGHT | V2D_SCROLL_BOTTOM); - ar->v2d.keepzoom = V2D_KEEPZOOM | V2D_LIMITZOOM | V2D_KEEPASPECT; - ar->v2d.keeptot = V2D_KEEPTOT_BOUNDS; - ar->v2d.align = V2D_ALIGN_NO_POS_Y | V2D_ALIGN_NO_NEG_X; - ar->v2d.keepofs = V2D_KEEPOFS_Y; - - return (SpaceLink *)slogic; -} - -/* not spacelink itself */ -static void logic_free(SpaceLink *UNUSED(sl)) -{ -// Spacelogic *slogic= (SpaceLogic *) sl; - -// if (slogic->gpd) -// XXX BKE_gpencil_free(slogic->gpd); - -} - - -/* spacetype; init callback */ -static void logic_init(struct wmWindowManager *UNUSED(wm), ScrArea *UNUSED(sa)) -{ - -} - -static SpaceLink *logic_duplicate(SpaceLink *sl) -{ - SpaceLogic *slogicn= MEM_dupallocN(sl); - - return (SpaceLink *)slogicn; -} - -static void logic_operatortypes(void) -{ - WM_operatortype_append(LOGIC_OT_properties); - WM_operatortype_append(LOGIC_OT_links_cut); -} - -static void logic_keymap(struct wmKeyConfig *keyconf) -{ - WM_keymap_ensure(keyconf, "Logic Editor", SPACE_LOGIC, 0); -} - -static void logic_refresh(const bContext *UNUSED(C), ScrArea *UNUSED(sa)) -{ -// SpaceLogic *slogic= CTX_wm_space_logic(C); -// Object *obedit= CTX_data_edit_object(C); - -} - -static void logic_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar, wmNotifier *wmn) -{ - /* context changes */ - switch (wmn->category) { - case NC_LOGIC: - ED_region_tag_redraw(ar); - break; - case NC_SCENE: - switch (wmn->data) { - case ND_FRAME: - ED_region_tag_redraw(ar); - break; - - case ND_OB_ACTIVE: - ED_region_tag_redraw(ar); - break; - } - break; - case NC_OBJECT: - break; - case NC_ID: - if (wmn->action == NA_RENAME) - ED_region_tag_redraw(ar); - break; - } -} - -static int logic_context(const bContext *UNUSED(C), const char *UNUSED(member), bContextDataResult *UNUSED(result)) -{ -// SpaceLogic *slogic= CTX_wm_space_logic(C); - return 0; -} - -/************************** main region ***************************/ - - -/* add handlers, stuff you only do once or on area/region changes */ -static void logic_main_region_init(wmWindowManager *wm, ARegion *ar) -{ - wmKeyMap *keymap; - - UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_CUSTOM, ar->winx, ar->winy); - - /* own keymaps */ - keymap = WM_keymap_ensure(wm->defaultconf, "Logic Editor", SPACE_LOGIC, 0); - WM_event_add_keymap_handler(&ar->handlers, keymap); -} - -static void logic_main_region_draw(const bContext *C, ARegion *ar) -{ - /* draw entirely, view changes should be handled here */ -// SpaceLogic *slogic= CTX_wm_space_logic(C); - View2D *v2d= &ar->v2d; - View2DScrollers *scrollers; - - /* clear and setup matrix */ - UI_ThemeClearColor(TH_BACK); - glClear(GL_COLOR_BUFFER_BIT); - - UI_view2d_view_ortho(v2d); - - logic_buttons((bContext *)C, ar); - - /* reset view matrix */ - UI_view2d_view_restore(C); - - /* scrollers */ - scrollers= UI_view2d_scrollers_calc(C, v2d, V2D_ARG_DUMMY, V2D_ARG_DUMMY, V2D_ARG_DUMMY, V2D_ARG_DUMMY); - UI_view2d_scrollers_draw(C, v2d, scrollers); - UI_view2d_scrollers_free(scrollers); - -} - - -/* *********************** buttons region ************************ */ - -/* add handlers, stuff you only do once or on area/region changes */ -static void logic_buttons_region_init(wmWindowManager *wm, ARegion *ar) -{ - wmKeyMap *keymap; - - ED_region_panels_init(wm, ar); - - keymap = WM_keymap_ensure(wm->defaultconf, "Logic Editor", SPACE_LOGIC, 0); - WM_event_add_keymap_handler(&ar->handlers, keymap); -} - -static void logic_buttons_region_draw(const bContext *C, ARegion *ar) -{ - ED_region_panels(C, ar, NULL, -1, true); -} - -/************************* header region **************************/ - -/* add handlers, stuff you only do once or on area/region changes */ -static void logic_header_region_init(wmWindowManager *UNUSED(wm), ARegion *ar) -{ - ED_region_header_init(ar); -} - -static void logic_header_region_draw(const bContext *C, ARegion *ar) -{ - ED_region_header(C, ar); -} - -/**************************** spacetype *****************************/ - -static void logic_id_remap(ScrArea *UNUSED(sa), SpaceLink *slink, ID *old_id, ID *new_id) -{ - SpaceLogic *slog = (SpaceLogic *)slink; - - if (!ELEM(GS(old_id->name), ID_GD)) { - return; - } - - if ((ID *)slog->gpd == old_id) { - slog->gpd = (bGPdata *)new_id; - id_us_min(old_id); - id_us_plus(new_id); - } -} - -/* only called once, from space/spacetypes.c */ -void ED_spacetype_logic(void) -{ - SpaceType *st = MEM_callocN(sizeof(SpaceType), "spacetype logic"); - ARegionType *art; - - st->spaceid = SPACE_LOGIC; - strncpy(st->name, "Logic", BKE_ST_MAXNAME); - - st->new = logic_new; - st->free = logic_free; - st->init = logic_init; - st->duplicate = logic_duplicate; - st->operatortypes = logic_operatortypes; - st->keymap = logic_keymap; - st->refresh = logic_refresh; - st->context = logic_context; - st->id_remap = logic_id_remap; - - /* regions: main window */ - art = MEM_callocN(sizeof(ARegionType), "spacetype logic region"); - art->regionid = RGN_TYPE_WINDOW; - art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_FRAMES | ED_KEYMAP_VIEW2D; - art->init = logic_main_region_init; - art->draw = logic_main_region_draw; - art->listener = logic_listener; - - BLI_addhead(&st->regiontypes, art); - - /* regions: listview/buttons */ - art = MEM_callocN(sizeof(ARegionType), "spacetype logic region"); - art->regionid = RGN_TYPE_UI; - art->prefsizex= 220; // XXX - art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_FRAMES; - art->listener = logic_listener; - art->init = logic_buttons_region_init; - art->draw = logic_buttons_region_draw; - BLI_addhead(&st->regiontypes, art); - - /* regions: header */ - art= MEM_callocN(sizeof(ARegionType), "spacetype logic region"); - art->regionid = RGN_TYPE_HEADER; - art->prefsizey = HEADERY; - art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_VIEW2D | ED_KEYMAP_FRAMES | ED_KEYMAP_HEADER; - art->init = logic_header_region_init; - art->draw = logic_header_region_draw; - - BLI_addhead(&st->regiontypes, art); - - BKE_spacetype_register(st); -} diff --git a/source/blender/editors/space_time/space_time.c b/source/blender/editors/space_time/space_time.c deleted file mode 100644 index 29cc5bafb17..00000000000 --- a/source/blender/editors/space_time/space_time.c +++ /dev/null @@ -1,834 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2008 Blender Foundation. - * All rights reserved. - * - * - * Contributor(s): Blender Foundation - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/editors/space_time/space_time.c - * \ingroup sptime - */ - - -#include <string.h> -#include <stdio.h> - -#include "DNA_cachefile_types.h" -#include "DNA_constraint_types.h" -#include "DNA_gpencil_types.h" -#include "DNA_modifier_types.h" -#include "DNA_object_types.h" -#include "DNA_scene_types.h" - -#include "MEM_guardedalloc.h" - -#include "BLI_blenlib.h" -#include "BLI_dlrbTree.h" -#include "BLI_utildefines.h" - -#include "BKE_constraint.h" -#include "BKE_context.h" -#include "BKE_main.h" -#include "BKE_modifier.h" -#include "BKE_screen.h" -#include "BKE_pointcache.h" - -#include "ED_anim_api.h" -#include "ED_keyframes_draw.h" -#include "ED_screen.h" - -#include "WM_api.h" -#include "WM_types.h" - -#include "BIF_gl.h" -#include "BIF_glutil.h" - -#include "UI_resources.h" -#include "UI_view2d.h" -#include "UI_interface.h" - -#include "ED_space_api.h" -#include "ED_markers.h" - -#include "time_intern.h" - -/* ************************ main time area region *********************** */ - -static void time_draw_sfra_efra(Scene *scene, View2D *v2d) -{ - /* draw darkened area outside of active timeline - * frame range used is preview range or scene range - */ - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glEnable(GL_BLEND); - glColor4f(0.0f, 0.0f, 0.0f, 0.4f); - - if (PSFRA < PEFRA) { - glRectf(v2d->cur.xmin, v2d->cur.ymin, (float)PSFRA, v2d->cur.ymax); - glRectf((float)PEFRA, v2d->cur.ymin, v2d->cur.xmax, v2d->cur.ymax); - } - else { - glRectf(v2d->cur.xmin, v2d->cur.ymin, v2d->cur.xmax, v2d->cur.ymax); - } - glDisable(GL_BLEND); - - UI_ThemeColorShade(TH_BACK, -60); - /* thin lines where the actual frames are */ - fdrawline((float)PSFRA, v2d->cur.ymin, (float)PSFRA, v2d->cur.ymax); - fdrawline((float)PEFRA, v2d->cur.ymin, (float)PEFRA, v2d->cur.ymax); -} - -static void time_draw_cache(Main *bmain, SpaceTime *stime, Object *ob, Scene *scene) -{ - PTCacheID *pid; - ListBase pidlist; - SpaceTimeCache *stc = stime->caches.first; - const float cache_draw_height = (4.0f * UI_DPI_FAC * U.pixelsize); - float yoffs = 0.f; - - if (!(stime->cache_display & TIME_CACHE_DISPLAY) || (!ob)) - return; - - BKE_ptcache_ids_from_object(bmain, &pidlist, ob, scene, 0); - - /* iterate over pointcaches on the active object, - * add spacetimecache and vertex array for each */ - for (pid = pidlist.first; pid; pid = pid->next) { - float col[4], *fp; - int i, sta = pid->cache->startframe, end = pid->cache->endframe; - int len = (end - sta + 1) * 4; - - switch (pid->type) { - case PTCACHE_TYPE_SOFTBODY: - if (!(stime->cache_display & TIME_CACHE_SOFTBODY)) continue; - break; - case PTCACHE_TYPE_PARTICLES: - if (!(stime->cache_display & TIME_CACHE_PARTICLES)) continue; - break; - case PTCACHE_TYPE_CLOTH: - if (!(stime->cache_display & TIME_CACHE_CLOTH)) continue; - break; - case PTCACHE_TYPE_SMOKE_DOMAIN: - case PTCACHE_TYPE_SMOKE_HIGHRES: - if (!(stime->cache_display & TIME_CACHE_SMOKE)) continue; - break; - case PTCACHE_TYPE_DYNAMICPAINT: - if (!(stime->cache_display & TIME_CACHE_DYNAMICPAINT)) continue; - break; - case PTCACHE_TYPE_RIGIDBODY: - if (!(stime->cache_display & TIME_CACHE_RIGIDBODY)) continue; - break; - } - - if (pid->cache->cached_frames == NULL) - continue; - - /* make sure we have stc with correct array length */ - if (stc == NULL || MEM_allocN_len(stc->array) != len * 2 * sizeof(float)) { - if (stc) { - MEM_freeN(stc->array); - } - else { - stc = MEM_callocN(sizeof(SpaceTimeCache), "spacetimecache"); - BLI_addtail(&stime->caches, stc); - } - - stc->array = MEM_callocN(len * 2 * sizeof(float), "SpaceTimeCache array"); - } - - /* fill the vertex array with a quad for each cached frame */ - for (i = sta, fp = stc->array; i <= end; i++) { - if (pid->cache->cached_frames[i - sta]) { - fp[0] = (float)i - 0.5f; - fp[1] = 0.0; - fp += 2; - - fp[0] = (float)i - 0.5f; - fp[1] = 1.0; - fp += 2; - - fp[0] = (float)i + 0.5f; - fp[1] = 1.0; - fp += 2; - - fp[0] = (float)i + 0.5f; - fp[1] = 0.0; - fp += 2; - } - } - - glPushMatrix(); - glTranslatef(0.0, (float)V2D_SCROLL_HEIGHT + yoffs, 0.0); - glScalef(1.0, cache_draw_height, 0.0); - - switch (pid->type) { - case PTCACHE_TYPE_SOFTBODY: - col[0] = 1.0; col[1] = 0.4; col[2] = 0.02; - col[3] = 0.1; - break; - case PTCACHE_TYPE_PARTICLES: - col[0] = 1.0; col[1] = 0.1; col[2] = 0.02; - col[3] = 0.1; - break; - case PTCACHE_TYPE_CLOTH: - col[0] = 0.1; col[1] = 0.1; col[2] = 0.75; - col[3] = 0.1; - break; - case PTCACHE_TYPE_SMOKE_DOMAIN: - case PTCACHE_TYPE_SMOKE_HIGHRES: - col[0] = 0.2; col[1] = 0.2; col[2] = 0.2; - col[3] = 0.1; - break; - case PTCACHE_TYPE_DYNAMICPAINT: - col[0] = 1.0; col[1] = 0.1; col[2] = 0.75; - col[3] = 0.1; - break; - case PTCACHE_TYPE_RIGIDBODY: - col[0] = 1.0; col[1] = 0.6; col[2] = 0.0; - col[3] = 0.1; - break; - default: - col[0] = 1.0; col[1] = 0.0; col[2] = 1.0; - col[3] = 0.1; - BLI_assert(0); - break; - } - glColor4fv(col); - - glEnable(GL_BLEND); - - glRectf((float)sta, 0.0, (float)end, 1.0); - - col[3] = 0.4f; - if (pid->cache->flag & PTCACHE_BAKED) { - col[0] -= 0.4f; col[1] -= 0.4f; col[2] -= 0.4f; - } - else if (pid->cache->flag & PTCACHE_OUTDATED) { - col[0] += 0.4f; col[1] += 0.4f; col[2] += 0.4f; - } - glColor4fv(col); - - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(2, GL_FLOAT, 0, stc->array); - glDrawArrays(GL_QUADS, 0, (fp - stc->array) / 2); - glDisableClientState(GL_VERTEX_ARRAY); - - glDisable(GL_BLEND); - - glPopMatrix(); - - yoffs += cache_draw_height; - - stc = stc->next; - } - - BLI_freelistN(&pidlist); - - /* free excessive caches */ - while (stc) { - SpaceTimeCache *tmp = stc->next; - BLI_remlink(&stime->caches, stc); - MEM_freeN(stc->array); - MEM_freeN(stc); - stc = tmp; - } -} - -static void time_cache_free(SpaceTime *stime) -{ - SpaceTimeCache *stc; - - for (stc = stime->caches.first; stc; stc = stc->next) { - if (stc->array) { - MEM_freeN(stc->array); - stc->array = NULL; - } - } - - BLI_freelistN(&stime->caches); -} - -static void time_cache_refresh(SpaceTime *stime) -{ - /* Free previous caches to indicate full refresh */ - time_cache_free(stime); -} - -/* helper function - find actkeycolumn that occurs on cframe, or the nearest one if not found */ -static ActKeyColumn *time_cfra_find_ak(ActKeyColumn *ak, float cframe) -{ - ActKeyColumn *akn = NULL; - - /* sanity checks */ - if (ak == NULL) - return NULL; - - /* check if this is a match, or whether it is in some subtree */ - if (cframe < ak->cfra) - akn = time_cfra_find_ak(ak->left, cframe); - else if (cframe > ak->cfra) - akn = time_cfra_find_ak(ak->right, cframe); - - /* if no match found (or found match), just use the current one */ - if (akn == NULL) - return ak; - else - return akn; -} - -/* helper for time_draw_keyframes() */ -static void time_draw_idblock_keyframes(View2D *v2d, ID *id, short onlysel) -{ - bDopeSheet ads = {NULL}; - DLRBT_Tree keys; - ActKeyColumn *ak; - - float fac1 = (GS(id->name) == ID_GD) ? 0.8f : 0.6f; /* draw GPencil keys taller, to help distinguish them */ - float fac2 = 1.0f - fac1; - - float ymin = v2d->tot.ymin; - float ymax = v2d->tot.ymax * fac1 + ymin * fac2; - - /* init binarytree-list for getting keyframes */ - BLI_dlrbTree_init(&keys); - - /* init dopesheet settings */ - if (onlysel) - ads.filterflag |= ADS_FILTER_ONLYSEL; - - /* populate tree with keyframe nodes */ - switch (GS(id->name)) { - case ID_SCE: - scene_to_keylist(&ads, (Scene *)id, &keys, NULL); - break; - case ID_OB: - ob_to_keylist(&ads, (Object *)id, &keys, NULL); - break; - case ID_GD: - gpencil_to_keylist(&ads, (bGPdata *)id, &keys); - break; - case ID_CF: - cachefile_to_keylist(&ads, (CacheFile *)id, &keys, NULL); - break; - default: - break; - } - - /* build linked-list for searching */ - BLI_dlrbTree_linkedlist_sync(&keys); - - /* start drawing keyframes - * - we use the binary-search capabilities of the tree to only start from - * the first visible keyframe (last one can then be easily checked) - * - draw within a single GL block to be faster - */ - glBegin(GL_LINES); - for (ak = time_cfra_find_ak(keys.root, v2d->cur.xmin); - (ak) && (ak->cfra <= v2d->cur.xmax); - ak = ak->next) - { - glVertex2f(ak->cfra, ymin); - glVertex2f(ak->cfra, ymax); - } - glEnd(); // GL_LINES - - /* free temp stuff */ - BLI_dlrbTree_free(&keys); -} - -static void time_draw_caches_keyframes(Main *bmain, Scene *scene, View2D *v2d, bool onlysel) -{ - CacheFile *cache_file; - - for (cache_file = bmain->cachefiles.first; - cache_file; - cache_file = cache_file->id.next) - { - cache_file->draw_flag &= ~CACHEFILE_KEYFRAME_DRAWN; - } - - for (Base *base = scene->base.first; base; base = base->next) { - Object *ob = base->object; - - ModifierData *md = modifiers_findByType(ob, eModifierType_MeshSequenceCache); - - if (md) { - MeshSeqCacheModifierData *mcmd = (MeshSeqCacheModifierData *)md; - - cache_file = mcmd->cache_file; - - if (!cache_file || (cache_file->draw_flag & CACHEFILE_KEYFRAME_DRAWN) != 0) { - continue; - } - - cache_file->draw_flag |= CACHEFILE_KEYFRAME_DRAWN; - - time_draw_idblock_keyframes(v2d, (ID *)cache_file, onlysel); - } - - for (bConstraint *con = ob->constraints.first; con; con = con->next) { - if (con->type != CONSTRAINT_TYPE_TRANSFORM_CACHE) { - continue; - } - - bTransformCacheConstraint *data = con->data; - - cache_file = data->cache_file; - - if (!cache_file || (cache_file->draw_flag & CACHEFILE_KEYFRAME_DRAWN) != 0) { - continue; - } - - cache_file->draw_flag |= CACHEFILE_KEYFRAME_DRAWN; - - time_draw_idblock_keyframes(v2d, (ID *)cache_file, onlysel); - } - } -} - -/* draw keyframe lines for timeline */ -static void time_draw_keyframes(const bContext *C, ARegion *ar) -{ - Scene *scene = CTX_data_scene(C); - Object *ob = CTX_data_active_object(C); - View2D *v2d = &ar->v2d; - bool onlysel = ((scene->flag & SCE_KEYS_NO_SELONLY) == 0); - - /* set this for all keyframe lines once and for all */ - glLineWidth(1.0); - - /* draw cache files keyframes (if available) */ - UI_ThemeColor(TH_TIME_KEYFRAME); - time_draw_caches_keyframes(CTX_data_main(C), scene, v2d, onlysel); - - /* draw grease pencil keyframes (if available) */ - UI_ThemeColor(TH_TIME_GP_KEYFRAME); - if (scene->gpd) { - time_draw_idblock_keyframes(v2d, (ID *)scene->gpd, onlysel); - } - if (ob && ob->gpd) { - time_draw_idblock_keyframes(v2d, (ID *)ob->gpd, onlysel); - } - - /* draw scene keyframes first - * - don't try to do this when only drawing active/selected data keyframes, - * since this can become quite slow - */ - if (onlysel == 0) { - /* set draw color */ - UI_ThemeColorShade(TH_TIME_KEYFRAME, -50); - time_draw_idblock_keyframes(v2d, (ID *)scene, onlysel); - } - - /* draw keyframes from selected objects - * - only do the active object if in posemode (i.e. showing only keyframes for the bones) - * OR the onlysel flag was set, which means that only active object's keyframes should - * be considered - */ - UI_ThemeColor(TH_TIME_KEYFRAME); - - if (ob && ((ob->mode == OB_MODE_POSE) || onlysel)) { - /* draw keyframes for active object only */ - time_draw_idblock_keyframes(v2d, (ID *)ob, onlysel); - } - else { - bool active_done = false; - - /* draw keyframes from all selected objects */ - CTX_DATA_BEGIN (C, Object *, obsel, selected_objects) - { - /* last arg is 0, since onlysel doesn't apply here... */ - time_draw_idblock_keyframes(v2d, (ID *)obsel, 0); - - /* if this object is the active one, set flag so that we don't draw again */ - if (obsel == ob) - active_done = true; - } - CTX_DATA_END; - - /* if active object hasn't been done yet, draw it... */ - if (ob && (active_done == 0)) - time_draw_idblock_keyframes(v2d, (ID *)ob, 0); - } -} - -/* ---------------- */ - -static void time_refresh(const bContext *UNUSED(C), ScrArea *sa) -{ - /* find the main timeline region and refresh cache display*/ - ARegion *ar = BKE_area_find_region_type(sa, RGN_TYPE_WINDOW); - if (ar) { - SpaceTime *stime = (SpaceTime *)sa->spacedata.first; - time_cache_refresh(stime); - } -} - -/* editor level listener */ -static void time_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn) -{ - - /* mainly for updating cache display */ - switch (wmn->category) { - case NC_OBJECT: - { - switch (wmn->data) { - case ND_BONE_SELECT: - case ND_BONE_ACTIVE: - case ND_POINTCACHE: - case ND_MODIFIER: - case ND_PARTICLE: - case ND_KEYS: - ED_area_tag_refresh(sa); - ED_area_tag_redraw(sa); - break; - } - break; - } - case NC_SCENE: - { - switch (wmn->data) { - case ND_RENDER_RESULT: - ED_area_tag_redraw(sa); - break; - case ND_OB_ACTIVE: - case ND_FRAME: - ED_area_tag_refresh(sa); - break; - case ND_FRAME_RANGE: - { - ARegion *ar; - Scene *scene = wmn->reference; - - for (ar = sa->regionbase.first; ar; ar = ar->next) { - if (ar->regiontype == RGN_TYPE_WINDOW) { - ar->v2d.tot.xmin = (float)(SFRA - 4); - ar->v2d.tot.xmax = (float)(EFRA + 4); - break; - } - } - break; - } - } - break; - } - case NC_SPACE: - { - switch (wmn->data) { - case ND_SPACE_CHANGED: - ED_area_tag_refresh(sa); - break; - } - break; - } - case NC_WM: - { - switch (wmn->data) { - case ND_FILEREAD: - ED_area_tag_refresh(sa); - break; - } - break; - } - } -} - -/* ---------------- */ - -/* add handlers, stuff you only do once or on area/region changes */ -static void time_main_region_init(wmWindowManager *wm, ARegion *ar) -{ - wmKeyMap *keymap; - - UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_CUSTOM, ar->winx, ar->winy); - - /* own keymap */ - keymap = WM_keymap_ensure(wm->defaultconf, "Timeline", SPACE_TIME, 0); - WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct); -} - -static void time_main_region_draw(const bContext *C, ARegion *ar) -{ - /* draw entirely, view changes should be handled here */ - Main *bmain = CTX_data_main(C); - Scene *scene = CTX_data_scene(C); - SpaceTime *stime = CTX_wm_space_time(C); - Object *obact = CTX_data_active_object(C); - View2D *v2d = &ar->v2d; - View2DGrid *grid; - View2DScrollers *scrollers; - int unit, flag = 0; - - /* clear and setup matrix */ - UI_ThemeClearColor(TH_BACK); - glClear(GL_COLOR_BUFFER_BIT); - - UI_view2d_view_ortho(v2d); - - /* grid */ - unit = (stime->flag & TIME_DRAWFRAMES) ? V2D_UNIT_FRAMES : V2D_UNIT_SECONDS; - grid = UI_view2d_grid_calc(scene, v2d, unit, V2D_GRID_CLAMP, V2D_ARG_DUMMY, V2D_ARG_DUMMY, ar->winx, ar->winy); - UI_view2d_grid_draw(v2d, grid, (V2D_VERTICAL_LINES | V2D_VERTICAL_AXIS)); - UI_view2d_grid_free(grid); - - ED_region_draw_cb_draw(C, ar, REGION_DRAW_PRE_VIEW); - - /* start and end frame */ - time_draw_sfra_efra(scene, v2d); - - /* current frame */ - flag = DRAWCFRA_WIDE; /* this is only really needed on frames where there's a keyframe, but this will do... */ - if ((stime->flag & TIME_DRAWFRAMES) == 0) flag |= DRAWCFRA_UNIT_SECONDS; - if (stime->flag & TIME_CFRA_NUM) flag |= DRAWCFRA_SHOW_NUMBOX; - ANIM_draw_cfra(C, v2d, flag); - - UI_view2d_view_ortho(v2d); - - /* keyframes */ - time_draw_keyframes(C, ar); - - /* markers */ - UI_view2d_view_orthoSpecial(ar, v2d, 1); - ED_markers_draw(C, 0); - - /* caches */ - time_draw_cache(bmain, stime, obact, scene); - - /* callback */ - UI_view2d_view_ortho(v2d); - ED_region_draw_cb_draw(C, ar, REGION_DRAW_POST_VIEW); - - /* reset view matrix */ - UI_view2d_view_restore(C); - - /* scrollers */ - scrollers = UI_view2d_scrollers_calc(C, v2d, unit, V2D_GRID_CLAMP, V2D_ARG_DUMMY, V2D_ARG_DUMMY); - UI_view2d_scrollers_draw(C, v2d, scrollers); - UI_view2d_scrollers_free(scrollers); -} - -static void time_main_region_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar, wmNotifier *wmn) -{ - /* context changes */ - switch (wmn->category) { - case NC_SPACE: - if (wmn->data == ND_SPACE_TIME) - ED_region_tag_redraw(ar); - break; - - case NC_ANIMATION: - ED_region_tag_redraw(ar); - break; - - case NC_SCENE: - switch (wmn->data) { - case ND_OB_SELECT: - case ND_OB_ACTIVE: - case ND_FRAME: - case ND_FRAME_RANGE: - case ND_KEYINGSET: - case ND_RENDER_OPTIONS: - ED_region_tag_redraw(ar); - break; - } - break; - case NC_GPENCIL: - if (wmn->data == ND_DATA) - ED_region_tag_redraw(ar); - break; - } -} - -/* ************************ header time area region *********************** */ - -/* add handlers, stuff you only do once or on area/region changes */ -static void time_header_region_init(wmWindowManager *UNUSED(wm), ARegion *ar) -{ - ED_region_header_init(ar); -} - -static void time_header_region_draw(const bContext *C, ARegion *ar) -{ - ED_region_header(C, ar); -} - -static void time_header_region_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegion *ar, wmNotifier *wmn) -{ - /* context changes */ - switch (wmn->category) { - case NC_SCREEN: - { - if (wmn->data == ND_ANIMPLAY) - ED_region_tag_redraw(ar); - break; - } - case NC_SCENE: - { - switch (wmn->data) { - case ND_RENDER_RESULT: - case ND_OB_SELECT: - case ND_FRAME: - case ND_FRAME_RANGE: - case ND_KEYINGSET: - case ND_RENDER_OPTIONS: - ED_region_tag_redraw(ar); - break; - } - break; - } - case NC_SPACE: - { - if (wmn->data == ND_SPACE_TIME) - ED_region_tag_redraw(ar); - break; - } - } -} - -/* ******************** default callbacks for time space ***************** */ - -static SpaceLink *time_new(const bContext *C) -{ - Scene *scene = CTX_data_scene(C); - ARegion *ar; - SpaceTime *stime; - - stime = MEM_callocN(sizeof(SpaceTime), "inittime"); - - stime->spacetype = SPACE_TIME; - stime->flag |= TIME_DRAWFRAMES; - - /* header */ - ar = MEM_callocN(sizeof(ARegion), "header for time"); - - BLI_addtail(&stime->regionbase, ar); - ar->regiontype = RGN_TYPE_HEADER; - ar->alignment = RGN_ALIGN_BOTTOM; - - /* main region */ - ar = MEM_callocN(sizeof(ARegion), "main region for time"); - - BLI_addtail(&stime->regionbase, ar); - ar->regiontype = RGN_TYPE_WINDOW; - - ar->v2d.tot.xmin = (float)(SFRA - 4); - ar->v2d.tot.ymin = 0.0f; - ar->v2d.tot.xmax = (float)(EFRA + 4); - ar->v2d.tot.ymax = 50.0f; - - ar->v2d.cur = ar->v2d.tot; - - ar->v2d.min[0] = 1.0f; - ar->v2d.min[1] = 50.0f; - - ar->v2d.max[0] = MAXFRAMEF; - ar->v2d.max[1] = 50.0; - - ar->v2d.minzoom = 0.1f; - ar->v2d.maxzoom = 10.0; - - ar->v2d.scroll |= (V2D_SCROLL_BOTTOM | V2D_SCROLL_SCALE_HORIZONTAL); - ar->v2d.align |= V2D_ALIGN_NO_NEG_Y; - ar->v2d.keepofs |= V2D_LOCKOFS_Y; - ar->v2d.keepzoom |= V2D_LOCKZOOM_Y; - - - return (SpaceLink *)stime; -} - -/* not spacelink itself */ -static void time_free(SpaceLink *sl) -{ - SpaceTime *stime = (SpaceTime *)sl; - - time_cache_free(stime); -} -/* spacetype; init callback in ED_area_initialize() */ -/* init is called to (re)initialize an existing editor (file read, screen changes) */ -/* validate spacedata, add own area level handlers */ -static void time_init(wmWindowManager *UNUSED(wm), ScrArea *sa) -{ - SpaceTime *stime = (SpaceTime *)sa->spacedata.first; - - time_cache_free(stime); - - /* enable all cache display */ - stime->cache_display |= TIME_CACHE_DISPLAY; - stime->cache_display |= (TIME_CACHE_SOFTBODY | TIME_CACHE_PARTICLES); - stime->cache_display |= (TIME_CACHE_CLOTH | TIME_CACHE_SMOKE | TIME_CACHE_DYNAMICPAINT); - stime->cache_display |= TIME_CACHE_RIGIDBODY; -} - -static SpaceLink *time_duplicate(SpaceLink *sl) -{ - SpaceTime *stime = (SpaceTime *)sl; - SpaceTime *stimen = MEM_dupallocN(stime); - - BLI_listbase_clear(&stimen->caches); - - return (SpaceLink *)stimen; -} - -/* only called once, from space_api/spacetypes.c */ -/* it defines all callbacks to maintain spaces */ -void ED_spacetype_time(void) -{ - SpaceType *st = MEM_callocN(sizeof(SpaceType), "spacetype time"); - ARegionType *art; - - st->spaceid = SPACE_TIME; - strncpy(st->name, "Timeline", BKE_ST_MAXNAME); - - st->new = time_new; - st->free = time_free; - st->init = time_init; - st->duplicate = time_duplicate; - st->operatortypes = time_operatortypes; - st->keymap = NULL; - st->listener = time_listener; - st->refresh = time_refresh; - - /* regions: main window */ - art = MEM_callocN(sizeof(ARegionType), "spacetype time region"); - art->regionid = RGN_TYPE_WINDOW; - art->keymapflag = ED_KEYMAP_VIEW2D | ED_KEYMAP_MARKERS | ED_KEYMAP_ANIMATION | ED_KEYMAP_FRAMES; - - art->init = time_main_region_init; - art->draw = time_main_region_draw; - art->listener = time_main_region_listener; - art->keymap = time_keymap; - art->lock = 1; /* Due to pointcache, see T4960. */ - BLI_addhead(&st->regiontypes, art); - - /* regions: header */ - art = MEM_callocN(sizeof(ARegionType), "spacetype time region"); - art->regionid = RGN_TYPE_HEADER; - art->prefsizey = HEADERY; - art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_VIEW2D | ED_KEYMAP_FRAMES | ED_KEYMAP_HEADER; - - art->init = time_header_region_init; - art->draw = time_header_region_draw; - art->listener = time_header_region_listener; - BLI_addhead(&st->regiontypes, art); - - BKE_spacetype_register(st); -} diff --git a/source/blender/editors/space_time/time_ops.c b/source/blender/editors/space_time/time_ops.c deleted file mode 100644 index 6962af52bb1..00000000000 --- a/source/blender/editors/space_time/time_ops.c +++ /dev/null @@ -1,218 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2008 Blender Foundation. - * All rights reserved. - * - * - * Contributor(s): Blender Foundation - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/editors/space_time/time_ops.c - * \ingroup sptime - */ - - -#include <stdlib.h> -#include <math.h> - -#include "DNA_scene_types.h" - -#include "BLI_blenlib.h" -#include "BLI_utildefines.h" - -#include "BKE_context.h" - -#include "ED_anim_api.h" -#include "ED_screen.h" - -#include "WM_api.h" -#include "WM_types.h" - -#include "time_intern.h" - -/* ****************** Start/End Frame Operators *******************************/ -static int time_set_sfra_exec(bContext *C, wmOperator *UNUSED(op)) -{ - Scene *scene = CTX_data_scene(C); - int frame; - - if (scene == NULL) - return OPERATOR_CANCELLED; - - frame = CFRA; - - /* if Preview Range is defined, set the 'start' frame for that */ - if (PRVRANGEON) - scene->r.psfra = frame; - else - scene->r.sfra = frame; - - if (PEFRA < frame) { - if (PRVRANGEON) - scene->r.pefra = frame; - else - scene->r.efra = frame; - } - - WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene); - - return OPERATOR_FINISHED; -} - -static void TIME_OT_start_frame_set(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Set Start Frame"; - ot->idname = "TIME_OT_start_frame_set"; - ot->description = "Set the start frame"; - - /* api callbacks */ - ot->exec = time_set_sfra_exec; - ot->poll = ED_operator_timeline_active; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; -} - - -static int time_set_efra_exec(bContext *C, wmOperator *UNUSED(op)) -{ - Scene *scene = CTX_data_scene(C); - int frame; - - if (scene == NULL) - return OPERATOR_CANCELLED; - - frame = CFRA; - - /* if Preview Range is defined, set the 'end' frame for that */ - if (PRVRANGEON) - scene->r.pefra = frame; - else - scene->r.efra = frame; - - if (PSFRA > frame) { - if (PRVRANGEON) - scene->r.psfra = frame; - else - scene->r.sfra = frame; - } - - WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene); - - return OPERATOR_FINISHED; -} - -static void TIME_OT_end_frame_set(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Set End Frame"; - ot->idname = "TIME_OT_end_frame_set"; - ot->description = "Set the end frame"; - - /* api callbacks */ - ot->exec = time_set_efra_exec; - ot->poll = ED_operator_timeline_active; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; -} - -/* ************************ View All Operator *******************************/ - -static int time_view_all_exec(bContext *C, wmOperator *UNUSED(op)) -{ - Scene *scene = CTX_data_scene(C); - ARegion *ar = CTX_wm_region(C); - - if (ELEM(NULL, scene, ar)) - return OPERATOR_CANCELLED; - - View2D *v2d = &ar->v2d; - - /* set extents of view to start/end frames (Preview Range too) */ - v2d->cur.xmin = (float)PSFRA; - v2d->cur.xmax = (float)PEFRA; - - /* we need an extra "buffer" factor on either side so that the endpoints are visible */ - const float extra = 0.01f * BLI_rctf_size_x(&v2d->cur); - v2d->cur.xmin -= extra; - v2d->cur.xmax += extra; - - /* this only affects this TimeLine instance, so just force redraw of this region */ - ED_region_tag_redraw(ar); - - return OPERATOR_FINISHED; -} - -static void TIME_OT_view_all(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "View All"; - ot->idname = "TIME_OT_view_all"; - ot->description = "Show the entire playable frame range"; - - /* api callbacks */ - ot->exec = time_view_all_exec; - ot->poll = ED_operator_timeline_active; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; -} - -/* ************************ View Frame Operator *******************************/ - -static int time_view_frame_exec(bContext *C, wmOperator *op) -{ - const int smooth_viewtx = WM_operator_smooth_viewtx_get(op); - ANIM_center_frame(C, smooth_viewtx); - - return OPERATOR_FINISHED; -} - -static void TIME_OT_view_frame(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "View Frame"; - ot->idname = "TIME_OT_view_frame"; - ot->description = "Reset viewable area to show range around current frame"; - - /* api callbacks */ - ot->exec = time_view_frame_exec; - ot->poll = ED_operator_timeline_active; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; -} - -/* ************************** registration **********************************/ - -void time_operatortypes(void) -{ - WM_operatortype_append(TIME_OT_start_frame_set); - WM_operatortype_append(TIME_OT_end_frame_set); - WM_operatortype_append(TIME_OT_view_all); - WM_operatortype_append(TIME_OT_view_frame); -} - -void time_keymap(wmKeyConfig *keyconf) -{ - WM_keymap_ensure(keyconf, "Timeline", SPACE_TIME, 0); -} diff --git a/source/blender/makesrna/intern/rna_sensor.c b/source/blender/makesrna/intern/rna_sensor.c deleted file mode 100644 index e04e78f3ac7..00000000000 --- a/source/blender/makesrna/intern/rna_sensor.c +++ /dev/null @@ -1,939 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * Contributor(s): Blender Foundation (2008). - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/makesrna/intern/rna_sensor.c - * \ingroup RNA - */ - -#include <stdlib.h> - -#include "DNA_constraint_types.h" -#include "DNA_object_types.h" -#include "DNA_sensor_types.h" - -#include "BLI_utildefines.h" -#include "BLI_math.h" -#include "BLI_string_utils.h" - -#include "BLT_translation.h" - -#include "RNA_define.h" -#include "RNA_enum_types.h" -#include "RNA_access.h" - -#include "rna_internal.h" - -#include "WM_types.h" - -/* Always keep in alphabetical order */ -static const EnumPropertyItem sensor_type_items[] = { - {SENS_ACTUATOR, "ACTUATOR", 0, "Actuator", ""}, - {SENS_ALWAYS, "ALWAYS", 0, "Always", ""}, - {SENS_ARMATURE, "ARMATURE", 0, "Armature", ""}, - {SENS_COLLISION, "COLLISION", 0, "Collision", ""}, - {SENS_DELAY, "DELAY", 0, "Delay", ""}, - {SENS_JOYSTICK, "JOYSTICK", 0, "Joystick", ""}, - {SENS_KEYBOARD, "KEYBOARD", 0, "Keyboard", ""}, - {SENS_MESSAGE, "MESSAGE", 0, "Message", ""}, - {SENS_MOUSE, "MOUSE", 0, "Mouse", ""}, - {SENS_NEAR, "NEAR", 0, "Near", ""}, - {SENS_PROPERTY, "PROPERTY", 0, "Property", ""}, - {SENS_RADAR, "RADAR", 0, "Radar", ""}, - {SENS_RANDOM, "RANDOM", 0, "Random", ""}, - {SENS_RAY, "RAY", 0, "Ray", ""}, - {0, NULL, 0, NULL, NULL} -}; - -#ifdef RNA_RUNTIME - -#include "BKE_sca.h" -#include "DNA_controller_types.h" - -static StructRNA *rna_Sensor_refine(struct PointerRNA *ptr) -{ - bSensor *sensor = (bSensor *)ptr->data; - - switch (sensor->type) { - case SENS_ALWAYS: - return &RNA_AlwaysSensor; - case SENS_NEAR: - return &RNA_NearSensor; - case SENS_KEYBOARD: - return &RNA_KeyboardSensor; - case SENS_PROPERTY: - return &RNA_PropertySensor; - case SENS_ARMATURE: - return &RNA_ArmatureSensor; - case SENS_MOUSE: - return &RNA_MouseSensor; - case SENS_COLLISION: - return &RNA_CollisionSensor; - case SENS_RADAR: - return &RNA_RadarSensor; - case SENS_RANDOM: - return &RNA_RandomSensor; - case SENS_RAY: - return &RNA_RaySensor; - case SENS_MESSAGE: - return &RNA_MessageSensor; - case SENS_JOYSTICK: - return &RNA_JoystickSensor; - case SENS_ACTUATOR: - return &RNA_ActuatorSensor; - case SENS_DELAY: - return &RNA_DelaySensor; - default: - return &RNA_Sensor; - } -} - -static void rna_Sensor_name_set(PointerRNA *ptr, const char *value) -{ - Object *ob = ptr->id.data; - bSensor *sens = ptr->data; - BLI_strncpy_utf8(sens->name, value, sizeof(sens->name)); - BLI_uniquename(&ob->sensors, sens, DATA_("Sensor"), '.', offsetof(bSensor, name), sizeof(sens->name)); -} - -static void rna_Sensor_type_set(struct PointerRNA *ptr, int value) -{ - bSensor *sens = (bSensor *)ptr->data; - if (value != sens->type) { - sens->type = value; - init_sensor(sens); - } -} - -/* Always keep in alphabetical order */ - -static void rna_Sensor_controllers_begin(CollectionPropertyIterator *iter, PointerRNA *ptr) -{ - bSensor *sens = (bSensor *)ptr->data; - rna_iterator_array_begin(iter, sens->links, sizeof(bController *), (int)sens->totlinks, 0, NULL); -} - -static int rna_Sensor_controllers_length(PointerRNA *ptr) -{ - bSensor *sens = (bSensor *)ptr->data; - return (int) sens->totlinks; -} - -const EnumPropertyItem *rna_Sensor_type_itemf(bContext *C, PointerRNA *ptr, PropertyRNA *UNUSED(prop), bool *r_free) -{ - EnumPropertyItem *item = NULL; - Object *ob = NULL; - int totitem = 0; - - if (ptr->type == &RNA_Sensor || RNA_struct_is_a(ptr->type, &RNA_Sensor)) { - ob = (Object *)ptr->id.data; - } - else { - /* can't use ob from ptr->id.data because that enum is also used by operators */ - ob = CTX_data_active_object(C); - } - - RNA_enum_items_add_value(&item, &totitem, sensor_type_items, SENS_ACTUATOR); - RNA_enum_items_add_value(&item, &totitem, sensor_type_items, SENS_ALWAYS); - - if (ob != NULL) { - if (ob->type == OB_ARMATURE) { - RNA_enum_items_add_value(&item, &totitem, sensor_type_items, SENS_ARMATURE); - } - } - RNA_enum_items_add_value(&item, &totitem, sensor_type_items, SENS_COLLISION); - RNA_enum_items_add_value(&item, &totitem, sensor_type_items, SENS_DELAY); - RNA_enum_items_add_value(&item, &totitem, sensor_type_items, SENS_JOYSTICK); - RNA_enum_items_add_value(&item, &totitem, sensor_type_items, SENS_KEYBOARD); - RNA_enum_items_add_value(&item, &totitem, sensor_type_items, SENS_MESSAGE); - RNA_enum_items_add_value(&item, &totitem, sensor_type_items, SENS_MOUSE); - RNA_enum_items_add_value(&item, &totitem, sensor_type_items, SENS_NEAR); - RNA_enum_items_add_value(&item, &totitem, sensor_type_items, SENS_PROPERTY); - RNA_enum_items_add_value(&item, &totitem, sensor_type_items, SENS_RADAR); - RNA_enum_items_add_value(&item, &totitem, sensor_type_items, SENS_RANDOM); - RNA_enum_items_add_value(&item, &totitem, sensor_type_items, SENS_RAY); - RNA_enum_items_add_value(&item, &totitem, sensor_type_items, SENS_TOUCH); - - RNA_enum_item_end(&item, &totitem); - *r_free = true; - - return item; -} - -static void rna_Sensor_keyboard_key_set(struct PointerRNA *ptr, int value) -{ - bSensor *sens = (bSensor *)ptr->data; - bKeyboardSensor *ks = (bKeyboardSensor *)sens->data; - - if (ISKEYBOARD(value)) - ks->key = value; - else - ks->key = 0; -} - -static void rna_Sensor_keyboard_modifier_set(struct PointerRNA *ptr, int value) -{ - bSensor *sens = (bSensor *)ptr->data; - bKeyboardSensor *ks = (bKeyboardSensor *)sens->data; - - if (ISKEYBOARD(value)) - ks->qual = value; - else - ks->qual = 0; -} - -static void rna_Sensor_keyboard_modifier2_set(struct PointerRNA *ptr, int value) -{ - bSensor *sens = (bSensor *)ptr->data; - bKeyboardSensor *ks = (bKeyboardSensor *)sens->data; - - if (ISKEYBOARD(value)) - ks->qual2 = value; - else - ks->qual2 = 0; -} - -static void rna_Sensor_tap_set(struct PointerRNA *ptr, bool value) -{ - bSensor *sens = (bSensor *)ptr->data; - - sens->tap = value; - if (sens->tap == 1) - sens->level = 0; -} - -static void rna_Sensor_level_set(struct PointerRNA *ptr, bool value) -{ - bSensor *sens = (bSensor *)ptr->data; - - sens->level = value; - if (sens->level == 1) - sens->tap = 0; -} - -static void rna_Sensor_Armature_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr) -{ - bSensor *sens = (bSensor *)ptr->data; - bArmatureSensor *as = sens->data; - Object *ob = (Object *)ptr->id.data; - - char *posechannel = as->posechannel; - char *constraint = as->constraint; - - /* check that bone exist in the active object */ - if (ob->type == OB_ARMATURE && ob->pose) { - bPoseChannel *pchan; - bPose *pose = ob->pose; - for (pchan = pose->chanbase.first; pchan; pchan = pchan->next) { - if (STREQ(pchan->name, posechannel)) { - /* found it, now look for constraint channel */ - bConstraint *con; - for (con = pchan->constraints.first; con; con = con->next) { - if (STREQ(con->name, constraint)) { - /* found it, all ok */ - return; - } - } - /* didn't find constraint, make empty */ - constraint[0] = 0; - return; - } - } - } - /* didn't find any */ - posechannel[0] = 0; - constraint[0] = 0; -} -#else - -static void rna_def_sensor(BlenderRNA *brna) -{ - StructRNA *srna; - PropertyRNA *prop; - - srna = RNA_def_struct(brna, "Sensor", NULL); - RNA_def_struct_ui_text(srna, "Sensor", "Game engine logic brick to detect events"); - RNA_def_struct_sdna(srna, "bSensor"); - RNA_def_struct_refine_func(srna, "rna_Sensor_refine"); - - prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE); - RNA_def_property_ui_text(prop, "Name", "Sensor name"); - RNA_def_property_string_funcs(prop, NULL, NULL, "rna_Sensor_name_set"); - RNA_def_struct_name_property(srna, prop); - RNA_def_property_update(prop, NC_LOGIC, NULL); - - prop = RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE); - RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_enum_items(prop, sensor_type_items); - RNA_def_property_enum_funcs(prop, NULL, "rna_Sensor_type_set", "rna_Sensor_type_itemf"); - RNA_def_property_ui_text(prop, "Type", ""); - RNA_def_property_update(prop, NC_LOGIC, NULL); - - prop = RNA_def_property(srna, "pin", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", SENS_PIN); - RNA_def_property_ui_text(prop, "Pinned", "Display when not linked to a visible states controller"); - RNA_def_property_ui_icon(prop, ICON_UNPINNED, 1); - RNA_def_property_update(prop, NC_LOGIC, NULL); - - prop = RNA_def_property(srna, "active", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", SENS_DEACTIVATE); - RNA_def_property_ui_text(prop, "Active", "Set active state of the sensor"); - RNA_def_property_update(prop, NC_LOGIC, NULL); - - prop = RNA_def_property(srna, "show_expanded", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", SENS_SHOW); - RNA_def_property_ui_text(prop, "Expanded", "Set sensor expanded in the user interface"); - RNA_def_property_ui_icon(prop, ICON_TRIA_RIGHT, 1); - RNA_def_property_update(prop, NC_LOGIC, NULL); - - prop = RNA_def_property(srna, "invert", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_ui_text(prop, "Invert Output", "Invert the level(output) of this sensor"); - RNA_def_property_update(prop, NC_LOGIC, NULL); - - prop = RNA_def_property(srna, "use_level", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "level", 1); - RNA_def_property_ui_text(prop, "Level", - "Level detector, trigger controllers of new states " - "(only applicable upon logic state transition)"); - RNA_def_property_boolean_funcs(prop, NULL, "rna_Sensor_level_set"); - RNA_def_property_update(prop, NC_LOGIC, NULL); - - prop = RNA_def_property(srna, "use_pulse_true_level", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "pulse", SENS_PULSE_REPEAT); - RNA_def_property_ui_text(prop, "Pulse True Level", "Activate TRUE level triggering (pulse mode)"); - RNA_def_property_update(prop, NC_LOGIC, NULL); - - prop = RNA_def_property(srna, "use_pulse_false_level", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "pulse", SENS_NEG_PULSE_MODE); - RNA_def_property_ui_text(prop, "Pulse False Level", "Activate FALSE level triggering (pulse mode)"); - RNA_def_property_update(prop, NC_LOGIC, NULL); - - prop = RNA_def_property(srna, "tick_skip", PROP_INT, PROP_NONE); - RNA_def_property_int_sdna(prop, NULL, "freq"); - RNA_def_property_ui_text(prop, "Skip", - "Number of logic ticks skipped between 2 active pulses " - "(0 = pulse every logic tick, 1 = skip 1 logic tick between pulses, etc.)"); - RNA_def_property_range(prop, 0, 10000); - RNA_def_property_update(prop, NC_LOGIC, NULL); - - prop = RNA_def_property(srna, "use_tap", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "tap", 1); - RNA_def_property_boolean_funcs(prop, NULL, "rna_Sensor_tap_set"); - RNA_def_property_ui_text(prop, "Tap", - "Trigger controllers only for an instant, even while the sensor remains true"); - RNA_def_property_update(prop, NC_LOGIC, NULL); - - prop = RNA_def_property(srna, "controllers", PROP_COLLECTION, PROP_NONE); - RNA_def_property_collection_sdna(prop, NULL, "links", NULL); - RNA_def_property_struct_type(prop, "Controller"); - RNA_def_property_ui_text(prop, "Controllers", "The list containing the controllers connected to the sensor"); - RNA_def_property_collection_funcs(prop, "rna_Sensor_controllers_begin", "rna_iterator_array_next", - "rna_iterator_array_end", "rna_iterator_array_dereference_get", - "rna_Sensor_controllers_length", NULL, NULL, NULL); - - - RNA_api_sensor(srna); -} - -static void rna_def_always_sensor(BlenderRNA *brna) -{ - StructRNA *srna; - srna = RNA_def_struct(brna, "AlwaysSensor", "Sensor"); - RNA_def_struct_ui_text(srna, "Always Sensor", "Sensor to generate continuous pulses"); -} - -static void rna_def_near_sensor(BlenderRNA *brna) -{ - StructRNA *srna; - PropertyRNA *prop; - - srna = RNA_def_struct(brna, "NearSensor", "Sensor"); - RNA_def_struct_ui_text(srna, "Near Sensor", "Sensor to detect nearby objects"); - RNA_def_struct_sdna_from(srna, "bNearSensor", "data"); - - prop = RNA_def_property(srna, "property", PROP_STRING, PROP_NONE); - RNA_def_property_string_sdna(prop, NULL, "name"); - RNA_def_property_ui_text(prop, "Property", "Only look for objects with this property (blank = all objects)"); - RNA_def_property_update(prop, NC_LOGIC, NULL); - - prop = RNA_def_property(srna, "distance", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "dist"); - RNA_def_property_ui_text(prop, "Distance", "Trigger distance"); - RNA_def_property_range(prop, 0.0f, 10000.0f); - RNA_def_property_update(prop, NC_LOGIC, NULL); - - prop = RNA_def_property(srna, "reset_distance", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "resetdist"); - RNA_def_property_ui_text(prop, "Reset Distance", "The distance where the sensor forgets the actor"); - RNA_def_property_range(prop, 0.0f, 10000.0f); - RNA_def_property_update(prop, NC_LOGIC, NULL); -} - -static void rna_def_mouse_sensor(BlenderRNA *brna) -{ - StructRNA *srna; - PropertyRNA *prop; - - static const EnumPropertyItem mouse_event_items[] = { - {BL_SENS_MOUSE_LEFT_BUTTON, "LEFTCLICK", 0, "Left Button", ""}, - {BL_SENS_MOUSE_MIDDLE_BUTTON, "MIDDLECLICK", 0, "Middle Button", ""}, - {BL_SENS_MOUSE_RIGHT_BUTTON, "RIGHTCLICK", 0, "Right Button", ""}, - {BL_SENS_MOUSE_WHEEL_UP, "WHEELUP", 0, "Wheel Up", ""}, - {BL_SENS_MOUSE_WHEEL_DOWN, "WHEELDOWN", 0, "Wheel Down", ""}, - {BL_SENS_MOUSE_MOVEMENT, "MOVEMENT", 0, "Movement", ""}, - {BL_SENS_MOUSE_MOUSEOVER, "MOUSEOVER", 0, "Mouse Over", ""}, - {BL_SENS_MOUSE_MOUSEOVER_ANY, "MOUSEOVERANY", 0, "Mouse Over Any", ""}, - {0, NULL, 0, NULL, NULL} - }; - - static const EnumPropertyItem prop_mouse_type_items[] = { - {SENS_COLLISION_PROPERTY, "PROPERTY", ICON_LOGIC, "Property", "Use a property for ray intersections"}, - {SENS_COLLISION_MATERIAL, "MATERIAL", ICON_MATERIAL_DATA, "Material", "Use a material for ray intersections"}, - {0, NULL, 0, NULL, NULL} - }; - - srna = RNA_def_struct(brna, "MouseSensor", "Sensor"); - RNA_def_struct_ui_text(srna, "Mouse Sensor", "Sensor to detect mouse events"); - RNA_def_struct_sdna_from(srna, "bMouseSensor", "data"); - - prop = RNA_def_property(srna, "mouse_event", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_sdna(prop, NULL, "type"); - RNA_def_property_enum_items(prop, mouse_event_items); - RNA_def_property_ui_text(prop, "Mouse Event", "Type of event this mouse sensor should trigger on"); - RNA_def_property_update(prop, NC_LOGIC, NULL); - - prop = RNA_def_property(srna, "use_pulse", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", SENS_MOUSE_FOCUS_PULSE); - RNA_def_property_ui_text(prop, "Pulse", "Moving the mouse over a different object generates a pulse"); - RNA_def_property_update(prop, NC_LOGIC, NULL); - - prop = RNA_def_property(srna, "use_material", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_bitflag_sdna(prop, NULL, "mode"); - RNA_def_property_enum_items(prop, prop_mouse_type_items); - RNA_def_property_ui_text(prop, "M/P", "Toggle collision on material or property"); - RNA_def_property_update(prop, NC_LOGIC, NULL); - - prop = RNA_def_property(srna, "property", PROP_STRING, PROP_NONE); - RNA_def_property_string_sdna(prop, NULL, "propname"); - RNA_def_property_ui_text(prop, "Property", "Only look for objects with this property (blank = all objects)"); - RNA_def_property_update(prop, NC_LOGIC, NULL); - - prop = RNA_def_property(srna, "material", PROP_STRING, PROP_NONE); - RNA_def_property_string_sdna(prop, NULL, "matname"); - RNA_def_property_ui_text(prop, "Material", "Only look for objects with this material (blank = all objects)"); - RNA_def_property_update(prop, NC_LOGIC, NULL); - - prop = RNA_def_property(srna, "use_x_ray", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", SENS_RAY_XRAY); - RNA_def_property_ui_text(prop, "X-Ray", "Toggle X-Ray option (see through objects that don't have the property)"); - RNA_def_property_update(prop, NC_LOGIC, NULL); -} - -static void rna_def_keyboard_sensor(BlenderRNA *brna) -{ - StructRNA *srna; - PropertyRNA *prop; - - srna = RNA_def_struct(brna, "KeyboardSensor", "Sensor"); - RNA_def_struct_ui_text(srna, "Keyboard Sensor", "Sensor to detect keyboard events"); - RNA_def_struct_sdna_from(srna, "bKeyboardSensor", "data"); - - prop = RNA_def_property(srna, "key", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_sdna(prop, NULL, "key"); - RNA_def_property_enum_items(prop, rna_enum_event_type_items); - RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_UI_EVENTS); - RNA_def_property_enum_funcs(prop, NULL, "rna_Sensor_keyboard_key_set", NULL); - RNA_def_property_ui_text(prop, "Key", ""); - RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_WINDOWMANAGER); - RNA_def_property_update(prop, NC_LOGIC, NULL); - - prop = RNA_def_property(srna, "modifier_key_1", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_sdna(prop, NULL, "qual"); - RNA_def_property_enum_items(prop, rna_enum_event_type_items); - RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_UI_EVENTS); - RNA_def_property_enum_funcs(prop, NULL, "rna_Sensor_keyboard_modifier_set", NULL); - RNA_def_property_ui_text(prop, "Modifier Key", "Modifier key code"); - RNA_def_property_update(prop, NC_LOGIC, NULL); - - prop = RNA_def_property(srna, "modifier_key_2", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_sdna(prop, NULL, "qual2"); - RNA_def_property_enum_items(prop, rna_enum_event_type_items); - RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_UI_EVENTS); - RNA_def_property_enum_funcs(prop, NULL, "rna_Sensor_keyboard_modifier2_set", NULL); - RNA_def_property_ui_text(prop, "Second Modifier Key", "Modifier key code"); - RNA_def_property_update(prop, NC_LOGIC, NULL); - - prop = RNA_def_property(srna, "target", PROP_STRING, PROP_NONE); - RNA_def_property_string_sdna(prop, NULL, "targetName"); - RNA_def_property_ui_text(prop, "Target", "Property that receives the keystrokes in case a string is logged"); - RNA_def_property_update(prop, NC_LOGIC, NULL); - - prop = RNA_def_property(srna, "log", PROP_STRING, PROP_NONE); - RNA_def_property_string_sdna(prop, NULL, "toggleName"); - RNA_def_property_ui_text(prop, "Log Toggle", "Property that indicates whether to log keystrokes as a string"); - RNA_def_property_update(prop, NC_LOGIC, NULL); - - prop = RNA_def_property(srna, "use_all_keys", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "type", 1); - RNA_def_property_ui_text(prop, "All Keys", "Trigger this sensor on any keystroke"); - RNA_def_property_update(prop, NC_LOGIC, NULL); -} - -static void rna_def_property_sensor(BlenderRNA *brna) -{ - StructRNA *srna; - PropertyRNA *prop; - static const EnumPropertyItem prop_type_items[] = { - {SENS_PROP_EQUAL, "PROPEQUAL", 0, "Equal", ""}, - {SENS_PROP_NEQUAL, "PROPNEQUAL", 0, "Not Equal", ""}, - {SENS_PROP_INTERVAL, "PROPINTERVAL", 0, "Interval", ""}, - {SENS_PROP_CHANGED, "PROPCHANGED", 0, "Changed", ""}, - /* {SENS_PROP_EXPRESSION, "PROPEXPRESSION", 0, "Expression", ""}, NOT_USED_IN_UI */ - {SENS_PROP_LESSTHAN, "PROPLESSTHAN", 0, "Less Than", ""}, - {SENS_PROP_GREATERTHAN, "PROPGREATERTHAN", 0, "Greater Than", ""}, - {0, NULL, 0, NULL, NULL} - }; - - srna = RNA_def_struct(brna, "PropertySensor", "Sensor"); - RNA_def_struct_ui_text(srna, "Property Sensor", "Sensor to detect values and changes in values of properties"); - RNA_def_struct_sdna_from(srna, "bPropertySensor", "data"); - - prop = RNA_def_property(srna, "evaluation_type", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_sdna(prop, NULL, "type"); - RNA_def_property_enum_items(prop, prop_type_items); - RNA_def_property_ui_text(prop, "Evaluation Type", "Type of property evaluation"); - RNA_def_property_update(prop, NC_LOGIC, NULL); - - prop = RNA_def_property(srna, "property", PROP_STRING, PROP_NONE); - RNA_def_property_string_sdna(prop, NULL, "name"); - RNA_def_property_ui_text(prop, "Property", ""); - RNA_def_property_update(prop, NC_LOGIC, NULL); - - prop = RNA_def_property(srna, "value", PROP_STRING, PROP_NONE); - RNA_def_property_string_sdna(prop, NULL, "value"); - RNA_def_property_ui_text(prop, "Value", "Check for this value in types in Equal, Not Equal, Less Than and Greater Than types"); - RNA_def_property_update(prop, NC_LOGIC, NULL); - - prop = RNA_def_property(srna, "value_min", PROP_STRING, PROP_NONE); - RNA_def_property_string_sdna(prop, NULL, "value"); - RNA_def_property_ui_text(prop, "Minimum Value", "Minimum value in Interval type"); - RNA_def_property_update(prop, NC_LOGIC, NULL); - - prop = RNA_def_property(srna, "value_max", PROP_STRING, PROP_NONE); - RNA_def_property_string_sdna(prop, NULL, "maxvalue"); - RNA_def_property_ui_text(prop, "Maximum Value", "Maximum value in Interval type"); - RNA_def_property_update(prop, NC_LOGIC, NULL); -} - -static void rna_def_armature_sensor(BlenderRNA *brna) -{ - StructRNA *srna; - PropertyRNA *prop; - static const EnumPropertyItem prop_type_items[] = { - {SENS_ARM_STATE_CHANGED, "STATECHG", 0, "State Changed", ""}, - {SENS_ARM_LIN_ERROR_BELOW, "LINERRORBELOW", 0, "Lin error below", ""}, - {SENS_ARM_LIN_ERROR_ABOVE, "LINERRORABOVE", 0, "Lin error above", ""}, - {SENS_ARM_ROT_ERROR_BELOW, "ROTERRORBELOW", 0, "Rot error below", ""}, - {SENS_ARM_ROT_ERROR_ABOVE, "ROTERRORABOVE", 0, "Rot error above", ""}, - {0, NULL, 0, NULL, NULL} - }; - - srna = RNA_def_struct(brna, "ArmatureSensor", "Sensor"); - RNA_def_struct_ui_text(srna, "Armature Sensor", "Sensor to detect values and changes in values of IK solver"); - RNA_def_struct_sdna_from(srna, "bArmatureSensor", "data"); - - prop = RNA_def_property(srna, "test_type", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_sdna(prop, NULL, "type"); - RNA_def_property_enum_items(prop, prop_type_items); - RNA_def_property_ui_text(prop, "Test", "Type of value and test"); - RNA_def_property_update(prop, NC_LOGIC, NULL); - - prop = RNA_def_property(srna, "bone", PROP_STRING, PROP_NONE); - RNA_def_property_string_sdna(prop, NULL, "posechannel"); - RNA_def_property_ui_text(prop, "Bone Name", "Identify the bone to check value from"); - RNA_def_property_update(prop, NC_LOGIC, "rna_Sensor_Armature_update"); - - prop = RNA_def_property(srna, "constraint", PROP_STRING, PROP_NONE); - RNA_def_property_string_sdna(prop, NULL, "constraint"); - RNA_def_property_ui_text(prop, "Constraint Name", "Identify the bone constraint to check value from"); - RNA_def_property_update(prop, NC_LOGIC, "rna_Sensor_Armature_update"); - - prop = RNA_def_property(srna, "value", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "value"); - RNA_def_property_ui_text(prop, "Compare Value", "Value to be used in comparison"); - RNA_def_property_update(prop, NC_LOGIC, NULL); -} - -static void rna_def_actuator_sensor(BlenderRNA *brna) -{ - StructRNA *srna; - PropertyRNA *prop; - - srna = RNA_def_struct(brna, "ActuatorSensor", "Sensor"); - RNA_def_struct_ui_text(srna, "Actuator Sensor", "Sensor to detect state modifications of actuators"); - RNA_def_struct_sdna_from(srna, "bActuatorSensor", "data"); - - /* XXX if eventually have Logics using RNA 100%, we could use the actuator data-block isntead of its name */ - prop = RNA_def_property(srna, "actuator", PROP_STRING, PROP_NONE); - RNA_def_property_string_sdna(prop, NULL, "name"); - RNA_def_property_ui_text(prop, "Actuator", "Actuator name, actuator active state modifications will be detected"); - RNA_def_property_update(prop, NC_LOGIC, NULL); -} - -static void rna_def_delay_sensor(BlenderRNA *brna) -{ - StructRNA *srna; - PropertyRNA *prop; - - srna = RNA_def_struct(brna, "DelaySensor", "Sensor"); - RNA_def_struct_ui_text(srna, "Delay Sensor", "Sensor to send delayed events"); - RNA_def_struct_sdna_from(srna, "bDelaySensor", "data"); - - prop = RNA_def_property(srna, "delay", PROP_INT, PROP_NONE); - RNA_def_property_ui_text(prop, "Delay", - "Delay in number of logic tics before the positive trigger (default 60 per second)"); - RNA_def_property_range(prop, 0, 5000); - RNA_def_property_update(prop, NC_LOGIC, NULL); - - prop = RNA_def_property(srna, "duration", PROP_INT, PROP_NONE); - RNA_def_property_ui_text(prop, "Duration", - "If >0, delay in number of logic tics before the negative trigger following " - "the positive trigger"); - RNA_def_property_range(prop, 0, 5000); - RNA_def_property_update(prop, NC_LOGIC, NULL); - - prop = RNA_def_property(srna, "use_repeat", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", SENS_DELAY_REPEAT); - RNA_def_property_ui_text(prop, "Repeat", - "Toggle repeat option (if selected, the sensor restarts after Delay+Duration " - "logic tics)"); - RNA_def_property_update(prop, NC_LOGIC, NULL); -} - -static void rna_def_collision_sensor(BlenderRNA *brna) -{ - StructRNA *srna; - PropertyRNA *prop; - - srna = RNA_def_struct(brna, "CollisionSensor", "Sensor"); - RNA_def_struct_ui_text(srna, "Collision Sensor", - "Sensor to detect objects colliding with the current object, with more settings than " - "the Touch sensor"); - RNA_def_struct_sdna_from(srna, "bCollisionSensor", "data"); - - prop = RNA_def_property(srna, "use_pulse", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "mode", SENS_COLLISION_PULSE); - RNA_def_property_ui_text(prop, "Pulse", "Change to the set of colliding objects generates pulse"); - RNA_def_property_update(prop, NC_LOGIC, NULL); - - prop = RNA_def_property(srna, "use_material", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "mode", SENS_COLLISION_MATERIAL); - RNA_def_property_ui_text(prop, "M/P", "Toggle collision on material or property"); - RNA_def_property_update(prop, NC_LOGIC, NULL); - - prop = RNA_def_property(srna, "property", PROP_STRING, PROP_NONE); - RNA_def_property_string_sdna(prop, NULL, "name"); - RNA_def_property_ui_text(prop, "Property", "Only look for objects with this property (blank = all objects)"); - RNA_def_property_update(prop, NC_LOGIC, NULL); - - /*XXX to make a setFunction to create a lookup with all materials in Blend File (not only this object mat.) */ - prop = RNA_def_property(srna, "material", PROP_STRING, PROP_NONE); - RNA_def_property_string_sdna(prop, NULL, "materialName"); - RNA_def_property_ui_text(prop, "Material", "Only look for objects with this material (blank = all objects)"); - RNA_def_property_update(prop, NC_LOGIC, NULL); - -#if 0 - /* XXX either use a data-block look up to store the string name (material) - * or to do a doversion and use a material pointer. */ - prop = RNA_def_property(srna, "material", PROP_POINTER, PROP_NONE); - RNA_def_property_struct_type(prop, "Material"); - RNA_def_property_flag(prop, PROP_EDITABLE); - RNA_def_property_pointer_sdna(prop, NULL, "ma"); - RNA_def_property_ui_text(prop, "Material", "Only look for objects with this material (blank = all objects)"); -#endif -} - -static void rna_def_radar_sensor(BlenderRNA *brna) -{ - StructRNA *srna; - PropertyRNA *prop; - static const EnumPropertyItem axis_items[] = { - {SENS_RADAR_X_AXIS, "XAXIS", 0, "+X axis", ""}, - {SENS_RADAR_Y_AXIS, "YAXIS", 0, "+Y axis", ""}, - {SENS_RADAR_Z_AXIS, "ZAXIS", 0, "+Z axis", ""}, - {SENS_RADAR_NEG_X_AXIS, "NEGXAXIS", 0, "-X axis", ""}, - {SENS_RADAR_NEG_Y_AXIS, "NEGYAXIS", 0, "-Y axis", ""}, - {SENS_RADAR_NEG_Z_AXIS, "NEGZAXIS", 0, "-Z axis", ""}, - {0, NULL, 0, NULL, NULL} - }; - - srna = RNA_def_struct(brna, "RadarSensor", "Sensor"); - RNA_def_struct_ui_text(srna, "Radar Sensor", - "Sensor to detect objects in a cone shaped radar emanating from the current object"); - RNA_def_struct_sdna_from(srna, "bRadarSensor", "data"); - - prop = RNA_def_property(srna, "property", PROP_STRING, PROP_NONE); - RNA_def_property_string_sdna(prop, NULL, "name"); - RNA_def_property_ui_text(prop, "Property", "Only look for objects with this property (blank = all objects)"); - RNA_def_property_update(prop, NC_LOGIC, NULL); - - prop = RNA_def_property(srna, "axis", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_items(prop, axis_items); - RNA_def_property_ui_text(prop, "Axis", "Along which axis the radar cone is cast"); - RNA_def_property_update(prop, NC_LOGIC, NULL); - - prop = RNA_def_property(srna, "angle", PROP_FLOAT, PROP_ANGLE); - RNA_def_property_range(prop, 0.0, DEG2RADF(179.9f)); - RNA_def_property_ui_text(prop, "Angle", "Opening angle of the radar cone"); - RNA_def_property_update(prop, NC_LOGIC, NULL); - - prop = RNA_def_property(srna, "distance", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "range"); - RNA_def_property_range(prop, 0.0, 10000.0); - RNA_def_property_ui_text(prop, "Distance", "Depth of the radar cone"); - RNA_def_property_update(prop, NC_LOGIC, NULL); -} - -static void rna_def_random_sensor(BlenderRNA *brna) -{ - StructRNA *srna; - PropertyRNA *prop; - - srna = RNA_def_struct(brna, "RandomSensor", "Sensor"); - RNA_def_struct_ui_text(srna, "Random Sensor", "Sensor to send random events"); - RNA_def_struct_sdna_from(srna, "bRandomSensor", "data"); - - prop = RNA_def_property(srna, "seed", PROP_INT, PROP_NONE); - RNA_def_property_range(prop, 0, 1000); - RNA_def_property_ui_text(prop, "Seed", "Initial seed of the generator (choose 0 for not random)"); - RNA_def_property_update(prop, NC_LOGIC, NULL); -} - -static void rna_def_ray_sensor(BlenderRNA *brna) -{ - StructRNA *srna; - PropertyRNA *prop; - static const EnumPropertyItem axis_items[] = { - {SENS_RAY_X_AXIS, "XAXIS", 0, "+X axis", ""}, - {SENS_RAY_Y_AXIS, "YAXIS", 0, "+Y axis", ""}, - {SENS_RAY_Z_AXIS, "ZAXIS", 0, "+Z axis", ""}, - {SENS_RAY_NEG_X_AXIS, "NEGXAXIS", 0, "-X axis", ""}, - {SENS_RAY_NEG_Y_AXIS, "NEGYAXIS", 0, "-Y axis", ""}, - {SENS_RAY_NEG_Z_AXIS, "NEGZAXIS", 0, "-Z axis", ""}, - {0, NULL, 0, NULL, NULL} - }; - - static const EnumPropertyItem prop_ray_type_items[] = { - {SENS_COLLISION_PROPERTY, "PROPERTY", ICON_LOGIC, "Property", "Use a property for ray intersections"}, - {SENS_COLLISION_MATERIAL, "MATERIAL", ICON_MATERIAL_DATA, "Material", "Use a material for ray intersections"}, - {0, NULL, 0, NULL, NULL} - }; - - srna = RNA_def_struct(brna, "RaySensor", "Sensor"); - RNA_def_struct_ui_text(srna, "Ray Sensor", - "Sensor to detect intersections with a ray emanating from the current object"); - RNA_def_struct_sdna_from(srna, "bRaySensor", "data"); - - prop = RNA_def_property(srna, "ray_type", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_bitflag_sdna(prop, NULL, "mode"); - RNA_def_property_enum_items(prop, prop_ray_type_items); - RNA_def_property_ui_text(prop, "Ray Type", "Toggle collision on material or property"); - RNA_def_property_update(prop, NC_LOGIC, NULL); - - prop = RNA_def_property(srna, "property", PROP_STRING, PROP_NONE); - RNA_def_property_string_sdna(prop, NULL, "propname"); - RNA_def_property_ui_text(prop, "Property", "Only look for objects with this property (blank = all objects)"); - RNA_def_property_update(prop, NC_LOGIC, NULL); - - prop = RNA_def_property(srna, "material", PROP_STRING, PROP_NONE); - RNA_def_property_string_sdna(prop, NULL, "matname"); - RNA_def_property_ui_text(prop, "Material", "Only look for objects with this material (blank = all objects)"); - RNA_def_property_update(prop, NC_LOGIC, NULL); - -#if 0 - /* XXX either use a data-block look up to store the string name (material) - * or to do a doversion and use a material pointer. */ - prop = RNA_def_property(srna, "material", PROP_POINTER, PROP_NONE); - RNA_def_property_struct_type(prop, "Material"); - RNA_def_property_flag(prop, PROP_EDITABLE); - RNA_def_property_pointer_sdna(prop, NULL, "ma"); - RNA_def_property_ui_text(prop, "Material", "Only look for objects with this material (blank = all objects)"); -#endif - - prop = RNA_def_property(srna, "use_x_ray", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "mode", SENS_RAY_XRAY); - RNA_def_property_ui_text(prop, "X-Ray Mode", - "Toggle X-Ray option (see through objects that don't have the property)"); - RNA_def_property_update(prop, NC_LOGIC, NULL); - - prop = RNA_def_property(srna, "range", PROP_FLOAT, PROP_NONE); - RNA_def_property_range(prop, 0.01, 10000.0); - RNA_def_property_ui_text(prop, "Range", "Sense objects no farther than this distance"); - RNA_def_property_update(prop, NC_LOGIC, NULL); - - prop = RNA_def_property(srna, "axis", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_sdna(prop, NULL, "axisflag"); - RNA_def_property_enum_items(prop, axis_items); - RNA_def_property_ui_text(prop, "Axis", "Along which axis the ray is cast"); - RNA_def_property_update(prop, NC_LOGIC, NULL); -} - -static void rna_def_message_sensor(BlenderRNA *brna) -{ - StructRNA *srna; - PropertyRNA *prop; - - srna = RNA_def_struct(brna, "MessageSensor", "Sensor"); - RNA_def_struct_ui_text(srna, "Message Sensor", "Sensor to detect incoming messages"); - RNA_def_struct_sdna_from(srna, "bMessageSensor", "data"); - - prop = RNA_def_property(srna, "subject", PROP_STRING, PROP_NONE); - RNA_def_property_ui_text(prop, "Subject", - "Optional subject filter: only accept messages with this subject, " - "or empty to accept all"); - RNA_def_property_update(prop, NC_LOGIC, NULL); -} - -static void rna_def_joystick_sensor(BlenderRNA *brna) -{ - StructRNA *srna; - PropertyRNA *prop; - - static const EnumPropertyItem event_type_joystick_items[] = { - {SENS_JOY_BUTTON, "BUTTON", 0, "Button", ""}, - {SENS_JOY_AXIS, "AXIS", 0, "Axis", ""}, - {SENS_JOY_HAT, "HAT", 0, "Hat", ""}, - {SENS_JOY_AXIS_SINGLE, "AXIS_SINGLE", 0, "Single Axis", ""}, - {0, NULL, 0, NULL, NULL} - }; - - static const EnumPropertyItem axis_direction_items[] = { - {SENS_JOY_X_AXIS, "RIGHTAXIS", 0, "Right Axis", ""}, - {SENS_JOY_Y_AXIS, "UPAXIS", 0, "Up Axis", ""}, - {SENS_JOY_NEG_X_AXIS, "LEFTAXIS", 0, "Left Axis", ""}, - {SENS_JOY_NEG_Y_AXIS, "DOWNAXIS", 0, "Down Axis", ""}, - {0, NULL, 0, NULL, NULL} - }; - - static const EnumPropertyItem hat_direction_items[] = { - {SENS_JOY_HAT_UP, "UP", 0, "Up", ""}, - {SENS_JOY_HAT_DOWN, "DOWN", 0, "Down", ""}, - {SENS_JOY_HAT_LEFT, "LEFT", 0, "Left", ""}, - {SENS_JOY_HAT_RIGHT, "RIGHT", 0, "Right", ""}, - - {SENS_JOY_HAT_UP_RIGHT, "UPRIGHT", 0, "Up/Right", ""}, - {SENS_JOY_HAT_DOWN_LEFT, "DOWNLEFT", 0, "Down/Left", ""}, - {SENS_JOY_HAT_UP_LEFT, "UPLEFT", 0, "Up/Left", ""}, - {SENS_JOY_HAT_DOWN_RIGHT, "DOWNRIGHT", 0, "Down/Right", ""}, - {0, NULL, 0, NULL, NULL} - }; - - srna = RNA_def_struct(brna, "JoystickSensor", "Sensor"); - RNA_def_struct_ui_text(srna, "Joystick Sensor", "Sensor to detect joystick events"); - RNA_def_struct_sdna_from(srna, "bJoystickSensor", "data"); - - prop = RNA_def_property(srna, "joystick_index", PROP_INT, PROP_NONE); - RNA_def_property_int_sdna(prop, NULL, "joyindex"); - RNA_def_property_ui_text(prop, "Index", "Which joystick to use"); - RNA_def_property_range(prop, 0, SENS_JOY_MAXINDEX - 1); - RNA_def_property_update(prop, NC_LOGIC, NULL); - - prop = RNA_def_property(srna, "event_type", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_sdna(prop, NULL, "type"); - RNA_def_property_enum_items(prop, event_type_joystick_items); - RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_UI_EVENTS); - RNA_def_property_ui_text(prop, "Event Type", "The type of event this joystick sensor is triggered on"); - RNA_def_property_update(prop, NC_LOGIC, NULL); - - prop = RNA_def_property(srna, "use_all_events", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", SENS_JOY_ANY_EVENT); - RNA_def_property_ui_text(prop, "All Events", - "Triggered by all events on this joystick's current type (axis/button/hat)"); - RNA_def_property_update(prop, NC_LOGIC, NULL); - - /* Button */ - prop = RNA_def_property(srna, "button_number", PROP_INT, PROP_NONE); - RNA_def_property_int_sdna(prop, NULL, "button"); - RNA_def_property_ui_text(prop, "Button Number", "Which button to use"); - RNA_def_property_range(prop, 0, 18); - RNA_def_property_update(prop, NC_LOGIC, NULL); - - /* Axis */ - prop = RNA_def_property(srna, "axis_number", PROP_INT, PROP_NONE); - RNA_def_property_int_sdna(prop, NULL, "axis"); - RNA_def_property_ui_text(prop, "Axis Number", "Which axis pair to use, 1 is usually the main direction input"); - RNA_def_property_range(prop, 1, 8); - RNA_def_property_update(prop, NC_LOGIC, NULL); - - prop = RNA_def_property(srna, "axis_threshold", PROP_INT, PROP_NONE); - RNA_def_property_int_sdna(prop, NULL, "precision"); - RNA_def_property_ui_text(prop, "Axis Threshold", "Precision of the axis"); - RNA_def_property_range(prop, 0, 32768); - RNA_def_property_update(prop, NC_LOGIC, NULL); - - prop = RNA_def_property(srna, "axis_direction", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_sdna(prop, NULL, "axisf"); - RNA_def_property_enum_items(prop, axis_direction_items); - RNA_def_property_ui_text(prop, "Axis Direction", "The direction of the axis"); - RNA_def_property_update(prop, NC_LOGIC, NULL); - - /* Single Axis */ - prop = RNA_def_property(srna, "single_axis_number", PROP_INT, PROP_NONE); - RNA_def_property_int_sdna(prop, NULL, "axis_single"); - RNA_def_property_ui_text(prop, "Axis Number", "Single axis (vertical/horizontal/other) to detect"); - RNA_def_property_range(prop, 1, 16); - RNA_def_property_update(prop, NC_LOGIC, NULL); - - /* Hat */ - prop = RNA_def_property(srna, "hat_number", PROP_INT, PROP_NONE); - RNA_def_property_int_sdna(prop, NULL, "hat"); - RNA_def_property_ui_text(prop, "Hat Number", "Which hat to use"); - RNA_def_property_range(prop, 1, 2); - RNA_def_property_update(prop, NC_LOGIC, NULL); - - prop = RNA_def_property(srna, "hat_direction", PROP_ENUM, PROP_NONE); - RNA_def_property_enum_sdna(prop, NULL, "hatf"); - RNA_def_property_enum_items(prop, hat_direction_items); - RNA_def_property_ui_text(prop, "Hat Direction", "Hat direction"); - RNA_def_property_update(prop, NC_LOGIC, NULL); -} - -void RNA_def_sensor(BlenderRNA *brna) -{ - rna_def_sensor(brna); - - rna_def_always_sensor(brna); - rna_def_near_sensor(brna); - rna_def_mouse_sensor(brna); - rna_def_keyboard_sensor(brna); - rna_def_property_sensor(brna); - rna_def_armature_sensor(brna); - rna_def_actuator_sensor(brna); - rna_def_delay_sensor(brna); - rna_def_collision_sensor(brna); - rna_def_radar_sensor(brna); - rna_def_random_sensor(brna); - rna_def_ray_sensor(brna); - rna_def_message_sensor(brna); - rna_def_joystick_sensor(brna); -} - -#endif diff --git a/source/blender/render/intern/source/voxeldata.c b/source/blender/render/intern/source/voxeldata.c deleted file mode 100644 index 2daa4123536..00000000000 --- a/source/blender/render/intern/source/voxeldata.c +++ /dev/null @@ -1,571 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. - * All rights reserved. - * - * The Original Code is: all of this file. - * - * Contributor(s): Raul Fernandez Hernandez (Farsthary), Matt Ebb. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/render/intern/source/voxeldata.c - * \ingroup render - */ - - -#include <math.h> -#include <stdlib.h> -#include <stdio.h> - -#ifdef WIN32 -#include "BLI_winstuff.h" -#endif - -#include "MEM_guardedalloc.h" - -#include "BLI_math.h" -#include "BLI_blenlib.h" -#include "BLI_threads.h" -#include "BLI_voxel.h" -#include "BLI_utildefines.h" - -#include "BLT_translation.h" - -#include "IMB_imbuf.h" -#include "IMB_imbuf_types.h" - -#include "BKE_cloth.h" -#include "BKE_global.h" -#include "BKE_image.h" -#include "BKE_main.h" -#include "BKE_modifier.h" - -#include "smoke_API.h" -#include "BPH_mass_spring.h" - -#include "DNA_texture_types.h" -#include "DNA_object_force_types.h" -#include "DNA_object_types.h" -#include "DNA_particle_types.h" -#include "DNA_modifier_types.h" -#include "DNA_smoke_types.h" - - -#include "render_types.h" -#include "texture.h" -#include "voxeldata.h" - -static bool is_vd_res_ok(VoxelData *vd) -{ - /* arbitrary large value so corrupt headers don't break */ - const int min = 1, max = 100000; - return (vd->resol[0] >= min && vd->resol[0] <= max) && - (vd->resol[1] >= min && vd->resol[1] <= max) && - (vd->resol[2] >= min && vd->resol[2] <= max); -} - -/* use size_t because the result may exceed INT_MAX */ -static size_t vd_resol_size(VoxelData *vd) -{ - return (size_t)vd->resol[0] * (size_t)vd->resol[1] * (size_t)vd->resol[2]; -} - -static int load_frame_blendervoxel(VoxelData *vd, FILE *fp, int frame) -{ - const size_t size = vd_resol_size(vd); - size_t offset = sizeof(VoxelDataHeader); - - if (is_vd_res_ok(vd) == false) - return 0; - - vd->dataset = MEM_mapallocN(sizeof(float) * size, "voxel dataset"); - if (vd->dataset == NULL) return 0; - - if (fseek(fp, frame * size * sizeof(float) + offset, 0) == -1) - return 0; - if (fread(vd->dataset, sizeof(float), size, fp) != size) - return 0; - - vd->cachedframe = frame; - vd->ok = 1; - return 1; -} - -static int load_frame_raw8(VoxelData *vd, FILE *fp, int frame) -{ - const size_t size = vd_resol_size(vd); - size_t i; - char *data_c; - - if (is_vd_res_ok(vd) == false) - return 0; - - vd->dataset = MEM_mapallocN(sizeof(float) * size, "voxel dataset"); - if (vd->dataset == NULL) return 0; - data_c = (char *)MEM_mallocN(sizeof(char) * size, "temporary voxel file reading storage"); - if (data_c == NULL) { - MEM_freeN(vd->dataset); - vd->dataset = NULL; - return 0; - } - - if (fseek(fp, (frame - 1) * size * sizeof(char), 0) == -1) { - MEM_freeN(data_c); - MEM_freeN(vd->dataset); - vd->dataset = NULL; - return 0; - } - if (fread(data_c, sizeof(char), size, fp) != size) { - MEM_freeN(data_c); - MEM_freeN(vd->dataset); - vd->dataset = NULL; - return 0; - } - - for (i = 0; i < size; i++) { - vd->dataset[i] = (float)data_c[i] / 255.f; - } - MEM_freeN(data_c); - - vd->cachedframe = frame; - vd->ok = 1; - return 1; -} - -static void load_frame_image_sequence(VoxelData *vd, Tex *tex) -{ - ImBuf *ibuf; - Image *ima = tex->ima; - ImageUser *tiuser = &tex->iuser; - ImageUser iuser = *(tiuser); - int x = 0, y = 0, z = 0; - const float *rf; - - if (!ima) return; - if (iuser.frames == 0) return; - - ima->source = IMA_SRC_SEQUENCE; - iuser.framenr = 1 + iuser.offset; - - /* find the first valid ibuf and use it to initialize the resolution of the data set */ - /* need to do this in advance so we know how much memory to allocate */ - ibuf = BKE_image_acquire_ibuf(ima, &iuser, NULL); - while (!ibuf && (iuser.framenr < iuser.frames)) { - iuser.framenr++; - ibuf = BKE_image_acquire_ibuf(ima, &iuser, NULL); - } - if (!ibuf) return; - if (!ibuf->rect_float) IMB_float_from_rect(ibuf); - - vd->flag |= TEX_VD_STILL; - vd->resol[0] = ibuf->x; - vd->resol[1] = ibuf->y; - vd->resol[2] = iuser.frames; - vd->dataset = MEM_mapallocN(sizeof(float) * vd_resol_size(vd), "voxel dataset"); - - for (z = 0; z < iuser.frames; z++) { - /* get a new ibuf for each frame */ - if (z > 0) { - iuser.framenr++; - BKE_image_release_ibuf(ima, ibuf, NULL); - ibuf = BKE_image_acquire_ibuf(ima, &iuser, NULL); - if (!ibuf) break; - if (!ibuf->rect_float) IMB_float_from_rect(ibuf); - } - rf = ibuf->rect_float; - - for (y = 0; y < ibuf->y; y++) { - for (x = 0; x < ibuf->x; x++) { - /* currently averaged to monchrome */ - vd->dataset[BLI_VOXEL_INDEX(x, y, z, vd->resol)] = (rf[0] + rf[1] + rf[2]) / 3.0f; - rf += 4; - } - } - - BKE_image_free_anim_ibufs(ima, iuser.framenr); - } - - BKE_image_release_ibuf(ima, ibuf, NULL); - - vd->ok = 1; - return; -} - -static int read_voxeldata_header(FILE *fp, struct VoxelData *vd) -{ - VoxelDataHeader *h = (VoxelDataHeader *)MEM_mallocN(sizeof(VoxelDataHeader), "voxel data header"); - - rewind(fp); - if (fread(h, sizeof(VoxelDataHeader), 1, fp) != 1) { - MEM_freeN(h); - return 0; - } - - vd->resol[0] = h->resolX; - vd->resol[1] = h->resolY; - vd->resol[2] = h->resolZ; - - MEM_freeN(h); - return 1; -} - -static void init_frame_smoke(VoxelData *vd, int cfra) -{ -#ifdef WITH_SMOKE - Object *ob; - ModifierData *md; - - vd->dataset = NULL; - if (vd->object == NULL) return; - ob = vd->object; - - /* draw code for smoke */ - if ((md = (ModifierData *)modifiers_findByType(ob, eModifierType_Smoke))) { - SmokeModifierData *smd = (SmokeModifierData *)md; - SmokeDomainSettings *sds = smd->domain; - - if (sds && sds->fluid) { - BLI_rw_mutex_lock(sds->fluid_mutex, THREAD_LOCK_READ); - - if (!sds->fluid) { - BLI_rw_mutex_unlock(sds->fluid_mutex); - return; - } - - if (cfra < sds->point_cache[0]->startframe) - ; /* don't show smoke before simulation starts, this could be made an option in the future */ - else if (vd->smoked_type == TEX_VD_SMOKEHEAT) { - size_t totRes; - size_t i; - float *heat; - - if (!smoke_has_heat(sds->fluid)) { - BLI_rw_mutex_unlock(sds->fluid_mutex); - return; - } - - copy_v3_v3_int(vd->resol, sds->res); - totRes = vd_resol_size(vd); - vd->dataset = MEM_mapallocN(sizeof(float) * (totRes), "smoke data"); - /* get heat data */ - heat = smoke_get_heat(sds->fluid); - - /* scale heat values from -2.0-2.0 to 0.0-1.0 */ - for (i = 0; i < totRes; i++) { - vd->dataset[i] = (heat[i] + 2.0f) / 4.0f; - } - } - else if (vd->smoked_type == TEX_VD_SMOKEVEL) { - size_t totRes; - size_t i; - float *xvel, *yvel, *zvel; - - copy_v3_v3_int(vd->resol, sds->res); - totRes = vd_resol_size(vd); - vd->dataset = MEM_mapallocN(sizeof(float) * (totRes), "smoke data"); - /* get velocity data */ - xvel = smoke_get_velocity_x(sds->fluid); - yvel = smoke_get_velocity_y(sds->fluid); - zvel = smoke_get_velocity_z(sds->fluid); - - /* map velocities between 0 and 0.3f */ - for (i = 0; i < totRes; i++) { - vd->dataset[i] = sqrtf(xvel[i] * xvel[i] + yvel[i] * yvel[i] + zvel[i] * zvel[i]) * 3.0f; - } - - } - else if (vd->smoked_type == TEX_VD_SMOKEFLAME) { - size_t totRes; - float *flame; - - if (sds->flags & MOD_SMOKE_HIGHRES) { - if (!smoke_turbulence_has_fuel(sds->wt)) { - BLI_rw_mutex_unlock(sds->fluid_mutex); - return; - } - smoke_turbulence_get_res(sds->wt, vd->resol); - flame = smoke_turbulence_get_flame(sds->wt); - } - else { - if (!smoke_has_fuel(sds->fluid)) { - BLI_rw_mutex_unlock(sds->fluid_mutex); - return; - } - copy_v3_v3_int(vd->resol, sds->res); - flame = smoke_get_flame(sds->fluid); - } - - /* always store copy, as smoke internal data can change */ - totRes = vd_resol_size(vd); - vd->dataset = MEM_mapallocN(sizeof(float)*(totRes), "smoke data"); - memcpy(vd->dataset, flame, sizeof(float)*totRes); - } - else { - size_t totCells; - int depth = 4; - vd->data_type = TEX_VD_RGBA_PREMUL; - - /* data resolution */ - if (sds->flags & MOD_SMOKE_HIGHRES) { - smoke_turbulence_get_res(sds->wt, vd->resol); - } - else { - copy_v3_v3_int(vd->resol, sds->res); - } - - /* TODO: is_vd_res_ok(rvd) doesnt check this resolution */ - totCells = vd_resol_size(vd) * depth; - /* always store copy, as smoke internal data can change */ - vd->dataset = MEM_mapallocN(sizeof(float) * totCells, "smoke data"); - - if (sds->flags & MOD_SMOKE_HIGHRES) { - if (smoke_turbulence_has_colors(sds->wt)) { - smoke_turbulence_get_rgba(sds->wt, vd->dataset, 1); - } - else { - smoke_turbulence_get_rgba_from_density(sds->wt, sds->active_color, vd->dataset, 1); - } - } - else { - if (smoke_has_colors(sds->fluid)) { - smoke_get_rgba(sds->fluid, vd->dataset, 1); - } - else { - smoke_get_rgba_from_density(sds->fluid, sds->active_color, vd->dataset, 1); - } - } - } /* end of fluid condition */ - - BLI_rw_mutex_unlock(sds->fluid_mutex); - } - } - - vd->ok = 1; - -#else // WITH_SMOKE - (void)vd; - (void)cfra; - - vd->dataset = NULL; -#endif -} - -static void init_frame_hair(VoxelData *vd, int UNUSED(cfra)) -{ - Object *ob; - ModifierData *md; - - vd->dataset = NULL; - if (vd->object == NULL) return; - ob = vd->object; - - if ((md = (ModifierData *)modifiers_findByType(ob, eModifierType_ParticleSystem))) { - ParticleSystemModifierData *pmd = (ParticleSystemModifierData *)md; - - if (pmd->psys && pmd->psys->clmd) { - vd->ok |= BPH_cloth_solver_get_texture_data(ob, pmd->psys->clmd, vd); - } - } -} - -void cache_voxeldata(Tex *tex, int scene_frame) -{ - VoxelData *vd = tex->vd; - FILE *fp; - int curframe; - char path[sizeof(vd->source_path)]; - - /* only re-cache if dataset needs updating */ - if ((vd->flag & TEX_VD_STILL) || (vd->cachedframe == scene_frame)) - if (vd->ok) return; - - /* clear out old cache, ready for new */ - if (vd->dataset) { - MEM_freeN(vd->dataset); - vd->dataset = NULL; - } - /* reset data_type */ - vd->data_type = TEX_VD_INTENSITY; - - if (vd->flag & TEX_VD_STILL) - curframe = vd->still_frame; - else - curframe = scene_frame; - - BLI_strncpy(path, vd->source_path, sizeof(path)); - - /* each type is responsible for setting to true */ - vd->ok = false; - - switch (vd->file_format) { - case TEX_VD_IMAGE_SEQUENCE: - load_frame_image_sequence(vd, tex); - return; - case TEX_VD_SMOKE: - init_frame_smoke(vd, scene_frame); - return; - case TEX_VD_HAIR: - init_frame_hair(vd, scene_frame); - return; - case TEX_VD_BLENDERVOXEL: - BLI_path_abs(path, BKE_main_blendfile_path_from_global()); - fp = BLI_fopen(path, "rb"); - if (!fp) return; - - if (read_voxeldata_header(fp, vd)) - load_frame_blendervoxel(vd, fp, curframe - 1); - - fclose(fp); - return; - case TEX_VD_RAW_8BIT: - BLI_path_abs(path, BKE_main_blendfile_path_from_global()); - fp = BLI_fopen(path, "rb"); - if (!fp) return; - - load_frame_raw8(vd, fp, curframe); - fclose(fp); - return; - } -} - -void make_voxeldata(struct Render *re) -{ - Tex *tex; - - re->i.infostr = IFACE_("Loading voxel datasets"); - re->stats_draw(re->sdh, &re->i); - - /* XXX: should be doing only textures used in this render */ - for (tex = re->main->tex.first; tex; tex = tex->id.next) { - if (tex->id.us && tex->type == TEX_VOXELDATA) { - cache_voxeldata(tex, re->r.cfra); - } - } - - re->i.infostr = NULL; - re->stats_draw(re->sdh, &re->i); - -} - -int voxeldatatex(struct Tex *tex, const float texvec[3], struct TexResult *texres) -{ - VoxelData *vd = tex->vd; - float co[3], offset[3] = {0.5, 0.5, 0.5}, a; - int retval = (vd->data_type == TEX_VD_RGBA_PREMUL) ? TEX_RGB : TEX_INT; - int depth = (vd->data_type == TEX_VD_RGBA_PREMUL) ? 4 : 1; - int ch; - - if (vd->dataset == NULL) { - texres->tin = 0.0f; - return 0; - } - - /* scale lookup from 0.0-1.0 (original location) to -1.0, 1.0, consistent with image texture tex coords */ - /* in implementation this works backwards, bringing sample locations from -1.0, 1.0 - * to the range 0.0, 1.0, before looking up in the voxel structure. */ - copy_v3_v3(co, texvec); - mul_v3_fl(co, 0.5f); - add_v3_v3(co, offset); - - /* co is now in the range 0.0, 1.0 */ - switch (vd->extend) { - case TEX_CLIP: - { - if ((co[0] < 0.f || co[0] > 1.f) || (co[1] < 0.f || co[1] > 1.f) || (co[2] < 0.f || co[2] > 1.f)) { - texres->tin = 0.f; - return retval; - } - break; - } - case TEX_REPEAT: - { - co[0] = co[0] - floorf(co[0]); - co[1] = co[1] - floorf(co[1]); - co[2] = co[2] - floorf(co[2]); - break; - } - case TEX_EXTEND: - { - CLAMP(co[0], 0.f, 1.f); - CLAMP(co[1], 0.f, 1.f); - CLAMP(co[2], 0.f, 1.f); - break; - } - } - - for (ch = 0; ch < depth; ch++) { - float *dataset = vd->dataset + ch*vd->resol[0]*vd->resol[1]*vd->resol[2]; - float *result = &texres->tin; - - if (vd->data_type == TEX_VD_RGBA_PREMUL) { - switch (ch) { - case 0: - result = &texres->tr; - break; - case 1: - result = &texres->tg; - break; - case 2: - result = &texres->tb; - break; - } - } - - switch (vd->interp_type) { - case TEX_VD_NEARESTNEIGHBOR: - *result = BLI_voxel_sample_nearest(dataset, vd->resol, co); - break; - case TEX_VD_LINEAR: - *result = BLI_voxel_sample_trilinear(dataset, vd->resol, co); - break; - case TEX_VD_QUADRATIC: - *result = BLI_voxel_sample_triquadratic(dataset, vd->resol, co); - break; - case TEX_VD_TRICUBIC_CATROM: - case TEX_VD_TRICUBIC_BSPLINE: - *result = BLI_voxel_sample_tricubic(dataset, vd->resol, co, (vd->interp_type == TEX_VD_TRICUBIC_BSPLINE)); - break; - } - } - - a = texres->tin; - texres->tin *= vd->int_multiplier; - BRICONT; - - if (vd->data_type == TEX_VD_RGBA_PREMUL) { - /* unmultiply */ - if (a>0.001f) { - texres->tr /= a; - texres->tg /= a; - texres->tb /= a; - } - texres->talpha = 1; - } - else { - texres->tr = texres->tin; - texres->tg = texres->tin; - texres->tb = texres->tin; - } - - texres->ta = texres->tin; - BRICONTRGB; - - return retval; -} |