CurvesGeometry: Add initial vertex group support #106944

Merged
Falk David merged 24 commits from filedescriptor/blender:curves-deform-verts into main 2023-09-27 10:26:16 +02:00
2 changed files with 134 additions and 8 deletions
Showing only changes of commit 1617379a68 - Show all commits

View File

@ -32,6 +32,7 @@
#include "DNA_scene_types.h"
#include "BKE_action.h"
#include "BKE_curves.hh"
#include "BKE_deform.h"
#include "BKE_editmesh.h"
#include "BKE_gpencil_legacy.h"
@ -111,14 +112,22 @@ bDeformGroup *BKE_object_defgroup_add(Object *ob)
MDeformVert *BKE_object_defgroup_data_create(ID *id)
{
if (GS(id->name) == ID_ME) {
return BKE_mesh_deform_verts_for_write((Mesh *)id);
}
if (GS(id->name) == ID_LT) {
Lattice *lt = (Lattice *)id;
lt->dvert = static_cast<MDeformVert *>(MEM_callocN(
sizeof(MDeformVert) * lt->pntsu * lt->pntsv * lt->pntsw, "lattice deformVert"));
return lt->dvert;
switch (GS(id->name)) {
case ID_ME: {
return BKE_mesh_deform_verts_for_write((Mesh *)id);
}
case ID_LT: {
Lattice *lt = (Lattice *)id;
lt->dvert = static_cast<MDeformVert *>(MEM_callocN(
sizeof(MDeformVert) * lt->pntsu * lt->pntsv * lt->pntsw, "lattice deformVert"));
return lt->dvert;
}
case ID_CV: {
Curves *curves_id = reinterpret_cast<Curves *>(id);
filedescriptor marked this conversation as resolved Outdated

Same here, ID_CV and OB_CURVES don't need to be supported right now (at least in this commit)

Same here, `ID_CV` and `OB_CURVES` don't need to be supported right now (at least in this commit)
return curves_id->geometry.wrap().deform_verts_for_write().data();
}
default:
BLI_assert_unreachable();
}
return nullptr;
@ -197,6 +206,25 @@ bool BKE_object_defgroup_clear(Object *ob, bDeformGroup *dg, const bool use_sele
}
}
}
else if (ob->type == OB_CURVES) {
using namespace blender;
Curves *curves_id = static_cast<Curves *>(ob->data);
bke::CurvesGeometry &curves = curves_id->geometry.wrap();
const Span<MDeformVert> dverts = curves.deform_verts();
if (!dverts.is_empty()) {
const VArray<bool> selection = *curves.attributes().lookup_or_default<bool>(
".selection", ATTR_DOMAIN_POINT, true);
MutableSpan<MDeformVert> dverts = curves.deform_verts_for_write();
for (const int64_t index : curves.points_range()) {
if (&dverts[index] && (!use_selection || selection[index])) {
MDeformWeight *dw = BKE_defvert_find_index(&dverts[index], def_nr);
BKE_defvert_remove_group(&dverts[index], dw); /* dw can be nullptr */
changed = true;
}
}
}
}
return changed;
}
@ -264,6 +292,11 @@ static void object_defgroup_remove_common(Object *ob, bDeformGroup *dg, const in
Lattice *lt = object_defgroup_lattice_get((ID *)(ob->data));
MEM_SAFE_FREE(lt->dvert);
}
else if (ob->type == OB_CURVES) {
Curves *curves_id = static_cast<Curves *>(ob->data);
CustomData_free_layer_active(
&curves_id->geometry.point_data, CD_MDEFORMVERT, curves_id->geometry.point_num);
}
}
else if (BKE_object_defgroup_active_index_get(ob) < 1) {
/* Keep a valid active index if we still have some vgroups. */
@ -357,6 +390,25 @@ static void object_defgroup_remove_edit_mode(Object *ob, bDeformGroup *dg)
}
}
}
else if (ob->type == OB_CURVES) {
using namespace blender;
Curves *curves_id = static_cast<Curves *>(ob->data);
bke::CurvesGeometry &curves = curves_id->geometry.wrap();
MutableSpan<MDeformVert> dverts = curves.deform_verts_for_write();
threading::parallel_for(curves.points_range(), 4096, [&](const IndexRange range) {
for (const int64_t index : range) {
MDeformVert *dvert = &dverts[index];
if (dvert) {
for (int64_t i = 0; i < dvert->totweight; i++) {
if (dvert->dw[i].def_nr > def_nr) {
dvert->dw[i].def_nr--;
}
}
}
}
});
}
object_defgroup_remove_common(ob, dg, def_nr);
}
@ -411,6 +463,11 @@ void BKE_object_defgroup_remove_all_ex(Object *ob, bool only_unlocked)
Lattice *lt = object_defgroup_lattice_get((ID *)(ob->data));
MEM_SAFE_FREE(lt->dvert);
}
else if (ob->type == OB_CURVES) {
Curves *curves_id = static_cast<Curves *>(ob->data);
CustomData_free_layer_active(
&curves_id->geometry.point_data, CD_MDEFORMVERT, curves_id->geometry.point_num);
}
/* Fix counters/indices */
BKE_object_defgroup_active_index_set(ob, 0);
}
@ -506,6 +563,11 @@ bool BKE_object_defgroup_array_get(ID *id, MDeformVert **dvert_arr, int *dvert_t
*dvert_tot = lt->pntsu * lt->pntsv * lt->pntsw;
return true;
}
case ID_CV: {
Curves *curves_id = reinterpret_cast<Curves *>(id);
*dvert_arr = const_cast<MDeformVert *>(curves_id->geometry.wrap().deform_verts().data());
*dvert_tot = curves_id->geometry.point_num;
}
default:
break;
}

