Blender V5.0
transform_mode_curveshrinkfatten.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2001-2002 NaN Holding BV. All rights reserved.
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
8
9#include <cstdlib>
10
11#include "BLI_math_bits.h"
12#include "BLI_math_vector.h"
13#include "BLI_string_utf8.h"
14
15#include "BKE_unit.hh"
16
17#include "ED_screen.hh"
18
19#include "BLT_translation.hh"
20
21#include "UI_interface_types.hh"
22
23#include "transform.hh"
24#include "transform_convert.hh"
25#include "transform_snap.hh"
26
27#include "transform_mode.hh"
28
29namespace blender::ed::transform {
30
31/* -------------------------------------------------------------------- */
34
36{
37 float ratio;
38 int i;
39 char str[UI_MAX_DRAW_STR];
40
41 ratio = t->values[0] + t->values_modal_offset[0];
42
43 transform_snap_increment(t, &ratio);
44
45 applyNumInput(&t->num, &ratio);
46
47 t->values_final[0] = ratio;
48
49 /* Header print for NumInput. */
50 if (hasNumInput(&t->num)) {
51 char c[NUM_STR_REP_LEN];
52
53 outputNumInput(&(t->num), c, t->scene->unit);
54 SNPRINTF_UTF8(str, IFACE_("Shrink/Fatten: %s"), c);
55 }
56 else {
57 SNPRINTF_UTF8(str, IFACE_("Shrink/Fatten: %3f"), ratio);
58 }
59
61 TransData *td = tc->data;
62 for (i = 0; i < tc->data_len; i++, td++) {
63 if (td->flag & TD_SKIP) {
64 continue;
65 }
66
67 if (td->val) {
68 if (td->ival == 0.0f && ratio > 1.0f) {
69 /* Allow Shrink/Fatten for zero radius. */
70 *td->val = (ratio - 1.0f) * uint_as_float(POINTER_AS_UINT(t->custom.mode.data));
71 }
72 else {
73 *td->val = td->ival * ratio;
74 }
75
76 /* Apply proportional editing. */
77 *td->val = interpf(*td->val, td->ival, td->factor);
78 CLAMP_MIN(*td->val, 0.0f);
79 }
80 }
81 }
82
83 recalc_data(t);
84
86}
87
89{
91
93
94 t->idx_max = 0;
95 t->num.idx_max = 0;
96 t->increment[0] = 0.1f;
97 t->increment_precision = 0.1f;
98
100 t->num.unit_sys = t->scene->unit.system;
101 t->num.unit_type[0] = B_UNIT_NONE;
102
103 float scale_factor = 0.0f;
104 if ((t->spacetype == SPACE_VIEW3D) && (t->region->regiontype == RGN_TYPE_WINDOW)) {
105 /* For cases where only one point on the curve is being transformed and the radius of that
106 * point is zero [that is actually only checked for in #applyCurveShrinkFatten()], use the
107 * factor to multiply the offset of the ratio and allow scaling. Note that for bezier curves, 3
108 * TransData equals 1 point in most cases. */
109 bool use_scaling_factor = false;
110 if (t->data_len_all == 1) {
111 /* Either a single control point of a non-bezier curve or single handle of a bezier curve
112 * selected. */
113 use_scaling_factor = TRANS_DATA_CONTAINER_FIRST_OK(t)->data[0].val != nullptr;
114 }
115 if (t->data_len_all == 3) {
116 /* Either a single control point of a bezier curve (or its handles as well) selected, also
117 * true for three individual handles selected. Note the layout/order of TransData is
118 * different for Curve vs. Curves (Curves have the control point first, Curve has it in the
119 * middle), so check this explicitly. */
121
123 use_scaling_factor = tc->data[1].val != nullptr;
124 }
125 else if (ELEM(t->data_type,
128 {
129 use_scaling_factor = tc->data[0].val != nullptr;
130 }
131 }
132
133 if (use_scaling_factor) {
134 RegionView3D *rv3d = static_cast<RegionView3D *>(t->region->regiondata);
135 scale_factor = rv3d->pixsize * t->mouse.factor * t->zfac;
136 }
137 }
138 t->custom.mode.data = POINTER_FROM_UINT(float_as_uint(scale_factor));
139}
140
142
144 /*flags*/ T_NO_CONSTRAINT,
145 /*init_fn*/ initCurveShrinkFatten,
146 /*transform_fn*/ applyCurveShrinkFatten,
147 /*transform_matrix_fn*/ nullptr,
148 /*handle_event_fn*/ nullptr,
149 /*snap_distance_fn*/ nullptr,
150 /*snap_apply_fn*/ nullptr,
151 /*draw_fn*/ nullptr,
152};
153
154} // namespace blender::ed::transform
@ B_UNIT_NONE
Definition BKE_unit.hh:136
MINLINE float interpf(float target, float origin, float t)
MINLINE unsigned int float_as_uint(float f)
MINLINE float uint_as_float(unsigned int i)
MINLINE void copy_v3_fl(float r[3], float f)
#define SNPRINTF_UTF8(dst, format,...)
#define POINTER_AS_UINT(i)
#define ELEM(...)
#define POINTER_FROM_UINT(i)
#define CLAMP_MIN(a, b)
#define IFACE_(msgid)
@ RGN_TYPE_WINDOW
@ SPACE_VIEW3D
#define NUM_STR_REP_LEN
bool applyNumInput(NumInput *n, float *vec)
Definition numinput.cc:190
void outputNumInput(NumInput *n, char *str, const UnitSettings &unit_settings)
Definition numinput.cc:88
bool hasNumInput(const NumInput *n)
Definition numinput.cc:171
void ED_area_status_text(ScrArea *area, const char *str)
Definition area.cc:851
#define UI_MAX_DRAW_STR
#define str(s)
void initMouseInputMode(TransInfo *t, MouseInput *mi, MouseInputMode mode)
void recalc_data(TransInfo *t)
bool transform_snap_increment(const TransInfo *t, float *r_val)
static void applyCurveShrinkFatten(TransInfo *t)
TransConvertTypeInfo TransConvertType_Curve
static void initCurveShrinkFatten(TransInfo *t, wmOperator *)
void * regiondata
short idx_max
float val_inc[NUM_MAX_ELEMENTS]
int unit_type[NUM_MAX_ELEMENTS]
struct UnitSettings unit
TransConvertTypeInfo * data_type
Definition transform.hh:810
TransCustomDataContainer custom
Definition transform.hh:974
i
Definition text_draw.cc:230
#define TRANS_DATA_CONTAINER_FIRST_OK(t)
Definition transform.hh:37
#define FOREACH_TRANS_DATA_CONTAINER(t, th)
Definition transform.hh:42
conversion and adaptation of different datablocks to a common struct.
transform modes used by different operators.