Merge branch 'master' into blender2.8

This commit is contained in:
Campbell Barton 2016-06-15 17:29:11 +10:00
commit eedcc4a6a0
17 changed files with 387 additions and 157 deletions

View File

@ -60,6 +60,7 @@ int curve_fit_cubic_to_points_db(
const unsigned int points_len,
const unsigned int dims,
const double error_threshold,
const unsigned int calc_flag,
const unsigned int *corners,
unsigned int corners_len,
@ -72,6 +73,7 @@ int curve_fit_cubic_to_points_fl(
const unsigned int points_len,
const unsigned int dims,
const float error_threshold,
const unsigned int calc_flag,
const unsigned int *corners,
const unsigned int corners_len,
@ -117,6 +119,10 @@ int curve_fit_cubic_to_points_single_fl(
float r_handle_r[],
float *r_error_sq);
enum {
CURVE_FIT_CALC_HIGH_QUALIY = (1 << 0),
};
/* curve_fit_corners_detect.c */
/**

View File

@ -1086,11 +1086,7 @@ static bool fit_cubic_to_points(
*r_error_max_sq = error_max_sq;
*r_split_index = split_index;
if (error_max_sq < error_threshold_sq) {
free(u);
return true;
}
else {
if (!(error_max_sq < error_threshold_sq)) {
cubic_copy(cubic_test, r_cubic, dims);
/* If error not too large, try some reparameterization and iteration */
@ -1108,25 +1104,28 @@ static bool fit_cubic_to_points(
points_offset_coords_length,
#endif
u_prime, tan_l, tan_r, dims, cubic_test);
error_max_sq = cubic_calc_error(
const double error_max_sq_test = cubic_calc_error(
cubic_test, points_offset, points_offset_len, u_prime, dims,
&split_index);
if (error_max_sq < error_threshold_sq) {
free(u_prime);
free(u);
cubic_copy(r_cubic, cubic_test, dims);
*r_error_max_sq = error_max_sq;
*r_split_index = split_index;
return true;
}
else if (error_max_sq < *r_error_max_sq) {
if (error_max_sq > error_max_sq_test) {
error_max_sq = error_max_sq_test;
cubic_copy(r_cubic, cubic_test, dims);
*r_error_max_sq = error_max_sq;
*r_split_index = split_index;
}
if (!(error_max_sq < error_threshold_sq)) {
/* continue */
}
else {
assert((error_max_sq < error_threshold_sq));
free(u_prime);
free(u);
return true;
}
SWAP(double *, u, u_prime);
}
free(u_prime);
@ -1134,6 +1133,10 @@ static bool fit_cubic_to_points(
return false;
}
else {
free(u);
return true;
}
}
static void fit_cubic_to_points_recursive(
@ -1145,6 +1148,7 @@ static void fit_cubic_to_points_recursive(
const double tan_l[],
const double tan_r[],
const double error_threshold_sq,
const uint calc_flag,
const uint dims,
/* fill in the list */
CubicList *clist)
@ -1158,8 +1162,11 @@ static void fit_cubic_to_points_recursive(
#ifdef USE_LENGTH_CACHE
points_length_cache,
#endif
tan_l, tan_r, error_threshold_sq, dims,
cubic, &error_max_sq, &split_index))
tan_l, tan_r,
(calc_flag & CURVE_FIT_CALC_HIGH_QUALIY) ? DBL_EPSILON : error_threshold_sq,
dims,
cubic, &error_max_sq, &split_index) ||
(error_max_sq < error_threshold_sq))
{
cubic_list_prepend(clist, cubic);
return;
@ -1211,13 +1218,13 @@ static void fit_cubic_to_points_recursive(
#ifdef USE_LENGTH_CACHE
points_length_cache,
#endif
tan_l, tan_center, error_threshold_sq, dims, clist);
tan_l, tan_center, error_threshold_sq, calc_flag, dims, clist);
fit_cubic_to_points_recursive(
&points_offset[split_index * dims], points_offset_len - split_index,
#ifdef USE_LENGTH_CACHE
points_length_cache + split_index,
#endif
tan_center, tan_r, error_threshold_sq, dims, clist);
tan_center, tan_r, error_threshold_sq, calc_flag, dims, clist);
}
@ -1240,6 +1247,7 @@ int curve_fit_cubic_to_points_db(
const uint points_len,
const uint dims,
const double error_threshold,
const uint calc_flag,
const uint *corners,
uint corners_len,
@ -1315,7 +1323,7 @@ int curve_fit_cubic_to_points_db(
#ifdef USE_LENGTH_CACHE
points_length_cache,
#endif
tan_l, tan_r, error_threshold_sq, dims, &clist);
tan_l, tan_r, error_threshold_sq, calc_flag, dims, &clist);
}
else if (points_len == 1) {
assert(points_offset_len == 1);
@ -1382,6 +1390,7 @@ int curve_fit_cubic_to_points_fl(
const uint points_len,
const uint dims,
const float error_threshold,
const uint calc_flag,
const uint *corners,
const uint corners_len,
@ -1399,7 +1408,7 @@ int curve_fit_cubic_to_points_fl(
uint cubic_array_len = 0;
int result = curve_fit_cubic_to_points_db(
points_db, points_len, dims, error_threshold, corners, corners_len,
points_db, points_len, dims, error_threshold, calc_flag, corners, corners_len,
&cubic_array_db, &cubic_array_len,
r_cubic_orig_index,
r_corner_index_array, r_corner_index_len);

View File

@ -2985,7 +2985,7 @@ NODE_DEFINE(LightPathNode)
SOCKET_OUT_FLOAT(is_camera_ray, "Is Camera Ray");
SOCKET_OUT_FLOAT(is_shadow_ray, "Is Shadow Ray");
SOCKET_OUT_FLOAT(is_diffus_ray, "Is Diffus Ray");
SOCKET_OUT_FLOAT(is_diffuse_ray, "Is Diffuse Ray");
SOCKET_OUT_FLOAT(is_glossy_ray, "Is Glossy Ray");
SOCKET_OUT_FLOAT(is_singular_ray, "Is Singular Ray");
SOCKET_OUT_FLOAT(is_reflection_ray, "Is Reflection Ray");

View File

@ -76,7 +76,9 @@ KM_HIERARCHY = [
('Graph Editor', 'GRAPH_EDITOR', 'WINDOW', [
('Graph Editor Generic', 'GRAPH_EDITOR', 'WINDOW', []),
]),
('Dopesheet', 'DOPESHEET_EDITOR', 'WINDOW', []),
('Dopesheet', 'DOPESHEET_EDITOR', 'WINDOW', [
('Dopesheet Generic', 'DOPESHEET_EDITOR', 'WINDOW', []),
]),
('NLA Editor', 'NLA_EDITOR', 'WINDOW', [
('NLA Channels', 'NLA_EDITOR', 'WINDOW', []),
('NLA Generic', 'NLA_EDITOR', 'WINDOW', []),

View File

@ -348,6 +348,7 @@ void ntreeUserDecrefID(struct bNodeTree *ntree);
struct bNodeTree *ntreeFromID(struct ID *id);
void ntreeMakeLocal(struct bNodeTree *ntree, bool id_in_mainlist);
struct bNode *ntreeFindType(const struct bNodeTree *ntree, int type);
bool ntreeHasType(const struct bNodeTree *ntree, int type);
bool ntreeHasTree(const struct bNodeTree *ntree, const struct bNodeTree *lookup);
void ntreeUpdateTree(struct Main *main, struct bNodeTree *ntree);

View File

@ -88,8 +88,10 @@ struct IDNameLib_Map *BKE_main_idmap_create(struct Main *bmain)
int index = 0;
while (index < MAX_LIBARRAY) {
id_map->type_maps[index].map = NULL;
id_map->type_maps[index].id_type = BKE_idcode_iter_step(&index);
struct IDNameLib_TypeMap *type_map = &id_map->type_maps[index];
type_map->map = NULL;
type_map->id_type = BKE_idcode_iter_step(&index);
BLI_assert(type_map->id_type != 0);
}
BLI_assert(index == MAX_LIBARRAY);

View File

@ -2418,15 +2418,20 @@ void ntreeInterfaceTypeUpdate(bNodeTree *ntree)
/* ************ find stuff *************** */
bNode *ntreeFindType(const bNodeTree *ntree, int type) {
if (ntree) {
for (bNode * node = ntree->nodes.first; node; node = node->next) {
if (node->type == type) {
return node;
}
}
}
return NULL;
}
bool ntreeHasType(const bNodeTree *ntree, int type)
{
bNode *node;
if (ntree)
for (node = ntree->nodes.first; node; node = node->next)
if (node->type == type)
return true;
return false;
return ntreeFindType(ntree, type) != NULL;
}
bool ntreeHasTree(const bNodeTree *ntree, const bNodeTree *lookup)

View File

@ -55,7 +55,8 @@
/* if the cost from #BLI_quadric_evaluate is 'noise', fallback to topology */
#define USE_TOPOLOGY_FALLBACK
#ifdef USE_TOPOLOGY_FALLBACK
# define TOPOLOGY_FALLBACK_EPS FLT_EPSILON
/* cost is calculated with double precision, it's ok to use a very small epsilon, see T48154. */
# define TOPOLOGY_FALLBACK_EPS 1e-12f
#endif
/* these checks are for rare cases that we can't avoid since they are valid meshes still */

View File

@ -271,38 +271,41 @@ bool MeshImporter::is_nice_mesh(COLLADAFW::Mesh *mesh) // checks if mesh has su
COLLADAFW::MeshPrimitiveArray& prim_arr = mesh->getMeshPrimitives();
const std::string &name = bc_get_dae_name(mesh);
int hole_count = 0;
for (unsigned i = 0; i < prim_arr.getCount(); i++) {
COLLADAFW::MeshPrimitive *mp = prim_arr[i];
COLLADAFW::MeshPrimitive::PrimitiveType type = mp->getPrimitiveType();
const char *type_str = bc_primTypeToStr(type);
// OpenCollada passes POLYGONS type for <polylist>
if (type == COLLADAFW::MeshPrimitive::POLYLIST || type == COLLADAFW::MeshPrimitive::POLYGONS) {
COLLADAFW::Polygons *mpvc = (COLLADAFW::Polygons *)mp;
COLLADAFW::Polygons::VertexCountArray& vca = mpvc->getGroupedVerticesVertexCountArray();
int hole_count = 0;
int nonface_count = 0;
for (unsigned int j = 0; j < vca.getCount(); j++) {
int count = vca[j];
if (abs(count) < 3) {
fprintf(stderr, "ERROR: Primitive %s in %s has at least one face with vertex count < 3\n",
type_str, name.c_str());
return false;
nonface_count++;
}
if (count < 0)
{
if (count < 0) {
hole_count ++;
}
}
if (hole_count > 0)
{
if (hole_count > 0) {
fprintf(stderr, "WARNING: Primitive %s in %s: %d holes not imported (unsupported)\n", type_str, name.c_str(), hole_count);
}
if (nonface_count > 0) {
fprintf(stderr, "WARNING: Primitive %s in %s: %d faces with vertex count < 3 (rejected)\n", type_str, name.c_str(), nonface_count);
}
}
else if (type == COLLADAFW::MeshPrimitive::LINES) {

View File

@ -911,7 +911,7 @@ static int curve_draw_exec(bContext *C, wmOperator *op)
unsigned int corners_index_len = 0;
const int result = curve_fit_cubic_to_points_fl(
coords, stroke_len, dims, error_threshold,
coords, stroke_len, dims, error_threshold, CURVE_FIT_CALC_HIGH_QUALIY,
corners, corners_len,
&cubic_spline, &cubic_spline_len,
NULL,

View File

@ -6981,13 +6981,15 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, const wmEvent *
!IS_EVENT_MOD(event, shift, oskey) &&
(event->val == KM_PRESS))
{
if (event->alt)
ui_but_anim_remove_driver(C);
else if (event->ctrl)
ui_but_anim_add_driver(C);
ED_region_tag_redraw(data->region);
/* quick check to prevent this opening within the popup menu its self */
if (!ELEM(NULL, but->rnapoin.data, but->rnaprop)) {
if (event->alt)
ui_but_anim_remove_driver(C);
else if (event->ctrl)
ui_but_anim_add_driver(C);
ED_region_tag_redraw(data->region);
}
return WM_UI_HANDLER_BREAK;
}
/* handle keyingsets */

View File

@ -482,7 +482,7 @@ void WM_OT_collada_import(wmOperatorType *ot)
RNA_def_boolean(ot->srna,
"auto_connect", 0, "Auto Connect",
"set use_connect for parent bones which have exactly one child bone");
"Set use_connect for parent bones which have exactly one child bone");
RNA_def_int(ot->srna,
"min_chain_length",

View File

@ -61,27 +61,42 @@
/* until implement profile = 0 case, need to clamp somewhat above zero */
#define PROFILE_HARD_MIN 0.15f
#define SEGMENTS_HARD_MAX 1000
/* which value is mouse movement and numeric input controlling? */
#define OFFSET_VALUE 0
#define OFFSET_VALUE_PERCENT 1
#define PROFILE_VALUE 2
#define SEGMENTS_VALUE 3
#define NUM_VALUE_KINDS 4
static const char *value_rna_name[NUM_VALUE_KINDS] = {"offset", "offset", "profile", "segments"};
static const float value_clamp_min[NUM_VALUE_KINDS] = {0.0f, 0.0f, PROFILE_HARD_MIN, 1.0f};
static const float value_clamp_max[NUM_VALUE_KINDS] = {1e6, 100.0f, 1.0f, SEGMENTS_HARD_MAX};
static const float value_start[NUM_VALUE_KINDS] = {0.0f, 0.0f, 0.5f, 1.0f};
static const float value_scale_per_inch[NUM_VALUE_KINDS] = { 0.0f, 100.0f, 1.0f, 4.0f};
typedef struct {
BMEditMesh *em;
float initial_length;
float pixel_size; /* use when mouse input is interpreted as spatial distance */
float initial_length[NUM_VALUE_KINDS];
float scale[NUM_VALUE_KINDS];
NumInput num_input[NUM_VALUE_KINDS];
float shift_value[NUM_VALUE_KINDS]; /* The current value when shift is pressed. Negative when shift not active. */
bool is_modal;
NumInput num_input;
float shift_factor; /* The current factor when shift is pressed. Negative when shift not active. */
/* modal only */
float mcenter[2];
BMBackup mesh_backup;
void *draw_handle_pixel;
short twtype;
bool mouse_controls_profile;
short value_mode; /* Which value does mouse movement and numeric input affect? */
float segments; /* Segments as float so smooth mouse pan works in small increments */
} BevelData;
static void edbm_bevel_update_header(bContext *C, wmOperator *op)
{
const char *str = IFACE_("Confirm: (Enter/LMB), Cancel: (Esc/RMB), Mode: %s (M), Clamp Overlap: %s (C), "
"Vertex Only: %s (V), Profile Control: %s (P), Offset: %s, Segments: %d");
"Vertex Only: %s (V), Profile Control: %s (P), Offset: %s, Segments: %d, Profile: %.3f");
char msg[UI_MAX_DRAW_STR];
ScrArea *sa = CTX_wm_area(C);
@ -93,8 +108,8 @@ static void edbm_bevel_update_header(bContext *C, wmOperator *op)
const char *type_str;
PropertyRNA *prop = RNA_struct_find_property(op->ptr, "offset_type");
if (hasNumInput(&opdata->num_input)) {
outputNumInput(&opdata->num_input, offset_str, &sce->unit);
if (hasNumInput(&opdata->num_input[OFFSET_VALUE])) {
outputNumInput(&opdata->num_input[OFFSET_VALUE], offset_str, &sce->unit);
}
else {
BLI_snprintf(offset_str, NUM_STR_REP_LEN, "%f", RNA_float_get(op->ptr, "offset"));
@ -105,8 +120,8 @@ static void edbm_bevel_update_header(bContext *C, wmOperator *op)
BLI_snprintf(msg, sizeof(msg), str, type_str,
WM_bool_as_string(RNA_boolean_get(op->ptr, "clamp_overlap")),
WM_bool_as_string(RNA_boolean_get(op->ptr, "vertex_only")),
WM_bool_as_string(opdata->mouse_controls_profile),
offset_str, RNA_int_get(op->ptr, "segments"));
WM_bool_as_string(opdata->value_mode == PROFILE_VALUE),
offset_str, RNA_int_get(op->ptr, "segments"), RNA_float_get(op->ptr, "profile"));
ED_area_headerprint(sa, msg);
}
@ -118,6 +133,8 @@ static bool edbm_bevel_init(bContext *C, wmOperator *op, const bool is_modal)
Scene *scene = CTX_data_scene(C);
BMEditMesh *em = BKE_editmesh_from_object(obedit);
BevelData *opdata;
float pixels_per_inch;
int i;
if (em->bm->totvertsel == 0) {
return false;
@ -127,14 +144,25 @@ static bool edbm_bevel_init(bContext *C, wmOperator *op, const bool is_modal)
opdata->em = em;
opdata->is_modal = is_modal;
opdata->shift_factor = -1.0f;
opdata->mouse_controls_profile = false;
opdata->value_mode = OFFSET_VALUE;
pixels_per_inch = U.dpi * U.pixelsize;
initNumInput(&opdata->num_input);
opdata->num_input.idx_max = 0;
opdata->num_input.val_flag[0] |= NUM_NO_NEGATIVE;
opdata->num_input.unit_sys = scene->unit.system;
opdata->num_input.unit_type[0] = B_UNIT_NONE; /* Not sure this is a factor or a unit? */
for (i = 0; i < NUM_VALUE_KINDS; i++) {
opdata->shift_value[i] = -1.0f;
/* note: scale for OFFSET_VALUE will get overwritten in edbm_bevel_invoke */
opdata->scale[i] = value_scale_per_inch[i] / pixels_per_inch;
initNumInput(&opdata->num_input[i]);
opdata->num_input[i].idx_max = 0;
opdata->num_input[i].val_flag[0] |= NUM_NO_NEGATIVE;
if (i == SEGMENTS_VALUE) {
opdata->num_input[i].val_flag[0] |= NUM_NO_FRACTION | NUM_NO_ZERO;
}
if (i == OFFSET_VALUE) {
opdata->num_input[i].unit_sys = scene->unit.system;
}
opdata->num_input[i].unit_type[0] = B_UNIT_NONE; /* Not sure this is a factor or a unit? */
}
/* avoid the cost of allocating a bm copy */
if (is_modal) {
@ -142,7 +170,8 @@ static bool edbm_bevel_init(bContext *C, wmOperator *op, const bool is_modal)
ARegion *ar = CTX_wm_region(C);
opdata->mesh_backup = EDBM_redo_state_store(em);
opdata->draw_handle_pixel = ED_region_draw_cb_activate(ar->type, ED_region_draw_mouse_line_cb, opdata->mcenter, REGION_DRAW_POST_PIXEL);
opdata->draw_handle_pixel = ED_region_draw_cb_activate(ar->type, ED_region_draw_mouse_line_cb,
opdata->mcenter, REGION_DRAW_POST_PIXEL);
G.moving = G_TRANSFORM_EDIT;
if (v3d) {
@ -173,13 +202,15 @@ static bool edbm_bevel_calc(wmOperator *op)
EDBM_redo_state_restore(opdata->mesh_backup, em, false);
}
if (em->ob)
if (em->ob) {
material = CLAMPIS(material, -1, em->ob->totcol - 1);
}
EDBM_op_init(em, &bmop, op,
"bevel geom=%hev offset=%f segments=%i vertex_only=%b offset_type=%i profile=%f clamp_overlap=%b "
"material=%i loop_slide=%b",
BM_ELEM_SELECT, offset, segments, vertex_only, offset_type, profile, clamp_overlap, material, loop_slide);
BM_ELEM_SELECT, offset, segments, vertex_only, offset_type, profile,
clamp_overlap, material, loop_slide);
BMO_op_exec(em->bm, &bmop);
@ -191,8 +222,9 @@ static bool edbm_bevel_calc(wmOperator *op)
}
/* no need to de-select existing geometry */
if (!EDBM_op_finish(em, &bmop, op, true))
if (!EDBM_op_finish(em, &bmop, op, true)) {
return false;
}
EDBM_mesh_normals_update(opdata->em);
@ -256,12 +288,37 @@ static int edbm_bevel_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
static void edbm_bevel_calc_initial_length(wmOperator *op, const wmEvent *event, bool mode_changed)
{
BevelData *opdata;
float mlen[2], len, value, sc, st;
int vmode;
opdata = op->customdata;
mlen[0] = opdata->mcenter[0] - event->mval[0];
mlen[1] = opdata->mcenter[1] - event->mval[1];
len = len_v2(mlen);
vmode = opdata->value_mode;
if (mode_changed) {
/* If current value is not default start value, adjust len so that
* the scaling and offset in edbm_bevel_mouse_set_value will
* start at current value */
value = (vmode == SEGMENTS_VALUE) ?
opdata->segments : RNA_float_get(op->ptr, value_rna_name[vmode]);
sc = opdata->scale[vmode];
st = value_start[vmode];
if (value != value_start[vmode]) {
len = (st + sc * (len - MVAL_PIXEL_MARGIN) - value) / sc;
}
}
opdata->initial_length[opdata->value_mode] = len;
}
static int edbm_bevel_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
/* TODO make modal keymap (see fly mode) */
RegionView3D *rv3d = CTX_wm_region_view3d(C);
BevelData *opdata;
float mlen[2];
float center_3d[3];
if (!edbm_bevel_init(C, op, true)) {
@ -276,10 +333,10 @@ static int edbm_bevel_invoke(bContext *C, wmOperator *op, const wmEvent *event)
* ideally this will never happen and should be checked for above */
opdata->mcenter[0] = opdata->mcenter[1] = 0;
}
mlen[0] = opdata->mcenter[0] - event->mval[0];
mlen[1] = opdata->mcenter[1] - event->mval[1];
opdata->initial_length = len_v2(mlen);
opdata->pixel_size = rv3d ? ED_view3d_pixel_size(rv3d, center_3d) : 1.0f;
edbm_bevel_calc_initial_length(op, event, false);
/* for OFFSET_VALUE only, the scale is the size of a pixel under the mouse in 3d space */
opdata->scale[OFFSET_VALUE] = rv3d ? ED_view3d_pixel_size(rv3d, center_3d) : 1.0f;
edbm_bevel_update_header(C, op);
@ -293,69 +350,72 @@ static int edbm_bevel_invoke(bContext *C, wmOperator *op, const wmEvent *event)
return OPERATOR_RUNNING_MODAL;
}
static float edbm_bevel_mval_factor(wmOperator *op, const wmEvent *event)
static void edbm_bevel_mouse_set_value(wmOperator *op, const wmEvent *event)
{
BevelData *opdata = op->customdata;
bool use_dist;
bool is_percent, is_profile;
int vmode = opdata->value_mode;
float mdiff[2];
float factor;
float value;
mdiff[0] = opdata->mcenter[0] - event->mval[0];
mdiff[1] = opdata->mcenter[1] - event->mval[1];
is_percent = (RNA_enum_get(op->ptr, "offset_type") == BEVEL_AMT_PERCENT);
use_dist = !is_percent;
is_profile = opdata->mouse_controls_profile;
factor = ((len_v2(mdiff) - MVAL_PIXEL_MARGIN) - opdata->initial_length) * opdata->pixel_size;
value = ((len_v2(mdiff) - MVAL_PIXEL_MARGIN) - opdata->initial_length[vmode]);
/* Scale according to value mode */
value = value_start[vmode] + value * opdata->scale[vmode];
/* Fake shift-transform... */
if (event->shift) {
if (opdata->shift_factor < 0.0f) {
if (is_profile)
opdata->shift_factor = RNA_float_get(op->ptr, "profile");
else {
opdata->shift_factor = RNA_float_get(op->ptr, "offset");
if (is_percent) {
opdata->shift_factor /= 100.0f;
}
}
if (opdata->shift_value[vmode] < 0.0f) {
opdata->shift_value[vmode] = (vmode == SEGMENTS_VALUE) ?
opdata->segments : RNA_float_get(op->ptr, value_rna_name[vmode]);
}
factor = (factor - opdata->shift_factor) * 0.1f + opdata->shift_factor;
value = (value - opdata->shift_value[vmode]) * 0.1f + opdata->shift_value[vmode];
}
else if (opdata->shift_factor >= 0.0f) {
opdata->shift_factor = -1.0f;
else if (opdata->shift_value[vmode] >= 0.0f) {
opdata->shift_value[vmode] = -1.0f;
}
/* clamp differently based on distance/factor/profile */
if (is_profile) {
CLAMP(factor, PROFILE_HARD_MIN, 1.0f);
/* clamp accordingto value mode, and store value back */
CLAMP(value, value_clamp_min[vmode], value_clamp_max[vmode]);
if (vmode == SEGMENTS_VALUE) {
opdata->segments = value;
RNA_int_set(op->ptr, "segments", (int)(value + 0.5f));
}
else {
if (use_dist) {
if (factor < 0.0f) factor = 0.0f;
}
else {
CLAMP(factor, 0.0f, 1.0f);
if (is_percent) {
factor *= 100.0f;
}
}
RNA_float_set(op->ptr, value_rna_name[vmode], value);
}
}
return factor;
static void edbm_bevel_numinput_set_value(wmOperator *op)
{
BevelData *opdata = op->customdata;
float value;
int vmode;
vmode = opdata->value_mode;
value = (vmode == SEGMENTS_VALUE) ?
opdata->segments : RNA_float_get(op->ptr, value_rna_name[vmode]);
applyNumInput(&opdata->num_input[vmode], &value);
CLAMP(value, value_clamp_min[vmode], value_clamp_max[vmode]);
if (vmode == SEGMENTS_VALUE) {
opdata->segments = value;
RNA_int_set(op->ptr, "segments", (int)value);
}
else {
RNA_float_set(op->ptr, value_rna_name[vmode], value);
}
}
static int edbm_bevel_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
BevelData *opdata = op->customdata;
const bool has_numinput = hasNumInput(&opdata->num_input);
const bool has_numinput = hasNumInput(&opdata->num_input[opdata->value_mode]);
/* Modal numinput active, try to handle numeric inputs first... */
if (event->val == KM_PRESS && has_numinput && handleNumInput(C, &opdata->num_input, event)) {
float value = RNA_float_get(op->ptr, "offset");
applyNumInput(&opdata->num_input, &value);
RNA_float_set(op->ptr, "offset", value);
if (event->val == KM_PRESS && has_numinput && handleNumInput(C, &opdata->num_input[opdata->value_mode], event)) {
edbm_bevel_numinput_set_value(op);
edbm_bevel_calc(op);
edbm_bevel_update_header(C, op);
return OPERATOR_RUNNING_MODAL;
@ -370,12 +430,7 @@ static int edbm_bevel_modal(bContext *C, wmOperator *op, const wmEvent *event)
case MOUSEMOVE:
if (!has_numinput) {
const float factor = edbm_bevel_mval_factor(op, event);
if (opdata->mouse_controls_profile)
RNA_float_set(op->ptr, "profile", factor);
else
RNA_float_set(op->ptr, "offset", factor);
edbm_bevel_mouse_set_value(op, event);
edbm_bevel_calc(op);
edbm_bevel_update_header(C, op);
handled = true;
@ -445,12 +500,18 @@ static int edbm_bevel_modal(bContext *C, wmOperator *op, const wmEvent *event)
if (type > BEVEL_AMT_PERCENT) {
type = BEVEL_AMT_OFFSET;
}
if (opdata->value_mode == OFFSET_VALUE && type == BEVEL_AMT_PERCENT)
opdata->value_mode = OFFSET_VALUE_PERCENT;
else if (opdata->value_mode == OFFSET_VALUE_PERCENT && type != BEVEL_AMT_PERCENT)
opdata->value_mode = OFFSET_VALUE;
RNA_property_enum_set(op->ptr, prop, type);
}
/* Update factor accordingly to new offset_type. */
if (!has_numinput) {
RNA_float_set(op->ptr, "offset", edbm_bevel_mval_factor(op, event));
}
/* Update offset accordingly to new offset_type. */
if (!has_numinput &&
(opdata->value_mode == OFFSET_VALUE || opdata->value_mode == OFFSET_VALUE_PERCENT))
{
edbm_bevel_mouse_set_value(op, event);
}
edbm_bevel_calc(op);
edbm_bevel_update_header(C, op);
handled = true;
@ -470,7 +531,24 @@ static int edbm_bevel_modal(bContext *C, wmOperator *op, const wmEvent *event)
case PKEY:
if (event->val == KM_RELEASE)
break;
opdata->mouse_controls_profile = !opdata->mouse_controls_profile;
if (opdata->value_mode == PROFILE_VALUE) {
opdata->value_mode = OFFSET_VALUE;
}
else {
opdata->value_mode = PROFILE_VALUE;
}
edbm_bevel_calc_initial_length(op, event, true);
break;
case SKEY:
if (event->val == KM_RELEASE)
break;
if (opdata->value_mode == SEGMENTS_VALUE) {
opdata->value_mode = OFFSET_VALUE;
}
else {
opdata->value_mode = SEGMENTS_VALUE;
}
edbm_bevel_calc_initial_length(op, event, true);
break;
case VKEY:
if (event->val == KM_RELEASE)
@ -488,10 +566,8 @@ static int edbm_bevel_modal(bContext *C, wmOperator *op, const wmEvent *event)
}
/* Modal numinput inactive, try to handle numeric inputs last... */
if (!handled && event->val == KM_PRESS && handleNumInput(C, &opdata->num_input, event)) {
float value = RNA_float_get(op->ptr, "offset");
applyNumInput(&opdata->num_input, &value);
RNA_float_set(op->ptr, "offset", value);
if (!handled && event->val == KM_PRESS && handleNumInput(C, &opdata->num_input[opdata->value_mode], event)) {
edbm_bevel_numinput_set_value(op);
edbm_bevel_calc(op);
edbm_bevel_update_header(C, op);
return OPERATOR_RUNNING_MODAL;
@ -542,12 +618,13 @@ void MESH_OT_bevel(wmOperatorType *ot)
RNA_def_enum(ot->srna, "offset_type", offset_type_items, 0, "Amount Type", "What distance Amount measures");
prop = RNA_def_float(ot->srna, "offset", 0.0f, -1e6f, 1e6f, "Amount", "", 0.0f, 1.0f);
RNA_def_property_float_array_funcs_runtime(prop, NULL, NULL, mesh_ot_bevel_offset_range_func);
RNA_def_int(ot->srna, "segments", 1, 1, 50, "Segments", "Segments for curved edge", 1, 8);
RNA_def_int(ot->srna, "segments", 1, 1, SEGMENTS_HARD_MAX, "Segments", "Segments for curved edge", 1, 8);
RNA_def_float(ot->srna, "profile", 0.5f, PROFILE_HARD_MIN, 1.0f, "Profile",
"Controls profile shape (0.5 = round)", PROFILE_HARD_MIN, 1.0f);
"Controls profile shape (0.5 = round)", PROFILE_HARD_MIN, 1.0f);
RNA_def_boolean(ot->srna, "vertex_only", false, "Vertex Only", "Bevel only vertices");
RNA_def_boolean(ot->srna, "clamp_overlap", false, "Clamp Overlap",
"Do not allow beveled edges/vertices to overlap each other");
"Do not allow beveled edges/vertices to overlap each other");
RNA_def_boolean(ot->srna, "loop_slide", true, "Loop Slide", "Prefer slide along edge to even widths");
RNA_def_int(ot->srna, "material", -1, -1, INT_MAX, "Material", "Material for bevel faces (-1 means use adjacent faces)", -1, 100);
RNA_def_int(ot->srna, "material", -1, -1, INT_MAX, "Material",
"Material for bevel faces (-1 means use adjacent faces)", -1, 100);
}

View File

@ -4144,7 +4144,12 @@ static void initSnapSpatial(TransInfo *t, float r_snap[3])
r_snap[2] = r_snap[1] * 0.1f;
}
}
else if (ELEM(t->spacetype, SPACE_IMAGE, SPACE_CLIP)) {
else if (t->spacetype == SPACE_IMAGE) {
r_snap[0] = 0.0f;
r_snap[1] = 0.0625f;
r_snap[2] = 0.03125f;
}
else if (t->spacetype == SPACE_CLIP) {
r_snap[0] = 0.0f;
r_snap[1] = 0.125f;
r_snap[2] = 0.0625f;

View File

@ -296,10 +296,11 @@ static int logImageSetData10(LogImageFile *logImage, LogImageElement logElement,
row[index] = swap_uint(pixel, logImage->isMSB);
if (logimage_fwrite(row, rowLength, 1, logImage) == 0) {
if (verbose) printf("DPX/Cineon: Error while writing file.\n"); {
MEM_freeN(row);
return 1;
if (verbose) {
printf("DPX/Cineon: Error while writing file.\n");
}
MEM_freeN(row);
return 1;
}
}
MEM_freeN(row);

View File

@ -898,7 +898,7 @@ static void rna_def_pose_channel(BlenderRNA *brna)
prop = RNA_def_property(srna, "use_bbone_relative_start_handle", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "bboneflag", PCHAN_BBONE_CUSTOM_START_REL);
RNA_def_property_ui_text(prop, "Relative B-Bone Start Handle",
"Use treat custom start handle position as a relative value");
"Treat custom start handle position as a relative value");
RNA_def_property_editable_func(prop, "rna_PoseChannel_proxy_editable");
RNA_def_property_update(prop, NC_OBJECT | ND_POSE, "rna_Pose_update");
@ -914,7 +914,7 @@ static void rna_def_pose_channel(BlenderRNA *brna)
prop = RNA_def_property(srna, "use_bbone_relative_end_handle", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "bboneflag", PCHAN_BBONE_CUSTOM_END_REL);
RNA_def_property_ui_text(prop, "Relative B-Bone End Handle",
"Use treat custom end handle position as a relative value");
"Treat custom end handle position as a relative value");
RNA_def_property_editable_func(prop, "rna_PoseChannel_proxy_editable");
RNA_def_property_update(prop, NC_OBJECT | ND_POSE, "rna_Pose_update");

View File

@ -199,6 +199,12 @@ void register_node_tree_type_sh(void)
/* GPU material from shader nodes */
static void ntree_shader_link_builtin_normal(bNodeTree *ntree,
bNode *node_from,
bNodeSocket *socket_from,
bNode *displacement_node,
bNodeSocket *displacement_socket);
/* Find an output node of the shader tree.
*
* NOTE: it will only return output which is NOT in the group, which isn't how
@ -277,32 +283,138 @@ static bool ntree_shader_has_displacement(bNodeTree *ntree,
return displacement->link != NULL;
}
static bool ntree_shader_relink_node_normal(bNodeTree *ntree,
bNode *node,
bNode *node_from,
bNodeSocket *socket_from)
{
bNodeSocket *sock = ntree_shader_node_find_input(node, "Normal");
/* TODO(sergey): Can we do something smarter here than just a name-based
* matching?
*/
if (sock == NULL) {
/* There's no Normal input, nothing to link. */
return false;
}
if (sock->link != NULL) {
/* Something is linked to the normal input already. can't
* use other input for that.
*/
return false;
}
/* Create connection between specified node and the normal input. */
nodeAddLink(ntree, node_from, socket_from, node, sock);
return true;
}
static void ntree_shader_link_builtin_group_normal(
bNodeTree *ntree,
bNode *group_node,
bNode *node_from,
bNodeSocket *socket_from,
bNode *displacement_node,
bNodeSocket *displacement_socket)
{
bNodeTree *group_ntree = (bNodeTree *)group_node->id;
/* Create input socket to plug displacement connection to. */
bNodeSocket *group_normal_socket =
ntreeAddSocketInterface(group_ntree,
SOCK_IN,
"NodeSocketVector",
"Normal");
/* Need to update tree so all node instances nodes gets proper sockets. */
ntreeUpdateTree(G.main, group_ntree);
/* Assumes sockets are always added at the end. */
bNodeSocket *group_node_normal_socket = (bNodeSocket*)group_node->inputs.last;
if (displacement_node == group_node) {
/* If displacement is coming from this node group we need to perform
* some internal re-linking in order to avoid cycles.
*/
bNode *group_output_node = ntreeFindType(group_ntree, NODE_GROUP_OUTPUT);
BLI_assert(group_output_node != NULL);
bNodeSocket *group_output_node_displacement_socket =
nodeFindSocket(group_output_node,
SOCK_IN,
displacement_socket->identifier);
bNodeLink *group_displacement_link = group_output_node_displacement_socket->link;
if (group_displacement_link == NULL) {
/* Displacement output is not connected to anything, can just stop
* right away.
*/
return;
}
/* This code is similar to ntree_shader_relink_displacement() */
bNode *group_displacement_node = group_displacement_link->fromnode;
bNodeSocket *group_displacement_socket = group_displacement_link->fromsock;
nodeRemLink(group_ntree, group_displacement_link);
/* Create and link bump node.
* Can't re-use bump node from parent tree because it'll cause cycle.
*/
bNode *bump_node = nodeAddStaticNode(NULL, group_ntree, SH_NODE_BUMP);
bNodeSocket *bump_input_socket = ntree_shader_node_find_input(bump_node, "Height");
bNodeSocket *bump_output_socket = ntree_shader_node_find_output(bump_node, "Normal");
BLI_assert(bump_input_socket != NULL);
BLI_assert(bump_output_socket != NULL);
nodeAddLink(group_ntree,
group_displacement_node, group_displacement_socket,
bump_node, bump_input_socket);
/* Relink normals inside of the instanced tree. */
ntree_shader_link_builtin_normal(group_ntree,
bump_node,
bump_output_socket,
group_displacement_node,
group_displacement_socket);
ntreeUpdateTree(G.main, group_ntree);
}
else {
/* Connect group node normal input. */
nodeAddLink(ntree,
node_from, socket_from,
group_node, group_node_normal_socket);
bNode *group_input_node = ntreeFindType(group_ntree, NODE_GROUP_INPUT);
BLI_assert(group_input_node != NULL);
bNodeSocket *group_input_node_normal_socket =
nodeFindSocket(group_input_node,
SOCK_OUT,
group_normal_socket->identifier);
BLI_assert(group_input_node_normal_socket != NULL);
/* Relink normals inside of the instanced tree. */
ntree_shader_link_builtin_normal(group_ntree,
group_input_node,
group_input_node_normal_socket,
displacement_node,
displacement_socket);
ntreeUpdateTree(G.main, group_ntree);
}
}
/* Use specified node and socket as an input for unconnected normal sockets. */
static void ntree_shader_link_builtin_normal(bNodeTree *ntree,
bNode *node_from,
bNodeSocket *socket_from)
bNodeSocket *socket_from,
bNode *displacement_node,
bNodeSocket *displacement_socket)
{
for (bNode *node = ntree->nodes.first; node != NULL; node = node->next) {
if (node == node_from) {
/* Don't connect node itself! */
continue;
}
bNodeSocket *sock = ntree_shader_node_find_input(node, "Normal");
/* TODO(sergey): Can we do something smarter here than just a name-based
* matching?
*/
if (sock == NULL) {
/* There's no Normal input, nothing to link. */
if (node->type == NODE_GROUP && node->id) {
/* Special re-linking for group nodes. */
ntree_shader_link_builtin_group_normal(ntree,
node,
node_from,
socket_from,
displacement_node,
displacement_socket);
continue;
}
if (sock->link != NULL) {
/* Something is linked to the normal input already. can't
* use other input for that.
*/
if (ELEM(node->type, NODE_GROUP_INPUT, NODE_GROUP_OUTPUT)) {
/* Group inputs and outputs needs nothing special. */
continue;
}
/* Create connection between specified node and the normal input. */
nodeAddLink(ntree, node_from, socket_from, node, sock);
ntree_shader_relink_node_normal(ntree, node, node_from, socket_from);
}
}
@ -346,7 +458,11 @@ static void ntree_shader_relink_displacement(bNodeTree *ntree,
displacement_node, displacement_socket,
bump_node, bump_input_socket);
/* Connect all free-standing Normal inputs. */
ntree_shader_link_builtin_normal(ntree, bump_node, bump_output_socket);
ntree_shader_link_builtin_normal(ntree,
bump_node,
bump_output_socket,
displacement_node,
displacement_socket);
/* TODO(sergey): Reconnect Geometry Info->Normal sockets to the new
* bump node.
*/