Curves: Add initial transform support
This adds basic support for the transform operators for curves. Differential Revision: https://developer.blender.org/D17063
This commit is contained in:
parent
0b17d171d7
commit
50387964b6
|
@ -5332,7 +5332,10 @@ class VIEW3D_MT_edit_curves(Menu):
|
|||
bl_label = "Curves"
|
||||
|
||||
def draw(self, _context):
|
||||
pass
|
||||
layout = self.layout
|
||||
|
||||
layout.menu("VIEW3D_MT_transform")
|
||||
layout.separator()
|
||||
|
||||
|
||||
class VIEW3D_MT_object_mode_pie(Menu):
|
||||
|
|
|
@ -56,8 +56,7 @@ IndexMask retrieve_selected_curves(const Curves &curves_id, Vector<int64_t> &r_i
|
|||
return retrieve_selected_curves(curves, r_indices);
|
||||
}
|
||||
|
||||
static IndexMask retrieve_selected_points(const bke::CurvesGeometry &curves,
|
||||
Vector<int64_t> &r_indices)
|
||||
IndexMask retrieve_selected_points(const bke::CurvesGeometry &curves, Vector<int64_t> &r_indices)
|
||||
{
|
||||
return index_mask_ops::find_indices_from_virtual_array(
|
||||
curves.points_range(),
|
||||
|
|
|
@ -94,6 +94,7 @@ IndexMask retrieve_selected_curves(const Curves &curves_id, Vector<int64_t> &r_i
|
|||
* Find points that are selected (a selection factor greater than zero),
|
||||
* or points in curves with a selection factor greater than zero).
|
||||
*/
|
||||
IndexMask retrieve_selected_points(const bke::CurvesGeometry &curves, Vector<int64_t> &r_indices);
|
||||
IndexMask retrieve_selected_points(const Curves &curves_id, Vector<int64_t> &r_indices);
|
||||
|
||||
/**
|
||||
|
|
|
@ -30,6 +30,7 @@ set(SRC
|
|||
transform_convert_armature.c
|
||||
transform_convert_cursor.c
|
||||
transform_convert_curve.c
|
||||
transform_convert_curves.cc
|
||||
transform_convert_gpencil.c
|
||||
transform_convert_graph.c
|
||||
transform_convert_lattice.c
|
||||
|
|
|
@ -713,6 +713,7 @@ static void init_proportional_edit(TransInfo *t)
|
|||
if (!ELEM(t->data_type,
|
||||
&TransConvertType_Action,
|
||||
&TransConvertType_Curve,
|
||||
&TransConvertType_Curves,
|
||||
&TransConvertType_Graph,
|
||||
&TransConvertType_GPencil,
|
||||
&TransConvertType_Lattice,
|
||||
|
@ -784,6 +785,7 @@ static void init_TransDataContainers(TransInfo *t,
|
|||
&TransConvertType_Pose,
|
||||
&TransConvertType_EditArmature,
|
||||
&TransConvertType_Curve,
|
||||
&TransConvertType_Curves,
|
||||
&TransConvertType_GPencil,
|
||||
&TransConvertType_Lattice,
|
||||
&TransConvertType_MBall,
|
||||
|
@ -959,6 +961,9 @@ static TransConvertTypeInfo *convert_type_get(const TransInfo *t, Object **r_obj
|
|||
if (t->obedit_type == OB_ARMATURE) {
|
||||
return &TransConvertType_EditArmature;
|
||||
}
|
||||
if (t->obedit_type == OB_CURVES) {
|
||||
return &TransConvertType_Curves;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
if (ob && (ob->mode & OB_MODE_POSE)) {
|
||||
|
|
|
@ -134,6 +134,10 @@ extern TransConvertTypeInfo TransConvertType_Cursor3D;
|
|||
|
||||
extern TransConvertTypeInfo TransConvertType_Curve;
|
||||
|
||||
/* transform_convert_curves.cc */
|
||||
|
||||
extern TransConvertTypeInfo TransConvertType_Curves;
|
||||
|
||||
/* transform_convert_graph.c */
|
||||
|
||||
extern TransConvertTypeInfo TransConvertType_Graph;
|
||||
|
|
|
@ -0,0 +1,102 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup edtransform
|
||||
*/
|
||||
|
||||
#include "BLI_array.hh"
|
||||
#include "BLI_index_mask_ops.hh"
|
||||
#include "BLI_span.hh"
|
||||
|
||||
#include "BKE_curves.hh"
|
||||
|
||||
#include "ED_curves.h"
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "transform.h"
|
||||
#include "transform_convert.h"
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Curve/Surfaces Transform Creation
|
||||
* \{ */
|
||||
|
||||
namespace blender::ed::transform::curves {
|
||||
|
||||
static void createTransCurvesVerts(bContext * /*C*/, TransInfo *t)
|
||||
{
|
||||
MutableSpan<TransDataContainer> trans_data_contrainers(t->data_container, t->data_container_len);
|
||||
Array<Vector<int64_t>> selected_indices_per_object(t->data_container_len);
|
||||
Array<IndexMask> selection_per_object(t->data_container_len);
|
||||
|
||||
/* Count selected elements per object and create TransData structs. */
|
||||
for (const int i : trans_data_contrainers.index_range()) {
|
||||
TransDataContainer &tc = trans_data_contrainers[i];
|
||||
Curves *curves_id = static_cast<Curves *>(tc.obedit->data);
|
||||
bke::CurvesGeometry &curves = bke::CurvesGeometry::wrap(curves_id->geometry);
|
||||
|
||||
selection_per_object[i] = ed::curves::retrieve_selected_points(curves,
|
||||
selected_indices_per_object[i]);
|
||||
|
||||
tc.data_len = selection_per_object[i].size();
|
||||
if (tc.data_len > 0) {
|
||||
tc.data = MEM_cnew_array<TransData>(tc.data_len, __func__);
|
||||
}
|
||||
}
|
||||
|
||||
/* Populate TransData structs. */
|
||||
for (const int i : trans_data_contrainers.index_range()) {
|
||||
TransDataContainer &tc = trans_data_contrainers[i];
|
||||
if (tc.data_len == 0) {
|
||||
continue;
|
||||
}
|
||||
Curves *curves_id = static_cast<Curves *>(tc.obedit->data);
|
||||
bke::CurvesGeometry &curves = bke::CurvesGeometry::wrap(curves_id->geometry);
|
||||
IndexMask selected_indices = selection_per_object[i];
|
||||
|
||||
float mtx[3][3], smtx[3][3];
|
||||
copy_m3_m4(mtx, tc.obedit->object_to_world);
|
||||
pseudoinverse_m3_m3(smtx, mtx, PSEUDOINVERSE_EPSILON);
|
||||
|
||||
MutableSpan<float3> positions = curves.positions_for_write();
|
||||
threading::parallel_for(selected_indices.index_range(), 1024, [&](const IndexRange range) {
|
||||
for (const int selection_i : range) {
|
||||
TransData *td = &tc.data[selection_i];
|
||||
float *elem = reinterpret_cast<float *>(&positions[selected_indices[selection_i]]);
|
||||
copy_v3_v3(td->iloc, elem);
|
||||
copy_v3_v3(td->center, td->iloc);
|
||||
td->loc = elem;
|
||||
|
||||
td->flag = TD_SELECTED;
|
||||
td->ext = nullptr;
|
||||
|
||||
copy_m3_m3(td->smtx, smtx);
|
||||
copy_m3_m3(td->mtx, mtx);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
static void recalcData_curves(TransInfo *t)
|
||||
{
|
||||
Span<TransDataContainer> trans_data_contrainers(t->data_container, t->data_container_len);
|
||||
for (const TransDataContainer &tc : trans_data_contrainers) {
|
||||
Curves *curves_id = static_cast<Curves *>(tc.obedit->data);
|
||||
bke::CurvesGeometry &curves = bke::CurvesGeometry::wrap(curves_id->geometry);
|
||||
|
||||
curves.calculate_bezier_auto_handles();
|
||||
curves.tag_positions_changed();
|
||||
DEG_id_tag_update(&curves_id->id, ID_RECALC_GEOMETRY);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace blender::ed::transform::curves
|
||||
|
||||
/** \} */
|
||||
|
||||
TransConvertTypeInfo TransConvertType_Curves = {
|
||||
/*flags*/ (T_EDIT | T_POINTS),
|
||||
/*createTransData*/ blender::ed::transform::curves::createTransCurvesVerts,
|
||||
/*recalcData*/ blender::ed::transform::curves::recalcData_curves,
|
||||
/*special_aftertrans_update*/ nullptr,
|
||||
};
|
Loading…
Reference in New Issue