61 #define USE_SPLINE_FIT
64 # include "curve_fit_nd.h"
68 #define STROKE_SAMPLE_DIST_MIN_PX 1
69 #define STROKE_SAMPLE_DIST_MAX_PX 3
72 #define STROKE_CYCLIC_DIST_PX 8
184 const float mval_fl[2],
185 float surface_offset,
187 float r_location_world[3],
188 float r_normal_world[3])
193 bool is_location_world_set =
false;
199 region, cdd->
project.
plane, mval_fl,
true, r_location_world)) {
200 if (r_normal_world) {
203 is_location_world_set =
true;
208 if (depths && ((
uint)mval_i[0] < depths->
w) && ((
uint)mval_i[1] < depths->
h)) {
209 float depth_fl = 1.0f;
211 const double depth = (
double)depth_fl;
214 is_location_world_set =
true;
215 if (r_normal_world) {
219 if (surface_offset != 0.0f) {
224 if (r_normal_world) {
234 if (is_location_world_set) {
240 return is_location_world_set;
245 const float mval_fl[2],
246 const float surface_offset,
248 const float location_fallback_depth[3],
249 float r_location_world[3],
250 float r_location_local[3],
251 float r_normal_world[3],
252 float r_normal_local[3])
255 cdd, mval_i, mval_fl, surface_offset, radius, r_location_world, r_normal_world);
256 if (is_depth_found ==
false) {
258 cdd->
vc.
v3d, cdd->
vc.
region, location_fallback_depth, mval_fl, r_location_world);
272 return is_depth_found;
279 const float location_fallback_depth[3],
289 location_fallback_depth,
360 if (stroke_len == 0) {
367 if (cu->
ext2 > 0.0f) {
371 const float location_zero[3] = {0};
372 const float *location_prev = location_zero;
405 if (stroke_len > 1) {
406 float(*coord_array)[3] =
MEM_mallocN(
sizeof(*coord_array) * stroke_len, __func__);
431 for (
int i = 0; i < stroke_len; i++) {
440 for (
int i = 0; i < stroke_len; i++) {
469 selem->
pressure =
event->tablet.pressure;
474 if (is_depth_found) {
484 const struct StrokeElem selem_target = *selem;
489 for (
int i = 1; i < n; i++) {
490 struct StrokeElem *selem_new = selem_new_last;
495 if (is_depth_found ==
false) {
496 if (is_depth_found_substep) {
504 selem = selem_new_last;
505 *selem_new_last = selem_target;
534 float cross_a[3], cross_b[3];
555 float location_no_offset[3];
659 float len_3d = 0.0f, len_2d = 0.0f;
670 scale_px = ((len_3d > 0.0f) && (len_2d > 0.0f)) ? (len_3d / len_2d) : 0.0f;
677 bool use_cyclic =
false;
681 const struct StrokeElem *selem, *selem_first, *selem_last;
705 float *lengths =
MEM_mallocN(
sizeof(
float) * stroke_len, __func__);
714 selem_array[0] = selem_prev;
717 len_3d += len_3d_segment;
719 selem_array[i] = selem;
725 for (i = 0; i < stroke_len && lengths[i] < len_taper_max; i++) {
726 const float pressure_new = selem_array[i]->
pressure * (lengths[i] / len_taper_max);
733 const float len_taper_min = len_3d - len_taper_max;
734 for (i = stroke_len - 1; i > 0 && lengths[i] > len_taper_min; i--) {
735 const float pressure_new = selem_array[i]->
pressure *
736 ((len_3d - lengths[i]) / len_taper_max);
763 const bool is_3d = (cu->
flag &
CU_3D) != 0;
791 #ifdef USE_SPLINE_FIT
798 coords_indices.radius = use_pressure_radius ? dims++ : -1;
800 float *coords =
MEM_mallocN(
sizeof(*coords) * stroke_len * dims, __func__);
802 float *cubic_spline =
NULL;
803 uint cubic_spline_len = 0;
820 if (coords_indices.radius != -1) {
821 co[coords_indices.radius] = selem->
pressure;
825 if ((co != coords) &&
UNLIKELY(memcmp(co, co - dims,
sizeof(
float) * dims) == 0)) {
833 uint corners_len = 0;
837 const float corner_radius_min = error_threshold / 8;
838 const float corner_radius_max = error_threshold * 2;
839 const uint samples_max = 16;
841 curve_fit_corners_detect_fl(coords,
853 uint corners_index_len = 0;
854 uint calc_flag = CURVE_FIT_CALC_HIGH_QUALIY;
856 if ((stroke_len > 2) && use_cyclic) {
857 calc_flag |= CURVE_FIT_CALC_CYCLIC;
862 result = curve_fit_cubic_to_points_refit_fl(coords,
877 result = curve_fit_cubic_to_points_fl(coords,
897 nu->
pntsu = cubic_spline_len;
900 float *co = cubic_spline;
902 for (
int j = 0; j < cubic_spline_len; j++, bezt++, co += (dims * 3)) {
903 const float *handle_l = co + (dims * 0);
904 const float *pt = co + (dims * 1);
905 const float *handle_r = co + (dims * 2);
911 if (coords_indices.radius != -1) {
915 bezt->
radius = radius_max;
924 uint i_start = 0, i_end = corners_index_len;
926 if ((corners_index_len >= 2) && (calc_flag & CURVE_FIT_CALC_CYCLIC) == 0) {
931 for (
uint i = i_start; i < i_end; i++) {
932 bezt = &nu->
bezt[corners_index[i]];
937 if (calc_flag & CURVE_FIT_CALC_CYCLIC) {
951 nu->
pntsu = stroke_len;
964 bezt->
vec[1][2] = 0.0f;
967 if (use_pressure_radius) {
971 bezt->
radius = radius_max;
991 nu->
pntsu = stroke_len;
1011 if (use_pressure_radius) {
1074 const float *plane_no =
NULL;
1075 const float *plane_co =
NULL;
1079 plane_co = obedit->
obmat[3];
1080 plane_no = obedit->
obmat[2];
1118 if (is_modal ==
false) {
1202 "Error distance threshold (in object units)",
typedef float(TangentPoint)[2]
struct Scene * CTX_data_scene(const bContext *C)
struct Object * CTX_data_edit_object(const bContext *C)
struct ViewLayer * CTX_data_view_layer(const bContext *C)
struct Depsgraph * CTX_data_ensure_evaluated_depsgraph(const bContext *C)
struct Main * CTX_data_main(const bContext *C)
void BKE_nurb_handles_calc(struct Nurb *nu)
void BKE_nurb_knot_calc_u(struct Nurb *nu)
void BKE_curve_nurb_active_set(struct Curve *cu, const struct Nurb *nu)
void BKE_report(ReportList *reports, ReportType type, const char *message)
void BLI_kdtree_nd_() free(KDTree *tree)
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
MINLINE float square_f(float a)
MINLINE float interpf(float a, float b, float t)
bool invert_m4_m4(float R[4][4], const float A[4][4])
void mul_transposed_mat3_m4_v3(const float M[4][4], float r[3])
void mul_v3_m4v3(float r[3], const float M[4][4], const float v[3])
void interp_v2_v2v2(float r[2], const float a[2], const float b[2], const float t)
void interp_v3_v3v3(float r[3], const float a[3], const float b[3], const float t)
MINLINE float len_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void madd_v3_v3fl(float r[3], const float a[3], float f)
MINLINE float len_squared_v2v2(const float a[2], const float b[2]) ATTR_WARN_UNUSED_RESULT
MINLINE float normalize_v3(float r[3])
MINLINE void sub_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void copy_v2_v2(float r[2], const float a[2])
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE void negate_v3_v3(float r[3], const float a[3])
MINLINE bool is_zero_v3(const float a[3]) ATTR_WARN_UNUSED_RESULT
MINLINE float dot_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void cross_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE float normalize_v3_v3(float r[3], const float a[3])
MINLINE float len_v2v2(const float a[2], const float b[2]) ATTR_WARN_UNUSED_RESULT
MINLINE void zero_v3(float r[3])
MINLINE void add_v3_v3(float r[3], const float a[3])
void * BLI_mempool_calloc(BLI_mempool *pool) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void BLI_mempool_iternew(BLI_mempool *pool, BLI_mempool_iter *iter) ATTR_NONNULL()
void * BLI_mempool_iterstep(BLI_mempool_iter *iter) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
BLI_mempool * BLI_mempool_create(unsigned int esize, unsigned int totelem, unsigned int pchunk, unsigned int flag) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
void BLI_mempool_destroy(BLI_mempool *pool) ATTR_NONNULL(1)
int BLI_mempool_len(BLI_mempool *pool) ATTR_NONNULL(1)
#define ARRAY_SET_ITEMS(...)
typedef double(DMatrix)[4][4]
struct Depsgraph Depsgraph
void DEG_id_tag_update(struct ID *id, int flag)
Object is a sort of wrapper for general info.
@ CURVE_PAINT_PROJECT_SURFACE
@ CURVE_PAINT_FLAG_DEPTH_STROKE_ENDPOINTS
@ CURVE_PAINT_FLAG_DEPTH_STROKE_OFFSET_ABS
@ CURVE_PAINT_FLAG_CORNERS_DETECT
@ CURVE_PAINT_FLAG_PRESSURE_RADIUS
@ CURVE_PAINT_SURFACE_PLANE_NORMAL_SURFACE
@ CURVE_PAINT_SURFACE_PLANE_NORMAL_VIEW
@ CURVE_PAINT_FIT_METHOD_REFIT
@ CURVE_PAINT_FIT_METHOD_SPLIT
bool ED_operator_editcurve(struct bContext *C)
void ED_region_tag_redraw(struct ARegion *region)
#define REGION_DRAW_POST_VIEW
void * ED_region_draw_cb_activate(struct ARegionType *art, void(*draw)(const struct bContext *, struct ARegion *, void *), void *customdata, int type)
void ED_region_draw_cb_exit(struct ARegionType *, void *)
bool ED_view3d_win_to_3d_on_plane(const struct ARegion *region, const float plane[4], const float mval[2], const bool do_clip, float r_out[3])
bool ED_view3d_depth_read_cached(const ViewDepths *vd, const int mval[2], int margin, float *r_depth)
void ED_view3d_viewcontext_init(struct bContext *C, struct ViewContext *vc, struct Depsgraph *depsgraph)
bool ED_view3d_depth_read_cached_normal(const ViewContext *vc, const int mval[2], float r_normal[3])
bool ED_view3d_depth_unproject(const struct ARegion *region, const int mval[2], const double depth, float r_location_world[3])
void ED_view3d_depth_override(struct Depsgraph *depsgraph, struct ARegion *region, struct View3D *v3d, struct Object *obact, eV3DDepthOverrideMode mode, bool update_cache)
void ED_view3d_win_to_3d(const struct View3D *v3d, const struct ARegion *region, const float depth_pt[3], const float mval[2], float r_out[3])
void view3d_operator_needs_opengl(const struct bContext *C)
NSNotificationCenter * center
void GPU_batch_program_set_builtin(GPUBatch *batch, eGPUBuiltinShader shader_id)
void GPU_batch_draw(GPUBatch *batch)
#define GPU_batch_uniform_3fv(batch, name, val)
struct GPUBatch * GPU_batch_preset_sphere(int lod) ATTR_WARN_UNUSED_RESULT
_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 GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble y2 _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat y2 _GL_VOID_RET _GL_VOID GLint GLint GLint y2 _GL_VOID_RET _GL_VOID GLshort GLshort GLshort y2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLuint *buffer _GL_VOID_RET _GL_VOID GLdouble t _GL_VOID_RET _GL_VOID GLfloat t _GL_VOID_RET _GL_VOID GLint t _GL_VOID_RET _GL_VOID GLshort t _GL_VOID_RET _GL_VOID GLdouble t
void GPU_matrix_pop(void)
#define GPU_matrix_mul(x)
void GPU_matrix_push(void)
void GPU_matrix_scale_1f(float factor)
void GPU_matrix_translate_3f(float x, float y, float z)
@ GPU_SHADER_3D_UNIFORM_COLOR
void GPU_blend(eGPUBlend blend)
void GPU_line_width(float width)
void GPU_line_smooth(bool enable)
void GPU_depth_test(eGPUDepthTest test)
Read Guarded memory(de)allocation.
#define RNA_BEGIN(sptr, itemptr, propname)
StructRNA RNA_OperatorStrokeElement
void UI_GetThemeColor3fv(int colorid, float col[3])
const Depsgraph * depsgraph
ListBase * object_editcurve_get(Object *ob)
static bool stroke_elem_project(const struct CurveDrawData *cdd, const int mval_i[2], const float mval_fl[2], float surface_offset, const float radius, float r_location_world[3], float r_normal_world[3])
static void curve_draw_stroke_3d(const struct bContext *UNUSED(C), ARegion *UNUSED(region), void *arg)
#define STROKE_CYCLIC_DIST_PX
static void curve_draw_exec_precalc(wmOperator *op)
static void curve_draw_cancel(bContext *UNUSED(C), wmOperator *op)
static int curve_draw_exec(bContext *C, wmOperator *op)
static bool stroke_elem_project_fallback_elem(const struct CurveDrawData *cdd, const float location_fallback_depth[3], struct StrokeElem *selem)
static bool stroke_elem_project_fallback(const struct CurveDrawData *cdd, const int mval_i[2], const float mval_fl[2], const float surface_offset, const float radius, const float location_fallback_depth[3], float r_location_world[3], float r_location_local[3], float r_normal_world[3], float r_normal_local[3])
static float stroke_elem_radius(const struct CurveDrawData *cdd, const struct StrokeElem *selem)
#define STROKE_SAMPLE_DIST_MIN_PX
static int curve_draw_invoke(bContext *C, wmOperator *op, const wmEvent *event)
static void curve_draw_stroke_to_operator_elem(wmOperator *op, const struct StrokeElem *selem)
static void stroke_elem_pressure_set(const struct CurveDrawData *cdd, struct StrokeElem *selem, float pressure)
static void curve_draw_event_add(wmOperator *op, const wmEvent *event)
void CURVE_OT_draw(wmOperatorType *ot)
static void curve_draw_stroke_from_operator_elem(wmOperator *op, PointerRNA *itemptr)
static void curve_draw_stroke_to_operator(wmOperator *op)
static bool curve_draw_init(bContext *C, wmOperator *op, bool is_invoke)
static void stroke_elem_interp(struct StrokeElem *selem_out, const struct StrokeElem *selem_a, const struct StrokeElem *selem_b, float t)
static float stroke_elem_radius_from_pressure(const struct CurveDrawData *cdd, const float pressure)
static int curve_draw_modal(bContext *C, wmOperator *op, const wmEvent *event)
static void curve_draw_stroke_from_operator(wmOperator *op)
#define STROKE_SAMPLE_DIST_MAX_PX
static void curve_draw_event_add_first(wmOperator *op, const wmEvent *event)
static void curve_draw_exit(wmOperator *op)
bool ED_curve_deselect_all_multi(struct bContext *C)
IconTextureDrawCall normal
void(* MEM_freeN)(void *vmemh)
void *(* MEM_callocN)(size_t len, const char *str)
void *(* MEM_mallocN)(size_t len, const char *str)
bool RNA_property_is_set(PointerRNA *ptr, PropertyRNA *prop)
void RNA_property_enum_set(PointerRNA *ptr, PropertyRNA *prop, int value)
PropertyRNA * RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
void RNA_float_get_array(PointerRNA *ptr, const char *name, float *values)
void RNA_collection_add(PointerRNA *ptr, const char *name, PointerRNA *r_value)
void RNA_property_boolean_set(PointerRNA *ptr, PropertyRNA *prop, bool value)
float RNA_float_get(PointerRNA *ptr, const char *name)
void RNA_float_set(PointerRNA *ptr, const char *name, float value)
void RNA_property_float_set(PointerRNA *ptr, PropertyRNA *prop, float value)
bool RNA_struct_property_is_set(PointerRNA *ptr, const char *identifier)
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
void RNA_float_set_array(PointerRNA *ptr, const char *name, const float *values)
int RNA_enum_get(PointerRNA *ptr, const char *name)
PropertyRNA * RNA_def_boolean(StructOrFunctionRNA *cont_, const char *identifier, bool default_value, const char *ui_name, const char *ui_description)
PropertyRNA * RNA_def_float_distance(StructOrFunctionRNA *cont_, const char *identifier, float default_value, float hardmin, float hardmax, const char *ui_name, const char *ui_description, float softmin, float softmax)
PropertyRNA * RNA_def_collection_runtime(StructOrFunctionRNA *cont_, const char *identifier, StructRNA *type, const char *ui_name, const char *ui_description)
void RNA_def_property_flag(PropertyRNA *prop, PropertyFlag flag)
void RNA_def_property_subtype(PropertyRNA *prop, PropertySubType subtype)
void RNA_def_property_ui_range(PropertyRNA *prop, double min, double max, double step, int precision)
PropertyRNA * RNA_def_enum(StructOrFunctionRNA *cont_, const char *identifier, const EnumPropertyItem *items, int default_value, const char *ui_name, const char *ui_description)
const EnumPropertyItem rna_enum_curve_fit_method_items[]
struct ARegionType * type
struct CurveDrawData::@311 project
const struct StrokeElem * selem
bool use_surface_offset_absolute
struct CurveDrawData::@313 radius
enum CurveDrawData::@315 state
struct CurveDrawData::@312 sample
struct CurveDrawData::@314 prev
float location_world_valid[3]
BLI_mempool * stroke_elem_pool
struct ViewDepths * depths
struct ToolSettings * toolsettings
struct Depsgraph * depsgraph
struct ViewLayer * view_layer
struct RegionView3D * rv3d
int(* invoke)(struct bContext *, struct wmOperator *, const struct wmEvent *) ATTR_WARN_UNUSED_RESULT
int(* modal)(struct bContext *, struct wmOperator *, const struct wmEvent *) ATTR_WARN_UNUSED_RESULT
bool(* poll)(struct bContext *) ATTR_WARN_UNUSED_RESULT
void(* cancel)(struct bContext *, struct wmOperator *)
int(* exec)(struct bContext *, struct wmOperator *) ATTR_WARN_UNUSED_RESULT
struct ReportList * reports
ccl_device_inline float3 ceil(const float3 &a)
void WM_cursor_modal_set(wmWindow *win, int val)
void WM_cursor_modal_restore(wmWindow *win)
wmEventHandler_Op * WM_event_add_modal_handler(bContext *C, wmOperator *op)
void WM_event_add_notifier(const bContext *C, uint type, void *reference)