GPencil: Add new parameteres to transform layers
When using grease pencil for drawing Storyboards, it's very common to require a transform of the layers. This transform can be done using the offset modifier, but in some cases, the scene requires a lot of modifiers and makes the file hard to work. This new feature adds a transforms Location, Rotation and Scale at Layer level, and allows to transform the layer without using a modifier, keeping the scene more clean. {F9480695} This feature was suggested by @pepeland after receiving feedback from several artists. Also, done some code cleanup and rename some functions to get a better naming. Maniphest Tasks: T83660 Differential Revision: https://developer.blender.org/D9761
This commit is contained in:
parent
0a44c4b594
commit
e02d84eb3b
Notes:
blender-bot
2023-02-14 06:46:23 +01:00
Referenced by issue #83660, GPencil: New Layer transform parameters
|
@ -759,6 +759,16 @@ class GreasePencilLayerAdjustmentsPanel:
|
|||
col = layout.row(align=True)
|
||||
col.prop(gpl, "lock_material")
|
||||
|
||||
# Transforms
|
||||
row = layout.row(align=True)
|
||||
row.prop(gpl, "location")
|
||||
|
||||
row = layout.row(align=True)
|
||||
row.prop(gpl, "rotation")
|
||||
|
||||
row = layout.row(align=True)
|
||||
row.prop(gpl, "scale")
|
||||
|
||||
|
||||
class GPENCIL_UL_masks(UIList):
|
||||
def draw_item(self, _context, layout, _data, item, icon, _active_data, _active_propname, _index):
|
||||
|
|
|
@ -280,12 +280,12 @@ void BKE_gpencil_frame_original_pointers_update(const struct bGPDframe *gpf_orig
|
|||
const struct bGPDframe *gpf_eval);
|
||||
void BKE_gpencil_update_orig_pointers(const struct Object *ob_orig, const struct Object *ob_eval);
|
||||
|
||||
void BKE_gpencil_parent_matrix_get(const struct Depsgraph *depsgraph,
|
||||
struct Object *obact,
|
||||
struct bGPDlayer *gpl,
|
||||
float diff_mat[4][4]);
|
||||
void BKE_gpencil_layer_transform_matrix_get(const struct Depsgraph *depsgraph,
|
||||
struct Object *obact,
|
||||
struct bGPDlayer *gpl,
|
||||
float diff_mat[4][4]);
|
||||
|
||||
void BKE_gpencil_update_layer_parent(const struct Depsgraph *depsgraph, struct Object *ob);
|
||||
void BKE_gpencil_update_layer_transforms(const struct Depsgraph *depsgraph, struct Object *ob);
|
||||
|
||||
int BKE_gpencil_material_find_index_by_name_prefix(struct Object *ob, const char *name_prefix);
|
||||
|
||||
|
|
|
@ -95,6 +95,32 @@ static void greasepencil_copy_data(Main *UNUSED(bmain),
|
|||
/* TODO here too could add unused flags... */
|
||||
bGPDlayer *gpl_dst = BKE_gpencil_layer_duplicate(gpl_src);
|
||||
|
||||
/* Apply local layer transform to all frames. Calc the active frame is not enough
|
||||
* because onion skin can use more frames. This is more slow but required here. */
|
||||
if (gpl_dst->actframe != NULL) {
|
||||
bool transfomed = ((!is_zero_v3(gpl_dst->location)) || (!is_zero_v3(gpl_dst->rotation)) ||
|
||||
(!is_one_v3(gpl_dst->scale)));
|
||||
if (transfomed) {
|
||||
loc_eul_size_to_mat4(
|
||||
gpl_dst->layer_mat, gpl_dst->location, gpl_dst->rotation, gpl_dst->scale);
|
||||
bool do_onion = ((gpl_dst->onion_flag & GP_LAYER_ONIONSKIN) != 0);
|
||||
bGPDframe *init_gpf = (do_onion) ? gpl_dst->frames.first : gpl_dst->actframe;
|
||||
for (bGPDframe *gpf = init_gpf; gpf; gpf = gpf->next) {
|
||||
LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
|
||||
bGPDspoint *pt;
|
||||
int i;
|
||||
for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
|
||||
mul_m4_v3(gpl_dst->layer_mat, &pt->x);
|
||||
}
|
||||
}
|
||||
/* if not onion, exit loop. */
|
||||
if (!do_onion) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BLI_addtail(&gpd_dst->layers, gpl_dst);
|
||||
}
|
||||
}
|
||||
|
@ -686,6 +712,14 @@ bGPDlayer *BKE_gpencil_layer_addnew(bGPdata *gpd, const char *name, bool setacti
|
|||
|
||||
/* Enable always affected by scene lights. */
|
||||
gpl->flag |= GP_LAYER_USE_LIGHTS;
|
||||
|
||||
/* Init transform. */
|
||||
zero_v3(gpl->location);
|
||||
zero_v3(gpl->rotation);
|
||||
copy_v3_fl(gpl->scale, 1.0f);
|
||||
loc_eul_size_to_mat4(gpl->layer_mat, gpl->location, gpl->rotation, gpl->scale);
|
||||
invert_m4_m4(gpl->layer_invmat, gpl->layer_mat);
|
||||
|
||||
/* make this one the active one */
|
||||
if (setactive) {
|
||||
BKE_gpencil_layer_active_set(gpd, gpl);
|
||||
|
@ -2759,10 +2793,10 @@ void BKE_gpencil_update_orig_pointers(const Object *ob_orig, const Object *ob_ev
|
|||
* \param gpl: Grease pencil layer
|
||||
* \param diff_mat: Result parent matrix
|
||||
*/
|
||||
void BKE_gpencil_parent_matrix_get(const Depsgraph *depsgraph,
|
||||
Object *obact,
|
||||
bGPDlayer *gpl,
|
||||
float diff_mat[4][4])
|
||||
void BKE_gpencil_layer_transform_matrix_get(const Depsgraph *depsgraph,
|
||||
Object *obact,
|
||||
bGPDlayer *gpl,
|
||||
float diff_mat[4][4])
|
||||
{
|
||||
Object *ob_eval = depsgraph != NULL ? DEG_get_evaluated_object(depsgraph, obact) : obact;
|
||||
Object *obparent = gpl->parent;
|
||||
|
@ -2771,11 +2805,10 @@ void BKE_gpencil_parent_matrix_get(const Depsgraph *depsgraph,
|
|||
|
||||
/* if not layer parented, try with object parented */
|
||||
if (obparent_eval == NULL) {
|
||||
if (ob_eval != NULL) {
|
||||
if (ob_eval->type == OB_GPENCIL) {
|
||||
copy_m4_m4(diff_mat, ob_eval->obmat);
|
||||
return;
|
||||
}
|
||||
if ((ob_eval != NULL) && (ob_eval->type == OB_GPENCIL)) {
|
||||
copy_m4_m4(diff_mat, ob_eval->obmat);
|
||||
mul_m4_m4m4(diff_mat, diff_mat, gpl->layer_mat);
|
||||
return;
|
||||
}
|
||||
/* not gpencil object */
|
||||
unit_m4(diff_mat);
|
||||
|
@ -2785,6 +2818,7 @@ void BKE_gpencil_parent_matrix_get(const Depsgraph *depsgraph,
|
|||
if (ELEM(gpl->partype, PAROBJECT, PARSKEL)) {
|
||||
mul_m4_m4m4(diff_mat, obparent_eval->obmat, gpl->inverse);
|
||||
add_v3_v3(diff_mat[3], ob_eval->obmat[3]);
|
||||
mul_m4_m4m4(diff_mat, diff_mat, gpl->layer_mat);
|
||||
return;
|
||||
}
|
||||
if (gpl->partype == PARBONE) {
|
||||
|
@ -2800,6 +2834,7 @@ void BKE_gpencil_parent_matrix_get(const Depsgraph *depsgraph,
|
|||
mul_m4_m4m4(diff_mat, obparent_eval->obmat, gpl->inverse);
|
||||
add_v3_v3(diff_mat[3], ob_eval->obmat[3]);
|
||||
}
|
||||
mul_m4_m4m4(diff_mat, diff_mat, gpl->layer_mat);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2807,11 +2842,11 @@ void BKE_gpencil_parent_matrix_get(const Depsgraph *depsgraph,
|
|||
}
|
||||
|
||||
/**
|
||||
* Update parent matrix.
|
||||
* Update parent matrix and local transforms.
|
||||
* \param depsgraph: Depsgraph
|
||||
* \param ob: Grease pencil object
|
||||
*/
|
||||
void BKE_gpencil_update_layer_parent(const Depsgraph *depsgraph, Object *ob)
|
||||
void BKE_gpencil_update_layer_transforms(const Depsgraph *depsgraph, Object *ob)
|
||||
{
|
||||
if (ob->type != OB_GPENCIL) {
|
||||
return;
|
||||
|
@ -2820,31 +2855,50 @@ void BKE_gpencil_update_layer_parent(const Depsgraph *depsgraph, Object *ob)
|
|||
bGPdata *gpd = (bGPdata *)ob->data;
|
||||
float cur_mat[4][4];
|
||||
|
||||
bool changed = false;
|
||||
LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
|
||||
if ((gpl->parent != NULL) && (gpl->actframe != NULL)) {
|
||||
Object *ob_parent = DEG_get_evaluated_object(depsgraph, gpl->parent);
|
||||
/* calculate new matrix */
|
||||
if (ELEM(gpl->partype, PAROBJECT, PARSKEL)) {
|
||||
copy_m4_m4(cur_mat, ob_parent->obmat);
|
||||
}
|
||||
else if (gpl->partype == PARBONE) {
|
||||
bPoseChannel *pchan = BKE_pose_channel_find_name(ob_parent->pose, gpl->parsubstr);
|
||||
if (pchan != NULL) {
|
||||
copy_m4_m4(cur_mat, ob->imat);
|
||||
mul_m4_m4m4(cur_mat, ob_parent->obmat, pchan->pose_mat);
|
||||
unit_m4(cur_mat);
|
||||
if (gpl->actframe != NULL) {
|
||||
if (gpl->parent != NULL) {
|
||||
Object *ob_parent = DEG_get_evaluated_object(depsgraph, gpl->parent);
|
||||
/* calculate new matrix */
|
||||
if (ELEM(gpl->partype, PAROBJECT, PARSKEL)) {
|
||||
copy_m4_m4(cur_mat, ob_parent->obmat);
|
||||
}
|
||||
else {
|
||||
unit_m4(cur_mat);
|
||||
else if (gpl->partype == PARBONE) {
|
||||
bPoseChannel *pchan = BKE_pose_channel_find_name(ob_parent->pose, gpl->parsubstr);
|
||||
if (pchan != NULL) {
|
||||
copy_m4_m4(cur_mat, ob->imat);
|
||||
mul_m4_m4m4(cur_mat, ob_parent->obmat, pchan->pose_mat);
|
||||
}
|
||||
else {
|
||||
unit_m4(cur_mat);
|
||||
}
|
||||
}
|
||||
changed = !equals_m4m4(gpl->inverse, cur_mat);
|
||||
}
|
||||
|
||||
/* Calc local layer transform. */
|
||||
bool transfomed = ((!is_zero_v3(gpl->location)) || (!is_zero_v3(gpl->rotation)) ||
|
||||
(!is_one_v3(gpl->scale)));
|
||||
if (transfomed) {
|
||||
loc_eul_size_to_mat4(gpl->layer_mat, gpl->location, gpl->rotation, gpl->scale);
|
||||
}
|
||||
|
||||
/* only redo if any change */
|
||||
if (!equals_m4m4(gpl->inverse, cur_mat)) {
|
||||
if (changed || transfomed) {
|
||||
LISTBASE_FOREACH (bGPDstroke *, gps, &gpl->actframe->strokes) {
|
||||
bGPDspoint *pt;
|
||||
int i;
|
||||
for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
|
||||
mul_m4_v3(gpl->inverse, &pt->x);
|
||||
mul_m4_v3(cur_mat, &pt->x);
|
||||
if (changed) {
|
||||
mul_m4_v3(gpl->inverse, &pt->x);
|
||||
mul_m4_v3(cur_mat, &pt->x);
|
||||
}
|
||||
|
||||
if (transfomed) {
|
||||
mul_m4_v3(gpl->layer_mat, &pt->x);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -701,13 +701,18 @@ void BKE_gpencil_prepare_eval_data(Depsgraph *depsgraph, Scene *scene, Object *o
|
|||
Object *ob_orig = (Object *)DEG_get_original_id(&ob->id);
|
||||
bGPdata *gpd_orig = (bGPdata *)ob_orig->data;
|
||||
|
||||
/* Need check if some layer is parented. */
|
||||
/* Need check if some layer is parented or transformed. */
|
||||
bool do_parent = false;
|
||||
bool do_transform = false;
|
||||
LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd_orig->layers) {
|
||||
if (gpl->parent != NULL) {
|
||||
do_parent = true;
|
||||
break;
|
||||
}
|
||||
if ((!is_zero_v3(gpl->location)) || (!is_zero_v3(gpl->rotation)) || (!is_one_v3(gpl->scale))) {
|
||||
do_transform = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const bool is_multiedit = (bool)GPENCIL_MULTIEDIT_SESSIONS_ON(gpd_eval);
|
||||
|
@ -715,7 +720,7 @@ void BKE_gpencil_prepare_eval_data(Depsgraph *depsgraph, Scene *scene, Object *o
|
|||
const bool do_modifiers = (bool)((!is_multiedit) && (!is_curve_edit) &&
|
||||
(ob->greasepencil_modifiers.first != NULL) &&
|
||||
(!GPENCIL_SIMPLIFY_MODIF(scene)));
|
||||
if ((!do_modifiers) && (!do_parent)) {
|
||||
if ((!do_modifiers) && (!do_parent) && (!do_transform)) {
|
||||
return;
|
||||
}
|
||||
DEG_debug_print_eval(depsgraph, __func__, gpd_eval->id.name, gpd_eval);
|
||||
|
|
|
@ -225,7 +225,7 @@ void BKE_object_handle_data_update(Depsgraph *depsgraph, Scene *scene, Object *o
|
|||
case OB_GPENCIL: {
|
||||
BKE_gpencil_prepare_eval_data(depsgraph, scene, ob);
|
||||
BKE_gpencil_modifiers_calc(depsgraph, scene, ob);
|
||||
BKE_gpencil_update_layer_parent(depsgraph, ob);
|
||||
BKE_gpencil_update_layer_transforms(depsgraph, ob);
|
||||
break;
|
||||
}
|
||||
case OB_HAIR:
|
||||
|
|
|
@ -1582,5 +1582,18 @@ void blo_do_versions_290(FileData *fd, Library *UNUSED(lib), Main *bmain)
|
|||
*/
|
||||
{
|
||||
/* Keep this block, even when empty. */
|
||||
|
||||
/* Grease pencil layer transform matrix. */
|
||||
if (!DNA_struct_elem_find(fd->filesdna, "bGPDlayer", "float", "location[0]")) {
|
||||
LISTBASE_FOREACH (bGPdata *, gpd, &bmain->gpencils) {
|
||||
LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
|
||||
zero_v3(gpl->location);
|
||||
zero_v3(gpl->rotation);
|
||||
copy_v3_fl(gpl->scale, 1.0f);
|
||||
loc_eul_size_to_mat4(gpl->layer_mat, gpl->location, gpl->rotation, gpl->scale);
|
||||
invert_m4_m4(gpl->layer_invmat, gpl->layer_mat);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -258,6 +258,16 @@ void OVERLAY_gpencil_cache_init(OVERLAY_Data *vedata)
|
|||
|
||||
copy_m4_m4(mat, ob->obmat);
|
||||
|
||||
/* Rotate and scale except align to cursor. */
|
||||
bGPDlayer *gpl = BKE_gpencil_layer_active_get(gpd);
|
||||
if (gpl != NULL) {
|
||||
if (ts->gp_sculpt.lock_axis != GP_LOCKAXIS_CURSOR) {
|
||||
float matrot[3][3];
|
||||
copy_m3_m4(matrot, gpl->layer_mat);
|
||||
mul_m4_m4m3(mat, mat, matrot);
|
||||
}
|
||||
}
|
||||
|
||||
float viewinv[4][4];
|
||||
/* Set the grid in the selected axis */
|
||||
switch (ts->gp_sculpt.lock_axis) {
|
||||
|
@ -294,6 +304,11 @@ void OVERLAY_gpencil_cache_init(OVERLAY_Data *vedata)
|
|||
mul_v2_v2fl(size, gpd->grid.scale, 2.0f * ED_scene_grid_scale(scene, &grid_unit));
|
||||
rescale_m4(mat, (float[3]){size[0], size[1], 0.0f});
|
||||
|
||||
/* Apply layer loc transform, except cursor mode. */
|
||||
if ((gpl != NULL) && (ts->gpencil_v3d_align & GP_PROJECT_CURSOR) == 0) {
|
||||
add_v3_v3(mat[3], gpl->layer_mat[3]);
|
||||
}
|
||||
|
||||
const int gridlines = (gpd->grid.lines <= 0) ? 1 : gpd->grid.lines;
|
||||
int line_ct = gridlines * 4 + 2;
|
||||
|
||||
|
|
|
@ -800,20 +800,20 @@ static void gpencil_edit_curve_stroke_iter_cb(bGPDlayer *gpl,
|
|||
};
|
||||
|
||||
/* First segment. */
|
||||
copy_v3_v3(vert_ptr->pos, bezt->vec[0]);
|
||||
mul_v3_m4v3(vert_ptr->pos, gpl->layer_mat, bezt->vec[0]);
|
||||
vert_ptr->data = vflag[0];
|
||||
vert_ptr++;
|
||||
|
||||
copy_v3_v3(vert_ptr->pos, bezt->vec[1]);
|
||||
mul_v3_m4v3(vert_ptr->pos, gpl->layer_mat, bezt->vec[1]);
|
||||
vert_ptr->data = vflag[1];
|
||||
vert_ptr++;
|
||||
|
||||
/* Second segment. */
|
||||
copy_v3_v3(vert_ptr->pos, bezt->vec[1]);
|
||||
mul_v3_m4v3(vert_ptr->pos, gpl->layer_mat, bezt->vec[1]);
|
||||
vert_ptr->data = vflag[1];
|
||||
vert_ptr++;
|
||||
|
||||
copy_v3_v3(vert_ptr->pos, bezt->vec[2]);
|
||||
mul_v3_m4v3(vert_ptr->pos, gpl->layer_mat, bezt->vec[2]);
|
||||
vert_ptr->data = vflag[2];
|
||||
vert_ptr++;
|
||||
}
|
||||
|
|
|
@ -178,7 +178,7 @@ static void gpencil_strokepoint_convertcoords(bContext *C,
|
|||
|
||||
/* apply parent transform */
|
||||
float fpt[3];
|
||||
BKE_gpencil_parent_matrix_get(depsgraph, obact, gpl, diff_mat);
|
||||
BKE_gpencil_layer_transform_matrix_get(depsgraph, obact, gpl, diff_mat);
|
||||
mul_v3_m4v3(fpt, diff_mat, &source_pt->x);
|
||||
copy_v3_v3(&pt->x, fpt);
|
||||
|
||||
|
|
|
@ -2854,7 +2854,7 @@ int ED_gpencil_join_objects_exec(bContext *C, wmOperator *op)
|
|||
float inverse_diff_mat[4][4];
|
||||
|
||||
/* recalculate all stroke points */
|
||||
BKE_gpencil_parent_matrix_get(depsgraph, ob_iter, gpl_src, diff_mat);
|
||||
BKE_gpencil_layer_transform_matrix_get(depsgraph, ob_iter, gpl_src, diff_mat);
|
||||
invert_m4_m4_safe_ortho(inverse_diff_mat, diff_mat);
|
||||
|
||||
Material *ma_src = NULL;
|
||||
|
|
|
@ -2800,7 +2800,7 @@ static int gpencil_snap_to_grid(bContext *C, wmOperator *UNUSED(op))
|
|||
float diff_mat[4][4];
|
||||
|
||||
/* calculate difference matrix object */
|
||||
BKE_gpencil_parent_matrix_get(depsgraph, obact, gpl, diff_mat);
|
||||
BKE_gpencil_layer_transform_matrix_get(depsgraph, obact, gpl, diff_mat);
|
||||
|
||||
LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
|
||||
/* skip strokes that are invalid for current view */
|
||||
|
@ -2935,7 +2935,7 @@ static int gpencil_snap_to_cursor(bContext *C, wmOperator *op)
|
|||
float diff_mat[4][4];
|
||||
|
||||
/* calculate difference matrix */
|
||||
BKE_gpencil_parent_matrix_get(depsgraph, obact, gpl, diff_mat);
|
||||
BKE_gpencil_layer_transform_matrix_get(depsgraph, obact, gpl, diff_mat);
|
||||
|
||||
LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
|
||||
bGPDspoint *pt;
|
||||
|
@ -3039,7 +3039,7 @@ static bool gpencil_stroke_points_centroid(Depsgraph *depsgraph,
|
|||
float diff_mat[4][4];
|
||||
|
||||
/* calculate difference matrix */
|
||||
BKE_gpencil_parent_matrix_get(depsgraph, obact, gpl, diff_mat);
|
||||
BKE_gpencil_layer_transform_matrix_get(depsgraph, obact, gpl, diff_mat);
|
||||
|
||||
LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
|
||||
bGPDspoint *pt;
|
||||
|
|
|
@ -263,14 +263,14 @@ static void gpencil_draw_datablock(tGPDfill *tgpf, const float ink[4])
|
|||
BLI_assert(gpl_active_index >= 0);
|
||||
|
||||
LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
|
||||
/* calculate parent position */
|
||||
BKE_gpencil_parent_matrix_get(tgpw.depsgraph, ob, gpl, tgpw.diff_mat);
|
||||
|
||||
/* do not draw layer if hidden */
|
||||
if (gpl->flag & GP_LAYER_HIDE) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* calculate parent position */
|
||||
BKE_gpencil_layer_transform_matrix_get(tgpw.depsgraph, ob, gpl, tgpw.diff_mat);
|
||||
|
||||
/* Decide if the strokes of layers are included or not depending on the layer mode.
|
||||
* Cannot skip the layer because it can use boundary strokes and must be used. */
|
||||
bool skip = false;
|
||||
|
@ -1275,7 +1275,7 @@ static void gpencil_stroke_from_buffer(tGPDfill *tgpf)
|
|||
float origin[3];
|
||||
ED_gpencil_drawing_reference_get(tgpf->scene, tgpf->ob, ts->gpencil_v3d_align, origin);
|
||||
ED_gpencil_project_stroke_to_plane(
|
||||
tgpf->scene, tgpf->ob, tgpf->rv3d, gps, origin, tgpf->lock_axis - 1);
|
||||
tgpf->scene, tgpf->ob, tgpf->rv3d, tgpf->gpl, gps, origin, tgpf->lock_axis - 1);
|
||||
}
|
||||
|
||||
/* if parented change position relative to parent object */
|
||||
|
|
|
@ -667,7 +667,8 @@ struct GP_EditableStrokes_Iter {
|
|||
bGPDframe *init_gpf_ = (is_multiedit_) ? gpl->frames.first : gpl->actframe; \
|
||||
for (bGPDframe *gpf_ = init_gpf_; gpf_; gpf_ = gpf_->next) { \
|
||||
if ((gpf_ == gpl->actframe) || ((gpf_->flag & GP_FRAME_SELECT) && is_multiedit_)) { \
|
||||
BKE_gpencil_parent_matrix_get(depsgraph_, obact_, gpl, gpstroke_iter.diff_mat); \
|
||||
BKE_gpencil_layer_transform_matrix_get( \
|
||||
depsgraph_, obact_, gpl, gpstroke_iter.diff_mat); \
|
||||
invert_m4_m4(gpstroke_iter.inverse_diff_mat, gpstroke_iter.diff_mat); \
|
||||
/* loop over strokes */ \
|
||||
bGPDstroke *gpsn_; \
|
||||
|
@ -718,7 +719,8 @@ struct GP_EditableStrokes_Iter {
|
|||
bGPDframe *init_gpf_ = (is_multiedit_) ? gpl->frames.first : gpl->actframe; \
|
||||
for (bGPDframe *gpf_ = init_gpf_; gpf_; gpf_ = gpf_->next) { \
|
||||
if ((gpf_ == gpl->actframe) || ((gpf_->flag & GP_FRAME_SELECT) && is_multiedit_)) { \
|
||||
BKE_gpencil_parent_matrix_get(depsgraph_, obact_, gpl, gpstroke_iter.diff_mat); \
|
||||
BKE_gpencil_layer_transform_matrix_get( \
|
||||
depsgraph_, obact_, gpl, gpstroke_iter.diff_mat); \
|
||||
invert_m4_m4(gpstroke_iter.inverse_diff_mat, gpstroke_iter.diff_mat); \
|
||||
/* loop over strokes */ \
|
||||
bGPDstroke *gpsn_; \
|
||||
|
@ -767,8 +769,10 @@ struct GP_EditableStrokes_Iter {
|
|||
bGPDframe *init_gpf_ = (is_multiedit_) ? gpl->frames.first : gpl->actframe; \
|
||||
for (bGPDframe *gpf_ = init_gpf_; gpf_; gpf_ = gpf_->next) { \
|
||||
if ((gpf_ == gpl->actframe) || ((gpf_->flag & GP_FRAME_SELECT) && is_multiedit_)) { \
|
||||
BKE_gpencil_parent_matrix_get(depsgraph_, obact_, gpl, gpstroke_iter.diff_mat); \
|
||||
invert_m4_m4(gpstroke_iter.inverse_diff_mat, gpstroke_iter.diff_mat); \
|
||||
BKE_gpencil_layer_transform_matrix_get( \
|
||||
depsgraph_, obact_, gpl, gpstroke_iter.diff_mat); \
|
||||
/* Undo layer transform. */ \
|
||||
mul_m4_m4m4(gpstroke_iter.diff_mat, gpstroke_iter.diff_mat, gpl->layer_invmat); \
|
||||
/* loop over strokes */ \
|
||||
LISTBASE_FOREACH (bGPDstroke *, gps, &gpf_->strokes) { \
|
||||
/* skip strokes that are invalid for current view */ \
|
||||
|
|
|
@ -426,7 +426,7 @@ static void gpencil_reproject_toplane(tGPsdata *p, bGPDstroke *gps)
|
|||
|
||||
/* get drawing origin */
|
||||
gpencil_get_3d_reference(p, origin);
|
||||
ED_gpencil_project_stroke_to_plane(p->scene, obact, rv3d, gps, origin, p->lock_axis - 1);
|
||||
ED_gpencil_project_stroke_to_plane(p->scene, obact, rv3d, p->gpl, gps, origin, p->lock_axis - 1);
|
||||
}
|
||||
|
||||
/* convert screen-coordinates to buffer-coordinates */
|
||||
|
@ -887,11 +887,13 @@ static short gpencil_stroke_addpoint(tGPsdata *p,
|
|||
gpencil_get_3d_reference(p, origin);
|
||||
/* reproject current */
|
||||
ED_gpencil_tpoint_to_point(p->region, origin, pt, &spt);
|
||||
ED_gpencil_project_point_to_plane(p->scene, obact, rv3d, origin, p->lock_axis - 1, &spt);
|
||||
ED_gpencil_project_point_to_plane(
|
||||
p->scene, obact, p->gpl, rv3d, origin, p->lock_axis - 1, &spt);
|
||||
|
||||
/* reproject previous */
|
||||
ED_gpencil_tpoint_to_point(p->region, origin, ptb, &spt2);
|
||||
ED_gpencil_project_point_to_plane(p->scene, obact, rv3d, origin, p->lock_axis - 1, &spt2);
|
||||
ED_gpencil_project_point_to_plane(
|
||||
p->scene, obact, p->gpl, rv3d, origin, p->lock_axis - 1, &spt2);
|
||||
p->totpixlen += len_v3v3(&spt.x, &spt2.x);
|
||||
pt->uv_fac = p->totpixlen;
|
||||
}
|
||||
|
@ -1349,7 +1351,7 @@ static bool gpencil_stroke_eraser_is_occluded(tGPsdata *p,
|
|||
|
||||
float diff_mat[4][4];
|
||||
/* calculate difference matrix if parent object */
|
||||
BKE_gpencil_parent_matrix_get(p->depsgraph, obact, gpl, diff_mat);
|
||||
BKE_gpencil_layer_transform_matrix_get(p->depsgraph, obact, gpl, diff_mat);
|
||||
|
||||
if (ED_view3d_autodist_simple(p->region, mval_i, mval_3d, 0, NULL)) {
|
||||
const float depth_mval = view3d_point_depth(rv3d, mval_3d);
|
||||
|
@ -1731,7 +1733,7 @@ static void gpencil_stroke_doeraser(tGPsdata *p)
|
|||
continue;
|
||||
}
|
||||
/* calculate difference matrix */
|
||||
BKE_gpencil_parent_matrix_get(p->depsgraph, p->ob, gpl, p->diff_mat);
|
||||
BKE_gpencil_layer_transform_matrix_get(p->depsgraph, p->ob, gpl, p->diff_mat);
|
||||
|
||||
/* loop over strokes, checking segments for intersections */
|
||||
LISTBASE_FOREACH_MUTABLE (bGPDstroke *, gps, &gpf->strokes) {
|
||||
|
@ -2103,6 +2105,11 @@ static void gpencil_paint_initstroke(tGPsdata *p,
|
|||
copy_v3_v3(p->gpl->color, p->custom_color);
|
||||
}
|
||||
}
|
||||
|
||||
/* Recalculate layer transform matrix to avoid problems if props are animated. */
|
||||
loc_eul_size_to_mat4(p->gpl->layer_mat, p->gpl->location, p->gpl->rotation, p->gpl->scale);
|
||||
invert_m4_m4(p->gpl->layer_invmat, p->gpl->layer_mat);
|
||||
|
||||
if ((paintmode != GP_PAINTMODE_ERASER) && (p->gpl->flag & GP_LAYER_LOCKED)) {
|
||||
p->status = GP_STATUS_ERROR;
|
||||
if (G.debug & G_DEBUG) {
|
||||
|
|
|
@ -317,6 +317,10 @@ static void gpencil_primitive_set_initdata(bContext *C, tGPDprimitive *tgpi)
|
|||
}
|
||||
tgpi->gpl = gpl;
|
||||
|
||||
/* Recalculate layer transform matrix to avoid problems if props are animated. */
|
||||
loc_eul_size_to_mat4(gpl->layer_mat, gpl->location, gpl->rotation, gpl->scale);
|
||||
invert_m4_m4(gpl->layer_invmat, gpl->layer_mat);
|
||||
|
||||
/* create a new temporary frame */
|
||||
tgpi->gpf = MEM_callocN(sizeof(bGPDframe), "Temp bGPDframe");
|
||||
tgpi->gpf->framenum = tgpi->cframe = cfra;
|
||||
|
@ -1004,12 +1008,12 @@ static void gpencil_primitive_update_strokes(bContext *C, tGPDprimitive *tgpi)
|
|||
/* reproject current */
|
||||
ED_gpencil_tpoint_to_point(tgpi->region, origin, tpt, &spt);
|
||||
ED_gpencil_project_point_to_plane(
|
||||
tgpi->scene, tgpi->ob, tgpi->rv3d, origin, tgpi->lock_axis - 1, &spt);
|
||||
tgpi->scene, tgpi->ob, tgpi->gpl, tgpi->rv3d, origin, tgpi->lock_axis - 1, &spt);
|
||||
|
||||
/* reproject previous */
|
||||
ED_gpencil_tpoint_to_point(tgpi->region, origin, tptb, &spt2);
|
||||
ED_gpencil_project_point_to_plane(
|
||||
tgpi->scene, tgpi->ob, tgpi->rv3d, origin, tgpi->lock_axis - 1, &spt2);
|
||||
tgpi->scene, tgpi->ob, tgpi->gpl, tgpi->rv3d, origin, tgpi->lock_axis - 1, &spt2);
|
||||
tgpi->totpixlen += len_v3v3(&spt.x, &spt2.x);
|
||||
tpt->uv_fac = tgpi->totpixlen;
|
||||
}
|
||||
|
@ -1067,7 +1071,7 @@ static void gpencil_primitive_update_strokes(bContext *C, tGPDprimitive *tgpi)
|
|||
float origin[3];
|
||||
ED_gpencil_drawing_reference_get(tgpi->scene, tgpi->ob, ts->gpencil_v3d_align, origin);
|
||||
ED_gpencil_project_stroke_to_plane(
|
||||
tgpi->scene, tgpi->ob, tgpi->rv3d, gps, origin, ts->gp_sculpt.lock_axis - 1);
|
||||
tgpi->scene, tgpi->ob, tgpi->rv3d, tgpi->gpl, gps, origin, ts->gp_sculpt.lock_axis - 1);
|
||||
}
|
||||
|
||||
/* if parented change position relative to parent object */
|
||||
|
|
|
@ -1441,11 +1441,6 @@ static bool gpencil_sculpt_brush_do_stroke(tGP_BrushEditData *gso,
|
|||
bool changed = false;
|
||||
float rot_eval = 0.0f;
|
||||
|
||||
/* Check if the stroke collide with brush. */
|
||||
if (!ED_gpencil_stroke_check_collision(gsc, gps, gso->mval, radius, diff_mat)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (gps->totpoints == 1) {
|
||||
bGPDspoint pt_temp;
|
||||
pt = &gps->points[0];
|
||||
|
@ -1577,6 +1572,13 @@ static bool gpencil_sculpt_brush_do_frame(bContext *C,
|
|||
Object *ob = gso->object;
|
||||
bGPdata *gpd = ob->data;
|
||||
char tool = gso->brush->gpencil_sculpt_tool;
|
||||
GP_SpaceConversion *gsc = &gso->gsc;
|
||||
Brush *brush = gso->brush;
|
||||
const int radius = (brush->flag & GP_BRUSH_USE_PRESSURE) ? gso->brush->size * gso->pressure :
|
||||
gso->brush->size;
|
||||
/* Calc bound box matrix. */
|
||||
float bound_mat[4][4];
|
||||
BKE_gpencil_layer_transform_matrix_get(gso->depsgraph, gso->object, gpl, bound_mat);
|
||||
|
||||
LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
|
||||
/* skip strokes that are invalid for current view */
|
||||
|
@ -1588,6 +1590,11 @@ static bool gpencil_sculpt_brush_do_frame(bContext *C,
|
|||
continue;
|
||||
}
|
||||
|
||||
/* Check if the stroke collide with brush. */
|
||||
if (!ED_gpencil_stroke_check_collision(gsc, gps, gso->mval, radius, bound_mat)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (tool) {
|
||||
case GPSCULPT_TOOL_SMOOTH: /* Smooth strokes */
|
||||
{
|
||||
|
@ -1742,7 +1749,8 @@ static bool gpencil_sculpt_brush_apply_standard(bContext *C, tGP_BrushEditData *
|
|||
|
||||
/* calculate difference matrix */
|
||||
float diff_mat[4][4];
|
||||
BKE_gpencil_parent_matrix_get(depsgraph, obact, gpl, diff_mat);
|
||||
BKE_gpencil_layer_transform_matrix_get(depsgraph, obact, gpl, diff_mat);
|
||||
mul_m4_m4m4(diff_mat, diff_mat, gpl->layer_invmat);
|
||||
|
||||
/* Active Frame or MultiFrame? */
|
||||
if (gso->is_multiframe) {
|
||||
|
|
|
@ -674,7 +674,7 @@ void gpencil_apply_parent(Depsgraph *depsgraph, Object *obact, bGPDlayer *gpl, b
|
|||
float inverse_diff_mat[4][4];
|
||||
float fpt[3];
|
||||
|
||||
BKE_gpencil_parent_matrix_get(depsgraph, obact, gpl, diff_mat);
|
||||
BKE_gpencil_layer_transform_matrix_get(depsgraph, obact, gpl, diff_mat);
|
||||
invert_m4_m4(inverse_diff_mat, diff_mat);
|
||||
|
||||
for (i = 0; i < gps->totpoints; i++) {
|
||||
|
@ -697,10 +697,11 @@ void gpencil_apply_parent_point(Depsgraph *depsgraph,
|
|||
float inverse_diff_mat[4][4];
|
||||
float fpt[3];
|
||||
|
||||
BKE_gpencil_parent_matrix_get(depsgraph, obact, gpl, diff_mat);
|
||||
BKE_gpencil_layer_transform_matrix_get(depsgraph, obact, gpl, diff_mat);
|
||||
invert_m4_m4(inverse_diff_mat, diff_mat);
|
||||
|
||||
mul_v3_m4v3(fpt, inverse_diff_mat, &pt->x);
|
||||
|
||||
copy_v3_v3(&pt->x, fpt);
|
||||
}
|
||||
|
||||
|
@ -997,6 +998,12 @@ void ED_gpencil_drawing_reference_get(const Scene *scene,
|
|||
else {
|
||||
/* use object location */
|
||||
copy_v3_v3(r_vec, ob->obmat[3]);
|
||||
/* Apply layer offset. */
|
||||
bGPdata *gpd = ob->data;
|
||||
bGPDlayer *gpl = BKE_gpencil_layer_active_get(gpd);
|
||||
if (gpl != NULL) {
|
||||
add_v3_v3(r_vec, gpl->layer_mat[3]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1021,7 +1028,7 @@ void ED_gpencil_project_stroke_to_view(bContext *C, bGPDlayer *gpl, bGPDstroke *
|
|||
/* init space conversion stuff */
|
||||
gpencil_point_conversion_init(C, &gsc);
|
||||
|
||||
BKE_gpencil_parent_matrix_get(depsgraph, ob, gpl, diff_mat);
|
||||
BKE_gpencil_layer_transform_matrix_get(depsgraph, ob, gpl, diff_mat);
|
||||
invert_m4_m4(inverse_diff_mat, diff_mat);
|
||||
|
||||
/* Adjust each point */
|
||||
|
@ -1046,6 +1053,7 @@ void ED_gpencil_project_stroke_to_view(bContext *C, bGPDlayer *gpl, bGPDstroke *
|
|||
void ED_gpencil_project_stroke_to_plane(const Scene *scene,
|
||||
const Object *ob,
|
||||
const RegionView3D *rv3d,
|
||||
bGPDlayer *gpl,
|
||||
bGPDstroke *gps,
|
||||
const float origin[3],
|
||||
const int axis)
|
||||
|
@ -1058,6 +1066,10 @@ void ED_gpencil_project_stroke_to_plane(const Scene *scene,
|
|||
float ray[3];
|
||||
float rpoint[3];
|
||||
|
||||
/* Recalculate layer transform matrix. */
|
||||
loc_eul_size_to_mat4(gpl->layer_mat, gpl->location, gpl->rotation, gpl->scale);
|
||||
invert_m4_m4(gpl->layer_invmat, gpl->layer_mat);
|
||||
|
||||
/* normal vector for a plane locked to axis */
|
||||
zero_v3(plane_normal);
|
||||
if (axis < 0) {
|
||||
|
@ -1074,24 +1086,27 @@ void ED_gpencil_project_stroke_to_plane(const Scene *scene,
|
|||
copy_m4_m4(mat, ob->obmat);
|
||||
|
||||
/* move origin to cursor */
|
||||
if ((ts->gpencil_v3d_align & GP_PROJECT_CURSOR) == 0) {
|
||||
if (gpl != NULL) {
|
||||
add_v3_v3(mat[3], gpl->location);
|
||||
}
|
||||
}
|
||||
if (ts->gpencil_v3d_align & GP_PROJECT_CURSOR) {
|
||||
copy_v3_v3(mat[3], cursor->location);
|
||||
}
|
||||
|
||||
mul_mat3_m4_v3(mat, plane_normal);
|
||||
}
|
||||
|
||||
if ((gpl != NULL) && (ts->gp_sculpt.lock_axis != GP_LOCKAXIS_CURSOR)) {
|
||||
mul_mat3_m4_v3(gpl->layer_mat, plane_normal);
|
||||
}
|
||||
}
|
||||
else {
|
||||
const float scale[3] = {1.0f, 1.0f, 1.0f};
|
||||
plane_normal[2] = 1.0f;
|
||||
float mat[4][4];
|
||||
loc_eul_size_to_mat4(mat, cursor->location, cursor->rotation_euler, scale);
|
||||
|
||||
/* move origin to object */
|
||||
if ((ts->gpencil_v3d_align & GP_PROJECT_CURSOR) == 0) {
|
||||
copy_v3_v3(mat[3], ob->obmat[3]);
|
||||
}
|
||||
|
||||
mul_mat3_m4_v3(mat, plane_normal);
|
||||
}
|
||||
|
||||
|
@ -1127,8 +1142,12 @@ void ED_gpencil_stroke_reproject(Depsgraph *depsgraph,
|
|||
ARegion *region = gsc->region;
|
||||
RegionView3D *rv3d = region->regiondata;
|
||||
|
||||
/* Recalculate layer transform matrix. */
|
||||
loc_eul_size_to_mat4(gpl->layer_mat, gpl->location, gpl->rotation, gpl->scale);
|
||||
invert_m4_m4(gpl->layer_invmat, gpl->layer_mat);
|
||||
|
||||
float diff_mat[4][4], inverse_diff_mat[4][4];
|
||||
BKE_gpencil_parent_matrix_get(depsgraph, gsc->ob, gpl, diff_mat);
|
||||
BKE_gpencil_layer_transform_matrix_get(depsgraph, gsc->ob, gpl, diff_mat);
|
||||
invert_m4_m4(inverse_diff_mat, diff_mat);
|
||||
|
||||
float origin[3];
|
||||
|
@ -1194,7 +1213,7 @@ void ED_gpencil_stroke_reproject(Depsgraph *depsgraph,
|
|||
}
|
||||
}
|
||||
|
||||
ED_gpencil_project_point_to_plane(gsc->scene, gsc->ob, rv3d, origin, axis, &pt2);
|
||||
ED_gpencil_project_point_to_plane(gsc->scene, gsc->ob, gpl, rv3d, origin, axis, &pt2);
|
||||
|
||||
copy_v3_v3(&pt->x, &pt2.x);
|
||||
|
||||
|
@ -1250,6 +1269,7 @@ void ED_gpencil_stroke_reproject(Depsgraph *depsgraph,
|
|||
*/
|
||||
void ED_gpencil_project_point_to_plane(const Scene *scene,
|
||||
const Object *ob,
|
||||
bGPDlayer *gpl,
|
||||
const RegionView3D *rv3d,
|
||||
const float origin[3],
|
||||
const int axis,
|
||||
|
@ -1277,6 +1297,11 @@ void ED_gpencil_project_point_to_plane(const Scene *scene,
|
|||
if (ob && (ob->type == OB_GPENCIL)) {
|
||||
float mat[4][4];
|
||||
copy_m4_m4(mat, ob->obmat);
|
||||
if ((ts->gpencil_v3d_align & GP_PROJECT_CURSOR) == 0) {
|
||||
if (gpl != NULL) {
|
||||
add_v3_v3(mat[3], gpl->location);
|
||||
}
|
||||
}
|
||||
|
||||
/* move origin to cursor */
|
||||
if (ts->gpencil_v3d_align & GP_PROJECT_CURSOR) {
|
||||
|
@ -1284,6 +1309,10 @@ void ED_gpencil_project_point_to_plane(const Scene *scene,
|
|||
}
|
||||
|
||||
mul_mat3_m4_v3(mat, plane_normal);
|
||||
/* Apply layer rotation (local transform). */
|
||||
if ((gpl != NULL) && (ts->gp_sculpt.lock_axis != GP_LOCKAXIS_CURSOR)) {
|
||||
mul_mat3_m4_v3(gpl->layer_mat, plane_normal);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -1449,7 +1478,7 @@ void ED_gpencil_reset_layers_parent(Depsgraph *depsgraph, Object *obact, bGPdata
|
|||
/* only redo if any change */
|
||||
if (!equals_m4m4(gpl->inverse, cur_mat)) {
|
||||
/* first apply current transformation to all strokes */
|
||||
BKE_gpencil_parent_matrix_get(depsgraph, obact, gpl, diff_mat);
|
||||
BKE_gpencil_layer_transform_matrix_get(depsgraph, obact, gpl, diff_mat);
|
||||
/* undo local object */
|
||||
sub_v3_v3(diff_mat[3], gpl_loc);
|
||||
|
||||
|
@ -3126,7 +3155,7 @@ bGPDstroke *ED_gpencil_stroke_nearest_to_ends(bContext *C,
|
|||
|
||||
/* calculate difference matrix object */
|
||||
float diff_mat[4][4];
|
||||
BKE_gpencil_parent_matrix_get(depsgraph, ob, gpl, diff_mat);
|
||||
BKE_gpencil_layer_transform_matrix_get(depsgraph, ob, gpl, diff_mat);
|
||||
|
||||
/* Calculate the extremes of the stroke in 2D. */
|
||||
bGPDspoint pt_parent;
|
||||
|
|
|
@ -825,7 +825,8 @@ static void gpencil_save_selected_point(tGP_BrushVertexpaintData *gso,
|
|||
static bool gpencil_vertexpaint_select_stroke(tGP_BrushVertexpaintData *gso,
|
||||
bGPDstroke *gps,
|
||||
const char tool,
|
||||
const float diff_mat[4][4])
|
||||
const float diff_mat[4][4],
|
||||
const float bound_mat[4][4])
|
||||
{
|
||||
GP_SpaceConversion *gsc = &gso->gsc;
|
||||
rcti *rect = &gso->brush_rect;
|
||||
|
@ -846,7 +847,7 @@ static bool gpencil_vertexpaint_select_stroke(tGP_BrushVertexpaintData *gso,
|
|||
bool saved = false;
|
||||
|
||||
/* Check if the stroke collide with brush. */
|
||||
if (!ED_gpencil_stroke_check_collision(gsc, gps, gso->mval, radius, diff_mat)) {
|
||||
if (!ED_gpencil_stroke_check_collision(gsc, gps, gso->mval, radius, bound_mat)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -991,7 +992,8 @@ static bool gpencil_vertexpaint_brush_do_frame(bContext *C,
|
|||
tGP_BrushVertexpaintData *gso,
|
||||
bGPDlayer *gpl,
|
||||
bGPDframe *gpf,
|
||||
const float diff_mat[4][4])
|
||||
const float diff_mat[4][4],
|
||||
const float bound_mat[4][4])
|
||||
{
|
||||
Object *ob = CTX_data_active_object(C);
|
||||
const char tool = ob->mode == OB_MODE_VERTEX_GPENCIL ? gso->brush->gpencil_vertex_tool :
|
||||
|
@ -1018,7 +1020,7 @@ static bool gpencil_vertexpaint_brush_do_frame(bContext *C,
|
|||
}
|
||||
|
||||
/* Check points below the brush. */
|
||||
bool hit = gpencil_vertexpaint_select_stroke(gso, gps, tool, diff_mat);
|
||||
bool hit = gpencil_vertexpaint_select_stroke(gso, gps, tool, diff_mat, bound_mat);
|
||||
|
||||
/* If stroke was hit and has an editcurve the curve needs an update. */
|
||||
bGPDstroke *gps_active = (gps->runtime.gps_orig) ? gps->runtime.gps_orig : gps;
|
||||
|
@ -1123,9 +1125,11 @@ static bool gpencil_vertexpaint_brush_apply_to_layers(bContext *C, tGP_BrushVert
|
|||
continue;
|
||||
}
|
||||
|
||||
/* calculate difference matrix */
|
||||
float diff_mat[4][4];
|
||||
BKE_gpencil_parent_matrix_get(depsgraph, obact, gpl, diff_mat);
|
||||
/* Calculate transform matrix. */
|
||||
float diff_mat[4][4], bound_mat[4][4];
|
||||
BKE_gpencil_layer_transform_matrix_get(depsgraph, obact, gpl, diff_mat);
|
||||
copy_m4_m4(bound_mat, diff_mat);
|
||||
mul_m4_m4m4(diff_mat, diff_mat, gpl->layer_invmat);
|
||||
|
||||
/* Active Frame or MultiFrame? */
|
||||
if (gso->is_multiframe) {
|
||||
|
@ -1152,7 +1156,7 @@ static bool gpencil_vertexpaint_brush_apply_to_layers(bContext *C, tGP_BrushVert
|
|||
}
|
||||
|
||||
/* affect strokes in this frame */
|
||||
changed |= gpencil_vertexpaint_brush_do_frame(C, gso, gpl, gpf, diff_mat);
|
||||
changed |= gpencil_vertexpaint_brush_do_frame(C, gso, gpl, gpf, diff_mat, bound_mat);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1160,7 +1164,8 @@ static bool gpencil_vertexpaint_brush_apply_to_layers(bContext *C, tGP_BrushVert
|
|||
/* Apply to active frame's strokes */
|
||||
if (gpl->actframe != NULL) {
|
||||
gso->mf_falloff = 1.0f;
|
||||
changed |= gpencil_vertexpaint_brush_do_frame(C, gso, gpl, gpl->actframe, diff_mat);
|
||||
changed |= gpencil_vertexpaint_brush_do_frame(
|
||||
C, gso, gpl, gpl->actframe, diff_mat, bound_mat);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -383,7 +383,8 @@ static void gpencil_save_selected_point(tGP_BrushWeightpaintData *gso,
|
|||
/* Select points in this stroke and add to an array to be used later. */
|
||||
static void gpencil_weightpaint_select_stroke(tGP_BrushWeightpaintData *gso,
|
||||
bGPDstroke *gps,
|
||||
const float diff_mat[4][4])
|
||||
const float diff_mat[4][4],
|
||||
const float bound_mat[4][4])
|
||||
{
|
||||
GP_SpaceConversion *gsc = &gso->gsc;
|
||||
rcti *rect = &gso->brush_rect;
|
||||
|
@ -402,7 +403,7 @@ static void gpencil_weightpaint_select_stroke(tGP_BrushWeightpaintData *gso,
|
|||
bool include_last = false;
|
||||
|
||||
/* Check if the stroke collide with brush. */
|
||||
if (!ED_gpencil_stroke_check_collision(gsc, gps, gso->mval, radius, diff_mat)) {
|
||||
if (!ED_gpencil_stroke_check_collision(gsc, gps, gso->mval, radius, bound_mat)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -505,7 +506,8 @@ static bool gpencil_weightpaint_brush_do_frame(bContext *C,
|
|||
tGP_BrushWeightpaintData *gso,
|
||||
bGPDlayer *gpl,
|
||||
bGPDframe *gpf,
|
||||
const float diff_mat[4][4])
|
||||
const float diff_mat[4][4],
|
||||
const float bound_mat[4][4])
|
||||
{
|
||||
Object *ob = CTX_data_active_object(C);
|
||||
char tool = gso->brush->gpencil_weight_tool;
|
||||
|
@ -531,7 +533,7 @@ static bool gpencil_weightpaint_brush_do_frame(bContext *C,
|
|||
}
|
||||
|
||||
/* Check points below the brush. */
|
||||
gpencil_weightpaint_select_stroke(gso, gps, diff_mat);
|
||||
gpencil_weightpaint_select_stroke(gso, gps, diff_mat, bound_mat);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------
|
||||
|
@ -578,9 +580,11 @@ static bool gpencil_weightpaint_brush_apply_to_layers(bContext *C, tGP_BrushWeig
|
|||
continue;
|
||||
}
|
||||
|
||||
/* calculate difference matrix */
|
||||
float diff_mat[4][4];
|
||||
BKE_gpencil_parent_matrix_get(depsgraph, obact, gpl, diff_mat);
|
||||
/* Calculate transform matrix. */
|
||||
float diff_mat[4][4], bound_mat[4][4];
|
||||
BKE_gpencil_layer_transform_matrix_get(depsgraph, obact, gpl, diff_mat);
|
||||
copy_m4_m4(bound_mat, diff_mat);
|
||||
mul_m4_m4m4(diff_mat, diff_mat, gpl->layer_invmat);
|
||||
|
||||
/* Active Frame or MultiFrame? */
|
||||
if (gso->is_multiframe) {
|
||||
|
@ -608,7 +612,7 @@ static bool gpencil_weightpaint_brush_apply_to_layers(bContext *C, tGP_BrushWeig
|
|||
}
|
||||
|
||||
/* affect strokes in this frame */
|
||||
changed |= gpencil_weightpaint_brush_do_frame(C, gso, gpl, gpf, diff_mat);
|
||||
changed |= gpencil_weightpaint_brush_do_frame(C, gso, gpl, gpf, diff_mat, bound_mat);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -616,7 +620,8 @@ static bool gpencil_weightpaint_brush_apply_to_layers(bContext *C, tGP_BrushWeig
|
|||
if (gpl->actframe != NULL) {
|
||||
/* Apply to active frame's strokes */
|
||||
gso->mf_falloff = 1.0f;
|
||||
changed |= gpencil_weightpaint_brush_do_frame(C, gso, gpl, gpl->actframe, diff_mat);
|
||||
changed |= gpencil_weightpaint_brush_do_frame(
|
||||
C, gso, gpl, gpl->actframe, diff_mat, bound_mat);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -263,11 +263,13 @@ bool ED_object_gpencil_exit(struct Main *bmain, struct Object *ob);
|
|||
void ED_gpencil_project_stroke_to_plane(const struct Scene *scene,
|
||||
const struct Object *ob,
|
||||
const struct RegionView3D *rv3d,
|
||||
struct bGPDlayer *gpl,
|
||||
struct bGPDstroke *gps,
|
||||
const float origin[3],
|
||||
const int axis);
|
||||
void ED_gpencil_project_point_to_plane(const struct Scene *scene,
|
||||
const struct Object *ob,
|
||||
struct bGPDlayer *gpl,
|
||||
const struct RegionView3D *rv3d,
|
||||
const float origin[3],
|
||||
const int axis,
|
||||
|
|
|
@ -1394,7 +1394,7 @@ static int object_origin_set_exec(bContext *C, wmOperator *op)
|
|||
* (all layers are considered without evaluating lock attributes) */
|
||||
LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
|
||||
/* calculate difference matrix */
|
||||
BKE_gpencil_parent_matrix_get(depsgraph, obact, gpl, diff_mat);
|
||||
BKE_gpencil_layer_transform_matrix_get(depsgraph, obact, gpl, diff_mat);
|
||||
/* undo matrix */
|
||||
invert_m4_m4(inverse_diff_mat, diff_mat);
|
||||
LISTBASE_FOREACH (bGPDframe *, gpf, &gpl->frames) {
|
||||
|
|
|
@ -242,7 +242,7 @@ static void createTransGPencil_curves(bContext *C,
|
|||
}
|
||||
|
||||
/* Calculate difference matrix. */
|
||||
BKE_gpencil_parent_matrix_get(depsgraph, obact, gpl, diff_mat);
|
||||
BKE_gpencil_layer_transform_matrix_get(depsgraph, obact, gpl, diff_mat);
|
||||
copy_m3_m4(mtx, diff_mat);
|
||||
pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON);
|
||||
|
||||
|
@ -507,7 +507,7 @@ static void createTransGPencil_strokes(bContext *C,
|
|||
}
|
||||
|
||||
/* Calculate difference matrix. */
|
||||
BKE_gpencil_parent_matrix_get(depsgraph, obact, gpl, diff_mat);
|
||||
BKE_gpencil_layer_transform_matrix_get(depsgraph, obact, gpl, diff_mat);
|
||||
/* Undo matrix. */
|
||||
invert_m4_m4(inverse_diff_mat, diff_mat);
|
||||
|
||||
|
|
|
@ -704,7 +704,7 @@ int ED_transform_calc_gizmo_stats(const bContext *C,
|
|||
if (BKE_gpencil_layer_is_editable(gpl) && (gpl->actframe != NULL)) {
|
||||
|
||||
/* calculate difference matrix */
|
||||
BKE_gpencil_parent_matrix_get(depsgraph, ob, gpl, diff_mat);
|
||||
BKE_gpencil_layer_transform_matrix_get(depsgraph, ob, gpl, diff_mat);
|
||||
|
||||
LISTBASE_FOREACH (bGPDstroke *, gps, &gpl->actframe->strokes) {
|
||||
/* skip strokes that are invalid for current view */
|
||||
|
|
|
@ -512,6 +512,11 @@ typedef struct bGPDlayer {
|
|||
int act_mask;
|
||||
char _pad2[4];
|
||||
|
||||
/** Layer transforms. */
|
||||
float location[3], rotation[3], scale[3];
|
||||
float layer_mat[4][4], layer_invmat[4][4];
|
||||
char _pad3[4];
|
||||
|
||||
bGPDlayer_Runtime runtime;
|
||||
} bGPDlayer;
|
||||
|
||||
|
|
|
@ -182,6 +182,16 @@ static void rna_GPencil_update(Main *UNUSED(bmain), Scene *UNUSED(scene), Pointe
|
|||
WM_main_add_notifier(NC_GPENCIL | NA_EDITED, NULL);
|
||||
}
|
||||
|
||||
static void rna_GpencilLayerMatrix_update(Main *bmain, Scene *scene, PointerRNA *ptr)
|
||||
{
|
||||
bGPDlayer *gpl = (bGPDlayer *)ptr->data;
|
||||
|
||||
loc_eul_size_to_mat4(gpl->layer_mat, gpl->location, gpl->rotation, gpl->scale);
|
||||
invert_m4_m4(gpl->layer_invmat, gpl->layer_mat);
|
||||
|
||||
rna_GPencil_update(bmain, scene, ptr);
|
||||
}
|
||||
|
||||
static void rna_GPencil_curve_edit_mode_toggle(Main *bmain, Scene *scene, PointerRNA *ptr)
|
||||
{
|
||||
ToolSettings *ts = scene->toolsettings;
|
||||
|
@ -2012,6 +2022,45 @@ static void rna_def_gpencil_layer(BlenderRNA *brna)
|
|||
RNA_def_property_ui_text(prop, "Blend Mode", "Blend mode");
|
||||
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
|
||||
|
||||
/* Layer transforms. */
|
||||
prop = RNA_def_property(srna, "location", PROP_FLOAT, PROP_TRANSLATION);
|
||||
RNA_def_property_float_sdna(prop, NULL, "location");
|
||||
RNA_def_property_ui_text(prop, "Location", "Values for change location");
|
||||
RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 1, RNA_TRANSLATION_PREC_DEFAULT);
|
||||
RNA_def_property_update(prop, 0, "rna_GpencilLayerMatrix_update");
|
||||
|
||||
prop = RNA_def_property(srna, "rotation", PROP_FLOAT, PROP_EULER);
|
||||
RNA_def_property_float_sdna(prop, NULL, "rotation");
|
||||
RNA_def_property_ui_text(prop, "Rotation", "Values for changes in rotation");
|
||||
RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 1, RNA_TRANSLATION_PREC_DEFAULT);
|
||||
RNA_def_property_update(prop, 0, "rna_GpencilLayerMatrix_update");
|
||||
|
||||
prop = RNA_def_property(srna, "scale", PROP_FLOAT, PROP_XYZ);
|
||||
RNA_def_property_float_sdna(prop, NULL, "scale");
|
||||
RNA_def_property_float_default(prop, 1.0f);
|
||||
RNA_def_property_ui_text(prop, "Scale", "Values for changes in scale");
|
||||
RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 1, RNA_TRANSLATION_PREC_DEFAULT);
|
||||
RNA_def_property_update(prop, 0, "rna_GpencilLayerMatrix_update");
|
||||
|
||||
/* Layer matrix. */
|
||||
prop = RNA_def_property(srna, "matrix_layer", PROP_FLOAT, PROP_MATRIX);
|
||||
RNA_def_property_float_sdna(prop, NULL, "layer_mat");
|
||||
RNA_def_property_multi_array(prop, 2, rna_matrix_dimsize_4x4);
|
||||
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_override_flag(prop, PROPOVERRIDE_NO_COMPARISON);
|
||||
RNA_def_property_override_clear_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY);
|
||||
RNA_def_property_ui_text(prop, "Matrix Layer", "Local Layer transformation matrix");
|
||||
|
||||
/* Layer inverse matrix. */
|
||||
prop = RNA_def_property(srna, "matrix_inverse_layer", PROP_FLOAT, PROP_MATRIX);
|
||||
RNA_def_property_float_sdna(prop, NULL, "layer_invmat");
|
||||
RNA_def_property_multi_array(prop, 2, rna_matrix_dimsize_4x4);
|
||||
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_override_flag(prop, PROPOVERRIDE_NO_COMPARISON);
|
||||
RNA_def_property_override_clear_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY);
|
||||
RNA_def_property_ui_text(
|
||||
prop, "Matrix Layer Inverse", "Local Layer transformation inverse matrix");
|
||||
|
||||
/* Flags */
|
||||
prop = RNA_def_property(srna, "hide", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_LAYER_HIDE);
|
||||
|
|
Loading…
Reference in New Issue