Cleanup: Remove unused GP V2 transform, curve edit code
See #123468. Pull Request: https://projects.blender.org/blender/blender/pulls/129731
This commit is contained in:
@@ -1,44 +0,0 @@
|
||||
/* SPDX-FileCopyrightText: 2008 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#pragma once
|
||||
|
||||
/** \file
|
||||
* \ingroup bke
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct Main;
|
||||
struct Object;
|
||||
struct Scene;
|
||||
struct bGPDcurve;
|
||||
struct bGPDlayer;
|
||||
struct bGPDstroke;
|
||||
struct bGPdata;
|
||||
|
||||
/**
|
||||
* Creates a bGPDcurve by doing a cubic curve fitting on the grease pencil stroke points.
|
||||
*/
|
||||
struct bGPDcurve *BKE_gpencil_stroke_editcurve_generate(struct bGPDstroke *gps,
|
||||
float error_threshold,
|
||||
float corner_angle,
|
||||
float stroke_radius);
|
||||
/**
|
||||
* Sync the selection from stroke to edit-curve.
|
||||
*/
|
||||
void BKE_gpencil_editcurve_stroke_sync_selection(struct bGPdata *gpd,
|
||||
struct bGPDstroke *gps,
|
||||
struct bGPDcurve *gpc);
|
||||
/**
|
||||
* Recalculate the handles of the edit curve of a grease pencil stroke.
|
||||
*/
|
||||
void BKE_gpencil_editcurve_recalculate_handles(struct bGPDstroke *gps);
|
||||
void BKE_gpencil_editcurve_subdivide(struct bGPDstroke *gps, int cuts);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -313,26 +313,6 @@ void BKE_gpencil_brush_material_set(struct Brush *brush, struct Material *materi
|
||||
*/
|
||||
void BKE_gpencil_stroke_weights_duplicate(struct bGPDstroke *gps_src, struct bGPDstroke *gps_dst);
|
||||
|
||||
/**
|
||||
* Get range of selected frames in layer.
|
||||
* Always the active frame is considered as selected, so if no more selected the range
|
||||
* will be equal to the current active frame.
|
||||
* \param gpl: Layer.
|
||||
* \param r_initframe: Number of first selected frame.
|
||||
* \param r_endframe: Number of last selected frame.
|
||||
*/
|
||||
void BKE_gpencil_frame_range_selected(struct bGPDlayer *gpl, int *r_initframe, int *r_endframe);
|
||||
/**
|
||||
* Get Falloff factor base on frame range
|
||||
* \param gpf: Frame.
|
||||
* \param actnum: Number of active frame in layer.
|
||||
* \param f_init: Number of first selected frame.
|
||||
* \param f_end: Number of last selected frame.
|
||||
* \param cur_falloff: Curve with falloff factors.
|
||||
*/
|
||||
float BKE_gpencil_multiframe_falloff_calc(
|
||||
struct bGPDframe *gpf, int actnum, int f_init, int f_end, struct CurveMapping *cur_falloff);
|
||||
|
||||
/**
|
||||
* Create a default palette.
|
||||
* \param bmain: Main pointer
|
||||
|
||||
@@ -144,7 +144,6 @@ set(SRC
|
||||
intern/geometry_fields.cc
|
||||
intern/geometry_set.cc
|
||||
intern/geometry_set_instances.cc
|
||||
intern/gpencil_curve_legacy.cc
|
||||
intern/gpencil_geom_legacy.cc
|
||||
intern/gpencil_legacy.cc
|
||||
intern/gpencil_modifier_legacy.cc
|
||||
@@ -405,7 +404,6 @@ set(SRC
|
||||
BKE_geometry_set.hh
|
||||
BKE_geometry_set_instances.hh
|
||||
BKE_global.hh
|
||||
BKE_gpencil_curve_legacy.h
|
||||
BKE_gpencil_geom_legacy.h
|
||||
BKE_gpencil_legacy.h
|
||||
BKE_gpencil_modifier_legacy.h
|
||||
|
||||
@@ -1,483 +0,0 @@
|
||||
/* SPDX-FileCopyrightText: 2008 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup bke
|
||||
*/
|
||||
|
||||
#include <cmath>
|
||||
#include <cstddef>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "BLI_math_color.h"
|
||||
#include "BLI_math_vector.h"
|
||||
|
||||
#include "BLT_translation.hh"
|
||||
|
||||
#include "DNA_collection_types.h"
|
||||
#include "DNA_gpencil_legacy_types.h"
|
||||
#include "DNA_material_types.h"
|
||||
#include "DNA_meshdata_types.h"
|
||||
#include "DNA_scene_types.h"
|
||||
|
||||
#include "BKE_collection.hh"
|
||||
#include "BKE_curve.hh"
|
||||
#include "BKE_gpencil_curve_legacy.h"
|
||||
#include "BKE_gpencil_geom_legacy.h"
|
||||
#include "BKE_gpencil_legacy.h"
|
||||
#include "BKE_material.h"
|
||||
|
||||
extern "C" {
|
||||
#include "curve_fit_nd.h"
|
||||
}
|
||||
|
||||
#include "DEG_depsgraph_query.hh"
|
||||
|
||||
#define COORD_FITTING_INFLUENCE 20.0f
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Convert to curve object
|
||||
* \{ */
|
||||
|
||||
static void gpencil_editstroke_deselect_all(bGPDcurve *gpc)
|
||||
{
|
||||
for (int i = 0; i < gpc->tot_curve_points; i++) {
|
||||
bGPDcurve_point *gpc_pt = &gpc->curve_points[i];
|
||||
BezTriple *bezt = &gpc_pt->bezt;
|
||||
gpc_pt->flag &= ~GP_CURVE_POINT_SELECT;
|
||||
BEZT_DESEL_ALL(bezt);
|
||||
}
|
||||
gpc->flag &= ~GP_CURVE_SELECT;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Edit-Curve Kernel Functions
|
||||
* \{ */
|
||||
|
||||
static bGPDcurve *gpencil_stroke_editcurve_generate_edgecases(bGPDstroke *gps,
|
||||
const float stroke_radius)
|
||||
{
|
||||
BLI_assert(gps->totpoints < 3);
|
||||
|
||||
if (gps->totpoints == 1) {
|
||||
bGPDcurve *editcurve = BKE_gpencil_stroke_editcurve_new(1);
|
||||
bGPDspoint *pt = &gps->points[0];
|
||||
bGPDcurve_point *cpt = &editcurve->curve_points[0];
|
||||
BezTriple *bezt = &cpt->bezt;
|
||||
|
||||
/* Handles are twice as long as the radius of the point. */
|
||||
float offset = (pt->pressure * stroke_radius) * 2.0f;
|
||||
|
||||
float tmp_vec[3];
|
||||
for (int j = 0; j < 3; j++) {
|
||||
copy_v3_v3(tmp_vec, &pt->x);
|
||||
/* Move handles along the x-axis away from the control point */
|
||||
tmp_vec[0] += float(j - 1) * offset;
|
||||
copy_v3_v3(bezt->vec[j], tmp_vec);
|
||||
}
|
||||
|
||||
cpt->pressure = pt->pressure;
|
||||
cpt->strength = pt->strength;
|
||||
copy_v4_v4(cpt->vert_color, pt->vert_color);
|
||||
|
||||
/* default handle type */
|
||||
bezt->h1 = HD_FREE;
|
||||
bezt->h2 = HD_FREE;
|
||||
|
||||
cpt->point_index = 0;
|
||||
|
||||
return editcurve;
|
||||
}
|
||||
if (gps->totpoints == 2) {
|
||||
bGPDcurve *editcurve = BKE_gpencil_stroke_editcurve_new(2);
|
||||
bGPDspoint *first_pt = &gps->points[0];
|
||||
bGPDspoint *last_pt = &gps->points[1];
|
||||
|
||||
float length = len_v3v3(&first_pt->x, &last_pt->x);
|
||||
float offset = length / 3;
|
||||
float dir[3];
|
||||
sub_v3_v3v3(dir, &last_pt->x, &first_pt->x);
|
||||
|
||||
for (int i = 0; i < 2; i++) {
|
||||
bGPDspoint *pt = &gps->points[i];
|
||||
bGPDcurve_point *cpt = &editcurve->curve_points[i];
|
||||
BezTriple *bezt = &cpt->bezt;
|
||||
|
||||
float tmp_vec[3];
|
||||
for (int j = 0; j < 3; j++) {
|
||||
copy_v3_v3(tmp_vec, dir);
|
||||
normalize_v3_length(tmp_vec, float(j - 1) * offset);
|
||||
add_v3_v3v3(bezt->vec[j], &pt->x, tmp_vec);
|
||||
}
|
||||
|
||||
cpt->pressure = pt->pressure;
|
||||
cpt->strength = pt->strength;
|
||||
copy_v4_v4(cpt->vert_color, pt->vert_color);
|
||||
|
||||
/* default handle type */
|
||||
bezt->h1 = HD_VECT;
|
||||
bezt->h2 = HD_VECT;
|
||||
|
||||
cpt->point_index = 0;
|
||||
}
|
||||
|
||||
return editcurve;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bGPDcurve *BKE_gpencil_stroke_editcurve_generate(bGPDstroke *gps,
|
||||
const float error_threshold,
|
||||
const float corner_angle,
|
||||
const float stroke_radius)
|
||||
{
|
||||
if (gps->totpoints < 3) {
|
||||
return gpencil_stroke_editcurve_generate_edgecases(gps, stroke_radius);
|
||||
}
|
||||
#define POINT_DIM 9
|
||||
|
||||
float *points = static_cast<float *>(
|
||||
MEM_callocN(sizeof(float) * gps->totpoints * POINT_DIM, __func__));
|
||||
float diag_length = len_v3v3(gps->boundbox_min, gps->boundbox_max);
|
||||
float tmp_vec[3];
|
||||
|
||||
for (int i = 0; i < gps->totpoints; i++) {
|
||||
bGPDspoint *pt = &gps->points[i];
|
||||
int row = i * POINT_DIM;
|
||||
|
||||
/* normalize coordinate to 0..1 */
|
||||
sub_v3_v3v3(tmp_vec, &pt->x, gps->boundbox_min);
|
||||
mul_v3_v3fl(&points[row], tmp_vec, COORD_FITTING_INFLUENCE / diag_length);
|
||||
points[row + 3] = pt->pressure / diag_length;
|
||||
|
||||
/* strength and color are already normalized */
|
||||
points[row + 4] = pt->strength / diag_length;
|
||||
mul_v4_v4fl(&points[row + 5], pt->vert_color, 1.0f / diag_length);
|
||||
}
|
||||
|
||||
uint calc_flag = CURVE_FIT_CALC_HIGH_QUALIY;
|
||||
if (gps->totpoints > 2 && gps->flag & GP_STROKE_CYCLIC) {
|
||||
calc_flag |= CURVE_FIT_CALC_CYCLIC;
|
||||
}
|
||||
|
||||
float *r_cubic_array = nullptr;
|
||||
uint r_cubic_array_len = 0;
|
||||
uint *r_cubic_orig_index = nullptr;
|
||||
uint *r_corners_index_array = nullptr;
|
||||
uint r_corners_index_len = 0;
|
||||
int r = curve_fit_cubic_to_points_refit_fl(points,
|
||||
gps->totpoints,
|
||||
POINT_DIM,
|
||||
error_threshold,
|
||||
calc_flag,
|
||||
nullptr,
|
||||
0,
|
||||
corner_angle,
|
||||
&r_cubic_array,
|
||||
&r_cubic_array_len,
|
||||
&r_cubic_orig_index,
|
||||
&r_corners_index_array,
|
||||
&r_corners_index_len);
|
||||
|
||||
if (r != 0 || r_cubic_array_len < 1) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
uint curve_point_size = 3 * POINT_DIM;
|
||||
|
||||
bGPDcurve *editcurve = BKE_gpencil_stroke_editcurve_new(r_cubic_array_len);
|
||||
|
||||
for (int i = 0; i < r_cubic_array_len; i++) {
|
||||
bGPDcurve_point *cpt = &editcurve->curve_points[i];
|
||||
BezTriple *bezt = &cpt->bezt;
|
||||
float *curve_point = &r_cubic_array[i * curve_point_size];
|
||||
|
||||
for (int j = 0; j < 3; j++) {
|
||||
float *bez = &curve_point[j * POINT_DIM];
|
||||
madd_v3_v3v3fl(bezt->vec[j], gps->boundbox_min, bez, diag_length / COORD_FITTING_INFLUENCE);
|
||||
}
|
||||
|
||||
float *ctrl_point = &curve_point[1 * POINT_DIM];
|
||||
cpt->pressure = ctrl_point[3] * diag_length;
|
||||
cpt->strength = ctrl_point[4] * diag_length;
|
||||
mul_v4_v4fl(cpt->vert_color, &ctrl_point[5], diag_length);
|
||||
|
||||
/* default handle type */
|
||||
bezt->h1 = HD_ALIGN;
|
||||
bezt->h2 = HD_ALIGN;
|
||||
|
||||
cpt->point_index = r_cubic_orig_index[i];
|
||||
}
|
||||
|
||||
if (r_corners_index_len > 0 && r_corners_index_array != nullptr) {
|
||||
int start = 0, end = r_corners_index_len;
|
||||
if ((r_corners_index_len > 1) && (calc_flag & CURVE_FIT_CALC_CYCLIC) == 0) {
|
||||
start = 1;
|
||||
end = r_corners_index_len - 1;
|
||||
}
|
||||
for (int i = start; i < end; i++) {
|
||||
bGPDcurve_point *cpt = &editcurve->curve_points[r_corners_index_array[i]];
|
||||
BezTriple *bezt = &cpt->bezt;
|
||||
bezt->h1 = HD_FREE;
|
||||
bezt->h2 = HD_FREE;
|
||||
}
|
||||
}
|
||||
|
||||
MEM_freeN(points);
|
||||
if (r_cubic_array) {
|
||||
free(r_cubic_array);
|
||||
}
|
||||
if (r_corners_index_array) {
|
||||
free(r_corners_index_array);
|
||||
}
|
||||
if (r_cubic_orig_index) {
|
||||
free(r_cubic_orig_index);
|
||||
}
|
||||
|
||||
#undef POINT_DIM
|
||||
return editcurve;
|
||||
}
|
||||
|
||||
void BKE_gpencil_editcurve_stroke_sync_selection(bGPdata * /*gpd*/,
|
||||
bGPDstroke *gps,
|
||||
bGPDcurve *gpc)
|
||||
{
|
||||
if (gps->flag & GP_STROKE_SELECT) {
|
||||
gpc->flag |= GP_CURVE_SELECT;
|
||||
|
||||
for (int i = 0; i < gpc->tot_curve_points; i++) {
|
||||
bGPDcurve_point *gpc_pt = &gpc->curve_points[i];
|
||||
bGPDspoint *pt = &gps->points[gpc_pt->point_index];
|
||||
if (pt->flag & GP_SPOINT_SELECT) {
|
||||
gpc_pt->flag |= GP_CURVE_POINT_SELECT;
|
||||
BEZT_SEL_ALL(&gpc_pt->bezt);
|
||||
}
|
||||
else {
|
||||
gpc_pt->flag &= ~GP_CURVE_POINT_SELECT;
|
||||
BEZT_DESEL_ALL(&gpc_pt->bezt);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
gpc->flag &= ~GP_CURVE_SELECT;
|
||||
gpencil_editstroke_deselect_all(gpc);
|
||||
}
|
||||
}
|
||||
|
||||
void BKE_gpencil_editcurve_recalculate_handles(bGPDstroke *gps)
|
||||
{
|
||||
if (gps == nullptr || gps->editcurve == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool changed = false;
|
||||
bGPDcurve *gpc = gps->editcurve;
|
||||
if (gpc->tot_curve_points < 2) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (gpc->tot_curve_points == 1) {
|
||||
BKE_nurb_handle_calc(
|
||||
&(gpc->curve_points[0].bezt), nullptr, &(gpc->curve_points[0].bezt), false, 0);
|
||||
gps->flag |= GP_STROKE_NEEDS_CURVE_UPDATE;
|
||||
}
|
||||
|
||||
for (int i = 1; i < gpc->tot_curve_points - 1; i++) {
|
||||
bGPDcurve_point *gpc_pt = &gpc->curve_points[i];
|
||||
bGPDcurve_point *gpc_pt_prev = &gpc->curve_points[i - 1];
|
||||
bGPDcurve_point *gpc_pt_next = &gpc->curve_points[i + 1];
|
||||
/* update handle if point or neighbor is selected */
|
||||
if (gpc_pt->flag & GP_CURVE_POINT_SELECT || gpc_pt_prev->flag & GP_CURVE_POINT_SELECT ||
|
||||
gpc_pt_next->flag & GP_CURVE_POINT_SELECT)
|
||||
{
|
||||
BezTriple *bezt = &gpc_pt->bezt;
|
||||
BezTriple *bezt_prev = &gpc_pt_prev->bezt;
|
||||
BezTriple *bezt_next = &gpc_pt_next->bezt;
|
||||
|
||||
BKE_nurb_handle_calc(bezt, bezt_prev, bezt_next, false, 0);
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
bGPDcurve_point *gpc_first = &gpc->curve_points[0];
|
||||
bGPDcurve_point *gpc_last = &gpc->curve_points[gpc->tot_curve_points - 1];
|
||||
bGPDcurve_point *gpc_first_next = &gpc->curve_points[1];
|
||||
bGPDcurve_point *gpc_last_prev = &gpc->curve_points[gpc->tot_curve_points - 2];
|
||||
if (gps->flag & GP_STROKE_CYCLIC) {
|
||||
if (gpc_first->flag & GP_CURVE_POINT_SELECT || gpc_last->flag & GP_CURVE_POINT_SELECT) {
|
||||
BezTriple *bezt_first = &gpc_first->bezt;
|
||||
BezTriple *bezt_last = &gpc_last->bezt;
|
||||
BezTriple *bezt_first_next = &gpc_first_next->bezt;
|
||||
BezTriple *bezt_last_prev = &gpc_last_prev->bezt;
|
||||
|
||||
BKE_nurb_handle_calc(bezt_first, bezt_last, bezt_first_next, false, 0);
|
||||
BKE_nurb_handle_calc(bezt_last, bezt_last_prev, bezt_first, false, 0);
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (gpc_first->flag & GP_CURVE_POINT_SELECT || gpc_last->flag & GP_CURVE_POINT_SELECT) {
|
||||
BezTriple *bezt_first = &gpc_first->bezt;
|
||||
BezTriple *bezt_last = &gpc_last->bezt;
|
||||
BezTriple *bezt_first_next = &gpc_first_next->bezt;
|
||||
BezTriple *bezt_last_prev = &gpc_last_prev->bezt;
|
||||
|
||||
BKE_nurb_handle_calc(bezt_first, nullptr, bezt_first_next, false, 0);
|
||||
BKE_nurb_handle_calc(bezt_last, bezt_last_prev, nullptr, false, 0);
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (changed) {
|
||||
gps->flag |= GP_STROKE_NEEDS_CURVE_UPDATE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Helper: count how many new curve points must be generated. */
|
||||
static int gpencil_editcurve_subdivide_count(bGPDcurve *gpc, bool is_cyclic)
|
||||
{
|
||||
int count = 0;
|
||||
for (int i = 0; i < gpc->tot_curve_points - 1; i++) {
|
||||
bGPDcurve_point *cpt = &gpc->curve_points[i];
|
||||
bGPDcurve_point *cpt_next = &gpc->curve_points[i + 1];
|
||||
|
||||
if (cpt->flag & GP_CURVE_POINT_SELECT && cpt_next->flag & GP_CURVE_POINT_SELECT) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
if (is_cyclic) {
|
||||
bGPDcurve_point *cpt = &gpc->curve_points[0];
|
||||
bGPDcurve_point *cpt_next = &gpc->curve_points[gpc->tot_curve_points - 1];
|
||||
|
||||
if (cpt->flag & GP_CURVE_POINT_SELECT && cpt_next->flag & GP_CURVE_POINT_SELECT) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static void gpencil_editcurve_subdivide_curve_segment(bGPDcurve_point *cpt_start,
|
||||
bGPDcurve_point *cpt_end,
|
||||
bGPDcurve_point *cpt_new)
|
||||
{
|
||||
BezTriple *bezt_start = &cpt_start->bezt;
|
||||
BezTriple *bezt_end = &cpt_end->bezt;
|
||||
BezTriple *bezt_new = &cpt_new->bezt;
|
||||
for (int axis = 0; axis < 3; axis++) {
|
||||
float p0, p1, p2, p3, m0, m1, q0, q1, b;
|
||||
p0 = bezt_start->vec[1][axis];
|
||||
p1 = bezt_start->vec[2][axis];
|
||||
p2 = bezt_end->vec[0][axis];
|
||||
p3 = bezt_end->vec[1][axis];
|
||||
|
||||
m0 = (p0 + p1) / 2;
|
||||
q0 = (p0 + 2 * p1 + p2) / 4;
|
||||
b = (p0 + 3 * p1 + 3 * p2 + p3) / 8;
|
||||
q1 = (p1 + 2 * p2 + p3) / 4;
|
||||
m1 = (p2 + p3) / 2;
|
||||
|
||||
bezt_new->vec[0][axis] = q0;
|
||||
bezt_new->vec[2][axis] = q1;
|
||||
bezt_new->vec[1][axis] = b;
|
||||
|
||||
bezt_start->vec[2][axis] = m0;
|
||||
bezt_end->vec[0][axis] = m1;
|
||||
}
|
||||
|
||||
cpt_new->pressure = interpf(cpt_end->pressure, cpt_start->pressure, 0.5f);
|
||||
cpt_new->strength = interpf(cpt_end->strength, cpt_start->strength, 0.5f);
|
||||
interp_v4_v4v4(cpt_new->vert_color, cpt_start->vert_color, cpt_end->vert_color, 0.5f);
|
||||
}
|
||||
|
||||
void BKE_gpencil_editcurve_subdivide(bGPDstroke *gps, const int cuts)
|
||||
{
|
||||
bGPDcurve *gpc = gps->editcurve;
|
||||
if (gpc == nullptr || gpc->tot_curve_points < 2) {
|
||||
return;
|
||||
}
|
||||
bool is_cyclic = gps->flag & GP_STROKE_CYCLIC;
|
||||
|
||||
/* repeat for number of cuts */
|
||||
for (int s = 0; s < cuts; s++) {
|
||||
int old_tot_curve_points = gpc->tot_curve_points;
|
||||
int new_num_curve_points = gpencil_editcurve_subdivide_count(gpc, is_cyclic);
|
||||
if (new_num_curve_points == 0) {
|
||||
break;
|
||||
}
|
||||
int new_tot_curve_points = old_tot_curve_points + new_num_curve_points;
|
||||
|
||||
bGPDcurve_point *temp_curve_points = (bGPDcurve_point *)MEM_callocN(
|
||||
sizeof(bGPDcurve_point) * new_tot_curve_points, __func__);
|
||||
|
||||
bool prev_subdivided = false;
|
||||
int j = 0;
|
||||
for (int i = 0; i < old_tot_curve_points - 1; i++, j++) {
|
||||
bGPDcurve_point *cpt = &gpc->curve_points[i];
|
||||
bGPDcurve_point *cpt_next = &gpc->curve_points[i + 1];
|
||||
|
||||
if (cpt->flag & GP_CURVE_POINT_SELECT && cpt_next->flag & GP_CURVE_POINT_SELECT) {
|
||||
bGPDcurve_point *cpt_new = &temp_curve_points[j + 1];
|
||||
gpencil_editcurve_subdivide_curve_segment(cpt, cpt_next, cpt_new);
|
||||
|
||||
memcpy(&temp_curve_points[j], cpt, sizeof(bGPDcurve_point));
|
||||
memcpy(&temp_curve_points[j + 2], cpt_next, sizeof(bGPDcurve_point));
|
||||
|
||||
cpt_new->flag |= GP_CURVE_POINT_SELECT;
|
||||
cpt_new->bezt.h1 = HD_ALIGN;
|
||||
cpt_new->bezt.h2 = HD_ALIGN;
|
||||
BEZT_SEL_ALL(&cpt_new->bezt);
|
||||
|
||||
prev_subdivided = true;
|
||||
j++;
|
||||
}
|
||||
else if (!prev_subdivided) {
|
||||
memcpy(&temp_curve_points[j], cpt, sizeof(bGPDcurve_point));
|
||||
prev_subdivided = false;
|
||||
}
|
||||
else {
|
||||
prev_subdivided = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (is_cyclic) {
|
||||
bGPDcurve_point *cpt = &gpc->curve_points[old_tot_curve_points - 1];
|
||||
bGPDcurve_point *cpt_next = &gpc->curve_points[0];
|
||||
|
||||
if (cpt->flag & GP_CURVE_POINT_SELECT && cpt_next->flag & GP_CURVE_POINT_SELECT) {
|
||||
bGPDcurve_point *cpt_new = &temp_curve_points[j + 1];
|
||||
gpencil_editcurve_subdivide_curve_segment(cpt, cpt_next, cpt_new);
|
||||
|
||||
memcpy(&temp_curve_points[j], cpt, sizeof(bGPDcurve_point));
|
||||
memcpy(&temp_curve_points[0], cpt_next, sizeof(bGPDcurve_point));
|
||||
|
||||
cpt_new->flag |= GP_CURVE_POINT_SELECT;
|
||||
cpt_new->bezt.h1 = HD_ALIGN;
|
||||
cpt_new->bezt.h2 = HD_ALIGN;
|
||||
BEZT_SEL_ALL(&cpt_new->bezt);
|
||||
}
|
||||
else if (!prev_subdivided) {
|
||||
memcpy(&temp_curve_points[j], cpt, sizeof(bGPDcurve_point));
|
||||
}
|
||||
}
|
||||
else {
|
||||
bGPDcurve_point *cpt = &gpc->curve_points[old_tot_curve_points - 1];
|
||||
memcpy(&temp_curve_points[j], cpt, sizeof(bGPDcurve_point));
|
||||
}
|
||||
|
||||
MEM_freeN(gpc->curve_points);
|
||||
gpc->curve_points = temp_curve_points;
|
||||
gpc->tot_curve_points = new_tot_curve_points;
|
||||
}
|
||||
}
|
||||
|
||||
/** \} */
|
||||
@@ -39,7 +39,6 @@
|
||||
|
||||
#include "BKE_attribute.hh"
|
||||
#include "BKE_deform.hh"
|
||||
#include "BKE_gpencil_curve_legacy.h"
|
||||
#include "BKE_gpencil_geom_legacy.h"
|
||||
#include "BKE_gpencil_legacy.h"
|
||||
#include "BKE_material.h"
|
||||
|
||||
@@ -1369,54 +1369,6 @@ void BKE_gpencil_brush_material_set(Brush *brush, Material *ma)
|
||||
}
|
||||
}
|
||||
|
||||
void BKE_gpencil_frame_range_selected(bGPDlayer *gpl, int *r_initframe, int *r_endframe)
|
||||
{
|
||||
*r_initframe = gpl->actframe->framenum;
|
||||
*r_endframe = gpl->actframe->framenum;
|
||||
|
||||
LISTBASE_FOREACH (bGPDframe *, gpf, &gpl->frames) {
|
||||
if (gpf->flag & GP_FRAME_SELECT) {
|
||||
if (gpf->framenum < *r_initframe) {
|
||||
*r_initframe = gpf->framenum;
|
||||
}
|
||||
if (gpf->framenum > *r_endframe) {
|
||||
*r_endframe = gpf->framenum;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
float BKE_gpencil_multiframe_falloff_calc(
|
||||
bGPDframe *gpf, int actnum, int f_init, int f_end, CurveMapping *cur_falloff)
|
||||
{
|
||||
float fnum = 0.5f; /* default mid curve */
|
||||
float value;
|
||||
|
||||
/* check curve is available */
|
||||
if (cur_falloff == nullptr) {
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
/* frames to the right of the active frame */
|
||||
if (gpf->framenum < actnum) {
|
||||
fnum = float(gpf->framenum - f_init) / (actnum - f_init);
|
||||
fnum *= 0.5f;
|
||||
value = BKE_curvemapping_evaluateF(cur_falloff, 0, fnum);
|
||||
}
|
||||
/* frames to the left of the active frame */
|
||||
else if (gpf->framenum > actnum) {
|
||||
fnum = float(gpf->framenum - actnum) / (f_end - actnum);
|
||||
fnum *= 0.5f;
|
||||
value = BKE_curvemapping_evaluateF(cur_falloff, 0, fnum + 0.5f);
|
||||
}
|
||||
else {
|
||||
/* Center of the curve. */
|
||||
value = BKE_curvemapping_evaluateF(cur_falloff, 0, 0.5f);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
void BKE_gpencil_palette_ensure(Main *bmain, Scene *scene)
|
||||
{
|
||||
const char *hexcol[] = {
|
||||
|
||||
@@ -39,7 +39,6 @@
|
||||
#include "BKE_context.hh"
|
||||
#include "BKE_deform.hh"
|
||||
#include "BKE_global.hh"
|
||||
#include "BKE_gpencil_curve_legacy.h"
|
||||
#include "BKE_gpencil_geom_legacy.h"
|
||||
#include "BKE_gpencil_legacy.h"
|
||||
#include "BKE_lib_id.hh"
|
||||
|
||||
@@ -43,7 +43,6 @@
|
||||
#include "BKE_colortools.hh"
|
||||
#include "BKE_context.hh"
|
||||
#include "BKE_deform.hh"
|
||||
#include "BKE_gpencil_curve_legacy.h"
|
||||
#include "BKE_gpencil_geom_legacy.h"
|
||||
#include "BKE_gpencil_legacy.h"
|
||||
#include "BKE_main.hh"
|
||||
@@ -303,29 +302,6 @@ bool ED_gpencil_stroke_can_use_direct(const ScrArea *area, const bGPDstroke *gps
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ED_gpencil_stroke_can_use(const bContext *C, const bGPDstroke *gps)
|
||||
{
|
||||
ScrArea *area = CTX_wm_area(C);
|
||||
return ED_gpencil_stroke_can_use_direct(area, gps);
|
||||
}
|
||||
|
||||
bool ED_gpencil_stroke_material_editable(Object *ob, const bGPDlayer *gpl, const bGPDstroke *gps)
|
||||
{
|
||||
/* check if the color is editable */
|
||||
MaterialGPencilStyle *gp_style = BKE_gpencil_material_settings(ob, gps->mat_nr + 1);
|
||||
|
||||
if (gp_style != nullptr) {
|
||||
if (gp_style->flag & GP_MATERIAL_HIDE) {
|
||||
return false;
|
||||
}
|
||||
if (((gpl->flag & GP_LAYER_UNLOCK_COLOR) == 0) && (gp_style->flag & GP_MATERIAL_LOCKED)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* ******************************************************** */
|
||||
/* Space Conversion */
|
||||
|
||||
|
||||
@@ -130,10 +130,6 @@ bool ED_gpencil_data_owner_is_annotation(PointerRNA *owner_ptr);
|
||||
* TODO: do we need additional flags for screen-space vs data-space?.
|
||||
*/
|
||||
bool ED_gpencil_stroke_can_use_direct(const ScrArea *area, const bGPDstroke *gps);
|
||||
/** Check whether given stroke can be edited in the current context */
|
||||
bool ED_gpencil_stroke_can_use(const bContext *C, const bGPDstroke *gps);
|
||||
/** Check whether given stroke can be edited for the current color */
|
||||
bool ED_gpencil_stroke_material_editable(Object *ob, const bGPDlayer *gpl, const bGPDstroke *gps);
|
||||
|
||||
/* ----------- Grease Pencil Operators ----------------- */
|
||||
|
||||
|
||||
@@ -64,7 +64,6 @@
|
||||
#include "BKE_effect.h"
|
||||
#include "BKE_geometry_set.hh"
|
||||
#include "BKE_geometry_set_instances.hh"
|
||||
#include "BKE_gpencil_curve_legacy.h"
|
||||
#include "BKE_gpencil_geom_legacy.h"
|
||||
#include "BKE_gpencil_legacy.h"
|
||||
#include "BKE_gpencil_modifier_legacy.h"
|
||||
|
||||
@@ -28,7 +28,6 @@ set(SRC
|
||||
transform_convert_cursor.cc
|
||||
transform_convert_curve.cc
|
||||
transform_convert_curves.cc
|
||||
transform_convert_gpencil_legacy.cc
|
||||
transform_convert_graph.cc
|
||||
transform_convert_grease_pencil.cc
|
||||
transform_convert_lattice.cc
|
||||
|
||||
@@ -718,7 +718,6 @@ static void init_proportional_edit(TransInfo *t)
|
||||
&TransConvertType_Curve,
|
||||
&TransConvertType_Curves,
|
||||
&TransConvertType_Graph,
|
||||
&TransConvertType_GPencil,
|
||||
&TransConvertType_GreasePencil,
|
||||
&TransConvertType_Lattice,
|
||||
&TransConvertType_Mask,
|
||||
@@ -789,7 +788,6 @@ static void init_TransDataContainers(TransInfo *t, Object *obact, Span<Object *>
|
||||
&TransConvertType_EditArmature,
|
||||
&TransConvertType_Curve,
|
||||
&TransConvertType_Curves,
|
||||
&TransConvertType_GPencil,
|
||||
&TransConvertType_GreasePencil,
|
||||
&TransConvertType_Lattice,
|
||||
&TransConvertType_MBall,
|
||||
@@ -806,8 +804,7 @@ static void init_TransDataContainers(TransInfo *t, Object *obact, Span<Object *>
|
||||
const eObjectMode object_mode = eObjectMode(obact ? obact->mode : OB_MODE_OBJECT);
|
||||
const short object_type = obact ? obact->type : -1;
|
||||
|
||||
if ((object_mode & OB_MODE_EDIT) || (t->data_type == &TransConvertType_GPencil) ||
|
||||
(t->data_type == &TransConvertType_GreasePencil) ||
|
||||
if ((object_mode & OB_MODE_EDIT) || (t->data_type == &TransConvertType_GreasePencil) ||
|
||||
((object_mode & OB_MODE_POSE) && (object_type == OB_ARMATURE)))
|
||||
{
|
||||
if (t->data_container) {
|
||||
@@ -851,9 +848,6 @@ static void init_TransDataContainers(TransInfo *t, Object *obact, Span<Object *>
|
||||
tc->poseobj = objects[i];
|
||||
tc->use_local_mat = true;
|
||||
}
|
||||
else if (t->data_type == &TransConvertType_GPencil) {
|
||||
tc->use_local_mat = true;
|
||||
}
|
||||
else if (t->data_type == &TransConvertType_GreasePencil) {
|
||||
tc->use_local_mat = true;
|
||||
}
|
||||
@@ -906,9 +900,6 @@ static TransConvertTypeInfo *convert_type_get(const TransInfo *t, Object **r_obj
|
||||
if (t->obedit_type == OB_GREASE_PENCIL) {
|
||||
return &TransConvertType_GreasePencil;
|
||||
}
|
||||
else if (t->obedit_type == OB_GPENCIL_LEGACY) {
|
||||
return &TransConvertType_GPencil;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
if (t->spacetype == SPACE_IMAGE) {
|
||||
|
||||
@@ -226,10 +226,6 @@ extern TransConvertTypeInfo TransConvertType_Curves;
|
||||
|
||||
extern TransConvertTypeInfo TransConvertType_Graph;
|
||||
|
||||
/* `transform_convert_gpencil_legacy.cc` */
|
||||
|
||||
extern TransConvertTypeInfo TransConvertType_GPencil;
|
||||
|
||||
/* `transform_convert_greasepencil.cc` */
|
||||
|
||||
extern TransConvertTypeInfo TransConvertType_GreasePencil;
|
||||
|
||||
@@ -1,786 +0,0 @@
|
||||
/* SPDX-FileCopyrightText: 2001-2002 NaN Holding BV. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup edtransform
|
||||
*/
|
||||
|
||||
#include "DNA_gpencil_legacy_types.h"
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "BLI_ghash.h"
|
||||
#include "BLI_listbase.h"
|
||||
#include "BLI_math_matrix.h"
|
||||
#include "BLI_math_vector.h"
|
||||
|
||||
#include "BKE_colortools.hh"
|
||||
#include "BKE_context.hh"
|
||||
#include "BKE_curve.hh"
|
||||
#include "BKE_gpencil_curve_legacy.h"
|
||||
#include "BKE_gpencil_geom_legacy.h"
|
||||
#include "BKE_gpencil_legacy.h"
|
||||
#include "BKE_layer.hh"
|
||||
|
||||
#include "ED_gpencil_legacy.hh"
|
||||
|
||||
#include "ANIM_keyframing.hh"
|
||||
|
||||
#include "transform.hh"
|
||||
#include "transform_convert.hh"
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Gpencil Transform Creation
|
||||
* \{ */
|
||||
|
||||
static void createTransGPencil_center_get(bGPDstroke *gps, float r_center[3])
|
||||
{
|
||||
bGPDspoint *pt;
|
||||
int i;
|
||||
|
||||
zero_v3(r_center);
|
||||
int tot_sel = 0;
|
||||
for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
|
||||
if (pt->flag & GP_SPOINT_SELECT) {
|
||||
add_v3_v3(r_center, &pt->x);
|
||||
tot_sel++;
|
||||
}
|
||||
}
|
||||
|
||||
if (tot_sel > 0) {
|
||||
mul_v3_fl(r_center, 1.0f / tot_sel);
|
||||
}
|
||||
}
|
||||
|
||||
static short get_bezt_sel_triple_flag(BezTriple *bezt, const bool hide_handles)
|
||||
{
|
||||
#define SEL_F1 (1 << 0)
|
||||
#define SEL_F2 (1 << 1)
|
||||
#define SEL_F3 (1 << 2)
|
||||
#define SEL_ALL ((1 << 0) | (1 << 1) | (1 << 2))
|
||||
|
||||
short flag = 0;
|
||||
|
||||
if (hide_handles) {
|
||||
if (bezt->f2 & SELECT) {
|
||||
flag = SEL_ALL;
|
||||
}
|
||||
}
|
||||
else {
|
||||
flag = ((bezt->f1 & SELECT) ? SEL_F1 : 0) | ((bezt->f2 & SELECT) ? SEL_F2 : 0) |
|
||||
((bezt->f3 & SELECT) ? SEL_F3 : 0);
|
||||
}
|
||||
|
||||
/* Special case for auto & aligned handles. */
|
||||
if ((flag != SEL_ALL) && (flag & SEL_F2)) {
|
||||
if (ELEM(bezt->h1, HD_AUTO, HD_ALIGN) && ELEM(bezt->h2, HD_AUTO, HD_ALIGN)) {
|
||||
flag = SEL_ALL;
|
||||
}
|
||||
}
|
||||
|
||||
#undef SEL_F1
|
||||
#undef SEL_F2
|
||||
#undef SEL_F3
|
||||
return flag;
|
||||
}
|
||||
|
||||
static void createTransGPencil_curves(bContext *C,
|
||||
TransInfo *t,
|
||||
Depsgraph *depsgraph,
|
||||
ToolSettings *ts,
|
||||
Object *obact,
|
||||
bGPdata *gpd,
|
||||
const int cfra_scene,
|
||||
const bool is_multiedit,
|
||||
const bool use_multiframe_falloff,
|
||||
const bool is_prop_edit,
|
||||
const bool is_prop_edit_connected,
|
||||
const bool is_scale_thickness)
|
||||
{
|
||||
#define SEL_F1 (1 << 0)
|
||||
#define SEL_F2 (1 << 1)
|
||||
#define SEL_F3 (1 << 2)
|
||||
|
||||
View3D *v3d = static_cast<View3D *>(t->view);
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
const bool handle_only_selected_visible = (v3d->overlay.handle_display == CURVE_HANDLE_SELECTED);
|
||||
const bool handle_all_visible = (v3d->overlay.handle_display == CURVE_HANDLE_ALL);
|
||||
|
||||
TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_SINGLE(t);
|
||||
tc->data_len = 0;
|
||||
|
||||
/* Number of selected curve points. */
|
||||
uint32_t tot_curve_points = 0, tot_sel_curve_points = 0, tot_points = 0, tot_sel_points = 0;
|
||||
LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
|
||||
/* Only editable and visible layers are considered. */
|
||||
if (BKE_gpencil_layer_is_editable(gpl) && (gpl->actframe != nullptr)) {
|
||||
bGPDframe *init_gpf = static_cast<bGPDframe *>((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))) {
|
||||
LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
|
||||
/* Skip strokes that are invalid for current view. */
|
||||
if (ED_gpencil_stroke_can_use(C, gps) == false) {
|
||||
continue;
|
||||
}
|
||||
/* Check if the color is editable. */
|
||||
if (ED_gpencil_stroke_material_editable(obact, gpl, gps) == false) {
|
||||
continue;
|
||||
}
|
||||
/* Check if stroke has an editcurve. */
|
||||
if (gps->editcurve == nullptr) {
|
||||
continue;
|
||||
}
|
||||
|
||||
bGPDcurve *gpc = gps->editcurve;
|
||||
for (int i = 0; i < gpc->tot_curve_points; i++) {
|
||||
bGPDcurve_point *gpc_pt = &gpc->curve_points[i];
|
||||
BezTriple *bezt = &gpc_pt->bezt;
|
||||
if (bezt->hide) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const bool hide_handles = !(
|
||||
handle_all_visible ||
|
||||
(handle_only_selected_visible && (gpc_pt->flag & GP_CURVE_POINT_SELECT)));
|
||||
|
||||
const short sel_flag = get_bezt_sel_triple_flag(bezt, hide_handles);
|
||||
if (sel_flag & (SEL_F1 | SEL_F2 | SEL_F3)) {
|
||||
if (sel_flag & SEL_F1) {
|
||||
tot_sel_points++;
|
||||
}
|
||||
if (sel_flag & SEL_F2) {
|
||||
tot_sel_points++;
|
||||
}
|
||||
if (sel_flag & SEL_F3) {
|
||||
tot_sel_points++;
|
||||
}
|
||||
tot_sel_curve_points++;
|
||||
}
|
||||
|
||||
if (is_prop_edit) {
|
||||
tot_points += 3;
|
||||
tot_curve_points++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* If not multi-edit out of loop. */
|
||||
if (!is_multiedit) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (((is_prop_edit && !is_prop_edit_connected) ? tot_curve_points : tot_sel_points) == 0) {
|
||||
tc->data_len = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
int data_len_pt = 0;
|
||||
|
||||
if (is_prop_edit) {
|
||||
tc->data_len = tot_points;
|
||||
data_len_pt = tot_curve_points;
|
||||
}
|
||||
else {
|
||||
tc->data_len = tot_sel_points;
|
||||
data_len_pt = tot_sel_curve_points;
|
||||
}
|
||||
|
||||
if (tc->data_len == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
transform_around_single_fallback_ex(t, data_len_pt);
|
||||
|
||||
tc->data = static_cast<TransData *>(MEM_callocN(tc->data_len * sizeof(TransData), __func__));
|
||||
TransData *td = tc->data;
|
||||
|
||||
const bool use_around_origins_for_handles_test = ((t->around == V3D_AROUND_LOCAL_ORIGINS) &&
|
||||
transform_mode_use_local_origins(t));
|
||||
|
||||
LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
|
||||
/* Only editable and visible layers are considered. */
|
||||
if (BKE_gpencil_layer_is_editable(gpl) && (gpl->actframe != nullptr)) {
|
||||
const int cfra = (gpl->flag & GP_LAYER_FRAMELOCK) ? gpl->actframe->framenum : cfra_scene;
|
||||
bGPDframe *gpf = gpl->actframe;
|
||||
bGPDframe *init_gpf = static_cast<bGPDframe *>((is_multiedit) ? gpl->frames.first :
|
||||
gpl->actframe);
|
||||
float diff_mat[4][4], mtx[3][3];
|
||||
float smtx[3][3];
|
||||
|
||||
/* Init multiframe falloff options. */
|
||||
int f_init = 0;
|
||||
int f_end = 0;
|
||||
|
||||
if (use_multiframe_falloff) {
|
||||
BKE_gpencil_frame_range_selected(gpl, &f_init, &f_end);
|
||||
}
|
||||
|
||||
if ((gpf->framenum != cfra) && (!is_multiedit)) {
|
||||
if (blender::animrig::is_autokey_on(scene)) {
|
||||
gpf = BKE_gpencil_frame_addcopy(gpl, cfra);
|
||||
}
|
||||
/* In some weird situations (frame-lock enabled) return nullptr. */
|
||||
if (gpf == nullptr) {
|
||||
continue;
|
||||
}
|
||||
if (!is_multiedit) {
|
||||
init_gpf = gpf;
|
||||
}
|
||||
}
|
||||
|
||||
/* Calculate difference matrix. */
|
||||
BKE_gpencil_layer_transform_matrix_get(depsgraph, obact, gpl, diff_mat);
|
||||
copy_m3_m4(mtx, diff_mat);
|
||||
pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON);
|
||||
|
||||
for (gpf = init_gpf; gpf; gpf = gpf->next) {
|
||||
if ((gpf == gpl->actframe) || ((gpf->flag & GP_FRAME_SELECT) && (is_multiedit))) {
|
||||
/* If multi-frame and falloff, recalculate and save value. */
|
||||
float falloff = 1.0f; /* By default no falloff. */
|
||||
if ((is_multiedit) && (use_multiframe_falloff)) {
|
||||
/* Falloff depends on distance to active frame
|
||||
* (relative to the overall frame range). */
|
||||
falloff = BKE_gpencil_multiframe_falloff_calc(
|
||||
gpf, gpl->actframe->framenum, f_init, f_end, ts->gp_sculpt.cur_falloff);
|
||||
}
|
||||
|
||||
LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
|
||||
/* Skip strokes that are invalid for current view. */
|
||||
if (ED_gpencil_stroke_can_use(C, gps) == false) {
|
||||
continue;
|
||||
}
|
||||
/* Check if the color is editable. */
|
||||
if (ED_gpencil_stroke_material_editable(obact, gpl, gps) == false) {
|
||||
continue;
|
||||
}
|
||||
/* Check if stroke has an editcurve. */
|
||||
if (gps->editcurve == nullptr) {
|
||||
continue;
|
||||
}
|
||||
TransData *head, *tail;
|
||||
head = tail = td;
|
||||
|
||||
gps->runtime.multi_frame_falloff = falloff;
|
||||
bool need_handle_recalc = false;
|
||||
|
||||
bGPDcurve *gpc = gps->editcurve;
|
||||
const bool is_cyclic = gps->flag & GP_STROKE_CYCLIC;
|
||||
for (int i = 0; i < gpc->tot_curve_points; i++) {
|
||||
bGPDcurve_point *gpc_pt = &gpc->curve_points[i];
|
||||
BezTriple *bezt = &gpc_pt->bezt;
|
||||
if (bezt->hide) {
|
||||
continue;
|
||||
}
|
||||
|
||||
TransDataCurveHandleFlags *hdata = nullptr;
|
||||
bool bezt_use = false;
|
||||
const bool hide_handles = !(
|
||||
handle_all_visible ||
|
||||
(handle_only_selected_visible && (gpc_pt->flag & GP_CURVE_POINT_SELECT)));
|
||||
const short sel_flag = get_bezt_sel_triple_flag(bezt, hide_handles);
|
||||
/* Iterate over bezier triple. */
|
||||
for (int j = 0; j < 3; j++) {
|
||||
bool is_ctrl_point = (j == 1);
|
||||
bool sel = sel_flag & (1 << j);
|
||||
|
||||
if (is_prop_edit || sel) {
|
||||
copy_v3_v3(td->iloc, bezt->vec[j]);
|
||||
td->loc = bezt->vec[j];
|
||||
bool rotate_around_ctrl = hide_handles ||
|
||||
(t->around == V3D_AROUND_LOCAL_ORIGINS) ||
|
||||
(bezt->f2 & SELECT);
|
||||
copy_v3_v3(td->center, bezt->vec[rotate_around_ctrl ? 1 : j]);
|
||||
|
||||
if (hide_handles || is_ctrl_point) {
|
||||
if (bezt->f2 & SELECT) {
|
||||
td->flag = TD_SELECTED;
|
||||
}
|
||||
else {
|
||||
td->flag = 0;
|
||||
}
|
||||
}
|
||||
else if (!hide_handles) {
|
||||
if (sel) {
|
||||
td->flag = TD_SELECTED;
|
||||
}
|
||||
else {
|
||||
td->flag = 0;
|
||||
}
|
||||
}
|
||||
|
||||
td->ext = nullptr;
|
||||
if (is_ctrl_point) {
|
||||
if (t->mode != TFM_MIRROR) {
|
||||
if (t->mode != TFM_GPENCIL_OPACITY) {
|
||||
if (is_scale_thickness) {
|
||||
td->val = &(gpc_pt->pressure);
|
||||
td->ival = gpc_pt->pressure;
|
||||
}
|
||||
}
|
||||
else {
|
||||
td->val = &(gpc_pt->strength);
|
||||
td->ival = gpc_pt->strength;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
td->val = nullptr;
|
||||
}
|
||||
|
||||
if (hdata == nullptr) {
|
||||
if (is_ctrl_point && ((sel_flag & SEL_F1 & SEL_F3) == 0)) {
|
||||
hdata = initTransDataCurveHandles(td, bezt);
|
||||
}
|
||||
else if (!is_ctrl_point) {
|
||||
hdata = initTransDataCurveHandles(td, bezt);
|
||||
}
|
||||
}
|
||||
|
||||
td->extra = gps;
|
||||
td->ob = obact;
|
||||
|
||||
copy_m3_m3(td->smtx, smtx);
|
||||
copy_m3_m3(td->mtx, mtx);
|
||||
copy_m3_m3(td->axismtx, mtx);
|
||||
|
||||
td++;
|
||||
tail++;
|
||||
}
|
||||
|
||||
bezt_use |= sel;
|
||||
}
|
||||
|
||||
/* Update the handle types so transformation is possible. */
|
||||
if (bezt_use && !ELEM(t->mode, TFM_GPENCIL_OPACITY, TFM_GPENCIL_SHRINKFATTEN)) {
|
||||
BKE_nurb_bezt_handle_test(bezt,
|
||||
SELECT,
|
||||
hide_handles ? NURB_HANDLE_TEST_KNOT_ONLY :
|
||||
NURB_HANDLE_TEST_KNOT_OR_EACH,
|
||||
use_around_origins_for_handles_test);
|
||||
need_handle_recalc = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (is_prop_edit && (head != tail)) {
|
||||
calc_distanceCurveVerts(head, tail - 1, is_cyclic);
|
||||
}
|
||||
|
||||
if (need_handle_recalc) {
|
||||
BKE_gpencil_editcurve_recalculate_handles(gps);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* If not multi-edit out of loop. */
|
||||
if (!is_multiedit) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#undef SEL_F1
|
||||
#undef SEL_F2
|
||||
#undef SEL_F3
|
||||
}
|
||||
|
||||
static void createTransGPencil_strokes(bContext *C,
|
||||
TransInfo *t,
|
||||
Depsgraph *depsgraph,
|
||||
ToolSettings *ts,
|
||||
Object *obact,
|
||||
bGPdata *gpd,
|
||||
const int cfra_scene,
|
||||
const bool is_multiedit,
|
||||
const bool use_multiframe_falloff,
|
||||
const bool is_prop_edit,
|
||||
const bool is_prop_edit_connected,
|
||||
const bool is_scale_thickness)
|
||||
{
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
TransData *td = nullptr;
|
||||
float mtx[3][3], smtx[3][3];
|
||||
|
||||
TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_SINGLE(t);
|
||||
/* == Grease Pencil Strokes to Transform Data ==
|
||||
* Grease Pencil stroke points can be a mixture of 2D (screen-space),
|
||||
* or 3D coordinates. However, they're always saved as 3D points.
|
||||
* For now, we just do these without creating TransData2D for the 2D
|
||||
* strokes. This may cause issues in future though.
|
||||
*/
|
||||
tc->data_len = 0;
|
||||
|
||||
/* First Pass: Count the number of data-points required for the strokes,
|
||||
* (and additional info about the configuration - e.g. 2D/3D?).
|
||||
*/
|
||||
LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
|
||||
/* Only editable and visible layers are considered. */
|
||||
if (BKE_gpencil_layer_is_editable(gpl) && (gpl->actframe != nullptr)) {
|
||||
bGPDframe *gpf;
|
||||
bGPDframe *init_gpf = static_cast<bGPDframe *>((is_multiedit) ? gpl->frames.first :
|
||||
gpl->actframe);
|
||||
|
||||
for (gpf = init_gpf; gpf; gpf = gpf->next) {
|
||||
if ((gpf == gpl->actframe) || ((gpf->flag & GP_FRAME_SELECT) && (is_multiedit))) {
|
||||
LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
|
||||
/* Skip strokes that are invalid for current view. */
|
||||
if (ED_gpencil_stroke_can_use(C, gps) == false) {
|
||||
continue;
|
||||
}
|
||||
/* Check if the color is editable. */
|
||||
if (ED_gpencil_stroke_material_editable(obact, gpl, gps) == false) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (is_prop_edit) {
|
||||
/* Proportional Editing... */
|
||||
if (is_prop_edit_connected) {
|
||||
/* Connected only - so only if selected. */
|
||||
if (gps->flag & GP_STROKE_SELECT) {
|
||||
tc->data_len += gps->totpoints;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Everything goes - connection status doesn't matter. */
|
||||
tc->data_len += gps->totpoints;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Only selected stroke points are considered. */
|
||||
if (gps->flag & GP_STROKE_SELECT) {
|
||||
bGPDspoint *pt;
|
||||
int i;
|
||||
|
||||
for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
|
||||
if (pt->flag & GP_SPOINT_SELECT) {
|
||||
tc->data_len++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* If not multi-edit out of loop. */
|
||||
if (!is_multiedit) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Stop trying if nothing selected. */
|
||||
if (tc->data_len == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Allocate memory for data. */
|
||||
tc->data = static_cast<TransData *>(
|
||||
MEM_callocN(tc->data_len * sizeof(TransData), "TransData(GPencil)"));
|
||||
td = tc->data;
|
||||
|
||||
unit_m3(smtx);
|
||||
unit_m3(mtx);
|
||||
|
||||
/* Second Pass: Build transform-data array. */
|
||||
LISTBASE_FOREACH (bGPDlayer *, gpl, &gpd->layers) {
|
||||
/* Only editable and visible layers are considered. */
|
||||
if (BKE_gpencil_layer_is_editable(gpl) && (gpl->actframe != nullptr)) {
|
||||
const int cfra = (gpl->flag & GP_LAYER_FRAMELOCK) ? gpl->actframe->framenum : cfra_scene;
|
||||
bGPDframe *gpf = gpl->actframe;
|
||||
float diff_mat[3][3];
|
||||
float inverse_diff_mat[3][3];
|
||||
|
||||
bGPDframe *init_gpf = static_cast<bGPDframe *>((is_multiedit) ? gpl->frames.first :
|
||||
gpl->actframe);
|
||||
/* Initialize multi-frame falloff options. */
|
||||
int f_init = 0;
|
||||
int f_end = 0;
|
||||
|
||||
if (use_multiframe_falloff) {
|
||||
BKE_gpencil_frame_range_selected(gpl, &f_init, &f_end);
|
||||
}
|
||||
|
||||
/* Calculate difference matrix. */
|
||||
{
|
||||
float diff_mat_tmp[4][4];
|
||||
BKE_gpencil_layer_transform_matrix_get(depsgraph, obact, gpl, diff_mat_tmp);
|
||||
copy_m3_m4(diff_mat, diff_mat_tmp);
|
||||
}
|
||||
|
||||
/* Use safe invert for cases where the input matrix has zero axes. */
|
||||
invert_m3_m3_safe_ortho(inverse_diff_mat, diff_mat);
|
||||
|
||||
/* Make a new frame to work on if the layer's frame
|
||||
* and the current scene frame don't match up.
|
||||
*
|
||||
* - This is useful when animating as it saves that "uh-oh" moment when you realize you've
|
||||
* spent too much time editing the wrong frame...
|
||||
*/
|
||||
if ((gpf->framenum != cfra) && (!is_multiedit)) {
|
||||
if (blender::animrig::is_autokey_on(scene)) {
|
||||
gpf = BKE_gpencil_frame_addcopy(gpl, cfra);
|
||||
}
|
||||
/* In some weird situations (frame-lock enabled) return nullptr. */
|
||||
if (gpf == nullptr) {
|
||||
continue;
|
||||
}
|
||||
if (!is_multiedit) {
|
||||
init_gpf = gpf;
|
||||
}
|
||||
}
|
||||
|
||||
/* Loop over strokes, adding TransData for points as needed... */
|
||||
for (gpf = init_gpf; gpf; gpf = gpf->next) {
|
||||
if ((gpf == gpl->actframe) || ((gpf->flag & GP_FRAME_SELECT) && (is_multiedit))) {
|
||||
|
||||
/* If multi-frame and falloff, recalculate and save value. */
|
||||
float falloff = 1.0f; /* By default no falloff. */
|
||||
if ((is_multiedit) && (use_multiframe_falloff)) {
|
||||
/* Falloff depends on distance to active frame
|
||||
* (relative to the overall frame range). */
|
||||
falloff = BKE_gpencil_multiframe_falloff_calc(
|
||||
gpf, gpl->actframe->framenum, f_init, f_end, ts->gp_sculpt.cur_falloff);
|
||||
}
|
||||
|
||||
LISTBASE_FOREACH (bGPDstroke *, gps, &gpf->strokes) {
|
||||
TransData *head = td;
|
||||
TransData *tail = td;
|
||||
bool stroke_ok;
|
||||
|
||||
/* Skip strokes that are invalid for current view. */
|
||||
if (ED_gpencil_stroke_can_use(C, gps) == false) {
|
||||
continue;
|
||||
}
|
||||
/* Check if the color is editable. */
|
||||
if (ED_gpencil_stroke_material_editable(obact, gpl, gps) == false) {
|
||||
continue;
|
||||
}
|
||||
/* What we need to include depends on proportional editing settings... */
|
||||
if (is_prop_edit) {
|
||||
if (is_prop_edit_connected) {
|
||||
/* A) "Connected" - Only those in selected strokes. */
|
||||
stroke_ok = (gps->flag & GP_STROKE_SELECT) != 0;
|
||||
}
|
||||
else {
|
||||
/* B) All points, always. */
|
||||
stroke_ok = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* C) Only selected points in selected strokes. */
|
||||
stroke_ok = (gps->flag & GP_STROKE_SELECT) != 0;
|
||||
}
|
||||
|
||||
/* Do stroke... */
|
||||
if (stroke_ok && gps->totpoints) {
|
||||
bGPDspoint *pt;
|
||||
int i;
|
||||
|
||||
/* Save falloff factor. */
|
||||
gps->runtime.multi_frame_falloff = falloff;
|
||||
|
||||
/* Calculate stroke center. */
|
||||
float center[3];
|
||||
createTransGPencil_center_get(gps, center);
|
||||
|
||||
/* Add all necessary points... */
|
||||
for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) {
|
||||
bool point_ok;
|
||||
|
||||
/* Include point? */
|
||||
if (is_prop_edit) {
|
||||
/* Always all points in strokes that get included. */
|
||||
point_ok = true;
|
||||
}
|
||||
else {
|
||||
/* Only selected points in selected strokes. */
|
||||
point_ok = (pt->flag & GP_SPOINT_SELECT) != 0;
|
||||
}
|
||||
|
||||
/* Do point... */
|
||||
if (point_ok) {
|
||||
copy_v3_v3(td->iloc, &pt->x);
|
||||
/* Only copy center in local origins.
|
||||
* This allows get interesting effects also when move
|
||||
* using proportional editing. */
|
||||
if ((gps->flag & GP_STROKE_SELECT) &&
|
||||
(ts->transform_pivot_point == V3D_AROUND_LOCAL_ORIGINS))
|
||||
{
|
||||
copy_v3_v3(td->center, center);
|
||||
}
|
||||
else {
|
||||
copy_v3_v3(td->center, &pt->x);
|
||||
}
|
||||
|
||||
td->loc = &pt->x;
|
||||
|
||||
td->flag = 0;
|
||||
|
||||
if (pt->flag & GP_SPOINT_SELECT) {
|
||||
td->flag |= TD_SELECTED;
|
||||
}
|
||||
|
||||
/* For other transform modes (e.g. shrink-fatten), need to additional data
|
||||
* but never for mirror. */
|
||||
if (t->mode != TFM_MIRROR) {
|
||||
if (t->mode != TFM_GPENCIL_OPACITY) {
|
||||
if (is_scale_thickness) {
|
||||
td->val = &pt->pressure;
|
||||
td->ival = pt->pressure;
|
||||
}
|
||||
}
|
||||
else {
|
||||
td->val = &pt->strength;
|
||||
td->ival = pt->strength;
|
||||
}
|
||||
}
|
||||
|
||||
/* Screen-space needs special matrices. */
|
||||
if ((gps->flag & (GP_STROKE_3DSPACE | GP_STROKE_2DSPACE | GP_STROKE_2DIMAGE)) ==
|
||||
0)
|
||||
{
|
||||
/* Screen-space. */
|
||||
td->protectflag = OB_LOCK_LOCZ | OB_LOCK_ROTZ | OB_LOCK_SCALEZ;
|
||||
}
|
||||
else {
|
||||
/* Configure 2D data-space points so that they don't play up. */
|
||||
if (gps->flag & (GP_STROKE_2DSPACE | GP_STROKE_2DIMAGE)) {
|
||||
td->protectflag = OB_LOCK_LOCZ | OB_LOCK_ROTZ | OB_LOCK_SCALEZ;
|
||||
}
|
||||
}
|
||||
/* Apply parent transformations. */
|
||||
copy_m3_m3(td->smtx, inverse_diff_mat); /* Final position. */
|
||||
copy_m3_m3(td->mtx, diff_mat); /* Display position. */
|
||||
copy_m3_m3(td->axismtx, diff_mat); /* Axis orientation. */
|
||||
|
||||
/* Triangulation must be calculated again,
|
||||
* so save the stroke for recalculate function. */
|
||||
td->extra = gps;
|
||||
|
||||
/* Save pointer to object. */
|
||||
td->ob = obact;
|
||||
|
||||
td++;
|
||||
tail++;
|
||||
}
|
||||
}
|
||||
|
||||
/* March over these points, and calculate the proportional editing distances. */
|
||||
if (is_prop_edit && (head != tail)) {
|
||||
calc_distanceCurveVerts(head, tail - 1, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* If not multi-edit out of loop. */
|
||||
if (!is_multiedit) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void createTransGPencil(bContext *C, TransInfo *t)
|
||||
{
|
||||
if (t->data_container_len == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
|
||||
const Scene *scene = CTX_data_scene(C);
|
||||
ToolSettings *ts = scene->toolsettings;
|
||||
BKE_view_layer_synced_ensure(t->scene, t->view_layer);
|
||||
Object *obact = BKE_view_layer_active_object_get(t->view_layer);
|
||||
bGPdata *gpd = static_cast<bGPdata *>(obact->data);
|
||||
BLI_assert(gpd != nullptr);
|
||||
|
||||
const int cfra_scene = scene->r.cfra;
|
||||
|
||||
const bool is_multiedit = bool(GPENCIL_MULTIEDIT_SESSIONS_ON(gpd));
|
||||
const bool use_multiframe_falloff = (ts->gp_sculpt.flag & GP_SCULPT_SETT_FLAG_FRAME_FALLOFF) !=
|
||||
0;
|
||||
|
||||
const bool is_prop_edit = (t->flag & T_PROP_EDIT) != 0;
|
||||
const bool is_prop_edit_connected = (t->flag & T_PROP_CONNECTED) != 0;
|
||||
const bool is_scale_thickness = ((t->mode == TFM_GPENCIL_SHRINKFATTEN) ||
|
||||
(ts->gp_sculpt.flag & GP_SCULPT_SETT_FLAG_SCALE_THICKNESS));
|
||||
|
||||
const bool is_curve_edit = bool(GPENCIL_CURVE_EDIT_SESSIONS_ON(gpd));
|
||||
|
||||
/* Initialize falloff curve. */
|
||||
if (is_multiedit) {
|
||||
BKE_curvemapping_init(ts->gp_sculpt.cur_falloff);
|
||||
}
|
||||
|
||||
if (gpd == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_curve_edit) {
|
||||
createTransGPencil_curves(C,
|
||||
t,
|
||||
depsgraph,
|
||||
ts,
|
||||
obact,
|
||||
gpd,
|
||||
cfra_scene,
|
||||
is_multiedit,
|
||||
use_multiframe_falloff,
|
||||
is_prop_edit,
|
||||
is_prop_edit_connected,
|
||||
is_scale_thickness);
|
||||
}
|
||||
else {
|
||||
createTransGPencil_strokes(C,
|
||||
t,
|
||||
depsgraph,
|
||||
ts,
|
||||
obact,
|
||||
gpd,
|
||||
cfra_scene,
|
||||
is_multiedit,
|
||||
use_multiframe_falloff,
|
||||
is_prop_edit,
|
||||
is_prop_edit_connected,
|
||||
is_scale_thickness);
|
||||
}
|
||||
}
|
||||
|
||||
static void recalcData_gpencil_strokes(TransInfo *t)
|
||||
{
|
||||
TransDataContainer *tc = TRANS_DATA_CONTAINER_FIRST_SINGLE(t);
|
||||
GHash *strokes = BLI_ghash_ptr_new(__func__);
|
||||
|
||||
TransData *td = tc->data;
|
||||
bGPdata *gpd = static_cast<bGPdata *>(td->ob->data);
|
||||
const bool is_curve_edit = bool(GPENCIL_CURVE_EDIT_SESSIONS_ON(gpd));
|
||||
for (int i = 0; i < tc->data_len; i++, td++) {
|
||||
bGPDstroke *gps = static_cast<bGPDstroke *>(td->extra);
|
||||
|
||||
if ((gps != nullptr) && !BLI_ghash_haskey(strokes, gps)) {
|
||||
BLI_ghash_insert(strokes, gps, gps);
|
||||
if (is_curve_edit && gps->editcurve != nullptr) {
|
||||
BKE_gpencil_editcurve_recalculate_handles(gps);
|
||||
gps->flag |= GP_STROKE_NEEDS_CURVE_UPDATE;
|
||||
}
|
||||
/* Calc geometry data. */
|
||||
BKE_gpencil_stroke_geometry_update(gpd, gps);
|
||||
}
|
||||
}
|
||||
BLI_ghash_free(strokes, nullptr, nullptr);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
TransConvertTypeInfo TransConvertType_GPencil = {
|
||||
/*flags*/ (T_EDIT | T_POINTS),
|
||||
/*create_trans_data*/ createTransGPencil,
|
||||
/*recalc_data*/ recalcData_gpencil_strokes,
|
||||
/*special_aftertrans_update*/ nullptr,
|
||||
};
|
||||
@@ -22,7 +22,6 @@
|
||||
#include "DNA_modifier_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
|
||||
#include "BKE_gpencil_curve_legacy.h"
|
||||
#include "BKE_layer.hh"
|
||||
|
||||
#include "DEG_depsgraph.hh"
|
||||
|
||||
Reference in New Issue
Block a user