Cleanup: indentation
Indent lines for multi object editing, no functional changes. Also strip trailing space from indented regions.
This commit is contained in:
@@ -1345,33 +1345,33 @@ static int armature_delete_selected_exec(bContext *C, wmOperator *UNUSED(op))
|
||||
uint objects_len = 0;
|
||||
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, &objects_len);
|
||||
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
|
||||
Object *obedit = objects[ob_index];
|
||||
bArmature *arm = obedit->data;
|
||||
bool changed = false;
|
||||
Object *obedit = objects[ob_index];
|
||||
bArmature *arm = obedit->data;
|
||||
bool changed = false;
|
||||
|
||||
armature_select_mirrored(arm);
|
||||
armature_select_mirrored(arm);
|
||||
|
||||
BKE_pose_channels_remove(obedit, armature_delete_ebone_cb, arm);
|
||||
BKE_pose_channels_remove(obedit, armature_delete_ebone_cb, arm);
|
||||
|
||||
for (curBone = arm->edbo->first; curBone; curBone = ebone_next) {
|
||||
ebone_next = curBone->next;
|
||||
if (arm->layer & curBone->layer) {
|
||||
if (curBone->flag & BONE_SELECTED) {
|
||||
if (curBone == arm->act_edbone) arm->act_edbone = NULL;
|
||||
ED_armature_ebone_remove(arm, curBone);
|
||||
changed = true;
|
||||
for (curBone = arm->edbo->first; curBone; curBone = ebone_next) {
|
||||
ebone_next = curBone->next;
|
||||
if (arm->layer & curBone->layer) {
|
||||
if (curBone->flag & BONE_SELECTED) {
|
||||
if (curBone == arm->act_edbone) arm->act_edbone = NULL;
|
||||
ED_armature_ebone_remove(arm, curBone);
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (changed) {
|
||||
changed_multi = true;
|
||||
if (changed) {
|
||||
changed_multi = true;
|
||||
|
||||
ED_armature_edit_sync_selection(arm->edbo);
|
||||
BKE_pose_tag_recalc(CTX_data_main(C), obedit->pose);
|
||||
ED_armature_edit_sync_selection(arm->edbo);
|
||||
BKE_pose_tag_recalc(CTX_data_main(C), obedit->pose);
|
||||
|
||||
WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, obedit);
|
||||
}
|
||||
WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, obedit);
|
||||
}
|
||||
}
|
||||
|
||||
if (!changed_multi) {
|
||||
|
||||
@@ -2712,171 +2712,171 @@ static int edbm_select_linked_exec(bContext *C, wmOperator *op)
|
||||
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, &objects_len);
|
||||
|
||||
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
|
||||
Object *obedit = objects[ob_index];
|
||||
Object *obedit = objects[ob_index];
|
||||
|
||||
BMEditMesh *em = BKE_editmesh_from_object(obedit);
|
||||
BMesh *bm = em->bm;
|
||||
BMIter iter;
|
||||
BMWalker walker;
|
||||
BMEditMesh *em = BKE_editmesh_from_object(obedit);
|
||||
BMesh *bm = em->bm;
|
||||
BMIter iter;
|
||||
BMWalker walker;
|
||||
|
||||
int delimit = delimit_init;
|
||||
int delimit = delimit_init;
|
||||
|
||||
select_linked_delimit_validate(bm, &delimit);
|
||||
select_linked_delimit_validate(bm, &delimit);
|
||||
|
||||
if (delimit) {
|
||||
select_linked_delimit_begin(em->bm, delimit);
|
||||
}
|
||||
|
||||
if (em->selectmode & SCE_SELECT_VERTEX) {
|
||||
BMVert *v;
|
||||
|
||||
BM_ITER_MESH (v, &iter, em->bm, BM_VERTS_OF_MESH) {
|
||||
BM_elem_flag_set(v, BM_ELEM_TAG, BM_elem_flag_test(v, BM_ELEM_SELECT));
|
||||
if (delimit) {
|
||||
select_linked_delimit_begin(em->bm, delimit);
|
||||
}
|
||||
|
||||
/* exclude all delimited verts */
|
||||
if (delimit) {
|
||||
if (em->selectmode & SCE_SELECT_VERTEX) {
|
||||
BMVert *v;
|
||||
|
||||
BM_ITER_MESH (v, &iter, em->bm, BM_VERTS_OF_MESH) {
|
||||
BM_elem_flag_set(v, BM_ELEM_TAG, BM_elem_flag_test(v, BM_ELEM_SELECT));
|
||||
}
|
||||
|
||||
/* exclude all delimited verts */
|
||||
if (delimit) {
|
||||
BMEdge *e;
|
||||
BM_ITER_MESH (e, &iter, em->bm, BM_EDGES_OF_MESH) {
|
||||
if (!BMO_edge_flag_test(bm, e, BMO_ELE_TAG)) {
|
||||
BM_elem_flag_disable(e->v1, BM_ELEM_TAG);
|
||||
BM_elem_flag_disable(e->v2, BM_ELEM_TAG);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BMW_init(&walker, em->bm, delimit ? BMW_LOOP_SHELL_WIRE : BMW_VERT_SHELL,
|
||||
BMW_MASK_NOP, delimit ? BMO_ELE_TAG : BMW_MASK_NOP, BMW_MASK_NOP,
|
||||
BMW_FLAG_TEST_HIDDEN,
|
||||
BMW_NIL_LAY);
|
||||
|
||||
if (delimit) {
|
||||
BM_ITER_MESH (v, &iter, em->bm, BM_VERTS_OF_MESH) {
|
||||
if (BM_elem_flag_test(v, BM_ELEM_TAG)) {
|
||||
BMElem *ele_walk;
|
||||
BMW_ITER (ele_walk, &walker, v) {
|
||||
if (ele_walk->head.htype == BM_LOOP) {
|
||||
BMVert *v_step = ((BMLoop *)ele_walk)->v;
|
||||
BM_vert_select_set(em->bm, v_step, true);
|
||||
BM_elem_flag_disable(v_step, BM_ELEM_TAG);
|
||||
}
|
||||
else {
|
||||
BMEdge *e_step = (BMEdge *)ele_walk;
|
||||
BLI_assert(ele_walk->head.htype == BM_EDGE);
|
||||
BM_edge_select_set(em->bm, e_step, true);
|
||||
BM_elem_flag_disable(e_step->v1, BM_ELEM_TAG);
|
||||
BM_elem_flag_disable(e_step->v2, BM_ELEM_TAG);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
BM_ITER_MESH (v, &iter, em->bm, BM_VERTS_OF_MESH) {
|
||||
if (BM_elem_flag_test(v, BM_ELEM_TAG)) {
|
||||
BMEdge *e_walk;
|
||||
BMW_ITER (e_walk, &walker, v) {
|
||||
BM_edge_select_set(em->bm, e_walk, true);
|
||||
BM_elem_flag_disable(e_walk, BM_ELEM_TAG);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BMW_end(&walker);
|
||||
|
||||
EDBM_selectmode_flush(em);
|
||||
}
|
||||
else if (em->selectmode & SCE_SELECT_EDGE) {
|
||||
BMEdge *e;
|
||||
BM_ITER_MESH (e, &iter, em->bm, BM_EDGES_OF_MESH) {
|
||||
if (!BMO_edge_flag_test(bm, e, BMO_ELE_TAG)) {
|
||||
BM_elem_flag_disable(e->v1, BM_ELEM_TAG);
|
||||
BM_elem_flag_disable(e->v2, BM_ELEM_TAG);
|
||||
|
||||
if (delimit) {
|
||||
BM_ITER_MESH (e, &iter, em->bm, BM_EDGES_OF_MESH) {
|
||||
BM_elem_flag_set(
|
||||
e, BM_ELEM_TAG,
|
||||
(BM_elem_flag_test(e, BM_ELEM_SELECT) && BMO_edge_flag_test(bm, e, BMO_ELE_TAG)));
|
||||
}
|
||||
}
|
||||
else {
|
||||
BM_ITER_MESH (e, &iter, em->bm, BM_EDGES_OF_MESH) {
|
||||
BM_elem_flag_set(e, BM_ELEM_TAG, BM_elem_flag_test(e, BM_ELEM_SELECT));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BMW_init(&walker, em->bm, delimit ? BMW_LOOP_SHELL_WIRE : BMW_VERT_SHELL,
|
||||
BMW_MASK_NOP, delimit ? BMO_ELE_TAG : BMW_MASK_NOP, BMW_MASK_NOP,
|
||||
BMW_FLAG_TEST_HIDDEN,
|
||||
BMW_NIL_LAY);
|
||||
BMW_init(&walker, em->bm, delimit ? BMW_LOOP_SHELL_WIRE : BMW_VERT_SHELL,
|
||||
BMW_MASK_NOP, delimit ? BMO_ELE_TAG : BMW_MASK_NOP, BMW_MASK_NOP,
|
||||
BMW_FLAG_TEST_HIDDEN,
|
||||
BMW_NIL_LAY);
|
||||
|
||||
if (delimit) {
|
||||
BM_ITER_MESH (v, &iter, em->bm, BM_VERTS_OF_MESH) {
|
||||
if (BM_elem_flag_test(v, BM_ELEM_TAG)) {
|
||||
BMElem *ele_walk;
|
||||
BMW_ITER (ele_walk, &walker, v) {
|
||||
if (ele_walk->head.htype == BM_LOOP) {
|
||||
BMVert *v_step = ((BMLoop *)ele_walk)->v;
|
||||
BM_vert_select_set(em->bm, v_step, true);
|
||||
BM_elem_flag_disable(v_step, BM_ELEM_TAG);
|
||||
}
|
||||
else {
|
||||
BMEdge *e_step = (BMEdge *)ele_walk;
|
||||
BLI_assert(ele_walk->head.htype == BM_EDGE);
|
||||
BM_edge_select_set(em->bm, e_step, true);
|
||||
BM_elem_flag_disable(e_step->v1, BM_ELEM_TAG);
|
||||
BM_elem_flag_disable(e_step->v2, BM_ELEM_TAG);
|
||||
if (delimit) {
|
||||
BM_ITER_MESH (e, &iter, em->bm, BM_EDGES_OF_MESH) {
|
||||
if (BM_elem_flag_test(e, BM_ELEM_TAG)) {
|
||||
BMElem *ele_walk;
|
||||
BMW_ITER (ele_walk, &walker, e) {
|
||||
if (ele_walk->head.htype == BM_LOOP) {
|
||||
BMLoop *l_step = (BMLoop *)ele_walk;
|
||||
BM_edge_select_set(em->bm, l_step->e, true);
|
||||
BM_edge_select_set(em->bm, l_step->prev->e, true);
|
||||
BM_elem_flag_disable(l_step->e, BM_ELEM_TAG);
|
||||
}
|
||||
else {
|
||||
BMEdge *e_step = (BMEdge *)ele_walk;
|
||||
BLI_assert(ele_walk->head.htype == BM_EDGE);
|
||||
BM_edge_select_set(em->bm, e_step, true);
|
||||
BM_elem_flag_disable(e_step, BM_ELEM_TAG);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
BM_ITER_MESH (e, &iter, em->bm, BM_EDGES_OF_MESH) {
|
||||
if (BM_elem_flag_test(e, BM_ELEM_TAG)) {
|
||||
BMEdge *e_walk;
|
||||
BMW_ITER (e_walk, &walker, e) {
|
||||
BM_edge_select_set(em->bm, e_walk, true);
|
||||
BM_elem_flag_disable(e_walk, BM_ELEM_TAG);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BMW_end(&walker);
|
||||
|
||||
EDBM_selectmode_flush(em);
|
||||
}
|
||||
else {
|
||||
BM_ITER_MESH (v, &iter, em->bm, BM_VERTS_OF_MESH) {
|
||||
if (BM_elem_flag_test(v, BM_ELEM_TAG)) {
|
||||
BMEdge *e_walk;
|
||||
BMW_ITER (e_walk, &walker, v) {
|
||||
BM_edge_select_set(em->bm, e_walk, true);
|
||||
BM_elem_flag_disable(e_walk, BM_ELEM_TAG);
|
||||
BMFace *f;
|
||||
|
||||
BM_ITER_MESH (f, &iter, em->bm, BM_FACES_OF_MESH) {
|
||||
BM_elem_flag_set(f, BM_ELEM_TAG, BM_elem_flag_test(f, BM_ELEM_SELECT));
|
||||
}
|
||||
|
||||
BMW_init(&walker, bm, BMW_ISLAND,
|
||||
BMW_MASK_NOP, delimit ? BMO_ELE_TAG : BMW_MASK_NOP, BMW_MASK_NOP,
|
||||
BMW_FLAG_TEST_HIDDEN,
|
||||
BMW_NIL_LAY);
|
||||
|
||||
BM_ITER_MESH (f, &iter, em->bm, BM_FACES_OF_MESH) {
|
||||
if (BM_elem_flag_test(f, BM_ELEM_TAG)) {
|
||||
BMFace *f_walk;
|
||||
BMW_ITER (f_walk, &walker, f) {
|
||||
BM_face_select_set(bm, f_walk, true);
|
||||
BM_elem_flag_disable(f_walk, BM_ELEM_TAG);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BMW_end(&walker);
|
||||
}
|
||||
|
||||
BMW_end(&walker);
|
||||
|
||||
EDBM_selectmode_flush(em);
|
||||
}
|
||||
else if (em->selectmode & SCE_SELECT_EDGE) {
|
||||
BMEdge *e;
|
||||
|
||||
if (delimit) {
|
||||
BM_ITER_MESH (e, &iter, em->bm, BM_EDGES_OF_MESH) {
|
||||
BM_elem_flag_set(
|
||||
e, BM_ELEM_TAG,
|
||||
(BM_elem_flag_test(e, BM_ELEM_SELECT) && BMO_edge_flag_test(bm, e, BMO_ELE_TAG)));
|
||||
}
|
||||
}
|
||||
else {
|
||||
BM_ITER_MESH (e, &iter, em->bm, BM_EDGES_OF_MESH) {
|
||||
BM_elem_flag_set(e, BM_ELEM_TAG, BM_elem_flag_test(e, BM_ELEM_SELECT));
|
||||
}
|
||||
select_linked_delimit_end(em);
|
||||
}
|
||||
|
||||
BMW_init(&walker, em->bm, delimit ? BMW_LOOP_SHELL_WIRE : BMW_VERT_SHELL,
|
||||
BMW_MASK_NOP, delimit ? BMO_ELE_TAG : BMW_MASK_NOP, BMW_MASK_NOP,
|
||||
BMW_FLAG_TEST_HIDDEN,
|
||||
BMW_NIL_LAY);
|
||||
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
|
||||
|
||||
if (delimit) {
|
||||
BM_ITER_MESH (e, &iter, em->bm, BM_EDGES_OF_MESH) {
|
||||
if (BM_elem_flag_test(e, BM_ELEM_TAG)) {
|
||||
BMElem *ele_walk;
|
||||
BMW_ITER (ele_walk, &walker, e) {
|
||||
if (ele_walk->head.htype == BM_LOOP) {
|
||||
BMLoop *l_step = (BMLoop *)ele_walk;
|
||||
BM_edge_select_set(em->bm, l_step->e, true);
|
||||
BM_edge_select_set(em->bm, l_step->prev->e, true);
|
||||
BM_elem_flag_disable(l_step->e, BM_ELEM_TAG);
|
||||
}
|
||||
else {
|
||||
BMEdge *e_step = (BMEdge *)ele_walk;
|
||||
BLI_assert(ele_walk->head.htype == BM_EDGE);
|
||||
BM_edge_select_set(em->bm, e_step, true);
|
||||
BM_elem_flag_disable(e_step, BM_ELEM_TAG);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
BM_ITER_MESH (e, &iter, em->bm, BM_EDGES_OF_MESH) {
|
||||
if (BM_elem_flag_test(e, BM_ELEM_TAG)) {
|
||||
BMEdge *e_walk;
|
||||
BMW_ITER (e_walk, &walker, e) {
|
||||
BM_edge_select_set(em->bm, e_walk, true);
|
||||
BM_elem_flag_disable(e_walk, BM_ELEM_TAG);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BMW_end(&walker);
|
||||
|
||||
EDBM_selectmode_flush(em);
|
||||
}
|
||||
else {
|
||||
BMFace *f;
|
||||
|
||||
BM_ITER_MESH (f, &iter, em->bm, BM_FACES_OF_MESH) {
|
||||
BM_elem_flag_set(f, BM_ELEM_TAG, BM_elem_flag_test(f, BM_ELEM_SELECT));
|
||||
}
|
||||
|
||||
BMW_init(&walker, bm, BMW_ISLAND,
|
||||
BMW_MASK_NOP, delimit ? BMO_ELE_TAG : BMW_MASK_NOP, BMW_MASK_NOP,
|
||||
BMW_FLAG_TEST_HIDDEN,
|
||||
BMW_NIL_LAY);
|
||||
|
||||
BM_ITER_MESH (f, &iter, em->bm, BM_FACES_OF_MESH) {
|
||||
if (BM_elem_flag_test(f, BM_ELEM_TAG)) {
|
||||
BMFace *f_walk;
|
||||
BMW_ITER (f_walk, &walker, f) {
|
||||
BM_face_select_set(bm, f_walk, true);
|
||||
BM_elem_flag_disable(f_walk, BM_ELEM_TAG);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BMW_end(&walker);
|
||||
}
|
||||
|
||||
if (delimit) {
|
||||
select_linked_delimit_end(em);
|
||||
}
|
||||
|
||||
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
|
||||
|
||||
} /* objects */
|
||||
|
||||
MEM_SAFE_FREE(objects);
|
||||
|
||||
|
||||
@@ -99,30 +99,30 @@ static int edbm_subdivide_exec(bContext *C, wmOperator *op)
|
||||
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, &objects_len);
|
||||
|
||||
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
|
||||
Object *obedit = objects[ob_index];
|
||||
Object *obedit = objects[ob_index];
|
||||
|
||||
BMEditMesh *em = BKE_editmesh_from_object(obedit);
|
||||
const int cuts = RNA_int_get(op->ptr, "number_cuts");
|
||||
float smooth = RNA_float_get(op->ptr, "smoothness");
|
||||
const float fractal = RNA_float_get(op->ptr, "fractal") / 2.5f;
|
||||
const float along_normal = RNA_float_get(op->ptr, "fractal_along_normal");
|
||||
BMEditMesh *em = BKE_editmesh_from_object(obedit);
|
||||
const int cuts = RNA_int_get(op->ptr, "number_cuts");
|
||||
float smooth = RNA_float_get(op->ptr, "smoothness");
|
||||
const float fractal = RNA_float_get(op->ptr, "fractal") / 2.5f;
|
||||
const float along_normal = RNA_float_get(op->ptr, "fractal_along_normal");
|
||||
|
||||
if (RNA_boolean_get(op->ptr, "quadtri") &&
|
||||
RNA_enum_get(op->ptr, "quadcorner") == SUBD_CORNER_STRAIGHT_CUT)
|
||||
{
|
||||
RNA_enum_set(op->ptr, "quadcorner", SUBD_CORNER_INNERVERT);
|
||||
}
|
||||
if (RNA_boolean_get(op->ptr, "quadtri") &&
|
||||
RNA_enum_get(op->ptr, "quadcorner") == SUBD_CORNER_STRAIGHT_CUT)
|
||||
{
|
||||
RNA_enum_set(op->ptr, "quadcorner", SUBD_CORNER_INNERVERT);
|
||||
}
|
||||
|
||||
BM_mesh_esubdivide(
|
||||
em->bm, BM_ELEM_SELECT,
|
||||
smooth, SUBD_FALLOFF_LIN, false,
|
||||
fractal, along_normal,
|
||||
cuts,
|
||||
SUBDIV_SELECT_ORIG, RNA_enum_get(op->ptr, "quadcorner"),
|
||||
RNA_boolean_get(op->ptr, "quadtri"), true, false,
|
||||
RNA_int_get(op->ptr, "seed"));
|
||||
BM_mesh_esubdivide(
|
||||
em->bm, BM_ELEM_SELECT,
|
||||
smooth, SUBD_FALLOFF_LIN, false,
|
||||
fractal, along_normal,
|
||||
cuts,
|
||||
SUBDIV_SELECT_ORIG, RNA_enum_get(op->ptr, "quadcorner"),
|
||||
RNA_boolean_get(op->ptr, "quadtri"), true, false,
|
||||
RNA_int_get(op->ptr, "seed"));
|
||||
|
||||
EDBM_update_generic(em, true, true);
|
||||
EDBM_update_generic(em, true, true);
|
||||
}
|
||||
|
||||
MEM_SAFE_FREE(objects);
|
||||
@@ -392,44 +392,44 @@ static int edbm_delete_exec(bContext *C, wmOperator *op)
|
||||
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, &objects_len);
|
||||
|
||||
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
|
||||
Object *obedit = objects[ob_index];
|
||||
BMEditMesh *em = BKE_editmesh_from_object(obedit);
|
||||
const int type = RNA_enum_get(op->ptr, "type");
|
||||
Object *obedit = objects[ob_index];
|
||||
BMEditMesh *em = BKE_editmesh_from_object(obedit);
|
||||
const int type = RNA_enum_get(op->ptr, "type");
|
||||
|
||||
switch (type) {
|
||||
case MESH_DELETE_VERT:
|
||||
if (!EDBM_op_callf(em, op, "delete geom=%hv context=%i", BM_ELEM_SELECT, DEL_VERTS)) /* Erase Vertices */
|
||||
return OPERATOR_CANCELLED;
|
||||
break;
|
||||
case MESH_DELETE_EDGE:
|
||||
if (!EDBM_op_callf(em, op, "delete geom=%he context=%i", BM_ELEM_SELECT, DEL_EDGES)) /* Erase Edges */
|
||||
return OPERATOR_CANCELLED;
|
||||
break;
|
||||
case MESH_DELETE_FACE:
|
||||
if (!EDBM_op_callf(em, op, "delete geom=%hf context=%i", BM_ELEM_SELECT, DEL_FACES)) /* Erase Faces */
|
||||
return OPERATOR_CANCELLED;
|
||||
break;
|
||||
case MESH_DELETE_EDGE_FACE:
|
||||
/* Edges and Faces */
|
||||
if (!EDBM_op_callf(em, op, "delete geom=%hef context=%i", BM_ELEM_SELECT, DEL_EDGESFACES))
|
||||
return OPERATOR_CANCELLED;
|
||||
break;
|
||||
case MESH_DELETE_ONLY_FACE:
|
||||
/* Only faces. */
|
||||
if (!EDBM_op_callf(em, op, "delete geom=%hf context=%i", BM_ELEM_SELECT, DEL_ONLYFACES))
|
||||
return OPERATOR_CANCELLED;
|
||||
break;
|
||||
default:
|
||||
BLI_assert(0);
|
||||
break;
|
||||
}
|
||||
|
||||
EDBM_flag_disable_all(em, BM_ELEM_SELECT);
|
||||
|
||||
EDBM_update_generic(em, true, true);
|
||||
|
||||
switch (type) {
|
||||
case MESH_DELETE_VERT:
|
||||
if (!EDBM_op_callf(em, op, "delete geom=%hv context=%i", BM_ELEM_SELECT, DEL_VERTS)) /* Erase Vertices */
|
||||
return OPERATOR_CANCELLED;
|
||||
break;
|
||||
case MESH_DELETE_EDGE:
|
||||
if (!EDBM_op_callf(em, op, "delete geom=%he context=%i", BM_ELEM_SELECT, DEL_EDGES)) /* Erase Edges */
|
||||
return OPERATOR_CANCELLED;
|
||||
break;
|
||||
case MESH_DELETE_FACE:
|
||||
if (!EDBM_op_callf(em, op, "delete geom=%hf context=%i", BM_ELEM_SELECT, DEL_FACES)) /* Erase Faces */
|
||||
return OPERATOR_CANCELLED;
|
||||
break;
|
||||
case MESH_DELETE_EDGE_FACE:
|
||||
/* Edges and Faces */
|
||||
if (!EDBM_op_callf(em, op, "delete geom=%hef context=%i", BM_ELEM_SELECT, DEL_EDGESFACES))
|
||||
return OPERATOR_CANCELLED;
|
||||
break;
|
||||
case MESH_DELETE_ONLY_FACE:
|
||||
/* Only faces. */
|
||||
if (!EDBM_op_callf(em, op, "delete geom=%hf context=%i", BM_ELEM_SELECT, DEL_ONLYFACES))
|
||||
return OPERATOR_CANCELLED;
|
||||
break;
|
||||
default:
|
||||
BLI_assert(0);
|
||||
break;
|
||||
}
|
||||
|
||||
EDBM_flag_disable_all(em, BM_ELEM_SELECT);
|
||||
|
||||
EDBM_update_generic(em, true, true);
|
||||
|
||||
} /* objects */
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
@@ -499,53 +499,53 @@ static int edbm_delete_loose_exec(bContext *C, wmOperator *op)
|
||||
const bool use_faces = (RNA_boolean_get(op->ptr, "use_faces") && totelem_old_sel[2]);
|
||||
|
||||
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
|
||||
Object *obedit = objects[ob_index];
|
||||
Object *obedit = objects[ob_index];
|
||||
|
||||
BMEditMesh *em = BKE_editmesh_from_object(obedit);
|
||||
BMesh *bm = em->bm;
|
||||
BMIter iter;
|
||||
BMEditMesh *em = BKE_editmesh_from_object(obedit);
|
||||
BMesh *bm = em->bm;
|
||||
BMIter iter;
|
||||
|
||||
BM_mesh_elem_hflag_disable_all(bm, BM_VERT | BM_EDGE | BM_FACE, BM_ELEM_TAG, false);
|
||||
BM_mesh_elem_hflag_disable_all(bm, BM_VERT | BM_EDGE | BM_FACE, BM_ELEM_TAG, false);
|
||||
|
||||
if (use_faces) {
|
||||
BMFace *f;
|
||||
if (use_faces) {
|
||||
BMFace *f;
|
||||
|
||||
BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
|
||||
if (BM_elem_flag_test(f, BM_ELEM_SELECT)) {
|
||||
BM_elem_flag_set(f, BM_ELEM_TAG, bm_face_is_loose(f));
|
||||
BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
|
||||
if (BM_elem_flag_test(f, BM_ELEM_SELECT)) {
|
||||
BM_elem_flag_set(f, BM_ELEM_TAG, bm_face_is_loose(f));
|
||||
}
|
||||
}
|
||||
|
||||
BM_mesh_delete_hflag_context(bm, BM_ELEM_TAG, DEL_FACES);
|
||||
}
|
||||
|
||||
BM_mesh_delete_hflag_context(bm, BM_ELEM_TAG, DEL_FACES);
|
||||
}
|
||||
if (use_edges) {
|
||||
BMEdge *e;
|
||||
|
||||
if (use_edges) {
|
||||
BMEdge *e;
|
||||
|
||||
BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
|
||||
if (BM_elem_flag_test(e, BM_ELEM_SELECT)) {
|
||||
BM_elem_flag_set(e, BM_ELEM_TAG, BM_edge_is_wire(e));
|
||||
BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
|
||||
if (BM_elem_flag_test(e, BM_ELEM_SELECT)) {
|
||||
BM_elem_flag_set(e, BM_ELEM_TAG, BM_edge_is_wire(e));
|
||||
}
|
||||
}
|
||||
|
||||
BM_mesh_delete_hflag_context(bm, BM_ELEM_TAG, DEL_EDGES);
|
||||
}
|
||||
|
||||
BM_mesh_delete_hflag_context(bm, BM_ELEM_TAG, DEL_EDGES);
|
||||
}
|
||||
if (use_verts) {
|
||||
BMVert *v;
|
||||
|
||||
if (use_verts) {
|
||||
BMVert *v;
|
||||
|
||||
BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
|
||||
if (BM_elem_flag_test(v, BM_ELEM_SELECT)) {
|
||||
BM_elem_flag_set(v, BM_ELEM_TAG, (v->e == NULL));
|
||||
BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
|
||||
if (BM_elem_flag_test(v, BM_ELEM_SELECT)) {
|
||||
BM_elem_flag_set(v, BM_ELEM_TAG, (v->e == NULL));
|
||||
}
|
||||
}
|
||||
|
||||
BM_mesh_delete_hflag_context(bm, BM_ELEM_TAG, DEL_VERTS);
|
||||
}
|
||||
|
||||
BM_mesh_delete_hflag_context(bm, BM_ELEM_TAG, DEL_VERTS);
|
||||
}
|
||||
EDBM_flag_disable_all(em, BM_ELEM_SELECT);
|
||||
|
||||
EDBM_flag_disable_all(em, BM_ELEM_SELECT);
|
||||
|
||||
EDBM_update_generic(em, true, true);
|
||||
EDBM_update_generic(em, true, true);
|
||||
}
|
||||
|
||||
int totelem_new[3];
|
||||
@@ -4136,34 +4136,34 @@ static int edbm_quads_convert_to_tris_exec(bContext *C, wmOperator *op)
|
||||
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, &objects_len);
|
||||
|
||||
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
|
||||
Object *obedit = objects[ob_index];
|
||||
Object *obedit = objects[ob_index];
|
||||
|
||||
BMEditMesh *em = BKE_editmesh_from_object(obedit);
|
||||
BMOperator bmop;
|
||||
BMOIter oiter;
|
||||
BMFace *f;
|
||||
BMEditMesh *em = BKE_editmesh_from_object(obedit);
|
||||
BMOperator bmop;
|
||||
BMOIter oiter;
|
||||
BMFace *f;
|
||||
|
||||
EDBM_op_init(em, &bmop, op, "triangulate faces=%hf quad_method=%i ngon_method=%i", BM_ELEM_SELECT, quad_method, ngon_method);
|
||||
BMO_op_exec(em->bm, &bmop);
|
||||
EDBM_op_init(em, &bmop, op, "triangulate faces=%hf quad_method=%i ngon_method=%i", BM_ELEM_SELECT, quad_method, ngon_method);
|
||||
BMO_op_exec(em->bm, &bmop);
|
||||
|
||||
/* select the output */
|
||||
BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "faces.out", BM_FACE, BM_ELEM_SELECT, true);
|
||||
/* select the output */
|
||||
BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "faces.out", BM_FACE, BM_ELEM_SELECT, true);
|
||||
|
||||
/* remove the doubles */
|
||||
BMO_ITER (f, &oiter, bmop.slots_out, "face_map_double.out", BM_FACE) {
|
||||
BM_face_kill(em->bm, f);
|
||||
}
|
||||
/* remove the doubles */
|
||||
BMO_ITER (f, &oiter, bmop.slots_out, "face_map_double.out", BM_FACE) {
|
||||
BM_face_kill(em->bm, f);
|
||||
}
|
||||
|
||||
EDBM_selectmode_flush(em);
|
||||
EDBM_selectmode_flush(em);
|
||||
|
||||
// XXX, TODO
|
||||
#if 0
|
||||
if (!EDBM_op_finish(em, &bmop, op, true)) {
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
#endif
|
||||
// XXX, TODO
|
||||
#if 0
|
||||
if (!EDBM_op_finish(em, &bmop, op, true)) {
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
#endif
|
||||
|
||||
EDBM_update_generic(em, true, true);
|
||||
EDBM_update_generic(em, true, true);
|
||||
}
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
@@ -4212,53 +4212,53 @@ static int edbm_tris_convert_to_quads_exec(bContext *C, wmOperator *op)
|
||||
}
|
||||
|
||||
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
|
||||
Object *obedit = objects[ob_index];
|
||||
Object *obedit = objects[ob_index];
|
||||
|
||||
BMEditMesh *em = BKE_editmesh_from_object(obedit);
|
||||
bool do_seam, do_sharp, do_uvs, do_vcols, do_materials;
|
||||
float angle_face_threshold, angle_shape_threshold;
|
||||
PropertyRNA *prop;
|
||||
BMEditMesh *em = BKE_editmesh_from_object(obedit);
|
||||
bool do_seam, do_sharp, do_uvs, do_vcols, do_materials;
|
||||
float angle_face_threshold, angle_shape_threshold;
|
||||
PropertyRNA *prop;
|
||||
|
||||
/* When joining exactly 2 faces, no limit.
|
||||
* this is useful for one off joins while editing. */
|
||||
prop = RNA_struct_find_property(op->ptr, "face_threshold");
|
||||
if (is_face_pair &&
|
||||
(RNA_property_is_set(op->ptr, prop) == false))
|
||||
{
|
||||
angle_face_threshold = DEG2RADF(180.0f);
|
||||
}
|
||||
else {
|
||||
angle_face_threshold = RNA_property_float_get(op->ptr, prop);
|
||||
}
|
||||
/* When joining exactly 2 faces, no limit.
|
||||
* this is useful for one off joins while editing. */
|
||||
prop = RNA_struct_find_property(op->ptr, "face_threshold");
|
||||
if (is_face_pair &&
|
||||
(RNA_property_is_set(op->ptr, prop) == false))
|
||||
{
|
||||
angle_face_threshold = DEG2RADF(180.0f);
|
||||
}
|
||||
else {
|
||||
angle_face_threshold = RNA_property_float_get(op->ptr, prop);
|
||||
}
|
||||
|
||||
prop = RNA_struct_find_property(op->ptr, "shape_threshold");
|
||||
if (is_face_pair &&
|
||||
(RNA_property_is_set(op->ptr, prop) == false))
|
||||
{
|
||||
angle_shape_threshold = DEG2RADF(180.0f);
|
||||
}
|
||||
else {
|
||||
angle_shape_threshold = RNA_property_float_get(op->ptr, prop);
|
||||
}
|
||||
prop = RNA_struct_find_property(op->ptr, "shape_threshold");
|
||||
if (is_face_pair &&
|
||||
(RNA_property_is_set(op->ptr, prop) == false))
|
||||
{
|
||||
angle_shape_threshold = DEG2RADF(180.0f);
|
||||
}
|
||||
else {
|
||||
angle_shape_threshold = RNA_property_float_get(op->ptr, prop);
|
||||
}
|
||||
|
||||
do_seam = RNA_boolean_get(op->ptr, "seam");
|
||||
do_sharp = RNA_boolean_get(op->ptr, "sharp");
|
||||
do_uvs = RNA_boolean_get(op->ptr, "uvs");
|
||||
do_vcols = RNA_boolean_get(op->ptr, "vcols");
|
||||
do_materials = RNA_boolean_get(op->ptr, "materials");
|
||||
do_seam = RNA_boolean_get(op->ptr, "seam");
|
||||
do_sharp = RNA_boolean_get(op->ptr, "sharp");
|
||||
do_uvs = RNA_boolean_get(op->ptr, "uvs");
|
||||
do_vcols = RNA_boolean_get(op->ptr, "vcols");
|
||||
do_materials = RNA_boolean_get(op->ptr, "materials");
|
||||
|
||||
if (!EDBM_op_call_and_selectf(
|
||||
em, op,
|
||||
"faces.out", true,
|
||||
"join_triangles faces=%hf angle_face_threshold=%f angle_shape_threshold=%f "
|
||||
"cmp_seam=%b cmp_sharp=%b cmp_uvs=%b cmp_vcols=%b cmp_materials=%b",
|
||||
BM_ELEM_SELECT, angle_face_threshold, angle_shape_threshold,
|
||||
do_seam, do_sharp, do_uvs, do_vcols, do_materials))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (!EDBM_op_call_and_selectf(
|
||||
em, op,
|
||||
"faces.out", true,
|
||||
"join_triangles faces=%hf angle_face_threshold=%f angle_shape_threshold=%f "
|
||||
"cmp_seam=%b cmp_sharp=%b cmp_uvs=%b cmp_vcols=%b cmp_materials=%b",
|
||||
BM_ELEM_SELECT, angle_face_threshold, angle_shape_threshold,
|
||||
do_seam, do_sharp, do_uvs, do_vcols, do_materials))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
EDBM_update_generic(em, true, true);
|
||||
EDBM_update_generic(em, true, true);
|
||||
}
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
@@ -4805,26 +4805,26 @@ static int edbm_dissolve_degenerate_exec(bContext *C, wmOperator *op)
|
||||
const float thresh = RNA_float_get(op->ptr, "threshold");
|
||||
|
||||
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
|
||||
Object *obedit = objects[ob_index];
|
||||
BMEditMesh *em = BKE_editmesh_from_object(obedit);
|
||||
BMesh *bm = em->bm;
|
||||
Object *obedit = objects[ob_index];
|
||||
BMEditMesh *em = BKE_editmesh_from_object(obedit);
|
||||
BMesh *bm = em->bm;
|
||||
|
||||
if (!EDBM_op_callf(
|
||||
em, op,
|
||||
"dissolve_degenerate edges=%he dist=%f",
|
||||
BM_ELEM_SELECT, thresh))
|
||||
{
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
if (!EDBM_op_callf(
|
||||
em, op,
|
||||
"dissolve_degenerate edges=%he dist=%f",
|
||||
BM_ELEM_SELECT, thresh))
|
||||
{
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
/* tricky to maintain correct selection here, so just flush up from verts */
|
||||
EDBM_select_flush(em);
|
||||
/* tricky to maintain correct selection here, so just flush up from verts */
|
||||
EDBM_select_flush(em);
|
||||
|
||||
EDBM_update_generic(em, true, true);
|
||||
EDBM_update_generic(em, true, true);
|
||||
|
||||
totelem_new[0] += bm->totvert;
|
||||
totelem_new[1] += bm->totedge;
|
||||
totelem_new[2] += bm->totface;
|
||||
totelem_new[0] += bm->totvert;
|
||||
totelem_new[1] += bm->totedge;
|
||||
totelem_new[2] += bm->totface;
|
||||
}
|
||||
|
||||
edbm_report_delete_info(op->reports, totelem_old, totelem_new);
|
||||
|
||||
@@ -213,42 +213,42 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
|
||||
uint objects_len;
|
||||
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, &objects_len);
|
||||
for (uint i = 0; i < objects_len; i++) {
|
||||
Object *ob = objects[i];
|
||||
arm = ob->data;
|
||||
Object *ob = objects[i];
|
||||
arm = ob->data;
|
||||
|
||||
/* Attention: X-Axis Mirroring is also handled here... */
|
||||
for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
|
||||
/* first and foremost, bone must be visible and selected */
|
||||
if (EBONE_VISIBLE(arm, ebone)) {
|
||||
/* Get 'x-axis mirror equivalent' bone if the X-Axis Mirroring option is enabled
|
||||
* so that most users of this data don't need to explicitly check for it themselves.
|
||||
*
|
||||
* We need to make sure that these mirrored copies are not selected, otherwise some
|
||||
* bones will be operated on twice.
|
||||
*/
|
||||
if (arm->flag & ARM_MIRROR_EDIT)
|
||||
flipbone = ED_armature_ebone_get_mirrored(arm->edbo, ebone);
|
||||
|
||||
/* if we're filtering for editable too, use the check for that instead, as it has selection check too */
|
||||
if (editable_bones) {
|
||||
/* only selected + editable */
|
||||
if (EBONE_EDITABLE(ebone)) {
|
||||
/* Attention: X-Axis Mirroring is also handled here... */
|
||||
for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
|
||||
/* first and foremost, bone must be visible and selected */
|
||||
if (EBONE_VISIBLE(arm, ebone)) {
|
||||
/* Get 'x-axis mirror equivalent' bone if the X-Axis Mirroring option is enabled
|
||||
* so that most users of this data don't need to explicitly check for it themselves.
|
||||
*
|
||||
* We need to make sure that these mirrored copies are not selected, otherwise some
|
||||
* bones will be operated on twice.
|
||||
*/
|
||||
if (arm->flag & ARM_MIRROR_EDIT)
|
||||
flipbone = ED_armature_ebone_get_mirrored(arm->edbo, ebone);
|
||||
|
||||
/* if we're filtering for editable too, use the check for that instead, as it has selection check too */
|
||||
if (editable_bones) {
|
||||
/* only selected + editable */
|
||||
if (EBONE_EDITABLE(ebone)) {
|
||||
CTX_data_list_add(result, &arm->id, &RNA_EditBone, ebone);
|
||||
|
||||
if ((flipbone) && !(flipbone->flag & BONE_SELECTED))
|
||||
CTX_data_list_add(result, &arm->id, &RNA_EditBone, flipbone);
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* only include bones if visible */
|
||||
CTX_data_list_add(result, &arm->id, &RNA_EditBone, ebone);
|
||||
|
||||
if ((flipbone) && !(flipbone->flag & BONE_SELECTED))
|
||||
|
||||
if ((flipbone) && EBONE_VISIBLE(arm, flipbone) == 0)
|
||||
CTX_data_list_add(result, &arm->id, &RNA_EditBone, flipbone);
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* only include bones if visible */
|
||||
CTX_data_list_add(result, &arm->id, &RNA_EditBone, ebone);
|
||||
|
||||
if ((flipbone) && EBONE_VISIBLE(arm, flipbone) == 0)
|
||||
CTX_data_list_add(result, &arm->id, &RNA_EditBone, flipbone);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
MEM_freeN(objects);
|
||||
|
||||
CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
|
||||
@@ -264,42 +264,42 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
|
||||
uint objects_len;
|
||||
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, &objects_len);
|
||||
for (uint i = 0; i < objects_len; i++) {
|
||||
Object *ob = objects[i];
|
||||
arm = ob->data;
|
||||
Object *ob = objects[i];
|
||||
arm = ob->data;
|
||||
|
||||
/* Attention: X-Axis Mirroring is also handled here... */
|
||||
for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
|
||||
/* first and foremost, bone must be visible and selected */
|
||||
if (EBONE_VISIBLE(arm, ebone) && (ebone->flag & BONE_SELECTED)) {
|
||||
/* Get 'x-axis mirror equivalent' bone if the X-Axis Mirroring option is enabled
|
||||
* so that most users of this data don't need to explicitly check for it themselves.
|
||||
*
|
||||
* We need to make sure that these mirrored copies are not selected, otherwise some
|
||||
* bones will be operated on twice.
|
||||
*/
|
||||
if (arm->flag & ARM_MIRROR_EDIT)
|
||||
flipbone = ED_armature_ebone_get_mirrored(arm->edbo, ebone);
|
||||
|
||||
/* if we're filtering for editable too, use the check for that instead, as it has selection check too */
|
||||
if (selected_editable_bones) {
|
||||
/* only selected + editable */
|
||||
if (EBONE_EDITABLE(ebone)) {
|
||||
/* Attention: X-Axis Mirroring is also handled here... */
|
||||
for (ebone = arm->edbo->first; ebone; ebone = ebone->next) {
|
||||
/* first and foremost, bone must be visible and selected */
|
||||
if (EBONE_VISIBLE(arm, ebone) && (ebone->flag & BONE_SELECTED)) {
|
||||
/* Get 'x-axis mirror equivalent' bone if the X-Axis Mirroring option is enabled
|
||||
* so that most users of this data don't need to explicitly check for it themselves.
|
||||
*
|
||||
* We need to make sure that these mirrored copies are not selected, otherwise some
|
||||
* bones will be operated on twice.
|
||||
*/
|
||||
if (arm->flag & ARM_MIRROR_EDIT)
|
||||
flipbone = ED_armature_ebone_get_mirrored(arm->edbo, ebone);
|
||||
|
||||
/* if we're filtering for editable too, use the check for that instead, as it has selection check too */
|
||||
if (selected_editable_bones) {
|
||||
/* only selected + editable */
|
||||
if (EBONE_EDITABLE(ebone)) {
|
||||
CTX_data_list_add(result, &arm->id, &RNA_EditBone, ebone);
|
||||
|
||||
if ((flipbone) && !(flipbone->flag & BONE_SELECTED))
|
||||
CTX_data_list_add(result, &arm->id, &RNA_EditBone, flipbone);
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* only include bones if selected */
|
||||
CTX_data_list_add(result, &arm->id, &RNA_EditBone, ebone);
|
||||
|
||||
|
||||
if ((flipbone) && !(flipbone->flag & BONE_SELECTED))
|
||||
CTX_data_list_add(result, &arm->id, &RNA_EditBone, flipbone);
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* only include bones if selected */
|
||||
CTX_data_list_add(result, &arm->id, &RNA_EditBone, ebone);
|
||||
|
||||
if ((flipbone) && !(flipbone->flag & BONE_SELECTED))
|
||||
CTX_data_list_add(result, &arm->id, &RNA_EditBone, flipbone);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
MEM_freeN(objects);
|
||||
|
||||
CTX_data_type_set(result, CTX_DATA_TYPE_COLLECTION);
|
||||
|
||||
@@ -860,31 +860,31 @@ static void view3d_lasso_select(
|
||||
else { /* Edit Mode */
|
||||
|
||||
FOREACH_OBJECT_IN_MODE_BEGIN (eval_ctx.view_layer, ob->mode, ob_iter) {
|
||||
ED_view3d_viewcontext_init_object(vc, ob_iter);
|
||||
ED_view3d_viewcontext_init_object(vc, ob_iter);
|
||||
|
||||
switch (vc->obedit->type) {
|
||||
case OB_MESH:
|
||||
do_lasso_select_mesh(&eval_ctx, vc, mcords, moves, extend, select);
|
||||
break;
|
||||
case OB_CURVE:
|
||||
case OB_SURF:
|
||||
do_lasso_select_curve(vc, mcords, moves, extend, select);
|
||||
break;
|
||||
case OB_LATTICE:
|
||||
do_lasso_select_lattice(vc, mcords, moves, extend, select);
|
||||
break;
|
||||
case OB_ARMATURE:
|
||||
do_lasso_select_armature(vc, mcords, moves, extend, select);
|
||||
break;
|
||||
case OB_MBALL:
|
||||
do_lasso_select_meta(vc, mcords, moves, extend, select);
|
||||
break;
|
||||
default:
|
||||
assert(!"lasso select on incorrect object type");
|
||||
break;
|
||||
}
|
||||
switch (vc->obedit->type) {
|
||||
case OB_MESH:
|
||||
do_lasso_select_mesh(&eval_ctx, vc, mcords, moves, extend, select);
|
||||
break;
|
||||
case OB_CURVE:
|
||||
case OB_SURF:
|
||||
do_lasso_select_curve(vc, mcords, moves, extend, select);
|
||||
break;
|
||||
case OB_LATTICE:
|
||||
do_lasso_select_lattice(vc, mcords, moves, extend, select);
|
||||
break;
|
||||
case OB_ARMATURE:
|
||||
do_lasso_select_armature(vc, mcords, moves, extend, select);
|
||||
break;
|
||||
case OB_MBALL:
|
||||
do_lasso_select_meta(vc, mcords, moves, extend, select);
|
||||
break;
|
||||
default:
|
||||
assert(!"lasso select on incorrect object type");
|
||||
break;
|
||||
}
|
||||
|
||||
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, vc->obedit->data);
|
||||
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, vc->obedit->data);
|
||||
}
|
||||
FOREACH_OBJECT_IN_MODE_END;
|
||||
}
|
||||
@@ -2209,45 +2209,45 @@ static int view3d_borderselect_exec(bContext *C, wmOperator *op)
|
||||
if (vc.obedit) {
|
||||
|
||||
FOREACH_OBJECT_IN_MODE_BEGIN (eval_ctx.view_layer, vc.obedit->mode, ob_iter) {
|
||||
ED_view3d_viewcontext_init_object(&vc, ob_iter);
|
||||
ED_view3d_viewcontext_init_object(&vc, ob_iter);
|
||||
|
||||
switch (vc.obedit->type) {
|
||||
case OB_MESH:
|
||||
vc.em = BKE_editmesh_from_object(vc.obedit);
|
||||
ret |= do_mesh_box_select(&eval_ctx, &vc, &rect, select, extend);
|
||||
if (ret & OPERATOR_FINISHED) {
|
||||
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, vc.obedit->data);
|
||||
}
|
||||
break;
|
||||
case OB_CURVE:
|
||||
case OB_SURF:
|
||||
ret |= do_nurbs_box_select(&vc, &rect, select, extend);
|
||||
if (ret & OPERATOR_FINISHED) {
|
||||
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, vc.obedit->data);
|
||||
}
|
||||
break;
|
||||
case OB_MBALL:
|
||||
ret |= do_meta_box_select(&eval_ctx, &vc, &rect, select, extend);
|
||||
if (ret & OPERATOR_FINISHED) {
|
||||
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, vc.obedit->data);
|
||||
}
|
||||
break;
|
||||
case OB_ARMATURE:
|
||||
ret |= do_armature_box_select(&eval_ctx, &vc, &rect, select, extend);
|
||||
if (ret & OPERATOR_FINISHED) {
|
||||
WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, vc.obedit);
|
||||
}
|
||||
break;
|
||||
case OB_LATTICE:
|
||||
ret |= do_lattice_box_select(&vc, &rect, select, extend);
|
||||
if (ret & OPERATOR_FINISHED) {
|
||||
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, vc.obedit->data);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
assert(!"border select on incorrect object type");
|
||||
break;
|
||||
}
|
||||
switch (vc.obedit->type) {
|
||||
case OB_MESH:
|
||||
vc.em = BKE_editmesh_from_object(vc.obedit);
|
||||
ret |= do_mesh_box_select(&eval_ctx, &vc, &rect, select, extend);
|
||||
if (ret & OPERATOR_FINISHED) {
|
||||
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, vc.obedit->data);
|
||||
}
|
||||
break;
|
||||
case OB_CURVE:
|
||||
case OB_SURF:
|
||||
ret |= do_nurbs_box_select(&vc, &rect, select, extend);
|
||||
if (ret & OPERATOR_FINISHED) {
|
||||
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, vc.obedit->data);
|
||||
}
|
||||
break;
|
||||
case OB_MBALL:
|
||||
ret |= do_meta_box_select(&eval_ctx, &vc, &rect, select, extend);
|
||||
if (ret & OPERATOR_FINISHED) {
|
||||
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, vc.obedit->data);
|
||||
}
|
||||
break;
|
||||
case OB_ARMATURE:
|
||||
ret |= do_armature_box_select(&eval_ctx, &vc, &rect, select, extend);
|
||||
if (ret & OPERATOR_FINISHED) {
|
||||
WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, vc.obedit);
|
||||
}
|
||||
break;
|
||||
case OB_LATTICE:
|
||||
ret |= do_lattice_box_select(&vc, &rect, select, extend);
|
||||
if (ret & OPERATOR_FINISHED) {
|
||||
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, vc.obedit->data);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
assert(!"border select on incorrect object type");
|
||||
break;
|
||||
}
|
||||
}
|
||||
FOREACH_OBJECT_IN_MODE_END;
|
||||
}
|
||||
@@ -2936,29 +2936,29 @@ static int view3d_circle_select_exec(bContext *C, wmOperator *op)
|
||||
view3d_operator_needs_opengl(C);
|
||||
|
||||
FOREACH_OBJECT_IN_MODE_BEGIN (eval_ctx.view_layer, obact->mode, ob_iter) {
|
||||
ED_view3d_viewcontext_init_object(&vc, ob_iter);
|
||||
ED_view3d_viewcontext_init_object(&vc, ob_iter);
|
||||
|
||||
obact = vc.obact;
|
||||
obedit = vc.obedit;
|
||||
obact = vc.obact;
|
||||
obedit = vc.obedit;
|
||||
|
||||
if (CTX_data_edit_object(C)) {
|
||||
obedit_circle_select(&eval_ctx, &vc, select, mval, (float)radius);
|
||||
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obact->data);
|
||||
}
|
||||
else if (BKE_paint_select_face_test(obact)) {
|
||||
paint_facesel_circle_select(&eval_ctx, &vc, select, mval, (float)radius);
|
||||
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obact->data);
|
||||
}
|
||||
else if (BKE_paint_select_vert_test(obact)) {
|
||||
paint_vertsel_circle_select(&eval_ctx, &vc, select, mval, (float)radius);
|
||||
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obact->data);
|
||||
}
|
||||
else if (obact->mode & OB_MODE_POSE) {
|
||||
pose_circle_select(&vc, select, mval, (float)radius);
|
||||
}
|
||||
else {
|
||||
return PE_circle_select(C, select, mval, (float)radius);
|
||||
}
|
||||
if (CTX_data_edit_object(C)) {
|
||||
obedit_circle_select(&eval_ctx, &vc, select, mval, (float)radius);
|
||||
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obact->data);
|
||||
}
|
||||
else if (BKE_paint_select_face_test(obact)) {
|
||||
paint_facesel_circle_select(&eval_ctx, &vc, select, mval, (float)radius);
|
||||
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obact->data);
|
||||
}
|
||||
else if (BKE_paint_select_vert_test(obact)) {
|
||||
paint_vertsel_circle_select(&eval_ctx, &vc, select, mval, (float)radius);
|
||||
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obact->data);
|
||||
}
|
||||
else if (obact->mode & OB_MODE_POSE) {
|
||||
pose_circle_select(&vc, select, mval, (float)radius);
|
||||
}
|
||||
else {
|
||||
return PE_circle_select(C, select, mval, (float)radius);
|
||||
}
|
||||
}
|
||||
FOREACH_OBJECT_IN_MODE_END;
|
||||
}
|
||||
|
||||
@@ -3030,72 +3030,72 @@ static void Bend(TransInfo *t, const int UNUSED(mval[2]))
|
||||
|
||||
/* TODO(campbell): xform, compensate object center. */
|
||||
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
|
||||
TransData *td = tc->data;
|
||||
TransData *td = tc->data;
|
||||
|
||||
float warp_sta_local[3];
|
||||
float warp_end_local[3];
|
||||
float warp_end_radius_local[3];
|
||||
float pivot_local[3];
|
||||
float warp_sta_local[3];
|
||||
float warp_end_local[3];
|
||||
float warp_end_radius_local[3];
|
||||
float pivot_local[3];
|
||||
|
||||
if (t->flag & T_EDIT) {
|
||||
sub_v3_v3v3(warp_sta_local, data->warp_sta, tc->obedit->obmat[3]);
|
||||
sub_v3_v3v3(warp_end_local, data->warp_end, tc->obedit->obmat[3]);
|
||||
sub_v3_v3v3(warp_end_radius_local, warp_end_radius_global, tc->obedit->obmat[3]);
|
||||
sub_v3_v3v3(pivot_local, pivot_global, tc->obedit->obmat[3]);
|
||||
}
|
||||
else {
|
||||
copy_v3_v3(warp_sta_local, data->warp_sta);
|
||||
copy_v3_v3(warp_end_local, data->warp_end);
|
||||
copy_v3_v3(warp_end_radius_local, warp_end_radius_global);
|
||||
copy_v3_v3(pivot_local, pivot_global);
|
||||
}
|
||||
|
||||
for (i = 0; i < tc->data_len; i++, td++) {
|
||||
float mat[3][3];
|
||||
float delta[3];
|
||||
float fac, fac_scaled;
|
||||
|
||||
if (td->flag & TD_NOACTION)
|
||||
break;
|
||||
|
||||
if (td->flag & TD_SKIP)
|
||||
continue;
|
||||
|
||||
if (UNLIKELY(values.angle == 0.0f)) {
|
||||
copy_v3_v3(td->loc, td->iloc);
|
||||
continue;
|
||||
if (t->flag & T_EDIT) {
|
||||
sub_v3_v3v3(warp_sta_local, data->warp_sta, tc->obedit->obmat[3]);
|
||||
sub_v3_v3v3(warp_end_local, data->warp_end, tc->obedit->obmat[3]);
|
||||
sub_v3_v3v3(warp_end_radius_local, warp_end_radius_global, tc->obedit->obmat[3]);
|
||||
sub_v3_v3v3(pivot_local, pivot_global, tc->obedit->obmat[3]);
|
||||
}
|
||||
else {
|
||||
copy_v3_v3(warp_sta_local, data->warp_sta);
|
||||
copy_v3_v3(warp_end_local, data->warp_end);
|
||||
copy_v3_v3(warp_end_radius_local, warp_end_radius_global);
|
||||
copy_v3_v3(pivot_local, pivot_global);
|
||||
}
|
||||
|
||||
copy_v3_v3(vec, td->iloc);
|
||||
mul_m3_v3(td->mtx, vec);
|
||||
for (i = 0; i < tc->data_len; i++, td++) {
|
||||
float mat[3][3];
|
||||
float delta[3];
|
||||
float fac, fac_scaled;
|
||||
|
||||
fac = line_point_factor_v3(vec, warp_sta_local, warp_end_radius_local);
|
||||
if (is_clamp) {
|
||||
CLAMP(fac, 0.0f, 1.0f);
|
||||
if (td->flag & TD_NOACTION)
|
||||
break;
|
||||
|
||||
if (td->flag & TD_SKIP)
|
||||
continue;
|
||||
|
||||
if (UNLIKELY(values.angle == 0.0f)) {
|
||||
copy_v3_v3(td->loc, td->iloc);
|
||||
continue;
|
||||
}
|
||||
|
||||
copy_v3_v3(vec, td->iloc);
|
||||
mul_m3_v3(td->mtx, vec);
|
||||
|
||||
fac = line_point_factor_v3(vec, warp_sta_local, warp_end_radius_local);
|
||||
if (is_clamp) {
|
||||
CLAMP(fac, 0.0f, 1.0f);
|
||||
}
|
||||
|
||||
fac_scaled = fac * td->factor;
|
||||
axis_angle_normalized_to_mat3(mat, data->warp_nor, values.angle * fac_scaled);
|
||||
interp_v3_v3v3(delta, warp_sta_local, warp_end_radius_local, fac_scaled);
|
||||
sub_v3_v3(delta, warp_sta_local);
|
||||
|
||||
/* delta is subtracted, rotation adds back this offset */
|
||||
sub_v3_v3(vec, delta);
|
||||
|
||||
sub_v3_v3(vec, pivot_local);
|
||||
mul_m3_v3(mat, vec);
|
||||
add_v3_v3(vec, pivot_local);
|
||||
|
||||
mul_m3_v3(td->smtx, vec);
|
||||
|
||||
/* rotation */
|
||||
if ((t->flag & T_POINTS) == 0) {
|
||||
ElementRotation(t, tc, td, mat, V3D_AROUND_LOCAL_ORIGINS);
|
||||
}
|
||||
|
||||
/* location */
|
||||
copy_v3_v3(td->loc, vec);
|
||||
}
|
||||
|
||||
fac_scaled = fac * td->factor;
|
||||
axis_angle_normalized_to_mat3(mat, data->warp_nor, values.angle * fac_scaled);
|
||||
interp_v3_v3v3(delta, warp_sta_local, warp_end_radius_local, fac_scaled);
|
||||
sub_v3_v3(delta, warp_sta_local);
|
||||
|
||||
/* delta is subtracted, rotation adds back this offset */
|
||||
sub_v3_v3(vec, delta);
|
||||
|
||||
sub_v3_v3(vec, pivot_local);
|
||||
mul_m3_v3(mat, vec);
|
||||
add_v3_v3(vec, pivot_local);
|
||||
|
||||
mul_m3_v3(td->smtx, vec);
|
||||
|
||||
/* rotation */
|
||||
if ((t->flag & T_POINTS) == 0) {
|
||||
ElementRotation(t, tc, td, mat, V3D_AROUND_LOCAL_ORIGINS);
|
||||
}
|
||||
|
||||
/* location */
|
||||
copy_v3_v3(td->loc, vec);
|
||||
}
|
||||
}
|
||||
|
||||
recalcData(t);
|
||||
@@ -3211,45 +3211,45 @@ static void applyShear(TransInfo *t, const int UNUSED(mval[2]))
|
||||
mul_m3_m3m3(totmat, persinv, tmat);
|
||||
|
||||
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
|
||||
TransData *td = tc->data;
|
||||
for (i = 0; i < tc->data_len; i++, td++) {
|
||||
const float *center, *co;
|
||||
TransData *td = tc->data;
|
||||
for (i = 0; i < tc->data_len; i++, td++) {
|
||||
const float *center, *co;
|
||||
|
||||
if (td->flag & TD_NOACTION)
|
||||
break;
|
||||
|
||||
if (td->flag & TD_SKIP)
|
||||
continue;
|
||||
if (td->flag & TD_NOACTION)
|
||||
break;
|
||||
|
||||
if (t->flag & T_EDIT) {
|
||||
float mat3[3][3];
|
||||
mul_m3_m3m3(mat3, totmat, td->mtx);
|
||||
mul_m3_m3m3(tmat, td->smtx, mat3);
|
||||
}
|
||||
else {
|
||||
copy_m3_m3(tmat, totmat);
|
||||
}
|
||||
if (td->flag & TD_SKIP)
|
||||
continue;
|
||||
|
||||
if (is_local_center) {
|
||||
center = td->center;
|
||||
co = td->loc;
|
||||
}
|
||||
else {
|
||||
center = tc->center_local;
|
||||
co = td->center;
|
||||
}
|
||||
if (t->flag & T_EDIT) {
|
||||
float mat3[3][3];
|
||||
mul_m3_m3m3(mat3, totmat, td->mtx);
|
||||
mul_m3_m3m3(tmat, td->smtx, mat3);
|
||||
}
|
||||
else {
|
||||
copy_m3_m3(tmat, totmat);
|
||||
}
|
||||
|
||||
sub_v3_v3v3(vec, co, center);
|
||||
|
||||
mul_m3_v3(tmat, vec);
|
||||
|
||||
add_v3_v3(vec, center);
|
||||
sub_v3_v3(vec, co);
|
||||
|
||||
mul_v3_fl(vec, td->factor);
|
||||
|
||||
add_v3_v3v3(td->loc, td->iloc, vec);
|
||||
}
|
||||
if (is_local_center) {
|
||||
center = td->center;
|
||||
co = td->loc;
|
||||
}
|
||||
else {
|
||||
center = tc->center_local;
|
||||
co = td->center;
|
||||
}
|
||||
|
||||
sub_v3_v3v3(vec, co, center);
|
||||
|
||||
mul_m3_v3(tmat, vec);
|
||||
|
||||
add_v3_v3(vec, center);
|
||||
sub_v3_v3(vec, co);
|
||||
|
||||
mul_v3_fl(vec, td->factor);
|
||||
|
||||
add_v3_v3v3(td->loc, td->iloc, vec);
|
||||
}
|
||||
}
|
||||
|
||||
recalcData(t);
|
||||
@@ -3496,16 +3496,16 @@ static void applyResize(TransInfo *t, const int UNUSED(mval[2]))
|
||||
headerResize(t, t->values, str);
|
||||
|
||||
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
|
||||
TransData *td = tc->data;
|
||||
for (i = 0; i < tc->data_len; i++, td++) {
|
||||
if (td->flag & TD_NOACTION)
|
||||
break;
|
||||
|
||||
if (td->flag & TD_SKIP)
|
||||
continue;
|
||||
TransData *td = tc->data;
|
||||
for (i = 0; i < tc->data_len; i++, td++) {
|
||||
if (td->flag & TD_NOACTION)
|
||||
break;
|
||||
|
||||
ElementResize(t, tc, td, mat);
|
||||
}
|
||||
if (td->flag & TD_SKIP)
|
||||
continue;
|
||||
|
||||
ElementResize(t, tc, td, mat);
|
||||
}
|
||||
}
|
||||
|
||||
/* evil hack - redo resize if cliping needed */
|
||||
@@ -3517,17 +3517,17 @@ static void applyResize(TransInfo *t, const int UNUSED(mval[2]))
|
||||
|
||||
|
||||
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
|
||||
TransData *td = tc->data;
|
||||
for (i = 0; i < tc->data_len; i++, td++)
|
||||
ElementResize(t, tc, td, mat);
|
||||
TransData *td = tc->data;
|
||||
for (i = 0; i < tc->data_len; i++, td++)
|
||||
ElementResize(t, tc, td, mat);
|
||||
|
||||
/* In proportional edit it can happen that */
|
||||
/* vertices in the radius of the brush end */
|
||||
/* outside the clipping area */
|
||||
/* XXX HACK - dg */
|
||||
if (t->flag & T_PROP_EDIT_ALL) {
|
||||
clipUVData(t);
|
||||
}
|
||||
/* In proportional edit it can happen that */
|
||||
/* vertices in the radius of the brush end */
|
||||
/* outside the clipping area */
|
||||
/* XXX HACK - dg */
|
||||
if (t->flag & T_PROP_EDIT_ALL) {
|
||||
clipUVData(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3605,33 +3605,33 @@ static void applySkinResize(TransInfo *t, const int UNUSED(mval[2]))
|
||||
headerResize(t, size, str);
|
||||
|
||||
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
|
||||
TransData *td = tc->data;
|
||||
for (i = 0; i < tc->data_len; i++, td++) {
|
||||
float tmat[3][3], smat[3][3];
|
||||
float fsize[3];
|
||||
|
||||
if (td->flag & TD_NOACTION)
|
||||
break;
|
||||
|
||||
if (td->flag & TD_SKIP)
|
||||
continue;
|
||||
TransData *td = tc->data;
|
||||
for (i = 0; i < tc->data_len; i++, td++) {
|
||||
float tmat[3][3], smat[3][3];
|
||||
float fsize[3];
|
||||
|
||||
if (t->flag & T_EDIT) {
|
||||
mul_m3_m3m3(smat, mat, td->mtx);
|
||||
mul_m3_m3m3(tmat, td->smtx, smat);
|
||||
}
|
||||
else {
|
||||
copy_m3_m3(tmat, mat);
|
||||
}
|
||||
|
||||
if (t->con.applySize) {
|
||||
t->con.applySize(t, NULL, NULL, tmat);
|
||||
}
|
||||
if (td->flag & TD_NOACTION)
|
||||
break;
|
||||
|
||||
mat3_to_size(fsize, tmat);
|
||||
td->val[0] = td->ext->isize[0] * (1 + (fsize[0] - 1) * td->factor);
|
||||
td->val[1] = td->ext->isize[1] * (1 + (fsize[1] - 1) * td->factor);
|
||||
}
|
||||
if (td->flag & TD_SKIP)
|
||||
continue;
|
||||
|
||||
if (t->flag & T_EDIT) {
|
||||
mul_m3_m3m3(smat, mat, td->mtx);
|
||||
mul_m3_m3m3(tmat, td->smtx, smat);
|
||||
}
|
||||
else {
|
||||
copy_m3_m3(tmat, mat);
|
||||
}
|
||||
|
||||
if (t->con.applySize) {
|
||||
t->con.applySize(t, NULL, NULL, tmat);
|
||||
}
|
||||
|
||||
mat3_to_size(fsize, tmat);
|
||||
td->val[0] = td->ext->isize[0] * (1 + (fsize[0] - 1) * td->factor);
|
||||
td->val[1] = td->ext->isize[1] * (1 + (fsize[1] - 1) * td->factor);
|
||||
}
|
||||
}
|
||||
|
||||
recalcData(t);
|
||||
@@ -3671,10 +3671,10 @@ static void initToSphere(TransInfo *t)
|
||||
|
||||
// Calculate average radius
|
||||
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
|
||||
TransData *td = tc->data;
|
||||
for (i = 0; i < tc->data_len; i++, td++) {
|
||||
t->val += len_v3v3(tc->center_local, td->iloc);
|
||||
}
|
||||
TransData *td = tc->data;
|
||||
for (i = 0; i < tc->data_len; i++, td++) {
|
||||
t->val += len_v3v3(tc->center_local, td->iloc);
|
||||
}
|
||||
}
|
||||
|
||||
t->val /= (float)t->data_len_all;
|
||||
@@ -3711,25 +3711,25 @@ static void applyToSphere(TransInfo *t, const int UNUSED(mval[2]))
|
||||
}
|
||||
|
||||
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
|
||||
TransData *td = tc->data;
|
||||
for (i = 0; i < tc->data_len; i++, td++) {
|
||||
float tratio;
|
||||
if (td->flag & TD_NOACTION)
|
||||
break;
|
||||
|
||||
if (td->flag & TD_SKIP)
|
||||
continue;
|
||||
TransData *td = tc->data;
|
||||
for (i = 0; i < tc->data_len; i++, td++) {
|
||||
float tratio;
|
||||
if (td->flag & TD_NOACTION)
|
||||
break;
|
||||
|
||||
sub_v3_v3v3(vec, td->iloc, tc->center_local);
|
||||
if (td->flag & TD_SKIP)
|
||||
continue;
|
||||
|
||||
radius = normalize_v3(vec);
|
||||
|
||||
tratio = ratio * td->factor;
|
||||
|
||||
mul_v3_fl(vec, radius * (1.0f - tratio) + t->val * tratio);
|
||||
sub_v3_v3v3(vec, td->iloc, tc->center_local);
|
||||
|
||||
add_v3_v3v3(td->loc, tc->center_local, vec);
|
||||
}
|
||||
radius = normalize_v3(vec);
|
||||
|
||||
tratio = ratio * td->factor;
|
||||
|
||||
mul_v3_fl(vec, radius * (1.0f - tratio) + t->val * tratio);
|
||||
|
||||
add_v3_v3v3(td->loc, tc->center_local, vec);
|
||||
}
|
||||
}
|
||||
|
||||
recalcData(t);
|
||||
@@ -4029,25 +4029,25 @@ static void applyRotationValue(TransInfo *t, float angle, float axis[3])
|
||||
axis_angle_normalized_to_mat3(mat, axis, angle);
|
||||
|
||||
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
|
||||
TransData *td = tc->data;
|
||||
for (i = 0; i < tc->data_len; i++, td++) {
|
||||
TransData *td = tc->data;
|
||||
for (i = 0; i < tc->data_len; i++, td++) {
|
||||
|
||||
if (td->flag & TD_NOACTION)
|
||||
break;
|
||||
|
||||
if (td->flag & TD_SKIP)
|
||||
continue;
|
||||
|
||||
if (t->con.applyRot) {
|
||||
t->con.applyRot(t, tc, td, axis, NULL);
|
||||
axis_angle_normalized_to_mat3(mat, axis, angle * td->factor);
|
||||
}
|
||||
else if (t->flag & T_PROP_EDIT) {
|
||||
axis_angle_normalized_to_mat3(mat, axis, angle * td->factor);
|
||||
}
|
||||
if (td->flag & TD_NOACTION)
|
||||
break;
|
||||
|
||||
ElementRotation(t, tc, td, mat, t->around);
|
||||
}
|
||||
if (td->flag & TD_SKIP)
|
||||
continue;
|
||||
|
||||
if (t->con.applyRot) {
|
||||
t->con.applyRot(t, tc, td, axis, NULL);
|
||||
axis_angle_normalized_to_mat3(mat, axis, angle * td->factor);
|
||||
}
|
||||
else if (t->flag & T_PROP_EDIT) {
|
||||
axis_angle_normalized_to_mat3(mat, axis, angle * td->factor);
|
||||
}
|
||||
|
||||
ElementRotation(t, tc, td, mat, t->around);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4143,20 +4143,20 @@ static void applyTrackballValue(TransInfo *t, const float axis1[3], const float
|
||||
axis_angle_normalized_to_mat3(mat, axis, angle);
|
||||
|
||||
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
|
||||
TransData *td = tc->data;
|
||||
for (i = 0; i < tc->data_len; i++, td++) {
|
||||
if (td->flag & TD_NOACTION)
|
||||
break;
|
||||
TransData *td = tc->data;
|
||||
for (i = 0; i < tc->data_len; i++, td++) {
|
||||
if (td->flag & TD_NOACTION)
|
||||
break;
|
||||
|
||||
if (td->flag & TD_SKIP)
|
||||
continue;
|
||||
if (td->flag & TD_SKIP)
|
||||
continue;
|
||||
|
||||
if (t->flag & T_PROP_EDIT) {
|
||||
axis_angle_normalized_to_mat3(mat, axis, td->factor * angle);
|
||||
if (t->flag & T_PROP_EDIT) {
|
||||
axis_angle_normalized_to_mat3(mat, axis, td->factor * angle);
|
||||
}
|
||||
|
||||
ElementRotation(t, tc, td, mat, t->around);
|
||||
}
|
||||
|
||||
ElementRotation(t, tc, td, mat, t->around);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4419,76 +4419,76 @@ static void applyTranslationValue(TransInfo *t, const float vec[3])
|
||||
* but you need "handle snapping rotation before doing the translation" (really?) */
|
||||
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
|
||||
|
||||
float pivot[3];
|
||||
if (apply_snap_align_rotation) {
|
||||
copy_v3_v3(pivot, t->tsnap.snapTarget);
|
||||
/* The pivot has to be in local-space (see T49494) */
|
||||
if (t->flag & (T_EDIT | T_POSE)) {
|
||||
Object *ob = tc->obedit ? tc->obedit : tc->poseobj;
|
||||
mul_m4_v3(ob->imat, pivot);
|
||||
}
|
||||
}
|
||||
|
||||
TransData *td = tc->data;
|
||||
for (int i = 0; i < tc->data_len; i++, td++) {
|
||||
if (td->flag & TD_NOACTION)
|
||||
break;
|
||||
|
||||
if (td->flag & TD_SKIP)
|
||||
continue;
|
||||
|
||||
float rotate_offset[3] = {0};
|
||||
bool use_rotate_offset = false;
|
||||
|
||||
/* handle snapping rotation before doing the translation */
|
||||
float pivot[3];
|
||||
if (apply_snap_align_rotation) {
|
||||
float mat[3][3];
|
||||
copy_v3_v3(pivot, t->tsnap.snapTarget);
|
||||
/* The pivot has to be in local-space (see T49494) */
|
||||
if (t->flag & (T_EDIT | T_POSE)) {
|
||||
Object *ob = tc->obedit ? tc->obedit : tc->poseobj;
|
||||
mul_m4_v3(ob->imat, pivot);
|
||||
}
|
||||
}
|
||||
|
||||
if (validSnappingNormal(t)) {
|
||||
const float *original_normal;
|
||||
TransData *td = tc->data;
|
||||
for (int i = 0; i < tc->data_len; i++, td++) {
|
||||
if (td->flag & TD_NOACTION)
|
||||
break;
|
||||
|
||||
/* In pose mode, we want to align normals with Y axis of bones... */
|
||||
if (t->flag & T_POSE)
|
||||
original_normal = td->axismtx[1];
|
||||
else
|
||||
original_normal = td->axismtx[2];
|
||||
if (td->flag & TD_SKIP)
|
||||
continue;
|
||||
|
||||
rotation_between_vecs_to_mat3(mat, original_normal, t->tsnap.snapNormal);
|
||||
float rotate_offset[3] = {0};
|
||||
bool use_rotate_offset = false;
|
||||
|
||||
/* handle snapping rotation before doing the translation */
|
||||
if (apply_snap_align_rotation) {
|
||||
float mat[3][3];
|
||||
|
||||
if (validSnappingNormal(t)) {
|
||||
const float *original_normal;
|
||||
|
||||
/* In pose mode, we want to align normals with Y axis of bones... */
|
||||
if (t->flag & T_POSE)
|
||||
original_normal = td->axismtx[1];
|
||||
else
|
||||
original_normal = td->axismtx[2];
|
||||
|
||||
rotation_between_vecs_to_mat3(mat, original_normal, t->tsnap.snapNormal);
|
||||
}
|
||||
else {
|
||||
unit_m3(mat);
|
||||
}
|
||||
|
||||
ElementRotation_ex(t, tc, td, mat, pivot);
|
||||
|
||||
if (td->loc) {
|
||||
use_rotate_offset = true;
|
||||
sub_v3_v3v3(rotate_offset, td->loc, td->iloc);
|
||||
}
|
||||
}
|
||||
|
||||
if (t->con.applyVec) {
|
||||
float pvec[3];
|
||||
t->con.applyVec(t, tc, td, vec, tvec, pvec);
|
||||
}
|
||||
else {
|
||||
unit_m3(mat);
|
||||
copy_v3_v3(tvec, vec);
|
||||
}
|
||||
|
||||
ElementRotation_ex(t, tc, td, mat, pivot);
|
||||
|
||||
if (td->loc) {
|
||||
use_rotate_offset = true;
|
||||
sub_v3_v3v3(rotate_offset, td->loc, td->iloc);
|
||||
if (use_rotate_offset) {
|
||||
add_v3_v3(tvec, rotate_offset);
|
||||
}
|
||||
}
|
||||
|
||||
if (t->con.applyVec) {
|
||||
float pvec[3];
|
||||
t->con.applyVec(t, tc, td, vec, tvec, pvec);
|
||||
}
|
||||
else {
|
||||
copy_v3_v3(tvec, vec);
|
||||
}
|
||||
mul_m3_v3(td->smtx, tvec);
|
||||
mul_v3_fl(tvec, td->factor);
|
||||
|
||||
if (use_rotate_offset) {
|
||||
add_v3_v3(tvec, rotate_offset);
|
||||
}
|
||||
|
||||
mul_m3_v3(td->smtx, tvec);
|
||||
mul_v3_fl(tvec, td->factor);
|
||||
|
||||
protectedTransBits(td->protectflag, tvec);
|
||||
|
||||
if (td->loc)
|
||||
add_v3_v3v3(td->loc, td->iloc, tvec);
|
||||
protectedTransBits(td->protectflag, tvec);
|
||||
|
||||
constraintTransLim(t, td);
|
||||
}
|
||||
if (td->loc)
|
||||
add_v3_v3v3(td->loc, td->iloc, tvec);
|
||||
|
||||
constraintTransLim(t, td);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4625,23 +4625,23 @@ static void applyShrinkFatten(TransInfo *t, const int UNUSED(mval[2]))
|
||||
/* done with header string */
|
||||
|
||||
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
|
||||
TransData *td = tc->data;
|
||||
for (i = 0; i < tc->data_len; i++, td++) {
|
||||
float tdistance; /* temp dist */
|
||||
if (td->flag & TD_NOACTION)
|
||||
break;
|
||||
TransData *td = tc->data;
|
||||
for (i = 0; i < tc->data_len; i++, td++) {
|
||||
float tdistance; /* temp dist */
|
||||
if (td->flag & TD_NOACTION)
|
||||
break;
|
||||
|
||||
if (td->flag & TD_SKIP)
|
||||
continue;
|
||||
if (td->flag & TD_SKIP)
|
||||
continue;
|
||||
|
||||
/* get the final offset */
|
||||
tdistance = distance * td->factor;
|
||||
if (td->ext && (t->flag & T_ALT_TRANSFORM)) {
|
||||
tdistance *= td->ext->isize[0]; /* shell factor */
|
||||
/* get the final offset */
|
||||
tdistance = distance * td->factor;
|
||||
if (td->ext && (t->flag & T_ALT_TRANSFORM)) {
|
||||
tdistance *= td->ext->isize[0]; /* shell factor */
|
||||
}
|
||||
|
||||
madd_v3_v3v3fl(td->loc, td->iloc, td->axismtx[2], tdistance);
|
||||
}
|
||||
|
||||
madd_v3_v3v3fl(td->loc, td->iloc, td->axismtx[2], tdistance);
|
||||
}
|
||||
}
|
||||
|
||||
recalcData(t);
|
||||
@@ -4709,19 +4709,19 @@ static void applyTilt(TransInfo *t, const int UNUSED(mval[2]))
|
||||
}
|
||||
|
||||
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
|
||||
TransData *td = tc->data;
|
||||
for (i = 0; i < tc->data_len; i++, td++) {
|
||||
if (td->flag & TD_NOACTION)
|
||||
break;
|
||||
TransData *td = tc->data;
|
||||
for (i = 0; i < tc->data_len; i++, td++) {
|
||||
if (td->flag & TD_NOACTION)
|
||||
break;
|
||||
|
||||
if (td->flag & TD_SKIP)
|
||||
continue;
|
||||
if (td->flag & TD_SKIP)
|
||||
continue;
|
||||
|
||||
if (td->val) {
|
||||
*td->val = td->ival + final * td->factor;
|
||||
if (td->val) {
|
||||
*td->val = td->ival + final * td->factor;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
recalcData(t);
|
||||
|
||||
@@ -4787,22 +4787,22 @@ static void applyCurveShrinkFatten(TransInfo *t, const int UNUSED(mval[2]))
|
||||
}
|
||||
|
||||
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
|
||||
TransData *td = tc->data;
|
||||
for (i = 0; i < tc->data_len; i++, td++) {
|
||||
if (td->flag & TD_NOACTION)
|
||||
break;
|
||||
TransData *td = tc->data;
|
||||
for (i = 0; i < tc->data_len; i++, td++) {
|
||||
if (td->flag & TD_NOACTION)
|
||||
break;
|
||||
|
||||
if (td->flag & TD_SKIP)
|
||||
continue;
|
||||
if (td->flag & TD_SKIP)
|
||||
continue;
|
||||
|
||||
if (td->val) {
|
||||
*td->val = td->ival * ratio;
|
||||
/* apply PET */
|
||||
*td->val = (*td->val * td->factor) + ((1.0f - td->factor) * td->ival);
|
||||
if (*td->val <= 0.0f) *td->val = 0.001f;
|
||||
if (td->val) {
|
||||
*td->val = td->ival * ratio;
|
||||
/* apply PET */
|
||||
*td->val = (*td->val * td->factor) + ((1.0f - td->factor) * td->ival);
|
||||
if (*td->val <= 0.0f) *td->val = 0.001f;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
recalcData(t);
|
||||
|
||||
@@ -4873,41 +4873,41 @@ static void applyMaskShrinkFatten(TransInfo *t, const int UNUSED(mval[2]))
|
||||
initial_feather = true;
|
||||
|
||||
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
|
||||
TransData *td = tc->data;
|
||||
for (i = 0; i < tc->data_len; i++, td++) {
|
||||
if (td->flag & TD_NOACTION)
|
||||
break;
|
||||
|
||||
if (td->flag & TD_SKIP)
|
||||
continue;
|
||||
|
||||
if (td->ival >= 0.001f)
|
||||
initial_feather = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* apply shrink/fatten */
|
||||
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
|
||||
TransData *td = tc->data;
|
||||
for (i = 0; i < tc->data_len; i++, td++) {
|
||||
for (td = tc->data, i = 0; i < tc->data_len; i++, td++) {
|
||||
if (td->flag & TD_NOACTION)
|
||||
break;
|
||||
|
||||
if (td->flag & TD_SKIP)
|
||||
continue;
|
||||
|
||||
if (td->ival >= 0.001f)
|
||||
initial_feather = false;
|
||||
if (td->val) {
|
||||
if (initial_feather)
|
||||
*td->val = td->ival + (ratio - 1.0f) * 0.01f;
|
||||
else
|
||||
*td->val = td->ival * ratio;
|
||||
|
||||
/* apply PET */
|
||||
*td->val = (*td->val * td->factor) + ((1.0f - td->factor) * td->ival);
|
||||
if (*td->val <= 0.0f) *td->val = 0.001f;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* apply shrink/fatten */
|
||||
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
|
||||
TransData *td = tc->data;
|
||||
for (td = tc->data, i = 0; i < tc->data_len; i++, td++) {
|
||||
if (td->flag & TD_NOACTION)
|
||||
break;
|
||||
|
||||
if (td->flag & TD_SKIP)
|
||||
continue;
|
||||
|
||||
if (td->val) {
|
||||
if (initial_feather)
|
||||
*td->val = td->ival + (ratio - 1.0f) * 0.01f;
|
||||
else
|
||||
*td->val = td->ival * ratio;
|
||||
|
||||
/* apply PET */
|
||||
*td->val = (*td->val * td->factor) + ((1.0f - td->factor) * td->ival);
|
||||
if (*td->val <= 0.0f) *td->val = 0.001f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
recalcData(t);
|
||||
@@ -4974,22 +4974,22 @@ static void applyGPShrinkFatten(TransInfo *t, const int UNUSED(mval[2]))
|
||||
}
|
||||
|
||||
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
|
||||
TransData *td = tc->data;
|
||||
for (i = 0; i < tc->data_len; i++, td++) {
|
||||
if (td->flag & TD_NOACTION)
|
||||
break;
|
||||
TransData *td = tc->data;
|
||||
for (i = 0; i < tc->data_len; i++, td++) {
|
||||
if (td->flag & TD_NOACTION)
|
||||
break;
|
||||
|
||||
if (td->flag & TD_SKIP)
|
||||
continue;
|
||||
if (td->flag & TD_SKIP)
|
||||
continue;
|
||||
|
||||
if (td->val) {
|
||||
*td->val = td->ival * ratio;
|
||||
/* apply PET */
|
||||
*td->val = (*td->val * td->factor) + ((1.0f - td->factor) * td->ival);
|
||||
if (*td->val <= 0.0f) *td->val = 0.001f;
|
||||
if (td->val) {
|
||||
*td->val = td->ival * ratio;
|
||||
/* apply PET */
|
||||
*td->val = (*td->val * td->factor) + ((1.0f - td->factor) * td->ival);
|
||||
if (*td->val <= 0.0f) *td->val = 0.001f;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
recalcData(t);
|
||||
|
||||
@@ -5056,34 +5056,34 @@ static void applyPushPull(TransInfo *t, const int UNUSED(mval[2]))
|
||||
}
|
||||
|
||||
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
|
||||
TransData *td = tc->data;
|
||||
for (i = 0; i < tc->data_len; i++, td++) {
|
||||
if (td->flag & TD_NOACTION)
|
||||
break;
|
||||
TransData *td = tc->data;
|
||||
for (i = 0; i < tc->data_len; i++, td++) {
|
||||
if (td->flag & TD_NOACTION)
|
||||
break;
|
||||
|
||||
if (td->flag & TD_SKIP)
|
||||
continue;
|
||||
if (td->flag & TD_SKIP)
|
||||
continue;
|
||||
|
||||
sub_v3_v3v3(vec, tc->center_local, td->center);
|
||||
if (t->con.applyRot && t->con.mode & CON_APPLY) {
|
||||
float axis[3];
|
||||
copy_v3_v3(axis, axis_global);
|
||||
t->con.applyRot(t, tc, td, axis, NULL);
|
||||
sub_v3_v3v3(vec, tc->center_local, td->center);
|
||||
if (t->con.applyRot && t->con.mode & CON_APPLY) {
|
||||
float axis[3];
|
||||
copy_v3_v3(axis, axis_global);
|
||||
t->con.applyRot(t, tc, td, axis, NULL);
|
||||
|
||||
mul_m3_v3(td->smtx, axis);
|
||||
if (isLockConstraint(t)) {
|
||||
float dvec[3];
|
||||
project_v3_v3v3(dvec, vec, axis);
|
||||
sub_v3_v3(vec, dvec);
|
||||
}
|
||||
else {
|
||||
project_v3_v3v3(vec, vec, axis);
|
||||
mul_m3_v3(td->smtx, axis);
|
||||
if (isLockConstraint(t)) {
|
||||
float dvec[3];
|
||||
project_v3_v3v3(dvec, vec, axis);
|
||||
sub_v3_v3(vec, dvec);
|
||||
}
|
||||
else {
|
||||
project_v3_v3v3(vec, vec, axis);
|
||||
}
|
||||
}
|
||||
normalize_v3_length(vec, distance * td->factor);
|
||||
|
||||
add_v3_v3v3(td->loc, td->iloc, vec);
|
||||
}
|
||||
normalize_v3_length(vec, distance * td->factor);
|
||||
|
||||
add_v3_v3v3(td->loc, td->iloc, vec);
|
||||
}
|
||||
}
|
||||
|
||||
recalcData(t);
|
||||
@@ -5155,18 +5155,18 @@ static void applyBevelWeight(TransInfo *t, const int UNUSED(mval[2]))
|
||||
}
|
||||
|
||||
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
|
||||
TransData *td = tc->data;
|
||||
for (i = 0; i < tc->data_len; i++, td++) {
|
||||
if (td->flag & TD_NOACTION)
|
||||
break;
|
||||
TransData *td = tc->data;
|
||||
for (i = 0; i < tc->data_len; i++, td++) {
|
||||
if (td->flag & TD_NOACTION)
|
||||
break;
|
||||
|
||||
if (td->val) {
|
||||
*td->val = td->ival + weight * td->factor;
|
||||
if (*td->val < 0.0f) *td->val = 0.0f;
|
||||
if (*td->val > 1.0f) *td->val = 1.0f;
|
||||
if (td->val) {
|
||||
*td->val = td->ival + weight * td->factor;
|
||||
if (*td->val < 0.0f) *td->val = 0.0f;
|
||||
if (*td->val > 1.0f) *td->val = 1.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
recalcData(t);
|
||||
|
||||
@@ -5237,21 +5237,21 @@ static void applyCrease(TransInfo *t, const int UNUSED(mval[2]))
|
||||
}
|
||||
|
||||
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
|
||||
TransData *td = tc->data;
|
||||
for (i = 0; i < tc->data_len; i++, td++) {
|
||||
if (td->flag & TD_NOACTION)
|
||||
break;
|
||||
TransData *td = tc->data;
|
||||
for (i = 0; i < tc->data_len; i++, td++) {
|
||||
if (td->flag & TD_NOACTION)
|
||||
break;
|
||||
|
||||
if (td->flag & TD_SKIP)
|
||||
continue;
|
||||
if (td->flag & TD_SKIP)
|
||||
continue;
|
||||
|
||||
if (td->val) {
|
||||
*td->val = td->ival + crease * td->factor;
|
||||
if (*td->val < 0.0f) *td->val = 0.0f;
|
||||
if (*td->val > 1.0f) *td->val = 1.0f;
|
||||
if (td->val) {
|
||||
*td->val = td->ival + crease * td->factor;
|
||||
if (*td->val < 0.0f) *td->val = 0.0f;
|
||||
if (*td->val > 1.0f) *td->val = 1.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
recalcData(t);
|
||||
|
||||
@@ -5364,16 +5364,16 @@ static void applyBoneSize(TransInfo *t, const int UNUSED(mval[2]))
|
||||
headerBoneSize(t, size, str);
|
||||
|
||||
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
|
||||
TransData *td = tc->data;
|
||||
for (i = 0; i < tc->data_len; i++, td++) {
|
||||
if (td->flag & TD_NOACTION)
|
||||
break;
|
||||
|
||||
if (td->flag & TD_SKIP)
|
||||
continue;
|
||||
TransData *td = tc->data;
|
||||
for (i = 0; i < tc->data_len; i++, td++) {
|
||||
if (td->flag & TD_NOACTION)
|
||||
break;
|
||||
|
||||
ElementBoneSize(t, tc, td, mat);
|
||||
}
|
||||
if (td->flag & TD_SKIP)
|
||||
continue;
|
||||
|
||||
ElementBoneSize(t, tc, td, mat);
|
||||
}
|
||||
}
|
||||
|
||||
recalcData(t);
|
||||
@@ -5435,23 +5435,23 @@ static void applyBoneEnvelope(TransInfo *t, const int UNUSED(mval[2]))
|
||||
}
|
||||
|
||||
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
|
||||
TransData *td = tc->data;
|
||||
for (i = 0; i < tc->data_len; i++, td++) {
|
||||
if (td->flag & TD_NOACTION)
|
||||
break;
|
||||
|
||||
if (td->flag & TD_SKIP)
|
||||
continue;
|
||||
|
||||
if (td->val) {
|
||||
/* if the old/original value was 0.0f, then just use ratio */
|
||||
if (td->ival)
|
||||
*td->val = td->ival * ratio;
|
||||
else
|
||||
*td->val = ratio;
|
||||
TransData *td = tc->data;
|
||||
for (i = 0; i < tc->data_len; i++, td++) {
|
||||
if (td->flag & TD_NOACTION)
|
||||
break;
|
||||
|
||||
if (td->flag & TD_SKIP)
|
||||
continue;
|
||||
|
||||
if (td->val) {
|
||||
/* if the old/original value was 0.0f, then just use ratio */
|
||||
if (td->ival)
|
||||
*td->val = td->ival * ratio;
|
||||
else
|
||||
*td->val = ratio;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
recalcData(t);
|
||||
|
||||
@@ -6779,14 +6779,14 @@ static bool createEdgeSlideVerts_single_side(TransInfo *t, TransDataContainer *t
|
||||
void projectEdgeSlideData(TransInfo *t, bool is_final)
|
||||
{
|
||||
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
|
||||
EdgeSlideData *sld = tc->custom.mode.data;
|
||||
SlideOrigData *sod = &sld->orig_data;
|
||||
EdgeSlideData *sld = tc->custom.mode.data;
|
||||
SlideOrigData *sod = &sld->orig_data;
|
||||
|
||||
if (sod->use_origfaces == false) {
|
||||
return;
|
||||
}
|
||||
if (sod->use_origfaces == false) {
|
||||
return;
|
||||
}
|
||||
|
||||
slide_origdata_interp_data(tc->obedit, sod, (TransDataGenericSlideVert *)sld->sv, sizeof(*sld->sv), sld->totsv, is_final);
|
||||
slide_origdata_interp_data(tc->obedit, sod, (TransDataGenericSlideVert *)sld->sv, sizeof(*sld->sv), sld->totsv, is_final);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7067,32 +7067,32 @@ static void doEdgeSlide(TransInfo *t, float perc)
|
||||
const int side_index = (perc < 0.0f);
|
||||
const float perc_final = fabsf(perc);
|
||||
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
|
||||
EdgeSlideData *sld = tc->custom.mode.data;
|
||||
TransDataEdgeSlideVert *sv = sld->sv;
|
||||
for (int i = 0; i < sld->totsv; i++, sv++) {
|
||||
madd_v3_v3v3fl(sv->v->co, sv->v_co_orig, sv->dir_side[side_index], perc_final);
|
||||
}
|
||||
sld->curr_side_unclamp = side_index;
|
||||
EdgeSlideData *sld = tc->custom.mode.data;
|
||||
TransDataEdgeSlideVert *sv = sld->sv;
|
||||
for (int i = 0; i < sld->totsv; i++, sv++) {
|
||||
madd_v3_v3v3fl(sv->v->co, sv->v_co_orig, sv->dir_side[side_index], perc_final);
|
||||
}
|
||||
sld->curr_side_unclamp = side_index;
|
||||
}
|
||||
}
|
||||
else {
|
||||
const float perc_init = fabsf(perc) * ((sld_active->curr_side_unclamp == (perc < 0.0f)) ? 1 : -1);
|
||||
const int side_index = sld_active->curr_side_unclamp;
|
||||
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
|
||||
EdgeSlideData *sld = tc->custom.mode.data;
|
||||
TransDataEdgeSlideVert *sv = sld->sv;
|
||||
for (int i = 0; i < sld->totsv; i++, sv++) {
|
||||
float dir_flip[3];
|
||||
float perc_final = perc_init;
|
||||
if (!is_zero_v3(sv->dir_side[side_index])) {
|
||||
copy_v3_v3(dir_flip, sv->dir_side[side_index]);
|
||||
EdgeSlideData *sld = tc->custom.mode.data;
|
||||
TransDataEdgeSlideVert *sv = sld->sv;
|
||||
for (int i = 0; i < sld->totsv; i++, sv++) {
|
||||
float dir_flip[3];
|
||||
float perc_final = perc_init;
|
||||
if (!is_zero_v3(sv->dir_side[side_index])) {
|
||||
copy_v3_v3(dir_flip, sv->dir_side[side_index]);
|
||||
}
|
||||
else {
|
||||
copy_v3_v3(dir_flip, sv->dir_side[!side_index]);
|
||||
perc_final *= -1;
|
||||
}
|
||||
madd_v3_v3v3fl(sv->v->co, sv->v_co_orig, dir_flip, perc_final);
|
||||
}
|
||||
else {
|
||||
copy_v3_v3(dir_flip, sv->dir_side[!side_index]);
|
||||
perc_final *= -1;
|
||||
}
|
||||
madd_v3_v3v3fl(sv->v->co, sv->v_co_orig, dir_flip, perc_final);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7112,24 +7112,24 @@ static void doEdgeSlide(TransInfo *t, float perc)
|
||||
float co_b[3];
|
||||
|
||||
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
|
||||
EdgeSlideData *sld = tc->custom.mode.data;
|
||||
TransDataEdgeSlideVert *sv = sld->sv;
|
||||
for (int i = 0; i < sld->totsv; i++, sv++) {
|
||||
if (sv->edge_len > FLT_EPSILON) {
|
||||
const float fac = min_ff(sv->edge_len, curr_length_perc) / sv->edge_len;
|
||||
EdgeSlideData *sld = tc->custom.mode.data;
|
||||
TransDataEdgeSlideVert *sv = sld->sv;
|
||||
for (int i = 0; i < sld->totsv; i++, sv++) {
|
||||
if (sv->edge_len > FLT_EPSILON) {
|
||||
const float fac = min_ff(sv->edge_len, curr_length_perc) / sv->edge_len;
|
||||
|
||||
add_v3_v3v3(co_a, sv->v_co_orig, sv->dir_side[0]);
|
||||
add_v3_v3v3(co_b, sv->v_co_orig, sv->dir_side[1]);
|
||||
add_v3_v3v3(co_a, sv->v_co_orig, sv->dir_side[0]);
|
||||
add_v3_v3v3(co_b, sv->v_co_orig, sv->dir_side[1]);
|
||||
|
||||
if (slp->flipped) {
|
||||
interp_line_v3_v3v3v3(sv->v->co, co_b, sv->v_co_orig, co_a, fac);
|
||||
}
|
||||
else {
|
||||
interp_line_v3_v3v3v3(sv->v->co, co_a, sv->v_co_orig, co_b, fac);
|
||||
if (slp->flipped) {
|
||||
interp_line_v3_v3v3v3(sv->v->co, co_b, sv->v_co_orig, co_a, fac);
|
||||
}
|
||||
else {
|
||||
interp_line_v3_v3v3v3(sv->v->co, co_a, sv->v_co_orig, co_b, fac);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7411,11 +7411,11 @@ static bool createVertSlideVerts(TransInfo *t, TransDataContainer *tc)
|
||||
void projectVertSlideData(TransInfo *t, bool is_final)
|
||||
{
|
||||
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
|
||||
VertSlideData *sld = tc->custom.mode.data;
|
||||
SlideOrigData *sod = &sld->orig_data;
|
||||
if (sod->use_origfaces == true) {
|
||||
slide_origdata_interp_data(tc->obedit, sod, (TransDataGenericSlideVert *)sld->sv, sizeof(*sld->sv), sld->totsv, is_final);
|
||||
}
|
||||
VertSlideData *sld = tc->custom.mode.data;
|
||||
SlideOrigData *sod = &sld->orig_data;
|
||||
if (sod->use_origfaces == true) {
|
||||
slide_origdata_interp_data(tc->obedit, sod, (TransDataGenericSlideVert *)sld->sv, sizeof(*sld->sv), sld->totsv, is_final);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7687,44 +7687,44 @@ static void drawVertSlide(TransInfo *t)
|
||||
static void doVertSlide(TransInfo *t, float perc)
|
||||
{
|
||||
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
|
||||
VertSlideData *sld = tc->custom.mode.data;
|
||||
TransDataVertSlideVert *svlist = sld->sv, *sv;
|
||||
int i;
|
||||
VertSlideData *sld = tc->custom.mode.data;
|
||||
TransDataVertSlideVert *svlist = sld->sv, *sv;
|
||||
int i;
|
||||
|
||||
sld->perc = perc;
|
||||
sv = svlist;
|
||||
sld->perc = perc;
|
||||
sv = svlist;
|
||||
|
||||
if (sld->use_even == false) {
|
||||
for (i = 0; i < sld->totsv; i++, sv++) {
|
||||
interp_v3_v3v3(sv->v->co, sv->co_orig_3d, sv->co_link_orig_3d[sv->co_link_curr], perc);
|
||||
if (sld->use_even == false) {
|
||||
for (i = 0; i < sld->totsv; i++, sv++) {
|
||||
interp_v3_v3v3(sv->v->co, sv->co_orig_3d, sv->co_link_orig_3d[sv->co_link_curr], perc);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
TransDataVertSlideVert *sv_curr = &sld->sv[sld->curr_sv_index];
|
||||
const float edge_len_curr = len_v3v3(sv_curr->co_orig_3d, sv_curr->co_link_orig_3d[sv_curr->co_link_curr]);
|
||||
const float tperc = perc * edge_len_curr;
|
||||
else {
|
||||
TransDataVertSlideVert *sv_curr = &sld->sv[sld->curr_sv_index];
|
||||
const float edge_len_curr = len_v3v3(sv_curr->co_orig_3d, sv_curr->co_link_orig_3d[sv_curr->co_link_curr]);
|
||||
const float tperc = perc * edge_len_curr;
|
||||
|
||||
for (i = 0; i < sld->totsv; i++, sv++) {
|
||||
float edge_len;
|
||||
float dir[3];
|
||||
for (i = 0; i < sld->totsv; i++, sv++) {
|
||||
float edge_len;
|
||||
float dir[3];
|
||||
|
||||
sub_v3_v3v3(dir, sv->co_link_orig_3d[sv->co_link_curr], sv->co_orig_3d);
|
||||
edge_len = normalize_v3(dir);
|
||||
sub_v3_v3v3(dir, sv->co_link_orig_3d[sv->co_link_curr], sv->co_orig_3d);
|
||||
edge_len = normalize_v3(dir);
|
||||
|
||||
if (edge_len > FLT_EPSILON) {
|
||||
if (sld->flipped) {
|
||||
madd_v3_v3v3fl(sv->v->co, sv->co_link_orig_3d[sv->co_link_curr], dir, -tperc);
|
||||
if (edge_len > FLT_EPSILON) {
|
||||
if (sld->flipped) {
|
||||
madd_v3_v3v3fl(sv->v->co, sv->co_link_orig_3d[sv->co_link_curr], dir, -tperc);
|
||||
}
|
||||
else {
|
||||
madd_v3_v3v3fl(sv->v->co, sv->co_orig_3d, dir, tperc);
|
||||
}
|
||||
}
|
||||
else {
|
||||
madd_v3_v3v3fl(sv->v->co, sv->co_orig_3d, dir, tperc);
|
||||
copy_v3_v3(sv->v->co, sv->co_orig_3d);
|
||||
}
|
||||
}
|
||||
else {
|
||||
copy_v3_v3(sv->v->co, sv->co_orig_3d);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void applyVertSlide(TransInfo *t, const int UNUSED(mval[2]))
|
||||
@@ -7833,16 +7833,16 @@ static void applyBoneRoll(TransInfo *t, const int UNUSED(mval[2]))
|
||||
|
||||
/* set roll values */
|
||||
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
|
||||
TransData *td = tc->data;
|
||||
for (i = 0; i < tc->data_len; i++, td++) {
|
||||
if (td->flag & TD_NOACTION)
|
||||
break;
|
||||
TransData *td = tc->data;
|
||||
for (i = 0; i < tc->data_len; i++, td++) {
|
||||
if (td->flag & TD_NOACTION)
|
||||
break;
|
||||
|
||||
if (td->flag & TD_SKIP)
|
||||
continue;
|
||||
if (td->flag & TD_SKIP)
|
||||
continue;
|
||||
|
||||
*(td->val) = td->ival - final;
|
||||
}
|
||||
*(td->val) = td->ival - final;
|
||||
}
|
||||
}
|
||||
|
||||
recalcData(t);
|
||||
@@ -7920,21 +7920,21 @@ static void applyBakeTime(TransInfo *t, const int mval[2])
|
||||
}
|
||||
|
||||
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
|
||||
TransData *td = tc->data;
|
||||
for (i = 0; i < tc->data_len; i++, td++) {
|
||||
if (td->flag & TD_NOACTION)
|
||||
break;
|
||||
TransData *td = tc->data;
|
||||
for (i = 0; i < tc->data_len; i++, td++) {
|
||||
if (td->flag & TD_NOACTION)
|
||||
break;
|
||||
|
||||
if (td->flag & TD_SKIP)
|
||||
continue;
|
||||
if (td->flag & TD_SKIP)
|
||||
continue;
|
||||
|
||||
if (td->val) {
|
||||
*td->val = td->ival + time * td->factor;
|
||||
if (td->ext->size && *td->val < *td->ext->size) *td->val = *td->ext->size;
|
||||
if (td->ext->quat && *td->val > *td->ext->quat) *td->val = *td->ext->quat;
|
||||
if (td->val) {
|
||||
*td->val = td->ival + time * td->factor;
|
||||
if (td->ext->size && *td->val < *td->ext->size) *td->val = *td->ext->size;
|
||||
if (td->ext->quat && *td->val > *td->ext->quat) *td->val = *td->ext->quat;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
recalcData(t);
|
||||
|
||||
@@ -7985,16 +7985,16 @@ static void applyMirror(TransInfo *t, const int UNUSED(mval[2]))
|
||||
BLI_snprintf(str, sizeof(str), IFACE_("Mirror%s"), t->con.text);
|
||||
|
||||
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
|
||||
TransData *td = tc->data;
|
||||
for (i = 0; i < tc->data_len; i++, td++) {
|
||||
if (td->flag & TD_NOACTION)
|
||||
break;
|
||||
TransData *td = tc->data;
|
||||
for (i = 0; i < tc->data_len; i++, td++) {
|
||||
if (td->flag & TD_NOACTION)
|
||||
break;
|
||||
|
||||
if (td->flag & TD_SKIP)
|
||||
continue;
|
||||
if (td->flag & TD_SKIP)
|
||||
continue;
|
||||
|
||||
ElementResize(t, tc, td, mat);
|
||||
}
|
||||
ElementResize(t, tc, td, mat);
|
||||
}
|
||||
}
|
||||
|
||||
recalcData(t);
|
||||
@@ -8007,16 +8007,16 @@ static void applyMirror(TransInfo *t, const int UNUSED(mval[2]))
|
||||
size_to_mat3(mat, size);
|
||||
|
||||
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
|
||||
TransData *td = tc->data;
|
||||
for (i = 0; i < tc->data_len; i++, td++) {
|
||||
if (td->flag & TD_NOACTION)
|
||||
break;
|
||||
TransData *td = tc->data;
|
||||
for (i = 0; i < tc->data_len; i++, td++) {
|
||||
if (td->flag & TD_NOACTION)
|
||||
break;
|
||||
|
||||
if (td->flag & TD_SKIP)
|
||||
continue;
|
||||
if (td->flag & TD_SKIP)
|
||||
continue;
|
||||
|
||||
ElementResize(t, tc, td, mat);
|
||||
}
|
||||
ElementResize(t, tc, td, mat);
|
||||
}
|
||||
}
|
||||
|
||||
recalcData(t);
|
||||
@@ -8052,36 +8052,36 @@ static void applyAlign(TransInfo *t, const int UNUSED(mval[2]))
|
||||
|
||||
|
||||
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
|
||||
/* saving original center */
|
||||
copy_v3_v3(center, tc->center_local);
|
||||
TransData *td = tc->data;
|
||||
for (i = 0; i < tc->data_len; i++, td++) {
|
||||
float mat[3][3], invmat[3][3];
|
||||
/* saving original center */
|
||||
copy_v3_v3(center, tc->center_local);
|
||||
TransData *td = tc->data;
|
||||
for (i = 0; i < tc->data_len; i++, td++) {
|
||||
float mat[3][3], invmat[3][3];
|
||||
|
||||
if (td->flag & TD_NOACTION)
|
||||
break;
|
||||
if (td->flag & TD_NOACTION)
|
||||
break;
|
||||
|
||||
if (td->flag & TD_SKIP)
|
||||
continue;
|
||||
if (td->flag & TD_SKIP)
|
||||
continue;
|
||||
|
||||
/* around local centers */
|
||||
if (t->flag & (T_OBJECT | T_POSE)) {
|
||||
copy_v3_v3(tc->center_local, td->center);
|
||||
}
|
||||
else {
|
||||
if (t->settings->selectmode & SCE_SELECT_FACE) {
|
||||
/* around local centers */
|
||||
if (t->flag & (T_OBJECT | T_POSE)) {
|
||||
copy_v3_v3(tc->center_local, td->center);
|
||||
}
|
||||
else {
|
||||
if (t->settings->selectmode & SCE_SELECT_FACE) {
|
||||
copy_v3_v3(tc->center_local, td->center);
|
||||
}
|
||||
}
|
||||
|
||||
invert_m3_m3(invmat, td->axismtx);
|
||||
|
||||
mul_m3_m3m3(mat, t->spacemtx, invmat);
|
||||
|
||||
ElementRotation(t, tc, td, mat, t->around);
|
||||
}
|
||||
|
||||
invert_m3_m3(invmat, td->axismtx);
|
||||
|
||||
mul_m3_m3m3(mat, t->spacemtx, invmat);
|
||||
|
||||
ElementRotation(t, tc, td, mat, t->around);
|
||||
}
|
||||
/* restoring original center */
|
||||
copy_v3_v3(tc->center_local, center);
|
||||
/* restoring original center */
|
||||
copy_v3_v3(tc->center_local, center);
|
||||
}
|
||||
|
||||
recalcData(t);
|
||||
@@ -8147,16 +8147,16 @@ static void applySeqSlideValue(TransInfo *t, const float val[2])
|
||||
int i;
|
||||
|
||||
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
|
||||
TransData *td = tc->data;
|
||||
for (i = 0; i < tc->data_len; i++, td++) {
|
||||
if (td->flag & TD_NOACTION)
|
||||
break;
|
||||
TransData *td = tc->data;
|
||||
for (i = 0; i < tc->data_len; i++, td++) {
|
||||
if (td->flag & TD_NOACTION)
|
||||
break;
|
||||
|
||||
if (td->flag & TD_SKIP)
|
||||
continue;
|
||||
if (td->flag & TD_SKIP)
|
||||
continue;
|
||||
|
||||
madd_v2_v2v2fl(td->loc, td->iloc, val, td->factor);
|
||||
}
|
||||
madd_v2_v2v2fl(td->loc, td->iloc, val, td->factor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8398,49 +8398,49 @@ static void applyTimeTranslateValue(TransInfo *t)
|
||||
float deltax, val /* , valprev */;
|
||||
|
||||
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
|
||||
TransData *td = tc->data;
|
||||
TransData2D *td2d = tc->data_2d;
|
||||
/* it doesn't matter whether we apply to t->data or t->data2d, but t->data2d is more convenient */
|
||||
for (i = 0; i < tc->data_len; i++, td++, td2d++) {
|
||||
/* it is assumed that td->extra is a pointer to the AnimData,
|
||||
* whose active action is where this keyframe comes from
|
||||
* (this is only valid when not in NLA)
|
||||
*/
|
||||
AnimData *adt = (t->spacetype != SPACE_NLA) ? td->extra : NULL;
|
||||
TransData *td = tc->data;
|
||||
TransData2D *td2d = tc->data_2d;
|
||||
/* it doesn't matter whether we apply to t->data or t->data2d, but t->data2d is more convenient */
|
||||
for (i = 0; i < tc->data_len; i++, td++, td2d++) {
|
||||
/* it is assumed that td->extra is a pointer to the AnimData,
|
||||
* whose active action is where this keyframe comes from
|
||||
* (this is only valid when not in NLA)
|
||||
*/
|
||||
AnimData *adt = (t->spacetype != SPACE_NLA) ? td->extra : NULL;
|
||||
|
||||
/* valprev = *td->val; */ /* UNUSED */
|
||||
/* valprev = *td->val; */ /* UNUSED */
|
||||
|
||||
/* check if any need to apply nla-mapping */
|
||||
if (adt && (t->spacetype != SPACE_SEQ)) {
|
||||
deltax = t->values[0];
|
||||
/* check if any need to apply nla-mapping */
|
||||
if (adt && (t->spacetype != SPACE_SEQ)) {
|
||||
deltax = t->values[0];
|
||||
|
||||
if (autosnap == SACTSNAP_TSTEP) {
|
||||
deltax = (float)(floor(((double)deltax / secf) + 0.5) * secf);
|
||||
if (autosnap == SACTSNAP_TSTEP) {
|
||||
deltax = (float)(floor(((double)deltax / secf) + 0.5) * secf);
|
||||
}
|
||||
else if (autosnap == SACTSNAP_STEP) {
|
||||
deltax = floorf(deltax + 0.5f);
|
||||
}
|
||||
|
||||
val = BKE_nla_tweakedit_remap(adt, td->ival, NLATIME_CONVERT_MAP);
|
||||
val += deltax * td->factor;
|
||||
*(td->val) = BKE_nla_tweakedit_remap(adt, val, NLATIME_CONVERT_UNMAP);
|
||||
}
|
||||
else if (autosnap == SACTSNAP_STEP) {
|
||||
deltax = floorf(deltax + 0.5f);
|
||||
else {
|
||||
deltax = val = t->values[0];
|
||||
|
||||
if (autosnap == SACTSNAP_TSTEP) {
|
||||
val = (float)(floor(((double)deltax / secf) + 0.5) * secf);
|
||||
}
|
||||
else if (autosnap == SACTSNAP_STEP) {
|
||||
val = floorf(val + 0.5f);
|
||||
}
|
||||
|
||||
*(td->val) = td->ival + val;
|
||||
}
|
||||
|
||||
val = BKE_nla_tweakedit_remap(adt, td->ival, NLATIME_CONVERT_MAP);
|
||||
val += deltax * td->factor;
|
||||
*(td->val) = BKE_nla_tweakedit_remap(adt, val, NLATIME_CONVERT_UNMAP);
|
||||
/* apply nearest snapping */
|
||||
doAnimEdit_SnapFrame(t, td, td2d, adt, autosnap);
|
||||
}
|
||||
else {
|
||||
deltax = val = t->values[0];
|
||||
|
||||
if (autosnap == SACTSNAP_TSTEP) {
|
||||
val = (float)(floor(((double)deltax / secf) + 0.5) * secf);
|
||||
}
|
||||
else if (autosnap == SACTSNAP_STEP) {
|
||||
val = floorf(val + 0.5f);
|
||||
}
|
||||
|
||||
*(td->val) = td->ival + val;
|
||||
}
|
||||
|
||||
/* apply nearest snapping */
|
||||
doAnimEdit_SnapFrame(t, td, td2d, adt, autosnap);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8508,18 +8508,18 @@ static void initTimeSlide(TransInfo *t)
|
||||
float min = 999999999.0f, max = -999999999.0f;
|
||||
int i;
|
||||
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
|
||||
TransData *td = tc->data;
|
||||
for (i = 0; i < tc->data_len; i++, td++) {
|
||||
AnimData *adt = (t->spacetype != SPACE_NLA) ? td->extra : NULL;
|
||||
float val = *(td->val);
|
||||
|
||||
/* strip/action time to global (mapped) time */
|
||||
if (adt)
|
||||
val = BKE_nla_tweakedit_remap(adt, val, NLATIME_CONVERT_MAP);
|
||||
|
||||
if (min > val) min = val;
|
||||
if (max < val) max = val;
|
||||
}
|
||||
TransData *td = tc->data;
|
||||
for (i = 0; i < tc->data_len; i++, td++) {
|
||||
AnimData *adt = (t->spacetype != SPACE_NLA) ? td->extra : NULL;
|
||||
float val = *(td->val);
|
||||
|
||||
/* strip/action time to global (mapped) time */
|
||||
if (adt)
|
||||
val = BKE_nla_tweakedit_remap(adt, val, NLATIME_CONVERT_MAP);
|
||||
|
||||
if (min > val) min = val;
|
||||
if (max < val) max = val;
|
||||
}
|
||||
}
|
||||
|
||||
if (min == max) {
|
||||
@@ -8587,49 +8587,49 @@ static void applyTimeSlideValue(TransInfo *t, float sval)
|
||||
|
||||
/* it doesn't matter whether we apply to t->data or t->data2d, but t->data2d is more convenient */
|
||||
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
|
||||
TransData *td = tc->data;
|
||||
for (i = 0; i < tc->data_len; i++, td++) {
|
||||
/* it is assumed that td->extra is a pointer to the AnimData,
|
||||
* whose active action is where this keyframe comes from
|
||||
* (this is only valid when not in NLA)
|
||||
*/
|
||||
AnimData *adt = (t->spacetype != SPACE_NLA) ? td->extra : NULL;
|
||||
float cval = t->values[0];
|
||||
|
||||
/* only apply to data if in range */
|
||||
if ((sval > minx) && (sval < maxx)) {
|
||||
float cvalc = CLAMPIS(cval, minx, maxx);
|
||||
float ival = td->ival;
|
||||
float timefac;
|
||||
|
||||
/* NLA mapping magic here works as follows:
|
||||
* - "ival" goes from strip time to global time
|
||||
* - calculation is performed into td->val in global time
|
||||
* (since sval and min/max are all in global time)
|
||||
* - "td->val" then gets put back into strip time
|
||||
TransData *td = tc->data;
|
||||
for (i = 0; i < tc->data_len; i++, td++) {
|
||||
/* it is assumed that td->extra is a pointer to the AnimData,
|
||||
* whose active action is where this keyframe comes from
|
||||
* (this is only valid when not in NLA)
|
||||
*/
|
||||
if (adt) {
|
||||
/* strip to global */
|
||||
ival = BKE_nla_tweakedit_remap(adt, ival, NLATIME_CONVERT_MAP);
|
||||
}
|
||||
|
||||
/* left half? */
|
||||
if (ival < sval) {
|
||||
timefac = (sval - ival) / (sval - minx);
|
||||
*(td->val) = cvalc - timefac * (cvalc - minx);
|
||||
}
|
||||
else {
|
||||
timefac = (ival - sval) / (maxx - sval);
|
||||
*(td->val) = cvalc + timefac * (maxx - cvalc);
|
||||
}
|
||||
|
||||
if (adt) {
|
||||
/* global to strip */
|
||||
*(td->val) = BKE_nla_tweakedit_remap(adt, *(td->val), NLATIME_CONVERT_UNMAP);
|
||||
AnimData *adt = (t->spacetype != SPACE_NLA) ? td->extra : NULL;
|
||||
float cval = t->values[0];
|
||||
|
||||
/* only apply to data if in range */
|
||||
if ((sval > minx) && (sval < maxx)) {
|
||||
float cvalc = CLAMPIS(cval, minx, maxx);
|
||||
float ival = td->ival;
|
||||
float timefac;
|
||||
|
||||
/* NLA mapping magic here works as follows:
|
||||
* - "ival" goes from strip time to global time
|
||||
* - calculation is performed into td->val in global time
|
||||
* (since sval and min/max are all in global time)
|
||||
* - "td->val" then gets put back into strip time
|
||||
*/
|
||||
if (adt) {
|
||||
/* strip to global */
|
||||
ival = BKE_nla_tweakedit_remap(adt, ival, NLATIME_CONVERT_MAP);
|
||||
}
|
||||
|
||||
/* left half? */
|
||||
if (ival < sval) {
|
||||
timefac = (sval - ival) / (sval - minx);
|
||||
*(td->val) = cvalc - timefac * (cvalc - minx);
|
||||
}
|
||||
else {
|
||||
timefac = (ival - sval) / (maxx - sval);
|
||||
*(td->val) = cvalc + timefac * (maxx - cvalc);
|
||||
}
|
||||
|
||||
if (adt) {
|
||||
/* global to strip */
|
||||
*(td->val) = BKE_nla_tweakedit_remap(adt, *(td->val), NLATIME_CONVERT_UNMAP);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void applyTimeSlide(TransInfo *t, const int mval[2])
|
||||
@@ -8735,34 +8735,34 @@ static void applyTimeScaleValue(TransInfo *t)
|
||||
const double secf = FPS;
|
||||
|
||||
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
|
||||
TransData *td = tc->data;
|
||||
TransData2D *td2d = tc->data_2d;
|
||||
for (i = 0; i < tc->data_len; i++, td++, td2d++) {
|
||||
/* it is assumed that td->extra is a pointer to the AnimData,
|
||||
* whose active action is where this keyframe comes from
|
||||
* (this is only valid when not in NLA)
|
||||
*/
|
||||
AnimData *adt = (t->spacetype != SPACE_NLA) ? td->extra : NULL;
|
||||
float startx = CFRA;
|
||||
float fac = t->values[0];
|
||||
TransData *td = tc->data;
|
||||
TransData2D *td2d = tc->data_2d;
|
||||
for (i = 0; i < tc->data_len; i++, td++, td2d++) {
|
||||
/* it is assumed that td->extra is a pointer to the AnimData,
|
||||
* whose active action is where this keyframe comes from
|
||||
* (this is only valid when not in NLA)
|
||||
*/
|
||||
AnimData *adt = (t->spacetype != SPACE_NLA) ? td->extra : NULL;
|
||||
float startx = CFRA;
|
||||
float fac = t->values[0];
|
||||
|
||||
if (autosnap == SACTSNAP_TSTEP) {
|
||||
fac = (float)(floor((double)fac / secf + 0.5) * secf);
|
||||
if (autosnap == SACTSNAP_TSTEP) {
|
||||
fac = (float)(floor((double)fac / secf + 0.5) * secf);
|
||||
}
|
||||
else if (autosnap == SACTSNAP_STEP) {
|
||||
fac = floorf(fac + 0.5f);
|
||||
}
|
||||
|
||||
/* check if any need to apply nla-mapping */
|
||||
if (adt)
|
||||
startx = BKE_nla_tweakedit_remap(adt, startx, NLATIME_CONVERT_UNMAP);
|
||||
|
||||
/* now, calculate the new value */
|
||||
*(td->val) = ((td->ival - startx) * fac) + startx;
|
||||
|
||||
/* apply nearest snapping */
|
||||
doAnimEdit_SnapFrame(t, td, td2d, adt, autosnap);
|
||||
}
|
||||
else if (autosnap == SACTSNAP_STEP) {
|
||||
fac = floorf(fac + 0.5f);
|
||||
}
|
||||
|
||||
/* check if any need to apply nla-mapping */
|
||||
if (adt)
|
||||
startx = BKE_nla_tweakedit_remap(adt, startx, NLATIME_CONVERT_UNMAP);
|
||||
|
||||
/* now, calculate the new value */
|
||||
*(td->val) = ((td->ival - startx) * fac) + startx;
|
||||
|
||||
/* apply nearest snapping */
|
||||
doAnimEdit_SnapFrame(t, td, td2d, adt, autosnap);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -848,55 +848,55 @@ static void drawObjectConstraint(TransInfo *t)
|
||||
float tmp_axismtx[3][3];
|
||||
|
||||
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
|
||||
TransData *td = tc->data;
|
||||
for (i = 0; i < tc->data_len; i++, td++) {
|
||||
float co[3];
|
||||
float (*axismtx)[3];
|
||||
TransData *td = tc->data;
|
||||
for (i = 0; i < tc->data_len; i++, td++) {
|
||||
float co[3];
|
||||
float (*axismtx)[3];
|
||||
|
||||
if (t->flag & T_PROP_EDIT) {
|
||||
/* we're sorted, so skip the rest */
|
||||
if (td->factor == 0.0f) {
|
||||
break;
|
||||
if (t->flag & T_PROP_EDIT) {
|
||||
/* we're sorted, so skip the rest */
|
||||
if (td->factor == 0.0f) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (t->options & CTX_GPENCIL_STROKES) {
|
||||
/* only draw a constraint line for one point, otherwise we can't see anything */
|
||||
if ((options & DRAWLIGHT) == 0) {
|
||||
break;
|
||||
if (t->options & CTX_GPENCIL_STROKES) {
|
||||
/* only draw a constraint line for one point, otherwise we can't see anything */
|
||||
if ((options & DRAWLIGHT) == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (t->flag & T_OBJECT) {
|
||||
copy_v3_v3(co, td->ob->obmat[3]);
|
||||
axismtx = td->axismtx;
|
||||
}
|
||||
else if (t->flag & T_EDIT) {
|
||||
mul_v3_m4v3(co, tc->obedit->obmat, td->center);
|
||||
if (t->flag & T_OBJECT) {
|
||||
copy_v3_v3(co, td->ob->obmat[3]);
|
||||
axismtx = td->axismtx;
|
||||
}
|
||||
else if (t->flag & T_EDIT) {
|
||||
mul_v3_m4v3(co, tc->obedit->obmat, td->center);
|
||||
|
||||
mul_m3_m3m3(tmp_axismtx, tc->obedit_mat, td->axismtx);
|
||||
axismtx = tmp_axismtx;
|
||||
}
|
||||
else if (t->flag & T_POSE) {
|
||||
mul_v3_m4v3(co, tc->poseobj->obmat, td->center);
|
||||
axismtx = td->axismtx;
|
||||
}
|
||||
else {
|
||||
copy_v3_v3(co, td->center);
|
||||
axismtx = td->axismtx;
|
||||
}
|
||||
mul_m3_m3m3(tmp_axismtx, tc->obedit_mat, td->axismtx);
|
||||
axismtx = tmp_axismtx;
|
||||
}
|
||||
else if (t->flag & T_POSE) {
|
||||
mul_v3_m4v3(co, tc->poseobj->obmat, td->center);
|
||||
axismtx = td->axismtx;
|
||||
}
|
||||
else {
|
||||
copy_v3_v3(co, td->center);
|
||||
axismtx = td->axismtx;
|
||||
}
|
||||
|
||||
if (t->con.mode & CON_AXIS0) {
|
||||
drawLine(t, co, axismtx[0], 'X', options);
|
||||
if (t->con.mode & CON_AXIS0) {
|
||||
drawLine(t, co, axismtx[0], 'X', options);
|
||||
}
|
||||
if (t->con.mode & CON_AXIS1) {
|
||||
drawLine(t, co, axismtx[1], 'Y', options);
|
||||
}
|
||||
if (t->con.mode & CON_AXIS2) {
|
||||
drawLine(t, co, axismtx[2], 'Z', options);
|
||||
}
|
||||
options &= ~DRAWLIGHT;
|
||||
}
|
||||
if (t->con.mode & CON_AXIS1) {
|
||||
drawLine(t, co, axismtx[1], 'Y', options);
|
||||
}
|
||||
if (t->con.mode & CON_AXIS2) {
|
||||
drawLine(t, co, axismtx[2], 'Z', options);
|
||||
}
|
||||
options &= ~DRAWLIGHT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -172,49 +172,49 @@ static int trans_data_compare_rdist(const void *a, const void *b)
|
||||
void sort_trans_data_dist(TransInfo *t)
|
||||
{
|
||||
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
|
||||
TransData *start = tc->data;
|
||||
int i;
|
||||
TransData *start = tc->data;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < tc->data_len && start->flag & TD_SELECTED; i++) {
|
||||
start++;
|
||||
}
|
||||
for (i = 0; i < tc->data_len && start->flag & TD_SELECTED; i++) {
|
||||
start++;
|
||||
}
|
||||
|
||||
if (i < tc->data_len) {
|
||||
if (t->flag & T_PROP_CONNECTED)
|
||||
qsort(start, tc->data_len - i, sizeof(TransData), trans_data_compare_dist);
|
||||
else
|
||||
qsort(start, tc->data_len - i, sizeof(TransData), trans_data_compare_rdist);
|
||||
}
|
||||
if (i < tc->data_len) {
|
||||
if (t->flag & T_PROP_CONNECTED)
|
||||
qsort(start, tc->data_len - i, sizeof(TransData), trans_data_compare_dist);
|
||||
else
|
||||
qsort(start, tc->data_len - i, sizeof(TransData), trans_data_compare_rdist);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void sort_trans_data(TransInfo *t)
|
||||
{
|
||||
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
|
||||
TransData *sel, *unsel;
|
||||
TransData temp;
|
||||
unsel = tc->data;
|
||||
sel = tc->data;
|
||||
sel += tc->data_len - 1;
|
||||
while (sel > unsel) {
|
||||
while (unsel->flag & TD_SELECTED) {
|
||||
unsel++;
|
||||
if (unsel == sel) {
|
||||
return;
|
||||
TransData *sel, *unsel;
|
||||
TransData temp;
|
||||
unsel = tc->data;
|
||||
sel = tc->data;
|
||||
sel += tc->data_len - 1;
|
||||
while (sel > unsel) {
|
||||
while (unsel->flag & TD_SELECTED) {
|
||||
unsel++;
|
||||
if (unsel == sel) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
while (!(sel->flag & TD_SELECTED)) {
|
||||
while (!(sel->flag & TD_SELECTED)) {
|
||||
sel--;
|
||||
if (unsel == sel) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
temp = *unsel;
|
||||
*unsel = *sel;
|
||||
*sel = temp;
|
||||
sel--;
|
||||
if (unsel == sel) {
|
||||
return;
|
||||
}
|
||||
unsel++;
|
||||
}
|
||||
temp = *unsel;
|
||||
*unsel = *sel;
|
||||
*sel = temp;
|
||||
sel--;
|
||||
unsel++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -239,53 +239,53 @@ static void set_prop_dist(TransInfo *t, const bool with_dist)
|
||||
}
|
||||
|
||||
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
|
||||
TransData *tob = tc->data;
|
||||
for (a = 0; a < tc->data_len; a++, tob++) {
|
||||
TransData *tob = tc->data;
|
||||
for (a = 0; a < tc->data_len; a++, tob++) {
|
||||
|
||||
tob->rdist = 0.0f; // init, it was mallocced
|
||||
tob->rdist = 0.0f; // init, it was mallocced
|
||||
|
||||
if ((tob->flag & TD_SELECTED) == 0) {
|
||||
TransData *td;
|
||||
int i;
|
||||
float dist_sq, vec[3];
|
||||
if ((tob->flag & TD_SELECTED) == 0) {
|
||||
TransData *td;
|
||||
int i;
|
||||
float dist_sq, vec[3];
|
||||
|
||||
tob->rdist = -1.0f; // signal for next loop
|
||||
tob->rdist = -1.0f; // signal for next loop
|
||||
|
||||
for (i = 0, td = tc->data; i < tc->data_len; i++, td++) {
|
||||
if (td->flag & TD_SELECTED) {
|
||||
if (use_island) {
|
||||
sub_v3_v3v3(vec, tob->iloc, td->iloc);
|
||||
}
|
||||
else {
|
||||
sub_v3_v3v3(vec, tob->center, td->center);
|
||||
}
|
||||
mul_m3_v3(tob->mtx, vec);
|
||||
|
||||
if (proj_vec) {
|
||||
float vec_p[3];
|
||||
project_v3_v3v3(vec_p, vec, proj_vec);
|
||||
sub_v3_v3(vec, vec_p);
|
||||
}
|
||||
|
||||
dist_sq = len_squared_v3(vec);
|
||||
if ((tob->rdist == -1.0f) || (dist_sq < SQUARE(tob->rdist))) {
|
||||
tob->rdist = sqrtf(dist_sq);
|
||||
for (i = 0, td = tc->data; i < tc->data_len; i++, td++) {
|
||||
if (td->flag & TD_SELECTED) {
|
||||
if (use_island) {
|
||||
copy_v3_v3(tob->center, td->center);
|
||||
copy_m3_m3(tob->axismtx, td->axismtx);
|
||||
sub_v3_v3v3(vec, tob->iloc, td->iloc);
|
||||
}
|
||||
else {
|
||||
sub_v3_v3v3(vec, tob->center, td->center);
|
||||
}
|
||||
mul_m3_v3(tob->mtx, vec);
|
||||
|
||||
if (proj_vec) {
|
||||
float vec_p[3];
|
||||
project_v3_v3v3(vec_p, vec, proj_vec);
|
||||
sub_v3_v3(vec, vec_p);
|
||||
}
|
||||
|
||||
dist_sq = len_squared_v3(vec);
|
||||
if ((tob->rdist == -1.0f) || (dist_sq < SQUARE(tob->rdist))) {
|
||||
tob->rdist = sqrtf(dist_sq);
|
||||
if (use_island) {
|
||||
copy_v3_v3(tob->center, td->center);
|
||||
copy_m3_m3(tob->axismtx, td->axismtx);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
break; /* by definition transdata has selected items in beginning */
|
||||
}
|
||||
}
|
||||
else {
|
||||
break; /* by definition transdata has selected items in beginning */
|
||||
if (with_dist) {
|
||||
tob->dist = tob->rdist;
|
||||
}
|
||||
}
|
||||
if (with_dist) {
|
||||
tob->dist = tob->rdist;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ************************** CONVERSIONS ************************* */
|
||||
@@ -355,76 +355,76 @@ static void createTransEdge(TransInfo *t)
|
||||
{
|
||||
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
|
||||
|
||||
BMEditMesh *em = BKE_editmesh_from_object(tc->obedit);
|
||||
TransData *td = NULL;
|
||||
BMEdge *eed;
|
||||
BMIter iter;
|
||||
float mtx[3][3], smtx[3][3];
|
||||
int count = 0, countsel = 0;
|
||||
const bool is_prop_edit = (t->flag & T_PROP_EDIT) != 0;
|
||||
int cd_edge_float_offset;
|
||||
BMEditMesh *em = BKE_editmesh_from_object(tc->obedit);
|
||||
TransData *td = NULL;
|
||||
BMEdge *eed;
|
||||
BMIter iter;
|
||||
float mtx[3][3], smtx[3][3];
|
||||
int count = 0, countsel = 0;
|
||||
const bool is_prop_edit = (t->flag & T_PROP_EDIT) != 0;
|
||||
int cd_edge_float_offset;
|
||||
|
||||
BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) {
|
||||
if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) {
|
||||
if (BM_elem_flag_test(eed, BM_ELEM_SELECT)) countsel++;
|
||||
if (is_prop_edit) count++;
|
||||
BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) {
|
||||
if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) {
|
||||
if (BM_elem_flag_test(eed, BM_ELEM_SELECT)) countsel++;
|
||||
if (is_prop_edit) count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (countsel == 0) {
|
||||
tc->data_len = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (is_prop_edit) {
|
||||
tc->data_len = count;
|
||||
}
|
||||
else {
|
||||
tc->data_len = countsel;
|
||||
}
|
||||
|
||||
td = tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransCrease");
|
||||
|
||||
copy_m3_m4(mtx, tc->obedit->obmat);
|
||||
pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON);
|
||||
|
||||
/* create data we need */
|
||||
if (t->mode == TFM_BWEIGHT) {
|
||||
BM_mesh_cd_flag_ensure(em->bm, BKE_mesh_from_object(tc->obedit), ME_CDFLAG_EDGE_BWEIGHT);
|
||||
cd_edge_float_offset = CustomData_get_offset(&em->bm->edata, CD_BWEIGHT);
|
||||
}
|
||||
else { //if (t->mode == TFM_CREASE) {
|
||||
BLI_assert(t->mode == TFM_CREASE);
|
||||
BM_mesh_cd_flag_ensure(em->bm, BKE_mesh_from_object(tc->obedit), ME_CDFLAG_EDGE_CREASE);
|
||||
cd_edge_float_offset = CustomData_get_offset(&em->bm->edata, CD_CREASE);
|
||||
}
|
||||
|
||||
BLI_assert(cd_edge_float_offset != -1);
|
||||
|
||||
BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) {
|
||||
if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN) && (BM_elem_flag_test(eed, BM_ELEM_SELECT) || is_prop_edit)) {
|
||||
float *fl_ptr;
|
||||
/* need to set center for center calculations */
|
||||
mid_v3_v3v3(td->center, eed->v1->co, eed->v2->co);
|
||||
|
||||
td->loc = NULL;
|
||||
if (BM_elem_flag_test(eed, BM_ELEM_SELECT))
|
||||
td->flag = TD_SELECTED;
|
||||
else
|
||||
td->flag = 0;
|
||||
|
||||
copy_m3_m3(td->smtx, smtx);
|
||||
copy_m3_m3(td->mtx, mtx);
|
||||
|
||||
td->ext = NULL;
|
||||
|
||||
fl_ptr = BM_ELEM_CD_GET_VOID_P(eed, cd_edge_float_offset);
|
||||
td->val = fl_ptr;
|
||||
td->ival = *fl_ptr;
|
||||
|
||||
td++;
|
||||
if (countsel == 0) {
|
||||
tc->data_len = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (is_prop_edit) {
|
||||
tc->data_len = count;
|
||||
}
|
||||
else {
|
||||
tc->data_len = countsel;
|
||||
}
|
||||
|
||||
td = tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransCrease");
|
||||
|
||||
copy_m3_m4(mtx, tc->obedit->obmat);
|
||||
pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON);
|
||||
|
||||
/* create data we need */
|
||||
if (t->mode == TFM_BWEIGHT) {
|
||||
BM_mesh_cd_flag_ensure(em->bm, BKE_mesh_from_object(tc->obedit), ME_CDFLAG_EDGE_BWEIGHT);
|
||||
cd_edge_float_offset = CustomData_get_offset(&em->bm->edata, CD_BWEIGHT);
|
||||
}
|
||||
else { //if (t->mode == TFM_CREASE) {
|
||||
BLI_assert(t->mode == TFM_CREASE);
|
||||
BM_mesh_cd_flag_ensure(em->bm, BKE_mesh_from_object(tc->obedit), ME_CDFLAG_EDGE_CREASE);
|
||||
cd_edge_float_offset = CustomData_get_offset(&em->bm->edata, CD_CREASE);
|
||||
}
|
||||
|
||||
BLI_assert(cd_edge_float_offset != -1);
|
||||
|
||||
BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) {
|
||||
if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN) && (BM_elem_flag_test(eed, BM_ELEM_SELECT) || is_prop_edit)) {
|
||||
float *fl_ptr;
|
||||
/* need to set center for center calculations */
|
||||
mid_v3_v3v3(td->center, eed->v1->co, eed->v2->co);
|
||||
|
||||
td->loc = NULL;
|
||||
if (BM_elem_flag_test(eed, BM_ELEM_SELECT))
|
||||
td->flag = TD_SELECTED;
|
||||
else
|
||||
td->flag = 0;
|
||||
|
||||
copy_m3_m3(td->smtx, smtx);
|
||||
copy_m3_m3(td->mtx, mtx);
|
||||
|
||||
td->ext = NULL;
|
||||
|
||||
fl_ptr = BM_ELEM_CD_GET_VOID_P(eed, cd_edge_float_offset);
|
||||
td->val = fl_ptr;
|
||||
td->ival = *fl_ptr;
|
||||
|
||||
td++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -851,14 +851,14 @@ void transform_autoik_update(TransInfo *t, short mode)
|
||||
|
||||
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
|
||||
|
||||
/* sanity checks (don't assume t->poseobj is set, or that it is an armature) */
|
||||
if (ELEM(NULL, tc->poseobj, tc->poseobj->pose)) {
|
||||
continue;
|
||||
}
|
||||
/* sanity checks (don't assume t->poseobj is set, or that it is an armature) */
|
||||
if (ELEM(NULL, tc->poseobj, tc->poseobj->pose)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (pchan = tc->poseobj->pose->chanbase.first; pchan; pchan = pchan->next) {
|
||||
changed |= pchan_autoik_adjust(pchan, *chainlen);
|
||||
}
|
||||
for (pchan = tc->poseobj->pose->chanbase.first; pchan; pchan = pchan->next) {
|
||||
changed |= pchan_autoik_adjust(pchan, *chainlen);
|
||||
}
|
||||
}
|
||||
|
||||
if (changed) {
|
||||
@@ -1088,69 +1088,69 @@ static void createTransPose(TransInfo *t, Object **objects, uint objects_len)
|
||||
t->data_len_all = 0;
|
||||
|
||||
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
|
||||
Object *ob = tc->poseobj;
|
||||
Object *ob = tc->poseobj;
|
||||
|
||||
bArmature *arm;
|
||||
bPoseChannel *pchan;
|
||||
TransData *td;
|
||||
TransDataExtension *tdx;
|
||||
short ik_on = 0;
|
||||
int i;
|
||||
bArmature *arm;
|
||||
bPoseChannel *pchan;
|
||||
TransData *td;
|
||||
TransDataExtension *tdx;
|
||||
short ik_on = 0;
|
||||
int i;
|
||||
|
||||
|
||||
/* check validity of state */
|
||||
arm = BKE_armature_from_object(tc->poseobj);
|
||||
if ((arm == NULL) || (ob->pose == NULL)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (arm->flag & ARM_RESTPOS) {
|
||||
if (ELEM(t->mode, TFM_DUMMY, TFM_BONESIZE) == 0) {
|
||||
BKE_report(t->reports, RPT_ERROR, "Cannot change Pose when 'Rest Position' is enabled");
|
||||
return;
|
||||
/* check validity of state */
|
||||
arm = BKE_armature_from_object(tc->poseobj);
|
||||
if ((arm == NULL) || (ob->pose == NULL)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* do we need to add temporal IK chains? */
|
||||
if ((arm->flag & ARM_AUTO_IK) && t->mode == TFM_TRANSLATION) {
|
||||
ik_on = pose_grab_with_ik(ob);
|
||||
if (ik_on) t->flag |= T_AUTOIK;
|
||||
}
|
||||
|
||||
/* set flags and count total (warning, can change transform to rotate) */
|
||||
tc->data_len = count_set_pose_transflags(&t->mode, t->around, ob);
|
||||
|
||||
if (tc->data_len == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
tc->poseobj = ob; /* we also allow non-active objects to be transformed, in weightpaint */
|
||||
|
||||
/* init trans data */
|
||||
td = tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransPoseBone");
|
||||
tdx = tc->data_ext = MEM_callocN(tc->data_len * sizeof(TransDataExtension), "TransPoseBoneExt");
|
||||
for (i = 0; i < tc->data_len; i++, td++, tdx++) {
|
||||
td->ext = tdx;
|
||||
td->val = NULL;
|
||||
}
|
||||
|
||||
/* use pose channels to fill trans data */
|
||||
td = tc->data;
|
||||
for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
|
||||
if (pchan->bone->flag & BONE_TRANSFORM) {
|
||||
add_pose_transdata(t, pchan, ob, tc, td);
|
||||
td++;
|
||||
if (arm->flag & ARM_RESTPOS) {
|
||||
if (ELEM(t->mode, TFM_DUMMY, TFM_BONESIZE) == 0) {
|
||||
BKE_report(t->reports, RPT_ERROR, "Cannot change Pose when 'Rest Position' is enabled");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (td != (tc->data + tc->data_len)) {
|
||||
BKE_report(t->reports, RPT_DEBUG, "Bone selection count error");
|
||||
}
|
||||
/* do we need to add temporal IK chains? */
|
||||
if ((arm->flag & ARM_AUTO_IK) && t->mode == TFM_TRANSLATION) {
|
||||
ik_on = pose_grab_with_ik(ob);
|
||||
if (ik_on) t->flag |= T_AUTOIK;
|
||||
}
|
||||
|
||||
/* initialize initial auto=ik chainlen's? */
|
||||
if (ik_on) {
|
||||
transform_autoik_update(t, 0);
|
||||
}
|
||||
/* set flags and count total (warning, can change transform to rotate) */
|
||||
tc->data_len = count_set_pose_transflags(&t->mode, t->around, ob);
|
||||
|
||||
if (tc->data_len == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
tc->poseobj = ob; /* we also allow non-active objects to be transformed, in weightpaint */
|
||||
|
||||
/* init trans data */
|
||||
td = tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransPoseBone");
|
||||
tdx = tc->data_ext = MEM_callocN(tc->data_len * sizeof(TransDataExtension), "TransPoseBoneExt");
|
||||
for (i = 0; i < tc->data_len; i++, td++, tdx++) {
|
||||
td->ext = tdx;
|
||||
td->val = NULL;
|
||||
}
|
||||
|
||||
/* use pose channels to fill trans data */
|
||||
td = tc->data;
|
||||
for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
|
||||
if (pchan->bone->flag & BONE_TRANSFORM) {
|
||||
add_pose_transdata(t, pchan, ob, tc, td);
|
||||
td++;
|
||||
}
|
||||
}
|
||||
|
||||
if (td != (tc->data + tc->data_len)) {
|
||||
BKE_report(t->reports, RPT_DEBUG, "Bone selection count error");
|
||||
}
|
||||
|
||||
/* initialize initial auto=ik chainlen's? */
|
||||
if (ik_on) {
|
||||
transform_autoik_update(t, 0);
|
||||
}
|
||||
}
|
||||
|
||||
t->flag |= T_POSE;
|
||||
@@ -1204,230 +1204,230 @@ void restoreBones(TransDataContainer *tc)
|
||||
static void createTransArmatureVerts(TransInfo *t)
|
||||
{
|
||||
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
|
||||
EditBone *ebo, *eboflip;
|
||||
bArmature *arm = tc->obedit->data;
|
||||
ListBase *edbo = arm->edbo;
|
||||
TransData *td, *td_old;
|
||||
float mtx[3][3], smtx[3][3], bonemat[3][3];
|
||||
bool mirror = ((arm->flag & ARM_MIRROR_EDIT) != 0);
|
||||
int total_mirrored = 0, i;
|
||||
int oldtot;
|
||||
BoneInitData *bid;
|
||||
|
||||
tc->data_len = 0;
|
||||
for (ebo = edbo->first; ebo; ebo = ebo->next) {
|
||||
oldtot = tc->data_len;
|
||||
EditBone *ebo, *eboflip;
|
||||
bArmature *arm = tc->obedit->data;
|
||||
ListBase *edbo = arm->edbo;
|
||||
TransData *td, *td_old;
|
||||
float mtx[3][3], smtx[3][3], bonemat[3][3];
|
||||
bool mirror = ((arm->flag & ARM_MIRROR_EDIT) != 0);
|
||||
int total_mirrored = 0, i;
|
||||
int oldtot;
|
||||
BoneInitData *bid;
|
||||
|
||||
if (EBONE_VISIBLE(arm, ebo) && !(ebo->flag & BONE_EDITMODE_LOCKED)) {
|
||||
if (ELEM(t->mode, TFM_BONESIZE, TFM_BONE_ENVELOPE_DIST)) {
|
||||
if (ebo->flag & BONE_SELECTED)
|
||||
tc->data_len++;
|
||||
tc->data_len = 0;
|
||||
for (ebo = edbo->first; ebo; ebo = ebo->next) {
|
||||
oldtot = tc->data_len;
|
||||
|
||||
if (EBONE_VISIBLE(arm, ebo) && !(ebo->flag & BONE_EDITMODE_LOCKED)) {
|
||||
if (ELEM(t->mode, TFM_BONESIZE, TFM_BONE_ENVELOPE_DIST)) {
|
||||
if (ebo->flag & BONE_SELECTED)
|
||||
tc->data_len++;
|
||||
}
|
||||
else if (t->mode == TFM_BONE_ROLL) {
|
||||
if (ebo->flag & BONE_SELECTED)
|
||||
tc->data_len++;
|
||||
}
|
||||
else {
|
||||
if (ebo->flag & BONE_TIPSEL)
|
||||
tc->data_len++;
|
||||
if (ebo->flag & BONE_ROOTSEL)
|
||||
tc->data_len++;
|
||||
}
|
||||
}
|
||||
else if (t->mode == TFM_BONE_ROLL) {
|
||||
if (ebo->flag & BONE_SELECTED)
|
||||
tc->data_len++;
|
||||
}
|
||||
else {
|
||||
if (ebo->flag & BONE_TIPSEL)
|
||||
tc->data_len++;
|
||||
if (ebo->flag & BONE_ROOTSEL)
|
||||
tc->data_len++;
|
||||
|
||||
if (mirror && (oldtot < tc->data_len)) {
|
||||
eboflip = ED_armature_ebone_get_mirrored(arm->edbo, ebo);
|
||||
if (eboflip)
|
||||
total_mirrored++;
|
||||
}
|
||||
}
|
||||
|
||||
if (mirror && (oldtot < tc->data_len)) {
|
||||
eboflip = ED_armature_ebone_get_mirrored(arm->edbo, ebo);
|
||||
if (eboflip)
|
||||
total_mirrored++;
|
||||
if (!tc->data_len) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (!tc->data_len) {
|
||||
continue;
|
||||
}
|
||||
transform_around_single_fallback(t);
|
||||
|
||||
transform_around_single_fallback(t);
|
||||
copy_m3_m4(mtx, tc->obedit->obmat);
|
||||
pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON);
|
||||
|
||||
copy_m3_m4(mtx, tc->obedit->obmat);
|
||||
pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON);
|
||||
td = tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransEditBone");
|
||||
|
||||
td = tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransEditBone");
|
||||
if (mirror) {
|
||||
tc->custom.type.data = bid = MEM_mallocN((total_mirrored + 1) * sizeof(BoneInitData), "BoneInitData");
|
||||
tc->custom.type.use_free = true;
|
||||
}
|
||||
|
||||
if (mirror) {
|
||||
tc->custom.type.data = bid = MEM_mallocN((total_mirrored + 1) * sizeof(BoneInitData), "BoneInitData");
|
||||
tc->custom.type.use_free = true;
|
||||
}
|
||||
i = 0;
|
||||
|
||||
i = 0;
|
||||
for (ebo = edbo->first; ebo; ebo = ebo->next) {
|
||||
td_old = td;
|
||||
ebo->oldlength = ebo->length; // length==0.0 on extrude, used for scaling radius of bone points
|
||||
|
||||
for (ebo = edbo->first; ebo; ebo = ebo->next) {
|
||||
td_old = td;
|
||||
ebo->oldlength = ebo->length; // length==0.0 on extrude, used for scaling radius of bone points
|
||||
if (EBONE_VISIBLE(arm, ebo) && !(ebo->flag & BONE_EDITMODE_LOCKED)) {
|
||||
if (t->mode == TFM_BONE_ENVELOPE) {
|
||||
if (ebo->flag & BONE_ROOTSEL) {
|
||||
td->val = &ebo->rad_head;
|
||||
td->ival = *td->val;
|
||||
|
||||
if (EBONE_VISIBLE(arm, ebo) && !(ebo->flag & BONE_EDITMODE_LOCKED)) {
|
||||
if (t->mode == TFM_BONE_ENVELOPE) {
|
||||
if (ebo->flag & BONE_ROOTSEL) {
|
||||
td->val = &ebo->rad_head;
|
||||
td->ival = *td->val;
|
||||
|
||||
copy_v3_v3(td->center, ebo->head);
|
||||
td->flag = TD_SELECTED;
|
||||
|
||||
copy_m3_m3(td->smtx, smtx);
|
||||
copy_m3_m3(td->mtx, mtx);
|
||||
|
||||
td->loc = NULL;
|
||||
td->ext = NULL;
|
||||
td->ob = tc->obedit;
|
||||
|
||||
td++;
|
||||
}
|
||||
if (ebo->flag & BONE_TIPSEL) {
|
||||
td->val = &ebo->rad_tail;
|
||||
td->ival = *td->val;
|
||||
copy_v3_v3(td->center, ebo->tail);
|
||||
td->flag = TD_SELECTED;
|
||||
|
||||
copy_m3_m3(td->smtx, smtx);
|
||||
copy_m3_m3(td->mtx, mtx);
|
||||
|
||||
td->loc = NULL;
|
||||
td->ext = NULL;
|
||||
td->ob = tc->obedit;
|
||||
|
||||
td++;
|
||||
}
|
||||
|
||||
}
|
||||
else if (ELEM(t->mode, TFM_BONESIZE, TFM_BONE_ENVELOPE_DIST)) {
|
||||
if (ebo->flag & BONE_SELECTED) {
|
||||
if ((t->mode == TFM_BONE_ENVELOPE_DIST) || (arm->drawtype == ARM_ENVELOPE)) {
|
||||
td->loc = NULL;
|
||||
td->val = &ebo->dist;
|
||||
td->ival = ebo->dist;
|
||||
}
|
||||
else {
|
||||
// abusive storage of scale in the loc pointer :)
|
||||
td->loc = &ebo->xwidth;
|
||||
copy_v3_v3(td->iloc, td->loc);
|
||||
td->val = NULL;
|
||||
}
|
||||
copy_v3_v3(td->center, ebo->head);
|
||||
td->flag = TD_SELECTED;
|
||||
|
||||
/* use local bone matrix */
|
||||
ED_armature_ebone_to_mat3(ebo, bonemat);
|
||||
mul_m3_m3m3(td->mtx, mtx, bonemat);
|
||||
invert_m3_m3(td->smtx, td->mtx);
|
||||
|
||||
copy_m3_m3(td->axismtx, td->mtx);
|
||||
normalize_m3(td->axismtx);
|
||||
|
||||
td->ext = NULL;
|
||||
td->ob = tc->obedit;
|
||||
|
||||
td++;
|
||||
}
|
||||
}
|
||||
else if (t->mode == TFM_BONE_ROLL) {
|
||||
if (ebo->flag & BONE_SELECTED) {
|
||||
td->loc = NULL;
|
||||
td->val = &(ebo->roll);
|
||||
td->ival = ebo->roll;
|
||||
|
||||
copy_v3_v3(td->center, ebo->head);
|
||||
td->flag = TD_SELECTED;
|
||||
|
||||
td->ext = NULL;
|
||||
td->ob = tc->obedit;
|
||||
|
||||
td++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (ebo->flag & BONE_TIPSEL) {
|
||||
copy_v3_v3(td->iloc, ebo->tail);
|
||||
|
||||
/* Don't allow single selected tips to have a modified center,
|
||||
* causes problem with snapping (see T45974).
|
||||
* However, in rotation mode, we want to keep that 'rotate bone around root with
|
||||
* only its tip selected' behavior (see T46325). */
|
||||
if ((t->around == V3D_AROUND_LOCAL_ORIGINS) &&
|
||||
((t->mode == TFM_ROTATION) || (ebo->flag & BONE_ROOTSEL)))
|
||||
{
|
||||
copy_v3_v3(td->center, ebo->head);
|
||||
td->flag = TD_SELECTED;
|
||||
|
||||
copy_m3_m3(td->smtx, smtx);
|
||||
copy_m3_m3(td->mtx, mtx);
|
||||
|
||||
td->loc = NULL;
|
||||
td->ext = NULL;
|
||||
td->ob = tc->obedit;
|
||||
|
||||
td++;
|
||||
}
|
||||
else {
|
||||
copy_v3_v3(td->center, td->iloc);
|
||||
if (ebo->flag & BONE_TIPSEL) {
|
||||
td->val = &ebo->rad_tail;
|
||||
td->ival = *td->val;
|
||||
copy_v3_v3(td->center, ebo->tail);
|
||||
td->flag = TD_SELECTED;
|
||||
|
||||
copy_m3_m3(td->smtx, smtx);
|
||||
copy_m3_m3(td->mtx, mtx);
|
||||
|
||||
td->loc = NULL;
|
||||
td->ext = NULL;
|
||||
td->ob = tc->obedit;
|
||||
|
||||
td++;
|
||||
}
|
||||
|
||||
td->loc = ebo->tail;
|
||||
td->flag = TD_SELECTED;
|
||||
if (ebo->flag & BONE_EDITMODE_LOCKED)
|
||||
td->protectflag = OB_LOCK_LOC | OB_LOCK_ROT | OB_LOCK_SCALE;
|
||||
}
|
||||
else if (ELEM(t->mode, TFM_BONESIZE, TFM_BONE_ENVELOPE_DIST)) {
|
||||
if (ebo->flag & BONE_SELECTED) {
|
||||
if ((t->mode == TFM_BONE_ENVELOPE_DIST) || (arm->drawtype == ARM_ENVELOPE)) {
|
||||
td->loc = NULL;
|
||||
td->val = &ebo->dist;
|
||||
td->ival = ebo->dist;
|
||||
}
|
||||
else {
|
||||
// abusive storage of scale in the loc pointer :)
|
||||
td->loc = &ebo->xwidth;
|
||||
copy_v3_v3(td->iloc, td->loc);
|
||||
td->val = NULL;
|
||||
}
|
||||
copy_v3_v3(td->center, ebo->head);
|
||||
td->flag = TD_SELECTED;
|
||||
|
||||
copy_m3_m3(td->smtx, smtx);
|
||||
copy_m3_m3(td->mtx, mtx);
|
||||
/* use local bone matrix */
|
||||
ED_armature_ebone_to_mat3(ebo, bonemat);
|
||||
mul_m3_m3m3(td->mtx, mtx, bonemat);
|
||||
invert_m3_m3(td->smtx, td->mtx);
|
||||
|
||||
ED_armature_ebone_to_mat3(ebo, td->axismtx);
|
||||
copy_m3_m3(td->axismtx, td->mtx);
|
||||
normalize_m3(td->axismtx);
|
||||
|
||||
if ((ebo->flag & BONE_ROOTSEL) == 0) {
|
||||
td->extra = ebo;
|
||||
td->ext = NULL;
|
||||
td->ob = tc->obedit;
|
||||
|
||||
td++;
|
||||
}
|
||||
}
|
||||
else if (t->mode == TFM_BONE_ROLL) {
|
||||
if (ebo->flag & BONE_SELECTED) {
|
||||
td->loc = NULL;
|
||||
td->val = &(ebo->roll);
|
||||
td->ival = ebo->roll;
|
||||
|
||||
copy_v3_v3(td->center, ebo->head);
|
||||
td->flag = TD_SELECTED;
|
||||
|
||||
td->ext = NULL;
|
||||
td->ob = tc->obedit;
|
||||
|
||||
td++;
|
||||
}
|
||||
|
||||
td->ext = NULL;
|
||||
td->val = NULL;
|
||||
td->ob = tc->obedit;
|
||||
|
||||
td++;
|
||||
}
|
||||
if (ebo->flag & BONE_ROOTSEL) {
|
||||
copy_v3_v3(td->iloc, ebo->head);
|
||||
copy_v3_v3(td->center, td->iloc);
|
||||
td->loc = ebo->head;
|
||||
td->flag = TD_SELECTED;
|
||||
if (ebo->flag & BONE_EDITMODE_LOCKED)
|
||||
td->protectflag = OB_LOCK_LOC | OB_LOCK_ROT | OB_LOCK_SCALE;
|
||||
else {
|
||||
if (ebo->flag & BONE_TIPSEL) {
|
||||
copy_v3_v3(td->iloc, ebo->tail);
|
||||
|
||||
copy_m3_m3(td->smtx, smtx);
|
||||
copy_m3_m3(td->mtx, mtx);
|
||||
/* Don't allow single selected tips to have a modified center,
|
||||
* causes problem with snapping (see T45974).
|
||||
* However, in rotation mode, we want to keep that 'rotate bone around root with
|
||||
* only its tip selected' behavior (see T46325). */
|
||||
if ((t->around == V3D_AROUND_LOCAL_ORIGINS) &&
|
||||
((t->mode == TFM_ROTATION) || (ebo->flag & BONE_ROOTSEL)))
|
||||
{
|
||||
copy_v3_v3(td->center, ebo->head);
|
||||
}
|
||||
else {
|
||||
copy_v3_v3(td->center, td->iloc);
|
||||
}
|
||||
|
||||
ED_armature_ebone_to_mat3(ebo, td->axismtx);
|
||||
td->loc = ebo->tail;
|
||||
td->flag = TD_SELECTED;
|
||||
if (ebo->flag & BONE_EDITMODE_LOCKED)
|
||||
td->protectflag = OB_LOCK_LOC | OB_LOCK_ROT | OB_LOCK_SCALE;
|
||||
|
||||
td->extra = ebo; /* to fix roll */
|
||||
td->ival = ebo->roll;
|
||||
copy_m3_m3(td->smtx, smtx);
|
||||
copy_m3_m3(td->mtx, mtx);
|
||||
|
||||
td->ext = NULL;
|
||||
td->val = NULL;
|
||||
td->ob = tc->obedit;
|
||||
ED_armature_ebone_to_mat3(ebo, td->axismtx);
|
||||
|
||||
td++;
|
||||
if ((ebo->flag & BONE_ROOTSEL) == 0) {
|
||||
td->extra = ebo;
|
||||
td->ival = ebo->roll;
|
||||
}
|
||||
|
||||
td->ext = NULL;
|
||||
td->val = NULL;
|
||||
td->ob = tc->obedit;
|
||||
|
||||
td++;
|
||||
}
|
||||
if (ebo->flag & BONE_ROOTSEL) {
|
||||
copy_v3_v3(td->iloc, ebo->head);
|
||||
copy_v3_v3(td->center, td->iloc);
|
||||
td->loc = ebo->head;
|
||||
td->flag = TD_SELECTED;
|
||||
if (ebo->flag & BONE_EDITMODE_LOCKED)
|
||||
td->protectflag = OB_LOCK_LOC | OB_LOCK_ROT | OB_LOCK_SCALE;
|
||||
|
||||
copy_m3_m3(td->smtx, smtx);
|
||||
copy_m3_m3(td->mtx, mtx);
|
||||
|
||||
ED_armature_ebone_to_mat3(ebo, td->axismtx);
|
||||
|
||||
td->extra = ebo; /* to fix roll */
|
||||
td->ival = ebo->roll;
|
||||
|
||||
td->ext = NULL;
|
||||
td->val = NULL;
|
||||
td->ob = tc->obedit;
|
||||
|
||||
td++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mirror && (td_old != td)) {
|
||||
eboflip = ED_armature_ebone_get_mirrored(arm->edbo, ebo);
|
||||
if (eboflip) {
|
||||
bid[i].bone = eboflip;
|
||||
bid[i].dist = eboflip->dist;
|
||||
bid[i].rad_tail = eboflip->rad_tail;
|
||||
bid[i].roll = eboflip->roll;
|
||||
bid[i].xwidth = eboflip->xwidth;
|
||||
bid[i].zwidth = eboflip->zwidth;
|
||||
copy_v3_v3(bid[i].head, eboflip->head);
|
||||
copy_v3_v3(bid[i].tail, eboflip->tail);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mirror && (td_old != td)) {
|
||||
eboflip = ED_armature_ebone_get_mirrored(arm->edbo, ebo);
|
||||
if (eboflip) {
|
||||
bid[i].bone = eboflip;
|
||||
bid[i].dist = eboflip->dist;
|
||||
bid[i].rad_tail = eboflip->rad_tail;
|
||||
bid[i].roll = eboflip->roll;
|
||||
bid[i].xwidth = eboflip->xwidth;
|
||||
bid[i].zwidth = eboflip->zwidth;
|
||||
copy_v3_v3(bid[i].head, eboflip->head);
|
||||
copy_v3_v3(bid[i].tail, eboflip->tail);
|
||||
i++;
|
||||
}
|
||||
if (mirror) {
|
||||
/* trick to terminate iteration */
|
||||
bid[total_mirrored].bone = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (mirror) {
|
||||
/* trick to terminate iteration */
|
||||
bid[total_mirrored].bone = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ********************* meta elements ********* */
|
||||
@@ -1435,76 +1435,76 @@ static void createTransArmatureVerts(TransInfo *t)
|
||||
static void createTransMBallVerts(TransInfo *t)
|
||||
{
|
||||
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
|
||||
MetaBall *mb = (MetaBall *)tc->obedit->data;
|
||||
MetaElem *ml;
|
||||
TransData *td;
|
||||
TransDataExtension *tx;
|
||||
float mtx[3][3], smtx[3][3];
|
||||
int count = 0, countsel = 0;
|
||||
const bool is_prop_edit = (t->flag & T_PROP_EDIT) != 0;
|
||||
MetaBall *mb = (MetaBall *)tc->obedit->data;
|
||||
MetaElem *ml;
|
||||
TransData *td;
|
||||
TransDataExtension *tx;
|
||||
float mtx[3][3], smtx[3][3];
|
||||
int count = 0, countsel = 0;
|
||||
const bool is_prop_edit = (t->flag & T_PROP_EDIT) != 0;
|
||||
|
||||
/* count totals */
|
||||
for (ml = mb->editelems->first; ml; ml = ml->next) {
|
||||
if (ml->flag & SELECT) countsel++;
|
||||
if (is_prop_edit) count++;
|
||||
}
|
||||
|
||||
/* note: in prop mode we need at least 1 selected */
|
||||
if (countsel == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (is_prop_edit) tc->data_len = count;
|
||||
else tc->data_len = countsel;
|
||||
|
||||
td = tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransObData(MBall EditMode)");
|
||||
tx = tc->data_ext = MEM_callocN(tc->data_len * sizeof(TransDataExtension), "MetaElement_TransExtension");
|
||||
|
||||
copy_m3_m4(mtx, tc->obedit->obmat);
|
||||
pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON);
|
||||
|
||||
for (ml = mb->editelems->first; ml; ml = ml->next) {
|
||||
if (is_prop_edit || (ml->flag & SELECT)) {
|
||||
td->loc = &ml->x;
|
||||
copy_v3_v3(td->iloc, td->loc);
|
||||
copy_v3_v3(td->center, td->loc);
|
||||
|
||||
quat_to_mat3(td->axismtx, ml->quat);
|
||||
|
||||
if (ml->flag & SELECT) td->flag = TD_SELECTED | TD_USEQUAT | TD_SINGLESIZE;
|
||||
else td->flag = TD_USEQUAT;
|
||||
|
||||
copy_m3_m3(td->smtx, smtx);
|
||||
copy_m3_m3(td->mtx, mtx);
|
||||
|
||||
td->ext = tx;
|
||||
|
||||
/* Radius of MetaElem (mass of MetaElem influence) */
|
||||
if (ml->flag & MB_SCALE_RAD) {
|
||||
td->val = &ml->rad;
|
||||
td->ival = ml->rad;
|
||||
}
|
||||
else {
|
||||
td->val = &ml->s;
|
||||
td->ival = ml->s;
|
||||
}
|
||||
|
||||
/* expx/expy/expz determine "shape" of some MetaElem types */
|
||||
tx->size = &ml->expx;
|
||||
tx->isize[0] = ml->expx;
|
||||
tx->isize[1] = ml->expy;
|
||||
tx->isize[2] = ml->expz;
|
||||
|
||||
/* quat is used for rotation of MetaElem */
|
||||
tx->quat = ml->quat;
|
||||
copy_qt_qt(tx->iquat, ml->quat);
|
||||
|
||||
tx->rot = NULL;
|
||||
|
||||
td++;
|
||||
tx++;
|
||||
/* count totals */
|
||||
for (ml = mb->editelems->first; ml; ml = ml->next) {
|
||||
if (ml->flag & SELECT) countsel++;
|
||||
if (is_prop_edit) count++;
|
||||
}
|
||||
|
||||
/* note: in prop mode we need at least 1 selected */
|
||||
if (countsel == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (is_prop_edit) tc->data_len = count;
|
||||
else tc->data_len = countsel;
|
||||
|
||||
td = tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransObData(MBall EditMode)");
|
||||
tx = tc->data_ext = MEM_callocN(tc->data_len * sizeof(TransDataExtension), "MetaElement_TransExtension");
|
||||
|
||||
copy_m3_m4(mtx, tc->obedit->obmat);
|
||||
pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON);
|
||||
|
||||
for (ml = mb->editelems->first; ml; ml = ml->next) {
|
||||
if (is_prop_edit || (ml->flag & SELECT)) {
|
||||
td->loc = &ml->x;
|
||||
copy_v3_v3(td->iloc, td->loc);
|
||||
copy_v3_v3(td->center, td->loc);
|
||||
|
||||
quat_to_mat3(td->axismtx, ml->quat);
|
||||
|
||||
if (ml->flag & SELECT) td->flag = TD_SELECTED | TD_USEQUAT | TD_SINGLESIZE;
|
||||
else td->flag = TD_USEQUAT;
|
||||
|
||||
copy_m3_m3(td->smtx, smtx);
|
||||
copy_m3_m3(td->mtx, mtx);
|
||||
|
||||
td->ext = tx;
|
||||
|
||||
/* Radius of MetaElem (mass of MetaElem influence) */
|
||||
if (ml->flag & MB_SCALE_RAD) {
|
||||
td->val = &ml->rad;
|
||||
td->ival = ml->rad;
|
||||
}
|
||||
else {
|
||||
td->val = &ml->s;
|
||||
td->ival = ml->s;
|
||||
}
|
||||
|
||||
/* expx/expy/expz determine "shape" of some MetaElem types */
|
||||
tx->size = &ml->expx;
|
||||
tx->isize[0] = ml->expx;
|
||||
tx->isize[1] = ml->expy;
|
||||
tx->isize[2] = ml->expz;
|
||||
|
||||
/* quat is used for rotation of MetaElem */
|
||||
tx->quat = ml->quat;
|
||||
copy_qt_qt(tx->iquat, ml->quat);
|
||||
|
||||
tx->rot = NULL;
|
||||
|
||||
td++;
|
||||
tx++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1614,274 +1614,274 @@ static void createTransCurveVerts(TransInfo *t)
|
||||
{
|
||||
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
|
||||
|
||||
Curve *cu = tc->obedit->data;
|
||||
TransData *td = NULL;
|
||||
Nurb *nu;
|
||||
BezTriple *bezt;
|
||||
BPoint *bp;
|
||||
float mtx[3][3], smtx[3][3];
|
||||
int a;
|
||||
int count = 0, countsel = 0;
|
||||
const bool is_prop_edit = (t->flag & T_PROP_EDIT) != 0;
|
||||
short hide_handles = (cu->drawflag & CU_HIDE_HANDLES);
|
||||
ListBase *nurbs;
|
||||
Curve *cu = tc->obedit->data;
|
||||
TransData *td = NULL;
|
||||
Nurb *nu;
|
||||
BezTriple *bezt;
|
||||
BPoint *bp;
|
||||
float mtx[3][3], smtx[3][3];
|
||||
int a;
|
||||
int count = 0, countsel = 0;
|
||||
const bool is_prop_edit = (t->flag & T_PROP_EDIT) != 0;
|
||||
short hide_handles = (cu->drawflag & CU_HIDE_HANDLES);
|
||||
ListBase *nurbs;
|
||||
|
||||
/* to be sure */
|
||||
if (cu->editnurb == NULL) return;
|
||||
/* to be sure */
|
||||
if (cu->editnurb == NULL) return;
|
||||
|
||||
#define SEL_F1 (1 << 0)
|
||||
#define SEL_F2 (1 << 1)
|
||||
#define SEL_F3 (1 << 2)
|
||||
#define SEL_F1 (1 << 0)
|
||||
#define SEL_F2 (1 << 1)
|
||||
#define SEL_F3 (1 << 2)
|
||||
|
||||
/* count total of vertices, check identical as in 2nd loop for making transdata! */
|
||||
nurbs = BKE_curve_editNurbs_get(cu);
|
||||
for (nu = nurbs->first; nu; nu = nu->next) {
|
||||
if (nu->type == CU_BEZIER) {
|
||||
for (a = 0, bezt = nu->bezt; a < nu->pntsu; a++, bezt++) {
|
||||
if (bezt->hide == 0) {
|
||||
const int bezt_tx = bezt_select_to_transform_triple_flag(bezt, hide_handles);
|
||||
if (bezt_tx & SEL_F1) { countsel++; }
|
||||
if (bezt_tx & SEL_F2) { countsel++; }
|
||||
if (bezt_tx & SEL_F3) { countsel++; }
|
||||
if (is_prop_edit) count += 3;
|
||||
/* count total of vertices, check identical as in 2nd loop for making transdata! */
|
||||
nurbs = BKE_curve_editNurbs_get(cu);
|
||||
for (nu = nurbs->first; nu; nu = nu->next) {
|
||||
if (nu->type == CU_BEZIER) {
|
||||
for (a = 0, bezt = nu->bezt; a < nu->pntsu; a++, bezt++) {
|
||||
if (bezt->hide == 0) {
|
||||
const int bezt_tx = bezt_select_to_transform_triple_flag(bezt, hide_handles);
|
||||
if (bezt_tx & SEL_F1) { countsel++; }
|
||||
if (bezt_tx & SEL_F2) { countsel++; }
|
||||
if (bezt_tx & SEL_F3) { countsel++; }
|
||||
if (is_prop_edit) count += 3;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (a = nu->pntsu * nu->pntsv, bp = nu->bp; a > 0; a--, bp++) {
|
||||
if (bp->hide == 0) {
|
||||
if (is_prop_edit) count++;
|
||||
if (bp->f1 & SELECT) countsel++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* note: in prop mode we need at least 1 selected */
|
||||
if (countsel == 0) {
|
||||
tc->data_len = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (is_prop_edit) tc->data_len = count;
|
||||
else tc->data_len = countsel;
|
||||
tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransObData(Curve EditMode)");
|
||||
|
||||
transform_around_single_fallback(t);
|
||||
|
||||
copy_m3_m4(mtx, tc->obedit->obmat);
|
||||
pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON);
|
||||
|
||||
td = tc->data;
|
||||
for (nu = nurbs->first; nu; nu = nu->next) {
|
||||
if (nu->type == CU_BEZIER) {
|
||||
TransData *head, *tail;
|
||||
head = tail = td;
|
||||
for (a = 0, bezt = nu->bezt; a < nu->pntsu; a++, bezt++) {
|
||||
if (bezt->hide == 0) {
|
||||
TransDataCurveHandleFlags *hdata = NULL;
|
||||
float axismtx[3][3];
|
||||
|
||||
if (t->around == V3D_AROUND_LOCAL_ORIGINS) {
|
||||
float normal[3], plane[3];
|
||||
|
||||
BKE_nurb_bezt_calc_normal(nu, bezt, normal);
|
||||
BKE_nurb_bezt_calc_plane(nu, bezt, plane);
|
||||
|
||||
if (createSpaceNormalTangent(axismtx, normal, plane)) {
|
||||
/* pass */
|
||||
}
|
||||
else {
|
||||
normalize_v3(normal);
|
||||
axis_dominant_v3_to_m3(axismtx, normal);
|
||||
invert_m3(axismtx);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (a = nu->pntsu * nu->pntsv, bp = nu->bp; a > 0; a--, bp++) {
|
||||
if (bp->hide == 0) {
|
||||
if (is_prop_edit) count++;
|
||||
if (bp->f1 & SELECT) countsel++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* note: in prop mode we need at least 1 selected */
|
||||
if (countsel == 0) {
|
||||
tc->data_len = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Elements that will be transform (not always a match to selection). */
|
||||
const int bezt_tx = bezt_select_to_transform_triple_flag(bezt, hide_handles);
|
||||
if (is_prop_edit) tc->data_len = count;
|
||||
else tc->data_len = countsel;
|
||||
tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransObData(Curve EditMode)");
|
||||
|
||||
if (is_prop_edit || bezt_tx & SEL_F1) {
|
||||
copy_v3_v3(td->iloc, bezt->vec[0]);
|
||||
td->loc = bezt->vec[0];
|
||||
copy_v3_v3(td->center, bezt->vec[(hide_handles ||
|
||||
(t->around == V3D_AROUND_LOCAL_ORIGINS) ||
|
||||
(bezt->f2 & SELECT)) ? 1 : 0]);
|
||||
if (hide_handles) {
|
||||
transform_around_single_fallback(t);
|
||||
|
||||
copy_m3_m4(mtx, tc->obedit->obmat);
|
||||
pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON);
|
||||
|
||||
td = tc->data;
|
||||
for (nu = nurbs->first; nu; nu = nu->next) {
|
||||
if (nu->type == CU_BEZIER) {
|
||||
TransData *head, *tail;
|
||||
head = tail = td;
|
||||
for (a = 0, bezt = nu->bezt; a < nu->pntsu; a++, bezt++) {
|
||||
if (bezt->hide == 0) {
|
||||
TransDataCurveHandleFlags *hdata = NULL;
|
||||
float axismtx[3][3];
|
||||
|
||||
if (t->around == V3D_AROUND_LOCAL_ORIGINS) {
|
||||
float normal[3], plane[3];
|
||||
|
||||
BKE_nurb_bezt_calc_normal(nu, bezt, normal);
|
||||
BKE_nurb_bezt_calc_plane(nu, bezt, plane);
|
||||
|
||||
if (createSpaceNormalTangent(axismtx, normal, plane)) {
|
||||
/* pass */
|
||||
}
|
||||
else {
|
||||
normalize_v3(normal);
|
||||
axis_dominant_v3_to_m3(axismtx, normal);
|
||||
invert_m3(axismtx);
|
||||
}
|
||||
}
|
||||
|
||||
/* Elements that will be transform (not always a match to selection). */
|
||||
const int bezt_tx = bezt_select_to_transform_triple_flag(bezt, hide_handles);
|
||||
|
||||
if (is_prop_edit || bezt_tx & SEL_F1) {
|
||||
copy_v3_v3(td->iloc, bezt->vec[0]);
|
||||
td->loc = bezt->vec[0];
|
||||
copy_v3_v3(td->center, bezt->vec[(hide_handles ||
|
||||
(t->around == V3D_AROUND_LOCAL_ORIGINS) ||
|
||||
(bezt->f2 & SELECT)) ? 1 : 0]);
|
||||
if (hide_handles) {
|
||||
if (bezt->f2 & SELECT) td->flag = TD_SELECTED;
|
||||
else td->flag = 0;
|
||||
}
|
||||
else {
|
||||
if (bezt->f1 & SELECT) td->flag = TD_SELECTED;
|
||||
else td->flag = 0;
|
||||
}
|
||||
td->ext = NULL;
|
||||
td->val = NULL;
|
||||
|
||||
hdata = initTransDataCurveHandles(td, bezt);
|
||||
|
||||
copy_m3_m3(td->smtx, smtx);
|
||||
copy_m3_m3(td->mtx, mtx);
|
||||
if (t->around == V3D_AROUND_LOCAL_ORIGINS) {
|
||||
copy_m3_m3(td->axismtx, axismtx);
|
||||
}
|
||||
|
||||
td++;
|
||||
count++;
|
||||
tail++;
|
||||
}
|
||||
|
||||
/* This is the Curve Point, the other two are handles */
|
||||
if (is_prop_edit || bezt_tx & SEL_F2) {
|
||||
copy_v3_v3(td->iloc, bezt->vec[1]);
|
||||
td->loc = bezt->vec[1];
|
||||
copy_v3_v3(td->center, td->loc);
|
||||
if (bezt->f2 & SELECT) td->flag = TD_SELECTED;
|
||||
else td->flag = 0;
|
||||
}
|
||||
else {
|
||||
if (bezt->f1 & SELECT) td->flag = TD_SELECTED;
|
||||
else td->flag = 0;
|
||||
}
|
||||
td->ext = NULL;
|
||||
td->val = NULL;
|
||||
td->ext = NULL;
|
||||
|
||||
hdata = initTransDataCurveHandles(td, bezt);
|
||||
if (t->mode == TFM_CURVE_SHRINKFATTEN) { /* || t->mode==TFM_RESIZE) {*/ /* TODO - make points scale */
|
||||
td->val = &(bezt->radius);
|
||||
td->ival = bezt->radius;
|
||||
}
|
||||
else if (t->mode == TFM_TILT) {
|
||||
td->val = &(bezt->alfa);
|
||||
td->ival = bezt->alfa;
|
||||
}
|
||||
else {
|
||||
td->val = NULL;
|
||||
}
|
||||
|
||||
copy_m3_m3(td->smtx, smtx);
|
||||
copy_m3_m3(td->mtx, mtx);
|
||||
if (t->around == V3D_AROUND_LOCAL_ORIGINS) {
|
||||
copy_m3_m3(td->axismtx, axismtx);
|
||||
copy_m3_m3(td->smtx, smtx);
|
||||
copy_m3_m3(td->mtx, mtx);
|
||||
if (t->around == V3D_AROUND_LOCAL_ORIGINS) {
|
||||
copy_m3_m3(td->axismtx, axismtx);
|
||||
}
|
||||
|
||||
if ((bezt_tx & SEL_F1) == 0 && (bezt_tx & SEL_F3) == 0)
|
||||
/* If the middle is selected but the sides arnt, this is needed */
|
||||
if (hdata == NULL) { /* if the handle was not saved by the previous handle */
|
||||
hdata = initTransDataCurveHandles(td, bezt);
|
||||
}
|
||||
|
||||
td++;
|
||||
count++;
|
||||
tail++;
|
||||
}
|
||||
|
||||
td++;
|
||||
count++;
|
||||
tail++;
|
||||
}
|
||||
|
||||
/* This is the Curve Point, the other two are handles */
|
||||
if (is_prop_edit || bezt_tx & SEL_F2) {
|
||||
copy_v3_v3(td->iloc, bezt->vec[1]);
|
||||
td->loc = bezt->vec[1];
|
||||
copy_v3_v3(td->center, td->loc);
|
||||
if (bezt->f2 & SELECT) td->flag = TD_SELECTED;
|
||||
else td->flag = 0;
|
||||
td->ext = NULL;
|
||||
|
||||
if (t->mode == TFM_CURVE_SHRINKFATTEN) { /* || t->mode==TFM_RESIZE) {*/ /* TODO - make points scale */
|
||||
td->val = &(bezt->radius);
|
||||
td->ival = bezt->radius;
|
||||
}
|
||||
else if (t->mode == TFM_TILT) {
|
||||
td->val = &(bezt->alfa);
|
||||
td->ival = bezt->alfa;
|
||||
}
|
||||
else {
|
||||
if (is_prop_edit || bezt_tx & SEL_F3) {
|
||||
copy_v3_v3(td->iloc, bezt->vec[2]);
|
||||
td->loc = bezt->vec[2];
|
||||
copy_v3_v3(td->center, bezt->vec[(hide_handles ||
|
||||
(t->around == V3D_AROUND_LOCAL_ORIGINS) ||
|
||||
(bezt->f2 & SELECT)) ? 1 : 2]);
|
||||
if (hide_handles) {
|
||||
if (bezt->f2 & SELECT) td->flag = TD_SELECTED;
|
||||
else td->flag = 0;
|
||||
}
|
||||
else {
|
||||
if (bezt->f3 & SELECT) td->flag = TD_SELECTED;
|
||||
else td->flag = 0;
|
||||
}
|
||||
td->ext = NULL;
|
||||
td->val = NULL;
|
||||
}
|
||||
|
||||
copy_m3_m3(td->smtx, smtx);
|
||||
copy_m3_m3(td->mtx, mtx);
|
||||
if (t->around == V3D_AROUND_LOCAL_ORIGINS) {
|
||||
copy_m3_m3(td->axismtx, axismtx);
|
||||
}
|
||||
|
||||
if ((bezt_tx & SEL_F1) == 0 && (bezt_tx & SEL_F3) == 0)
|
||||
/* If the middle is selected but the sides arnt, this is needed */
|
||||
if (hdata == NULL) { /* if the handle was not saved by the previous handle */
|
||||
hdata = initTransDataCurveHandles(td, bezt);
|
||||
}
|
||||
|
||||
td++;
|
||||
count++;
|
||||
tail++;
|
||||
}
|
||||
if (is_prop_edit || bezt_tx & SEL_F3) {
|
||||
copy_v3_v3(td->iloc, bezt->vec[2]);
|
||||
td->loc = bezt->vec[2];
|
||||
copy_v3_v3(td->center, bezt->vec[(hide_handles ||
|
||||
(t->around == V3D_AROUND_LOCAL_ORIGINS) ||
|
||||
(bezt->f2 & SELECT)) ? 1 : 2]);
|
||||
if (hide_handles) {
|
||||
if (bezt->f2 & SELECT) td->flag = TD_SELECTED;
|
||||
else td->flag = 0;
|
||||
}
|
||||
else {
|
||||
if (bezt->f3 & SELECT) td->flag = TD_SELECTED;
|
||||
else td->flag = 0;
|
||||
}
|
||||
td->ext = NULL;
|
||||
td->val = NULL;
|
||||
|
||||
if (hdata == NULL) { /* if the handle was not saved by the previous handle */
|
||||
hdata = initTransDataCurveHandles(td, bezt);
|
||||
}
|
||||
|
||||
copy_m3_m3(td->smtx, smtx);
|
||||
copy_m3_m3(td->mtx, mtx);
|
||||
if (t->around == V3D_AROUND_LOCAL_ORIGINS) {
|
||||
copy_m3_m3(td->axismtx, axismtx);
|
||||
}
|
||||
|
||||
td++;
|
||||
count++;
|
||||
tail++;
|
||||
}
|
||||
|
||||
(void)hdata; /* quiet warning */
|
||||
}
|
||||
else if (is_prop_edit && head != tail) {
|
||||
calc_distanceCurveVerts(head, tail - 1);
|
||||
head = tail;
|
||||
}
|
||||
}
|
||||
if (is_prop_edit && head != tail)
|
||||
calc_distanceCurveVerts(head, tail - 1);
|
||||
|
||||
/* TODO - in the case of tilt and radius we can also avoid allocating the initTransDataCurveHandles
|
||||
* but for now just don't change handle types */
|
||||
if (ELEM(t->mode, TFM_CURVE_SHRINKFATTEN, TFM_TILT, TFM_DUMMY) == 0) {
|
||||
/* sets the handles based on their selection, do this after the data is copied to the TransData */
|
||||
BKE_nurb_handles_test(nu, !hide_handles);
|
||||
}
|
||||
}
|
||||
else {
|
||||
TransData *head, *tail;
|
||||
head = tail = td;
|
||||
for (a = nu->pntsu * nu->pntsv, bp = nu->bp; a > 0; a--, bp++) {
|
||||
if (bp->hide == 0) {
|
||||
if (is_prop_edit || (bp->f1 & SELECT)) {
|
||||
float axismtx[3][3];
|
||||
|
||||
if (t->around == V3D_AROUND_LOCAL_ORIGINS) {
|
||||
if (nu->pntsv == 1) {
|
||||
float normal[3], plane[3];
|
||||
|
||||
BKE_nurb_bpoint_calc_normal(nu, bp, normal);
|
||||
BKE_nurb_bpoint_calc_plane(nu, bp, plane);
|
||||
|
||||
if (createSpaceNormalTangent(axismtx, normal, plane)) {
|
||||
/* pass */
|
||||
}
|
||||
else {
|
||||
normalize_v3(normal);
|
||||
axis_dominant_v3_to_m3(axismtx, normal);
|
||||
invert_m3(axismtx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
copy_v3_v3(td->iloc, bp->vec);
|
||||
td->loc = bp->vec;
|
||||
copy_v3_v3(td->center, td->loc);
|
||||
if (bp->f1 & SELECT) td->flag = TD_SELECTED;
|
||||
else td->flag = 0;
|
||||
td->ext = NULL;
|
||||
|
||||
if (t->mode == TFM_CURVE_SHRINKFATTEN || t->mode == TFM_RESIZE) {
|
||||
td->val = &(bp->radius);
|
||||
td->ival = bp->radius;
|
||||
}
|
||||
else {
|
||||
td->val = &(bp->alfa);
|
||||
td->ival = bp->alfa;
|
||||
}
|
||||
|
||||
copy_m3_m3(td->smtx, smtx);
|
||||
copy_m3_m3(td->mtx, mtx);
|
||||
if (t->around == V3D_AROUND_LOCAL_ORIGINS) {
|
||||
if (nu->pntsv == 1) {
|
||||
copy_m3_m3(td->smtx, smtx);
|
||||
copy_m3_m3(td->mtx, mtx);
|
||||
if (t->around == V3D_AROUND_LOCAL_ORIGINS) {
|
||||
copy_m3_m3(td->axismtx, axismtx);
|
||||
}
|
||||
|
||||
td++;
|
||||
count++;
|
||||
tail++;
|
||||
}
|
||||
|
||||
td++;
|
||||
count++;
|
||||
tail++;
|
||||
(void)hdata; /* quiet warning */
|
||||
}
|
||||
else if (is_prop_edit && head != tail) {
|
||||
calc_distanceCurveVerts(head, tail - 1);
|
||||
head = tail;
|
||||
}
|
||||
}
|
||||
else if (is_prop_edit && head != tail) {
|
||||
if (is_prop_edit && head != tail)
|
||||
calc_distanceCurveVerts(head, tail - 1);
|
||||
head = tail;
|
||||
|
||||
/* TODO - in the case of tilt and radius we can also avoid allocating the initTransDataCurveHandles
|
||||
* but for now just don't change handle types */
|
||||
if (ELEM(t->mode, TFM_CURVE_SHRINKFATTEN, TFM_TILT, TFM_DUMMY) == 0) {
|
||||
/* sets the handles based on their selection, do this after the data is copied to the TransData */
|
||||
BKE_nurb_handles_test(nu, !hide_handles);
|
||||
}
|
||||
}
|
||||
if (is_prop_edit && head != tail)
|
||||
calc_distanceCurveVerts(head, tail - 1);
|
||||
else {
|
||||
TransData *head, *tail;
|
||||
head = tail = td;
|
||||
for (a = nu->pntsu * nu->pntsv, bp = nu->bp; a > 0; a--, bp++) {
|
||||
if (bp->hide == 0) {
|
||||
if (is_prop_edit || (bp->f1 & SELECT)) {
|
||||
float axismtx[3][3];
|
||||
|
||||
if (t->around == V3D_AROUND_LOCAL_ORIGINS) {
|
||||
if (nu->pntsv == 1) {
|
||||
float normal[3], plane[3];
|
||||
|
||||
BKE_nurb_bpoint_calc_normal(nu, bp, normal);
|
||||
BKE_nurb_bpoint_calc_plane(nu, bp, plane);
|
||||
|
||||
if (createSpaceNormalTangent(axismtx, normal, plane)) {
|
||||
/* pass */
|
||||
}
|
||||
else {
|
||||
normalize_v3(normal);
|
||||
axis_dominant_v3_to_m3(axismtx, normal);
|
||||
invert_m3(axismtx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
copy_v3_v3(td->iloc, bp->vec);
|
||||
td->loc = bp->vec;
|
||||
copy_v3_v3(td->center, td->loc);
|
||||
if (bp->f1 & SELECT) td->flag = TD_SELECTED;
|
||||
else td->flag = 0;
|
||||
td->ext = NULL;
|
||||
|
||||
if (t->mode == TFM_CURVE_SHRINKFATTEN || t->mode == TFM_RESIZE) {
|
||||
td->val = &(bp->radius);
|
||||
td->ival = bp->radius;
|
||||
}
|
||||
else {
|
||||
td->val = &(bp->alfa);
|
||||
td->ival = bp->alfa;
|
||||
}
|
||||
|
||||
copy_m3_m3(td->smtx, smtx);
|
||||
copy_m3_m3(td->mtx, mtx);
|
||||
if (t->around == V3D_AROUND_LOCAL_ORIGINS) {
|
||||
if (nu->pntsv == 1) {
|
||||
copy_m3_m3(td->axismtx, axismtx);
|
||||
}
|
||||
}
|
||||
|
||||
td++;
|
||||
count++;
|
||||
tail++;
|
||||
}
|
||||
}
|
||||
else if (is_prop_edit && head != tail) {
|
||||
calc_distanceCurveVerts(head, tail - 1);
|
||||
head = tail;
|
||||
}
|
||||
}
|
||||
if (is_prop_edit && head != tail)
|
||||
calc_distanceCurveVerts(head, tail - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#undef SEL_F1
|
||||
#undef SEL_F2
|
||||
#undef SEL_F3
|
||||
@@ -1892,62 +1892,62 @@ static void createTransCurveVerts(TransInfo *t)
|
||||
static void createTransLatticeVerts(TransInfo *t)
|
||||
{
|
||||
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
|
||||
|
||||
Lattice *latt = ((Lattice *)tc->obedit->data)->editlatt->latt;
|
||||
TransData *td = NULL;
|
||||
BPoint *bp;
|
||||
float mtx[3][3], smtx[3][3];
|
||||
int a;
|
||||
int count = 0, countsel = 0;
|
||||
const bool is_prop_edit = (t->flag & T_PROP_EDIT) != 0;
|
||||
|
||||
bp = latt->def;
|
||||
a = latt->pntsu * latt->pntsv * latt->pntsw;
|
||||
while (a--) {
|
||||
if (bp->hide == 0) {
|
||||
if (bp->f1 & SELECT) countsel++;
|
||||
if (is_prop_edit) count++;
|
||||
}
|
||||
bp++;
|
||||
}
|
||||
Lattice *latt = ((Lattice *)tc->obedit->data)->editlatt->latt;
|
||||
TransData *td = NULL;
|
||||
BPoint *bp;
|
||||
float mtx[3][3], smtx[3][3];
|
||||
int a;
|
||||
int count = 0, countsel = 0;
|
||||
const bool is_prop_edit = (t->flag & T_PROP_EDIT) != 0;
|
||||
|
||||
/* note: in prop mode we need at least 1 selected */
|
||||
if (countsel == 0) return;
|
||||
|
||||
if (is_prop_edit) tc->data_len = count;
|
||||
else tc->data_len = countsel;
|
||||
tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransObData(Lattice EditMode)");
|
||||
|
||||
copy_m3_m4(mtx, tc->obedit->obmat);
|
||||
pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON);
|
||||
|
||||
td = tc->data;
|
||||
bp = latt->def;
|
||||
a = latt->pntsu * latt->pntsv * latt->pntsw;
|
||||
while (a--) {
|
||||
if (is_prop_edit || (bp->f1 & SELECT)) {
|
||||
bp = latt->def;
|
||||
a = latt->pntsu * latt->pntsv * latt->pntsw;
|
||||
while (a--) {
|
||||
if (bp->hide == 0) {
|
||||
copy_v3_v3(td->iloc, bp->vec);
|
||||
td->loc = bp->vec;
|
||||
copy_v3_v3(td->center, td->loc);
|
||||
if (bp->f1 & SELECT) {
|
||||
td->flag = TD_SELECTED;
|
||||
}
|
||||
else {
|
||||
td->flag = 0;
|
||||
}
|
||||
copy_m3_m3(td->smtx, smtx);
|
||||
copy_m3_m3(td->mtx, mtx);
|
||||
|
||||
td->ext = NULL;
|
||||
td->val = NULL;
|
||||
|
||||
td++;
|
||||
count++;
|
||||
if (bp->f1 & SELECT) countsel++;
|
||||
if (is_prop_edit) count++;
|
||||
}
|
||||
bp++;
|
||||
}
|
||||
|
||||
/* note: in prop mode we need at least 1 selected */
|
||||
if (countsel == 0) return;
|
||||
|
||||
if (is_prop_edit) tc->data_len = count;
|
||||
else tc->data_len = countsel;
|
||||
tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransObData(Lattice EditMode)");
|
||||
|
||||
copy_m3_m4(mtx, tc->obedit->obmat);
|
||||
pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON);
|
||||
|
||||
td = tc->data;
|
||||
bp = latt->def;
|
||||
a = latt->pntsu * latt->pntsv * latt->pntsw;
|
||||
while (a--) {
|
||||
if (is_prop_edit || (bp->f1 & SELECT)) {
|
||||
if (bp->hide == 0) {
|
||||
copy_v3_v3(td->iloc, bp->vec);
|
||||
td->loc = bp->vec;
|
||||
copy_v3_v3(td->center, td->loc);
|
||||
if (bp->f1 & SELECT) {
|
||||
td->flag = TD_SELECTED;
|
||||
}
|
||||
else {
|
||||
td->flag = 0;
|
||||
}
|
||||
copy_m3_m3(td->smtx, smtx);
|
||||
copy_m3_m3(td->mtx, mtx);
|
||||
|
||||
td->ext = NULL;
|
||||
td->val = NULL;
|
||||
|
||||
td++;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
bp++;
|
||||
}
|
||||
bp++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1956,120 +1956,120 @@ static void createTransParticleVerts(bContext *C, TransInfo *t)
|
||||
{
|
||||
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
|
||||
|
||||
TransData *td = NULL;
|
||||
TransDataExtension *tx;
|
||||
Object *ob = CTX_data_active_object(C);
|
||||
ParticleEditSettings *pset = PE_settings(t->scene);
|
||||
PTCacheEdit *edit = PE_get_current(t->scene, ob);
|
||||
ParticleSystem *psys = NULL;
|
||||
ParticleSystemModifierData *psmd = NULL;
|
||||
PTCacheEditPoint *point;
|
||||
PTCacheEditKey *key;
|
||||
float mat[4][4];
|
||||
int i, k, transformparticle;
|
||||
int count = 0, hasselected = 0;
|
||||
const bool is_prop_edit = (t->flag & T_PROP_EDIT) != 0;
|
||||
TransData *td = NULL;
|
||||
TransDataExtension *tx;
|
||||
Object *ob = CTX_data_active_object(C);
|
||||
ParticleEditSettings *pset = PE_settings(t->scene);
|
||||
PTCacheEdit *edit = PE_get_current(t->scene, ob);
|
||||
ParticleSystem *psys = NULL;
|
||||
ParticleSystemModifierData *psmd = NULL;
|
||||
PTCacheEditPoint *point;
|
||||
PTCacheEditKey *key;
|
||||
float mat[4][4];
|
||||
int i, k, transformparticle;
|
||||
int count = 0, hasselected = 0;
|
||||
const bool is_prop_edit = (t->flag & T_PROP_EDIT) != 0;
|
||||
|
||||
if (edit == NULL || t->settings->particle.selectmode == SCE_SELECT_PATH) return;
|
||||
if (edit == NULL || t->settings->particle.selectmode == SCE_SELECT_PATH) return;
|
||||
|
||||
psys = edit->psys;
|
||||
psys = edit->psys;
|
||||
|
||||
if (psys)
|
||||
psmd = psys_get_modifier(ob, psys);
|
||||
if (psys)
|
||||
psmd = psys_get_modifier(ob, psys);
|
||||
|
||||
for (i = 0, point = edit->points; i < edit->totpoint; i++, point++) {
|
||||
point->flag &= ~PEP_TRANSFORM;
|
||||
transformparticle = 0;
|
||||
for (i = 0, point = edit->points; i < edit->totpoint; i++, point++) {
|
||||
point->flag &= ~PEP_TRANSFORM;
|
||||
transformparticle = 0;
|
||||
|
||||
if ((point->flag & PEP_HIDE) == 0) {
|
||||
for (k = 0, key = point->keys; k < point->totkey; k++, key++) {
|
||||
if ((key->flag & PEK_HIDE) == 0) {
|
||||
if (key->flag & PEK_SELECT) {
|
||||
hasselected = 1;
|
||||
transformparticle = 1;
|
||||
if ((point->flag & PEP_HIDE) == 0) {
|
||||
for (k = 0, key = point->keys; k < point->totkey; k++, key++) {
|
||||
if ((key->flag & PEK_HIDE) == 0) {
|
||||
if (key->flag & PEK_SELECT) {
|
||||
hasselected = 1;
|
||||
transformparticle = 1;
|
||||
}
|
||||
else if (is_prop_edit)
|
||||
transformparticle = 1;
|
||||
}
|
||||
else if (is_prop_edit)
|
||||
transformparticle = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (transformparticle) {
|
||||
count += point->totkey;
|
||||
point->flag |= PEP_TRANSFORM;
|
||||
}
|
||||
}
|
||||
|
||||
/* note: in prop mode we need at least 1 selected */
|
||||
if (hasselected == 0) return;
|
||||
|
||||
tc->data_len = count;
|
||||
td = tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransObData(Particle Mode)");
|
||||
|
||||
if (t->mode == TFM_BAKE_TIME)
|
||||
tx = tc->data_ext = MEM_callocN(tc->data_len * sizeof(TransDataExtension), "Particle_TransExtension");
|
||||
else
|
||||
tx = tc->data_ext = NULL;
|
||||
|
||||
unit_m4(mat);
|
||||
|
||||
invert_m4_m4(ob->imat, ob->obmat);
|
||||
|
||||
for (i = 0, point = edit->points; i < edit->totpoint; i++, point++) {
|
||||
TransData *head, *tail;
|
||||
head = tail = td;
|
||||
|
||||
if (!(point->flag & PEP_TRANSFORM)) continue;
|
||||
|
||||
if (psys && !(psys->flag & PSYS_GLOBAL_HAIR))
|
||||
psys_mat_hair_to_global(ob, psmd->dm_final, psys->part->from, psys->particles + i, mat);
|
||||
|
||||
for (k = 0, key = point->keys; k < point->totkey; k++, key++) {
|
||||
if (key->flag & PEK_USE_WCO) {
|
||||
copy_v3_v3(key->world_co, key->co);
|
||||
mul_m4_v3(mat, key->world_co);
|
||||
td->loc = key->world_co;
|
||||
if (transformparticle) {
|
||||
count += point->totkey;
|
||||
point->flag |= PEP_TRANSFORM;
|
||||
}
|
||||
else
|
||||
td->loc = key->co;
|
||||
|
||||
copy_v3_v3(td->iloc, td->loc);
|
||||
copy_v3_v3(td->center, td->loc);
|
||||
|
||||
if (key->flag & PEK_SELECT)
|
||||
td->flag |= TD_SELECTED;
|
||||
else if (!is_prop_edit)
|
||||
td->flag |= TD_SKIP;
|
||||
|
||||
unit_m3(td->mtx);
|
||||
unit_m3(td->smtx);
|
||||
|
||||
/* don't allow moving roots */
|
||||
if (k == 0 && pset->flag & PE_LOCK_FIRST && (!psys || !(psys->flag & PSYS_GLOBAL_HAIR)))
|
||||
td->protectflag |= OB_LOCK_LOC;
|
||||
|
||||
td->ob = ob;
|
||||
td->ext = tx;
|
||||
if (t->mode == TFM_BAKE_TIME) {
|
||||
td->val = key->time;
|
||||
td->ival = *(key->time);
|
||||
/* abuse size and quat for min/max values */
|
||||
td->flag |= TD_NO_EXT;
|
||||
if (k == 0) tx->size = NULL;
|
||||
else tx->size = (key - 1)->time;
|
||||
|
||||
if (k == point->totkey - 1) tx->quat = NULL;
|
||||
else tx->quat = (key + 1)->time;
|
||||
}
|
||||
|
||||
td++;
|
||||
if (tx)
|
||||
tx++;
|
||||
tail++;
|
||||
}
|
||||
if (is_prop_edit && head != tail)
|
||||
calc_distanceCurveVerts(head, tail - 1);
|
||||
}
|
||||
|
||||
/* note: in prop mode we need at least 1 selected */
|
||||
if (hasselected == 0) return;
|
||||
|
||||
tc->data_len = count;
|
||||
td = tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransObData(Particle Mode)");
|
||||
|
||||
if (t->mode == TFM_BAKE_TIME)
|
||||
tx = tc->data_ext = MEM_callocN(tc->data_len * sizeof(TransDataExtension), "Particle_TransExtension");
|
||||
else
|
||||
tx = tc->data_ext = NULL;
|
||||
|
||||
unit_m4(mat);
|
||||
|
||||
invert_m4_m4(ob->imat, ob->obmat);
|
||||
|
||||
for (i = 0, point = edit->points; i < edit->totpoint; i++, point++) {
|
||||
TransData *head, *tail;
|
||||
head = tail = td;
|
||||
|
||||
if (!(point->flag & PEP_TRANSFORM)) continue;
|
||||
|
||||
if (psys && !(psys->flag & PSYS_GLOBAL_HAIR))
|
||||
psys_mat_hair_to_global(ob, psmd->dm_final, psys->part->from, psys->particles + i, mat);
|
||||
|
||||
for (k = 0, key = point->keys; k < point->totkey; k++, key++) {
|
||||
if (key->flag & PEK_USE_WCO) {
|
||||
copy_v3_v3(key->world_co, key->co);
|
||||
mul_m4_v3(mat, key->world_co);
|
||||
td->loc = key->world_co;
|
||||
}
|
||||
else
|
||||
td->loc = key->co;
|
||||
|
||||
copy_v3_v3(td->iloc, td->loc);
|
||||
copy_v3_v3(td->center, td->loc);
|
||||
|
||||
if (key->flag & PEK_SELECT)
|
||||
td->flag |= TD_SELECTED;
|
||||
else if (!is_prop_edit)
|
||||
td->flag |= TD_SKIP;
|
||||
|
||||
unit_m3(td->mtx);
|
||||
unit_m3(td->smtx);
|
||||
|
||||
/* don't allow moving roots */
|
||||
if (k == 0 && pset->flag & PE_LOCK_FIRST && (!psys || !(psys->flag & PSYS_GLOBAL_HAIR)))
|
||||
td->protectflag |= OB_LOCK_LOC;
|
||||
|
||||
td->ob = ob;
|
||||
td->ext = tx;
|
||||
if (t->mode == TFM_BAKE_TIME) {
|
||||
td->val = key->time;
|
||||
td->ival = *(key->time);
|
||||
/* abuse size and quat for min/max values */
|
||||
td->flag |= TD_NO_EXT;
|
||||
if (k == 0) tx->size = NULL;
|
||||
else tx->size = (key - 1)->time;
|
||||
|
||||
if (k == point->totkey - 1) tx->quat = NULL;
|
||||
else tx->quat = (key + 1)->time;
|
||||
}
|
||||
|
||||
td++;
|
||||
if (tx)
|
||||
tx++;
|
||||
tail++;
|
||||
}
|
||||
if (is_prop_edit && head != tail)
|
||||
calc_distanceCurveVerts(head, tail - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2077,49 +2077,49 @@ void flushTransParticles(TransInfo *t)
|
||||
{
|
||||
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
|
||||
|
||||
Scene *scene = t->scene;
|
||||
ViewLayer *view_layer = t->view_layer;
|
||||
Object *ob = OBACT(view_layer);
|
||||
PTCacheEdit *edit = PE_get_current(scene, ob);
|
||||
ParticleSystem *psys = edit->psys;
|
||||
ParticleSystemModifierData *psmd = NULL;
|
||||
PTCacheEditPoint *point;
|
||||
PTCacheEditKey *key;
|
||||
TransData *td;
|
||||
float mat[4][4], imat[4][4], co[3];
|
||||
int i, k;
|
||||
const bool is_prop_edit = (t->flag & T_PROP_EDIT) != 0;
|
||||
Scene *scene = t->scene;
|
||||
ViewLayer *view_layer = t->view_layer;
|
||||
Object *ob = OBACT(view_layer);
|
||||
PTCacheEdit *edit = PE_get_current(scene, ob);
|
||||
ParticleSystem *psys = edit->psys;
|
||||
ParticleSystemModifierData *psmd = NULL;
|
||||
PTCacheEditPoint *point;
|
||||
PTCacheEditKey *key;
|
||||
TransData *td;
|
||||
float mat[4][4], imat[4][4], co[3];
|
||||
int i, k;
|
||||
const bool is_prop_edit = (t->flag & T_PROP_EDIT) != 0;
|
||||
|
||||
if (psys)
|
||||
psmd = psys_get_modifier(ob, psys);
|
||||
if (psys)
|
||||
psmd = psys_get_modifier(ob, psys);
|
||||
|
||||
/* we do transform in world space, so flush world space position
|
||||
* back to particle local space (only for hair particles) */
|
||||
td = tc->data;
|
||||
for (i = 0, point = edit->points; i < edit->totpoint; i++, point++, td++) {
|
||||
if (!(point->flag & PEP_TRANSFORM)) continue;
|
||||
/* we do transform in world space, so flush world space position
|
||||
* back to particle local space (only for hair particles) */
|
||||
td = tc->data;
|
||||
for (i = 0, point = edit->points; i < edit->totpoint; i++, point++, td++) {
|
||||
if (!(point->flag & PEP_TRANSFORM)) continue;
|
||||
|
||||
if (psys && !(psys->flag & PSYS_GLOBAL_HAIR)) {
|
||||
psys_mat_hair_to_global(ob, psmd->dm_final, psys->part->from, psys->particles + i, mat);
|
||||
invert_m4_m4(imat, mat);
|
||||
if (psys && !(psys->flag & PSYS_GLOBAL_HAIR)) {
|
||||
psys_mat_hair_to_global(ob, psmd->dm_final, psys->part->from, psys->particles + i, mat);
|
||||
invert_m4_m4(imat, mat);
|
||||
|
||||
for (k = 0, key = point->keys; k < point->totkey; k++, key++) {
|
||||
copy_v3_v3(co, key->world_co);
|
||||
mul_m4_v3(imat, co);
|
||||
for (k = 0, key = point->keys; k < point->totkey; k++, key++) {
|
||||
copy_v3_v3(co, key->world_co);
|
||||
mul_m4_v3(imat, co);
|
||||
|
||||
|
||||
/* optimization for proportional edit */
|
||||
if (!is_prop_edit || !compare_v3v3(key->co, co, 0.0001f)) {
|
||||
copy_v3_v3(key->co, co);
|
||||
point->flag |= PEP_EDIT_RECALC;
|
||||
/* optimization for proportional edit */
|
||||
if (!is_prop_edit || !compare_v3v3(key->co, co, 0.0001f)) {
|
||||
copy_v3_v3(key->co, co);
|
||||
point->flag |= PEP_EDIT_RECALC;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
point->flag |= PEP_EDIT_RECALC;
|
||||
}
|
||||
else
|
||||
point->flag |= PEP_EDIT_RECALC;
|
||||
}
|
||||
|
||||
PE_update_object(&t->eval_ctx, scene, OBACT(view_layer), 1);
|
||||
PE_update_object(&t->eval_ctx, scene, OBACT(view_layer), 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2532,246 +2532,246 @@ static void createTransEditVerts(TransInfo *t)
|
||||
{
|
||||
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
|
||||
|
||||
TransData *tob = NULL;
|
||||
TransDataExtension *tx = NULL;
|
||||
BMEditMesh *em = BKE_editmesh_from_object(tc->obedit);
|
||||
Mesh *me = tc->obedit->data;
|
||||
BMesh *bm = em->bm;
|
||||
BMVert *eve;
|
||||
BMIter iter;
|
||||
float (*mappedcos)[3] = NULL, (*quats)[4] = NULL;
|
||||
float mtx[3][3], smtx[3][3], (*defmats)[3][3] = NULL, (*defcos)[3] = NULL;
|
||||
float *dists = NULL;
|
||||
int a;
|
||||
const int prop_mode = (t->flag & T_PROP_EDIT) ? (t->flag & T_PROP_EDIT_ALL) : 0;
|
||||
int mirror = 0;
|
||||
int cd_vert_bweight_offset = -1;
|
||||
bool use_topology = (me->editflag & ME_EDIT_MIRROR_TOPO) != 0;
|
||||
TransData *tob = NULL;
|
||||
TransDataExtension *tx = NULL;
|
||||
BMEditMesh *em = BKE_editmesh_from_object(tc->obedit);
|
||||
Mesh *me = tc->obedit->data;
|
||||
BMesh *bm = em->bm;
|
||||
BMVert *eve;
|
||||
BMIter iter;
|
||||
float (*mappedcos)[3] = NULL, (*quats)[4] = NULL;
|
||||
float mtx[3][3], smtx[3][3], (*defmats)[3][3] = NULL, (*defcos)[3] = NULL;
|
||||
float *dists = NULL;
|
||||
int a;
|
||||
const int prop_mode = (t->flag & T_PROP_EDIT) ? (t->flag & T_PROP_EDIT_ALL) : 0;
|
||||
int mirror = 0;
|
||||
int cd_vert_bweight_offset = -1;
|
||||
bool use_topology = (me->editflag & ME_EDIT_MIRROR_TOPO) != 0;
|
||||
|
||||
struct TransIslandData *island_info = NULL;
|
||||
int island_info_tot;
|
||||
int *island_vert_map = NULL;
|
||||
struct TransIslandData *island_info = NULL;
|
||||
int island_info_tot;
|
||||
int *island_vert_map = NULL;
|
||||
|
||||
/* Even for translation this is needed because of island-orientation, see: T51651. */
|
||||
const bool is_island_center = (t->around == V3D_AROUND_LOCAL_ORIGINS);
|
||||
/* Original index of our connected vertex when connected distances are calculated.
|
||||
* Optional, allocate if needed. */
|
||||
int *dists_index = NULL;
|
||||
/* Even for translation this is needed because of island-orientation, see: T51651. */
|
||||
const bool is_island_center = (t->around == V3D_AROUND_LOCAL_ORIGINS);
|
||||
/* Original index of our connected vertex when connected distances are calculated.
|
||||
* Optional, allocate if needed. */
|
||||
int *dists_index = NULL;
|
||||
|
||||
if (t->flag & T_MIRROR) {
|
||||
/* TODO(campbell): xform: We need support for many mirror objects at once! */
|
||||
if (tc->is_active) {
|
||||
EDBM_verts_mirror_cache_begin(em, 0, false, (t->flag & T_PROP_EDIT) == 0, use_topology);
|
||||
mirror = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Quick check if we can transform.
|
||||
*
|
||||
* \note ignore modes here, even in edge/face modes, transform data is created by selected vertices.
|
||||
* \note in prop mode we need at least 1 selected.
|
||||
*/
|
||||
if (bm->totvertsel == 0) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (t->mode == TFM_BWEIGHT) {
|
||||
BM_mesh_cd_flag_ensure(bm, BKE_mesh_from_object(tc->obedit), ME_CDFLAG_VERT_BWEIGHT);
|
||||
cd_vert_bweight_offset = CustomData_get_offset(&bm->vdata, CD_BWEIGHT);
|
||||
}
|
||||
|
||||
if (prop_mode) {
|
||||
unsigned int count = 0;
|
||||
BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
|
||||
if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) {
|
||||
count++;
|
||||
if (t->flag & T_MIRROR) {
|
||||
/* TODO(campbell): xform: We need support for many mirror objects at once! */
|
||||
if (tc->is_active) {
|
||||
EDBM_verts_mirror_cache_begin(em, 0, false, (t->flag & T_PROP_EDIT) == 0, use_topology);
|
||||
mirror = 1;
|
||||
}
|
||||
}
|
||||
|
||||
tc->data_len = count;
|
||||
/**
|
||||
* Quick check if we can transform.
|
||||
*
|
||||
* \note ignore modes here, even in edge/face modes, transform data is created by selected vertices.
|
||||
* \note in prop mode we need at least 1 selected.
|
||||
*/
|
||||
if (bm->totvertsel == 0) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (t->mode == TFM_BWEIGHT) {
|
||||
BM_mesh_cd_flag_ensure(bm, BKE_mesh_from_object(tc->obedit), ME_CDFLAG_VERT_BWEIGHT);
|
||||
cd_vert_bweight_offset = CustomData_get_offset(&bm->vdata, CD_BWEIGHT);
|
||||
}
|
||||
|
||||
if (prop_mode) {
|
||||
unsigned int count = 0;
|
||||
BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
|
||||
if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
tc->data_len = count;
|
||||
|
||||
/* allocating scratch arrays */
|
||||
if (prop_mode & T_PROP_CONNECTED) {
|
||||
dists = MEM_mallocN(em->bm->totvert * sizeof(float), __func__);
|
||||
if (is_island_center) {
|
||||
dists_index = MEM_mallocN(em->bm->totvert * sizeof(int), __func__);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
tc->data_len = bm->totvertsel;
|
||||
}
|
||||
|
||||
tob = tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransObData(Mesh EditMode)");
|
||||
if (ELEM(t->mode, TFM_SKIN_RESIZE, TFM_SHRINKFATTEN)) {
|
||||
/* warning, this is overkill, we only need 2 extra floats,
|
||||
* but this stores loads of extra stuff, for TFM_SHRINKFATTEN its even more overkill
|
||||
* since we may not use the 'alt' transform mode to maintain shell thickness,
|
||||
* but with generic transform code its hard to lazy init vars */
|
||||
tx = tc->data_ext = MEM_callocN(tc->data_len * sizeof(TransDataExtension), "TransObData ext");
|
||||
}
|
||||
|
||||
copy_m3_m4(mtx, tc->obedit->obmat);
|
||||
/* we use a pseudoinverse so that when one of the axes is scaled to 0,
|
||||
* matrix inversion still works and we can still moving along the other */
|
||||
pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON);
|
||||
|
||||
/* allocating scratch arrays */
|
||||
if (prop_mode & T_PROP_CONNECTED) {
|
||||
dists = MEM_mallocN(em->bm->totvert * sizeof(float), __func__);
|
||||
if (is_island_center) {
|
||||
dists_index = MEM_mallocN(em->bm->totvert * sizeof(int), __func__);
|
||||
editmesh_set_connectivity_distance(em->bm, mtx, dists, dists_index);
|
||||
}
|
||||
|
||||
if (is_island_center) {
|
||||
/* In this specific case, near-by vertices will need to know the island of the nearest connected vertex. */
|
||||
const bool calc_single_islands = (
|
||||
(prop_mode & T_PROP_CONNECTED) &&
|
||||
(t->around == V3D_AROUND_LOCAL_ORIGINS) &&
|
||||
(em->selectmode & SCE_SELECT_VERTEX));
|
||||
|
||||
island_info = editmesh_islands_info_calc(em, &island_info_tot, &island_vert_map, calc_single_islands);
|
||||
}
|
||||
|
||||
/* detect CrazySpace [tm] */
|
||||
if (modifiers_getCageIndex(t->scene, tc->obedit, NULL, 1) != -1) {
|
||||
int totleft = -1;
|
||||
if (modifiers_isCorrectableDeformed(t->scene, tc->obedit)) {
|
||||
/* check if we can use deform matrices for modifier from the
|
||||
* start up to stack, they are more accurate than quats */
|
||||
totleft = BKE_crazyspace_get_first_deform_matrices_editbmesh(&t->eval_ctx, t->scene, tc->obedit, em, &defmats, &defcos);
|
||||
}
|
||||
|
||||
/* if we still have more modifiers, also do crazyspace
|
||||
* correction with quats, relative to the coordinates after
|
||||
* the modifiers that support deform matrices (defcos) */
|
||||
|
||||
#if 0 /* TODO, fix crazyspace+extrude so it can be enabled for general use - campbell */
|
||||
if ((totleft > 0) || (totleft == -1))
|
||||
#else
|
||||
if (totleft > 0)
|
||||
#endif
|
||||
{
|
||||
mappedcos = BKE_crazyspace_get_mapped_editverts(&t->eval_ctx, t->scene, tc->obedit);
|
||||
quats = MEM_mallocN(em->bm->totvert * sizeof(*quats), "crazy quats");
|
||||
BKE_crazyspace_set_quats_editmesh(em, defcos, mappedcos, quats, !prop_mode);
|
||||
if (mappedcos)
|
||||
MEM_freeN(mappedcos);
|
||||
}
|
||||
|
||||
if (defcos) {
|
||||
MEM_freeN(defcos);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
tc->data_len = bm->totvertsel;
|
||||
}
|
||||
|
||||
tob = tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransObData(Mesh EditMode)");
|
||||
if (ELEM(t->mode, TFM_SKIN_RESIZE, TFM_SHRINKFATTEN)) {
|
||||
/* warning, this is overkill, we only need 2 extra floats,
|
||||
* but this stores loads of extra stuff, for TFM_SHRINKFATTEN its even more overkill
|
||||
* since we may not use the 'alt' transform mode to maintain shell thickness,
|
||||
* but with generic transform code its hard to lazy init vars */
|
||||
tx = tc->data_ext = MEM_callocN(tc->data_len * sizeof(TransDataExtension), "TransObData ext");
|
||||
}
|
||||
|
||||
copy_m3_m4(mtx, tc->obedit->obmat);
|
||||
/* we use a pseudoinverse so that when one of the axes is scaled to 0,
|
||||
* matrix inversion still works and we can still moving along the other */
|
||||
pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON);
|
||||
|
||||
if (prop_mode & T_PROP_CONNECTED) {
|
||||
editmesh_set_connectivity_distance(em->bm, mtx, dists, dists_index);
|
||||
}
|
||||
|
||||
if (is_island_center) {
|
||||
/* In this specific case, near-by vertices will need to know the island of the nearest connected vertex. */
|
||||
const bool calc_single_islands = (
|
||||
(prop_mode & T_PROP_CONNECTED) &&
|
||||
(t->around == V3D_AROUND_LOCAL_ORIGINS) &&
|
||||
(em->selectmode & SCE_SELECT_VERTEX));
|
||||
|
||||
island_info = editmesh_islands_info_calc(em, &island_info_tot, &island_vert_map, calc_single_islands);
|
||||
}
|
||||
|
||||
/* detect CrazySpace [tm] */
|
||||
if (modifiers_getCageIndex(t->scene, tc->obedit, NULL, 1) != -1) {
|
||||
int totleft = -1;
|
||||
if (modifiers_isCorrectableDeformed(t->scene, tc->obedit)) {
|
||||
/* check if we can use deform matrices for modifier from the
|
||||
* start up to stack, they are more accurate than quats */
|
||||
totleft = BKE_crazyspace_get_first_deform_matrices_editbmesh(&t->eval_ctx, t->scene, tc->obedit, em, &defmats, &defcos);
|
||||
}
|
||||
|
||||
/* if we still have more modifiers, also do crazyspace
|
||||
* correction with quats, relative to the coordinates after
|
||||
* the modifiers that support deform matrices (defcos) */
|
||||
|
||||
#if 0 /* TODO, fix crazyspace+extrude so it can be enabled for general use - campbell */
|
||||
if ((totleft > 0) || (totleft == -1))
|
||||
#else
|
||||
if (totleft > 0)
|
||||
#endif
|
||||
{
|
||||
mappedcos = BKE_crazyspace_get_mapped_editverts(&t->eval_ctx, t->scene, tc->obedit);
|
||||
quats = MEM_mallocN(em->bm->totvert * sizeof(*quats), "crazy quats");
|
||||
BKE_crazyspace_set_quats_editmesh(em, defcos, mappedcos, quats, !prop_mode);
|
||||
if (mappedcos)
|
||||
MEM_freeN(mappedcos);
|
||||
}
|
||||
|
||||
if (defcos) {
|
||||
MEM_freeN(defcos);
|
||||
}
|
||||
}
|
||||
|
||||
/* find out which half we do */
|
||||
if (mirror) {
|
||||
BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
|
||||
if (BM_elem_flag_test(eve, BM_ELEM_SELECT) && eve->co[0] != 0.0f) {
|
||||
if (eve->co[0] < 0.0f) {
|
||||
t->mirror = -1;
|
||||
mirror = -1;
|
||||
/* find out which half we do */
|
||||
if (mirror) {
|
||||
BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
|
||||
if (BM_elem_flag_test(eve, BM_ELEM_SELECT) && eve->co[0] != 0.0f) {
|
||||
if (eve->co[0] < 0.0f) {
|
||||
t->mirror = -1;
|
||||
mirror = -1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, a) {
|
||||
if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) {
|
||||
if (prop_mode || BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
|
||||
struct TransIslandData *v_island = NULL;
|
||||
float *bweight = (cd_vert_bweight_offset != -1) ? BM_ELEM_CD_GET_VOID_P(eve, cd_vert_bweight_offset) : NULL;
|
||||
BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, a) {
|
||||
if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) {
|
||||
if (prop_mode || BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
|
||||
struct TransIslandData *v_island = NULL;
|
||||
float *bweight = (cd_vert_bweight_offset != -1) ? BM_ELEM_CD_GET_VOID_P(eve, cd_vert_bweight_offset) : NULL;
|
||||
|
||||
if (island_info) {
|
||||
const int connected_index = (dists_index && dists_index[a] != -1) ? dists_index[a] : a;
|
||||
v_island = (island_vert_map[connected_index] != -1) ?
|
||||
&island_info[island_vert_map[connected_index]] : NULL;
|
||||
}
|
||||
if (island_info) {
|
||||
const int connected_index = (dists_index && dists_index[a] != -1) ? dists_index[a] : a;
|
||||
v_island = (island_vert_map[connected_index] != -1) ?
|
||||
&island_info[island_vert_map[connected_index]] : NULL;
|
||||
}
|
||||
|
||||
|
||||
VertsToTransData(t, tob, tx, em, eve, bweight, v_island);
|
||||
if (tx)
|
||||
tx++;
|
||||
VertsToTransData(t, tob, tx, em, eve, bweight, v_island);
|
||||
if (tx)
|
||||
tx++;
|
||||
|
||||
/* selected */
|
||||
if (BM_elem_flag_test(eve, BM_ELEM_SELECT))
|
||||
tob->flag |= TD_SELECTED;
|
||||
/* selected */
|
||||
if (BM_elem_flag_test(eve, BM_ELEM_SELECT))
|
||||
tob->flag |= TD_SELECTED;
|
||||
|
||||
if (prop_mode) {
|
||||
if (prop_mode & T_PROP_CONNECTED) {
|
||||
tob->dist = dists[a];
|
||||
if (prop_mode) {
|
||||
if (prop_mode & T_PROP_CONNECTED) {
|
||||
tob->dist = dists[a];
|
||||
}
|
||||
else {
|
||||
tob->flag |= TD_NOTCONNECTED;
|
||||
tob->dist = FLT_MAX;
|
||||
}
|
||||
}
|
||||
|
||||
/* CrazySpace */
|
||||
if (defmats || (quats && BM_elem_flag_test(eve, BM_ELEM_TAG))) {
|
||||
float mat[3][3], qmat[3][3], imat[3][3];
|
||||
|
||||
/* use both or either quat and defmat correction */
|
||||
if (quats && BM_elem_flag_test(eve, BM_ELEM_TAG)) {
|
||||
quat_to_mat3(qmat, quats[BM_elem_index_get(eve)]);
|
||||
|
||||
if (defmats)
|
||||
mul_m3_series(mat, defmats[a], qmat, mtx);
|
||||
else
|
||||
mul_m3_m3m3(mat, mtx, qmat);
|
||||
}
|
||||
else
|
||||
mul_m3_m3m3(mat, mtx, defmats[a]);
|
||||
|
||||
invert_m3_m3(imat, mat);
|
||||
|
||||
copy_m3_m3(tob->smtx, imat);
|
||||
copy_m3_m3(tob->mtx, mat);
|
||||
}
|
||||
else {
|
||||
tob->flag |= TD_NOTCONNECTED;
|
||||
tob->dist = FLT_MAX;
|
||||
copy_m3_m3(tob->smtx, smtx);
|
||||
copy_m3_m3(tob->mtx, mtx);
|
||||
}
|
||||
}
|
||||
|
||||
/* CrazySpace */
|
||||
if (defmats || (quats && BM_elem_flag_test(eve, BM_ELEM_TAG))) {
|
||||
float mat[3][3], qmat[3][3], imat[3][3];
|
||||
|
||||
/* use both or either quat and defmat correction */
|
||||
if (quats && BM_elem_flag_test(eve, BM_ELEM_TAG)) {
|
||||
quat_to_mat3(qmat, quats[BM_elem_index_get(eve)]);
|
||||
|
||||
if (defmats)
|
||||
mul_m3_series(mat, defmats[a], qmat, mtx);
|
||||
else
|
||||
mul_m3_m3m3(mat, mtx, qmat);
|
||||
/* Mirror? */
|
||||
if ((mirror > 0 && tob->iloc[0] > 0.0f) || (mirror < 0 && tob->iloc[0] < 0.0f)) {
|
||||
BMVert *vmir = EDBM_verts_mirror_get(em, eve); //t->obedit, em, eve, tob->iloc, a);
|
||||
if (vmir && vmir != eve) {
|
||||
tob->extra = vmir;
|
||||
}
|
||||
}
|
||||
else
|
||||
mul_m3_m3m3(mat, mtx, defmats[a]);
|
||||
|
||||
invert_m3_m3(imat, mat);
|
||||
|
||||
copy_m3_m3(tob->smtx, imat);
|
||||
copy_m3_m3(tob->mtx, mat);
|
||||
tob++;
|
||||
}
|
||||
else {
|
||||
copy_m3_m3(tob->smtx, smtx);
|
||||
copy_m3_m3(tob->mtx, mtx);
|
||||
}
|
||||
|
||||
/* Mirror? */
|
||||
if ((mirror > 0 && tob->iloc[0] > 0.0f) || (mirror < 0 && tob->iloc[0] < 0.0f)) {
|
||||
BMVert *vmir = EDBM_verts_mirror_get(em, eve); //t->obedit, em, eve, tob->iloc, a);
|
||||
if (vmir && vmir != eve) {
|
||||
tob->extra = vmir;
|
||||
}
|
||||
}
|
||||
tob++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (island_info) {
|
||||
MEM_freeN(island_info);
|
||||
MEM_freeN(island_vert_map);
|
||||
}
|
||||
|
||||
if (mirror != 0) {
|
||||
tob = tc->data;
|
||||
for (a = 0; a < tc->data_len; a++, tob++) {
|
||||
if (ABS(tob->loc[0]) <= 0.00001f) {
|
||||
tob->flag |= TD_MIRROR_EDGE;
|
||||
if (island_info) {
|
||||
MEM_freeN(island_info);
|
||||
MEM_freeN(island_vert_map);
|
||||
}
|
||||
|
||||
if (mirror != 0) {
|
||||
tob = tc->data;
|
||||
for (a = 0; a < tc->data_len; a++, tob++) {
|
||||
if (ABS(tob->loc[0]) <= 0.00001f) {
|
||||
tob->flag |= TD_MIRROR_EDGE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cleanup:
|
||||
/* crazy space free */
|
||||
if (quats)
|
||||
MEM_freeN(quats);
|
||||
if (defmats)
|
||||
MEM_freeN(defmats);
|
||||
if (dists)
|
||||
MEM_freeN(dists);
|
||||
if (dists_index)
|
||||
MEM_freeN(dists_index);
|
||||
/* crazy space free */
|
||||
if (quats)
|
||||
MEM_freeN(quats);
|
||||
if (defmats)
|
||||
MEM_freeN(defmats);
|
||||
if (dists)
|
||||
MEM_freeN(dists);
|
||||
if (dists_index)
|
||||
MEM_freeN(dists_index);
|
||||
|
||||
if (t->flag & T_MIRROR) {
|
||||
EDBM_verts_mirror_cache_end(em);
|
||||
}
|
||||
if (t->flag & T_MIRROR) {
|
||||
EDBM_verts_mirror_cache_end(em);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2781,40 +2781,40 @@ void flushTransNodes(TransInfo *t)
|
||||
const float dpi_fac = UI_DPI_FAC;
|
||||
|
||||
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
|
||||
int a;
|
||||
TransData *td;
|
||||
TransData2D *td2d;
|
||||
|
||||
applyGridAbsolute(t);
|
||||
|
||||
/* flush to 2d vector from internally used 3d vector */
|
||||
for (a = 0, td = tc->data, td2d = tc->data_2d; a < tc->data_len; a++, td++, td2d++) {
|
||||
bNode *node = td->extra;
|
||||
float locx, locy;
|
||||
int a;
|
||||
TransData *td;
|
||||
TransData2D *td2d;
|
||||
|
||||
/* weirdo - but the node system is a mix of free 2d elements and dpi sensitive UI */
|
||||
#ifdef USE_NODE_CENTER
|
||||
locx = (td2d->loc[0] - (BLI_rctf_size_x(&node->totr)) * +0.5f) / dpi_fac;
|
||||
locy = (td2d->loc[1] - (BLI_rctf_size_y(&node->totr)) * -0.5f) / dpi_fac;
|
||||
#else
|
||||
locx = td2d->loc[0] / dpi_fac;
|
||||
locy = td2d->loc[1] / dpi_fac;
|
||||
#endif
|
||||
|
||||
/* account for parents (nested nodes) */
|
||||
if (node->parent) {
|
||||
nodeFromView(node->parent, locx, locy, &node->locx, &node->locy);
|
||||
}
|
||||
else {
|
||||
node->locx = locx;
|
||||
node->locy = locy;
|
||||
}
|
||||
}
|
||||
applyGridAbsolute(t);
|
||||
|
||||
/* handle intersection with noodles */
|
||||
if (tc->data_len == 1) {
|
||||
ED_node_link_intersect_test(t->sa, 1);
|
||||
}
|
||||
/* flush to 2d vector from internally used 3d vector */
|
||||
for (a = 0, td = tc->data, td2d = tc->data_2d; a < tc->data_len; a++, td++, td2d++) {
|
||||
bNode *node = td->extra;
|
||||
float locx, locy;
|
||||
|
||||
/* weirdo - but the node system is a mix of free 2d elements and dpi sensitive UI */
|
||||
#ifdef USE_NODE_CENTER
|
||||
locx = (td2d->loc[0] - (BLI_rctf_size_x(&node->totr)) * +0.5f) / dpi_fac;
|
||||
locy = (td2d->loc[1] - (BLI_rctf_size_y(&node->totr)) * -0.5f) / dpi_fac;
|
||||
#else
|
||||
locx = td2d->loc[0] / dpi_fac;
|
||||
locy = td2d->loc[1] / dpi_fac;
|
||||
#endif
|
||||
|
||||
/* account for parents (nested nodes) */
|
||||
if (node->parent) {
|
||||
nodeFromView(node->parent, locx, locy, &node->locx, &node->locy);
|
||||
}
|
||||
else {
|
||||
node->locx = locx;
|
||||
node->locy = locy;
|
||||
}
|
||||
}
|
||||
|
||||
/* handle intersection with noodles */
|
||||
if (tc->data_len == 1) {
|
||||
ED_node_link_intersect_test(t->sa, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3018,161 +3018,161 @@ static void createTransUVs(bContext *C, TransInfo *t)
|
||||
|
||||
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
|
||||
|
||||
TransData *td = NULL;
|
||||
TransData2D *td2d = NULL;
|
||||
BMEditMesh *em = BKE_editmesh_from_object(tc->obedit);
|
||||
BMFace *efa;
|
||||
BMIter iter, liter;
|
||||
UvElementMap *elementmap = NULL;
|
||||
BLI_bitmap *island_enabled = NULL;
|
||||
struct { float co[2]; int co_num; } *island_center = NULL;
|
||||
int count = 0, countsel = 0, count_rejected = 0;
|
||||
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
|
||||
TransData *td = NULL;
|
||||
TransData2D *td2d = NULL;
|
||||
BMEditMesh *em = BKE_editmesh_from_object(tc->obedit);
|
||||
BMFace *efa;
|
||||
BMIter iter, liter;
|
||||
UvElementMap *elementmap = NULL;
|
||||
BLI_bitmap *island_enabled = NULL;
|
||||
struct { float co[2]; int co_num; } *island_center = NULL;
|
||||
int count = 0, countsel = 0, count_rejected = 0;
|
||||
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
|
||||
|
||||
if (!ED_space_image_show_uvedit(sima, tc->obedit)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* count */
|
||||
if (is_prop_connected || is_island_center) {
|
||||
/* create element map with island information */
|
||||
const bool use_facesel = (ts->uv_flag & UV_SYNC_SELECTION) == 0;
|
||||
elementmap = BM_uv_element_map_create(em->bm, use_facesel, false, true);
|
||||
if (elementmap == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_prop_connected) {
|
||||
island_enabled = BLI_BITMAP_NEW(elementmap->totalIslands, "TransIslandData(UV Editing)");
|
||||
}
|
||||
|
||||
if (is_island_center) {
|
||||
island_center = MEM_callocN(sizeof(*island_center) * elementmap->totalIslands, __func__);
|
||||
}
|
||||
}
|
||||
|
||||
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
|
||||
BMLoop *l;
|
||||
|
||||
if (!uvedit_face_visible_test(scene, tc->obedit, ima, efa)) {
|
||||
BM_elem_flag_disable(efa, BM_ELEM_TAG);
|
||||
if (!ED_space_image_show_uvedit(sima, tc->obedit)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
BM_elem_flag_enable(efa, BM_ELEM_TAG);
|
||||
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
|
||||
if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) {
|
||||
countsel++;
|
||||
/* count */
|
||||
if (is_prop_connected || is_island_center) {
|
||||
/* create element map with island information */
|
||||
const bool use_facesel = (ts->uv_flag & UV_SYNC_SELECTION) == 0;
|
||||
elementmap = BM_uv_element_map_create(em->bm, use_facesel, false, true);
|
||||
if (elementmap == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_prop_connected || island_center) {
|
||||
UvElement *element = BM_uv_element_get(elementmap, efa, l);
|
||||
if (is_prop_connected) {
|
||||
island_enabled = BLI_BITMAP_NEW(elementmap->totalIslands, "TransIslandData(UV Editing)");
|
||||
}
|
||||
|
||||
if (is_prop_connected) {
|
||||
BLI_BITMAP_ENABLE(island_enabled, element->island);
|
||||
}
|
||||
if (is_island_center) {
|
||||
island_center = MEM_callocN(sizeof(*island_center) * elementmap->totalIslands, __func__);
|
||||
}
|
||||
}
|
||||
|
||||
if (is_island_center) {
|
||||
if (element->flag == false) {
|
||||
MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
|
||||
add_v2_v2(island_center[element->island].co, luv->uv);
|
||||
island_center[element->island].co_num++;
|
||||
element->flag = true;
|
||||
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
|
||||
BMLoop *l;
|
||||
|
||||
if (!uvedit_face_visible_test(scene, tc->obedit, ima, efa)) {
|
||||
BM_elem_flag_disable(efa, BM_ELEM_TAG);
|
||||
continue;
|
||||
}
|
||||
|
||||
BM_elem_flag_enable(efa, BM_ELEM_TAG);
|
||||
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
|
||||
if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) {
|
||||
countsel++;
|
||||
|
||||
if (is_prop_connected || island_center) {
|
||||
UvElement *element = BM_uv_element_get(elementmap, efa, l);
|
||||
|
||||
if (is_prop_connected) {
|
||||
BLI_BITMAP_ENABLE(island_enabled, element->island);
|
||||
}
|
||||
|
||||
if (is_island_center) {
|
||||
if (element->flag == false) {
|
||||
MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
|
||||
add_v2_v2(island_center[element->island].co, luv->uv);
|
||||
island_center[element->island].co_num++;
|
||||
element->flag = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (is_prop_edit) {
|
||||
count++;
|
||||
if (is_prop_edit) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* note: in prop mode we need at least 1 selected */
|
||||
if (countsel == 0) {
|
||||
goto finally;
|
||||
}
|
||||
|
||||
if (is_island_center) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < elementmap->totalIslands; i++) {
|
||||
mul_v2_fl(island_center[i].co, 1.0f / island_center[i].co_num);
|
||||
mul_v2_v2(island_center[i].co, t->aspect);
|
||||
/* note: in prop mode we need at least 1 selected */
|
||||
if (countsel == 0) {
|
||||
goto finally;
|
||||
}
|
||||
}
|
||||
|
||||
tc->data_len = (is_prop_edit) ? count : countsel;
|
||||
tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransObData(UV Editing)");
|
||||
/* for each 2d uv coord a 3d vector is allocated, so that they can be
|
||||
* treated just as if they were 3d verts */
|
||||
tc->data_2d = MEM_callocN(tc->data_len * sizeof(TransData2D), "TransObData2D(UV Editing)");
|
||||
if (is_island_center) {
|
||||
int i;
|
||||
|
||||
if (sima->flag & SI_CLIP_UV)
|
||||
t->flag |= T_CLIP_UV;
|
||||
for (i = 0; i < elementmap->totalIslands; i++) {
|
||||
mul_v2_fl(island_center[i].co, 1.0f / island_center[i].co_num);
|
||||
mul_v2_v2(island_center[i].co, t->aspect);
|
||||
}
|
||||
}
|
||||
|
||||
td = tc->data;
|
||||
td2d = tc->data_2d;
|
||||
tc->data_len = (is_prop_edit) ? count : countsel;
|
||||
tc->data = MEM_callocN(tc->data_len * sizeof(TransData), "TransObData(UV Editing)");
|
||||
/* for each 2d uv coord a 3d vector is allocated, so that they can be
|
||||
* treated just as if they were 3d verts */
|
||||
tc->data_2d = MEM_callocN(tc->data_len * sizeof(TransData2D), "TransObData2D(UV Editing)");
|
||||
|
||||
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
|
||||
BMLoop *l;
|
||||
if (sima->flag & SI_CLIP_UV)
|
||||
t->flag |= T_CLIP_UV;
|
||||
|
||||
if (!BM_elem_flag_test(efa, BM_ELEM_TAG))
|
||||
continue;
|
||||
td = tc->data;
|
||||
td2d = tc->data_2d;
|
||||
|
||||
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
|
||||
const bool selected = uvedit_uv_select_test(scene, l, cd_loop_uv_offset);
|
||||
MLoopUV *luv;
|
||||
const float *center = NULL;
|
||||
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
|
||||
BMLoop *l;
|
||||
|
||||
if (!is_prop_edit && !selected)
|
||||
if (!BM_elem_flag_test(efa, BM_ELEM_TAG))
|
||||
continue;
|
||||
|
||||
if (is_prop_connected || is_island_center) {
|
||||
UvElement *element = BM_uv_element_get(elementmap, efa, l);
|
||||
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
|
||||
const bool selected = uvedit_uv_select_test(scene, l, cd_loop_uv_offset);
|
||||
MLoopUV *luv;
|
||||
const float *center = NULL;
|
||||
|
||||
if (is_prop_connected) {
|
||||
if (!BLI_BITMAP_TEST(island_enabled, element->island)) {
|
||||
count_rejected++;
|
||||
continue;
|
||||
if (!is_prop_edit && !selected)
|
||||
continue;
|
||||
|
||||
if (is_prop_connected || is_island_center) {
|
||||
UvElement *element = BM_uv_element_get(elementmap, efa, l);
|
||||
|
||||
if (is_prop_connected) {
|
||||
if (!BLI_BITMAP_TEST(island_enabled, element->island)) {
|
||||
count_rejected++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (is_island_center) {
|
||||
center = island_center[element->island].co;
|
||||
}
|
||||
}
|
||||
|
||||
if (is_island_center) {
|
||||
center = island_center[element->island].co;
|
||||
}
|
||||
BM_elem_flag_enable(l, BM_ELEM_TAG);
|
||||
luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
|
||||
UVsToTransData(t->aspect, td++, td2d++, luv->uv, center, selected);
|
||||
}
|
||||
|
||||
BM_elem_flag_enable(l, BM_ELEM_TAG);
|
||||
luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
|
||||
UVsToTransData(t->aspect, td++, td2d++, luv->uv, center, selected);
|
||||
}
|
||||
}
|
||||
|
||||
if (is_prop_connected) {
|
||||
tc->data_len -= count_rejected;
|
||||
}
|
||||
|
||||
if (sima->flag & SI_LIVE_UNWRAP) {
|
||||
/* TODO(campbell): xform: Only active object currently!
|
||||
* it uses a static variable. */
|
||||
if (tc->is_active) {
|
||||
ED_uvedit_live_unwrap_begin(t->scene, tc->obedit);
|
||||
}
|
||||
}
|
||||
|
||||
finally:
|
||||
if (is_prop_connected || is_island_center) {
|
||||
BM_uv_element_map_free(elementmap);
|
||||
|
||||
if (is_prop_connected) {
|
||||
MEM_freeN(island_enabled);
|
||||
tc->data_len -= count_rejected;
|
||||
}
|
||||
|
||||
if (island_center) {
|
||||
MEM_freeN(island_center);
|
||||
if (sima->flag & SI_LIVE_UNWRAP) {
|
||||
/* TODO(campbell): xform: Only active object currently!
|
||||
* it uses a static variable. */
|
||||
if (tc->is_active) {
|
||||
ED_uvedit_live_unwrap_begin(t->scene, tc->obedit);
|
||||
}
|
||||
}
|
||||
|
||||
finally:
|
||||
if (is_prop_connected || is_island_center) {
|
||||
BM_uv_element_map_free(elementmap);
|
||||
|
||||
if (is_prop_connected) {
|
||||
MEM_freeN(island_enabled);
|
||||
}
|
||||
|
||||
if (island_center) {
|
||||
MEM_freeN(island_center);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3182,30 +3182,30 @@ void flushTransUVs(TransInfo *t)
|
||||
const bool use_pixel_snap = ((sima->flag & SI_PIXELSNAP) && (t->state != TRANS_CANCEL));
|
||||
|
||||
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
|
||||
TransData2D *td;
|
||||
int a;
|
||||
float aspect_inv[2], size[2];
|
||||
TransData2D *td;
|
||||
int a;
|
||||
float aspect_inv[2], size[2];
|
||||
|
||||
aspect_inv[0] = 1.0f / t->aspect[0];
|
||||
aspect_inv[1] = 1.0f / t->aspect[1];
|
||||
|
||||
if (use_pixel_snap) {
|
||||
int size_i[2];
|
||||
ED_space_image_get_size(sima, &size_i[0], &size_i[1]);
|
||||
size[0] = size_i[0];
|
||||
size[1] = size_i[1];
|
||||
}
|
||||
|
||||
/* flush to 2d vector from internally used 3d vector */
|
||||
for (a = 0, td = tc->data_2d; a < tc->data_len; a++, td++) {
|
||||
td->loc2d[0] = td->loc[0] * aspect_inv[0];
|
||||
td->loc2d[1] = td->loc[1] * aspect_inv[1];
|
||||
aspect_inv[0] = 1.0f / t->aspect[0];
|
||||
aspect_inv[1] = 1.0f / t->aspect[1];
|
||||
|
||||
if (use_pixel_snap) {
|
||||
td->loc2d[0] = roundf(td->loc2d[0] * size[0]) / size[0];
|
||||
td->loc2d[1] = roundf(td->loc2d[1] * size[1]) / size[1];
|
||||
int size_i[2];
|
||||
ED_space_image_get_size(sima, &size_i[0], &size_i[1]);
|
||||
size[0] = size_i[0];
|
||||
size[1] = size_i[1];
|
||||
}
|
||||
|
||||
/* flush to 2d vector from internally used 3d vector */
|
||||
for (a = 0, td = tc->data_2d; a < tc->data_len; a++, td++) {
|
||||
td->loc2d[0] = td->loc[0] * aspect_inv[0];
|
||||
td->loc2d[1] = td->loc[1] * aspect_inv[1];
|
||||
|
||||
if (use_pixel_snap) {
|
||||
td->loc2d[0] = roundf(td->loc2d[0] * size[0]) / size[0];
|
||||
td->loc2d[1] = roundf(td->loc2d[1] * size[1]) / size[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3220,43 +3220,43 @@ bool clipUVTransform(TransInfo *t, float vec[2], const bool resize)
|
||||
|
||||
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
|
||||
|
||||
TransData *td;
|
||||
int a;
|
||||
TransData *td;
|
||||
int a;
|
||||
|
||||
for (a = 0, td = tc->data; a < tc->data_len; a++, td++) {
|
||||
minmax_v2v2_v2(min, max, td->loc);
|
||||
}
|
||||
for (a = 0, td = tc->data; a < tc->data_len; a++, td++) {
|
||||
minmax_v2v2_v2(min, max, td->loc);
|
||||
}
|
||||
|
||||
if (resize) {
|
||||
if (min[0] < 0.0f && t->center_global[0] > 0.0f && t->center_global[0] < t->aspect[0] * 0.5f)
|
||||
vec[0] *= t->center_global[0] / (t->center_global[0] - min[0]);
|
||||
else if (max[0] > t->aspect[0] && t->center_global[0] < t->aspect[0])
|
||||
vec[0] *= (t->center_global[0] - t->aspect[0]) / (t->center_global[0] - max[0]);
|
||||
else
|
||||
clipx = 0;
|
||||
if (resize) {
|
||||
if (min[0] < 0.0f && t->center_global[0] > 0.0f && t->center_global[0] < t->aspect[0] * 0.5f)
|
||||
vec[0] *= t->center_global[0] / (t->center_global[0] - min[0]);
|
||||
else if (max[0] > t->aspect[0] && t->center_global[0] < t->aspect[0])
|
||||
vec[0] *= (t->center_global[0] - t->aspect[0]) / (t->center_global[0] - max[0]);
|
||||
else
|
||||
clipx = 0;
|
||||
|
||||
if (min[1] < 0.0f && t->center_global[1] > 0.0f && t->center_global[1] < t->aspect[1] * 0.5f)
|
||||
vec[1] *= t->center_global[1] / (t->center_global[1] - min[1]);
|
||||
else if (max[1] > t->aspect[1] && t->center_global[1] < t->aspect[1])
|
||||
vec[1] *= (t->center_global[1] - t->aspect[1]) / (t->center_global[1] - max[1]);
|
||||
else
|
||||
clipy = 0;
|
||||
}
|
||||
else {
|
||||
if (min[0] < 0.0f)
|
||||
vec[0] -= min[0];
|
||||
else if (max[0] > t->aspect[0])
|
||||
vec[0] -= max[0] - t->aspect[0];
|
||||
else
|
||||
clipx = 0;
|
||||
if (min[1] < 0.0f && t->center_global[1] > 0.0f && t->center_global[1] < t->aspect[1] * 0.5f)
|
||||
vec[1] *= t->center_global[1] / (t->center_global[1] - min[1]);
|
||||
else if (max[1] > t->aspect[1] && t->center_global[1] < t->aspect[1])
|
||||
vec[1] *= (t->center_global[1] - t->aspect[1]) / (t->center_global[1] - max[1]);
|
||||
else
|
||||
clipy = 0;
|
||||
}
|
||||
else {
|
||||
if (min[0] < 0.0f)
|
||||
vec[0] -= min[0];
|
||||
else if (max[0] > t->aspect[0])
|
||||
vec[0] -= max[0] - t->aspect[0];
|
||||
else
|
||||
clipx = 0;
|
||||
|
||||
if (min[1] < 0.0f)
|
||||
vec[1] -= min[1];
|
||||
else if (max[1] > t->aspect[1])
|
||||
vec[1] -= max[1] - t->aspect[1];
|
||||
else
|
||||
clipy = 0;
|
||||
}
|
||||
if (min[1] < 0.0f)
|
||||
vec[1] -= min[1];
|
||||
else if (max[1] > t->aspect[1])
|
||||
vec[1] -= max[1] - t->aspect[1];
|
||||
else
|
||||
clipy = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return (clipx || clipy);
|
||||
@@ -3265,17 +3265,17 @@ bool clipUVTransform(TransInfo *t, float vec[2], const bool resize)
|
||||
void clipUVData(TransInfo *t)
|
||||
{
|
||||
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
|
||||
TransData *td = tc->data;
|
||||
for (int a = 0; a < tc->data_len; a++, td++) {
|
||||
if (td->flag & TD_NOACTION)
|
||||
break;
|
||||
TransData *td = tc->data;
|
||||
for (int a = 0; a < tc->data_len; a++, td++) {
|
||||
if (td->flag & TD_NOACTION)
|
||||
break;
|
||||
|
||||
if ((td->flag & TD_SKIP) || (!td->loc))
|
||||
continue;
|
||||
if ((td->flag & TD_SKIP) || (!td->loc))
|
||||
continue;
|
||||
|
||||
td->loc[0] = min_ff(max_ff(0.0f, td->loc[0]), t->aspect[0]);
|
||||
td->loc[1] = min_ff(max_ff(0.0f, td->loc[1]), t->aspect[1]);
|
||||
}
|
||||
td->loc[0] = min_ff(max_ff(0.0f, td->loc[0]), t->aspect[0]);
|
||||
td->loc[1] = min_ff(max_ff(0.0f, td->loc[1]), t->aspect[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6233,40 +6233,40 @@ static void special_aftertrans_update__mesh(bContext *UNUSED(C), TransInfo *t)
|
||||
{
|
||||
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
|
||||
|
||||
BMEditMesh *em = BKE_editmesh_from_object(tc->obedit);
|
||||
BMesh *bm = em->bm;
|
||||
char hflag;
|
||||
bool has_face_sel = (bm->totfacesel != 0);
|
||||
BMEditMesh *em = BKE_editmesh_from_object(tc->obedit);
|
||||
BMesh *bm = em->bm;
|
||||
char hflag;
|
||||
bool has_face_sel = (bm->totfacesel != 0);
|
||||
|
||||
if (t->flag & T_MIRROR) {
|
||||
TransData *td;
|
||||
int i;
|
||||
if (t->flag & T_MIRROR) {
|
||||
TransData *td;
|
||||
int i;
|
||||
|
||||
/* rather then adjusting the selection (which the user would notice)
|
||||
* tag all mirrored verts, then automerge those */
|
||||
BM_mesh_elem_hflag_disable_all(bm, BM_VERT, BM_ELEM_TAG, false);
|
||||
/* rather then adjusting the selection (which the user would notice)
|
||||
* tag all mirrored verts, then automerge those */
|
||||
BM_mesh_elem_hflag_disable_all(bm, BM_VERT, BM_ELEM_TAG, false);
|
||||
|
||||
for (i = 0, td = tc->data; i < tc->data_len; i++, td++) {
|
||||
if (td->extra) {
|
||||
BM_elem_flag_enable((BMVert *)td->extra, BM_ELEM_TAG);
|
||||
for (i = 0, td = tc->data; i < tc->data_len; i++, td++) {
|
||||
if (td->extra) {
|
||||
BM_elem_flag_enable((BMVert *)td->extra, BM_ELEM_TAG);
|
||||
}
|
||||
}
|
||||
|
||||
hflag = BM_ELEM_SELECT | BM_ELEM_TAG;
|
||||
}
|
||||
else {
|
||||
hflag = BM_ELEM_SELECT;
|
||||
}
|
||||
|
||||
hflag = BM_ELEM_SELECT | BM_ELEM_TAG;
|
||||
}
|
||||
else {
|
||||
hflag = BM_ELEM_SELECT;
|
||||
}
|
||||
EDBM_automerge(t->scene, tc->obedit, true, hflag);
|
||||
|
||||
EDBM_automerge(t->scene, tc->obedit, true, hflag);
|
||||
|
||||
/* Special case, this is needed or faces won't re-select.
|
||||
* Flush selected edges to faces. */
|
||||
if (has_face_sel && (em->selectmode == SCE_SELECT_FACE)) {
|
||||
EDBM_selectmode_flush_ex(em, SCE_SELECT_EDGE);
|
||||
/* Special case, this is needed or faces won't re-select.
|
||||
* Flush selected edges to faces. */
|
||||
if (has_face_sel && (em->selectmode == SCE_SELECT_FACE)) {
|
||||
EDBM_selectmode_flush_ex(em, SCE_SELECT_EDGE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* inserting keys, pointcache, redraw events... */
|
||||
@@ -6300,19 +6300,19 @@ void special_aftertrans_update(bContext *C, TransInfo *t)
|
||||
projectEdgeSlideData(t, true);
|
||||
|
||||
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
|
||||
EdgeSlideData *sld = tc->custom.mode.data;
|
||||
EdgeSlideData *sld = tc->custom.mode.data;
|
||||
|
||||
/* free temporary faces to avoid automerging and deleting
|
||||
* during cleanup - psy-fi */
|
||||
freeEdgeSlideTempFaces(sld);
|
||||
/* free temporary faces to avoid automerging and deleting
|
||||
* during cleanup - psy-fi */
|
||||
freeEdgeSlideTempFaces(sld);
|
||||
}
|
||||
}
|
||||
else if (t->mode == TFM_VERT_SLIDE) {
|
||||
/* as above */
|
||||
projectVertSlideData(t, true);
|
||||
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
|
||||
VertSlideData *sld = tc->custom.mode.data;
|
||||
freeVertSlideTempFaces(sld);
|
||||
VertSlideData *sld = tc->custom.mode.data;
|
||||
freeVertSlideTempFaces(sld);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6617,55 +6617,55 @@ void special_aftertrans_update(bContext *C, TransInfo *t)
|
||||
|
||||
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
|
||||
|
||||
bArmature *arm;
|
||||
bPoseChannel *pchan;
|
||||
short targetless_ik = 0;
|
||||
bArmature *arm;
|
||||
bPoseChannel *pchan;
|
||||
short targetless_ik = 0;
|
||||
|
||||
ob = tc->poseobj;
|
||||
arm = ob->data;
|
||||
ob = tc->poseobj;
|
||||
arm = ob->data;
|
||||
|
||||
if ((t->flag & T_AUTOIK) && (t->options & CTX_AUTOCONFIRM)) {
|
||||
/* when running transform non-interactively (operator exec),
|
||||
* we need to update the pose otherwise no updates get called during
|
||||
* transform and the auto-ik is not applied. see [#26164] */
|
||||
struct Object *pose_ob = tc->poseobj;
|
||||
BKE_pose_where_is(&t->eval_ctx, t->scene, pose_ob);
|
||||
}
|
||||
|
||||
/* set BONE_TRANSFORM flags for autokey, manipulator draw might have changed them */
|
||||
if (!canceled && (t->mode != TFM_DUMMY))
|
||||
count_set_pose_transflags(&t->mode, t->around, ob);
|
||||
|
||||
/* if target-less IK grabbing, we calculate the pchan transforms and clear flag */
|
||||
if (!canceled && t->mode == TFM_TRANSLATION)
|
||||
targetless_ik = apply_targetless_ik(ob);
|
||||
else {
|
||||
/* not forget to clear the auto flag */
|
||||
for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
|
||||
bKinematicConstraint *data = has_targetless_ik(pchan);
|
||||
if (data) data->flag &= ~CONSTRAINT_IK_AUTO;
|
||||
if ((t->flag & T_AUTOIK) && (t->options & CTX_AUTOCONFIRM)) {
|
||||
/* when running transform non-interactively (operator exec),
|
||||
* we need to update the pose otherwise no updates get called during
|
||||
* transform and the auto-ik is not applied. see [#26164] */
|
||||
struct Object *pose_ob = tc->poseobj;
|
||||
BKE_pose_where_is(&t->eval_ctx, t->scene, pose_ob);
|
||||
}
|
||||
}
|
||||
|
||||
if (t->mode == TFM_TRANSLATION)
|
||||
pose_grab_with_ik_clear(ob);
|
||||
/* set BONE_TRANSFORM flags for autokey, manipulator draw might have changed them */
|
||||
if (!canceled && (t->mode != TFM_DUMMY))
|
||||
count_set_pose_transflags(&t->mode, t->around, ob);
|
||||
|
||||
/* automatic inserting of keys and unkeyed tagging - only if transform wasn't canceled (or TFM_DUMMY) */
|
||||
if (!canceled && (t->mode != TFM_DUMMY)) {
|
||||
autokeyframe_pose_cb_func(C, t->scene, (View3D *)t->view, ob, t->mode, targetless_ik);
|
||||
DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
|
||||
}
|
||||
else if (arm->flag & ARM_DELAYDEFORM) {
|
||||
/* TODO(sergey): Armature is already updated by recalcData(), so we
|
||||
* might save some time by skipping re-evaluating it. But this isn't
|
||||
* possible yet within new dependency graph, and also other contexts
|
||||
* might need to update their CoW copies.
|
||||
*/
|
||||
DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
|
||||
}
|
||||
else {
|
||||
DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
|
||||
}
|
||||
/* if target-less IK grabbing, we calculate the pchan transforms and clear flag */
|
||||
if (!canceled && t->mode == TFM_TRANSLATION)
|
||||
targetless_ik = apply_targetless_ik(ob);
|
||||
else {
|
||||
/* not forget to clear the auto flag */
|
||||
for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
|
||||
bKinematicConstraint *data = has_targetless_ik(pchan);
|
||||
if (data) data->flag &= ~CONSTRAINT_IK_AUTO;
|
||||
}
|
||||
}
|
||||
|
||||
if (t->mode == TFM_TRANSLATION)
|
||||
pose_grab_with_ik_clear(ob);
|
||||
|
||||
/* automatic inserting of keys and unkeyed tagging - only if transform wasn't canceled (or TFM_DUMMY) */
|
||||
if (!canceled && (t->mode != TFM_DUMMY)) {
|
||||
autokeyframe_pose_cb_func(C, t->scene, (View3D *)t->view, ob, t->mode, targetless_ik);
|
||||
DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
|
||||
}
|
||||
else if (arm->flag & ARM_DELAYDEFORM) {
|
||||
/* TODO(sergey): Armature is already updated by recalcData(), so we
|
||||
* might save some time by skipping re-evaluating it. But this isn't
|
||||
* possible yet within new dependency graph, and also other contexts
|
||||
* might need to update their CoW copies.
|
||||
*/
|
||||
DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
|
||||
}
|
||||
else {
|
||||
DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (t->options & CTX_PAINT_CURVE) {
|
||||
|
||||
@@ -131,130 +131,130 @@ void getViewVector(TransInfo *t, float coord[3], float vec[3])
|
||||
static void clipMirrorModifier(TransInfo *t)
|
||||
{
|
||||
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
|
||||
Object *ob = tc->obedit;
|
||||
ModifierData *md = ob->modifiers.first;
|
||||
float tolerance[3] = {0.0f, 0.0f, 0.0f};
|
||||
int axis = 0;
|
||||
|
||||
for (; md; md = md->next) {
|
||||
if ((md->type == eModifierType_Mirror) && (md->mode & eModifierMode_Realtime)) {
|
||||
MirrorModifierData *mmd = (MirrorModifierData *) md;
|
||||
|
||||
if (mmd->flag & MOD_MIR_CLIPPING) {
|
||||
axis = 0;
|
||||
if (mmd->flag & MOD_MIR_AXIS_X) {
|
||||
axis |= 1;
|
||||
tolerance[0] = mmd->tolerance;
|
||||
}
|
||||
if (mmd->flag & MOD_MIR_AXIS_Y) {
|
||||
axis |= 2;
|
||||
tolerance[1] = mmd->tolerance;
|
||||
}
|
||||
if (mmd->flag & MOD_MIR_AXIS_Z) {
|
||||
axis |= 4;
|
||||
tolerance[2] = mmd->tolerance;
|
||||
}
|
||||
if (axis) {
|
||||
float mtx[4][4], imtx[4][4];
|
||||
int i;
|
||||
|
||||
if (mmd->mirror_ob) {
|
||||
float obinv[4][4];
|
||||
|
||||
invert_m4_m4(obinv, mmd->mirror_ob->obmat);
|
||||
mul_m4_m4m4(mtx, obinv, ob->obmat);
|
||||
invert_m4_m4(imtx, mtx);
|
||||
Object *ob = tc->obedit;
|
||||
ModifierData *md = ob->modifiers.first;
|
||||
float tolerance[3] = {0.0f, 0.0f, 0.0f};
|
||||
int axis = 0;
|
||||
|
||||
for (; md; md = md->next) {
|
||||
if ((md->type == eModifierType_Mirror) && (md->mode & eModifierMode_Realtime)) {
|
||||
MirrorModifierData *mmd = (MirrorModifierData *) md;
|
||||
|
||||
if (mmd->flag & MOD_MIR_CLIPPING) {
|
||||
axis = 0;
|
||||
if (mmd->flag & MOD_MIR_AXIS_X) {
|
||||
axis |= 1;
|
||||
tolerance[0] = mmd->tolerance;
|
||||
}
|
||||
|
||||
TransData *td = tc->data;
|
||||
for (i = 0; i < tc->data_len; i++, td++) {
|
||||
int clip;
|
||||
float loc[3], iloc[3];
|
||||
|
||||
if (td->flag & TD_NOACTION)
|
||||
break;
|
||||
if (td->loc == NULL)
|
||||
break;
|
||||
|
||||
if (td->flag & TD_SKIP)
|
||||
continue;
|
||||
|
||||
copy_v3_v3(loc, td->loc);
|
||||
copy_v3_v3(iloc, td->iloc);
|
||||
|
||||
if (mmd->flag & MOD_MIR_AXIS_Y) {
|
||||
axis |= 2;
|
||||
tolerance[1] = mmd->tolerance;
|
||||
}
|
||||
if (mmd->flag & MOD_MIR_AXIS_Z) {
|
||||
axis |= 4;
|
||||
tolerance[2] = mmd->tolerance;
|
||||
}
|
||||
if (axis) {
|
||||
float mtx[4][4], imtx[4][4];
|
||||
int i;
|
||||
|
||||
if (mmd->mirror_ob) {
|
||||
mul_m4_v3(mtx, loc);
|
||||
mul_m4_v3(mtx, iloc);
|
||||
float obinv[4][4];
|
||||
|
||||
invert_m4_m4(obinv, mmd->mirror_ob->obmat);
|
||||
mul_m4_m4m4(mtx, obinv, ob->obmat);
|
||||
invert_m4_m4(imtx, mtx);
|
||||
}
|
||||
|
||||
clip = 0;
|
||||
if (axis & 1) {
|
||||
if (fabsf(iloc[0]) <= tolerance[0] ||
|
||||
loc[0] * iloc[0] < 0.0f)
|
||||
{
|
||||
loc[0] = 0.0f;
|
||||
clip = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (axis & 2) {
|
||||
if (fabsf(iloc[1]) <= tolerance[1] ||
|
||||
loc[1] * iloc[1] < 0.0f)
|
||||
{
|
||||
loc[1] = 0.0f;
|
||||
clip = 1;
|
||||
}
|
||||
}
|
||||
if (axis & 4) {
|
||||
if (fabsf(iloc[2]) <= tolerance[2] ||
|
||||
loc[2] * iloc[2] < 0.0f)
|
||||
{
|
||||
loc[2] = 0.0f;
|
||||
clip = 1;
|
||||
}
|
||||
}
|
||||
if (clip) {
|
||||
|
||||
TransData *td = tc->data;
|
||||
for (i = 0; i < tc->data_len; i++, td++) {
|
||||
int clip;
|
||||
float loc[3], iloc[3];
|
||||
|
||||
if (td->flag & TD_NOACTION)
|
||||
break;
|
||||
if (td->loc == NULL)
|
||||
break;
|
||||
|
||||
if (td->flag & TD_SKIP)
|
||||
continue;
|
||||
|
||||
copy_v3_v3(loc, td->loc);
|
||||
copy_v3_v3(iloc, td->iloc);
|
||||
|
||||
if (mmd->mirror_ob) {
|
||||
mul_m4_v3(imtx, loc);
|
||||
mul_m4_v3(mtx, loc);
|
||||
mul_m4_v3(mtx, iloc);
|
||||
}
|
||||
|
||||
clip = 0;
|
||||
if (axis & 1) {
|
||||
if (fabsf(iloc[0]) <= tolerance[0] ||
|
||||
loc[0] * iloc[0] < 0.0f)
|
||||
{
|
||||
loc[0] = 0.0f;
|
||||
clip = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (axis & 2) {
|
||||
if (fabsf(iloc[1]) <= tolerance[1] ||
|
||||
loc[1] * iloc[1] < 0.0f)
|
||||
{
|
||||
loc[1] = 0.0f;
|
||||
clip = 1;
|
||||
}
|
||||
}
|
||||
if (axis & 4) {
|
||||
if (fabsf(iloc[2]) <= tolerance[2] ||
|
||||
loc[2] * iloc[2] < 0.0f)
|
||||
{
|
||||
loc[2] = 0.0f;
|
||||
clip = 1;
|
||||
}
|
||||
}
|
||||
if (clip) {
|
||||
if (mmd->mirror_ob) {
|
||||
mul_m4_v3(imtx, loc);
|
||||
}
|
||||
copy_v3_v3(td->loc, loc);
|
||||
}
|
||||
copy_v3_v3(td->loc, loc);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* assumes obedit set to mesh object */
|
||||
static void editbmesh_apply_to_mirror(TransInfo *t)
|
||||
{
|
||||
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
|
||||
TransData *td = tc->data;
|
||||
BMVert *eve;
|
||||
int i;
|
||||
TransData *td = tc->data;
|
||||
BMVert *eve;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < tc->data_len; i++, td++) {
|
||||
if (td->flag & TD_NOACTION)
|
||||
break;
|
||||
if (td->loc == NULL)
|
||||
break;
|
||||
if (td->flag & TD_SKIP)
|
||||
continue;
|
||||
|
||||
eve = td->extra;
|
||||
if (eve) {
|
||||
eve->co[0] = -td->loc[0];
|
||||
eve->co[1] = td->loc[1];
|
||||
eve->co[2] = td->loc[2];
|
||||
for (i = 0; i < tc->data_len; i++, td++) {
|
||||
if (td->flag & TD_NOACTION)
|
||||
break;
|
||||
if (td->loc == NULL)
|
||||
break;
|
||||
if (td->flag & TD_SKIP)
|
||||
continue;
|
||||
|
||||
eve = td->extra;
|
||||
if (eve) {
|
||||
eve->co[0] = -td->loc[0];
|
||||
eve->co[1] = td->loc[1];
|
||||
eve->co[2] = td->loc[2];
|
||||
}
|
||||
|
||||
if (td->flag & TD_MIRROR_EDGE) {
|
||||
td->loc[0] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (td->flag & TD_MIRROR_EDGE) {
|
||||
td->loc[0] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -737,27 +737,27 @@ static void recalcData_objects(TransInfo *t)
|
||||
}
|
||||
|
||||
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
|
||||
Curve *cu = tc->obedit->data;
|
||||
ListBase *nurbs = BKE_curve_editNurbs_get(cu);
|
||||
Nurb *nu = nurbs->first;
|
||||
Curve *cu = tc->obedit->data;
|
||||
ListBase *nurbs = BKE_curve_editNurbs_get(cu);
|
||||
Nurb *nu = nurbs->first;
|
||||
|
||||
DEG_id_tag_update(tc->obedit->data, 0); /* sets recalc flags */
|
||||
DEG_id_tag_update(tc->obedit->data, 0); /* sets recalc flags */
|
||||
|
||||
if (t->state == TRANS_CANCEL) {
|
||||
while (nu) {
|
||||
BKE_nurb_handles_calc(nu); /* Cant do testhandlesNurb here, it messes up the h1 and h2 flags */
|
||||
nu = nu->next;
|
||||
if (t->state == TRANS_CANCEL) {
|
||||
while (nu) {
|
||||
BKE_nurb_handles_calc(nu); /* Cant do testhandlesNurb here, it messes up the h1 and h2 flags */
|
||||
nu = nu->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Normal updating */
|
||||
while (nu) {
|
||||
BKE_nurb_test2D(nu);
|
||||
BKE_nurb_handles_calc(nu);
|
||||
nu = nu->next;
|
||||
else {
|
||||
/* Normal updating */
|
||||
while (nu) {
|
||||
BKE_nurb_test2D(nu);
|
||||
BKE_nurb_handles_calc(nu);
|
||||
nu = nu->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (t->obedit_type == OB_LATTICE) {
|
||||
|
||||
@@ -766,11 +766,11 @@ static void recalcData_objects(TransInfo *t)
|
||||
}
|
||||
|
||||
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
|
||||
Lattice *la = tc->obedit->data;
|
||||
DEG_id_tag_update(tc->obedit->data, 0); /* sets recalc flags */
|
||||
if (la->editlatt->latt->flag & LT_OUTSIDE) {
|
||||
outside_lattice(la->editlatt->latt);
|
||||
}
|
||||
Lattice *la = tc->obedit->data;
|
||||
DEG_id_tag_update(tc->obedit->data, 0); /* sets recalc flags */
|
||||
if (la->editlatt->latt->flag & LT_OUTSIDE) {
|
||||
outside_lattice(la->editlatt->latt);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (t->obedit_type == OB_MESH) {
|
||||
@@ -791,10 +791,10 @@ static void recalcData_objects(TransInfo *t)
|
||||
}
|
||||
|
||||
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
|
||||
DEG_id_tag_update(tc->obedit->data, 0); /* sets recalc flags */
|
||||
BMEditMesh *em = BKE_editmesh_from_object(tc->obedit);
|
||||
EDBM_mesh_normals_update(em);
|
||||
BKE_editmesh_tessface_calc(em);
|
||||
DEG_id_tag_update(tc->obedit->data, 0); /* sets recalc flags */
|
||||
BMEditMesh *em = BKE_editmesh_from_object(tc->obedit);
|
||||
EDBM_mesh_normals_update(em);
|
||||
BKE_editmesh_tessface_calc(em);
|
||||
}
|
||||
}
|
||||
else if (t->obedit_type == OB_ARMATURE) { /* no recalc flag, does pose */
|
||||
@@ -804,92 +804,92 @@ static void recalcData_objects(TransInfo *t)
|
||||
}
|
||||
|
||||
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
|
||||
bArmature *arm = tc->obedit->data;
|
||||
ListBase *edbo = arm->edbo;
|
||||
EditBone *ebo, *ebo_parent;
|
||||
TransData *td = tc->data;
|
||||
int i;
|
||||
bArmature *arm = tc->obedit->data;
|
||||
ListBase *edbo = arm->edbo;
|
||||
EditBone *ebo, *ebo_parent;
|
||||
TransData *td = tc->data;
|
||||
int i;
|
||||
|
||||
/* Ensure all bones are correctly adjusted */
|
||||
for (ebo = edbo->first; ebo; ebo = ebo->next) {
|
||||
ebo_parent = (ebo->flag & BONE_CONNECTED) ? ebo->parent : NULL;
|
||||
|
||||
if (ebo_parent) {
|
||||
/* If this bone has a parent tip that has been moved */
|
||||
if (ebo_parent->flag & BONE_TIPSEL) {
|
||||
copy_v3_v3(ebo->head, ebo_parent->tail);
|
||||
if (t->mode == TFM_BONE_ENVELOPE) ebo->rad_head = ebo_parent->rad_tail;
|
||||
}
|
||||
/* If this bone has a parent tip that has NOT been moved */
|
||||
else {
|
||||
copy_v3_v3(ebo_parent->tail, ebo->head);
|
||||
if (t->mode == TFM_BONE_ENVELOPE) ebo_parent->rad_tail = ebo->rad_head;
|
||||
}
|
||||
}
|
||||
|
||||
/* on extrude bones, oldlength==0.0f, so we scale radius of points */
|
||||
ebo->length = len_v3v3(ebo->head, ebo->tail);
|
||||
if (ebo->oldlength == 0.0f) {
|
||||
ebo->rad_head = 0.25f * ebo->length;
|
||||
ebo->rad_tail = 0.10f * ebo->length;
|
||||
ebo->dist = 0.25f * ebo->length;
|
||||
if (ebo->parent) {
|
||||
if (ebo->rad_head > ebo->parent->rad_tail)
|
||||
ebo->rad_head = ebo->parent->rad_tail;
|
||||
}
|
||||
}
|
||||
else if (t->mode != TFM_BONE_ENVELOPE) {
|
||||
/* if bones change length, lets do that for the deform distance as well */
|
||||
ebo->dist *= ebo->length / ebo->oldlength;
|
||||
ebo->rad_head *= ebo->length / ebo->oldlength;
|
||||
ebo->rad_tail *= ebo->length / ebo->oldlength;
|
||||
ebo->oldlength = ebo->length;
|
||||
/* Ensure all bones are correctly adjusted */
|
||||
for (ebo = edbo->first; ebo; ebo = ebo->next) {
|
||||
ebo_parent = (ebo->flag & BONE_CONNECTED) ? ebo->parent : NULL;
|
||||
|
||||
if (ebo_parent) {
|
||||
ebo_parent->rad_tail = ebo->rad_head;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!ELEM(t->mode, TFM_BONE_ROLL, TFM_BONE_ENVELOPE, TFM_BONE_ENVELOPE_DIST, TFM_BONESIZE)) {
|
||||
/* fix roll */
|
||||
for (i = 0; i < tc->data_len; i++, td++) {
|
||||
if (td->extra) {
|
||||
float vec[3], up_axis[3];
|
||||
float qrot[4];
|
||||
float roll;
|
||||
|
||||
ebo = td->extra;
|
||||
|
||||
if (t->state == TRANS_CANCEL) {
|
||||
/* restore roll */
|
||||
ebo->roll = td->ival;
|
||||
/* If this bone has a parent tip that has been moved */
|
||||
if (ebo_parent->flag & BONE_TIPSEL) {
|
||||
copy_v3_v3(ebo->head, ebo_parent->tail);
|
||||
if (t->mode == TFM_BONE_ENVELOPE) ebo->rad_head = ebo_parent->rad_tail;
|
||||
}
|
||||
/* If this bone has a parent tip that has NOT been moved */
|
||||
else {
|
||||
copy_v3_v3(up_axis, td->axismtx[2]);
|
||||
copy_v3_v3(ebo_parent->tail, ebo->head);
|
||||
if (t->mode == TFM_BONE_ENVELOPE) ebo_parent->rad_tail = ebo->rad_head;
|
||||
}
|
||||
}
|
||||
|
||||
sub_v3_v3v3(vec, ebo->tail, ebo->head);
|
||||
normalize_v3(vec);
|
||||
rotation_between_vecs_to_quat(qrot, td->axismtx[1], vec);
|
||||
mul_qt_v3(qrot, up_axis);
|
||||
/* on extrude bones, oldlength==0.0f, so we scale radius of points */
|
||||
ebo->length = len_v3v3(ebo->head, ebo->tail);
|
||||
if (ebo->oldlength == 0.0f) {
|
||||
ebo->rad_head = 0.25f * ebo->length;
|
||||
ebo->rad_tail = 0.10f * ebo->length;
|
||||
ebo->dist = 0.25f * ebo->length;
|
||||
if (ebo->parent) {
|
||||
if (ebo->rad_head > ebo->parent->rad_tail)
|
||||
ebo->rad_head = ebo->parent->rad_tail;
|
||||
}
|
||||
}
|
||||
else if (t->mode != TFM_BONE_ENVELOPE) {
|
||||
/* if bones change length, lets do that for the deform distance as well */
|
||||
ebo->dist *= ebo->length / ebo->oldlength;
|
||||
ebo->rad_head *= ebo->length / ebo->oldlength;
|
||||
ebo->rad_tail *= ebo->length / ebo->oldlength;
|
||||
ebo->oldlength = ebo->length;
|
||||
|
||||
/* roll has a tendency to flip in certain orientations - [#34283], [#33974] */
|
||||
roll = ED_armature_ebone_roll_to_vector(ebo, up_axis, false);
|
||||
ebo->roll = angle_compat_rad(roll, td->ival);
|
||||
if (ebo_parent) {
|
||||
ebo_parent->rad_tail = ebo->rad_head;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (arm->flag & ARM_MIRROR_EDIT) {
|
||||
if (t->state != TRANS_CANCEL) {
|
||||
ED_armature_edit_transform_mirror_update(tc->obedit);
|
||||
if (!ELEM(t->mode, TFM_BONE_ROLL, TFM_BONE_ENVELOPE, TFM_BONE_ENVELOPE_DIST, TFM_BONESIZE)) {
|
||||
/* fix roll */
|
||||
for (i = 0; i < tc->data_len; i++, td++) {
|
||||
if (td->extra) {
|
||||
float vec[3], up_axis[3];
|
||||
float qrot[4];
|
||||
float roll;
|
||||
|
||||
ebo = td->extra;
|
||||
|
||||
if (t->state == TRANS_CANCEL) {
|
||||
/* restore roll */
|
||||
ebo->roll = td->ival;
|
||||
}
|
||||
else {
|
||||
copy_v3_v3(up_axis, td->axismtx[2]);
|
||||
|
||||
sub_v3_v3v3(vec, ebo->tail, ebo->head);
|
||||
normalize_v3(vec);
|
||||
rotation_between_vecs_to_quat(qrot, td->axismtx[1], vec);
|
||||
mul_qt_v3(qrot, up_axis);
|
||||
|
||||
/* roll has a tendency to flip in certain orientations - [#34283], [#33974] */
|
||||
roll = ED_armature_ebone_roll_to_vector(ebo, up_axis, false);
|
||||
ebo->roll = angle_compat_rad(roll, td->ival);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
restoreBones(tc);
|
||||
|
||||
if (arm->flag & ARM_MIRROR_EDIT) {
|
||||
if (t->state != TRANS_CANCEL) {
|
||||
ED_armature_edit_transform_mirror_update(tc->obedit);
|
||||
}
|
||||
else {
|
||||
restoreBones(tc);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (t->state != TRANS_CANCEL) {
|
||||
@@ -905,31 +905,32 @@ static void recalcData_objects(TransInfo *t)
|
||||
}
|
||||
else if (t->flag & T_POSE) {
|
||||
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
|
||||
Object *ob = tc->poseobj;
|
||||
bArmature *arm = ob->data;
|
||||
|
||||
/* if animtimer is running, and the object already has animation data,
|
||||
* check if the auto-record feature means that we should record 'samples'
|
||||
* (i.e. uneditable animation values)
|
||||
*
|
||||
* context is needed for keying set poll() functions.
|
||||
*/
|
||||
// TODO: autokeyframe calls need some setting to specify to add samples (FPoints) instead of keyframes?
|
||||
if ((t->animtimer) && (t->context) && IS_AUTOKEY_ON(t->scene)) {
|
||||
int targetless_ik = (t->flag & T_AUTOIK); // XXX this currently doesn't work, since flags aren't set yet!
|
||||
|
||||
animrecord_check_state(t->scene, &ob->id, t->animtimer);
|
||||
autokeyframe_pose_cb_func(t->context, t->scene, (View3D *)t->view, ob, t->mode, targetless_ik);
|
||||
}
|
||||
|
||||
/* old optimize trick... this enforces to bypass the depgraph */
|
||||
if (!(arm->flag & ARM_DELAYDEFORM)) {
|
||||
DEG_id_tag_update(&ob->id, OB_RECALC_DATA); /* sets recalc flags */
|
||||
/* transformation of pose may affect IK tree, make sure it is rebuilt */
|
||||
BIK_clear_data(ob->pose);
|
||||
}
|
||||
else
|
||||
BKE_pose_where_is(&t->eval_ctx, t->scene, ob);
|
||||
Object *ob = tc->poseobj;
|
||||
bArmature *arm = ob->data;
|
||||
|
||||
/* if animtimer is running, and the object already has animation data,
|
||||
* check if the auto-record feature means that we should record 'samples'
|
||||
* (i.e. uneditable animation values)
|
||||
*
|
||||
* context is needed for keying set poll() functions.
|
||||
*/
|
||||
// TODO: autokeyframe calls need some setting to specify to add samples (FPoints) instead of keyframes?
|
||||
if ((t->animtimer) && (t->context) && IS_AUTOKEY_ON(t->scene)) {
|
||||
int targetless_ik = (t->flag & T_AUTOIK); // XXX this currently doesn't work, since flags aren't set yet!
|
||||
|
||||
animrecord_check_state(t->scene, &ob->id, t->animtimer);
|
||||
autokeyframe_pose_cb_func(t->context, t->scene, (View3D *)t->view, ob, t->mode, targetless_ik);
|
||||
}
|
||||
|
||||
/* old optimize trick... this enforces to bypass the depgraph */
|
||||
if (!(arm->flag & ARM_DELAYDEFORM)) {
|
||||
DEG_id_tag_update(&ob->id, OB_RECALC_DATA); /* sets recalc flags */
|
||||
/* transformation of pose may affect IK tree, make sure it is rebuilt */
|
||||
BIK_clear_data(ob->pose);
|
||||
}
|
||||
else {
|
||||
BKE_pose_where_is(&t->eval_ctx, t->scene, ob);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (base && (base->object->mode & OB_MODE_PARTICLE_EDIT) &&
|
||||
@@ -948,35 +949,35 @@ static void recalcData_objects(TransInfo *t)
|
||||
}
|
||||
|
||||
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
|
||||
TransData *td = tc->data;
|
||||
TransData *td = tc->data;
|
||||
|
||||
for (i = 0; i < tc->data_len; i++, td++) {
|
||||
Object *ob = td->ob;
|
||||
|
||||
if (td->flag & TD_NOACTION)
|
||||
break;
|
||||
|
||||
if (td->flag & TD_SKIP)
|
||||
continue;
|
||||
|
||||
/* if animtimer is running, and the object already has animation data,
|
||||
* check if the auto-record feature means that we should record 'samples'
|
||||
* (i.e. uneditable animation values)
|
||||
*/
|
||||
// TODO: autokeyframe calls need some setting to specify to add samples (FPoints) instead of keyframes?
|
||||
if ((t->animtimer) && IS_AUTOKEY_ON(t->scene)) {
|
||||
animrecord_check_state(t->scene, &ob->id, t->animtimer);
|
||||
autokeyframe_ob_cb_func(t->context, t->scene, t->view_layer, (View3D *)t->view, ob, t->mode);
|
||||
for (i = 0; i < tc->data_len; i++, td++) {
|
||||
Object *ob = td->ob;
|
||||
|
||||
if (td->flag & TD_NOACTION)
|
||||
break;
|
||||
|
||||
if (td->flag & TD_SKIP)
|
||||
continue;
|
||||
|
||||
/* if animtimer is running, and the object already has animation data,
|
||||
* check if the auto-record feature means that we should record 'samples'
|
||||
* (i.e. uneditable animation values)
|
||||
*/
|
||||
// TODO: autokeyframe calls need some setting to specify to add samples (FPoints) instead of keyframes?
|
||||
if ((t->animtimer) && IS_AUTOKEY_ON(t->scene)) {
|
||||
animrecord_check_state(t->scene, &ob->id, t->animtimer);
|
||||
autokeyframe_ob_cb_func(t->context, t->scene, t->view_layer, (View3D *)t->view, ob, t->mode);
|
||||
}
|
||||
|
||||
/* sets recalc flags fully, instead of flushing existing ones
|
||||
* otherwise proxies don't function correctly
|
||||
*/
|
||||
DEG_id_tag_update(&ob->id, OB_RECALC_OB);
|
||||
|
||||
if (t->flag & T_TEXTURE)
|
||||
DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
|
||||
}
|
||||
|
||||
/* sets recalc flags fully, instead of flushing existing ones
|
||||
* otherwise proxies don't function correctly
|
||||
*/
|
||||
DEG_id_tag_update(&ob->id, OB_RECALC_OB);
|
||||
|
||||
if (t->flag & T_TEXTURE)
|
||||
DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1117,16 +1118,16 @@ void drawLine(TransInfo *t, const float center[3], const float dir[3], char axis
|
||||
void resetTransModal(TransInfo *t)
|
||||
{
|
||||
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
|
||||
if (t->mode == TFM_EDGE_SLIDE) {
|
||||
freeEdgeSlideVerts(t, tc, &tc->custom.mode);
|
||||
}
|
||||
else if (t->mode == TFM_VERT_SLIDE) {
|
||||
freeVertSlideVerts(t, tc, &tc->custom.mode);
|
||||
}
|
||||
else {
|
||||
/* no need to keep looping... */
|
||||
break;
|
||||
}
|
||||
if (t->mode == TFM_EDGE_SLIDE) {
|
||||
freeEdgeSlideVerts(t, tc, &tc->custom.mode);
|
||||
}
|
||||
else if (t->mode == TFM_VERT_SLIDE) {
|
||||
freeVertSlideVerts(t, tc, &tc->custom.mode);
|
||||
}
|
||||
else {
|
||||
/* no need to keep looping... */
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1696,25 +1697,25 @@ void restoreTransObjects(TransInfo *t)
|
||||
{
|
||||
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
|
||||
|
||||
TransData *td;
|
||||
TransData2D *td2d;
|
||||
TransData *td;
|
||||
TransData2D *td2d;
|
||||
|
||||
for (td = tc->data; td < tc->data + tc->data_len; td++) {
|
||||
restoreElement(td);
|
||||
}
|
||||
|
||||
for (td2d = tc->data_2d; tc->data_2d && td2d < tc->data_2d + tc->data_len; td2d++) {
|
||||
if (td2d->h1) {
|
||||
td2d->h1[0] = td2d->ih1[0];
|
||||
td2d->h1[1] = td2d->ih1[1];
|
||||
for (td = tc->data; td < tc->data + tc->data_len; td++) {
|
||||
restoreElement(td);
|
||||
}
|
||||
if (td2d->h2) {
|
||||
td2d->h2[0] = td2d->ih2[0];
|
||||
td2d->h2[1] = td2d->ih2[1];
|
||||
}
|
||||
}
|
||||
|
||||
unit_m3(t->mat);
|
||||
for (td2d = tc->data_2d; tc->data_2d && td2d < tc->data_2d + tc->data_len; td2d++) {
|
||||
if (td2d->h1) {
|
||||
td2d->h1[0] = td2d->ih1[0];
|
||||
td2d->h1[1] = td2d->ih1[1];
|
||||
}
|
||||
if (td2d->h2) {
|
||||
td2d->h2[0] = td2d->ih2[0];
|
||||
td2d->h2[1] = td2d->ih2[1];
|
||||
}
|
||||
}
|
||||
|
||||
unit_m3(t->mat);
|
||||
|
||||
}
|
||||
|
||||
@@ -1831,24 +1832,24 @@ void calculateCenterMedian(TransInfo *t, float r_center[3])
|
||||
int total = 0;
|
||||
|
||||
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
|
||||
Object *ob_xform = tc->obedit ? tc->obedit : tc->poseobj;
|
||||
int i;
|
||||
for (i = 0; i < tc->data_len; i++) {
|
||||
if (tc->data[i].flag & TD_SELECTED) {
|
||||
if (!(tc->data[i].flag & TD_NOCENTER)) {
|
||||
if (ob_xform) {
|
||||
float v[3];
|
||||
mul_v3_m4v3(v, ob_xform->obmat, tc->data[i].center);
|
||||
add_v3_v3(partial, v);
|
||||
Object *ob_xform = tc->obedit ? tc->obedit : tc->poseobj;
|
||||
int i;
|
||||
for (i = 0; i < tc->data_len; i++) {
|
||||
if (tc->data[i].flag & TD_SELECTED) {
|
||||
if (!(tc->data[i].flag & TD_NOCENTER)) {
|
||||
if (ob_xform) {
|
||||
float v[3];
|
||||
mul_v3_m4v3(v, ob_xform->obmat, tc->data[i].center);
|
||||
add_v3_v3(partial, v);
|
||||
}
|
||||
else {
|
||||
add_v3_v3(partial, tc->data[i].center);
|
||||
}
|
||||
total++;
|
||||
}
|
||||
else {
|
||||
add_v3_v3(partial, tc->data[i].center);
|
||||
}
|
||||
total++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (total) {
|
||||
mul_v3_fl(partial, 1.0f / (float)total);
|
||||
}
|
||||
@@ -1862,28 +1863,28 @@ void calculateCenterBound(TransInfo *t, float r_center[3])
|
||||
int i;
|
||||
bool is_first = true;
|
||||
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
|
||||
Object *ob_xform = tc->obedit ? tc->obedit : tc->poseobj;
|
||||
for (i = 0; i < tc->data_len; i++) {
|
||||
if (is_first == false) {
|
||||
if (tc->data[i].flag & TD_SELECTED) {
|
||||
if (!(tc->data[i].flag & TD_NOCENTER)) {
|
||||
if (ob_xform) {
|
||||
float v[3];
|
||||
mul_v3_m4v3(v, ob_xform->obmat, tc->data[i].center);
|
||||
minmax_v3v3_v3(min, max, v);
|
||||
}
|
||||
else {
|
||||
minmax_v3v3_v3(min, max, tc->data[i].center);
|
||||
Object *ob_xform = tc->obedit ? tc->obedit : tc->poseobj;
|
||||
for (i = 0; i < tc->data_len; i++) {
|
||||
if (is_first == false) {
|
||||
if (tc->data[i].flag & TD_SELECTED) {
|
||||
if (!(tc->data[i].flag & TD_NOCENTER)) {
|
||||
if (ob_xform) {
|
||||
float v[3];
|
||||
mul_v3_m4v3(v, ob_xform->obmat, tc->data[i].center);
|
||||
minmax_v3v3_v3(min, max, v);
|
||||
}
|
||||
else {
|
||||
minmax_v3v3_v3(min, max, tc->data[i].center);
|
||||
}
|
||||
}
|
||||
}
|
||||
is_first = false;
|
||||
}
|
||||
else {
|
||||
copy_v3_v3(max, tc->data[i].center);
|
||||
copy_v3_v3(min, tc->data[i].center);
|
||||
}
|
||||
is_first = false;
|
||||
}
|
||||
else {
|
||||
copy_v3_v3(max, tc->data[i].center);
|
||||
copy_v3_v3(min, tc->data[i].center);
|
||||
}
|
||||
}
|
||||
}
|
||||
mid_v3_v3v3(r_center, min, max);
|
||||
}
|
||||
@@ -2058,77 +2059,77 @@ void calculatePropRatio(TransInfo *t)
|
||||
if (t->flag & T_PROP_EDIT) {
|
||||
const char *pet_id = NULL;
|
||||
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
|
||||
TransData *td = tc->data;
|
||||
for (i = 0; i < tc->data_len; i++, td++) {
|
||||
if (td->flag & TD_SELECTED) {
|
||||
td->factor = 1.0f;
|
||||
}
|
||||
else if (t->flag & T_MIRROR && td->loc[0] * t->mirror < -0.00001f) {
|
||||
td->flag |= TD_SKIP;
|
||||
td->factor = 0.0f;
|
||||
restoreElement(td);
|
||||
}
|
||||
else if ((connected && (td->flag & TD_NOTCONNECTED || td->dist > t->prop_size)) ||
|
||||
(connected == 0 && td->rdist > t->prop_size))
|
||||
{
|
||||
/*
|
||||
* The elements are sorted according to their dist member in the array,
|
||||
* that means we can stop when it finds one element outside of the propsize.
|
||||
* do not set 'td->flag |= TD_NOACTION', the prop circle is being changed.
|
||||
*/
|
||||
|
||||
td->factor = 0.0f;
|
||||
restoreElement(td);
|
||||
}
|
||||
else {
|
||||
/* Use rdist for falloff calculations, it is the real distance */
|
||||
td->flag &= ~TD_NOACTION;
|
||||
|
||||
if (connected)
|
||||
dist = (t->prop_size - td->dist) / t->prop_size;
|
||||
else
|
||||
dist = (t->prop_size - td->rdist) / t->prop_size;
|
||||
TransData *td = tc->data;
|
||||
for (i = 0; i < tc->data_len; i++, td++) {
|
||||
if (td->flag & TD_SELECTED) {
|
||||
td->factor = 1.0f;
|
||||
}
|
||||
else if (t->flag & T_MIRROR && td->loc[0] * t->mirror < -0.00001f) {
|
||||
td->flag |= TD_SKIP;
|
||||
td->factor = 0.0f;
|
||||
restoreElement(td);
|
||||
}
|
||||
else if ((connected && (td->flag & TD_NOTCONNECTED || td->dist > t->prop_size)) ||
|
||||
(connected == 0 && td->rdist > t->prop_size))
|
||||
{
|
||||
/*
|
||||
* The elements are sorted according to their dist member in the array,
|
||||
* that means we can stop when it finds one element outside of the propsize.
|
||||
* do not set 'td->flag |= TD_NOACTION', the prop circle is being changed.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Clamp to positive numbers.
|
||||
* Certain corner cases with connectivity and individual centers
|
||||
* can give values of rdist larger than propsize.
|
||||
*/
|
||||
if (dist < 0.0f)
|
||||
dist = 0.0f;
|
||||
|
||||
switch (t->prop_mode) {
|
||||
case PROP_SHARP:
|
||||
td->factor = dist * dist;
|
||||
break;
|
||||
case PROP_SMOOTH:
|
||||
td->factor = 3.0f * dist * dist - 2.0f * dist * dist * dist;
|
||||
break;
|
||||
case PROP_ROOT:
|
||||
td->factor = sqrtf(dist);
|
||||
break;
|
||||
case PROP_LIN:
|
||||
td->factor = dist;
|
||||
break;
|
||||
case PROP_CONST:
|
||||
td->factor = 1.0f;
|
||||
break;
|
||||
case PROP_SPHERE:
|
||||
td->factor = sqrtf(2 * dist - dist * dist);
|
||||
break;
|
||||
case PROP_RANDOM:
|
||||
td->factor = BLI_frand() * dist;
|
||||
break;
|
||||
case PROP_INVSQUARE:
|
||||
td->factor = dist * (2.0f - dist);
|
||||
break;
|
||||
default:
|
||||
td->factor = 1;
|
||||
break;
|
||||
td->factor = 0.0f;
|
||||
restoreElement(td);
|
||||
}
|
||||
else {
|
||||
/* Use rdist for falloff calculations, it is the real distance */
|
||||
td->flag &= ~TD_NOACTION;
|
||||
|
||||
if (connected)
|
||||
dist = (t->prop_size - td->dist) / t->prop_size;
|
||||
else
|
||||
dist = (t->prop_size - td->rdist) / t->prop_size;
|
||||
|
||||
/*
|
||||
* Clamp to positive numbers.
|
||||
* Certain corner cases with connectivity and individual centers
|
||||
* can give values of rdist larger than propsize.
|
||||
*/
|
||||
if (dist < 0.0f)
|
||||
dist = 0.0f;
|
||||
|
||||
switch (t->prop_mode) {
|
||||
case PROP_SHARP:
|
||||
td->factor = dist * dist;
|
||||
break;
|
||||
case PROP_SMOOTH:
|
||||
td->factor = 3.0f * dist * dist - 2.0f * dist * dist * dist;
|
||||
break;
|
||||
case PROP_ROOT:
|
||||
td->factor = sqrtf(dist);
|
||||
break;
|
||||
case PROP_LIN:
|
||||
td->factor = dist;
|
||||
break;
|
||||
case PROP_CONST:
|
||||
td->factor = 1.0f;
|
||||
break;
|
||||
case PROP_SPHERE:
|
||||
td->factor = sqrtf(2 * dist - dist * dist);
|
||||
break;
|
||||
case PROP_RANDOM:
|
||||
td->factor = BLI_frand() * dist;
|
||||
break;
|
||||
case PROP_INVSQUARE:
|
||||
td->factor = dist * (2.0f - dist);
|
||||
break;
|
||||
default:
|
||||
td->factor = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch (t->prop_mode) {
|
||||
case PROP_SHARP:
|
||||
|
||||
@@ -276,72 +276,74 @@ void applyProject(TransInfo *t)
|
||||
int i;
|
||||
|
||||
FOREACH_TRANS_DATA_CONTAINER(t, tc) {
|
||||
TransData *td = tc->data;
|
||||
TransData *td = tc->data;
|
||||
|
||||
float imat[4][4];
|
||||
if (t->flag & (T_EDIT | T_POSE)) {
|
||||
Object *ob = tc->obedit ? tc->obedit : tc->poseobj;
|
||||
invert_m4_m4(imat, ob->obmat);
|
||||
}
|
||||
|
||||
for (i = 0; i < tc->data_len; i++, td++) {
|
||||
float iloc[3], loc[3], no[3];
|
||||
float mval_fl[2];
|
||||
float dist_px = TRANSFORM_DIST_MAX_PX;
|
||||
|
||||
if (td->flag & TD_NOACTION)
|
||||
break;
|
||||
|
||||
if (td->flag & TD_SKIP)
|
||||
continue;
|
||||
|
||||
if ((t->flag & T_PROP_EDIT) && (td->factor == 0.0f))
|
||||
continue;
|
||||
|
||||
copy_v3_v3(iloc, td->loc);
|
||||
float imat[4][4];
|
||||
if (t->flag & (T_EDIT | T_POSE)) {
|
||||
Object *ob = tc->obedit ? tc->obedit : tc->poseobj;
|
||||
mul_m4_v3(ob->obmat, iloc);
|
||||
invert_m4_m4(imat, ob->obmat);
|
||||
}
|
||||
else if (t->flag & T_OBJECT) {
|
||||
BKE_object_eval_transform_all(G.main->eval_ctx, t->scene, td->ob);
|
||||
copy_v3_v3(iloc, td->ob->obmat[3]);
|
||||
}
|
||||
|
||||
if (ED_view3d_project_float_global(t->ar, iloc, mval_fl, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) {
|
||||
if (snapObjectsTransform(
|
||||
t, mval_fl, &dist_px,
|
||||
loc, no))
|
||||
{
|
||||
// if (t->flag & (T_EDIT|T_POSE)) {
|
||||
// mul_m4_v3(imat, loc);
|
||||
// }
|
||||
|
||||
sub_v3_v3v3(tvec, loc, iloc);
|
||||
for (i = 0; i < tc->data_len; i++, td++) {
|
||||
float iloc[3], loc[3], no[3];
|
||||
float mval_fl[2];
|
||||
float dist_px = TRANSFORM_DIST_MAX_PX;
|
||||
|
||||
mul_m3_v3(td->smtx, tvec);
|
||||
if (td->flag & TD_NOACTION)
|
||||
break;
|
||||
|
||||
add_v3_v3(td->loc, tvec);
|
||||
if (td->flag & TD_SKIP)
|
||||
continue;
|
||||
|
||||
if (t->tsnap.align && (t->flag & T_OBJECT)) {
|
||||
/* handle alignment as well */
|
||||
const float *original_normal;
|
||||
float mat[3][3];
|
||||
if ((t->flag & T_PROP_EDIT) && (td->factor == 0.0f))
|
||||
continue;
|
||||
|
||||
/* In pose mode, we want to align normals with Y axis of bones... */
|
||||
original_normal = td->axismtx[2];
|
||||
copy_v3_v3(iloc, td->loc);
|
||||
if (t->flag & (T_EDIT | T_POSE)) {
|
||||
Object *ob = tc->obedit ? tc->obedit : tc->poseobj;
|
||||
mul_m4_v3(ob->obmat, iloc);
|
||||
}
|
||||
else if (t->flag & T_OBJECT) {
|
||||
BKE_object_eval_transform_all(G.main->eval_ctx, t->scene, td->ob);
|
||||
copy_v3_v3(iloc, td->ob->obmat[3]);
|
||||
}
|
||||
|
||||
rotation_between_vecs_to_mat3(mat, original_normal, no);
|
||||
if (ED_view3d_project_float_global(t->ar, iloc, mval_fl, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) {
|
||||
if (snapObjectsTransform(
|
||||
t, mval_fl, &dist_px,
|
||||
loc, no))
|
||||
{
|
||||
#if 0
|
||||
if (t->flag & (T_EDIT | T_POSE)) {
|
||||
mul_m4_v3(imat, loc);
|
||||
}
|
||||
#endif
|
||||
|
||||
transform_data_ext_rotate(td, mat, true);
|
||||
sub_v3_v3v3(tvec, loc, iloc);
|
||||
|
||||
/* TODO support constraints for rotation too? see ElementRotation */
|
||||
mul_m3_v3(td->smtx, tvec);
|
||||
|
||||
add_v3_v3(td->loc, tvec);
|
||||
|
||||
if (t->tsnap.align && (t->flag & T_OBJECT)) {
|
||||
/* handle alignment as well */
|
||||
const float *original_normal;
|
||||
float mat[3][3];
|
||||
|
||||
/* In pose mode, we want to align normals with Y axis of bones... */
|
||||
original_normal = td->axismtx[2];
|
||||
|
||||
rotation_between_vecs_to_mat3(mat, original_normal, no);
|
||||
|
||||
transform_data_ext_rotate(td, mat, true);
|
||||
|
||||
/* TODO support constraints for rotation too? see ElementRotation */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//XXX constraintTransLim(t, td);
|
||||
}
|
||||
|
||||
//XXX constraintTransLim(t, td);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -371,45 +373,45 @@ void applyGridAbsolute(TransInfo *t)
|
||||
return;
|
||||
|
||||
FOREACH_TRANS_DATA_CONTAINER(t, tc) {
|
||||
TransData *td;
|
||||
TransData *td;
|
||||
|
||||
if (t->flag & (T_EDIT | T_POSE)) {
|
||||
Object *ob = tc->obedit ? tc->obedit : tc->poseobj;
|
||||
obmat = ob->obmat;
|
||||
use_obmat = true;
|
||||
}
|
||||
|
||||
for (i = 0, td = tc->data; i < tc->data_len; i++, td++) {
|
||||
float iloc[3], loc[3], tvec[3];
|
||||
|
||||
if (td->flag & TD_NOACTION)
|
||||
break;
|
||||
|
||||
if (td->flag & TD_SKIP)
|
||||
continue;
|
||||
|
||||
if ((t->flag & T_PROP_EDIT) && (td->factor == 0.0f))
|
||||
continue;
|
||||
|
||||
copy_v3_v3(iloc, td->loc);
|
||||
if (use_obmat) {
|
||||
mul_m4_v3(obmat, iloc);
|
||||
if (t->flag & (T_EDIT | T_POSE)) {
|
||||
Object *ob = tc->obedit ? tc->obedit : tc->poseobj;
|
||||
obmat = ob->obmat;
|
||||
use_obmat = true;
|
||||
}
|
||||
else if (t->flag & T_OBJECT) {
|
||||
BKE_object_eval_transform_all(G.main->eval_ctx, t->scene, td->ob);
|
||||
copy_v3_v3(iloc, td->ob->obmat[3]);
|
||||
}
|
||||
|
||||
mul_v3_v3fl(loc, iloc, 1.0f / grid_size);
|
||||
loc[0] = roundf(loc[0]);
|
||||
loc[1] = roundf(loc[1]);
|
||||
loc[2] = roundf(loc[2]);
|
||||
mul_v3_fl(loc, grid_size);
|
||||
|
||||
sub_v3_v3v3(tvec, loc, iloc);
|
||||
mul_m3_v3(td->smtx, tvec);
|
||||
add_v3_v3(td->loc, tvec);
|
||||
}
|
||||
for (i = 0, td = tc->data; i < tc->data_len; i++, td++) {
|
||||
float iloc[3], loc[3], tvec[3];
|
||||
|
||||
if (td->flag & TD_NOACTION)
|
||||
break;
|
||||
|
||||
if (td->flag & TD_SKIP)
|
||||
continue;
|
||||
|
||||
if ((t->flag & T_PROP_EDIT) && (td->factor == 0.0f))
|
||||
continue;
|
||||
|
||||
copy_v3_v3(iloc, td->loc);
|
||||
if (use_obmat) {
|
||||
mul_m4_v3(obmat, iloc);
|
||||
}
|
||||
else if (t->flag & T_OBJECT) {
|
||||
BKE_object_eval_transform_all(G.main->eval_ctx, t->scene, td->ob);
|
||||
copy_v3_v3(iloc, td->ob->obmat[3]);
|
||||
}
|
||||
|
||||
mul_v3_v3fl(loc, iloc, 1.0f / grid_size);
|
||||
loc[0] = roundf(loc[0]);
|
||||
loc[1] = roundf(loc[1]);
|
||||
loc[2] = roundf(loc[2]);
|
||||
mul_v3_fl(loc, grid_size);
|
||||
|
||||
sub_v3_v3v3(tvec, loc, iloc);
|
||||
mul_m3_v3(td->smtx, tvec);
|
||||
add_v3_v3(td->loc, tvec);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1130,21 +1132,39 @@ static void TargetSnapClosest(TransInfo *t)
|
||||
if (t->flag & T_OBJECT) {
|
||||
int i;
|
||||
FOREACH_TRANS_DATA_CONTAINER(t, tc) {
|
||||
TransData *td = tc->data;
|
||||
for (td = tc->data, i = 0; i < tc->data_len && td->flag & TD_SELECTED; i++, td++) {
|
||||
struct BoundBox *bb = BKE_object_boundbox_get(td->ob);
|
||||
|
||||
/* use boundbox if possible */
|
||||
if (bb) {
|
||||
int j;
|
||||
|
||||
for (j = 0; j < 8; j++) {
|
||||
TransData *td = tc->data;
|
||||
for (td = tc->data, i = 0; i < tc->data_len && td->flag & TD_SELECTED; i++, td++) {
|
||||
struct BoundBox *bb = BKE_object_boundbox_get(td->ob);
|
||||
|
||||
/* use boundbox if possible */
|
||||
if (bb) {
|
||||
int j;
|
||||
|
||||
for (j = 0; j < 8; j++) {
|
||||
float loc[3];
|
||||
float dist;
|
||||
|
||||
copy_v3_v3(loc, bb->vec[j]);
|
||||
mul_m4_v3(td->ext->obmat, loc);
|
||||
|
||||
dist = t->tsnap.distance(t, loc, t->tsnap.snapPoint);
|
||||
|
||||
if ((dist != TRANSFORM_DIST_INVALID) &&
|
||||
(closest == NULL || fabsf(dist) < fabsf(dist_closest)))
|
||||
{
|
||||
copy_v3_v3(t->tsnap.snapTarget, loc);
|
||||
closest = td;
|
||||
dist_closest = dist;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* use element center otherwise */
|
||||
else {
|
||||
float loc[3];
|
||||
float dist;
|
||||
|
||||
copy_v3_v3(loc, bb->vec[j]);
|
||||
mul_m4_v3(td->ext->obmat, loc);
|
||||
|
||||
|
||||
copy_v3_v3(loc, td->center);
|
||||
|
||||
dist = t->tsnap.distance(t, loc, t->tsnap.snapPoint);
|
||||
|
||||
if ((dist != TRANSFORM_DIST_INVALID) &&
|
||||
@@ -1152,17 +1172,26 @@ static void TargetSnapClosest(TransInfo *t)
|
||||
{
|
||||
copy_v3_v3(t->tsnap.snapTarget, loc);
|
||||
closest = td;
|
||||
dist_closest = dist;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* use element center otherwise */
|
||||
else {
|
||||
}
|
||||
}
|
||||
else {
|
||||
FOREACH_TRANS_DATA_CONTAINER(t, tc) {
|
||||
TransData *td = tc->data;
|
||||
int i;
|
||||
for (i = 0; i < tc->data_len && td->flag & TD_SELECTED; i++, td++) {
|
||||
float loc[3];
|
||||
float dist;
|
||||
|
||||
|
||||
copy_v3_v3(loc, td->center);
|
||||
|
||||
|
||||
if (t->flag & (T_EDIT | T_POSE)) {
|
||||
Object *ob = tc->obedit ? tc->obedit : tc->poseobj;
|
||||
mul_m4_v3(ob->obmat, loc);
|
||||
}
|
||||
|
||||
dist = t->tsnap.distance(t, loc, t->tsnap.snapPoint);
|
||||
|
||||
if ((dist != TRANSFORM_DIST_INVALID) &&
|
||||
@@ -1170,37 +1199,10 @@ static void TargetSnapClosest(TransInfo *t)
|
||||
{
|
||||
copy_v3_v3(t->tsnap.snapTarget, loc);
|
||||
closest = td;
|
||||
dist_closest = dist;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
FOREACH_TRANS_DATA_CONTAINER(t, tc) {
|
||||
TransData *td = tc->data;
|
||||
int i;
|
||||
for (i = 0; i < tc->data_len && td->flag & TD_SELECTED; i++, td++) {
|
||||
float loc[3];
|
||||
float dist;
|
||||
|
||||
copy_v3_v3(loc, td->center);
|
||||
|
||||
if (t->flag & (T_EDIT | T_POSE)) {
|
||||
Object *ob = tc->obedit ? tc->obedit : tc->poseobj;
|
||||
mul_m4_v3(ob->obmat, loc);
|
||||
}
|
||||
|
||||
dist = t->tsnap.distance(t, loc, t->tsnap.snapPoint);
|
||||
|
||||
if ((dist != TRANSFORM_DIST_INVALID) &&
|
||||
(closest == NULL || fabsf(dist) < fabsf(dist_closest)))
|
||||
{
|
||||
copy_v3_v3(t->tsnap.snapTarget, loc);
|
||||
closest = td;
|
||||
dist_closest = dist;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TargetSnapOffset(t, closest);
|
||||
|
||||
@@ -1203,170 +1203,127 @@ static void uv_select_linked_multi(
|
||||
{
|
||||
/* loop over objects, or just use hit_final->ob */
|
||||
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
|
||||
if (hit_final && ob_index != 0) {
|
||||
break;
|
||||
}
|
||||
Object *obedit = hit_final ? hit_final->ob : objects[ob_index];
|
||||
if (hit_final && ob_index != 0) {
|
||||
break;
|
||||
}
|
||||
Object *obedit = hit_final ? hit_final->ob : objects[ob_index];
|
||||
|
||||
BMFace *efa;
|
||||
BMLoop *l;
|
||||
BMIter iter, liter;
|
||||
MLoopUV *luv;
|
||||
UvVertMap *vmap;
|
||||
UvMapVert *vlist, *iterv, *startv;
|
||||
int i, stacksize = 0, *stack;
|
||||
unsigned int a;
|
||||
char *flag;
|
||||
BMFace *efa;
|
||||
BMLoop *l;
|
||||
BMIter iter, liter;
|
||||
MLoopUV *luv;
|
||||
UvVertMap *vmap;
|
||||
UvMapVert *vlist, *iterv, *startv;
|
||||
int i, stacksize = 0, *stack;
|
||||
unsigned int a;
|
||||
char *flag;
|
||||
|
||||
BMEditMesh *em = BKE_editmesh_from_object(obedit);
|
||||
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
|
||||
BMEditMesh *em = BKE_editmesh_from_object(obedit);
|
||||
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
|
||||
|
||||
BM_mesh_elem_table_ensure(em->bm, BM_FACE); /* we can use this too */
|
||||
BM_mesh_elem_table_ensure(em->bm, BM_FACE); /* we can use this too */
|
||||
|
||||
/* Note, we had 'use winding' so we don't consider overlapping islands as connected, see T44320
|
||||
* this made *every* projection split the island into front/back islands.
|
||||
* Keep 'use_winding' to false, see: T50970.
|
||||
*
|
||||
* Better solve this by having a delimit option for select-linked operator,
|
||||
* keeping island-select working as is. */
|
||||
vmap = BM_uv_vert_map_create(em->bm, limit, !select_faces, false);
|
||||
/* Note, we had 'use winding' so we don't consider overlapping islands as connected, see T44320
|
||||
* this made *every* projection split the island into front/back islands.
|
||||
* Keep 'use_winding' to false, see: T50970.
|
||||
*
|
||||
* Better solve this by having a delimit option for select-linked operator,
|
||||
* keeping island-select working as is. */
|
||||
vmap = BM_uv_vert_map_create(em->bm, limit, !select_faces, false);
|
||||
|
||||
if (vmap == NULL)
|
||||
return;
|
||||
if (vmap == NULL)
|
||||
return;
|
||||
|
||||
stack = MEM_mallocN(sizeof(*stack) * (em->bm->totface + 1), "UvLinkStack");
|
||||
flag = MEM_callocN(sizeof(*flag) * em->bm->totface, "UvLinkFlag");
|
||||
stack = MEM_mallocN(sizeof(*stack) * (em->bm->totface + 1), "UvLinkStack");
|
||||
flag = MEM_callocN(sizeof(*flag) * em->bm->totface, "UvLinkFlag");
|
||||
|
||||
if (hit_final == NULL) {
|
||||
/* Use existing selection */
|
||||
BM_ITER_MESH_INDEX (efa, &iter, em->bm, BM_FACES_OF_MESH, a) {
|
||||
if (uvedit_face_visible_test(scene, obedit, ima, efa)) {
|
||||
if (select_faces) {
|
||||
if (BM_elem_flag_test(efa, BM_ELEM_SELECT)) {
|
||||
stack[stacksize] = a;
|
||||
stacksize++;
|
||||
flag[a] = 1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
|
||||
luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
|
||||
|
||||
if (luv->flag & MLOOPUV_VERTSEL) {
|
||||
if (hit_final == NULL) {
|
||||
/* Use existing selection */
|
||||
BM_ITER_MESH_INDEX (efa, &iter, em->bm, BM_FACES_OF_MESH, a) {
|
||||
if (uvedit_face_visible_test(scene, obedit, ima, efa)) {
|
||||
if (select_faces) {
|
||||
if (BM_elem_flag_test(efa, BM_ELEM_SELECT)) {
|
||||
stack[stacksize] = a;
|
||||
stacksize++;
|
||||
flag[a] = 1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
|
||||
luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
|
||||
|
||||
break;
|
||||
if (luv->flag & MLOOPUV_VERTSEL) {
|
||||
stack[stacksize] = a;
|
||||
stacksize++;
|
||||
flag[a] = 1;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
BM_ITER_MESH_INDEX (efa, &iter, em->bm, BM_FACES_OF_MESH, a) {
|
||||
if (efa == hit_final->efa) {
|
||||
stack[stacksize] = a;
|
||||
stacksize++;
|
||||
flag[a] = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while (stacksize > 0) {
|
||||
|
||||
stacksize--;
|
||||
a = stack[stacksize];
|
||||
|
||||
efa = BM_face_at_index(em->bm, a);
|
||||
|
||||
BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) {
|
||||
|
||||
/* make_uv_vert_map_EM sets verts tmp.l to the indices */
|
||||
vlist = BM_uv_vert_map_at_index(vmap, BM_elem_index_get(l->v));
|
||||
|
||||
startv = vlist;
|
||||
|
||||
for (iterv = vlist; iterv; iterv = iterv->next) {
|
||||
if (iterv->separate)
|
||||
startv = iterv;
|
||||
if (iterv->f == a)
|
||||
break;
|
||||
}
|
||||
|
||||
for (iterv = startv; iterv; iterv = iterv->next) {
|
||||
if ((startv != iterv) && (iterv->separate))
|
||||
break;
|
||||
else if (!flag[iterv->f]) {
|
||||
flag[iterv->f] = 1;
|
||||
stack[stacksize] = iterv->f;
|
||||
else {
|
||||
BM_ITER_MESH_INDEX (efa, &iter, em->bm, BM_FACES_OF_MESH, a) {
|
||||
if (efa == hit_final->efa) {
|
||||
stack[stacksize] = a;
|
||||
stacksize++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!extend) {
|
||||
BM_ITER_MESH_INDEX (efa, &iter, em->bm, BM_FACES_OF_MESH, a) {
|
||||
if (select_faces) {
|
||||
if (flag[a])
|
||||
BM_face_select_set(em->bm, efa, true);
|
||||
else
|
||||
BM_face_select_set(em->bm, efa, false);
|
||||
}
|
||||
else {
|
||||
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
|
||||
luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
|
||||
|
||||
if (flag[a])
|
||||
luv->flag |= MLOOPUV_VERTSEL;
|
||||
else
|
||||
luv->flag &= ~MLOOPUV_VERTSEL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
BM_ITER_MESH_INDEX (efa, &iter, em->bm, BM_FACES_OF_MESH, a) {
|
||||
if (!flag[a]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (select_faces) {
|
||||
if (BM_elem_flag_test(efa, BM_ELEM_SELECT) && !BM_elem_flag_test(efa, BM_ELEM_HIDDEN))
|
||||
flag[a] = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
|
||||
luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
|
||||
}
|
||||
|
||||
if (luv->flag & MLOOPUV_VERTSEL) {
|
||||
while (stacksize > 0) {
|
||||
|
||||
stacksize--;
|
||||
a = stack[stacksize];
|
||||
|
||||
efa = BM_face_at_index(em->bm, a);
|
||||
|
||||
BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) {
|
||||
|
||||
/* make_uv_vert_map_EM sets verts tmp.l to the indices */
|
||||
vlist = BM_uv_vert_map_at_index(vmap, BM_elem_index_get(l->v));
|
||||
|
||||
startv = vlist;
|
||||
|
||||
for (iterv = vlist; iterv; iterv = iterv->next) {
|
||||
if (iterv->separate)
|
||||
startv = iterv;
|
||||
if (iterv->f == a)
|
||||
break;
|
||||
}
|
||||
|
||||
for (iterv = startv; iterv; iterv = iterv->next) {
|
||||
if ((startv != iterv) && (iterv->separate))
|
||||
break;
|
||||
else if (!flag[iterv->f]) {
|
||||
flag[iterv->f] = 1;
|
||||
stack[stacksize] = iterv->f;
|
||||
stacksize++;
|
||||
}
|
||||
}
|
||||
|
||||
if (l) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (efa) {
|
||||
if (!extend) {
|
||||
BM_ITER_MESH_INDEX (efa, &iter, em->bm, BM_FACES_OF_MESH, a) {
|
||||
if (!flag[a]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (select_faces) {
|
||||
BM_face_select_set(em->bm, efa, false);
|
||||
if (flag[a])
|
||||
BM_face_select_set(em->bm, efa, true);
|
||||
else
|
||||
BM_face_select_set(em->bm, efa, false);
|
||||
}
|
||||
else {
|
||||
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
|
||||
luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
|
||||
|
||||
luv->flag &= ~MLOOPUV_VERTSEL;
|
||||
if (flag[a])
|
||||
luv->flag |= MLOOPUV_VERTSEL;
|
||||
else
|
||||
luv->flag &= ~MLOOPUV_VERTSEL;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1378,22 +1335,65 @@ static void uv_select_linked_multi(
|
||||
}
|
||||
|
||||
if (select_faces) {
|
||||
BM_face_select_set(em->bm, efa, true);
|
||||
if (BM_elem_flag_test(efa, BM_ELEM_SELECT) && !BM_elem_flag_test(efa, BM_ELEM_HIDDEN))
|
||||
break;
|
||||
}
|
||||
else {
|
||||
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
|
||||
luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
|
||||
|
||||
luv->flag |= MLOOPUV_VERTSEL;
|
||||
if (luv->flag & MLOOPUV_VERTSEL) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (l) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (efa) {
|
||||
BM_ITER_MESH_INDEX (efa, &iter, em->bm, BM_FACES_OF_MESH, a) {
|
||||
if (!flag[a]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (select_faces) {
|
||||
BM_face_select_set(em->bm, efa, false);
|
||||
}
|
||||
else {
|
||||
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
|
||||
luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
|
||||
|
||||
luv->flag &= ~MLOOPUV_VERTSEL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
BM_ITER_MESH_INDEX (efa, &iter, em->bm, BM_FACES_OF_MESH, a) {
|
||||
if (!flag[a]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (select_faces) {
|
||||
BM_face_select_set(em->bm, efa, true);
|
||||
}
|
||||
else {
|
||||
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
|
||||
luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
|
||||
|
||||
luv->flag |= MLOOPUV_VERTSEL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MEM_freeN(stack);
|
||||
MEM_freeN(flag);
|
||||
BM_uv_vert_map_free(vmap);
|
||||
|
||||
MEM_freeN(stack);
|
||||
MEM_freeN(flag);
|
||||
BM_uv_vert_map_free(vmap);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3058,82 +3058,82 @@ static int uv_border_select_exec(bContext *C, wmOperator *op)
|
||||
|
||||
/* don't indent to avoid diff noise! */
|
||||
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
|
||||
Object *obedit = objects[ob_index];
|
||||
BMEditMesh *em = BKE_editmesh_from_object(obedit);
|
||||
Object *obedit = objects[ob_index];
|
||||
BMEditMesh *em = BKE_editmesh_from_object(obedit);
|
||||
|
||||
bool changed = false;
|
||||
bool changed = false;
|
||||
|
||||
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
|
||||
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
|
||||
|
||||
if (!extend)
|
||||
uv_select_all_perform_multi(scene, ima, objects, objects_len, SEL_DESELECT);
|
||||
if (!extend)
|
||||
uv_select_all_perform_multi(scene, ima, objects, objects_len, SEL_DESELECT);
|
||||
|
||||
/* do actual selection */
|
||||
if (use_face_center && !pinned) {
|
||||
/* handle face selection mode */
|
||||
float cent[2];
|
||||
/* do actual selection */
|
||||
if (use_face_center && !pinned) {
|
||||
/* handle face selection mode */
|
||||
float cent[2];
|
||||
|
||||
changed = false;
|
||||
changed = false;
|
||||
|
||||
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
|
||||
/* assume not touched */
|
||||
BM_elem_flag_disable(efa, BM_ELEM_TAG);
|
||||
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
|
||||
/* assume not touched */
|
||||
BM_elem_flag_disable(efa, BM_ELEM_TAG);
|
||||
|
||||
if (uvedit_face_visible_test(scene, obedit, ima, efa)) {
|
||||
uv_poly_center(efa, cent, cd_loop_uv_offset);
|
||||
if (BLI_rctf_isect_pt_v(&rectf, cent)) {
|
||||
BM_elem_flag_enable(efa, BM_ELEM_TAG);
|
||||
changed = true;
|
||||
if (uvedit_face_visible_test(scene, obedit, ima, efa)) {
|
||||
uv_poly_center(efa, cent, cd_loop_uv_offset);
|
||||
if (BLI_rctf_isect_pt_v(&rectf, cent)) {
|
||||
BM_elem_flag_enable(efa, BM_ELEM_TAG);
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* (de)selects all tagged faces and deals with sticky modes */
|
||||
if (changed) {
|
||||
uv_select_flush_from_tag_face(sima, scene, obedit, select);
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* other selection modes */
|
||||
changed = true;
|
||||
BM_mesh_elem_hflag_disable_all(em->bm, BM_VERT, BM_ELEM_TAG, false);
|
||||
|
||||
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
|
||||
if (!uvedit_face_visible_test(scene, obedit, ima, efa))
|
||||
continue;
|
||||
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
|
||||
luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
|
||||
|
||||
if (!pinned || (ts->uv_flag & UV_SYNC_SELECTION)) {
|
||||
|
||||
/* UV_SYNC_SELECTION - can't do pinned selection */
|
||||
if (BLI_rctf_isect_pt_v(&rectf, luv->uv)) {
|
||||
uvedit_uv_select_set(em, scene, l, select, false, cd_loop_uv_offset);
|
||||
BM_elem_flag_enable(l->v, BM_ELEM_TAG);
|
||||
}
|
||||
}
|
||||
else if (pinned) {
|
||||
if ((luv->flag & MLOOPUV_PINNED) && BLI_rctf_isect_pt_v(&rectf, luv->uv)) {
|
||||
uvedit_uv_select_set(em, scene, l, select, false, cd_loop_uv_offset);
|
||||
BM_elem_flag_enable(l->v, BM_ELEM_TAG);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (sima->sticky == SI_STICKY_VERTEX) {
|
||||
uvedit_vertex_select_tagged(em, scene, select, cd_loop_uv_offset);
|
||||
}
|
||||
}
|
||||
|
||||
/* (de)selects all tagged faces and deals with sticky modes */
|
||||
if (changed) {
|
||||
uv_select_flush_from_tag_face(sima, scene, obedit, select);
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* other selection modes */
|
||||
changed = true;
|
||||
BM_mesh_elem_hflag_disable_all(em->bm, BM_VERT, BM_ELEM_TAG, false);
|
||||
uv_select_sync_flush(ts, em, select);
|
||||
|
||||
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
|
||||
if (!uvedit_face_visible_test(scene, obedit, ima, efa))
|
||||
continue;
|
||||
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
|
||||
luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
|
||||
|
||||
if (!pinned || (ts->uv_flag & UV_SYNC_SELECTION)) {
|
||||
|
||||
/* UV_SYNC_SELECTION - can't do pinned selection */
|
||||
if (BLI_rctf_isect_pt_v(&rectf, luv->uv)) {
|
||||
uvedit_uv_select_set(em, scene, l, select, false, cd_loop_uv_offset);
|
||||
BM_elem_flag_enable(l->v, BM_ELEM_TAG);
|
||||
}
|
||||
}
|
||||
else if (pinned) {
|
||||
if ((luv->flag & MLOOPUV_PINNED) && BLI_rctf_isect_pt_v(&rectf, luv->uv)) {
|
||||
uvedit_uv_select_set(em, scene, l, select, false, cd_loop_uv_offset);
|
||||
BM_elem_flag_enable(l->v, BM_ELEM_TAG);
|
||||
}
|
||||
}
|
||||
if (ts->uv_flag & UV_SYNC_SELECTION) {
|
||||
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
|
||||
}
|
||||
}
|
||||
|
||||
if (sima->sticky == SI_STICKY_VERTEX) {
|
||||
uvedit_vertex_select_tagged(em, scene, select, cd_loop_uv_offset);
|
||||
}
|
||||
}
|
||||
|
||||
if (changed) {
|
||||
uv_select_sync_flush(ts, em, select);
|
||||
|
||||
if (ts->uv_flag & UV_SYNC_SELECTION) {
|
||||
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
|
||||
}
|
||||
}
|
||||
changed_multi |= changed;
|
||||
changed_multi |= changed;
|
||||
}
|
||||
|
||||
MEM_SAFE_FREE(objects);
|
||||
@@ -3326,79 +3326,79 @@ static bool do_lasso_select_mesh_uv(bContext *C, const int mcords[][2], short mo
|
||||
|
||||
/* don't indent to avoid diff noise! */
|
||||
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
|
||||
Object *obedit = objects[ob_index];
|
||||
Object *obedit = objects[ob_index];
|
||||
|
||||
bool changed = false;
|
||||
bool changed = false;
|
||||
|
||||
BMEditMesh *em = BKE_editmesh_from_object(obedit);
|
||||
BMEditMesh *em = BKE_editmesh_from_object(obedit);
|
||||
|
||||
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
|
||||
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
|
||||
|
||||
if (!extend && select) {
|
||||
uv_select_all_perform_multi(scene, ima, objects, objects_len, SEL_DESELECT);
|
||||
}
|
||||
if (!extend && select) {
|
||||
uv_select_all_perform_multi(scene, ima, objects, objects_len, SEL_DESELECT);
|
||||
}
|
||||
|
||||
if (use_face_center) { /* Face Center Sel */
|
||||
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
|
||||
BM_elem_flag_disable(efa, BM_ELEM_TAG);
|
||||
/* assume not touched */
|
||||
if (select != uvedit_face_select_test(scene, efa, cd_loop_uv_offset)) {
|
||||
float cent[2];
|
||||
uv_poly_center(efa, cent, cd_loop_uv_offset);
|
||||
if (use_face_center) { /* Face Center Sel */
|
||||
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
|
||||
BM_elem_flag_disable(efa, BM_ELEM_TAG);
|
||||
/* assume not touched */
|
||||
if (select != uvedit_face_select_test(scene, efa, cd_loop_uv_offset)) {
|
||||
float cent[2];
|
||||
uv_poly_center(efa, cent, cd_loop_uv_offset);
|
||||
|
||||
if (UI_view2d_view_to_region_clip(&ar->v2d, cent[0], cent[1], &screen_uv[0], &screen_uv[1]) &&
|
||||
BLI_rcti_isect_pt_v(&rect, screen_uv) &&
|
||||
BLI_lasso_is_point_inside(mcords, moves, screen_uv[0], screen_uv[1], V2D_IS_CLIPPED))
|
||||
{
|
||||
BM_elem_flag_enable(efa, BM_ELEM_TAG);
|
||||
changed = true;
|
||||
if (UI_view2d_view_to_region_clip(&ar->v2d, cent[0], cent[1], &screen_uv[0], &screen_uv[1]) &&
|
||||
BLI_rcti_isect_pt_v(&rect, screen_uv) &&
|
||||
BLI_lasso_is_point_inside(mcords, moves, screen_uv[0], screen_uv[1], V2D_IS_CLIPPED))
|
||||
{
|
||||
BM_elem_flag_enable(efa, BM_ELEM_TAG);
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* (de)selects all tagged faces and deals with sticky modes */
|
||||
if (changed) {
|
||||
uv_select_flush_from_tag_face(sima, scene, obedit, select);
|
||||
/* (de)selects all tagged faces and deals with sticky modes */
|
||||
if (changed) {
|
||||
uv_select_flush_from_tag_face(sima, scene, obedit, select);
|
||||
}
|
||||
}
|
||||
}
|
||||
else { /* Vert Sel */
|
||||
BM_mesh_elem_hflag_disable_all(em->bm, BM_VERT, BM_ELEM_TAG, false);
|
||||
else { /* Vert Sel */
|
||||
BM_mesh_elem_hflag_disable_all(em->bm, BM_VERT, BM_ELEM_TAG, false);
|
||||
|
||||
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
|
||||
if (uvedit_face_visible_test(scene, obedit, ima, efa)) {
|
||||
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
|
||||
if ((select) != (uvedit_uv_select_test(scene, l, cd_loop_uv_offset))) {
|
||||
MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
|
||||
if (UI_view2d_view_to_region_clip(
|
||||
&ar->v2d,
|
||||
luv->uv[0], luv->uv[1],
|
||||
&screen_uv[0], &screen_uv[1]) &&
|
||||
BLI_rcti_isect_pt_v(&rect, screen_uv) &&
|
||||
BLI_lasso_is_point_inside(mcords, moves, screen_uv[0], screen_uv[1], V2D_IS_CLIPPED))
|
||||
{
|
||||
uvedit_uv_select_set(em, scene, l, select, false, cd_loop_uv_offset);
|
||||
changed = true;
|
||||
BM_elem_flag_enable(l->v, BM_ELEM_TAG);
|
||||
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
|
||||
if (uvedit_face_visible_test(scene, obedit, ima, efa)) {
|
||||
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
|
||||
if ((select) != (uvedit_uv_select_test(scene, l, cd_loop_uv_offset))) {
|
||||
MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
|
||||
if (UI_view2d_view_to_region_clip(
|
||||
&ar->v2d,
|
||||
luv->uv[0], luv->uv[1],
|
||||
&screen_uv[0], &screen_uv[1]) &&
|
||||
BLI_rcti_isect_pt_v(&rect, screen_uv) &&
|
||||
BLI_lasso_is_point_inside(mcords, moves, screen_uv[0], screen_uv[1], V2D_IS_CLIPPED))
|
||||
{
|
||||
uvedit_uv_select_set(em, scene, l, select, false, cd_loop_uv_offset);
|
||||
changed = true;
|
||||
BM_elem_flag_enable(l->v, BM_ELEM_TAG);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (sima->sticky == SI_STICKY_VERTEX) {
|
||||
uvedit_vertex_select_tagged(em, scene, select, cd_loop_uv_offset);
|
||||
}
|
||||
}
|
||||
|
||||
if (sima->sticky == SI_STICKY_VERTEX) {
|
||||
uvedit_vertex_select_tagged(em, scene, select, cd_loop_uv_offset);
|
||||
if (changed) {
|
||||
uv_select_sync_flush(scene->toolsettings, em, select);
|
||||
|
||||
if (ts->uv_flag & UV_SYNC_SELECTION) {
|
||||
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (changed) {
|
||||
uv_select_sync_flush(scene->toolsettings, em, select);
|
||||
|
||||
if (ts->uv_flag & UV_SYNC_SELECTION) {
|
||||
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
|
||||
}
|
||||
}
|
||||
|
||||
changed_multi |= changed;
|
||||
changed_multi |= changed;
|
||||
}
|
||||
|
||||
return changed_multi;
|
||||
|
||||
@@ -378,46 +378,46 @@ static ParamHandle *construct_param_handle_multi(
|
||||
int offset = 0;
|
||||
|
||||
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
|
||||
Object *obedit = objects[ob_index];
|
||||
BMEditMesh *em = BKE_editmesh_from_object(obedit);
|
||||
BMesh *bm = em->bm;
|
||||
Object *obedit = objects[ob_index];
|
||||
BMEditMesh *em = BKE_editmesh_from_object(obedit);
|
||||
BMesh *bm = em->bm;
|
||||
|
||||
const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
|
||||
const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
|
||||
|
||||
BM_ITER_MESH_INDEX (efa, &iter, bm, BM_FACES_OF_MESH, i) {
|
||||
BM_ITER_MESH_INDEX (efa, &iter, bm, BM_FACES_OF_MESH, i) {
|
||||
|
||||
if ((BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) || (sel && BM_elem_flag_test(efa, BM_ELEM_SELECT) == 0)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (implicit) {
|
||||
bool is_loopsel = false;
|
||||
|
||||
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
|
||||
if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) {
|
||||
is_loopsel = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (is_loopsel == false) {
|
||||
if ((BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) || (sel && BM_elem_flag_test(efa, BM_ELEM_SELECT) == 0)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (implicit) {
|
||||
bool is_loopsel = false;
|
||||
|
||||
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
|
||||
if (uvedit_uv_select_test(scene, l, cd_loop_uv_offset)) {
|
||||
is_loopsel = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (is_loopsel == false) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
construct_param_handle_face_add(handle, scene, efa, i + offset, cd_loop_uv_offset);
|
||||
}
|
||||
|
||||
construct_param_handle_face_add(handle, scene, efa, i + offset, cd_loop_uv_offset);
|
||||
}
|
||||
|
||||
if (!implicit) {
|
||||
BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) {
|
||||
if (BM_elem_flag_test(eed, BM_ELEM_SEAM)) {
|
||||
ParamKey vkeys[2];
|
||||
vkeys[0] = (ParamKey)BM_elem_index_get(eed->v1);
|
||||
vkeys[1] = (ParamKey)BM_elem_index_get(eed->v2);
|
||||
param_edge_set_seam(handle, vkeys);
|
||||
if (!implicit) {
|
||||
BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) {
|
||||
if (BM_elem_flag_test(eed, BM_ELEM_SEAM)) {
|
||||
ParamKey vkeys[2];
|
||||
vkeys[0] = (ParamKey)BM_elem_index_get(eed->v1);
|
||||
vkeys[1] = (ParamKey)BM_elem_index_get(eed->v2);
|
||||
param_edge_set_seam(handle, vkeys);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
offset += bm->totface;
|
||||
offset += bm->totface;
|
||||
}
|
||||
|
||||
param_construct_end(handle, fill, implicit);
|
||||
@@ -1479,74 +1479,75 @@ static int uv_from_view_exec(bContext *C, wmOperator *op)
|
||||
Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, &objects_len);
|
||||
|
||||
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
|
||||
Object *obedit = objects[ob_index];
|
||||
BMEditMesh *em = BKE_editmesh_from_object(obedit);
|
||||
bool changed = false;
|
||||
Object *obedit = objects[ob_index];
|
||||
BMEditMesh *em = BKE_editmesh_from_object(obedit);
|
||||
bool changed = false;
|
||||
|
||||
/* add uvs if they don't exist yet */
|
||||
if (!ED_uvedit_ensure_uvs(C, scene, obedit)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
|
||||
|
||||
if (RNA_boolean_get(op->ptr, "orthographic")) {
|
||||
uv_map_rotation_matrix(rotmat, rv3d, obedit, 90.0f, 0.0f, 1.0f);
|
||||
|
||||
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
|
||||
if (!BM_elem_flag_test(efa, BM_ELEM_SELECT))
|
||||
continue;
|
||||
|
||||
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
|
||||
luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
|
||||
BLI_uvproject_from_view_ortho(luv->uv, l->v->co, rotmat);
|
||||
}
|
||||
changed = true;
|
||||
/* add uvs if they don't exist yet */
|
||||
if (!ED_uvedit_ensure_uvs(C, scene, obedit)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if (camera) {
|
||||
const bool camera_bounds = RNA_boolean_get(op->ptr, "camera_bounds");
|
||||
struct ProjCameraInfo *uci = BLI_uvproject_camera_info(v3d->camera, obedit->obmat,
|
||||
camera_bounds ? (scene->r.xsch * scene->r.xasp) : 1.0f,
|
||||
camera_bounds ? (scene->r.ysch * scene->r.yasp) : 1.0f);
|
||||
|
||||
if (uci) {
|
||||
const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
|
||||
|
||||
if (RNA_boolean_get(op->ptr, "orthographic")) {
|
||||
uv_map_rotation_matrix(rotmat, rv3d, obedit, 90.0f, 0.0f, 1.0f);
|
||||
|
||||
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
|
||||
if (!BM_elem_flag_test(efa, BM_ELEM_SELECT))
|
||||
continue;
|
||||
|
||||
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
|
||||
luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
|
||||
BLI_uvproject_from_camera(luv->uv, l->v->co, uci);
|
||||
BLI_uvproject_from_view_ortho(luv->uv, l->v->co, rotmat);
|
||||
}
|
||||
changed = true;
|
||||
}
|
||||
|
||||
MEM_freeN(uci);
|
||||
}
|
||||
}
|
||||
else {
|
||||
copy_m4_m4(rotmat, obedit->obmat);
|
||||
else if (camera) {
|
||||
const bool camera_bounds = RNA_boolean_get(op->ptr, "camera_bounds");
|
||||
struct ProjCameraInfo *uci = BLI_uvproject_camera_info(
|
||||
v3d->camera, obedit->obmat,
|
||||
camera_bounds ? (scene->r.xsch * scene->r.xasp) : 1.0f,
|
||||
camera_bounds ? (scene->r.ysch * scene->r.yasp) : 1.0f);
|
||||
|
||||
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
|
||||
if (!BM_elem_flag_test(efa, BM_ELEM_SELECT))
|
||||
continue;
|
||||
if (uci) {
|
||||
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
|
||||
if (!BM_elem_flag_test(efa, BM_ELEM_SELECT))
|
||||
continue;
|
||||
|
||||
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
|
||||
luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
|
||||
BLI_uvproject_from_view(luv->uv, l->v->co, rv3d->persmat, rotmat, ar->winx, ar->winy);
|
||||
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
|
||||
luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
|
||||
BLI_uvproject_from_camera(luv->uv, l->v->co, uci);
|
||||
}
|
||||
changed = true;
|
||||
}
|
||||
|
||||
MEM_freeN(uci);
|
||||
}
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
copy_m4_m4(rotmat, obedit->obmat);
|
||||
|
||||
if (changed) {
|
||||
uv_map_clip_correct(scene, obedit, em, op);
|
||||
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
|
||||
if (!BM_elem_flag_test(efa, BM_ELEM_SELECT))
|
||||
continue;
|
||||
|
||||
DEG_id_tag_update(obedit->data, 0);
|
||||
WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
|
||||
changed_multi = true;
|
||||
}
|
||||
BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
|
||||
luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
|
||||
BLI_uvproject_from_view(luv->uv, l->v->co, rv3d->persmat, rotmat, ar->winx, ar->winy);
|
||||
}
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (changed) {
|
||||
uv_map_clip_correct(scene, obedit, em, op);
|
||||
|
||||
DEG_id_tag_update(obedit->data, 0);
|
||||
WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
|
||||
changed_multi = true;
|
||||
}
|
||||
}
|
||||
MEM_SAFE_FREE(objects);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user