53 const float3 &ray_start_cu,
55 const float brush_radius_re,
62 const float brush_inner_radius_re = std::min<float>(brush_radius_re, (
float)
UI_UNIT_X / 3.0f);
63 const float brush_inner_radius_sq_re =
pow2f(brush_inner_radius_re);
76 if (
b.distance_sq_re <= brush_inner_radius_sq_re) {
77 if (
a.distance_sq_re > brush_inner_radius_sq_re) {
81 if (
b.depth_sq_cu <
a.depth_sq_cu) {
86 else if (
b.distance_sq_re <
a.distance_sq_re) {
94 if (is_better_candidate(
a,
b)) {
106 for (
const int curve_i : curves_range) {
109 if (points.
size() == 1) {
110 const float3 &pos_cu = positions[points.first()];
112 const float depth_sq_cu = math::distance_squared(ray_start_cu, pos_cu);
113 if (depth_sq_cu > max_depth_sq_cu) {
122 candidate.depth_sq_cu = depth_sq_cu;
125 update_if_better(best_candidate, candidate);
129 for (
const int segment_i : points.drop_back(1)) {
130 const float3 &p1_cu = positions[segment_i];
131 const float3 &p2_cu = positions[segment_i + 1];
134 ED_view3d_project_float_v2_m4(®ion, p1_cu, p1_re, projection.values);
135 ED_view3d_project_float_v2_m4(®ion, p2_cu, p2_re, projection.values);
138 const float lambda = closest_to_line_segment_v2(
139 closest_re, brush_pos_re, p1_re, p2_re);
141 const float3 closest_cu = math::interpolate(p1_cu, p2_cu, lambda);
142 const float depth_sq_cu = math::distance_squared(ray_start_cu, closest_cu);
143 if (depth_sq_cu > max_depth_sq_cu) {
157 update_if_better(best_candidate, candidate);
160 return best_candidate;
162 [&](
const BrushPositionCandidate &
a,
const BrushPositionCandidate &
b) {
163 return is_better_candidate(
a,
b) ?
b :
a;
166 if (best_candidate.distance_sq_re == FLT_MAX) {
171 return best_candidate.position_cu;
178 const Object &curves_object,
179 const float2 &brush_pos_re,
180 const float brush_radius_re)
187 float3 center_ray_start_wo, center_ray_end_wo;
189 &
depsgraph, ®ion, &v3d, brush_pos_re, center_ray_start_wo, center_ray_end_wo,
true);
192 if (surface_object_eval !=
nullptr) {
201 const float3 center_ray_start_su = world_to_surface_mat * center_ray_start_wo;
202 float3 center_ray_end_su = world_to_surface_mat * center_ray_end_wo;
204 center_ray_start_su);
207 center_ray_hit.
dist = FLT_MAX;
208 center_ray_hit.
index = -1;
211 center_ray_direction_su,
216 if (center_ray_hit.
index >= 0) {
217 const float3 hit_position_su = center_ray_hit.
co;
220 center_ray_end_su = hit_position_su;
221 center_ray_end_wo = surface_to_world_mat * center_ray_end_su;
229 const float3 center_ray_start_cu = world_to_curves_mat * center_ray_start_wo;
230 const float3 center_ray_end_cu = world_to_curves_mat * center_ray_end_wo;
244 if (!brush_position_optional_cu.has_value()) {
248 const float3 brush_position_cu = *brush_position_optional_cu;
251 float3 radius_ray_start_wo, radius_ray_end_wo;
255 brush_pos_re +
float2(brush_radius_re, 0.0f),
259 const float3 radius_ray_start_cu = world_to_curves_mat * radius_ray_start_wo;
260 const float3 radius_ray_end_cu = world_to_curves_mat * radius_ray_end_wo;
274 const float2 &brush_pos_re,
275 const float brush_radius_re)
277 float3 brush_ray_start_wo, brush_ray_end_wo;
279 &
depsgraph, ®ion, &v3d, brush_pos_re, brush_ray_start_wo, brush_ray_end_wo,
true);
286 ray_hit.
dist = FLT_MAX;
290 brush_ray_direction_su,
294 const_cast<void *
>(
static_cast<const void *
>(&surface_bvh)));
295 if (ray_hit.
index == -1) {
299 float3 brush_radius_ray_start_wo, brush_radius_ray_end_wo;
303 brush_pos_re +
float2(brush_radius_re, 0),
304 brush_radius_ray_start_wo,
305 brush_radius_ray_end_wo,
310 const float3 brush_pos_su = ray_hit.
co;
313 brush_pos_cu, brush_radius_ray_start_cu, brush_radius_ray_end_cu);
322 if (symmetry &
type) {
323 static std::array<float, 2> values = {1.0f, -1.0f};
326 static std::array<float, 1> values = {1.0f};
333 float4x4 matrix = float4x4::identity();
346 const float3 &brush_position,
347 const float old_radius)
349 const float3 offset_position = brush_position +
float3(old_radius, 0.0f, 0.0f);
360 length_parameterize::accumulate_lengths<float3>(
positions,
false, orig_lengths);
361 const float orig_total_length = orig_lengths.
last();
365 const float new_total_length = orig_lengths.
last(1) + new_last_segment_length;
366 const float length_factor =
safe_divide(new_total_length, orig_total_length);
370 new_lengths.
first() = 0.0f;
372 new_lengths[i] = orig_lengths[i - 1] * length_factor;
380 length_parameterize::interpolate<float3>(
positions,
indices, factors, new_positions);
381 positions.drop_back(1).copy_from(new_positions);
385 CurvesSculptCommonContext::CurvesSculptCommonContext(
const bContext &
C)
412 reports,
RPT_WARNING,
TIP_(
"Missing UV map for attaching curves on original surface"));
418 reports,
RPT_WARNING,
TIP_(
"Missing UV map for attaching curves on evaluated surface"));
void free_bvhtree_from_mesh(struct BVHTreeFromMesh *data)
BVHTree * BKE_bvhtree_from_mesh_get(struct BVHTreeFromMesh *data, const struct Mesh *mesh, BVHCacheType bvh_cache_type, int tree_type)
struct Scene * CTX_data_scene(const bContext *C)
struct View3D * CTX_wm_view3d(const bContext *C)
struct ARegion * CTX_wm_region(const bContext *C)
struct Depsgraph * CTX_data_depsgraph_pointer(const bContext *C)
struct RegionView3D * CTX_wm_region_view3d(const bContext *C)
Low-level operations for curves.
General operations, lookup, etc. for blender objects.
struct Mesh * BKE_object_get_evaluated_mesh(const struct Object *object)
void BKE_report(ReportList *reports, eReportType type, const char *message)
int BLI_bvhtree_ray_cast(BVHTree *tree, const float co[3], const float dir[3], float radius, BVHTreeRayHit *hit, BVHTree_RayCastCallback callback, void *userdata)
MINLINE float pow2f(float x)
float closest_to_line_segment_v3(float r_close[3], const float p[3], const float l1[3], const float l2[3])
float dist_to_line_v3(const float p[3], const float l1[3], const float l2[3])
#define BLI_SCOPED_DEFER(function_to_defer)
struct Depsgraph Depsgraph
struct Object * DEG_get_evaluated_object(const struct Depsgraph *depsgraph, struct Object *object)
bool ED_view3d_win_to_segment_clipped(const struct Depsgraph *depsgraph, const struct ARegion *region, const struct View3D *v3d, const float mval[2], float r_ray_start[3], float r_ray_end[3], bool do_clip_planes)
void ED_view3d_ob_project_mat_get(const struct RegionView3D *v3d, const struct Object *ob, float r_pmat[4][4])
void ED_view3d_project_float_v2_m4(const struct ARegion *region, const float co[3], float r_co[2], const float mat[4][4])
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble z
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint y
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum type
Group Output data from inside of a node group A color picker Mix two input colors RGB to Convert a color s luminance to a grayscale value Generate a normal vector and a dot product Bright Control the brightness and contrast of the input color Vector Map an input vectors to curves
SIMD_FORCE_INLINE btVector3 transform(const btVector3 &point) const
const T & last(const int64_t n=0) const
IndexRange index_range() const
constexpr int64_t size() const
constexpr IndexRange drop_front(int64_t n) const
void append(const T &value)
const Depsgraph * depsgraph
ccl_gpu_kernel_postfix int ccl_global int * indices
GeometryDeformation get_evaluated_curves_deformation(const Depsgraph &depsgraph, const Object &ob_orig)
int segments_num(const int points_num, const bool cyclic)
static struct PartialUpdateUser * wrap(PartialUpdateUserImpl *user)
std::optional< CurvesBrush3D > sample_curves_surface_3d_brush(const Depsgraph &depsgraph, const ARegion ®ion, const View3D &v3d, const CurvesSurfaceTransforms &transforms, const BVHTreeFromMesh &surface_bvh, const float2 &brush_pos_re, const float brush_radius_re)
void report_invalid_uv_map(ReportList *reports)
void report_empty_evaluated_surface(ReportList *reports)
static std::optional< float3 > find_curves_brush_position(const CurvesGeometry &curves, const float3 &ray_start_cu, const float3 &ray_end_cu, const float brush_radius_re, const ARegion ®ion, const RegionView3D &rv3d, const Object &object, const Span< float3 > positions)
std::optional< CurvesBrush3D > sample_curves_3d_brush(const Depsgraph &depsgraph, const ARegion ®ion, const View3D &v3d, const RegionView3D &rv3d, const Object &curves_object, const float2 &brush_pos_re, const float brush_radius_re)
void move_last_point_and_resample(MutableSpan< float3 > positions, const float3 &new_last_position)
void report_missing_uv_map_on_original_surface(ReportList *reports)
void report_missing_uv_map_on_evaluated_surface(ReportList *reports)
void report_missing_surface(ReportList *reports)
void report_empty_original_surface(ReportList *reports)
Vector< float4x4 > get_symmetry_brush_transforms(const eCurvesSymmetryType symmetry)
float transform_brush_radius(const float4x4 &transform, const float3 &brush_position, const float old_radius)
void sample_at_lengths(Span< float > accumulated_segment_lengths, Span< float > sample_lengths, MutableSpan< int > r_segment_indices, MutableSpan< float > r_factors)
T distance_squared(const vec_base< T, Size > &a, const vec_base< T, Size > &b)
T distance(const T &a, const T &b)
vec_base< T, Size > normalize(const vec_base< T, Size > &v)
T safe_divide(const T &a, const T &b)
Value parallel_reduce(IndexRange range, int64_t grain_size, const Value &identity, const Function &function, const Reduction &reduction)
static const pxr::TfToken b("b", pxr::TfToken::Immortal)
MutableSpan< float3 > positions
BVHTree_RayCastCallback raycast_callback
float4x4 inverted() const