diff options
author | Lukas Tönne <lukas.toenne@gmail.com> | 2016-04-16 19:10:37 +0300 |
---|---|---|
committer | Lukas Tönne <lukas.toenne@gmail.com> | 2016-04-16 19:10:37 +0300 |
commit | 07221e980b8b6899ccb0d145210c699b4fca175c (patch) | |
tree | 896f62da8ab9c5ddba4ff3cc4bc5f0be5e14dc51 /source/blender/editors/armature | |
parent | 892529029f08b4ca2e6c73a4e9299fb0b278f455 (diff) | |
parent | 5d6b695f00c839c34e4d9d9b371ca0a71ee46dbc (diff) |
Merge branch 'master' into strand_editmode
Diffstat (limited to 'source/blender/editors/armature')
-rw-r--r-- | source/blender/editors/armature/CMakeLists.txt | 8 | ||||
-rw-r--r-- | source/blender/editors/armature/SConscript | 57 | ||||
-rw-r--r-- | source/blender/editors/armature/armature_add.c | 67 | ||||
-rw-r--r-- | source/blender/editors/armature/armature_edit.c | 54 | ||||
-rw-r--r-- | source/blender/editors/armature/armature_intern.h | 2 | ||||
-rw-r--r-- | source/blender/editors/armature/armature_ops.c | 2 | ||||
-rw-r--r-- | source/blender/editors/armature/armature_select.c | 74 | ||||
-rw-r--r-- | source/blender/editors/armature/armature_skinning.c | 14 | ||||
-rw-r--r-- | source/blender/editors/armature/editarmature_retarget.c | 4 | ||||
-rw-r--r-- | source/blender/editors/armature/editarmature_sketch.c | 25 | ||||
-rw-r--r-- | source/blender/editors/armature/meshlaplacian.c | 477 | ||||
-rw-r--r-- | source/blender/editors/armature/meshlaplacian.h | 2 | ||||
-rw-r--r-- | source/blender/editors/armature/pose_edit.c | 59 | ||||
-rw-r--r-- | source/blender/editors/armature/pose_slide.c | 31 | ||||
-rw-r--r-- | source/blender/editors/armature/reeb.c | 54 |
15 files changed, 354 insertions, 576 deletions
diff --git a/source/blender/editors/armature/CMakeLists.txt b/source/blender/editors/armature/CMakeLists.txt index 1ed70b3cd98..b213aca478f 100644 --- a/source/blender/editors/armature/CMakeLists.txt +++ b/source/blender/editors/armature/CMakeLists.txt @@ -28,6 +28,7 @@ set(INC ../../makesrna ../../windowmanager ../../../../intern/guardedalloc + ../../../../intern/eigen ../../../../intern/glew-mx ) @@ -68,13 +69,6 @@ if(WITH_INTERNATIONAL) add_definitions(-DWITH_INTERNATIONAL) endif() -if(WITH_OPENNL) - add_definitions(-DWITH_OPENNL) - list(APPEND INC_SYS - ../../../../intern/opennl/extern - ) -endif() - add_definitions(${GL_DEFINITIONS}) blender_add_lib(bf_editor_armature "${SRC}" "${INC}" "${INC_SYS}") diff --git a/source/blender/editors/armature/SConscript b/source/blender/editors/armature/SConscript deleted file mode 100644 index 9c3959ecb5b..00000000000 --- a/source/blender/editors/armature/SConscript +++ /dev/null @@ -1,57 +0,0 @@ -#!/usr/bin/env python -# -# ***** 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) 2006, Blender Foundation -# All rights reserved. -# -# The Original Code is: all of this file. -# -# Contributor(s): Nathan Letwory. -# -# ***** END GPL LICENSE BLOCK ***** - -Import ('env') - -sources = env.Glob('*.c') - -incs = [ - '#/intern/guardedalloc', - env['BF_GLEW_INC'], - '#/intern/glew-mx', - '#/intern/opennl/extern', - '../include', - '../../blenkernel', - '../../blenlib', - '../../blentranslation', - '../../gpu', - '../../makesdna', - '../../makesrna', - '../../windowmanager', - ] -incs = ' '.join(incs) - -defs = [] -defs += env['BF_GL_DEFINITIONS'] - -if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc', 'win64-mingw'): - incs += ' ' + env['BF_PTHREADS_INC'] - -if env['WITH_BF_INTERNATIONAL']: - defs.append('WITH_INTERNATIONAL') - -env.BlenderLib ( 'bf_editors_armature', sources, Split(incs), defs, libtype=['core'], priority=[44] ) diff --git a/source/blender/editors/armature/armature_add.c b/source/blender/editors/armature/armature_add.c index 59453f0ac71..218f215a350 100644 --- a/source/blender/editors/armature/armature_add.c +++ b/source/blender/editors/armature/armature_add.c @@ -38,6 +38,7 @@ #include "BLI_blenlib.h" #include "BLI_math.h" +#include "BLI_ghash.h" #include "BKE_action.h" #include "BKE_constraint.h" @@ -287,6 +288,66 @@ void preEditBoneDuplicate(ListBase *editbones) ED_armature_ebone_listbase_temp_clear(editbones); } +/** + * Helper function for #postEditBoneDuplicate, + * return the destination pchan from the original. + * + * \param use_orig_fallback: return the input value if no new channel is found. + */ +static bPoseChannel *pchan_duplicate_map( + const bPose *pose, GHash *name_map, + bPoseChannel *pchan_src, bool use_orig_fallback) +{ + bPoseChannel *pchan_dst = NULL; + const char *name_src = pchan_src->name; + const char *name_dst = BLI_ghash_lookup(name_map, name_src); + if (name_dst) { + pchan_dst = BKE_pose_channel_find_name(pose, name_dst); + } + + if ((pchan_dst == NULL) && use_orig_fallback) { + pchan_dst = pchan_src; + } + + return pchan_dst; +} + +void postEditBoneDuplicate(struct ListBase *editbones, Object *ob) +{ + if (ob->pose == NULL) { + return; + } + + BKE_pose_channels_hash_free(ob->pose); + BKE_pose_channels_hash_make(ob->pose); + + GHash *name_map = BLI_ghash_str_new(__func__); + + for (EditBone *ebone_src = editbones->first; ebone_src; ebone_src = ebone_src->next) { + EditBone *ebone_dst = ebone_src->temp.ebone; + if (ebone_dst) { + BLI_ghash_insert(name_map, ebone_src->name, ebone_dst->name); + } + } + + for (EditBone *ebone_src = editbones->first; ebone_src; ebone_src = ebone_src->next) { + EditBone *ebone_dst = ebone_src->temp.ebone; + if (ebone_dst) { + bPoseChannel *pchan_src = BKE_pose_channel_find_name(ob->pose, ebone_src->name); + if (pchan_src) { + bPoseChannel *pchan_dst = BKE_pose_channel_find_name(ob->pose, ebone_dst->name); + if (pchan_dst) { + if (pchan_src->custom_tx) { + pchan_dst->custom_tx = pchan_duplicate_map(ob->pose, name_map, pchan_src->custom_tx, true); + } + } + } + } + } + + BLI_ghash_free(name_map, NULL, NULL); +} + /* * Note: When duplicating cross objects, editbones here is the list of bones * from the SOURCE object but ob is the DESTINATION object @@ -490,6 +551,8 @@ static int armature_duplicate_selected_exec(bContext *C, wmOperator *UNUSED(op)) } } + postEditBoneDuplicate(arm->edbo, obedit); + ED_armature_validate_active(arm); WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, obedit); @@ -687,6 +750,8 @@ static int armature_symmetrize_exec(bContext *C, wmOperator *op) arm->act_edbone = arm->act_edbone->temp.ebone; } + postEditBoneDuplicate(arm->edbo, obedit); + ED_armature_validate_active(arm); WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, obedit); @@ -697,7 +762,7 @@ static int armature_symmetrize_exec(bContext *C, wmOperator *op) /* following conventions from #MESH_OT_symmetrize */ void ARMATURE_OT_symmetrize(wmOperatorType *ot) { - /* subset of 'symmetrize_direction_items' */ + /* subset of 'rna_enum_symmetrize_direction_items' */ static EnumPropertyItem arm_symmetrize_direction_items[] = { {-1, "NEGATIVE_X", 0, "-X to +X", ""}, {+1, "POSITIVE_X", 0, "+X to -X", ""}, diff --git a/source/blender/editors/armature/armature_edit.c b/source/blender/editors/armature/armature_edit.c index 5a0e70dc5dd..b1c23fb4cac 100644 --- a/source/blender/editors/armature/armature_edit.c +++ b/source/blender/editors/armature/armature_edit.c @@ -156,7 +156,7 @@ void ED_armature_origin_set(Scene *scene, Object *ob, float cursor[3], int cente mul_m4_v3(ob->imat, cent); } else { - if (around == V3D_CENTROID) { + if (around == V3D_AROUND_CENTER_MEAN) { int total = 0; zero_v3(cent); for (ebone = arm->edbo->first; ebone; ebone = ebone->next) { @@ -459,6 +459,58 @@ void ARMATURE_OT_calculate_roll(wmOperatorType *ot) RNA_def_boolean(ot->srna, "axis_only", 0, "Shortest Rotation", "Ignore the axis direction, use the shortest rotation to align"); } +static int armature_roll_clear_exec(bContext *C, wmOperator *op) +{ + Object *ob = CTX_data_edit_object(C); + + bArmature *arm = ob->data; + EditBone *ebone; + + const float roll = RNA_float_get(op->ptr, "roll"); + + for (ebone = arm->edbo->first; ebone; ebone = ebone->next) { + if (EBONE_VISIBLE(arm, ebone) && EBONE_EDITABLE(ebone)) { + /* roll func is a callback which assumes that all is well */ + ebone->roll = roll; + } + } + + if (arm->flag & ARM_MIRROR_EDIT) { + for (ebone = arm->edbo->first; ebone; ebone = ebone->next) { + if ((EBONE_VISIBLE(arm, ebone) && EBONE_EDITABLE(ebone)) == 0) { + EditBone *ebone_mirr = ED_armature_bone_get_mirrored(arm->edbo, ebone); + if (ebone_mirr && (EBONE_VISIBLE(arm, ebone_mirr) && EBONE_EDITABLE(ebone_mirr))) { + ebone->roll = -ebone_mirr->roll; + } + } + } + } + + /* note, notifier might evolve */ + WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, ob); + + return OPERATOR_FINISHED; +} + +void ARMATURE_OT_roll_clear(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Clear Roll"; + ot->idname = "ARMATURE_OT_roll_clear"; + ot->description = "Clear roll for selected bones"; + + /* api callbacks */ + ot->exec = armature_roll_clear_exec; + ot->poll = ED_operator_editarmature; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + RNA_def_float_rotation( + ot->srna, "roll", 0, NULL, DEG2RADF(-360.0f), DEG2RADF(360.0f), + "Roll", "", DEG2RADF(-360.0f), DEG2RADF(360.0f)); +} + /* ******************************** Chain-Based Tools ********************************* */ /* temporary data-structure for merge/fill bones */ diff --git a/source/blender/editors/armature/armature_intern.h b/source/blender/editors/armature/armature_intern.h index 2968851f2eb..ac150b9af74 100644 --- a/source/blender/editors/armature/armature_intern.h +++ b/source/blender/editors/armature/armature_intern.h @@ -54,6 +54,7 @@ void ARMATURE_OT_bone_primitive_add(struct wmOperatorType *ot); void ARMATURE_OT_align(struct wmOperatorType *ot); void ARMATURE_OT_calculate_roll(struct wmOperatorType *ot); +void ARMATURE_OT_roll_clear(struct wmOperatorType *ot); void ARMATURE_OT_switch_direction(struct wmOperatorType *ot); void ARMATURE_OT_subdivide(struct wmOperatorType *ot); @@ -221,6 +222,7 @@ bool BIF_sk_selectStroke(struct bContext *C, const int mval[2], const bool exten /* duplicate method */ void preEditBoneDuplicate(struct ListBase *editbones); +void postEditBoneDuplicate(struct ListBase *editbones, struct Object *ob); struct EditBone *duplicateEditBone(struct EditBone *curBone, const char *name, struct ListBase *editbones, struct Object *ob); void updateDuplicateSubtarget(struct EditBone *dupBone, struct ListBase *editbones, struct Object *ob); diff --git a/source/blender/editors/armature/armature_ops.c b/source/blender/editors/armature/armature_ops.c index e7f036f6911..ed5f96a5829 100644 --- a/source/blender/editors/armature/armature_ops.c +++ b/source/blender/editors/armature/armature_ops.c @@ -49,6 +49,7 @@ void ED_operatortypes_armature(void) WM_operatortype_append(ARMATURE_OT_align); WM_operatortype_append(ARMATURE_OT_calculate_roll); + WM_operatortype_append(ARMATURE_OT_roll_clear); WM_operatortype_append(ARMATURE_OT_switch_direction); WM_operatortype_append(ARMATURE_OT_subdivide); @@ -228,6 +229,7 @@ void ED_keymap_armature(wmKeyConfig *keyconf) WM_keymap_add_item(keymap, "ARMATURE_OT_reveal", HKEY, KM_PRESS, KM_ALT, 0); WM_keymap_add_item(keymap, "ARMATURE_OT_align", AKEY, KM_PRESS, KM_CTRL | KM_ALT, 0); WM_keymap_add_item(keymap, "ARMATURE_OT_calculate_roll", NKEY, KM_PRESS, KM_CTRL, 0); + WM_keymap_add_item(keymap, "ARMATURE_OT_roll_clear", RKEY, KM_PRESS, KM_ALT, 0); WM_keymap_add_item(keymap, "ARMATURE_OT_switch_direction", FKEY, KM_PRESS, KM_ALT, 0); diff --git a/source/blender/editors/armature/armature_select.c b/source/blender/editors/armature/armature_select.c index f4575105426..5a70a45fad4 100644 --- a/source/blender/editors/armature/armature_select.c +++ b/source/blender/editors/armature/armature_select.c @@ -425,7 +425,7 @@ static int ebone_select_flag(EditBone *ebone) } /* context: editmode armature in view3d */ -bool mouse_armature(bContext *C, const int mval[2], bool extend, bool deselect, bool toggle) +bool ED_armature_select_pick(bContext *C, const int mval[2], bool extend, bool deselect, bool toggle) { Object *obedit = CTX_data_edit_object(C); bArmature *arm = obedit->data; @@ -740,14 +740,20 @@ void ARMATURE_OT_select_less(wmOperatorType *ot) } enum { - SIMEDBONE_LENGTH = 1, + SIMEDBONE_CHILDREN = 1, + SIMEDBONE_CHILDREN_IMMEDIATE, + SIMEDBONE_SIBLINGS, + SIMEDBONE_LENGTH, SIMEDBONE_DIRECTION, SIMEDBONE_PREFIX, SIMEDBONE_SUFFIX, - SIMEDBONE_LAYER + SIMEDBONE_LAYER, }; static EnumPropertyItem prop_similar_types[] = { + {SIMEDBONE_CHILDREN, "CHILDREN", 0, "Children", ""}, + {SIMEDBONE_CHILDREN_IMMEDIATE, "CHILDREN_IMMEDIATE", 0, "Immediate children", ""}, + {SIMEDBONE_SIBLINGS, "SIBLINGS", 0, "Siblings", ""}, {SIMEDBONE_LENGTH, "LENGTH", 0, "Length", ""}, {SIMEDBONE_DIRECTION, "DIRECTION", 0, "Direction (Y axis)", ""}, {SIMEDBONE_PREFIX, "PREFIX", 0, "Prefix", ""}, @@ -855,6 +861,57 @@ static void select_similar_suffix(bArmature *arm, EditBone *ebone_act) } } +static void is_ancestor(EditBone * bone, EditBone * ancestor) +{ + if (bone->temp.ebone == ancestor || bone->temp.ebone == NULL) + return; + + if (bone->temp.ebone->temp.ebone != NULL && bone->temp.ebone->temp.ebone != ancestor) + is_ancestor(bone->temp.ebone, ancestor); + + bone->temp.ebone = bone->temp.ebone->temp.ebone; +} + +static void select_similar_children(bArmature *arm, EditBone *ebone_act) +{ + EditBone *ebone_iter; + + for (ebone_iter = arm->edbo->first; ebone_iter; ebone_iter = ebone_iter->next) { + ebone_iter->temp.ebone = ebone_iter->parent; + } + + for (ebone_iter = arm->edbo->first; ebone_iter; ebone_iter = ebone_iter->next) { + is_ancestor(ebone_iter, ebone_act); + + if (ebone_iter->temp.ebone == ebone_act && EBONE_SELECTABLE(arm, ebone_iter)) + ED_armature_ebone_select_set(ebone_iter, true); + } +} + +static void select_similar_children_immediate(bArmature *arm, EditBone *ebone_act) +{ + EditBone *ebone_iter; + for (ebone_iter = arm->edbo->first; ebone_iter; ebone_iter = ebone_iter->next) { + if (ebone_iter->parent == ebone_act && EBONE_SELECTABLE(arm, ebone_iter)) { + ED_armature_ebone_select_set(ebone_iter, true); + } + } +} + +static void select_similar_siblings(bArmature *arm, EditBone *ebone_act) +{ + EditBone *ebone_iter; + + if (ebone_act->parent == NULL) + return; + + for (ebone_iter = arm->edbo->first; ebone_iter; ebone_iter = ebone_iter->next) { + if (ebone_iter->parent == ebone_act->parent && EBONE_SELECTABLE(arm, ebone_iter)) { + ED_armature_ebone_select_set(ebone_iter, true); + } + } +} + static int armature_select_similar_exec(bContext *C, wmOperator *op) { Object *obedit = CTX_data_edit_object(C); @@ -872,6 +929,15 @@ static int armature_select_similar_exec(bContext *C, wmOperator *op) } switch (type) { + case SIMEDBONE_CHILDREN: + select_similar_children(arm, ebone_act); + break; + case SIMEDBONE_CHILDREN_IMMEDIATE: + select_similar_children_immediate(arm, ebone_act); + break; + case SIMEDBONE_SIBLINGS: + select_similar_siblings(arm, ebone_act); + break; case SIMEDBONE_LENGTH: select_similar_length(arm, ebone_act, thresh); break; @@ -929,7 +995,7 @@ static int armature_select_hierarchy_exec(bContext *C, wmOperator *op) ob = obedit; arm = (bArmature *)ob->data; - ebone_active = arm->act_edbone; + ebone_active = arm->act_edbone; if (ebone_active == NULL) { return OPERATOR_CANCELLED; } diff --git a/source/blender/editors/armature/armature_skinning.c b/source/blender/editors/armature/armature_skinning.c index ea1a94fbba6..28fddbab796 100644 --- a/source/blender/editors/armature/armature_skinning.c +++ b/source/blender/editors/armature/armature_skinning.c @@ -51,12 +51,10 @@ #include "ED_armature.h" #include "ED_mesh.h" +#include "eigen_capi.h" #include "armature_intern.h" - -#ifdef WITH_OPENNL -# include "meshlaplacian.h" -#endif +#include "meshlaplacian.h" #if 0 #include "reeb.h" @@ -216,7 +214,7 @@ static void envelope_bone_weighting(Object *ob, Mesh *mesh, float (*verts)[3], i continue; } - iflip = (dgroupflip) ? mesh_get_x_mirror_vert(ob, i, use_topology) : -1; + iflip = (dgroupflip) ? mesh_get_x_mirror_vert(ob, NULL, i, use_topology) : -1; /* for each skinnable bone */ for (j = 0; j < numbones; ++j) { @@ -401,12 +399,8 @@ static void add_verts_to_dgroups(ReportList *reports, Scene *scene, Object *ob, if (heat) { const char *error = NULL; -#ifdef WITH_OPENNL heat_bone_weighting(ob, mesh, verts, numbones, dgrouplist, dgroupflip, root, tip, selected, &error); -#else - error = "Built without OpenNL"; -#endif if (error) { BKE_report(reports, RPT_WARNING, error); } @@ -417,7 +411,7 @@ static void add_verts_to_dgroups(ReportList *reports, Scene *scene, Object *ob, } /* only generated in some cases but can call anyway */ - ED_mesh_mirror_spatial_table(ob, NULL, NULL, 'e'); + ED_mesh_mirror_spatial_table(ob, NULL, NULL, NULL, 'e'); /* free the memory allocated */ MEM_freeN(bonelist); diff --git a/source/blender/editors/armature/editarmature_retarget.c b/source/blender/editors/armature/editarmature_retarget.c index 2235f9f92cc..7c09ad49f35 100644 --- a/source/blender/editors/armature/editarmature_retarget.c +++ b/source/blender/editors/armature/editarmature_retarget.c @@ -82,7 +82,7 @@ static RigGraph *GLOBAL_RIGG = NULL; /*******************************************************************************************************/ -void exec_retargetArctoArc(TaskPool *pool, void *taskdata, int threadid); +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]); @@ -2143,7 +2143,7 @@ static void retargetArctoArc(bContext *C, RigGraph *rigg, RigArc *iarc, RigNode BLI_task_pool_push(rigg->task_pool, exec_retargetArctoArc, p, true, TASK_PRIORITY_HIGH); } -void exec_retargetArctoArc(TaskPool *UNUSED(pool), void *taskdata, int UNUSED(threadid)) +void exec_retargetArctoArc(TaskPool * __restrict UNUSED(pool), void *taskdata, int UNUSED(threadid)) { RetargetParam *p = (RetargetParam *)taskdata; RigGraph *rigg = p->rigg; diff --git a/source/blender/editors/armature/editarmature_sketch.c b/source/blender/editors/armature/editarmature_sketch.c index c0098a3726a..87d75aa8fad 100644 --- a/source/blender/editors/armature/editarmature_sketch.c +++ b/source/blender/editors/armature/editarmature_sketch.c @@ -436,7 +436,7 @@ static float sk_clampPointSize(SK_Point *pt, float size) static void sk_drawPoint(GLUquadric *quad, SK_Point *pt, float size) { - glTranslatef(pt->p[0], pt->p[1], pt->p[2]); + glTranslate3fv(pt->p); gluSphere(quad, sk_clampPointSize(pt, size), 8, 8); } @@ -455,7 +455,7 @@ static void sk_drawEdge(GLUquadric *quad, SK_Point *pt0, SK_Point *pt1, float si angle = angle_normalized_v3v3(vec2, vec1); - glRotatef(angle * (float)(180.0 / M_PI) + 180.0f, axis[0], axis[1], axis[2]); + glRotate3fv(angle * (float)(180.0 / M_PI) + 180.0f, axis); gluCylinder(quad, sk_clampPointSize(pt1, size), sk_clampPointSize(pt0, size), length, 8, 8); } @@ -475,7 +475,7 @@ static void sk_drawNormal(GLUquadric *quad, SK_Point *pt, float size, float heig angle = angle_normalized_v3v3(vec2, pt->no); - glRotatef(angle * (float)(180.0 / M_PI), axis[0], axis[1], axis[2]); + glRotate3fv(angle * (float)(180.0 / M_PI), axis); glColor3f(0, 1, 1); gluCylinder(quad, sk_clampPointSize(pt, size), 0, sk_clampPointSize(pt, height), 10, 2); @@ -982,7 +982,7 @@ static int sk_getStrokeSnapPoint(bContext *C, SK_Point *pt, SK_Sketch *sketch, S mvalf[0] = dd->mval[0]; mvalf[1] = dd->mval[1]; - peelObjectsContext(C, &sketch->depth_peels, mvalf, SNAP_ALL); + peelObjectsContext(C, mvalf, SNAP_ALL, &sketch->depth_peels); if (stk->nb_points > 0 && stk->points[stk->nb_points - 1].type == PT_CONTINUOUS) { last_p = stk->points[stk->nb_points - 1].p; @@ -1086,7 +1086,9 @@ static int sk_getStrokeSnapPoint(bContext *C, SK_Point *pt, SK_Sketch *sketch, S mval[1] = dd->mval[1]; /* try to snap to closer object */ - found = snapObjectsContext(C, mval, &dist_px, vec, no, SNAP_NOT_SELECTED); + found = snapObjectsContext( + C, mval, SNAP_NOT_SELECTED, + vec, no, &dist_px); if (found == 1) { pt->type = dd->type; pt->mode = PT_SNAP; @@ -1779,14 +1781,13 @@ int sk_detectMergeGesture(bContext *C, SK_Gesture *gest, SK_Sketch *UNUSED(sketc { ARegion *ar = CTX_wm_region(C); if (gest->nb_segments > 2 && gest->nb_intersections == 2) { - short start_val[2], end_val[2]; - short dist; + int start_val[2], end_val[2]; + int dist; - if ((ED_view3d_project_short_global(ar, gest->stk->points[0].p, start_val, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) && - (ED_view3d_project_short_global(ar, sk_lastStrokePoint(gest->stk)->p, end_val, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK)) + if ((ED_view3d_project_int_global(ar, gest->stk->points[0].p, start_val, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) && + (ED_view3d_project_int_global(ar, sk_lastStrokePoint(gest->stk)->p, end_val, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK)) { - - dist = MAX2(ABS(start_val[0] - end_val[0]), ABS(start_val[1] - end_val[1])); + dist = len_manhattan_v2v2_int(start_val, end_val); /* if gesture is a circle */ if (dist <= 20) { @@ -2112,7 +2113,7 @@ static void sk_drawSketch(Scene *scene, View3D *UNUSED(v3d), SK_Sketch *sketch, glColor3fv(colors[index]); glPushMatrix(); - glTranslatef(p->p[0], p->p[1], p->p[2]); + glTranslate3fv(p->p); gluSphere(quad, 0.02, 8, 8); glPopMatrix(); } diff --git a/source/blender/editors/armature/meshlaplacian.c b/source/blender/editors/armature/meshlaplacian.c index b8dc4e1e7ab..9500fd59b8b 100644 --- a/source/blender/editors/armature/meshlaplacian.c +++ b/source/blender/editors/armature/meshlaplacian.c @@ -43,18 +43,12 @@ #include "BKE_modifier.h" #include "BKE_mesh.h" -#ifdef RIGID_DEFORM -#include "BLI_polardecomp.h" -#endif - #include "ED_mesh.h" #include "ED_armature.h" -#include "meshlaplacian.h" - -#ifdef WITH_OPENNL +#include "eigen_capi.h" -#include "ONL_opennl.h" +#include "meshlaplacian.h" /* ************* XXX *************** */ static void waitcursor(int UNUSED(val)) {} @@ -68,7 +62,7 @@ static void error(const char *str) { printf("error: %s\n", str); } /************************** Laplacian System *****************************/ struct LaplacianSystem { - NLContext context; /* opennl context */ + LinearSolver *context; /* linear solver */ int totvert, totface; @@ -80,7 +74,7 @@ struct LaplacianSystem { int areaweights; /* use area in cotangent weights? */ int storeweights; /* store cotangent weights in fweights */ - int nlbegun; /* nlBegin(NL_SYSTEM/NL_MATRIX) done */ + bool variablesdone; /* variables set in linear system */ EdgeHash *edgehash; /* edge hash for construction */ @@ -104,17 +98,6 @@ struct LaplacianSystem { BVHTree *bvhtree; /* ray tracing acceleration structure */ const MLoopTri **vltree; /* a looptri that the vertex belongs to */ } heat; - -#ifdef RIGID_DEFORM - struct RigidDeformation { - EditMesh *mesh; - - float (*R)[3][3]; - float (*rhs)[3]; - float (*origco)[3]; - int thrownerror; - } rigid; -#endif }; /* Laplacian matrix construction */ @@ -197,18 +180,18 @@ static void laplacian_triangle_weights(LaplacianSystem *sys, int f, int i1, int t2 = cotangent_tri_weight_v3(v2, v3, v1) / laplacian_edge_count(sys->edgehash, i3, i1); t3 = cotangent_tri_weight_v3(v3, v1, v2) / laplacian_edge_count(sys->edgehash, i1, i2); - nlMatrixAdd(i1, i1, (t2 + t3) * varea[i1]); - nlMatrixAdd(i2, i2, (t1 + t3) * varea[i2]); - nlMatrixAdd(i3, i3, (t1 + t2) * varea[i3]); + EIG_linear_solver_matrix_add(sys->context, i1, i1, (t2 + t3) * varea[i1]); + EIG_linear_solver_matrix_add(sys->context, i2, i2, (t1 + t3) * varea[i2]); + EIG_linear_solver_matrix_add(sys->context, i3, i3, (t1 + t2) * varea[i3]); - nlMatrixAdd(i1, i2, -t3 * varea[i1]); - nlMatrixAdd(i2, i1, -t3 * varea[i2]); + EIG_linear_solver_matrix_add(sys->context, i1, i2, -t3 * varea[i1]); + EIG_linear_solver_matrix_add(sys->context, i2, i1, -t3 * varea[i2]); - nlMatrixAdd(i2, i3, -t1 * varea[i2]); - nlMatrixAdd(i3, i2, -t1 * varea[i3]); + EIG_linear_solver_matrix_add(sys->context, i2, i3, -t1 * varea[i2]); + EIG_linear_solver_matrix_add(sys->context, i3, i2, -t1 * varea[i3]); - nlMatrixAdd(i3, i1, -t2 * varea[i3]); - nlMatrixAdd(i1, i3, -t2 * varea[i1]); + EIG_linear_solver_matrix_add(sys->context, i3, i1, -t2 * varea[i3]); + EIG_linear_solver_matrix_add(sys->context, i1, i3, -t2 * varea[i1]); if (sys->storeweights) { sys->fweights[f][0] = t1 * varea[i1]; @@ -233,13 +216,11 @@ static LaplacianSystem *laplacian_system_construct_begin(int totvert, int totfac sys->areaweights = 1; sys->storeweights = 0; - /* create opennl context */ - nlNewContext(); - nlSolverParameteri(NL_NB_VARIABLES, totvert); + /* create linear solver */ if (lsq) - nlSolverParameteri(NL_LEAST_SQUARES, NL_TRUE); - - sys->context = nlGetCurrent(); + sys->context = EIG_linear_least_squares_solver_new(0, totvert, 1); + else + sys->context = EIG_linear_solver_new(0, totvert, 1); return sys; } @@ -289,7 +270,7 @@ static void laplacian_system_construct_end(LaplacianSystem *sys) /* for heat weighting */ if (sys->heat.H) - nlMatrixAdd(a, a, sys->heat.H[a]); + EIG_linear_solver_matrix_add(sys->context, a, a, sys->heat.H[a]); } if (sys->storeweights) @@ -318,7 +299,7 @@ static void laplacian_system_delete(LaplacianSystem *sys) if (sys->faces) MEM_freeN(sys->faces); if (sys->fweights) MEM_freeN(sys->fweights); - nlDeleteContext(sys->context); + EIG_linear_solver_delete(sys->context); MEM_freeN(sys); } @@ -326,42 +307,37 @@ void laplacian_begin_solve(LaplacianSystem *sys, int index) { int a; - if (!sys->nlbegun) { - nlBegin(NL_SYSTEM); - + if (!sys->variablesdone) { if (index >= 0) { for (a = 0; a < sys->totvert; a++) { if (sys->vpinned[a]) { - nlSetVariable(0, a, sys->verts[a][index]); - nlLockVariable(a); + EIG_linear_solver_variable_set(sys->context, 0, a, sys->verts[a][index]); + EIG_linear_solver_variable_lock(sys->context, a); } } } - nlBegin(NL_MATRIX); - sys->nlbegun = 1; + sys->variablesdone = true; } } -void laplacian_add_right_hand_side(LaplacianSystem *UNUSED(sys), int v, float value) +void laplacian_add_right_hand_side(LaplacianSystem *sys, int v, float value) { - nlRightHandSideAdd(0, v, value); + EIG_linear_solver_right_hand_side_add(sys->context, 0, v, value); } int laplacian_system_solve(LaplacianSystem *sys) { - nlEnd(NL_MATRIX); - nlEnd(NL_SYSTEM); - sys->nlbegun = 0; + sys->variablesdone = false; - //nlPrintMatrix(); + //EIG_linear_solver_print_matrix(sys->context, ); - return nlSolveAdvanced(NULL, NL_TRUE); + return EIG_linear_solver_solve(sys->context); } -float laplacian_system_get_solution(int v) +float laplacian_system_get_solution(LaplacianSystem *sys, int v) { - return nlGetVariable(0, v); + return EIG_linear_solver_variable_get(sys->context, 0, v); } /************************* Heat Bone Weighting ******************************/ @@ -463,11 +439,7 @@ static int heat_ray_source_visible(LaplacianSystem *sys, int vertex, int source) data.sys = sys; copy_v3_v3(data.start, sys->heat.verts[vertex]); - if (sys->heat.root) /* bone */ - closest_to_line_segment_v3(end, data.start, - sys->heat.root[source], sys->heat.tip[source]); - else /* vertex */ - copy_v3_v3(end, sys->heat.source[source]); + closest_to_line_segment_v3(end, data.start, sys->heat.root[source], sys->heat.tip[source]); sub_v3_v3v3(data.vec, end, data.start); madd_v3_v3v3fl(data.start, data.start, data.vec, 1e-5); @@ -487,11 +459,7 @@ static float heat_source_distance(LaplacianSystem *sys, int vertex, int source) float closest[3], d[3], dist, cosine; /* compute euclidian distance */ - if (sys->heat.root) /* bone */ - closest_to_line_segment_v3(closest, sys->heat.verts[vertex], - sys->heat.root[source], sys->heat.tip[source]); - else /* vertex */ - copy_v3_v3(closest, sys->heat.source[source]); + closest_to_line_segment_v3(closest, sys->heat.verts[vertex], sys->heat.root[source], sys->heat.tip[source]); sub_v3_v3v3(d, sys->heat.verts[vertex], closest); dist = normalize_v3(d); @@ -608,7 +576,7 @@ static void heat_laplacian_create(LaplacianSystem *sys) static void heat_system_free(LaplacianSystem *sys) { BLI_bvhtree_free(sys->heat.bvhtree); - MEM_freeN(sys->heat.vltree); + MEM_freeN((void *)sys->heat.vltree); MEM_freeN((void *)sys->heat.mlooptri); MEM_freeN(sys->heat.mindist); @@ -707,7 +675,7 @@ void heat_bone_weighting(Object *ob, Mesh *me, float (*verts)[3], int numsource, if (dgroupflip) { vertsflipped = MEM_callocN(sizeof(int) * me->totvert, "vertsflipped"); for (a = 0; a < me->totvert; a++) - vertsflipped[a] = mesh_get_x_mirror_vert(ob, a, use_topology); + vertsflipped[a] = mesh_get_x_mirror_vert(ob, NULL, a, use_topology); } /* compute weights per bone */ @@ -746,7 +714,7 @@ void heat_bone_weighting(Object *ob, Mesh *me, float (*verts)[3], int numsource, if (mask && !mask[a]) continue; - solution = laplacian_system_get_solution(a); + solution = laplacian_system_get_solution(sys, a); if (bbone) { if (solution > 0.0f) @@ -815,232 +783,6 @@ void heat_bone_weighting(Object *ob, Mesh *me, float (*verts)[3], int numsource, laplacian_system_delete(sys); } -#ifdef RIGID_DEFORM -/********************** As-Rigid-As-Possible Deformation ******************/ -/* From "As-Rigid-As-Possible Surface Modeling", - * Olga Sorkine and Marc Alexa, ESGP 2007. */ - -/* investigate: - * - transpose R in orthogonal - * - flipped normals and per face adding - * - move canceling to transform, make origco pointer - */ - -static LaplacianSystem *RigidDeformSystem = NULL; - -static void rigid_add_half_edge_to_R(LaplacianSystem *sys, EditVert *v1, EditVert *v2, float w) -{ - float e[3], e_[3]; - int i; - - sub_v3_v3v3(e, sys->rigid.origco[v1->tmp.l], sys->rigid.origco[v2->tmp.l]); - sub_v3_v3v3(e_, v1->co, v2->co); - - /* formula (5) */ - for (i = 0; i < 3; i++) { - sys->rigid.R[v1->tmp.l][i][0] += w * e[0] * e_[i]; - sys->rigid.R[v1->tmp.l][i][1] += w * e[1] * e_[i]; - sys->rigid.R[v1->tmp.l][i][2] += w * e[2] * e_[i]; - } -} - -static void rigid_add_edge_to_R(LaplacianSystem *sys, EditVert *v1, EditVert *v2, float w) -{ - rigid_add_half_edge_to_R(sys, v1, v2, w); - rigid_add_half_edge_to_R(sys, v2, v1, w); -} - -static void rigid_orthogonalize_R(float R[3][3]) -{ - HMatrix M, Q, S; - - copy_m4_m3(M, R); - polar_decomp(M, Q, S); - copy_m3_m4(R, Q); -} - -static void rigid_add_half_edge_to_rhs(LaplacianSystem *sys, EditVert *v1, EditVert *v2, float w) -{ - /* formula (8) */ - float Rsum[3][3], rhs[3]; - - if (sys->vpinned[v1->tmp.l]) - return; - - add_m3_m3m3(Rsum, sys->rigid.R[v1->tmp.l], sys->rigid.R[v2->tmp.l]); - transpose_m3(Rsum); - - sub_v3_v3v3(rhs, sys->rigid.origco[v1->tmp.l], sys->rigid.origco[v2->tmp.l]); - mul_m3_v3(Rsum, rhs); - mul_v3_fl(rhs, 0.5f); - mul_v3_fl(rhs, w); - - add_v3_v3(sys->rigid.rhs[v1->tmp.l], rhs); -} - -static void rigid_add_edge_to_rhs(LaplacianSystem *sys, EditVert *v1, EditVert *v2, float w) -{ - rigid_add_half_edge_to_rhs(sys, v1, v2, w); - rigid_add_half_edge_to_rhs(sys, v2, v1, w); -} - -void rigid_deform_iteration() -{ - LaplacianSystem *sys = RigidDeformSystem; - EditMesh *em; - EditVert *eve; - EditFace *efa; - int a, i; - - if (!sys) - return; - - nlMakeCurrent(sys->context); - em = sys->rigid.mesh; - - /* compute R */ - memset(sys->rigid.R, 0, sizeof(float) * 3 * 3 * sys->totvert); - memset(sys->rigid.rhs, 0, sizeof(float) * 3 * sys->totvert); - - for (a = 0, efa = em->faces.first; efa; efa = efa->next, a++) { - rigid_add_edge_to_R(sys, efa->v1, efa->v2, sys->fweights[a][2]); - rigid_add_edge_to_R(sys, efa->v2, efa->v3, sys->fweights[a][0]); - rigid_add_edge_to_R(sys, efa->v3, efa->v1, sys->fweights[a][1]); - - if (efa->v4) { - a++; - rigid_add_edge_to_R(sys, efa->v1, efa->v3, sys->fweights[a][2]); - rigid_add_edge_to_R(sys, efa->v3, efa->v4, sys->fweights[a][0]); - rigid_add_edge_to_R(sys, efa->v4, efa->v1, sys->fweights[a][1]); - } - } - - for (a = 0, eve = em->verts.first; eve; eve = eve->next, a++) { - rigid_orthogonalize_R(sys->rigid.R[a]); - eve->tmp.l = a; - } - - /* compute right hand sides for solving */ - for (a = 0, efa = em->faces.first; efa; efa = efa->next, a++) { - rigid_add_edge_to_rhs(sys, efa->v1, efa->v2, sys->fweights[a][2]); - rigid_add_edge_to_rhs(sys, efa->v2, efa->v3, sys->fweights[a][0]); - rigid_add_edge_to_rhs(sys, efa->v3, efa->v1, sys->fweights[a][1]); - - if (efa->v4) { - a++; - rigid_add_edge_to_rhs(sys, efa->v1, efa->v3, sys->fweights[a][2]); - rigid_add_edge_to_rhs(sys, efa->v3, efa->v4, sys->fweights[a][0]); - rigid_add_edge_to_rhs(sys, efa->v4, efa->v1, sys->fweights[a][1]); - } - } - - /* solve for positions, for X, Y and Z separately */ - for (i = 0; i < 3; i++) { - laplacian_begin_solve(sys, i); - - for (a = 0; a < sys->totvert; a++) - if (!sys->vpinned[a]) - laplacian_add_right_hand_side(sys, a, sys->rigid.rhs[a][i]); - - if (laplacian_system_solve(sys)) { - for (a = 0, eve = em->verts.first; eve; eve = eve->next, a++) - eve->co[i] = laplacian_system_get_solution(a); - } - else { - if (!sys->rigid.thrownerror) { - error("RigidDeform: failed to find solution"); - sys->rigid.thrownerror = 1; - } - break; - } - } -} - -static void rigid_laplacian_create(LaplacianSystem *sys) -{ - EditMesh *em = sys->rigid.mesh; - EditVert *eve; - EditFace *efa; - int a; - - /* add verts and faces to laplacian */ - for (a = 0, eve = em->verts.first; eve; eve = eve->next, a++) { - laplacian_add_vertex(sys, eve->co, eve->pinned); - eve->tmp.l = a; - } - - for (efa = em->faces.first; efa; efa = efa->next) { - laplacian_add_triangle(sys, - efa->v1->tmp.l, efa->v2->tmp.l, efa->v3->tmp.l); - if (efa->v4) - laplacian_add_triangle(sys, - efa->v1->tmp.l, efa->v3->tmp.l, efa->v4->tmp.l); - } -} - -void rigid_deform_begin(EditMesh *em) -{ - LaplacianSystem *sys; - EditVert *eve; - EditFace *efa; - int a, totvert, totface; - - /* count vertices, triangles */ - for (totvert = 0, eve = em->verts.first; eve; eve = eve->next) - totvert++; - - for (totface = 0, efa = em->faces.first; efa; efa = efa->next) { - totface++; - if (efa->v4) totface++; - } - - /* create laplacian */ - sys = laplacian_system_construct_begin(totvert, totface, 0); - - sys->rigid.mesh = em; - sys->rigid.R = MEM_callocN(sizeof(float) * 3 * 3 * totvert, "RigidDeformR"); - sys->rigid.rhs = MEM_callocN(sizeof(float) * 3 * totvert, "RigidDeformRHS"); - sys->rigid.origco = MEM_callocN(sizeof(float) * 3 * totvert, "RigidDeformCo"); - - for (a = 0, eve = em->verts.first; eve; eve = eve->next, a++) - copy_v3_v3(sys->rigid.origco[a], eve->co); - - sys->areaweights = 0; - sys->storeweights = 1; - - rigid_laplacian_create(sys); - - laplacian_system_construct_end(sys); - - RigidDeformSystem = sys; -} - -void rigid_deform_end(int cancel) -{ - LaplacianSystem *sys = RigidDeformSystem; - - if (sys) { - EditMesh *em = sys->rigid.mesh; - EditVert *eve; - int a; - - if (cancel) - for (a = 0, eve = em->verts.first; eve; eve = eve->next, a++) - if (!eve->pinned) - copy_v3_v3(eve->co, sys->rigid.origco[a]); - - if (sys->rigid.R) MEM_freeN(sys->rigid.R); - if (sys->rigid.rhs) MEM_freeN(sys->rigid.rhs); - if (sys->rigid.origco) MEM_freeN(sys->rigid.origco); - - /* free */ - laplacian_system_delete(sys); - } - - RigidDeformSystem = NULL; -} -#endif - /************************** Harmonic Coordinates ****************************/ /* From "Harmonic Coordinates for Character Articulation", * Pushkar Joshi, Mark Meyer, Tony DeRose, Brian Green and Tom Sanocki, @@ -1251,7 +993,6 @@ static MDefBoundIsect *meshdeform_ray_tree_intersect(MeshDeformBind *mdb, const &isect_mdef, }; float end[3], vec_normal[3]; - // static float epsilon[3] = {1e-4, 1e-4, 1e-4}; /* happens binding when a cage has no faces */ if (UNLIKELY(mdb->bvhtree == NULL)) @@ -1261,18 +1002,13 @@ static MDefBoundIsect *meshdeform_ray_tree_intersect(MeshDeformBind *mdb, const memset(&isect_mdef, 0, sizeof(isect_mdef)); isect_mdef.lambda = 1e10f; -#if 0 - add_v3_v3v3(isect_mdef.start, co1, epsilon); - add_v3_v3v3(end, co2, epsilon); -#else copy_v3_v3(isect_mdef.start, co1); copy_v3_v3(end, co2); -#endif sub_v3_v3v3(isect_mdef.vec, end, isect_mdef.start); isect_mdef.vec_length = normalize_v3_v3(vec_normal, isect_mdef.vec); hit.index = -1; - hit.dist = FLT_MAX; + hit.dist = BVH_RAYCAST_DIST_MAX; if (BLI_bvhtree_ray_cast(mdb->bvhtree, isect_mdef.start, vec_normal, 0.0, &hit, harmonic_ray_callback, &data) != -1) { @@ -1541,7 +1277,7 @@ static float meshdeform_boundary_total_weight(MeshDeformBind *mdb, int x, int y, return totweight; } -static void meshdeform_matrix_add_cell(MeshDeformBind *mdb, int x, int y, int z) +static void meshdeform_matrix_add_cell(MeshDeformBind *mdb, LinearSolver *context, int x, int y, int z) { MDefBoundIsect *isect; float weight, totweight; @@ -1551,7 +1287,7 @@ static void meshdeform_matrix_add_cell(MeshDeformBind *mdb, int x, int y, int z) if (mdb->tag[acenter] == MESHDEFORM_TAG_EXTERIOR) return; - nlMatrixAdd(mdb->varidx[acenter], mdb->varidx[acenter], 1.0f); + EIG_linear_solver_matrix_add(context, mdb->varidx[acenter], mdb->varidx[acenter], 1.0f); totweight = meshdeform_boundary_total_weight(mdb, x, y, z); for (i = 1; i <= 6; i++) { @@ -1562,12 +1298,12 @@ static void meshdeform_matrix_add_cell(MeshDeformBind *mdb, int x, int y, int z) isect = mdb->boundisect[acenter][i - 1]; if (!isect) { weight = (1.0f / mdb->width[0]) / totweight; - nlMatrixAdd(mdb->varidx[acenter], mdb->varidx[a], -weight); + EIG_linear_solver_matrix_add(context, mdb->varidx[acenter], mdb->varidx[a], -weight); } } } -static void meshdeform_matrix_add_rhs(MeshDeformBind *mdb, int x, int y, int z, int cagevert) +static void meshdeform_matrix_add_rhs(MeshDeformBind *mdb, LinearSolver *context, int x, int y, int z, int cagevert) { MDefBoundIsect *isect; float rhs, weight, totweight; @@ -1588,7 +1324,7 @@ static void meshdeform_matrix_add_rhs(MeshDeformBind *mdb, int x, int y, int z, if (isect) { weight = (1.0f / isect->len) / totweight; rhs = weight * meshdeform_boundary_phi(mdb, isect, cagevert); - nlRightHandSideAdd(0, mdb->varidx[acenter], rhs); + EIG_linear_solver_right_hand_side_add(context, 0, mdb->varidx[acenter], rhs); } } } @@ -1643,7 +1379,7 @@ static void meshdeform_matrix_add_exterior_phi(MeshDeformBind *mdb, int x, int y static void meshdeform_matrix_solve(MeshDeformModifierData *mmd, MeshDeformBind *mdb) { - NLContext *context; + LinearSolver *context; float vec[3], gridvec[3]; int a, b, x, y, z, totvar; char message[256]; @@ -1660,44 +1396,24 @@ static void meshdeform_matrix_solve(MeshDeformModifierData *mmd, MeshDeformBind progress_bar(0, "Starting mesh deform solve"); - /* setup opennl solver */ - nlNewContext(); - context = nlGetCurrent(); - - nlSolverParameteri(NL_NB_VARIABLES, totvar); - nlSolverParameteri(NL_NB_ROWS, totvar); - nlSolverParameteri(NL_NB_RIGHT_HAND_SIDES, 1); - - nlBegin(NL_SYSTEM); - nlBegin(NL_MATRIX); + /* setup linear solver */ + context = EIG_linear_solver_new(totvar, totvar, 1); /* build matrix */ for (z = 0; z < mdb->size; z++) for (y = 0; y < mdb->size; y++) for (x = 0; x < mdb->size; x++) - meshdeform_matrix_add_cell(mdb, x, y, z); + meshdeform_matrix_add_cell(mdb, context, x, y, z); /* solve for each cage vert */ for (a = 0; a < mdb->totcagevert; a++) { - if (a != 0) { - nlBegin(NL_SYSTEM); - nlBegin(NL_MATRIX); - } - /* fill in right hand side and solve */ for (z = 0; z < mdb->size; z++) for (y = 0; y < mdb->size; y++) for (x = 0; x < mdb->size; x++) - meshdeform_matrix_add_rhs(mdb, x, y, z, a); - - nlEnd(NL_MATRIX); - nlEnd(NL_SYSTEM); - -#if 0 - nlPrintMatrix(); -#endif + meshdeform_matrix_add_rhs(mdb, context, x, y, z, a); - if (nlSolveAdvanced(NULL, NL_TRUE)) { + if (EIG_linear_solver_solve(context)) { for (z = 0; z < mdb->size; z++) for (y = 0; y < mdb->size; y++) for (x = 0; x < mdb->size; x++) @@ -1710,7 +1426,7 @@ static void meshdeform_matrix_solve(MeshDeformModifierData *mmd, MeshDeformBind for (b = 0; b < mdb->size3; b++) { if (mdb->tag[b] != MESHDEFORM_TAG_EXTERIOR) - mdb->phi[b] = nlGetVariable(0, mdb->varidx[b]); + mdb->phi[b] = EIG_linear_solver_variable_get(context, 0, mdb->varidx[b]); mdb->totalphi[b] += mdb->phi[b]; } @@ -1764,7 +1480,7 @@ static void meshdeform_matrix_solve(MeshDeformModifierData *mmd, MeshDeformBind /* free */ MEM_freeN(mdb->varidx); - nlDeleteContext(context); + EIG_linear_solver_delete(context); } static void harmonic_coordinates_bind(Scene *UNUSED(scene), MeshDeformModifierData *mmd, MeshDeformBind *mdb) @@ -1917,77 +1633,9 @@ static void harmonic_coordinates_bind(Scene *UNUSED(scene), MeshDeformModifierDa free_bvhtree_from_mesh(&mdb->bvhdata); } -#if 0 -static void heat_weighting_bind(Scene *scene, DerivedMesh *dm, MeshDeformModifierData *mmd, MeshDeformBind *mdb) -{ - LaplacianSystem *sys; - MFace *mface = dm->getTessFaceArray(dm), *mf; - int totvert = dm->getNumVerts(dm); - int totface = dm->getNumTessFaces(dm); - float solution, weight; - int a, tottri, j, thrownerror = 0; - - mdb->weights = MEM_callocN(sizeof(float) * mdb->totvert * mdb->totcagevert, "MDefWeights"); - - /* count triangles */ - for (tottri = 0, a = 0, mf = mface; a < totface; a++, mf++) { - tottri++; - if (mf->v4) tottri++; - } - - /* create laplacian */ - sys = laplacian_system_construct_begin(totvert, tottri, 1); - - sys->heat.mface = mface; - sys->heat.totface = totface; - sys->heat.totvert = totvert; - sys->heat.verts = mdb->vertexcos; - sys->heat.source = mdb->cagecos; - sys->heat.numsource = mdb->totcagevert; - - heat_ray_tree_create(sys); - heat_laplacian_create(sys); - - laplacian_system_construct_end(sys); - - /* compute weights per bone */ - for (j = 0; j < mdb->totcagevert; j++) { - /* fill right hand side */ - laplacian_begin_solve(sys, -1); - - for (a = 0; a < totvert; a++) - if (heat_source_closest(sys, a, j)) - laplacian_add_right_hand_side(sys, a, - sys->heat.H[a] * sys->heat.p[a]); - - /* solve */ - if (laplacian_system_solve(sys)) { - /* load solution into vertex groups */ - for (a = 0; a < totvert; a++) { - solution = laplacian_system_get_solution(a); - - weight = heat_limit_weight(solution); - if (weight > 0.0f) - mdb->weights[a * mdb->totcagevert + j] = weight; - } - } - else if (!thrownerror) { - error("Mesh Deform Heat Weighting:" - " failed to find solution for one or more vertices"); - thrownerror = 1; - break; - } - } - - /* free */ - heat_system_free(sys); - laplacian_system_delete(sys); - - mmd->bindweights = mdb->weights; -} -#endif - -void mesh_deform_bind(Scene *scene, MeshDeformModifierData *mmd, float *vertexcos, int totvert, float cagemat[4][4]) +void mesh_deform_bind( + Scene *scene, MeshDeformModifierData *mmd, DerivedMesh *cagedm, + float *vertexcos, int totvert, float cagemat[4][4]) { MeshDeformBind mdb; MVert *mvert; @@ -2002,7 +1650,7 @@ void mesh_deform_bind(Scene *scene, MeshDeformModifierData *mmd, float *vertexco mdb.vertexcos = MEM_callocN(sizeof(float) * 3 * totvert, "MeshDeformCos"); mdb.totvert = totvert; - mdb.cagedm = mesh_create_derived_no_deform(scene, mmd->object, NULL, CD_MASK_BAREMESH); + mdb.cagedm = cagedm; mdb.totcagevert = mdb.cagedm->getNumVerts(mdb.cagedm); mdb.cagecos = MEM_callocN(sizeof(*mdb.cagecos) * mdb.totcagevert, "MeshDeformBindCos"); copy_m4_m4(mdb.cagemat, cagemat); @@ -2014,14 +1662,7 @@ void mesh_deform_bind(Scene *scene, MeshDeformModifierData *mmd, float *vertexco mul_v3_m4v3(mdb.vertexcos[a], mdb.cagemat, vertexcos + a * 3); /* solve */ -#if 0 - if (mmd->mode == MOD_MDEF_VOLUME) - harmonic_coordinates_bind(scene, mmd, &mdb); - else - heat_weighting_bind(scene, dm, mmd, &mdb); -#else harmonic_coordinates_bind(scene, mmd, &mdb); -#endif /* assign bind variables */ mmd->bindcagecos = (float *)mdb.cagecos; @@ -2034,7 +1675,6 @@ void mesh_deform_bind(Scene *scene, MeshDeformModifierData *mmd, float *vertexco mul_m4_v3(mmd->object->obmat, mmd->bindcagecos + a * 3); /* free */ - mdb.cagedm->release(mdb.cagedm); MEM_freeN(mdb.vertexcos); /* compact weights */ @@ -2043,14 +1683,3 @@ void mesh_deform_bind(Scene *scene, MeshDeformModifierData *mmd, float *vertexco end_progress_bar(); waitcursor(0); } - -#else /* WITH_OPENNL */ - -#ifdef __GNUC__ -# pragma GCC diagnostic ignored "-Wunused-parameter" -#endif - -void mesh_deform_bind(Scene *scene, MeshDeformModifierData *mmd, float *vertexcos, int totvert, float cagemat[4][4]) {} -void *modifier_mdef_compact_influences_link_kludge = modifier_mdef_compact_influences; - -#endif /* WITH_OPENNL */ diff --git a/source/blender/editors/armature/meshlaplacian.h b/source/blender/editors/armature/meshlaplacian.h index 1412136c1a8..bba8c739abf 100644 --- a/source/blender/editors/armature/meshlaplacian.h +++ b/source/blender/editors/armature/meshlaplacian.h @@ -48,7 +48,7 @@ void laplacian_add_triangle(LaplacianSystem *sys, int v1, int v2, int v3); void laplacian_begin_solve(LaplacianSystem *sys, int index); void laplacian_add_right_hand_side(LaplacianSystem *sys, int v, float value); int laplacian_system_solve(LaplacianSystem *sys); -float laplacian_system_get_solution(int v); +float laplacian_system_get_solution(LaplacianSystem *sys, int v); /* Heat Weighting */ diff --git a/source/blender/editors/armature/pose_edit.c b/source/blender/editors/armature/pose_edit.c index e87c324d7ec..a929507929f 100644 --- a/source/blender/editors/armature/pose_edit.c +++ b/source/blender/editors/armature/pose_edit.c @@ -255,13 +255,23 @@ void POSE_OT_paths_calculate(wmOperatorType *ot) RNA_def_int(ot->srna, "end_frame", 250, MINAFRAME, MAXFRAME, "End", "Last frame to calculate bone paths on", MINFRAME, MAXFRAME / 2.0); - RNA_def_enum(ot->srna, "bake_location", motionpath_bake_location_items, 0, + RNA_def_enum(ot->srna, "bake_location", rna_enum_motionpath_bake_location_items, 0, "Bake Location", "Which point on the bones is used when calculating paths"); } /* --------- */ +static int pose_update_paths_poll(bContext *C) +{ + if (ED_operator_posemode_exclusive(C)) { + bPoseChannel *pchan = CTX_data_active_pose_bone(C); + return (pchan && pchan->mpath); + } + + return false; +} + static int pose_update_paths_exec(bContext *C, wmOperator *UNUSED(op)) { Object *ob = BKE_object_pose_armature_get(CTX_data_active_object(C)); @@ -289,7 +299,7 @@ void POSE_OT_paths_update(wmOperatorType *ot) /* api callbakcs */ ot->exec = pose_update_paths_exec; - ot->poll = ED_operator_posemode_exclusive; /* TODO: this should probably check for active bone and/or existing paths */ + ot->poll = pose_update_paths_poll; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; @@ -298,42 +308,44 @@ void POSE_OT_paths_update(wmOperatorType *ot) /* --------- */ /* for the object with pose/action: clear path curves for selected bones only */ -static void ED_pose_clear_paths(Object *ob) +static void ED_pose_clear_paths(Object *ob, bool only_selected) { bPoseChannel *pchan; - short skipped = 0; + bool skipped = false; if (ELEM(NULL, ob, ob->pose)) return; - /* free the motionpath blocks, but also take note of whether we skipped some... */ + /* free the motionpath blocks for all bones - This is easier for users to quickly clear all */ for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) { if (pchan->mpath) { - if ((pchan->bone) && (pchan->bone->flag & BONE_SELECTED)) { + if ((only_selected == false) || ((pchan->bone) && (pchan->bone->flag & BONE_SELECTED))) { animviz_free_motionpath(pchan->mpath); pchan->mpath = NULL; } - else - skipped = 1; + else { + skipped = true; + } } } - /* if we didn't skip any, we shouldn't have any paths left */ - if (skipped == 0) + /* if nothing was skipped, there should be no paths left! */ + if (skipped == false) ob->pose->avs.path_bakeflag &= ~MOTIONPATH_BAKE_HAS_PATHS; } -/* operator callback for this */ -static int pose_clear_paths_exec(bContext *C, wmOperator *UNUSED(op)) +/* operator callback - wrapper for the backend function */ +static int pose_clear_paths_exec(bContext *C, wmOperator *op) { Object *ob = BKE_object_pose_armature_get(CTX_data_active_object(C)); - + bool only_selected = RNA_boolean_get(op->ptr, "only_selected"); + /* only continue if there's an object */ if (ELEM(NULL, ob, ob->pose)) return OPERATOR_CANCELLED; /* use the backend function for this */ - ED_pose_clear_paths(ob); + ED_pose_clear_paths(ob, only_selected); /* notifiers for updates */ WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob); @@ -341,19 +353,34 @@ static int pose_clear_paths_exec(bContext *C, wmOperator *UNUSED(op)) return OPERATOR_FINISHED; } +/* operator callback/wrapper */ +static int pose_clear_paths_invoke(bContext *C, wmOperator *op, const wmEvent *evt) +{ + if ((evt->shift) && !RNA_struct_property_is_set(op->ptr, "only_selected")) { + RNA_boolean_set(op->ptr, "only_selected", true); + } + return pose_clear_paths_exec(C, op); +} + void POSE_OT_paths_clear(wmOperatorType *ot) { /* identifiers */ ot->name = "Clear Bone Paths"; ot->idname = "POSE_OT_paths_clear"; - ot->description = "Clear path caches for selected bones"; + ot->description = "Clear path caches for all bones, hold Shift key for selected bones only"; /* api callbacks */ + ot->invoke = pose_clear_paths_invoke; ot->exec = pose_clear_paths_exec; ot->poll = ED_operator_posemode_exclusive; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* properties */ + ot->prop = RNA_def_boolean(ot->srna, "only_selected", false, "Only Selected", + "Only clear paths from selected bones"); + RNA_def_property_flag(ot->prop, PROP_SKIP_SAVE); } /* ********************************************** */ @@ -700,7 +727,7 @@ void POSE_OT_rotation_mode_set(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; /* properties */ - ot->prop = RNA_def_enum(ot->srna, "type", posebone_rotmode_items, 0, "Rotation Mode", ""); + ot->prop = RNA_def_enum(ot->srna, "type", rna_enum_posebone_rotmode_items, 0, "Rotation Mode", ""); } /* ********************************************** */ diff --git a/source/blender/editors/armature/pose_slide.c b/source/blender/editors/armature/pose_slide.c index 40328e0c06e..16ba1483e38 100644 --- a/source/blender/editors/armature/pose_slide.c +++ b/source/blender/editors/armature/pose_slide.c @@ -655,6 +655,15 @@ static int pose_slide_invoke_common(bContext *C, wmOperator *op, tPoseSlideOp *p return OPERATOR_RUNNING_MODAL; } +/* calculate percentage based on position of mouse (we only use x-axis for now. + * since this is more convenient for users to do), and store new percentage value + */ +static void pose_slide_mouse_update_percentage(tPoseSlideOp *pso, wmOperator *op, const wmEvent *event) +{ + pso->percentage = (event->x - pso->ar->winrct.xmin) / ((float)pso->ar->winx); + RNA_float_set(op->ptr, "percentage", pso->percentage); +} + /* common code for modal() */ static int pose_slide_modal(bContext *C, wmOperator *op, const wmEvent *event) { @@ -702,11 +711,8 @@ static int pose_slide_modal(bContext *C, wmOperator *op, const wmEvent *event) { /* only handle mousemove if not doing numinput */ if (has_numinput == false) { - /* calculate percentage based on position of mouse (we only use x-axis for now. - * since this is more convenient for users to do), and store new percentage value - */ - pso->percentage = (event->x - pso->ar->winrct.xmin) / ((float)pso->ar->winx); - RNA_float_set(op->ptr, "percentage", pso->percentage); + /* update percentage based on position of mouse */ + pose_slide_mouse_update_percentage(pso, op, event); /* update percentage indicator in header */ pose_slide_draw_status(pso); @@ -787,7 +793,7 @@ static void pose_slide_opdef_properties(wmOperatorType *ot) /* ------------------------------------ */ /* invoke() - for 'push' mode */ -static int pose_slide_push_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) +static int pose_slide_push_invoke(bContext *C, wmOperator *op, const wmEvent *event) { tPoseSlideOp *pso; @@ -798,6 +804,9 @@ static int pose_slide_push_invoke(bContext *C, wmOperator *op, const wmEvent *UN } else pso = op->customdata; + + /* initialise percentage so that it won't pop on first mouse move */ + pose_slide_mouse_update_percentage(pso, op, event); /* do common setup work */ return pose_slide_invoke_common(C, op, pso); @@ -844,7 +853,7 @@ void POSE_OT_push(wmOperatorType *ot) /* ........................ */ /* invoke() - for 'relax' mode */ -static int pose_slide_relax_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) +static int pose_slide_relax_invoke(bContext *C, wmOperator *op, const wmEvent *event) { tPoseSlideOp *pso; @@ -856,6 +865,9 @@ static int pose_slide_relax_invoke(bContext *C, wmOperator *op, const wmEvent *U else pso = op->customdata; + /* initialise percentage so that it won't pop on first mouse move */ + pose_slide_mouse_update_percentage(pso, op, event); + /* do common setup work */ return pose_slide_invoke_common(C, op, pso); } @@ -901,7 +913,7 @@ void POSE_OT_relax(wmOperatorType *ot) /* ........................ */ /* invoke() - for 'breakdown' mode */ -static int pose_slide_breakdown_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) +static int pose_slide_breakdown_invoke(bContext *C, wmOperator *op, const wmEvent *event) { tPoseSlideOp *pso; @@ -913,6 +925,9 @@ static int pose_slide_breakdown_invoke(bContext *C, wmOperator *op, const wmEven else pso = op->customdata; + /* initialise percentage so that it won't pop on first mouse move */ + pose_slide_mouse_update_percentage(pso, op, event); + /* do common setup work */ return pose_slide_invoke_common(C, op, pso); } diff --git a/source/blender/editors/armature/reeb.c b/source/blender/editors/armature/reeb.c index f29d15ff416..661a8e1de9f 100644 --- a/source/blender/editors/armature/reeb.c +++ b/source/blender/editors/armature/reeb.c @@ -2497,7 +2497,7 @@ int weightFromLoc(EditMesh *em, int axis) return 1; } -static void addTriangle(EditVert *v1, EditVert *v2, EditVert *v3, int e1, int e2, int e3) +static void addTriangle(LinearSolver *context, EditVert *v1, EditVert *v2, EditVert *v3, int e1, int e2, int e3) { /* Angle opposite e1 */ float t1 = cotangent_tri_weight_v3(v1->co, v2->co, v3->co) / e2; @@ -2512,22 +2512,23 @@ static void addTriangle(EditVert *v1, EditVert *v2, EditVert *v3, int e1, int e2 int i2 = indexData(v2); int i3 = indexData(v3); - nlMatrixAdd(i1, i1, t2 + t3); - nlMatrixAdd(i2, i2, t1 + t3); - nlMatrixAdd(i3, i3, t1 + t2); + EIG_linear_solver_matrix_add(context, i1, i1, t2 + t3); + EIG_linear_solver_matrix_add(context, i2, i2, t1 + t3); + EIG_linear_solver_matrix_add(context, i3, i3, t1 + t2); - nlMatrixAdd(i1, i2, -t3); - nlMatrixAdd(i2, i1, -t3); + EIG_linear_solver_matrix_add(context, i1, i2, -t3); + EIG_linear_solver_matrix_add(context, i2, i1, -t3); - nlMatrixAdd(i2, i3, -t1); - nlMatrixAdd(i3, i2, -t1); + EIG_linear_solver_matrix_add(context, i2, i3, -t1); + EIG_linear_solver_matrix_add(context, i3, i2, -t1); - nlMatrixAdd(i3, i1, -t2); - nlMatrixAdd(i1, i3, -t2); + EIG_linear_solver_matrix_add(context, i3, i1, -t2); + EIG_linear_solver_matrix_add(context, i1, i3, -t2); } int weightToHarmonic(EditMesh *em, EdgeIndex *indexed_edges) { + LinearSolver *context; NLboolean success; EditVert *eve; EditEdge *eed; @@ -2541,14 +2542,10 @@ int weightToHarmonic(EditMesh *em, EdgeIndex *indexed_edges) totvert++; } - /* Solve with openNL */ + /* Solve */ - nlNewContext(); + context = EIG_linear_solver_new(, 0, totvert, 1); - nlSolverParameteri(NL_NB_VARIABLES, totvert); - - nlBegin(NL_SYSTEM); - /* Find local extrema */ for (index = 0, eve = em->verts.first; eve; index++, eve = eve->next) { if (eve->h == 0) { @@ -2582,8 +2579,8 @@ int weightToHarmonic(EditMesh *em, EdgeIndex *indexed_edges) if (maximum || minimum) { float w = weightData(eve); eve->f1 = 0; - nlSetVariable(0, index, w); - nlLockVariable(index); + EIG_linear_solver_variable_set(context, 0, index, w); + EIG_linear_solver_variable_lock(context, index); } else { eve->f1 = 1; @@ -2591,8 +2588,6 @@ int weightToHarmonic(EditMesh *em, EdgeIndex *indexed_edges) } } - nlBegin(NL_MATRIX); - /* Zero edge weight */ for (eed = em->edges.first; eed; eed = eed->next) { eed->tmp.l = 0; @@ -2615,32 +2610,28 @@ int weightToHarmonic(EditMesh *em, EdgeIndex *indexed_edges) for (efa = em->faces.first; efa; efa = efa->next) { if (efa->h == 0) { if (efa->v4 == NULL) { - addTriangle(efa->v1, efa->v2, efa->v3, efa->e1->tmp.l, efa->e2->tmp.l, efa->e3->tmp.l); + addTriangle(context, efa->v1, efa->v2, efa->v3, efa->e1->tmp.l, efa->e2->tmp.l, efa->e3->tmp.l); } else { - addTriangle(efa->v1, efa->v2, efa->v3, efa->e1->tmp.l, efa->e2->tmp.l, 2); - addTriangle(efa->v3, efa->v4, efa->v1, efa->e3->tmp.l, efa->e4->tmp.l, 2); + addTriangle(context, efa->v1, efa->v2, efa->v3, efa->e1->tmp.l, efa->e2->tmp.l, 2); + addTriangle(context, efa->v3, efa->v4, efa->v1, efa->e3->tmp.l, efa->e4->tmp.l, 2); } } } - nlEnd(NL_MATRIX); - - nlEnd(NL_SYSTEM); - - success = nlSolveAdvanced(NULL, NL_TRUE); + success = EIG_linear_solver_solve(context); if (success) { rval = 1; for (index = 0, eve = em->verts.first; eve; index++, eve = eve->next) { - weightSetData(eve, nlGetVariable(0, index)); + weightSetData(eve, EIG_linear_solver_variable_get(context, 0, index)); } } else { rval = 0; } - nlDeleteContext(nlGetCurrent()); + EIG_linear_solver_delete(context); return rval; } @@ -3439,9 +3430,6 @@ void REEB_draw() } } glEnable(GL_DEPTH_TEST); - - glLineWidth(1.0); - glPointSize(1.0); } #endif |