GPv3: Add support for transform object origin.
Implements support for `transform only origins`. Pull Request: https://projects.blender.org/blender/blender/pulls/126446
This commit is contained in:
committed by
Falk David
parent
ffb5226944
commit
50770bd8f5
@@ -1045,6 +1045,34 @@ void BKE_grease_pencil_data_update(Depsgraph *depsgraph, Scene *scene, Object *o
|
||||
void BKE_grease_pencil_duplicate_drawing_array(const GreasePencil *grease_pencil_src,
|
||||
GreasePencil *grease_pencil_dst);
|
||||
|
||||
typedef struct GreasePencilPointCoordinates {
|
||||
/* This is used when doing "move only origin" in object_data_transform.cc.
|
||||
* radius is needs to be stored here as it is tied to object scale. */
|
||||
float co[3];
|
||||
float radius;
|
||||
} GreasePencilPointCoordinates;
|
||||
|
||||
/**
|
||||
* \note Used for "move only origins" in object_data_transform.cc.
|
||||
*/
|
||||
int BKE_grease_pencil_stroke_point_count(const GreasePencil &grease_pencil);
|
||||
/**
|
||||
* \note Used for "move only origins" in object_data_transform.cc.
|
||||
*/
|
||||
void BKE_grease_pencil_point_coords_get(const GreasePencil &grease_pencil,
|
||||
GreasePencilPointCoordinates *elem_data);
|
||||
/**
|
||||
* \note Used for "move only origins" in object_data_transform.cc.
|
||||
*/
|
||||
void BKE_grease_pencil_point_coords_apply(GreasePencil &grease_pencil,
|
||||
GreasePencilPointCoordinates *elem_data);
|
||||
/**
|
||||
* \note Used for "move only origins" in object_data_transform.cc.
|
||||
*/
|
||||
void BKE_grease_pencil_point_coords_apply_with_mat4(GreasePencil &grease_pencil,
|
||||
GreasePencilPointCoordinates *elem_data,
|
||||
const blender::float4x4 &mat);
|
||||
|
||||
int BKE_grease_pencil_object_material_index_get_by_name(Object *ob, const char *name);
|
||||
Material *BKE_grease_pencil_object_material_new(Main *bmain,
|
||||
Object *ob,
|
||||
|
||||
@@ -1958,6 +1958,132 @@ void BKE_grease_pencil_duplicate_drawing_array(const GreasePencil *grease_pencil
|
||||
|
||||
/** \} */
|
||||
|
||||
/* ------------------------------------------------------------------- */
|
||||
/** \name Grease Pencil origin functions
|
||||
* \note Used for "move only origins" in object_data_transform.cc.
|
||||
* \{ */
|
||||
|
||||
int BKE_grease_pencil_stroke_point_count(const GreasePencil &grease_pencil)
|
||||
{
|
||||
using namespace blender;
|
||||
|
||||
int total_points = 0;
|
||||
|
||||
for (const int layer_i : grease_pencil.layers().index_range()) {
|
||||
const bke::greasepencil::Layer &layer = *grease_pencil.layer(layer_i);
|
||||
const Map<bke::greasepencil::FramesMapKeyT, GreasePencilFrame> frames = layer.frames();
|
||||
frames.foreach_item(
|
||||
[&](const bke::greasepencil::FramesMapKeyT /*key*/, const GreasePencilFrame frame) {
|
||||
const GreasePencilDrawingBase *base = grease_pencil.drawing(frame.drawing_index);
|
||||
if (base->type != GP_DRAWING) {
|
||||
return;
|
||||
}
|
||||
const bke::greasepencil::Drawing &drawing =
|
||||
reinterpret_cast<const GreasePencilDrawing *>(base)->wrap();
|
||||
const bke::CurvesGeometry &curves = drawing.strokes();
|
||||
total_points += curves.points_num();
|
||||
});
|
||||
}
|
||||
|
||||
return total_points;
|
||||
}
|
||||
|
||||
void BKE_grease_pencil_point_coords_get(const GreasePencil &grease_pencil,
|
||||
GreasePencilPointCoordinates *elem_data)
|
||||
{
|
||||
using namespace blender;
|
||||
|
||||
for (const int layer_i : grease_pencil.layers().index_range()) {
|
||||
const bke::greasepencil::Layer &layer = *grease_pencil.layer(layer_i);
|
||||
const float4x4 layer_to_object = layer.local_transform();
|
||||
const float4x4 object_to_layer = math::invert(layer_to_object);
|
||||
const Map<bke::greasepencil::FramesMapKeyT, GreasePencilFrame> frames = layer.frames();
|
||||
frames.foreach_item(
|
||||
[&](const bke::greasepencil::FramesMapKeyT /*key*/, const GreasePencilFrame frame) {
|
||||
const GreasePencilDrawingBase *base = grease_pencil.drawing(frame.drawing_index);
|
||||
if (base->type != GP_DRAWING) {
|
||||
return;
|
||||
}
|
||||
const bke::greasepencil::Drawing &drawing =
|
||||
reinterpret_cast<const GreasePencilDrawing *>(base)->wrap();
|
||||
const bke::CurvesGeometry &curves = drawing.strokes();
|
||||
const Span<float3> positions = curves.positions();
|
||||
const VArray<float> radii = drawing.radii();
|
||||
|
||||
for (const int i : curves.points_range()) {
|
||||
copy_v3_v3(elem_data->co, math::transform_point(layer_to_object, positions[i]));
|
||||
elem_data->radius = radii[i];
|
||||
elem_data++;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void BKE_grease_pencil_point_coords_apply(GreasePencil &grease_pencil,
|
||||
GreasePencilPointCoordinates *elem_data)
|
||||
{
|
||||
using namespace blender;
|
||||
|
||||
for (const int layer_i : grease_pencil.layers().index_range()) {
|
||||
bke::greasepencil::Layer &layer = *grease_pencil.layer(layer_i);
|
||||
const float4x4 layer_to_object = layer.local_transform();
|
||||
const float4x4 object_to_layer = math::invert(layer_to_object);
|
||||
const Map<bke::greasepencil::FramesMapKeyT, GreasePencilFrame> frames = layer.frames();
|
||||
frames.foreach_item([&](bke::greasepencil::FramesMapKeyT /*key*/, GreasePencilFrame frame) {
|
||||
GreasePencilDrawingBase *base = grease_pencil.drawing(frame.drawing_index);
|
||||
if (base->type != GP_DRAWING) {
|
||||
return;
|
||||
}
|
||||
bke::greasepencil::Drawing &drawing = reinterpret_cast<GreasePencilDrawing *>(base)->wrap();
|
||||
bke::CurvesGeometry &curves = drawing.strokes_for_write();
|
||||
|
||||
MutableSpan<float3> positions = curves.positions_for_write();
|
||||
MutableSpan<float> radii = drawing.radii_for_write();
|
||||
|
||||
for (const int i : curves.points_range()) {
|
||||
positions[i] = math::transform_point(object_to_layer, float3(elem_data->co));
|
||||
radii[i] = elem_data->radius;
|
||||
elem_data++;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void BKE_grease_pencil_point_coords_apply_with_mat4(GreasePencil &grease_pencil,
|
||||
GreasePencilPointCoordinates *elem_data,
|
||||
const blender::float4x4 &mat)
|
||||
{
|
||||
using namespace blender;
|
||||
|
||||
const float scalef = mat4_to_scale(mat.ptr());
|
||||
|
||||
for (const int layer_i : grease_pencil.layers().index_range()) {
|
||||
bke::greasepencil::Layer &layer = *grease_pencil.layer(layer_i);
|
||||
const float4x4 layer_to_object = layer.local_transform();
|
||||
const float4x4 object_to_layer = math::invert(layer_to_object);
|
||||
const Map<bke::greasepencil::FramesMapKeyT, GreasePencilFrame> frames = layer.frames();
|
||||
frames.foreach_item([&](bke::greasepencil::FramesMapKeyT /*key*/, GreasePencilFrame frame) {
|
||||
GreasePencilDrawingBase *base = grease_pencil.drawing(frame.drawing_index);
|
||||
if (base->type != GP_DRAWING) {
|
||||
return;
|
||||
}
|
||||
bke::greasepencil::Drawing &drawing = reinterpret_cast<GreasePencilDrawing *>(base)->wrap();
|
||||
bke::CurvesGeometry &curves = drawing.strokes_for_write();
|
||||
|
||||
MutableSpan<float3> positions = curves.positions_for_write();
|
||||
MutableSpan<float> radii = drawing.radii_for_write();
|
||||
|
||||
for (const int i : curves.points_range()) {
|
||||
positions[i] = math::transform_point(object_to_layer * mat, float3(elem_data->co));
|
||||
radii[i] = elem_data->radius * scalef;
|
||||
elem_data++;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* ------------------------------------------------------------------- */
|
||||
/** \name Grease Pencil material functions
|
||||
* \{ */
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#include "BKE_curve.hh"
|
||||
#include "BKE_editmesh.hh"
|
||||
#include "BKE_gpencil_geom_legacy.h"
|
||||
#include "BKE_grease_pencil.hh"
|
||||
#include "BKE_key.hh"
|
||||
#include "BKE_lattice.hh"
|
||||
#include "BKE_mball.hh"
|
||||
@@ -302,6 +303,11 @@ struct XFormObjectData_GPencil {
|
||||
GPencilPointCoordinates elem_array[0];
|
||||
};
|
||||
|
||||
struct XFormObjectData_GreasePencil {
|
||||
struct XFormObjectData base;
|
||||
struct GreasePencilPointCoordinates elem_array[0];
|
||||
};
|
||||
|
||||
XFormObjectData *data_xform_create_ex(ID *id, bool is_edit_mode)
|
||||
{
|
||||
XFormObjectData *xod_base = nullptr;
|
||||
@@ -474,6 +480,17 @@ XFormObjectData *data_xform_create_ex(ID *id, bool is_edit_mode)
|
||||
xod_base = &xod->base;
|
||||
break;
|
||||
}
|
||||
case ID_GP: {
|
||||
GreasePencil *grease_pencil = (GreasePencil *)id;
|
||||
const int elem_array_len = BKE_grease_pencil_stroke_point_count(*grease_pencil);
|
||||
XFormObjectData_GreasePencil *xod = static_cast<XFormObjectData_GreasePencil *>(
|
||||
MEM_mallocN(sizeof(*xod) + (sizeof(*xod->elem_array) * elem_array_len), __func__));
|
||||
memset(xod, 0x0, sizeof(*xod));
|
||||
|
||||
BKE_grease_pencil_point_coords_get(*grease_pencil, xod->elem_array);
|
||||
xod_base = &xod->base;
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
@@ -638,6 +655,13 @@ void data_xform_by_mat4(XFormObjectData *xod_base, const float mat[4][4])
|
||||
BKE_gpencil_point_coords_apply_with_mat4(gpd, xod->elem_array, mat);
|
||||
break;
|
||||
}
|
||||
case ID_GP: {
|
||||
GreasePencil *grease_pencil = (GreasePencil *)xod_base->id;
|
||||
XFormObjectData_GreasePencil *xod = (XFormObjectData_GreasePencil *)xod_base;
|
||||
BKE_grease_pencil_point_coords_apply_with_mat4(
|
||||
*grease_pencil, xod->elem_array, float4x4(mat));
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
@@ -739,6 +763,12 @@ void data_xform_restore(XFormObjectData *xod_base)
|
||||
BKE_gpencil_point_coords_apply(gpd, xod->elem_array);
|
||||
break;
|
||||
}
|
||||
case ID_GP: {
|
||||
GreasePencil *grease_pencil = (GreasePencil *)xod_base->id;
|
||||
XFormObjectData_GreasePencil *xod = (XFormObjectData_GreasePencil *)xod_base;
|
||||
BKE_grease_pencil_point_coords_apply(*grease_pencil, xod->elem_array);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
@@ -791,6 +821,12 @@ void data_xform_tag_update(XFormObjectData *xod_base)
|
||||
DEG_id_tag_update(&gpd->id, ID_RECALC_GEOMETRY | ID_RECALC_SYNC_TO_EVAL);
|
||||
break;
|
||||
}
|
||||
case ID_GP: {
|
||||
/* Generic update. */
|
||||
GreasePencil *grease_pencil = (GreasePencil *)xod_base->id;
|
||||
DEG_id_tag_update(&grease_pencil->id, ID_RECALC_GEOMETRY | ID_RECALC_SYNC_TO_EVAL);
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user