View File

@ -33,6 +33,7 @@
#include "BKE_attribute.hh"
#include "BKE_context.h"
#include "BKE_curves.hh"
#include "BKE_customdata.h"
#include "BKE_deform.h"
#include "BKE_editmesh.h"
@ -60,6 +61,7 @@
#include "WM_api.hh"
#include "WM_types.hh"
#include "ED_curves.hh"
#include "ED_mesh.hh"
#include "ED_object.hh"
#include "ED_screen.hh"
@ -254,7 +256,34 @@ bool ED_vgroup_parray_alloc(ID *id,
}
return false;
}
case ID_CV: {
Curves *curves_id = reinterpret_cast<Curves *>(id);
bke::CurvesGeometry &curves = curves_id->geometry.wrap();
if (!curves.deform_verts().is_empty()) {
MutableSpan<MDeformVert> dverts = curves.deform_verts_for_write();
*dvert_tot = curves.points_num();
*dvert_arr = static_cast<MDeformVert **>(
MEM_mallocN(sizeof(void *) * curves.points_num(), __func__));
if (use_vert_sel) {
const VArray<bool> selection = *curves.attributes().lookup_or_default<bool>(
".selection", ATTR_DOMAIN_POINT, true);
for (int64_t i = 0; i < curves.points_num(); i++) {
(*dvert_arr)[i] = selection[i] ? &dverts[i] : nullptr;
}
}
else {
for (int64_t i = 0; i < curves.points_num(); i++) {
(*dvert_arr)[i] = &dverts[i];
}
}
return true;
}
return false;
}
default:
break;
}
@ -1106,6 +1135,24 @@ static void vgroup_select_verts(Object *ob, int select)
}
}
}
else if (ob->type == OB_CURVES) {
Curves *curves_id = static_cast<Curves *>(ob->data);
bke::CurvesGeometry &curves = curves_id->geometry.wrap();
const Span<MDeformVert> dverts = curves.deform_verts();
if (!dverts.is_empty()) {
bke::GSpanAttributeWriter selection = ed::curves::ensure_selection_attribute(
curves, ATTR_DOMAIN_POINT, CD_PROP_BOOL);
MutableSpan<bool> selection_typed = selection.span.typed<bool>();
threading::parallel_for(curves.points_range(), 4096, [&](const IndexRange range) {
for (const int64_t index : range) {
if (BKE_defvert_find_index(&dverts[index], def_nr)) {
selection_typed[index] = bool(select);
}
}
});
selection.finish();
}
}
}
static void vgroup_duplicate(Object *ob)
@ -2308,6 +2355,23 @@ static void vgroup_assign_verts(Object *ob, const float weight)
}
}
}
else if (ob->type == OB_CURVES) {
Curves *curves_id = static_cast<Curves *>(ob->data);
bke::CurvesGeometry &curves = curves_id->geometry.wrap();
const VArray<bool> selection = *curves.attributes().lookup_or_default<bool>(
".selection", ATTR_DOMAIN_POINT, true);
MutableSpan<MDeformVert> dverts = curves.deform_verts_for_write();
threading::parallel_for(curves.points_range(), 4096, [&](const IndexRange range) {
for (const int64_t index : range) {
if (selection[index]) {
if (MDeformWeight *dw = BKE_defvert_ensure_index(&dverts[index], def_nr)) {
dw->weight = weight;
}
}
}
});
}
}
/** \} */