Changeset View
Changeset View
Standalone View
Standalone View
source/blender/blenkernel/intern/geometry_component_curve.cc
| Show First 20 Lines • Show All 427 Lines • ▼ Show 20 Lines | public: | ||||
| { | { | ||||
| const CurveEval *curve = get_curve_from_component_for_read(component); | const CurveEval *curve = get_curve_from_component_for_read(component); | ||||
| if (curve == nullptr) { | if (curve == nullptr) { | ||||
| return {}; | return {}; | ||||
| } | } | ||||
| return as_read_attribute_(*curve); | return as_read_attribute_(*curve); | ||||
| } | } | ||||
| GVMutableArrayPtr try_get_for_write(GeometryComponent &component) const final | WriteAttributeLookup try_get_for_write(GeometryComponent &component) const final | ||||
| { | { | ||||
| if (writable_ != Writable) { | if (writable_ != Writable) { | ||||
| return {}; | return {}; | ||||
| } | } | ||||
| CurveEval *curve = get_curve_from_component_for_write(component); | CurveEval *curve = get_curve_from_component_for_write(component); | ||||
| if (curve == nullptr) { | if (curve == nullptr) { | ||||
| return {}; | return {}; | ||||
| } | } | ||||
| return as_write_attribute_(*curve); | return {as_write_attribute_(*curve), domain_}; | ||||
| } | } | ||||
| bool try_delete(GeometryComponent &UNUSED(component)) const final | bool try_delete(GeometryComponent &UNUSED(component)) const final | ||||
| { | { | ||||
| return false; | return false; | ||||
| } | } | ||||
| bool try_create(GeometryComponent &UNUSED(component), | bool try_create(GeometryComponent &UNUSED(component), | ||||
| ▲ Show 20 Lines • Show All 663 Lines • ▼ Show 20 Lines | GVArrayPtr try_get_for_read(const GeometryComponent &component) const override | ||||
| Array<Span<T>> spans(splines.size()); | Array<Span<T>> spans(splines.size()); | ||||
| for (const int i : splines.index_range()) { | for (const int i : splines.index_range()) { | ||||
| spans[i] = get_span_(*splines[i]); | spans[i] = get_span_(*splines[i]); | ||||
| } | } | ||||
| return point_data_gvarray(spans, offsets); | return point_data_gvarray(spans, offsets); | ||||
| } | } | ||||
| GVMutableArrayPtr try_get_for_write(GeometryComponent &component) const override | WriteAttributeLookup try_get_for_write(GeometryComponent &component) const override | ||||
| { | { | ||||
| CurveEval *curve = get_curve_from_component_for_write(component); | CurveEval *curve = get_curve_from_component_for_write(component); | ||||
| if (curve == nullptr) { | if (curve == nullptr) { | ||||
| return {}; | return {}; | ||||
| } | } | ||||
| if (!this->exists(component)) { | if (!this->exists(component)) { | ||||
| return {}; | return {}; | ||||
| } | } | ||||
| std::function<void()> tag_modified_fn; | |||||
| if (update_on_write_ != nullptr) { | |||||
| tag_modified_fn = [curve, update = update_on_write_]() { | |||||
| for (SplinePtr &spline : curve->splines()) { | |||||
| update(*spline); | |||||
| } | |||||
| }; | |||||
| } | |||||
| MutableSpan<SplinePtr> splines = curve->splines(); | MutableSpan<SplinePtr> splines = curve->splines(); | ||||
| if (splines.size() == 1) { | if (splines.size() == 1) { | ||||
| if (update_on_write_) { | return {std::make_unique<fn::GVMutableArray_For_GMutableSpan>( | ||||
| update_on_write_(*splines[0]); | get_mutable_span_(*splines.first())), | ||||
| } | domain_, | ||||
| return std::make_unique<fn::GVMutableArray_For_GMutableSpan>( | std::move(tag_modified_fn)}; | ||||
| get_mutable_span_(*splines.first())); | |||||
| } | } | ||||
| Array<int> offsets = curve->control_point_offsets(); | Array<int> offsets = curve->control_point_offsets(); | ||||
| Array<MutableSpan<T>> spans(splines.size()); | Array<MutableSpan<T>> spans(splines.size()); | ||||
| for (const int i : splines.index_range()) { | for (const int i : splines.index_range()) { | ||||
| spans[i] = get_mutable_span_(*splines[i]); | spans[i] = get_mutable_span_(*splines[i]); | ||||
| if (update_on_write_) { | |||||
| update_on_write_(*splines[i]); | |||||
| } | |||||
| } | } | ||||
| return point_data_gvarray(spans, offsets); | return {point_data_gvarray(spans, offsets), domain_, tag_modified_fn}; | ||||
| } | } | ||||
| bool try_delete(GeometryComponent &component) const final | bool try_delete(GeometryComponent &component) const final | ||||
| { | { | ||||
| if (deletable_ == DeletableEnum::NonDeletable) { | if (deletable_ == DeletableEnum::NonDeletable) { | ||||
| return false; | return false; | ||||
| } | } | ||||
| return remove_point_attribute(component, name_); | return remove_point_attribute(component, name_); | ||||
| ▲ Show 20 Lines • Show All 55 Lines • ▼ Show 20 Lines | PositionAttributeProvider() | ||||
| BuiltinAttributeProvider::NonDeletable, | BuiltinAttributeProvider::NonDeletable, | ||||
| [](const Spline &spline) { return spline.positions(); }, | [](const Spline &spline) { return spline.positions(); }, | ||||
| [](Spline &spline) { return spline.positions(); }, | [](Spline &spline) { return spline.positions(); }, | ||||
| [](Spline &spline) { spline.mark_cache_invalid(); }, | [](Spline &spline) { spline.mark_cache_invalid(); }, | ||||
| false) | false) | ||||
| { | { | ||||
| } | } | ||||
| GVMutableArrayPtr try_get_for_write(GeometryComponent &component) const final | WriteAttributeLookup try_get_for_write(GeometryComponent &component) const final | ||||
| { | { | ||||
| CurveEval *curve = get_curve_from_component_for_write(component); | CurveEval *curve = get_curve_from_component_for_write(component); | ||||
| if (curve == nullptr) { | if (curve == nullptr) { | ||||
| return {}; | return {}; | ||||
| } | } | ||||
| /* Use the regular position virtual array when there aren't any Bezier splines | /* Use the regular position virtual array when there aren't any Bezier splines | ||||
| * to avoid the overhead of checking the spline type for every point. */ | * to avoid the overhead of checking the spline type for every point. */ | ||||
| if (!curve->has_spline_with_type(Spline::Type::Bezier)) { | if (!curve->has_spline_with_type(Spline::Type::Bezier)) { | ||||
| return BuiltinPointAttributeProvider<float3>::try_get_for_write(component); | return BuiltinPointAttributeProvider<float3>::try_get_for_write(component); | ||||
| } | } | ||||
| auto tag_modified_fn = [curve]() { | |||||
| /* Changing the positions requires recalculation of cached evaluated data in many cases. | /* 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. */ | * This could set more specific flags in the future to avoid unnecessary recomputation. */ | ||||
| for (SplinePtr &spline : curve->splines()) { | curve->mark_cache_invalid(); | ||||
| spline->mark_cache_invalid(); | }; | ||||
| } | |||||
| Array<int> offsets = curve->control_point_offsets(); | Array<int> offsets = curve->control_point_offsets(); | ||||
| return std::make_unique< | return {std::make_unique< | ||||
| fn::GVMutableArray_For_EmbeddedVMutableArray<float3, VMutableArray_For_SplinePosition>>( | fn::GVMutableArray_For_EmbeddedVMutableArray<float3, | ||||
| offsets.last(), curve->splines(), std::move(offsets)); | VMutableArray_For_SplinePosition>>( | ||||
| offsets.last(), curve->splines(), std::move(offsets)), | |||||
| domain_, | |||||
| tag_modified_fn}; | |||||
| } | } | ||||
| }; | }; | ||||
| class BezierHandleAttributeProvider : public BuiltinAttributeProvider { | class BezierHandleAttributeProvider : public BuiltinAttributeProvider { | ||||
| private: | private: | ||||
| bool is_right_; | bool is_right_; | ||||
| public: | public: | ||||
| Show All 19 Lines | if (!curve->has_spline_with_type(Spline::Type::Bezier)) { | ||||
| return {}; | return {}; | ||||
| } | } | ||||
| Array<int> offsets = curve->control_point_offsets(); | Array<int> offsets = curve->control_point_offsets(); | ||||
| return std::make_unique<fn::GVArray_For_EmbeddedVArray<float3, VArray_For_BezierHandle>>( | return std::make_unique<fn::GVArray_For_EmbeddedVArray<float3, VArray_For_BezierHandle>>( | ||||
| offsets.last(), curve->splines(), std::move(offsets), is_right_); | offsets.last(), curve->splines(), std::move(offsets), is_right_); | ||||
| } | } | ||||
| GVMutableArrayPtr try_get_for_write(GeometryComponent &component) const override | WriteAttributeLookup try_get_for_write(GeometryComponent &component) const override | ||||
| { | { | ||||
| CurveEval *curve = get_curve_from_component_for_write(component); | CurveEval *curve = get_curve_from_component_for_write(component); | ||||
| if (curve == nullptr) { | if (curve == nullptr) { | ||||
| return {}; | return {}; | ||||
| } | } | ||||
| if (!curve->has_spline_with_type(Spline::Type::Bezier)) { | if (!curve->has_spline_with_type(Spline::Type::Bezier)) { | ||||
| return {}; | return {}; | ||||
| } | } | ||||
| auto tag_modified_fn = [curve]() { curve->mark_cache_invalid(); }; | |||||
| Array<int> offsets = curve->control_point_offsets(); | Array<int> offsets = curve->control_point_offsets(); | ||||
| return std::make_unique< | return { | ||||
| std::make_unique< | |||||
| fn::GVMutableArray_For_EmbeddedVMutableArray<float3, VMutableArray_For_BezierHandles>>( | fn::GVMutableArray_For_EmbeddedVMutableArray<float3, VMutableArray_For_BezierHandles>>( | ||||
| offsets.last(), curve->splines(), std::move(offsets), is_right_); | offsets.last(), curve->splines(), std::move(offsets), is_right_), | ||||
| domain_, | |||||
| tag_modified_fn}; | |||||
| } | } | ||||
| bool try_delete(GeometryComponent &UNUSED(component)) const final | bool try_delete(GeometryComponent &UNUSED(component)) const final | ||||
| { | { | ||||
| return false; | return false; | ||||
| } | } | ||||
| bool try_create(GeometryComponent &UNUSED(component), | bool try_create(GeometryComponent &UNUSED(component), | ||||
| ▲ Show 20 Lines • Show All 280 Lines • Show Last 20 Lines | |||||