47#include "RNA_prototypes.hh"
55# include "curve_fit_nd.h"
60#define STROKE_SAMPLE_DIST_MIN_PX 1
61#define STROKE_SAMPLE_DIST_MAX_PX 3
64#define STROKE_CYCLIC_DIST_PX 8
178 const float mval_fl[2],
179 float surface_offset,
181 float r_location_world[3],
182 float r_normal_world[3])
186 bool is_location_world_set =
false;
193 if (r_normal_world) {
196 is_location_world_set =
true;
201 if (depths && (
uint(mval_i[0]) < depths->
w) && (
uint(mval_i[1]) < depths->
h)) {
202 float depth_fl = 1.0f;
204 const double depth =
double(depth_fl);
205 if ((depth > depths->
depth_range[0]) && (depth < depths->depth_range[1])) {
207 is_location_world_set =
true;
208 if (r_normal_world) {
212 if (surface_offset != 0.0f) {
216 madd_v3_v3fl(r_location_world, normal, offset * surface_offset);
217 if (r_normal_world) {
227 if (is_location_world_set) {
233 return is_location_world_set;
238 const float mval_fl[2],
239 const float surface_offset,
241 const float location_fallback_depth[3],
242 float r_location_world[3],
243 float r_location_local[3],
244 float r_normal_world[3],
245 float r_normal_local[3])
248 cdd, mval_i, mval_fl, surface_offset, radius, r_location_world, r_normal_world);
249 if (is_depth_found ==
false) {
251 cdd->
vc.
v3d, cdd->
vc.
region, location_fallback_depth, mval_fl, r_location_world);
265 return is_depth_found;
272 const float location_fallback_depth[3],
282 location_fallback_depth,
354 if (stroke_len == 0) {
365 const float location_zero[3] = {0};
366 const float *location_prev = location_zero;
400 if (stroke_len > 1) {
401 float(*coord_array)[3] =
static_cast<float(*)[3]
>(
402 MEM_mallocN(
sizeof(*coord_array) * stroke_len, __func__));
428 for (
int i = 0; i < stroke_len; i++) {
437 for (
int i = 0; i < stroke_len; i++) {
466 selem->
pressure =
event->tablet.pressure;
471 if (is_depth_found) {
486 for (
int i = 1; i < n; i++) {
492 if (is_depth_found ==
false) {
493 if (is_depth_found_substep) {
501 selem = selem_new_last;
502 *selem_new_last = selem_target;
526 float normal[3] = {0.0f};
533 float cross_a[3], cross_b[3];
554 float location_no_offset[3];
669 float len_3d = 0.0f, len_2d = 0.0f;
682 scale_px = ((len_3d > 0.0f) && (len_2d > 0.0f)) ? (len_3d / len_2d) : 0.0f;
689 bool use_cyclic =
false;
693 const StrokeElem *selem, *selem_first, *selem_last;
720 float *lengths =
static_cast<float *
>(
MEM_mallocN(
sizeof(
float) * stroke_len, __func__));
722 MEM_mallocN(
sizeof(*selem_array) * stroke_len, __func__));
730 selem_array[0] = selem_prev;
735 len_3d += len_3d_segment;
737 selem_array[i] = selem;
743 for (i = 0; i < stroke_len && lengths[i] < len_taper_max; i++) {
744 const float pressure_new = selem_array[i]->
pressure * (lengths[i] / len_taper_max);
751 const float len_taper_min = len_3d - len_taper_max;
752 for (i = stroke_len - 1; i > 0 && lengths[i] > len_taper_min; i--) {
753 const float pressure_new = selem_array[i]->
pressure *
754 ((len_3d - lengths[i]) / len_taper_max);
781 const bool is_3d = (cu->
flag &
CU_3D) != 0;
816 coords_indices.radius = use_pressure_radius ? dims++ : -1;
818 float *coords =
static_cast<float *
>(
819 MEM_mallocN(
sizeof(*coords) * stroke_len * dims, __func__));
821 float *cubic_spline =
nullptr;
822 uint cubic_spline_len = 0;
840 if (coords_indices.radius != -1) {
841 co[coords_indices.radius] = selem->
pressure;
845 if ((co != coords) &&
UNLIKELY(memcmp(co, co - dims,
sizeof(
float) * dims) == 0)) {
852 uint *corners =
nullptr;
853 uint corners_len = 0;
857 const float corner_radius_min = error_threshold / 8;
858 const float corner_radius_max = error_threshold * 2;
859 const uint samples_max = 16;
861 curve_fit_corners_detect_fl(coords,
872 uint *corners_index =
nullptr;
873 uint corners_index_len = 0;
874 uint calc_flag = CURVE_FIT_CALC_HIGH_QUALIY;
876 if ((stroke_len > 2) && use_cyclic) {
877 calc_flag |= CURVE_FIT_CALC_CYCLIC;
882 result = curve_fit_cubic_to_points_refit_fl(coords,
897 result = curve_fit_cubic_to_points_fl(coords,
917 nu->
pntsu = cubic_spline_len;
920 float *co = cubic_spline;
922 for (
int j = 0; j < cubic_spline_len; j++, bezt++, co += (dims * 3)) {
923 const float *handle_l = co + (dims * 0);
924 const float *pt = co + (dims * 1);
925 const float *handle_r = co + (dims * 2);
931 if (coords_indices.radius != -1) {
935 bezt->
radius = radius_max;
944 uint i_start = 0, i_end = corners_index_len;
946 if ((corners_index_len >= 2) && (calc_flag & CURVE_FIT_CALC_CYCLIC) == 0) {
951 for (
uint i = i_start; i < i_end; i++) {
952 bezt = &nu->
bezt[corners_index[i]];
957 if (calc_flag & CURVE_FIT_CALC_CYCLIC) {
971 nu->
pntsu = stroke_len;
984 bezt->
vec[1][2] = 0.0f;
987 if (use_pressure_radius) {
991 bezt->
radius = radius_max;
1011 nu->
pntsu = stroke_len;
1033 if (use_pressure_radius) {
1096 const float *plane_no =
nullptr;
1097 const float *plane_co =
nullptr;
1101 plane_co = obedit->object_to_world().location();
1102 plane_no = obedit->object_to_world().ptr()[2];
1123 if (cdd->
depths !=
nullptr) {
1150 if (is_modal ==
false) {
1211 ot->name =
"Draw Curve";
1212 ot->idname =
"CURVE_OT_draw";
1213 ot->description =
"Draw a freehand spline";
1234 "Error distance threshold (in object units)",
1247 ot->srna,
"corner_angle",
DEG2RADF(70.0f), 0.0f,
M_PI,
"Corner Angle",
"", 0.0f,
M_PI);
Depsgraph * CTX_data_ensure_evaluated_depsgraph(const bContext *C)
Scene * CTX_data_scene(const bContext *C)
Object * CTX_data_edit_object(const bContext *C)
Main * CTX_data_main(const bContext *C)
ViewLayer * CTX_data_view_layer(const bContext *C)
void BKE_nurb_handles_calc(Nurb *nu)
void BKE_curve_nurb_active_set(Curve *cu, const Nurb *nu)
void BKE_nurb_knot_calc_u(Nurb *nu)
void BKE_report(ReportList *reports, eReportType 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 target, float origin, float t)
void mul_transposed_mat3_m4_v3(const float M[4][4], float r[3])
void mul_v3_m4v3(float r[3], const float mat[4][4], const float vec[3])
bool invert_m4_m4(float inverse[4][4], const float mat[4][4])
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 void sub_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE float len_v2v2(const float v1[2], const float v2[2]) ATTR_WARN_UNUSED_RESULT
void interp_v2_v2v2(float r[2], const float a[2], const float b[2], float t)
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 float dot_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
void interp_v3_v3v3(float r[3], const float a[3], const float b[3], float t)
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 bool is_zero_v3(const float v[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void zero_v3(float r[3])
MINLINE void add_v3_v3(float r[3], const float a[3])
MINLINE float normalize_v3(float n[3])
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 elem_num, unsigned int pchunk, unsigned int flag) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_RETURNS_NONNULL
int BLI_mempool_len(const BLI_mempool *pool) ATTR_NONNULL(1)
void * BLI_mempool_calloc(BLI_mempool *pool) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_RETURNS_NONNULL ATTR_NONNULL(1)
void BLI_mempool_destroy(BLI_mempool *pool) ATTR_NONNULL(1)
#define ARRAY_SET_ITEMS(...)
typedef double(DMatrix)[4][4]
void DEG_id_tag_update(ID *id, unsigned int flags)
Object is a sort of wrapper for general info.
@ 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_FLAG_DEPTH_ONLY_SELECTED
@ CURVE_PAINT_FIT_METHOD_REFIT
@ CURVE_PAINT_FIT_METHOD_SPLIT
@ CURVE_PAINT_PROJECT_SURFACE
@ CURVE_PAINT_SURFACE_PLANE_NORMAL_SURFACE
@ CURVE_PAINT_SURFACE_PLANE_NORMAL_VIEW
bool ED_operator_editcurve(bContext *C)
void ED_region_tag_redraw(ARegion *region)
void * ED_region_draw_cb_activate(ARegionType *art, void(*draw)(const bContext *, ARegion *, void *), void *customdata, int type)
#define REGION_DRAW_POST_VIEW
bool ED_region_draw_cb_exit(ARegionType *art, void *handle)
bool ED_view3d_depth_read_cached(const ViewDepths *vd, const int mval[2], int margin, float *r_depth)
void ED_view3d_depth_override(Depsgraph *depsgraph, ARegion *region, View3D *v3d, Object *obact, eV3DDepthOverrideMode mode, bool use_overlay, ViewDepths **r_depths)
void ED_view3d_win_to_3d(const View3D *v3d, const ARegion *region, const float depth_pt[3], const float mval[2], float r_out[3])
ViewContext ED_view3d_viewcontext_init(bContext *C, Depsgraph *depsgraph)
bool ED_view3d_depth_read_cached_normal(const ARegion *region, const ViewDepths *depths, const int mval[2], float r_normal[3])
void view3d_operator_needs_opengl(const bContext *C)
void ED_view3d_depths_free(ViewDepths *depths)
@ V3D_DEPTH_SELECTED_ONLY
bool ED_view3d_win_to_3d_on_plane(const ARegion *region, const float plane[4], const float mval[2], bool do_clip, float r_out[3])
bool ED_view3d_depth_unproject_v3(const ARegion *region, const int mval[2], double depth, float r_location_world[3])
#define GPU_batch_uniform_3fv(batch, name, val)
void GPU_batch_program_set_builtin(blender::gpu::Batch *batch, eGPUBuiltinShader shader_id)
void GPU_batch_draw(blender::gpu::Batch *batch)
blender::gpu::Batch * GPU_batch_preset_sphere(int lod) ATTR_WARN_UNUSED_RESULT
#define GPU_matrix_mul(x)
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.
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 Brightness Control the brightness and contrast of the input color Vector Map input vector components with curves Camera Retrieve information about the camera and how it relates to the current shading point s position Clamp a value between a minimum and a maximum Vector Perform vector math operation Invert Invert a color
#define RNA_BEGIN(sptr, itemptr, propname)
void UI_GetThemeColor3fv(int colorid, float col[3])
BPy_StructRNA * depsgraph
ListBase * object_editcurve_get(Object *ob)
#define STROKE_CYCLIC_DIST_PX
static void curve_draw_exec_precalc(wmOperator *op)
static bool stroke_elem_project(const 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 int curve_draw_exec(bContext *C, wmOperator *op)
#define STROKE_SAMPLE_DIST_MIN_PX
static int curve_draw_invoke(bContext *C, wmOperator *op, const wmEvent *event)
static void curve_draw_event_add(wmOperator *op, const wmEvent *event)
void CURVE_OT_draw(wmOperatorType *ot)
static void curve_draw_stroke_to_operator_elem(wmOperator *op, const StrokeElem *selem)
static void curve_draw_stroke_3d(const bContext *, ARegion *, void *arg)
static void curve_draw_stroke_from_operator_elem(wmOperator *op, PointerRNA *itemptr)
static float stroke_elem_radius(const CurveDrawData *cdd, const StrokeElem *selem)
static void curve_draw_stroke_to_operator(wmOperator *op)
static bool stroke_elem_project_fallback_elem(const CurveDrawData *cdd, const float location_fallback_depth[3], StrokeElem *selem)
static bool curve_draw_init(bContext *C, wmOperator *op, bool is_invoke)
static float stroke_elem_radius_from_pressure(const CurveDrawData *cdd, const float pressure)
static void stroke_elem_pressure_set(const CurveDrawData *cdd, StrokeElem *selem, 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 stroke_elem_interp(StrokeElem *selem_out, const StrokeElem *selem_a, const StrokeElem *selem_b, float t)
static bool stroke_elem_project_fallback(const 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 void curve_draw_cancel(bContext *, wmOperator *op)
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(bContext *C)
draw_view in_light_buf[] float
draw_view push_constant(Type::INT, "radiance_src") .push_constant(Type capture_info_buf storage_buf(1, Qualifier::READ, "ObjectBounds", "bounds_buf[]") .push_constant(Type draw_view int
void *(* MEM_mallocN)(size_t len, const char *str)
void MEM_freeN(void *vmemh)
void *(* MEM_callocN)(size_t len, const char *str)
ccl_device_inline float3 ceil(const float3 a)
vector project(vector v, vector v_proj)
PropertyRNA * RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
bool RNA_collection_is_empty(PointerRNA *ptr, const char *name)
bool RNA_property_is_set(PointerRNA *ptr, PropertyRNA *prop)
void RNA_property_enum_set(PointerRNA *ptr, PropertyRNA *prop, int value)
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_float_distance(StructOrFunctionRNA *cont_, const char *identifier, const float default_value, const float hardmin, const float hardmax, const char *ui_name, const char *ui_description, const float softmin, const float softmax)
PropertyRNA * RNA_def_enum(StructOrFunctionRNA *cont_, const char *identifier, const EnumPropertyItem *items, const int default_value, const char *ui_name, const char *ui_description)
PropertyRNA * RNA_def_collection_runtime(StructOrFunctionRNA *cont_, const char *identifier, StructRNA *type, const char *ui_name, const char *ui_description)
PropertyRNA * RNA_def_boolean(StructOrFunctionRNA *cont_, const char *identifier, const bool default_value, 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)
const EnumPropertyItem rna_enum_curve_fit_method_items[]
struct ARegionType * type
bool use_surface_offset_absolute
struct CurveDrawData::@122053357257022202372332306253266340050352207025 prev
struct CurveDrawData::@245323005260216252031355354310256052310253267000 project
struct CurveDrawData::@312353161277223354351054131017041237303040206154 radius
float location_world_valid[3]
struct CurveDrawData::@306341371227123352063203344165060313364051346167 sample
BLI_mempool * stroke_elem_pool
ObjectRuntimeHandle * runtime
struct ToolSettings * toolsettings
struct ReportList * reports
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)
#define ISMOUSE_MOTION(event_type)