Cleanup: indentation

Indent lines for multi object editing, no functional changes.

Also strip trailing space from indented regions.
This commit is contained in:
Campbell Barton
2018-04-16 17:54:33 +02:00
parent bfc9d426bb
commit 292a2802ad
12 changed files with 3358 additions and 3354 deletions

View File

@@ -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) {

View File

@@ -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);

View File

@@ -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);

View File

@@ -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);

View File

@@ -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;
}

View File

@@ -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);
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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) {

View File

@@ -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:

View File

@@ -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);

View File

@@ -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;

View File

@@ -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);