Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/blenkernel/BKE_curves.hh')
-rw-r--r--source/blender/blenkernel/BKE_curves.hh126
1 files changed, 121 insertions, 5 deletions
diff --git a/source/blender/blenkernel/BKE_curves.hh b/source/blender/blenkernel/BKE_curves.hh
index 2bebd3ff97d..568899721a9 100644
--- a/source/blender/blenkernel/BKE_curves.hh
+++ b/source/blender/blenkernel/BKE_curves.hh
@@ -11,6 +11,7 @@
#include <mutex>
+#include "BLI_float3x3.hh"
#include "BLI_float4x4.hh"
#include "BLI_generic_virtual_array.hh"
#include "BLI_index_mask.hh"
@@ -20,7 +21,7 @@
#include "BLI_vector.hh"
#include "BLI_virtual_array.hh"
-#include "BKE_attribute_access.hh"
+#include "BKE_attribute.hh"
namespace blender::bke {
@@ -385,8 +386,6 @@ class CurvesGeometry : public ::CurvesGeometry {
void calculate_bezier_auto_handles();
- void update_customdata_pointers();
-
void remove_points(IndexMask points_to_delete);
void remove_curves(IndexMask curves_to_delete);
@@ -401,6 +400,9 @@ class CurvesGeometry : public ::CurvesGeometry {
*/
void remove_attributes_based_on_types();
+ AttributeAccessor attributes() const;
+ MutableAttributeAccessor attributes_for_write();
+
/* --------------------------------------------------------------------
* Attributes.
*/
@@ -413,6 +415,38 @@ class CurvesGeometry : public ::CurvesGeometry {
}
};
+/**
+ * Used to propagate deformation data through modifier evaluation so that sculpt tools can work on
+ * evaluated data.
+ */
+class CurvesEditHints {
+ public:
+ /**
+ * Original data that the edit hints below are meant to be used for.
+ */
+ const Curves &curves_id_orig;
+ /**
+ * Evaluated positions for the points in #curves_orig. If this is empty, the positions from the
+ * evaluated #Curves should be used if possible.
+ */
+ std::optional<Array<float3>> positions;
+ /**
+ * Matrices which transform point movement vectors from original data to corresponding movements
+ * of evaluated data.
+ */
+ std::optional<Array<float3x3>> deform_mats;
+
+ CurvesEditHints(const Curves &curves_id_orig) : curves_id_orig(curves_id_orig)
+ {
+ }
+
+ /**
+ * The edit hints have to correspond to the original curves, i.e. the number of deformed points
+ * is the same as the number of original points.
+ */
+ bool is_valid() const;
+};
+
namespace curves {
/* -------------------------------------------------------------------- */
@@ -423,7 +457,7 @@ namespace curves {
* The number of segments between control points, accounting for the last segment of cyclic
* curves. The logic is simple, but this function should be used to make intentions clearer.
*/
-inline int curve_segment_num(const int points_num, const bool cyclic)
+inline int segments_num(const int points_num, const bool cyclic)
{
BLI_assert(points_num > 0);
return (cyclic && points_num > 1) ? points_num : points_num - 1;
@@ -483,6 +517,8 @@ namespace bezier {
* Return true if the handles that make up a segment both have a vector type. Vector segments for
* Bezier curves have special behavior because they aren't divided into many evaluated points.
*/
+bool segment_is_vector(const HandleType left, const HandleType right);
+bool segment_is_vector(const int8_t left, const int8_t right);
bool segment_is_vector(Span<int8_t> handle_types_left,
Span<int8_t> handle_types_right,
int segment_index);
@@ -515,6 +551,43 @@ void calculate_evaluated_offsets(Span<int8_t> handle_types_left,
int resolution,
MutableSpan<int> evaluated_offsets);
+/** See #insert. */
+struct Insertion {
+ float3 handle_prev;
+ float3 left_handle;
+ float3 position;
+ float3 right_handle;
+ float3 handle_next;
+};
+
+/**
+ * Compute the Bezier segment insertion for the given parameter on the segment, returning
+ * the position and handles of the new point and the updated existing handle positions.
+ * <pre>
+ * handle_prev handle_next
+ * x-----------------x
+ * / \
+ * / x---O---x \
+ * / result \
+ * / \
+ * O O
+ * point_prev point_next
+ * </pre>
+ */
+Insertion insert(const float3 &point_prev,
+ const float3 &handle_prev,
+ const float3 &handle_next,
+ const float3 &point_next,
+ float parameter);
+
+/**
+ * Calculate the automatically defined positions for a vector handle (#BEZIER_HANDLE_VECTOR). While
+ * this can be calculated automatically with #calculate_auto_handles, when more context is
+ * available, it can be preferable for performance reasons to calculate it for a single segment
+ * when necessary.
+ */
+float3 calculate_vector_handle(const float3 &point, const float3 &next_point);
+
/**
* Recalculate all auto (#BEZIER_HANDLE_AUTO) and vector (#BEZIER_HANDLE_VECTOR) handles with
* positions automatically derived from the neighboring control points, and update aligned
@@ -599,6 +672,15 @@ int calculate_evaluated_num(int points_num, bool cyclic, int resolution);
*/
void interpolate_to_evaluated(GSpan src, bool cyclic, int resolution, GMutableSpan dst);
+/**
+ * Evaluate the Catmull Rom curve. The size of each segment and its offset in the #dst span
+ * is encoded in #evaluated_offsets, with the same method as #CurvesGeometry::offsets().
+ */
+void interpolate_to_evaluated(const GSpan src,
+ const bool cyclic,
+ const Span<int> evaluated_offsets,
+ GMutableSpan dst);
+
} // namespace catmull_rom
/** \} */
@@ -684,6 +766,12 @@ Curves *curves_new_nomain(CurvesGeometry curves);
*/
Curves *curves_new_nomain_single(int points_num, CurveType type);
+/**
+ * Copy data from #src to #dst, except the geometry data in #CurvesGeometry. Typically used to
+ * copy high-level parameters when a geometry-altering operation creates a new curves data-block.
+ */
+void curves_copy_parameters(const Curves &src, Curves &dst);
+
std::array<int, CURVE_TYPES_NUM> calculate_type_counts(const VArray<int8_t> &types);
/* -------------------------------------------------------------------- */
@@ -782,7 +870,7 @@ inline IndexRange CurvesGeometry::lengths_range_for_curve(const int curve_index,
BLI_assert(cyclic == this->cyclic()[curve_index]);
const IndexRange points = this->evaluated_points_for_curve(curve_index);
const int start = points.start() + curve_index;
- return {start, curves::curve_segment_num(points.size(), cyclic)};
+ return {start, curves::segments_num(points.size(), cyclic)};
}
inline Span<float> CurvesGeometry::evaluated_lengths_for_curve(const int curve_index,
@@ -819,8 +907,36 @@ inline bool point_is_sharp(const Span<int8_t> handle_types_left,
ELEM(handle_types_right[index], BEZIER_HANDLE_VECTOR, BEZIER_HANDLE_FREE);
}
+inline bool segment_is_vector(const HandleType left, const HandleType right)
+{
+ return left == BEZIER_HANDLE_VECTOR && right == BEZIER_HANDLE_VECTOR;
+}
+
+inline bool segment_is_vector(const int8_t left, const int8_t right)
+{
+ return segment_is_vector(HandleType(left), HandleType(right));
+}
+
+inline float3 calculate_vector_handle(const float3 &point, const float3 &next_point)
+{
+ return math::interpolate(point, next_point, 1.0f / 3.0f);
+}
+
/** \} */
} // namespace curves::bezier
+struct CurvesSurfaceTransforms {
+ float4x4 curves_to_world;
+ float4x4 curves_to_surface;
+ float4x4 world_to_curves;
+ float4x4 world_to_surface;
+ float4x4 surface_to_world;
+ float4x4 surface_to_curves;
+ float4x4 surface_to_curves_normal;
+
+ CurvesSurfaceTransforms() = default;
+ CurvesSurfaceTransforms(const Object &curves_ob, const Object *surface_ob);
+};
+
} // namespace blender::bke