col.prop(shading, "type", expand=True)
if shading.type == 'SOLID':
+ col.separator()
+ col.row().prop(shading, "single_color_mode", expand=True)
+
col.separator()
col.row().prop(shading, "light", expand=True)
+ if shading.light == 'STUDIO':
+ col.row().template_icon_view(shading, "studiolight")
col.separator()
- col.row().prop(shading, "single_color_mode", expand=True)
col.prop(shading, "show_object_overlap")
- if shading.light == 'STUDIO':
- # TODO: don't store these settings in the scene
- scene = context.scene
- props = scene.layer_properties['BLENDER_WORKBENCH']
-
- col.separator()
-
- sub = col.column()
- sub.label(text="Left/Right:")
- row = sub.row(align=True)
- row.prop(props, "diffuse_light_x_neg", text="")
- row.prop(props, "diffuse_light_x_pos", text="")
-
- sub = col.column()
- sub.label(text="Up/Down:")
- row = sub.row(align=True)
- row.prop(props, "diffuse_light_y_neg", text="")
- row.prop(props, "diffuse_light_y_pos", text="")
-
- sub = col.column()
- sub.label(text="Front/Back:")
- row = sub.row(align=True)
- row.prop(props, "diffuse_light_z_neg", text="")
- row.prop(props, "diffuse_light_z_pos", text="")
-
class VIEW3D_PT_overlay(Panel):
bl_space_type = 'VIEW_3D'
*/
deg_tag_copy_on_write_id(id_cow, id_orig);
/* Perform remapping of the nodes. */
- RemapCallbackUserData user_data;
+ RemapCallbackUserData user_data = {NULL};
user_data.depsgraph = depsgraph;
user_data.node_builder = node_builder;
user_data.create_placeholders = create_placeholders;
id_node->id_orig->name,
id_node->id_cow);
BKE_animdata_copy_id(NULL, id_node->id_cow, id_node->id_orig, false, false);
+ RemapCallbackUserData user_data = {NULL};
+ user_data.depsgraph = depsgraph;
+ BKE_library_foreach_ID_link(NULL,
+ id_node->id_cow,
+ foreach_libblock_remap_callback,
+ (void *)&user_data,
+ IDWALK_NOP);
}
ID *deg_update_copy_on_write_datablock(const Depsgraph *depsgraph,
engines/eevee/eevee_volumes.c
engines/workbench/workbench_engine.c
engines/workbench/workbench_materials.c
+ engines/workbench/workbench_studiolight.c
engines/workbench/solid_mode.c
engines/external/external_engine.c
data_to_c_simple(modes/shaders/object_grid_frag.glsl SRC)
data_to_c_simple(modes/shaders/object_grid_vert.glsl SRC)
data_to_c_simple(modes/shaders/object_lightprobe_grid_vert.glsl SRC)
+data_to_c_simple(modes/shaders/object_mball_handles_vert.glsl SRC)
data_to_c_simple(modes/shaders/object_particle_prim_vert.glsl SRC)
data_to_c_simple(modes/shaders/object_particle_dot_vert.glsl SRC)
data_to_c_simple(modes/shaders/object_particle_dot_frag.glsl SRC)
void DRW_deferred_shader_remove(struct GPUMaterial *mat);
+unsigned int *WORKBENCH_generate_studiolight_preview(int studiolight_id, int icon_size);
#endif /* __DRW_ENGINE_H__ */
BLI_assert(props &&
props->type == IDP_GROUP &&
props->subtype == IDP_GROUP_SUB_ENGINE_RENDER);
-
- const float diffuse_x_pos[3] = {1.0, 0.8, 0.6};
- const float diffuse_x_neg[3] = {1.0, 0.6, 0.6};
- const float diffuse_y_pos[3] = {0.9, 0.9, 1.0};
- const float diffuse_y_neg[3] = {0.05, 0.025, 0.025};
- const float diffuse_z_pos[3] = {0.8, 0.8, 0.75};
- const float diffuse_z_neg[3] = {1.0, 0.95, 0.8};
-
- BKE_collection_engine_property_add_float_array(props, "diffuse_light_x_pos", diffuse_x_pos, 3);
- BKE_collection_engine_property_add_float_array(props, "diffuse_light_x_neg", diffuse_x_neg, 3);
- BKE_collection_engine_property_add_float_array(props, "diffuse_light_y_pos", diffuse_y_pos, 3);
- BKE_collection_engine_property_add_float_array(props, "diffuse_light_y_neg", diffuse_y_neg, 3);
- BKE_collection_engine_property_add_float_array(props, "diffuse_light_z_pos", diffuse_z_pos, 3);
- BKE_collection_engine_property_add_float_array(props, "diffuse_light_z_neg", diffuse_z_neg, 3);
+ UNUSED_VARS_NDEBUG(props);
}
/* Note: currently unused, we may want to register so we can see this when debugging the view. */
WORKBENCH_PrivateData *wpd = stl->g_data;
DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
DRWShadingGroup *grp;
- const DRWContextState *draw_ctx = DRW_context_state_get();
- ViewLayer *view_layer = draw_ctx->view_layer;
- IDProperty *props = BKE_view_layer_engine_evaluated_get(view_layer, COLLECTION_MODE_NONE, RE_engine_id_BLENDER_WORKBENCH);
-
const DRWContextState *DCS = DRW_context_state_get();
wpd->material_hash = BLI_ghash_ptr_new(__func__);
if (v3d) {
wpd->drawtype_lighting = v3d->drawtype_lighting;
wpd->drawtype_options = v3d->drawtype_options;
+ wpd->drawtype_studiolight = v3d->drawtype_studiolight;
}
else {
wpd->drawtype_lighting = V3D_LIGHTING_STUDIO;
wpd->drawtype_options = 0;
+ wpd->drawtype_studiolight = 0;
}
select_deferred_shaders(wpd);
WORKBENCH_UBO_World *wd = &wpd->world_data;
UI_GetThemeColor3fv(UI_GetThemeValue(TH_SHOW_BACK_GRAD) ? TH_LOW_GRAD:TH_HIGH_GRAD, wd->background_color_low);
UI_GetThemeColor3fv(TH_HIGH_GRAD, wd->background_color_high);
- copy_v3_v3(wd->diffuse_light_x_pos, BKE_collection_engine_property_value_get_float_array(props, "diffuse_light_x_pos"));
- copy_v3_v3(wd->diffuse_light_x_neg, BKE_collection_engine_property_value_get_float_array(props, "diffuse_light_x_neg"));
- copy_v3_v3(wd->diffuse_light_y_pos, BKE_collection_engine_property_value_get_float_array(props, "diffuse_light_y_pos"));
- copy_v3_v3(wd->diffuse_light_y_neg, BKE_collection_engine_property_value_get_float_array(props, "diffuse_light_y_neg"));
- copy_v3_v3(wd->diffuse_light_z_pos, BKE_collection_engine_property_value_get_float_array(props, "diffuse_light_z_pos"));
- copy_v3_v3(wd->diffuse_light_z_neg, BKE_collection_engine_property_value_get_float_array(props, "diffuse_light_z_neg"));
+ studiolight_update_world(wpd->drawtype_studiolight, wd);
psl->composite_pass = DRW_pass_create("Composite", DRW_STATE_WRITE_COLOR);
grp = DRW_shgroup_create(wpd->composite_sh, psl->composite_pass);
struct GPUShader *composite_sh;
short drawtype_lighting;
short drawtype_options;
+ short drawtype_studiolight;
struct GPUUniformBuffer *world_ubo;
WORKBENCH_UBO_World world_data;
} WORKBENCH_PrivateData; /* Transient data */
void workbench_materials_solid_cache_populate(WORKBENCH_Data *vedata, Object *ob);
void workbench_materials_cache_finish(WORKBENCH_Data *vedata);
+/* workbench_studiolight.c */
+void studiolight_update_world(int studio_light, WORKBENCH_UBO_World* wd);
+
#endif
--- /dev/null
+/*
+ * Copyright 2016, Blender Foundation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor(s): Blender Institute
+ *
+ */
+
+/** \file workbench_studiolight.h
+ * \ingroup draw_engine
+ */
+ #include "DRW_engine.h"
+#include "workbench_private.h"
+
+#include "BLI_math.h"
+
+
+#define STUDIOLIGHT_X_POS 0
+#define STUDIOLIGHT_X_NEG 1
+#define STUDIOLIGHT_Y_POS 2
+#define STUDIOLIGHT_Y_NEG 3
+#define STUDIOLIGHT_Z_POS 4
+#define STUDIOLIGHT_Z_NEG 5
+
+const float studiolights[][6][3] = {
+ {
+ {1.0, 0.8, 0.6},
+ {1.0, 0.6, 0.6},
+ {0.9, 0.9, 1.0},
+ {0.05, 0.025, 0.025},
+ {0.8, 0.8, 0.75},
+ {1.0, 0.95, 0.8},
+ },
+ {
+ {0.0, 0.0, 0.0},
+ {0.0, 0.0, 0.0},
+ {0.0, 0.0, 0.0},
+ {0.0, 0.0, 0.0},
+ {0.8, 0.8, 1.0},
+ {0.0, 0.0, 0.0},
+ },
+ {
+ {0.4, 0.3, 0.8},
+ {0.4, 0.3, 0.8},
+ {0.8, 0.8, 0.2},
+ {0.0, 0.0, 0.0},
+ {0.4, 0.4, 0.8},
+ {0.0, 0.0, 0.0},
+ },
+ {
+ {0.2, 0.2, 0.0},
+ {0.8, 0.2, 0.0},
+ {0.8, 0.2, 0.0},
+ {0.2, 0.2, 0.0},
+ {0.8, 0.6, 0.4},
+ {0.0, 0.0, 0.0},
+ },
+ {
+ {0.8, 0.2, 0.0},
+ {0.8, 0.2, 0.0},
+ {0.8, 0.6, 0.0},
+ {0.2, 0.2, 0.0},
+ {1.0, 0.5, 0.0},
+ {0.0, 0.0, 0.0},
+ },
+};
+
+void studiolight_update_world(int studio_light, WORKBENCH_UBO_World* wd) {
+ copy_v3_v3(wd->diffuse_light_x_pos, studiolights[studio_light][STUDIOLIGHT_X_POS]);
+ copy_v3_v3(wd->diffuse_light_x_neg, studiolights[studio_light][STUDIOLIGHT_X_NEG]);
+ copy_v3_v3(wd->diffuse_light_y_pos, studiolights[studio_light][STUDIOLIGHT_Y_POS]);
+ copy_v3_v3(wd->diffuse_light_y_neg, studiolights[studio_light][STUDIOLIGHT_Y_NEG]);
+ copy_v3_v3(wd->diffuse_light_z_pos, studiolights[studio_light][STUDIOLIGHT_Z_POS]);
+ copy_v3_v3(wd->diffuse_light_z_neg, studiolights[studio_light][STUDIOLIGHT_Z_NEG]);
+}
+
+unsigned int *WORKBENCH_generate_studiolight_preview(int studiolight_id, int icon_size) {
+ unsigned int* rect = MEM_mallocN(icon_size * icon_size * sizeof(unsigned int), __func__);
+ int icon_center = icon_size / 2;
+ float sphere_radius = icon_center * 0.9;
+
+ int offset = 0;
+ for (int y = 0 ; y < icon_size ; y ++) {
+ float dy = y - icon_center;
+ for (int x = 0 ; x < icon_size ; x ++) {
+ float dx = x - icon_center;
+ /* calculate aliasing */
+ float alias = 0;
+ const float alias_step = 0.2;
+ for (float ay = dy - 0.5; ay < dy + 0.5 ; ay += alias_step) {
+ for (float ax = dx - 0.5; ax < dx + 0.5 ; ax += alias_step) {
+ if (sqrt(ay*ay + ax*ax) < sphere_radius) {
+ alias += alias_step*alias_step;
+ }
+ }
+ }
+ unsigned int pixelresult = 0x0;
+ unsigned int alias_i = clamp_i(alias * 256, 0, 255);
+ if (alias_i != 0) {
+ /* calculate normal */
+ unsigned int alias_mask = alias_i << 24;
+ float normal[3];
+ normal[0] = dx / sphere_radius;
+ normal[1] = dy / sphere_radius;
+ normal[2] = sqrt(-(normal[0]*normal[0])-(normal[1]*normal[1]) + 1);
+ normalize_v3(normal);
+
+ float color[3];
+ mul_v3_v3fl(color, studiolights[studiolight_id][STUDIOLIGHT_X_POS], clamp_f(normal[0], 0.0, 1.0));
+ interp_v3_v3v3(color, color, studiolights[studiolight_id][STUDIOLIGHT_X_NEG], clamp_f(-normal[0], 0.0, 1.0));
+ interp_v3_v3v3(color, color, studiolights[studiolight_id][STUDIOLIGHT_Y_POS], clamp_f(normal[1], 0.0, 1.0));
+ interp_v3_v3v3(color, color, studiolights[studiolight_id][STUDIOLIGHT_Y_NEG], clamp_f(-normal[1], 0.0, 1.0));
+ interp_v3_v3v3(color, color, studiolights[studiolight_id][STUDIOLIGHT_Z_POS], clamp_f(normal[2], 0.0, 1.0));
+
+ pixelresult = rgb_to_cpack(
+ linearrgb_to_srgb(color[0]),
+ linearrgb_to_srgb(color[1]),
+ linearrgb_to_srgb(color[2])
+ ) | alias_mask;
+ }
+ rect[offset++] = pixelresult;
+ }
+ }
+ return rect;
+}
\ No newline at end of file
rad_head = (pchan->parent && (boneflag & BONE_CONNECTED)) ? &pchan->parent->bone->rad_tail : &pchan->bone->rad_head;
}
- if ((boneflag & BONE_NO_DEFORM) == 0 &&
+ if ((select_id == -1) &&
+ (boneflag & BONE_NO_DEFORM) == 0 &&
((boneflag & BONE_SELECTED) || (eBone && (boneflag & (BONE_ROOTSEL | BONE_TIPSEL)))))
{
drw_shgroup_bone_envelope_distance(BONE_VAR(eBone, pchan, disp_mat), col_white, rad_head, rad_tail, distance);
extern char datatoc_armature_shape_outline_geom_glsl[];
extern char datatoc_gpu_shader_flat_color_frag_glsl[];
+extern char datatoc_object_mball_handles_vert_glsl[];
+
static struct {
struct GPUShader *shape_outline;
struct GPUShader *bone_envelope;
struct GPUShader *bone_envelope_outline;
struct GPUShader *bone_sphere;
struct GPUShader *bone_sphere_outline;
-} g_armature_shaders = {NULL};
+
+ struct GPUShader *mball_handles;
+} g_shaders = {NULL};
static struct {
struct Gwn_VertFormat *instance_screenspace;
MEM_SAFE_FREE(*format);
}
- struct GPUShader **shader = &g_armature_shaders.shape_outline;
- for (int i = 0; i < sizeof(g_armature_shaders) / sizeof(void *); ++i, ++shader) {
+ struct GPUShader **shader = &g_shaders.shape_outline;
+ for (int i = 0; i < sizeof(g_shaders) / sizeof(void *); ++i, ++shader) {
DRW_SHADER_FREE_SAFE(*shader);
}
}
DRWShadingGroup *shgroup_instance_bone_envelope_outline(DRWPass *pass)
{
- if (g_armature_shaders.bone_envelope_outline == NULL) {
- g_armature_shaders.bone_envelope_outline = DRW_shader_create(
+ if (g_shaders.bone_envelope_outline == NULL) {
+ g_shaders.bone_envelope_outline = DRW_shader_create(
datatoc_armature_envelope_outline_vert_glsl, NULL,
datatoc_gpu_shader_flat_color_frag_glsl, NULL);
}
{"xAxis" , DRW_ATTRIB_FLOAT, 3}
});
- DRWShadingGroup *grp = DRW_shgroup_instance_create(g_armature_shaders.bone_envelope_outline,
+ DRWShadingGroup *grp = DRW_shgroup_instance_create(g_shaders.bone_envelope_outline,
pass, DRW_cache_bone_envelope_outline_get(),
g_formats.instance_bone_envelope);
DRW_shgroup_uniform_vec2(grp, "viewportSize", DRW_viewport_size_get(), 1);
DRWShadingGroup *shgroup_instance_bone_envelope_distance(DRWPass *pass)
{
- if (g_armature_shaders.bone_envelope_distance == NULL) {
- g_armature_shaders.bone_envelope_distance = DRW_shader_create(
+ if (g_shaders.bone_envelope_distance == NULL) {
+ g_shaders.bone_envelope_distance = DRW_shader_create(
datatoc_armature_envelope_vert_glsl, NULL,
datatoc_armature_envelope_frag_glsl, NULL);
}
{"xAxis" , DRW_ATTRIB_FLOAT, 3}
});
- DRWShadingGroup *grp = DRW_shgroup_instance_create(g_armature_shaders.bone_envelope_distance,
+ DRWShadingGroup *grp = DRW_shgroup_instance_create(g_shaders.bone_envelope_distance,
pass, DRW_cache_bone_envelope_solid_get(),
g_formats.instance_bone_envelope);
DRWShadingGroup *shgroup_instance_bone_envelope_solid(DRWPass *pass)
{
- if (g_armature_shaders.bone_envelope == NULL) {
- g_armature_shaders.bone_envelope = DRW_shader_create(
+ if (g_shaders.bone_envelope == NULL) {
+ g_shaders.bone_envelope = DRW_shader_create(
datatoc_armature_envelope_vert_glsl, NULL,
datatoc_armature_envelope_frag_glsl, "#define SMOOTH_ENVELOPE\n");
}
{"xAxis" , DRW_ATTRIB_FLOAT, 3}
});
- DRWShadingGroup *grp = DRW_shgroup_instance_create(g_armature_shaders.bone_envelope,
+ DRWShadingGroup *grp = DRW_shgroup_instance_create(g_shaders.bone_envelope,
pass, DRW_cache_bone_envelope_solid_get(),
g_formats.instance_bone_envelope);
DRWShadingGroup *shgroup_instance_mball_handles(DRWPass *pass)
{
- GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_INSTANCE_MBALL_HANDLES);
+ if (g_shaders.mball_handles == NULL) {
+ g_shaders.mball_handles = DRW_shader_create(
+ datatoc_object_mball_handles_vert_glsl, NULL,
+ datatoc_gpu_shader_flat_color_frag_glsl, NULL);
+ }
DRW_shgroup_instance_format(g_formats.instance_mball_handles, {
{"ScaleTranslationMatrix" , DRW_ATTRIB_FLOAT, 12},
{"color" , DRW_ATTRIB_FLOAT, 3}
});
- DRWShadingGroup *grp = DRW_shgroup_instance_create(sh, pass, DRW_cache_screenspace_circle_get(),
+ DRWShadingGroup *grp = DRW_shgroup_instance_create(g_shaders.mball_handles, pass,
+ DRW_cache_screenspace_circle_get(),
g_formats.instance_mball_handles);
DRW_shgroup_uniform_vec3(grp, "screen_vecs[0]", DRW_viewport_screenvecs_get(), 2);
/* Only works with batches with adjacency infos. */
DRWShadingGroup *shgroup_instance_bone_shape_outline(DRWPass *pass, struct Gwn_Batch *geom)
{
- if (g_armature_shaders.shape_outline == NULL) {
- g_armature_shaders.shape_outline = DRW_shader_create(
+ if (g_shaders.shape_outline == NULL) {
+ g_shaders.shape_outline = DRW_shader_create(
datatoc_armature_shape_outline_vert_glsl,
datatoc_armature_shape_outline_geom_glsl,
datatoc_gpu_shader_flat_color_frag_glsl,
{"color" , DRW_ATTRIB_FLOAT, 4}
});
- DRWShadingGroup *grp = DRW_shgroup_instance_create(g_armature_shaders.shape_outline,
+ DRWShadingGroup *grp = DRW_shgroup_instance_create(g_shaders.shape_outline,
pass, geom, g_formats.instance_color);
DRW_shgroup_uniform_vec2(grp, "viewportSize", DRW_viewport_size_get(), 1);
DRWShadingGroup *shgroup_instance_bone_sphere(DRWPass *pass)
{
- if (g_armature_shaders.bone_sphere == NULL) {
- g_armature_shaders.bone_sphere = DRW_shader_create(
+ if (g_shaders.bone_sphere == NULL) {
+ g_shaders.bone_sphere = DRW_shader_create(
datatoc_armature_sphere_vert_glsl, NULL,
datatoc_armature_sphere_frag_glsl, NULL);
}
{"color" , DRW_ATTRIB_FLOAT, 4}
});
- DRWShadingGroup *grp = DRW_shgroup_instance_create(g_armature_shaders.bone_sphere,
+ DRWShadingGroup *grp = DRW_shgroup_instance_create(g_shaders.bone_sphere,
pass, DRW_cache_bone_point_get(), g_formats.instance_color);
return grp;
DRWShadingGroup *shgroup_instance_bone_sphere_outline(DRWPass *pass)
{
- if (g_armature_shaders.bone_sphere_outline == NULL) {
- g_armature_shaders.bone_sphere_outline = DRW_shader_create(
+ if (g_shaders.bone_sphere_outline == NULL) {
+ g_shaders.bone_sphere_outline = DRW_shader_create(
datatoc_armature_sphere_outline_vert_glsl, NULL,
datatoc_gpu_shader_flat_color_frag_glsl, NULL);
}
{"color" , DRW_ATTRIB_FLOAT, 4}
});
- DRWShadingGroup *grp = DRW_shgroup_instance_create(g_armature_shaders.bone_sphere_outline,
+ DRWShadingGroup *grp = DRW_shgroup_instance_create(g_shaders.bone_sphere_outline,
pass, DRW_cache_bone_point_wire_outline_get(),
g_formats.instance_color);
DRW_shgroup_uniform_vec2(grp, "viewportSize", DRW_viewport_size_get(), 1);
* Note that if the stiffness is zero, it assumes the scale is directly multiplied by the radius */
- #define M_PI_2 1.570796f // pi/2
-
uniform mat4 ViewProjectionMatrix;
uniform vec3 screen_vecs[2];
Base *base = NULL;
EditBone *ebone;
base = ED_armature_base_and_ebone_from_select_buffer(bases, bases_len, hitresult, &ebone);
+ /* If this fails, selection code is setting the selection ID's incorrectly. */
+ BLI_assert(base && ebone);
int dep;
/* clicks on bone points get advantage */
/* send necessary notifiers */
WM_main_add_notifier(NC_GEOM | ND_DATA, ob);
+
+ /* tag armature for copy-on-write update (since act_bone is in armature not object) */
+ DEG_id_tag_update(&arm->id, DEG_TAG_COPY_ON_WRITE);
}
}
*/
DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
}
+
+ /* tag armature for copy-on-write update (since act_bone is in armature not object) */
+ DEG_id_tag_update(&arm->id, DEG_TAG_COPY_ON_WRITE);
}
}
DEF_VICO(COLORSET_19_VEC)
DEF_VICO(COLORSET_20_VEC)
+ /* Studio lighting presets */
+DEF_ICON(STUDIOLIGHT_01)
+DEF_ICON(STUDIOLIGHT_02)
+DEF_ICON(STUDIOLIGHT_03)
+DEF_ICON(STUDIOLIGHT_04)
+DEF_ICON(STUDIOLIGHT_05)
../../blenlib
../../blentranslation
../../depsgraph
+ ../../draw
../../gpu
../../imbuf
../../makesdna
#include "DEG_depsgraph.h"
+#include "DRW_engine.h"
+
#include "ED_datafiles.h"
#include "ED_keyframes_draw.h"
#include "ED_render.h"
}
+static void init_studio_light_icons(void)
+{
+ /* dynamic allocation now, tucking datatoc pointers in DrawInfo */
+#define INIT_STUDIOLIGHT_ICON(icon_id, studiolight_id) \
+ { \
+ DrawInfo *di; \
+ di = def_internal_icon(NULL, icon_id, 0, 0, 96, ICON_TYPE_BUFFER); \
+ di->data.buffer.image->rect = WORKBENCH_generate_studiolight_preview(studiolight_id, 96); \
+ } (void)0
+
+ INIT_STUDIOLIGHT_ICON(ICON_STUDIOLIGHT_01, 0);
+ INIT_STUDIOLIGHT_ICON(ICON_STUDIOLIGHT_02, 1);
+ INIT_STUDIOLIGHT_ICON(ICON_STUDIOLIGHT_03, 2);
+ INIT_STUDIOLIGHT_ICON(ICON_STUDIOLIGHT_04, 3);
+ INIT_STUDIOLIGHT_ICON(ICON_STUDIOLIGHT_05, 4);
+
+}
static void init_internal_icons(void)
{
// bTheme *btheme = UI_GetTheme();
init_internal_icons();
init_brush_icons();
init_matcap_icons();
+ init_studio_light_icons();
#endif
}
#include "BKE_world.h"
#include "DEG_depsgraph.h"
+#include "DEG_depsgraph_query.h"
#include "DEG_depsgraph_build.h"
#include "IMB_imbuf.h"
short *stop, *do_update;
Scene *scene;
+ Depsgraph *depsgraph;
ID *id;
ID *parent;
MTex *slot;
typedef struct IconPreview {
Main *bmain;
Scene *scene;
+ Depsgraph *depsgraph;
void *owner;
ID *id;
ListBase sizes;
char name[32];
int sizex;
Main *pr_main = sp->pr_main;
+ ID *id_eval = DEG_get_evaluated_id(sp->depsgraph, id);
/* in case of split preview, use border render */
if (split) {
}
/* get the stuff from the builtin preview dbase */
- sce = preview_prepare_scene(sp->bmain, sp->scene, id, idtype, sp);
+ sce = preview_prepare_scene(sp->bmain, sp->scene, id_eval, idtype, sp);
if (sce == NULL) return;
if (!split || first) sprintf(name, "Preview %p", sp->owner);
/* construct shader preview from image size and previewcustomdata */
sp->scene = ip->scene;
+ sp->depsgraph = ip->depsgraph;
sp->owner = ip->owner;
sp->sizex = cur_size->sizex;
sp->sizey = cur_size->sizey;
/* customdata for preview thread */
ip->bmain = CTX_data_main(C);
ip->scene = CTX_data_scene(C);
+ ip->depsgraph = CTX_data_depsgraph(C);
ip->owner = owner;
ip->id = id;
/* customdata for preview thread */
sp->scene = scene;
+ sp->depsgraph = CTX_data_depsgraph(C);
sp->owner = owner;
sp->sizex = sizex;
sp->sizey = sizey;
data_to_c_simple(shaders/gpu_shader_instance_distance_line_vert.glsl SRC)
data_to_c_simple(shaders/gpu_shader_instance_edges_variying_color_geom.glsl SRC)
data_to_c_simple(shaders/gpu_shader_instance_edges_variying_color_vert.glsl SRC)
-data_to_c_simple(shaders/gpu_shader_instance_mball_handles_vert.glsl SRC)
data_to_c_simple(shaders/gpu_shader_3D_groundline_geom.glsl SRC)
data_to_c_simple(shaders/gpu_shader_3D_groundpoint_vert.glsl SRC)
GPU_SHADER_2D_NODELINK,
GPU_SHADER_2D_NODELINK_INST,
- GPU_SHADER_3D_INSTANCE_MBALL_HANDLES,
-
GPU_NUM_BUILTIN_SHADERS /* (not an actual shader) */
} GPUBuiltinShader;
datatoc_gpu_shader_2D_nodelink_frag_glsl },
[GPU_SHADER_2D_NODELINK_INST] = { datatoc_gpu_shader_2D_nodelink_vert_glsl,
datatoc_gpu_shader_2D_nodelink_frag_glsl },
-
- [GPU_SHADER_3D_INSTANCE_MBALL_HANDLES] = { datatoc_gpu_shader_instance_mball_handles_vert_glsl,
- datatoc_gpu_shader_flat_color_frag_glsl },
};
if (builtin_shaders[shader] == NULL) {
/* drawtype options (lighting, random) used for drawtype == OB_SOLID */
short drawtype_lighting;
short drawtype_options;
- short pad5;
+ short drawtype_studiolight;
int overlays;
int pad6;
RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_update");
}
-static void rna_def_constrainttarget(BlenderRNA *brna)
+static void rna_def_constraint_target_common(StructRNA *srna)
{
- StructRNA *srna;
PropertyRNA *prop;
- srna = RNA_def_struct(brna, "ConstraintTarget", NULL);
- RNA_def_struct_ui_text(srna, "Constraint Target", "Target object for multi-target constraints");
- RNA_def_struct_sdna(srna, "bConstraintTarget");
-
prop = RNA_def_property(srna, "target", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "tar");
- RNA_def_property_ui_text(prop, "Target", "Target Object");
+ RNA_def_property_ui_text(prop, "Target", "Target object");
RNA_def_property_flag(prop, PROP_EDITABLE);
RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_dependency_update");
prop = RNA_def_property(srna, "subtarget", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "subtarget");
- RNA_def_property_ui_text(prop, "Sub-Target", "");
+ RNA_def_property_ui_text(prop, "Sub-Target", "Armature bone, mesh or lattice vertex group, ...");
RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_dependency_update");
+}
+
+static void rna_def_constrainttarget(BlenderRNA *brna)
+{
+ StructRNA *srna;
+
+ srna = RNA_def_struct(brna, "ConstraintTarget", NULL);
+ RNA_def_struct_ui_text(srna, "Constraint Target", "Target object for multi-target constraints");
+ RNA_def_struct_sdna(srna, "bConstraintTarget");
+
+ rna_def_constraint_target_common(srna);
/* space, flag and type still to do */
}
RNA_def_struct_ui_text(srna, "Child Of Constraint", "Create constraint-based parent-child relationship");
RNA_def_struct_sdna_from(srna, "bChildOfConstraint", "data");
- prop = RNA_def_property(srna, "target", PROP_POINTER, PROP_NONE);
- RNA_def_property_pointer_sdna(prop, NULL, "tar");
- RNA_def_property_ui_text(prop, "Target", "Target Object");
- RNA_def_property_flag(prop, PROP_EDITABLE);
- RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_dependency_update");
-
- prop = RNA_def_property(srna, "subtarget", PROP_STRING, PROP_NONE);
- RNA_def_property_string_sdna(prop, NULL, "subtarget");
- RNA_def_property_ui_text(prop, "Sub-Target", "");
- RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_dependency_update");
+ rna_def_constraint_target_common(srna);
prop = RNA_def_property(srna, "use_location_x", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", CHILDOF_LOCX);
RNA_def_struct_ui_text(srna, "Kinematic Constraint", "Inverse Kinematics");
RNA_def_struct_sdna_from(srna, "bKinematicConstraint", "data");
- prop = RNA_def_property(srna, "target", PROP_POINTER, PROP_NONE);
- RNA_def_property_pointer_sdna(prop, NULL, "tar");
- RNA_def_property_ui_text(prop, "Target", "Target Object");
- RNA_def_property_flag(prop, PROP_EDITABLE);
- RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_dependency_update");
-
- prop = RNA_def_property(srna, "subtarget", PROP_STRING, PROP_NONE);
- RNA_def_property_string_sdna(prop, NULL, "subtarget");
- RNA_def_property_ui_text(prop, "Sub-Target", "");
- RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_dependency_update");
+ rna_def_constraint_target_common(srna);
prop = RNA_def_property(srna, "iterations", PROP_INT, PROP_NONE);
RNA_def_property_range(prop, 0, 10000);
RNA_def_struct_sdna_from(srna, "bTrackToConstraint", "data");
- prop = RNA_def_property(srna, "target", PROP_POINTER, PROP_NONE);
- RNA_def_property_pointer_sdna(prop, NULL, "tar");
- RNA_def_property_ui_text(prop, "Target", "Target Object");
- RNA_def_property_flag(prop, PROP_EDITABLE);
- RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_dependency_update");
-
- prop = RNA_def_property(srna, "subtarget", PROP_STRING, PROP_NONE);
- RNA_def_property_string_sdna(prop, NULL, "subtarget");
- RNA_def_property_ui_text(prop, "Sub-Target", "");
- RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_dependency_update");
+ rna_def_constraint_target_common(srna);
prop = RNA_def_property(srna, "track_axis", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "reserved1");
RNA_def_struct_sdna_from(srna, "bLocateLikeConstraint", "data");
- prop = RNA_def_property(srna, "target", PROP_POINTER, PROP_NONE);
- RNA_def_property_pointer_sdna(prop, NULL, "tar");
- RNA_def_property_flag(prop, PROP_EDITABLE);
- RNA_def_property_ui_text(prop, "Target", "Target Object");
- RNA_def_property_flag(prop, PROP_EDITABLE);
- RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_dependency_update");
-
- prop = RNA_def_property(srna, "subtarget", PROP_STRING, PROP_NONE);
- RNA_def_property_string_sdna(prop, NULL, "subtarget");
- RNA_def_property_ui_text(prop, "Sub-Target", "");
- RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_dependency_update");
+ rna_def_constraint_target_common(srna);
prop = RNA_def_property(srna, "use_x", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", LOCLIKE_X);
RNA_def_struct_ui_text(srna, "Copy Rotation Constraint", "Copy the rotation of the target");
RNA_def_struct_sdna_from(srna, "bRotateLikeConstraint", "data");
- prop = RNA_def_property(srna, "target", PROP_POINTER, PROP_NONE);
- RNA_def_property_pointer_sdna(prop, NULL, "tar");
- RNA_def_property_ui_text(prop, "Target", "Target Object");
- RNA_def_property_flag(prop, PROP_EDITABLE);
- RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_dependency_update");
-
- prop = RNA_def_property(srna, "subtarget", PROP_STRING, PROP_NONE);
- RNA_def_property_string_sdna(prop, NULL, "subtarget");
- RNA_def_property_ui_text(prop, "Sub-Target", "");
- RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_dependency_update");
+ rna_def_constraint_target_common(srna);
prop = RNA_def_property(srna, "use_x", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", ROTLIKE_X);
RNA_def_struct_ui_text(srna, "Copy Scale Constraint", "Copy the scale of the target");
RNA_def_struct_sdna_from(srna, "bSizeLikeConstraint", "data");
- prop = RNA_def_property(srna, "target", PROP_POINTER, PROP_NONE);
- RNA_def_property_pointer_sdna(prop, NULL, "tar");
- RNA_def_property_flag(prop, PROP_EDITABLE);
- RNA_def_property_ui_text(prop, "Target", "Target Object");
- RNA_def_property_flag(prop, PROP_EDITABLE);
- RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_dependency_update");
-
- prop = RNA_def_property(srna, "subtarget", PROP_STRING, PROP_NONE);
- RNA_def_property_string_sdna(prop, NULL, "subtarget");
- RNA_def_property_ui_text(prop, "Sub-Target", "");
- RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_dependency_update");
+ rna_def_constraint_target_common(srna);
prop = RNA_def_property(srna, "use_x", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", SIZELIKE_X);
static void rna_def_constraint_transform_like(BlenderRNA *brna)
{
StructRNA *srna;
- PropertyRNA *prop;
srna = RNA_def_struct(brna, "CopyTransformsConstraint", "Constraint");
RNA_def_struct_ui_text(srna, "Copy Transforms Constraint", "Copy all the transforms of the target");
RNA_def_struct_sdna_from(srna, "bTransLikeConstraint", "data");
- prop = RNA_def_property(srna, "target", PROP_POINTER, PROP_NONE);
- RNA_def_property_pointer_sdna(prop, NULL, "tar");
- RNA_def_property_ui_text(prop, "Target", "Target Object");
- RNA_def_property_flag(prop, PROP_EDITABLE);
- RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_dependency_update");
-
- prop = RNA_def_property(srna, "subtarget", PROP_STRING, PROP_NONE);
- RNA_def_property_string_sdna(prop, NULL, "subtarget");
- RNA_def_property_ui_text(prop, "Sub-Target", "");
- RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_dependency_update");
+ rna_def_constraint_target_common(srna);
}
static void rna_def_constraint_minmax(BlenderRNA *brna)
RNA_def_struct_ui_text(srna, "Floor Constraint", "Use the target object for location limitation");
RNA_def_struct_sdna_from(srna, "bMinMaxConstraint", "data");
- prop = RNA_def_property(srna, "target", PROP_POINTER, PROP_NONE);
- RNA_def_property_pointer_sdna(prop, NULL, "tar");
- RNA_def_property_ui_text(prop, "Target", "Target Object");
- RNA_def_property_flag(prop, PROP_EDITABLE);
- RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_dependency_update");
-
- prop = RNA_def_property(srna, "subtarget", PROP_STRING, PROP_NONE);
- RNA_def_property_string_sdna(prop, NULL, "subtarget");
- RNA_def_property_ui_text(prop, "Sub-Target", "");
- RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_dependency_update");
+ rna_def_constraint_target_common(srna);
prop = RNA_def_property(srna, "floor_location", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "minmaxflag");
RNA_def_struct_ui_text(srna, "Action Constraint", "Map an action to the transform axes of a bone");
RNA_def_struct_sdna_from(srna, "bActionConstraint", "data");
- prop = RNA_def_property(srna, "target", PROP_POINTER, PROP_NONE);
- RNA_def_property_pointer_sdna(prop, NULL, "tar");
- RNA_def_property_ui_text(prop, "Target", "Target Object");
- RNA_def_property_flag(prop, PROP_EDITABLE);
- RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_dependency_update");
-
- prop = RNA_def_property(srna, "subtarget", PROP_STRING, PROP_NONE);
- RNA_def_property_string_sdna(prop, NULL, "subtarget");
- RNA_def_property_ui_text(prop, "Sub-Target", "");
- RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_dependency_update");
+ rna_def_constraint_target_common(srna);
prop = RNA_def_property(srna, "transform_channel", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "type");
RNA_def_struct_sdna_from(srna, "bLockTrackConstraint", "data");
- prop = RNA_def_property(srna, "target", PROP_POINTER, PROP_NONE);
- RNA_def_property_pointer_sdna(prop, NULL, "tar");
- RNA_def_property_ui_text(prop, "Target", "Target Object");
- RNA_def_property_flag(prop, PROP_EDITABLE);
- RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_dependency_update");
-
- prop = RNA_def_property(srna, "subtarget", PROP_STRING, PROP_NONE);
- RNA_def_property_string_sdna(prop, NULL, "subtarget");
- RNA_def_property_ui_text(prop, "Sub-Target", "");
- RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_dependency_update");
+ rna_def_constraint_target_common(srna);
prop = RNA_def_property(srna, "track_axis", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "trackflag");
prop = RNA_def_property(srna, "target", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "tar");
RNA_def_property_pointer_funcs(prop, NULL, NULL, NULL, "rna_Curve_object_poll");
- RNA_def_property_ui_text(prop, "Target", "Target Object");
+ RNA_def_property_ui_text(prop, "Target", "Target Curve object");
RNA_def_property_flag(prop, PROP_EDITABLE);
RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_dependency_update");
RNA_def_struct_sdna_from(srna, "bStretchToConstraint", "data");
- prop = RNA_def_property(srna, "target", PROP_POINTER, PROP_NONE);
- RNA_def_property_pointer_sdna(prop, NULL, "tar");
- RNA_def_property_ui_text(prop, "Target", "Target Object");
- RNA_def_property_flag(prop, PROP_EDITABLE);
- RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_dependency_update");
-
- prop = RNA_def_property(srna, "subtarget", PROP_STRING, PROP_NONE);
- RNA_def_property_string_sdna(prop, NULL, "subtarget");
- RNA_def_property_ui_text(prop, "Sub-Target", "");
- RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_dependency_update");
+ rna_def_constraint_target_common(srna);
prop = RNA_def_property(srna, "volume", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "volmode");
RNA_def_struct_ui_text(srna, "Transformation Constraint", "Map transformations of the target to the object");
RNA_def_struct_sdna_from(srna, "bTransformConstraint", "data");
- prop = RNA_def_property(srna, "target", PROP_POINTER, PROP_NONE);
- RNA_def_property_pointer_sdna(prop, NULL, "tar");
- RNA_def_property_ui_text(prop, "Target", "Target Object");
- RNA_def_property_flag(prop, PROP_EDITABLE);
- RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_dependency_update");
-
- prop = RNA_def_property(srna, "subtarget", PROP_STRING, PROP_NONE);
- RNA_def_property_string_sdna(prop, NULL, "subtarget");
- RNA_def_property_ui_text(prop, "Sub-Target", "");
- RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_dependency_update");
+ rna_def_constraint_target_common(srna);
prop = RNA_def_property(srna, "map_from", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "from");
RNA_def_struct_sdna_from(srna, "bDistLimitConstraint", "data");
- prop = RNA_def_property(srna, "target", PROP_POINTER, PROP_NONE);
- RNA_def_property_pointer_sdna(prop, NULL, "tar");
- RNA_def_property_ui_text(prop, "Target", "Target Object");
- RNA_def_property_flag(prop, PROP_EDITABLE);
- RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_dependency_update");
-
- prop = RNA_def_property(srna, "subtarget", PROP_STRING, PROP_NONE);
- RNA_def_property_string_sdna(prop, NULL, "subtarget");
- RNA_def_property_ui_text(prop, "Sub-Target", "");
- RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_dependency_update");
+ rna_def_constraint_target_common(srna);
prop = RNA_def_property(srna, "distance", PROP_FLOAT, PROP_DISTANCE);
RNA_def_property_float_sdna(prop, NULL, "dist");
prop = RNA_def_property(srna, "target", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "target"); /* TODO, mesh type */
RNA_def_property_pointer_funcs(prop, NULL, NULL, NULL, "rna_Mesh_object_poll");
- RNA_def_property_ui_text(prop, "Target", "Target Object");
+ RNA_def_property_ui_text(prop, "Target", "Target Mesh object");
RNA_def_property_flag(prop, PROP_EDITABLE);
RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_dependency_update");
RNA_def_struct_sdna_from(srna, "bDampTrackConstraint", "data");
- prop = RNA_def_property(srna, "target", PROP_POINTER, PROP_NONE);
- RNA_def_property_pointer_sdna(prop, NULL, "tar");
- RNA_def_property_ui_text(prop, "Target", "Target Object");
- RNA_def_property_flag(prop, PROP_EDITABLE);
- RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_dependency_update");
-
- prop = RNA_def_property(srna, "subtarget", PROP_STRING, PROP_NONE);
- RNA_def_property_string_sdna(prop, NULL, "subtarget");
- RNA_def_property_ui_text(prop, "Sub-Target", "");
- RNA_def_property_update(prop, NC_OBJECT | ND_CONSTRAINT, "rna_Constraint_dependency_update");
+ rna_def_constraint_target_common(srna);
prop = RNA_def_property(srna, "track_axis", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "trackflag");
{V3D_DRAWOPTION_RANDOMIZE, "RANDOM", 0, "Random", "Show random object color"},
{0, NULL, 0, NULL, NULL}
};
+ static const EnumPropertyItem studio_lighting_items[] = {
+ {0, "01", ICON_STUDIOLIGHT_01, "", ""},
+ {1, "02", ICON_STUDIOLIGHT_02, "", ""},
+ {2, "03", ICON_STUDIOLIGHT_03, "", ""},
+ {3, "04", ICON_STUDIOLIGHT_04, "", ""},
+ {4, "05", ICON_STUDIOLIGHT_05, "", ""},
+ {0, NULL, 0, NULL, NULL}
+ };
srna = RNA_def_struct(brna, "View3DShading", NULL);
RNA_def_struct_sdna(srna, "View3D");
RNA_def_property_ui_text(prop, "Object Overlap", "Show Object Overlap");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, "rna_3DViewShading_type_update");
+ prop = RNA_def_property(srna, "studiolight", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "drawtype_studiolight");
+ RNA_def_property_enum_items(prop, studio_lighting_items);
+ RNA_def_property_ui_text(prop, "Studiolight", "Studio lighting setup");
+ RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, "rna_3DViewShading_type_update");
+
prop = RNA_def_property(srna, "single_color_mode", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, single_color_mode_items);
RNA_def_property_enum_funcs(prop, "rna_View3DShading_single_color_mode_get",
return !((edge_ref->f1 == 0) && (edge_ref->f2 == 0));
}
+/**
+ * \param dm Mesh to calculate normals for.
+ * \param face_nors Precalculated face normals.
+ * \param r_vert_nors Return vert normals.
+ */
+static void mesh_calc_hq_normal(Mesh *mesh, float (*face_nors)[3], float (*r_vert_nors)[3])
+{
+ int i, numVerts, numEdges, numFaces;
+ MPoly *mpoly, *mp;
+ MLoop *mloop, *ml;
+ MEdge *medge, *ed;
+ MVert *mvert, *mv;
+
+ numVerts = mesh->totvert;
+ numEdges = mesh->totedge;
+ numFaces = mesh->totface;
+ mpoly = mesh->mpoly;
+ medge = mesh->medge;
+ mvert = mesh->mvert;
+ mloop = mesh->mloop;
+
+ /* we don't want to overwrite any referenced layers */
+
+ /* Doesn't work here! */
+#if 0
+ mv = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT, numVerts);
+ cddm->mvert = mv;
+#endif
+
+ mv = mvert;
+ mp = mpoly;
+
+ {
+ EdgeFaceRef *edge_ref_array = MEM_calloc_arrayN((size_t)numEdges, sizeof(EdgeFaceRef), "Edge Connectivity");
+ EdgeFaceRef *edge_ref;
+ float edge_normal[3];
+
+ /* This loop adds an edge hash if its not there, and adds the face index */
+ for (i = 0; i < numFaces; i++, mp++) {
+ int j;
+
+ ml = mloop + mp->loopstart;
+
+ for (j = 0; j < mp->totloop; j++, ml++) {
+ /* --- add edge ref to face --- */
+ edge_ref = &edge_ref_array[ml->e];
+ if (!edgeref_is_init(edge_ref)) {
+ edge_ref->f1 = i;
+ edge_ref->f2 = -1;
+ }
+ else if ((edge_ref->f1 != -1) && (edge_ref->f2 == -1)) {
+ edge_ref->f2 = i;
+ }
+ else {
+ /* 3+ faces using an edge, we can't handle this usefully */
+ edge_ref->f1 = edge_ref->f2 = -1;
+#ifdef USE_NONMANIFOLD_WORKAROUND
+ medge[ml->e].flag |= ME_EDGE_TMP_TAG;
+#endif
+ }
+ /* --- done --- */
+ }
+ }
+
+ for (i = 0, ed = medge, edge_ref = edge_ref_array; i < numEdges; i++, ed++, edge_ref++) {
+ /* Get the edge vert indices, and edge value (the face indices that use it) */
+
+ if (edgeref_is_init(edge_ref) && (edge_ref->f1 != -1)) {
+ if (edge_ref->f2 != -1) {
+ /* We have 2 faces using this edge, calculate the edges normal
+ * using the angle between the 2 faces as a weighting */
+#if 0
+ add_v3_v3v3(edge_normal, face_nors[edge_ref->f1], face_nors[edge_ref->f2]);
+ normalize_v3_length(
+ edge_normal,
+ angle_normalized_v3v3(face_nors[edge_ref->f1], face_nors[edge_ref->f2]));
+#else
+ mid_v3_v3v3_angle_weighted(edge_normal, face_nors[edge_ref->f1], face_nors[edge_ref->f2]);
+#endif
+ }
+ else {
+ /* only one face attached to that edge */
+ /* an edge without another attached- the weight on this is undefined */
+ copy_v3_v3(edge_normal, face_nors[edge_ref->f1]);
+ }
+ add_v3_v3(r_vert_nors[ed->v1], edge_normal);
+ add_v3_v3(r_vert_nors[ed->v2], edge_normal);
+ }
+ }
+ MEM_freeN(edge_ref_array);
+ }
+
+ /* normalize vertex normals and assign */
+ for (i = 0; i < numVerts; i++, mv++) {
+ if (normalize_v3(r_vert_nors[i]) == 0.0f) {
+ normal_short_to_float_v3(r_vert_nors[i], mv->no);
+ }
+ }
+}
+
static void initData(ModifierData *md)
{
SolidifyModifierData *smd = (SolidifyModifierData *) md;
if (smd->flag & MOD_SOLIDIFY_NORMAL_CALC) {
vert_nors = MEM_calloc_arrayN(numVerts, 3 * sizeof(float), "mod_solid_vno_hq");
- BKE_mesh_calc_normals_poly(mesh->mvert, vert_nors, mesh->totvert,
- mesh->mloop, mesh->mpoly, mesh->totloop, mesh->totpoly,
- NULL, false);
+ mesh_calc_hq_normal(mesh, face_nors, vert_nors);
}
result = BKE_mesh_from_template(mesh,