Cleanup: Splines: Add accessors to spline vector
Not allowing external direct access to the vector of splines in the curve will help for things like reallocating custom data when a spline is added or removed.
This commit is contained in:
parent
3ef01692c8
commit
50bf033d3f
|
@ -478,8 +478,15 @@ class PolySpline final : public Spline {
|
|||
* more of the data is stored in the splines, but also just to be different than the name in DNA.
|
||||
*/
|
||||
class CurveEval {
|
||||
private:
|
||||
blender::Vector<SplinePtr> splines_;
|
||||
|
||||
public:
|
||||
blender::Vector<SplinePtr> splines;
|
||||
blender::Span<SplinePtr> splines() const;
|
||||
blender::MutableSpan<SplinePtr> splines();
|
||||
|
||||
void add_spline(SplinePtr spline);
|
||||
void remove_splines(blender::IndexMask mask);
|
||||
|
||||
CurveEval *copy();
|
||||
|
||||
|
|
|
@ -27,12 +27,34 @@ using blender::float3;
|
|||
using blender::float4x4;
|
||||
using blender::Span;
|
||||
|
||||
blender::Span<SplinePtr> CurveEval::splines() const
|
||||
{
|
||||
return splines_;
|
||||
}
|
||||
|
||||
blender::MutableSpan<SplinePtr> CurveEval::splines()
|
||||
{
|
||||
return splines_;
|
||||
}
|
||||
|
||||
void CurveEval::add_spline(SplinePtr spline)
|
||||
{
|
||||
splines_.append(std::move(spline));
|
||||
}
|
||||
|
||||
void CurveEval::remove_splines(blender::IndexMask mask)
|
||||
{
|
||||
for (int i = mask.size() - 1; i >= 0; i--) {
|
||||
splines_.remove_and_reorder(mask.indices()[i]);
|
||||
}
|
||||
}
|
||||
|
||||
CurveEval *CurveEval::copy()
|
||||
{
|
||||
CurveEval *new_curve = new CurveEval();
|
||||
|
||||
for (SplinePtr &spline : this->splines) {
|
||||
new_curve->splines.append(spline->copy());
|
||||
for (SplinePtr &spline : this->splines()) {
|
||||
new_curve->add_spline(spline->copy());
|
||||
}
|
||||
|
||||
return new_curve;
|
||||
|
@ -40,7 +62,7 @@ CurveEval *CurveEval::copy()
|
|||
|
||||
void CurveEval::translate(const float3 &translation)
|
||||
{
|
||||
for (SplinePtr &spline : this->splines) {
|
||||
for (SplinePtr &spline : this->splines()) {
|
||||
spline->translate(translation);
|
||||
spline->mark_cache_invalid();
|
||||
}
|
||||
|
@ -48,14 +70,14 @@ void CurveEval::translate(const float3 &translation)
|
|||
|
||||
void CurveEval::transform(const float4x4 &matrix)
|
||||
{
|
||||
for (SplinePtr &spline : this->splines) {
|
||||
for (SplinePtr &spline : this->splines()) {
|
||||
spline->transform(matrix);
|
||||
}
|
||||
}
|
||||
|
||||
void CurveEval::bounds_min_max(float3 &min, float3 &max, const bool use_evaluated) const
|
||||
{
|
||||
for (const SplinePtr &spline : this->splines) {
|
||||
for (const SplinePtr &spline : this->splines()) {
|
||||
spline->bounds_min_max(min, max, use_evaluated);
|
||||
}
|
||||
}
|
||||
|
@ -115,8 +137,6 @@ std::unique_ptr<CurveEval> curve_eval_from_dna_curve(const Curve &dna_curve)
|
|||
|
||||
const ListBase *nurbs = BKE_curve_nurbs_get(&const_cast<Curve &>(dna_curve));
|
||||
|
||||
curve->splines.reserve(BLI_listbase_count(nurbs));
|
||||
|
||||
/* TODO: Optimize by reserving the correct points size. */
|
||||
LISTBASE_FOREACH (const Nurb *, nurb, nurbs) {
|
||||
switch (nurb->type) {
|
||||
|
@ -135,7 +155,7 @@ std::unique_ptr<CurveEval> curve_eval_from_dna_curve(const Curve &dna_curve)
|
|||
bezt.tilt);
|
||||
}
|
||||
|
||||
curve->splines.append(std::move(spline));
|
||||
curve->add_spline(std::move(spline));
|
||||
break;
|
||||
}
|
||||
case CU_NURBS: {
|
||||
|
@ -149,7 +169,7 @@ std::unique_ptr<CurveEval> curve_eval_from_dna_curve(const Curve &dna_curve)
|
|||
spline->add_point(bp.vec, bp.radius, bp.tilt, bp.vec[3]);
|
||||
}
|
||||
|
||||
curve->splines.append(std::move(spline));
|
||||
curve->add_spline(std::move(spline));
|
||||
break;
|
||||
}
|
||||
case CU_POLY: {
|
||||
|
@ -160,7 +180,7 @@ std::unique_ptr<CurveEval> curve_eval_from_dna_curve(const Curve &dna_curve)
|
|||
spline->add_point(bp.vec, bp.radius, bp.tilt);
|
||||
}
|
||||
|
||||
curve->splines.append(std::move(spline));
|
||||
curve->add_spline(std::move(spline));
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
|
@ -174,7 +194,7 @@ std::unique_ptr<CurveEval> curve_eval_from_dna_curve(const Curve &dna_curve)
|
|||
* from multiple curve objects, where the value may be different. */
|
||||
const Spline::NormalCalculationMode normal_mode = normal_mode_from_dna_curve(
|
||||
dna_curve.twist_mode);
|
||||
for (SplinePtr &spline : curve->splines) {
|
||||
for (SplinePtr &spline : curve->splines()) {
|
||||
spline->normal_mode = normal_mode;
|
||||
}
|
||||
|
||||
|
|
|
@ -125,13 +125,13 @@ int CurveComponent::attribute_domain_size(const AttributeDomain domain) const
|
|||
}
|
||||
if (domain == ATTR_DOMAIN_POINT) {
|
||||
int total = 0;
|
||||
for (const SplinePtr &spline : curve_->splines) {
|
||||
for (const SplinePtr &spline : curve_->splines()) {
|
||||
total += spline->size();
|
||||
}
|
||||
return total;
|
||||
}
|
||||
if (domain == ATTR_DOMAIN_CURVE) {
|
||||
return curve_->splines.size();
|
||||
return curve_->splines().size();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -245,7 +245,7 @@ static void set_spline_resolution(SplinePtr &spline, const int resolution)
|
|||
static GVArrayPtr make_resolution_read_attribute(const CurveEval &curve)
|
||||
{
|
||||
return std::make_unique<fn::GVArray_For_DerivedSpan<SplinePtr, int, get_spline_resolution>>(
|
||||
curve.splines.as_span());
|
||||
curve.splines());
|
||||
}
|
||||
|
||||
static GVMutableArrayPtr make_resolution_write_attribute(CurveEval &curve)
|
||||
|
@ -254,7 +254,7 @@ static GVMutableArrayPtr make_resolution_write_attribute(CurveEval &curve)
|
|||
int,
|
||||
get_spline_resolution,
|
||||
set_spline_resolution>>(
|
||||
curve.splines.as_mutable_span());
|
||||
curve.splines());
|
||||
}
|
||||
|
||||
static bool get_cyclic_value(const SplinePtr &spline)
|
||||
|
@ -273,14 +273,14 @@ static void set_cyclic_value(SplinePtr &spline, const bool value)
|
|||
static GVArrayPtr make_cyclic_read_attribute(const CurveEval &curve)
|
||||
{
|
||||
return std::make_unique<fn::GVArray_For_DerivedSpan<SplinePtr, bool, get_cyclic_value>>(
|
||||
curve.splines.as_span());
|
||||
curve.splines());
|
||||
}
|
||||
|
||||
static GVMutableArrayPtr make_cyclic_write_attribute(CurveEval &curve)
|
||||
{
|
||||
return std::make_unique<
|
||||
fn::GVMutableArray_For_DerivedSpan<SplinePtr, bool, get_cyclic_value, set_cyclic_value>>(
|
||||
curve.splines.as_mutable_span());
|
||||
curve.splines());
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
@ -296,12 +296,13 @@ static GVMutableArrayPtr make_cyclic_write_attribute(CurveEval &curve)
|
|||
|
||||
static Array<int> control_point_offsets(const CurveEval &curve)
|
||||
{
|
||||
Array<int> offsets(curve.splines.size() + 1);
|
||||
Span<SplinePtr> splines = curve.splines();
|
||||
Array<int> offsets(splines.size() + 1);
|
||||
|
||||
int size = 0;
|
||||
for (const int spline_index : curve.splines.index_range()) {
|
||||
for (const int spline_index : splines.index_range()) {
|
||||
offsets[spline_index] = size;
|
||||
size += curve.splines[spline_index]->size();
|
||||
size += splines[spline_index]->size();
|
||||
}
|
||||
offsets.last() = size;
|
||||
|
||||
|
@ -584,14 +585,15 @@ template<typename T> class BuiltinPointAttributeProvider : public BuiltinAttribu
|
|||
return {};
|
||||
}
|
||||
|
||||
if (curve->splines.size() == 1) {
|
||||
return std::make_unique<fn::GVArray_For_GSpan>(get_span_(*curve->splines.first()));
|
||||
Span<SplinePtr> splines = curve->splines();
|
||||
if (splines.size() == 1) {
|
||||
return std::make_unique<fn::GVArray_For_GSpan>(get_span_(*splines.first()));
|
||||
}
|
||||
|
||||
Array<int> offsets = control_point_offsets(*curve);
|
||||
Array<Span<T>> spans(curve->splines.size());
|
||||
for (const int i : curve->splines.index_range()) {
|
||||
spans[i] = get_span_(*curve->splines[i]);
|
||||
Array<Span<T>> spans(splines.size());
|
||||
for (const int i : splines.index_range()) {
|
||||
spans[i] = get_span_(*splines[i]);
|
||||
}
|
||||
|
||||
return std::make_unique<fn::GVArray_For_EmbeddedVArray<T, VArray_For_SplinePoints<T>>>(
|
||||
|
@ -605,17 +607,18 @@ template<typename T> class BuiltinPointAttributeProvider : public BuiltinAttribu
|
|||
return {};
|
||||
}
|
||||
|
||||
if (curve->splines.size() == 1) {
|
||||
MutableSpan<SplinePtr> splines = curve->splines();
|
||||
if (splines.size() == 1) {
|
||||
return std::make_unique<fn::GVMutableArray_For_GMutableSpan>(
|
||||
get_mutable_span_(*curve->splines.first()));
|
||||
get_mutable_span_(*splines.first()));
|
||||
}
|
||||
|
||||
Array<int> offsets = control_point_offsets(*curve);
|
||||
Array<MutableSpan<T>> spans(curve->splines.size());
|
||||
for (const int i : curve->splines.index_range()) {
|
||||
spans[i] = get_mutable_span_(*curve->splines[i]);
|
||||
Array<MutableSpan<T>> spans(splines.size());
|
||||
for (const int i : splines.index_range()) {
|
||||
spans[i] = get_mutable_span_(*splines[i]);
|
||||
if (update_on_write_) {
|
||||
update_on_write_(*curve->splines[i]);
|
||||
update_on_write_(*splines[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -668,7 +671,7 @@ class PositionAttributeProvider final : public BuiltinPointAttributeProvider<flo
|
|||
/* Changing the positions requires recalculation of cached evaluated data in many cases.
|
||||
* This could set more specific flags in the future to avoid unnecessary recomputation. */
|
||||
bool curve_has_bezier_spline = false;
|
||||
for (SplinePtr &spline : curve->splines) {
|
||||
for (SplinePtr &spline : curve->splines()) {
|
||||
if (spline->type() == Spline::Type::Bezier) {
|
||||
curve_has_bezier_spline = true;
|
||||
break;
|
||||
|
@ -681,14 +684,14 @@ class PositionAttributeProvider final : public BuiltinPointAttributeProvider<flo
|
|||
return BuiltinPointAttributeProvider<float3>::try_get_for_write(component);
|
||||
}
|
||||
|
||||
for (SplinePtr &spline : curve->splines) {
|
||||
for (SplinePtr &spline : curve->splines()) {
|
||||
spline->mark_cache_invalid();
|
||||
}
|
||||
|
||||
Array<int> offsets = control_point_offsets(*curve);
|
||||
return std::make_unique<
|
||||
fn::GVMutableArray_For_EmbeddedVMutableArray<float3, VMutableArray_For_SplinePosition>>(
|
||||
offsets.last(), curve->splines, std::move(offsets));
|
||||
offsets.last(), curve->splines(), std::move(offsets));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -528,11 +528,11 @@ static void join_curve_splines(Span<GeometryInstanceGroup> set_groups, CurveComp
|
|||
}
|
||||
|
||||
const CurveEval &source_curve = *set.get_curve_for_read();
|
||||
for (const SplinePtr &source_spline : source_curve.splines) {
|
||||
for (const SplinePtr &source_spline : source_curve.splines()) {
|
||||
for (const float4x4 &transform : set_group.transforms) {
|
||||
SplinePtr new_spline = source_spline->copy();
|
||||
new_spline->transform(transform);
|
||||
new_curve->splines.append(std::move(new_spline));
|
||||
new_curve->add_spline(std::move(new_spline));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -139,16 +139,16 @@ static std::unique_ptr<CurveEval> resample_curve(const CurveEval &input_curve,
|
|||
{
|
||||
std::unique_ptr<CurveEval> output_curve = std::make_unique<CurveEval>();
|
||||
|
||||
for (const SplinePtr &spline : input_curve.splines) {
|
||||
for (const SplinePtr &spline : input_curve.splines()) {
|
||||
if (mode_param.mode == GEO_NODE_CURVE_SAMPLE_COUNT) {
|
||||
BLI_assert(mode_param.count);
|
||||
output_curve->splines.append(resample_spline(*spline, *mode_param.count));
|
||||
output_curve->add_spline(resample_spline(*spline, *mode_param.count));
|
||||
}
|
||||
else if (mode_param.mode == GEO_NODE_CURVE_SAMPLE_LENGTH) {
|
||||
BLI_assert(mode_param.length);
|
||||
const float length = spline->length();
|
||||
const int count = length / *mode_param.length;
|
||||
output_curve->splines.append(resample_spline(*spline, count));
|
||||
output_curve->add_spline(resample_spline(*spline, count));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -211,7 +211,7 @@ static Mesh *curve_to_mesh_calculate(const CurveEval &curve, const CurveEval &pr
|
|||
{
|
||||
int profile_vert_total = 0;
|
||||
int profile_edge_total = 0;
|
||||
for (const SplinePtr &profile_spline : profile_curve.splines) {
|
||||
for (const SplinePtr &profile_spline : profile_curve.splines()) {
|
||||
profile_vert_total += profile_spline->evaluated_points_size();
|
||||
profile_edge_total += profile_spline->evaluated_edges_size();
|
||||
}
|
||||
|
@ -219,7 +219,7 @@ static Mesh *curve_to_mesh_calculate(const CurveEval &curve, const CurveEval &pr
|
|||
int vert_total = 0;
|
||||
int edge_total = 0;
|
||||
int poly_total = 0;
|
||||
for (const SplinePtr &spline : curve.splines) {
|
||||
for (const SplinePtr &spline : curve.splines()) {
|
||||
const int spline_vert_len = spline->evaluated_points_size();
|
||||
const int spline_edge_len = spline->evaluated_edges_size();
|
||||
vert_total += spline_vert_len * profile_vert_total;
|
||||
|
@ -247,8 +247,8 @@ static Mesh *curve_to_mesh_calculate(const CurveEval &curve, const CurveEval &pr
|
|||
int edge_offset = 0;
|
||||
int loop_offset = 0;
|
||||
int poly_offset = 0;
|
||||
for (const SplinePtr &spline : curve.splines) {
|
||||
for (const SplinePtr &profile_spline : profile_curve.splines) {
|
||||
for (const SplinePtr &spline : curve.splines()) {
|
||||
for (const SplinePtr &profile_spline : profile_curve.splines()) {
|
||||
spline_extrude_to_mesh_data(*spline,
|
||||
*profile_spline,
|
||||
verts,
|
||||
|
@ -272,7 +272,7 @@ static CurveEval get_curve_single_vert()
|
|||
CurveEval curve;
|
||||
std::unique_ptr<PolySpline> spline = std::make_unique<PolySpline>();
|
||||
spline->add_point(float3(0), 0, 0.0f);
|
||||
curve.splines.append(std::move(spline));
|
||||
curve.add_spline(std::move(spline));
|
||||
|
||||
return curve;
|
||||
}
|
||||
|
|
|
@ -305,8 +305,8 @@ static void join_curve_components(MutableSpan<GeometrySet> src_geometry_sets, Ge
|
|||
CurveEval *dst_curve = new CurveEval();
|
||||
for (CurveComponent *component : src_components) {
|
||||
CurveEval *src_curve = component->get_for_write();
|
||||
for (SplinePtr &spline : src_curve->splines) {
|
||||
dst_curve->splines.append(std::move(spline));
|
||||
for (SplinePtr &spline : src_curve->splines()) {
|
||||
dst_curve->add_spline(std::move(spline));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue