UI: Curves and Grease Pencil dimensions in transform side panel
In edit mode, positions of selected points is not shown in transform side panel. Following existing logic, now introduced `TransformMedian_GreasePencil`, `TransformMedian_Curves` to track the median of selected points of grease pencil and Curves respectively. Resolves #136332 Pull Request: https://projects.blender.org/blender/blender/pulls/136592
This commit is contained in:
committed by
Pratik Borhade
parent
dc38872326
commit
2cc5143ca6
@@ -22,6 +22,17 @@ Vector<MutableSpan<float3>> get_curves_positions_for_write(bke::CurvesGeometry &
|
||||
return positions_per_attribute;
|
||||
}
|
||||
|
||||
Vector<Span<float3>> get_curves_positions(const bke::CurvesGeometry &curves)
|
||||
{
|
||||
Vector<Span<float3>> positions_per_attribute;
|
||||
positions_per_attribute.append(curves.positions());
|
||||
if (curves.has_curve_with_type(CURVE_TYPE_BEZIER)) {
|
||||
positions_per_attribute.append(curves.handle_positions_left());
|
||||
positions_per_attribute.append(curves.handle_positions_right());
|
||||
}
|
||||
return positions_per_attribute;
|
||||
}
|
||||
|
||||
void transverts_from_curves_positions_create(bke::CurvesGeometry &curves,
|
||||
TransVertStore *tvs,
|
||||
const bool skip_handles)
|
||||
|
||||
@@ -60,6 +60,11 @@ Span<StringRef> get_curves_selection_attribute_names(const bke::CurvesGeometry &
|
||||
*/
|
||||
Vector<MutableSpan<float3>> get_curves_positions_for_write(bke::CurvesGeometry &curves);
|
||||
|
||||
/**
|
||||
* Get read-only positions per selection attribute for given curve.
|
||||
*/
|
||||
Vector<Span<float3>> get_curves_positions(const bke::CurvesGeometry &curves);
|
||||
|
||||
/* Get all possible curve selection attribute names. */
|
||||
Span<StringRef> get_curves_all_selection_attribute_names();
|
||||
|
||||
|
||||
@@ -30,11 +30,13 @@
|
||||
#include "BLI_math_vector.h"
|
||||
#include "BLI_string.h"
|
||||
#include "BLI_utildefines.h"
|
||||
#include "BLI_vector.hh"
|
||||
|
||||
#include "BKE_action.hh"
|
||||
#include "BKE_armature.hh"
|
||||
#include "BKE_context.hh"
|
||||
#include "BKE_curve.hh"
|
||||
#include "BKE_curves.hh"
|
||||
#include "BKE_customdata.hh"
|
||||
#include "BKE_deform.hh"
|
||||
#include "BKE_editmesh.hh"
|
||||
@@ -55,6 +57,8 @@
|
||||
#include "RNA_access.hh"
|
||||
#include "RNA_prototypes.hh"
|
||||
|
||||
#include "ED_curves.hh"
|
||||
#include "ED_grease_pencil.hh"
|
||||
#include "ED_mesh.hh"
|
||||
#include "ED_object.hh"
|
||||
#include "ED_object_vgroup.hh"
|
||||
@@ -92,11 +96,21 @@ struct TransformMedian_Lattice {
|
||||
float location[3], weight;
|
||||
};
|
||||
|
||||
struct TransformMedian_GreasePencil {
|
||||
float location[3];
|
||||
};
|
||||
|
||||
struct TransformMedian_Curves {
|
||||
float location[3];
|
||||
};
|
||||
|
||||
union TransformMedian {
|
||||
TransformMedian_Generic generic;
|
||||
TransformMedian_Mesh mesh;
|
||||
TransformMedian_Curve curve;
|
||||
TransformMedian_Lattice lattice;
|
||||
TransformMedian_GreasePencil grease_pencil;
|
||||
TransformMedian_Curves curves;
|
||||
};
|
||||
|
||||
/* temporary struct for storing transform properties */
|
||||
@@ -293,8 +307,10 @@ static TransformProperties *v3d_transform_props_ensure(View3D *v3d)
|
||||
}
|
||||
|
||||
/* is used for both read and write... */
|
||||
static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float lim)
|
||||
static void v3d_editvertex_buts(
|
||||
const bContext *C, uiLayout *layout, View3D *v3d, Object *ob, float lim)
|
||||
{
|
||||
using namespace blender;
|
||||
uiBlock *block = (layout) ? uiLayoutAbsoluteBlock(layout) : nullptr;
|
||||
TransformProperties *tfp = v3d_transform_props_ensure(v3d);
|
||||
TransformMedian median_basis, ve_median_basis;
|
||||
@@ -468,6 +484,61 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float
|
||||
data_ptr = RNA_pointer_create_discrete(<->id, seltype, selp);
|
||||
}
|
||||
}
|
||||
else if (ob->type == OB_GREASE_PENCIL) {
|
||||
using namespace blender::ed::greasepencil;
|
||||
using namespace ed::curves;
|
||||
Scene &scene = *CTX_data_scene(C);
|
||||
GreasePencil &grease_pencil = *static_cast<GreasePencil *>(ob->data);
|
||||
blender::Vector<MutableDrawingInfo> drawings = retrieve_editable_drawings(scene,
|
||||
grease_pencil);
|
||||
|
||||
threading::parallel_for_each(drawings, [&](const MutableDrawingInfo &info) {
|
||||
const bke::CurvesGeometry &curves = info.drawing.strokes();
|
||||
if (curves.is_empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const Span<StringRef> selection_names = get_curves_selection_attribute_names(curves);
|
||||
Vector<Span<float3>> positions = get_curves_positions(curves);
|
||||
TransformMedian_Curves &median = median_basis.curves;
|
||||
for (int attribute_i : selection_names.index_range()) {
|
||||
IndexMaskMemory memory;
|
||||
const IndexMask selection = retrieve_selected_points(
|
||||
curves, selection_names[attribute_i], memory);
|
||||
if (selection.is_empty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
tot += selection.size();
|
||||
selection.foreach_index(
|
||||
[&](const int point) { add_v3_v3(median.location, positions[attribute_i][point]); });
|
||||
}
|
||||
});
|
||||
}
|
||||
else if (ob->type == OB_CURVES) {
|
||||
using namespace ed::curves;
|
||||
const Curves &curves_id = *static_cast<Curves *>(ob->data);
|
||||
const bke::CurvesGeometry &curves = curves_id.geometry.wrap();
|
||||
if (curves.is_empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const Span<StringRef> selection_names = get_curves_selection_attribute_names(curves);
|
||||
const Vector<Span<float3>> positions = get_curves_positions(curves);
|
||||
TransformMedian_Curves &median = median_basis.curves;
|
||||
for (int attribute_i : selection_names.index_range()) {
|
||||
IndexMaskMemory memory;
|
||||
const IndexMask selection = retrieve_selected_points(
|
||||
curves, selection_names[attribute_i], memory);
|
||||
if (selection.is_empty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
tot += selection.size();
|
||||
selection.foreach_index(
|
||||
[&](const int point) { add_v3_v3(median.location, positions[attribute_i][point]); });
|
||||
}
|
||||
}
|
||||
|
||||
if (tot == 0) {
|
||||
uiDefBut(
|
||||
@@ -527,6 +598,9 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float
|
||||
/* Curve */
|
||||
c = IFACE_("Control Point:");
|
||||
}
|
||||
else if (ELEM(ob->type, OB_CURVES, OB_GREASE_PENCIL)) {
|
||||
c = IFACE_("Point:");
|
||||
}
|
||||
else {
|
||||
/* Mesh or lattice */
|
||||
c = IFACE_("Vertex:");
|
||||
@@ -1168,9 +1242,70 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float
|
||||
bp++;
|
||||
}
|
||||
}
|
||||
else if (ob->type == OB_GREASE_PENCIL && apply_vcos) {
|
||||
using namespace blender::ed::greasepencil;
|
||||
using namespace ed::curves;
|
||||
Scene &scene = *CTX_data_scene(C);
|
||||
GreasePencil &grease_pencil = *static_cast<GreasePencil *>(ob->data);
|
||||
blender::Vector<MutableDrawingInfo> drawings = retrieve_editable_drawings(scene,
|
||||
grease_pencil);
|
||||
|
||||
// ED_undo_push(C, "Transform properties");
|
||||
threading::parallel_for_each(drawings, [&](const MutableDrawingInfo &info) {
|
||||
bke::CurvesGeometry &curves = info.drawing.strokes_for_write();
|
||||
if (curves.is_empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
TransformMedian_GreasePencil &median = median_basis.grease_pencil;
|
||||
TransformMedian_GreasePencil &ve_median = ve_median_basis.grease_pencil;
|
||||
IndexMaskMemory memory;
|
||||
const Span<StringRef> selection_names = get_curves_selection_attribute_names(curves);
|
||||
const Vector<MutableSpan<float3>> positions = get_curves_positions_for_write(curves);
|
||||
for (int attribute_i : selection_names.index_range()) {
|
||||
const IndexMask selection = retrieve_selected_points(
|
||||
curves, selection_names[attribute_i], memory);
|
||||
if (selection.is_empty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
selection.foreach_index([&](const int point) {
|
||||
apply_raw_diff_v3(
|
||||
positions[attribute_i][point], tot, ve_median.location, median.location);
|
||||
});
|
||||
info.drawing.tag_positions_changed();
|
||||
}
|
||||
});
|
||||
}
|
||||
else if (ob->type == OB_CURVES && apply_vcos) {
|
||||
using namespace ed::curves;
|
||||
Curves &curves_id = *static_cast<Curves *>(ob->data);
|
||||
bke::CurvesGeometry &curves = curves_id.geometry.wrap();
|
||||
if (curves.is_empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
TransformMedian_Curves &median = median_basis.curves;
|
||||
TransformMedian_Curves &ve_median = ve_median_basis.curves;
|
||||
IndexMaskMemory memory;
|
||||
const Span<StringRef> selection_names = get_curves_selection_attribute_names(curves);
|
||||
Vector<MutableSpan<float3>> positions = get_curves_positions_for_write(curves);
|
||||
for (int attribute_i : selection_names.index_range()) {
|
||||
const IndexMask selection = retrieve_selected_points(
|
||||
curves, selection_names[attribute_i], memory);
|
||||
if (selection.is_empty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
selection.foreach_index([&](const int point) {
|
||||
apply_raw_diff_v3(
|
||||
positions[attribute_i][point], tot, ve_median.location, median.location);
|
||||
});
|
||||
}
|
||||
curves.tag_positions_changed();
|
||||
}
|
||||
}
|
||||
|
||||
// ED_undo_push(C, "Transform properties");
|
||||
}
|
||||
|
||||
#undef TRANSFORM_MEDIAN_ARRAY_LEN
|
||||
@@ -1691,7 +1826,7 @@ static void do_view3d_region_buttons(bContext *C, void * /*index*/, int event)
|
||||
|
||||
case B_TRANSFORM_PANEL_MEDIAN:
|
||||
if (ob) {
|
||||
v3d_editvertex_buts(nullptr, v3d, ob, 1.0);
|
||||
v3d_editvertex_buts(C, nullptr, v3d, ob, 1.0);
|
||||
DEG_id_tag_update(static_cast<ID *>(ob->data), ID_RECALC_GEOMETRY);
|
||||
}
|
||||
break;
|
||||
@@ -1738,7 +1873,7 @@ static void view3d_panel_transform(const bContext *C, Panel *panel)
|
||||
}
|
||||
else {
|
||||
View3D *v3d = CTX_wm_view3d(C);
|
||||
v3d_editvertex_buts(col, v3d, ob, FLT_MAX);
|
||||
v3d_editvertex_buts(C, col, v3d, ob, FLT_MAX);
|
||||
}
|
||||
}
|
||||
else if (ob->mode & OB_MODE_POSE) {
|
||||
|
||||
Reference in New Issue
Block a user