Merge branch 'master' into blender2.8

This commit is contained in:
Campbell Barton 2017-03-31 23:52:22 +11:00
commit 70fdf0fe37
25 changed files with 225 additions and 127 deletions

View File

@ -22,6 +22,7 @@ if(WITH_CYCLES_NATIVE_ONLY)
-DWITH_KERNEL_NATIVE
)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=native")
set(CYCLES_KERNEL_FLAGS "-march=native")
elseif(NOT WITH_CPU_SSE)
set(CXX_HAS_SSE FALSE)
set(CXX_HAS_AVX FALSE)
@ -59,10 +60,13 @@ elseif(WIN32 AND MSVC)
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Ox")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /Ox")
set(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL} /Ox")
set(CYCLES_KERNEL_FLAGS "/fp:fast -D_CRT_SECURE_NO_WARNINGS /GS-")
elseif(CMAKE_COMPILER_IS_GNUCC)
check_cxx_compiler_flag(-msse CXX_HAS_SSE)
check_cxx_compiler_flag(-mavx CXX_HAS_AVX)
check_cxx_compiler_flag(-mavx2 CXX_HAS_AVX2)
set(CYCLES_KERNEL_FLAGS "-ffast-math")
if(CXX_HAS_SSE)
set(CYCLES_SSE2_KERNEL_FLAGS "-ffast-math -msse -msse2 -mfpmath=sse")
set(CYCLES_SSE3_KERNEL_FLAGS "-ffast-math -msse -msse2 -msse3 -mssse3 -mfpmath=sse")
@ -79,6 +83,7 @@ elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
check_cxx_compiler_flag(-msse CXX_HAS_SSE)
check_cxx_compiler_flag(-mavx CXX_HAS_AVX)
check_cxx_compiler_flag(-mavx2 CXX_HAS_AVX2)
set(CYCLES_KERNEL_FLAGS "-ffast-math")
if(CXX_HAS_SSE)
set(CYCLES_SSE2_KERNEL_FLAGS "-ffast-math -msse -msse2")
set(CYCLES_SSE3_KERNEL_FLAGS "-ffast-math -msse -msse2 -msse3 -mssse3")

View File

@ -67,7 +67,7 @@ BVH *BVH::create(const BVHParams& params, const vector<Object*>& objects)
if(params.use_qbvh)
return new QBVH(params, objects);
else
return new RegularBVH(params, objects);
return new BinaryBVH(params, objects);
}
/* Building */
@ -427,13 +427,13 @@ static bool node_bvh_is_unaligned(const BVHNode *node)
return node0->is_unaligned || node1->is_unaligned;
}
RegularBVH::RegularBVH(const BVHParams& params_, const vector<Object*>& objects_)
BinaryBVH::BinaryBVH(const BVHParams& params_, const vector<Object*>& objects_)
: BVH(params_, objects_)
{
}
void RegularBVH::pack_leaf(const BVHStackEntry& e,
const LeafNode *leaf)
void BinaryBVH::pack_leaf(const BVHStackEntry& e,
const LeafNode *leaf)
{
assert(e.idx + BVH_NODE_LEAF_SIZE <= pack.leaf_nodes.size());
float4 data[BVH_NODE_LEAF_SIZE];
@ -456,9 +456,9 @@ void RegularBVH::pack_leaf(const BVHStackEntry& e,
memcpy(&pack.leaf_nodes[e.idx], data, sizeof(float4)*BVH_NODE_LEAF_SIZE);
}
void RegularBVH::pack_inner(const BVHStackEntry& e,
const BVHStackEntry& e0,
const BVHStackEntry& e1)
void BinaryBVH::pack_inner(const BVHStackEntry& e,
const BVHStackEntry& e0,
const BVHStackEntry& e1)
{
if(e0.node->is_unaligned || e1.node->is_unaligned) {
pack_unaligned_inner(e, e0, e1);
@ -467,9 +467,9 @@ void RegularBVH::pack_inner(const BVHStackEntry& e,
}
}
void RegularBVH::pack_aligned_inner(const BVHStackEntry& e,
const BVHStackEntry& e0,
const BVHStackEntry& e1)
void BinaryBVH::pack_aligned_inner(const BVHStackEntry& e,
const BVHStackEntry& e0,
const BVHStackEntry& e1)
{
pack_aligned_node(e.idx,
e0.node->bounds, e1.node->bounds,
@ -477,11 +477,11 @@ void RegularBVH::pack_aligned_inner(const BVHStackEntry& e,
e0.node->visibility, e1.node->visibility);
}
void RegularBVH::pack_aligned_node(int idx,
const BoundBox& b0,
const BoundBox& b1,
int c0, int c1,
uint visibility0, uint visibility1)
void BinaryBVH::pack_aligned_node(int idx,
const BoundBox& b0,
const BoundBox& b1,
int c0, int c1,
uint visibility0, uint visibility1)
{
assert(idx + BVH_NODE_SIZE <= pack.nodes.size());
assert(c0 < 0 || c0 < pack.nodes.size());
@ -508,9 +508,9 @@ void RegularBVH::pack_aligned_node(int idx,
memcpy(&pack.nodes[idx], data, sizeof(int4)*BVH_NODE_SIZE);
}
void RegularBVH::pack_unaligned_inner(const BVHStackEntry& e,
const BVHStackEntry& e0,
const BVHStackEntry& e1)
void BinaryBVH::pack_unaligned_inner(const BVHStackEntry& e,
const BVHStackEntry& e0,
const BVHStackEntry& e1)
{
pack_unaligned_node(e.idx,
e0.node->get_aligned_space(),
@ -521,13 +521,13 @@ void RegularBVH::pack_unaligned_inner(const BVHStackEntry& e,
e0.node->visibility, e1.node->visibility);
}
void RegularBVH::pack_unaligned_node(int idx,
const Transform& aligned_space0,
const Transform& aligned_space1,
const BoundBox& bounds0,
const BoundBox& bounds1,
int c0, int c1,
uint visibility0, uint visibility1)
void BinaryBVH::pack_unaligned_node(int idx,
const Transform& aligned_space0,
const Transform& aligned_space1,
const BoundBox& bounds0,
const BoundBox& bounds1,
int c0, int c1,
uint visibility0, uint visibility1)
{
assert(idx + BVH_UNALIGNED_NODE_SIZE <= pack.nodes.size());
assert(c0 < 0 || c0 < pack.nodes.size());
@ -553,7 +553,7 @@ void RegularBVH::pack_unaligned_node(int idx,
memcpy(&pack.nodes[idx], data, sizeof(float4)*BVH_UNALIGNED_NODE_SIZE);
}
void RegularBVH::pack_nodes(const BVHNode *root)
void BinaryBVH::pack_nodes(const BVHNode *root)
{
const size_t num_nodes = root->getSubtreeSize(BVH_STAT_NODE_COUNT);
const size_t num_leaf_nodes = root->getSubtreeSize(BVH_STAT_LEAF_COUNT);
@ -630,7 +630,7 @@ void RegularBVH::pack_nodes(const BVHNode *root)
pack.root_index = (root->is_leaf())? -1: 0;
}
void RegularBVH::refit_nodes()
void BinaryBVH::refit_nodes()
{
assert(!params.top_level);
@ -639,7 +639,7 @@ void RegularBVH::refit_nodes()
refit_node(0, (pack.root_index == -1)? true: false, bbox, visibility);
}
void RegularBVH::refit_node(int idx, bool leaf, BoundBox& bbox, uint& visibility)
void BinaryBVH::refit_node(int idx, bool leaf, BoundBox& bbox, uint& visibility)
{
if(leaf) {
assert(idx + BVH_NODE_LEAF_SIZE <= pack.leaf_nodes.size());

View File

@ -110,15 +110,15 @@ protected:
virtual void refit_nodes() = 0;
};
/* Regular BVH
/* Binary BVH
*
* Typical BVH with each node having two children. */
class RegularBVH : public BVH {
class BinaryBVH : public BVH {
protected:
/* constructor */
friend class BVH;
RegularBVH(const BVHParams& params, const vector<Object*>& objects);
BinaryBVH(const BVHParams& params, const vector<Object*>& objects);
/* pack */
void pack_nodes(const BVHNode *root);

View File

@ -300,8 +300,8 @@ public:
{
const int cuda_version = cuewCompilerVersion();
const int machine = system_cpu_bits();
const string kernel_path = path_get("source/kernel");
const string include = path_dirname(kernel_path);
const string source_path = path_get("source");
const string include_path = source_path;
string cflags = string_printf("-m%d "
"--ptxas-options=\"-v\" "
"--use_fast_math "
@ -310,7 +310,7 @@ public:
"-I\"%s\"",
machine,
cuda_version,
include.c_str());
include_path.c_str());
if(use_adaptive_compilation()) {
cflags += " " + requested_features.get_build_options();
}
@ -382,8 +382,8 @@ public:
compile_kernel_get_common_cflags(requested_features, split);
/* Try to use locally compiled kernel. */
const string kernel_path = path_get("source/kernel");
const string kernel_md5 = path_files_md5_hash(kernel_path);
const string source_path = path_get("source");
const string kernel_md5 = path_files_md5_hash(source_path);
/* We include cflags into md5 so changing cuda toolkit or changing other
* compiler command line arguments makes sure cubin gets re-built.
@ -424,9 +424,10 @@ public:
return "";
}
const char *nvcc = cuewCompilerPath();
const string kernel = path_join(kernel_path,
path_join("kernels",
path_join("cuda", split ? "kernel_split.cu" : "kernel.cu")));
const string kernel = path_join(
path_join(source_path, "kernel"),
path_join("kernels",
path_join("cuda", split ? "kernel_split.cu" : "kernel.cu")));
double starttime = time_dt();
printf("Compiling CUDA kernel ...\n");

View File

@ -235,7 +235,7 @@ string OpenCLCache::get_kernel_md5()
thread_scoped_lock lock(self.kernel_md5_lock);
if(self.kernel_md5.empty()) {
self.kernel_md5 = path_files_md5_hash(path_get("source/kernel"));
self.kernel_md5 = path_files_md5_hash(path_get("source"));
}
return self.kernel_md5;
}
@ -443,8 +443,8 @@ void OpenCLDeviceBase::OpenCLProgram::load()
add_log(string("OpenCL program ") + program_name + " not found in cache.", true);
/* need to create source to get md5 */
string source = "#include \"kernels/opencl/" + kernel_file + "\"\n";
source = path_source_replace_includes(source, path_get("source/kernel"));
string source = "#include \"kernel/kernels/opencl/" + kernel_file + "\"\n";
source = path_source_replace_includes(source, path_get("source"));
string basename = "cycles_kernel_" + program_name + "_" + device_md5 + "_" + util_md5_string(source);
basename = path_cache_get(path_join("kernels", basename));

View File

@ -347,6 +347,9 @@ endif()
include_directories(${INC})
include_directories(SYSTEM ${INC_SYS})
set_source_files_properties(kernels/cpu/kernel.cpp PROPERTIES COMPILE_FLAGS "${CYCLES_KERNEL_FLAGS}")
set_source_files_properties(kernels/cpu/kernel_split.cpp PROPERTIES COMPILE_FLAGS "${CYCLES_KERNEL_FLAGS}")
if(CXX_HAS_SSE)
list(APPEND SRC
kernels/cpu/kernel_sse2.cpp

View File

@ -320,17 +320,18 @@ static char *path_specials(const string& sub)
{
static bool env_init = false;
static char *env_shader_path;
static char *env_kernel_path;
static char *env_source_path;
if(!env_init) {
env_shader_path = getenv("CYCLES_SHADER_PATH");
env_kernel_path = getenv("CYCLES_KERNEL_PATH");
/* NOTE: It is KERNEL in env variable for compatibility reasons. */
env_source_path = getenv("CYCLES_KERNEL_PATH");
env_init = true;
}
if(env_shader_path != NULL && sub == "shader") {
return env_shader_path;
}
else if(env_shader_path != NULL && sub == "kernel") {
return env_kernel_path;
else if(env_shader_path != NULL && sub == "source") {
return env_source_path;
}
return NULL;
}

View File

@ -2092,7 +2092,7 @@ class WM_OT_addon_install(Operator):
# print message
msg = (
tip_("Modules Installed (%s) from %r into %r (%s)") %
tip_("Modules Installed (%s) from %r into %r") %
(", ".join(sorted(addons_new)), pyfile, path_addons)
)
print(msg)

View File

@ -569,6 +569,14 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
col.prop(md, "use_mirror_u", text="U")
col.prop(md, "use_mirror_v", text="V")
col = layout.column(align=True)
if md.use_mirror_u:
col.prop(md, "mirror_offset_u")
if md.use_mirror_v:
col.prop(md, "mirror_offset_v")
col = layout.column()
if md.use_mirror_merge is True:

View File

@ -130,18 +130,22 @@ void IDP_FreeIDPArray(IDProperty *prop)
MEM_freeN(prop->data.pointer);
}
/*shallow copies item*/
/* shallow copies item */
void IDP_SetIndexArray(IDProperty *prop, int index, IDProperty *item)
{
IDProperty *old;
BLI_assert(prop->type == IDP_IDPARRAY);
if (index >= prop->len || index < 0)
return;
old = GETPROP(prop, index);
if (index >= prop->len || index < 0) return;
if (item != old) IDP_FreeProperty(old);
memcpy(GETPROP(prop, index), item, sizeof(IDProperty));
if (item != old) {
IDP_FreeProperty(old);
memcpy(old, item, sizeof(IDProperty));
}
}
IDProperty *IDP_GetIndexArray(IDProperty *prop, int index)

View File

@ -1512,23 +1512,6 @@ int BM_mesh_elem_count(BMesh *bm, const char htype)
}
}
/**
* Special case: Python uses custom-data layers to hold PyObject references.
* These have to be kept in-place, else the PyObject's we point to, wont point back to us.
*
* \note ``ele_src`` Is a duplicate, so we don't need to worry about getting in a feedback loop.
*
* \note If there are other customdata layers which need this functionality, it should be generalized.
* However #BM_mesh_remap is currently the only place where this is done.
*/
static void bm_mesh_remap_cd_update(
BMHeader *ele_dst, BMHeader *ele_src,
const int cd_elem_pyptr)
{
void **pyptr_dst_p = BM_ELEM_CD_GET_VOID_P(((BMElem *)ele_dst), cd_elem_pyptr);
void **pyptr_src_p = BM_ELEM_CD_GET_VOID_P(((BMElem *)ele_src), cd_elem_pyptr);
*pyptr_dst_p = *pyptr_src_p;
}
/**
* Remaps the vertices, edges and/or faces of the bmesh as indicated by vert/edge/face_idx arrays
@ -1570,6 +1553,8 @@ void BM_mesh_remap(
BMVert **verts_pool, *verts_copy, **vep;
int i, totvert = bm->totvert;
const unsigned int *new_idx;
/* Special case: Python uses custom - data layers to hold PyObject references.
* These have to be kept in - place, else the PyObject's we point to, wont point back to us. */
const int cd_vert_pyptr = CustomData_get_offset(&bm->vdata, CD_BM_ELEM_PYPTR);
/* Init the old-to-new vert pointers mapping */
@ -1578,9 +1563,14 @@ void BM_mesh_remap(
/* Make a copy of all vertices. */
verts_pool = bm->vtable;
verts_copy = MEM_mallocN(sizeof(BMVert) * totvert, "BM_mesh_remap verts copy");
void **pyptrs = (cd_vert_pyptr != -1) ? MEM_mallocN(sizeof(void *) * totvert, __func__) : NULL;
for (i = totvert, ve = verts_copy + totvert - 1, vep = verts_pool + totvert - 1; i--; ve--, vep--) {
*ve = **vep;
/* printf("*vep: %p, verts_pool[%d]: %p\n", *vep, i, verts_pool[i]);*/
if (cd_vert_pyptr != -1) {
void **pyptr = BM_ELEM_CD_GET_VOID_P(((BMElem *)ve), cd_vert_pyptr);
pyptrs[i] = *pyptr;
}
}
/* Copy back verts to their new place, and update old2new pointers mapping. */
@ -1593,13 +1583,17 @@ void BM_mesh_remap(
/* printf("mapping vert from %d to %d (%p/%p to %p)\n", i, *new_idx, *vep, verts_pool[i], new_vep);*/
BLI_ghash_insert(vptr_map, *vep, new_vep);
if (cd_vert_pyptr != -1) {
bm_mesh_remap_cd_update(&(*vep)->head, &new_vep->head, cd_vert_pyptr);
void **pyptr = BM_ELEM_CD_GET_VOID_P(((BMElem *)new_vep), cd_vert_pyptr);
*pyptr = pyptrs[*new_idx];
}
}
bm->elem_index_dirty |= BM_VERT;
bm->elem_table_dirty |= BM_VERT;
MEM_freeN(verts_copy);
if (pyptrs) {
MEM_freeN(pyptrs);
}
}
/* Remap Edges */
@ -1607,6 +1601,8 @@ void BM_mesh_remap(
BMEdge **edges_pool, *edges_copy, **edp;
int i, totedge = bm->totedge;
const unsigned int *new_idx;
/* Special case: Python uses custom - data layers to hold PyObject references.
* These have to be kept in - place, else the PyObject's we point to, wont point back to us. */
const int cd_edge_pyptr = CustomData_get_offset(&bm->edata, CD_BM_ELEM_PYPTR);
/* Init the old-to-new vert pointers mapping */
@ -1615,8 +1611,13 @@ void BM_mesh_remap(
/* Make a copy of all vertices. */
edges_pool = bm->etable;
edges_copy = MEM_mallocN(sizeof(BMEdge) * totedge, "BM_mesh_remap edges copy");
void **pyptrs = (cd_edge_pyptr != -1) ? MEM_mallocN(sizeof(void *) * totedge, __func__) : NULL;
for (i = totedge, ed = edges_copy + totedge - 1, edp = edges_pool + totedge - 1; i--; ed--, edp--) {
*ed = **edp;
if (cd_edge_pyptr != -1) {
void **pyptr = BM_ELEM_CD_GET_VOID_P(((BMElem *)ed), cd_edge_pyptr);
pyptrs[i] = *pyptr;
}
}
/* Copy back verts to their new place, and update old2new pointers mapping. */
@ -1629,13 +1630,17 @@ void BM_mesh_remap(
BLI_ghash_insert(eptr_map, *edp, new_edp);
/* printf("mapping edge from %d to %d (%p/%p to %p)\n", i, *new_idx, *edp, edges_pool[i], new_edp);*/
if (cd_edge_pyptr != -1) {
bm_mesh_remap_cd_update(&(*edp)->head, &new_edp->head, cd_edge_pyptr);
void **pyptr = BM_ELEM_CD_GET_VOID_P(((BMElem *)new_edp), cd_edge_pyptr);
*pyptr = pyptrs[*new_idx];
}
}
bm->elem_index_dirty |= BM_EDGE;
bm->elem_table_dirty |= BM_EDGE;
MEM_freeN(edges_copy);
if (pyptrs) {
MEM_freeN(pyptrs);
}
}
/* Remap Faces */
@ -1643,6 +1648,8 @@ void BM_mesh_remap(
BMFace **faces_pool, *faces_copy, **fap;
int i, totface = bm->totface;
const unsigned int *new_idx;
/* Special case: Python uses custom - data layers to hold PyObject references.
* These have to be kept in - place, else the PyObject's we point to, wont point back to us. */
const int cd_poly_pyptr = CustomData_get_offset(&bm->pdata, CD_BM_ELEM_PYPTR);
/* Init the old-to-new vert pointers mapping */
@ -1651,8 +1658,13 @@ void BM_mesh_remap(
/* Make a copy of all vertices. */
faces_pool = bm->ftable;
faces_copy = MEM_mallocN(sizeof(BMFace) * totface, "BM_mesh_remap faces copy");
void **pyptrs = (cd_poly_pyptr != -1) ? MEM_mallocN(sizeof(void *) * totface, __func__) : NULL;
for (i = totface, fa = faces_copy + totface - 1, fap = faces_pool + totface - 1; i--; fa--, fap--) {
*fa = **fap;
if (cd_poly_pyptr != -1) {
void **pyptr = BM_ELEM_CD_GET_VOID_P(((BMElem *)fa), cd_poly_pyptr);
pyptrs[i] = *pyptr;
}
}
/* Copy back verts to their new place, and update old2new pointers mapping. */
@ -1664,7 +1676,8 @@ void BM_mesh_remap(
*new_fap = *fa;
BLI_ghash_insert(fptr_map, *fap, new_fap);
if (cd_poly_pyptr != -1) {
bm_mesh_remap_cd_update(&(*fap)->head, &new_fap->head, cd_poly_pyptr);
void **pyptr = BM_ELEM_CD_GET_VOID_P(((BMElem *)new_fap), cd_poly_pyptr);
*pyptr = pyptrs[*new_idx];
}
}
@ -1672,6 +1685,9 @@ void BM_mesh_remap(
bm->elem_table_dirty |= BM_FACE;
MEM_freeN(faces_copy);
if (pyptrs) {
MEM_freeN(pyptrs);
}
}
/* And now, fix all vertices/edges/faces/loops pointers! */

View File

@ -77,28 +77,8 @@ static bool check_object_needs_evaluation(Object *object)
return false;
}
void deg_graph_build_finalize(Depsgraph *graph)
void deg_graph_build_flush_layers(Depsgraph *graph)
{
/* STEP 1: Make sure new invisible dependencies are ready for use.
*
* TODO(sergey): This might do a bit of extra tagging, but it's kinda nice
* to do it ahead of a time and don't spend time on flushing updates on
* every frame change.
*/
GHASH_FOREACH_BEGIN(IDDepsNode *, id_node, graph->id_hash)
{
if (id_node->layers == 0) {
ID *id = id_node->id;
if (GS(id->name) == ID_OB) {
Object *object = (Object *)id;
if (check_object_needs_evaluation(object)) {
id_node->tag_update(graph);
}
}
}
}
GHASH_FOREACH_END();
/* STEP 2: Flush visibility layers from children to parent. */
std::stack<OperationDepsNode *> stack;
foreach (OperationDepsNode *node, graph->operations) {
IDDepsNode *id_node = node->owner->owner;
@ -143,6 +123,31 @@ void deg_graph_build_finalize(Depsgraph *graph)
}
}
}
}
void deg_graph_build_finalize(Depsgraph *graph)
{
/* STEP 1: Make sure new invisible dependencies are ready for use.
*
* TODO(sergey): This might do a bit of extra tagging, but it's kinda nice
* to do it ahead of a time and don't spend time on flushing updates on
* every frame change.
*/
GHASH_FOREACH_BEGIN(IDDepsNode *, id_node, graph->id_hash)
{
if (id_node->layers == 0) {
ID *id = id_node->id;
if (GS(id->name) == ID_OB) {
Object *object = (Object *)id;
if (check_object_needs_evaluation(object)) {
id_node->tag_update(graph);
}
}
}
}
GHASH_FOREACH_END();
/* STEP 2: Flush visibility layers from children to parent. */
deg_graph_build_flush_layers(graph);
/* STEP 3: Re-tag IDs for update if it was tagged before the relations
* update tag.
*/

View File

@ -42,5 +42,6 @@ struct Depsgraph;
string deg_fcurve_id_name(const FCurve *fcu);
void deg_graph_build_finalize(struct Depsgraph *graph);
void deg_graph_build_flush_layers(struct Depsgraph *graph);
} // namespace DEG

View File

@ -56,8 +56,8 @@ extern "C" {
#include "DEG_depsgraph.h"
} /* extern "C" */
#include "intern/builder/deg_builder.h"
#include "intern/eval/deg_eval_flush.h"
#include "intern/nodes/deg_node.h"
#include "intern/nodes/deg_node_component.h"
#include "intern/nodes/deg_node_operation.h"
@ -348,6 +348,18 @@ void DEG_graph_on_visible_update(Main *bmain, Scene *scene)
GHASH_FOREACH_END();
}
scene->lay_updated |= graph->layers;
/* Special trick to get local view to work. */
LINKLIST_FOREACH (Base *, base, &scene->base) {
Object *object = base->object;
DEG::IDDepsNode *node = graph->find_id_node(&object->id);
node->layers = 0;
}
LINKLIST_FOREACH (Base *, base, &scene->base) {
Object *object = base->object;
DEG::IDDepsNode *node = graph->find_id_node(&object->id);
node->layers |= base->lay;
}
DEG::deg_graph_build_flush_layers(graph);
}
void DEG_on_visible_update(Main *bmain, const bool UNUSED(do_time))

View File

@ -424,7 +424,7 @@ typedef void (*uiBlockCancelFunc)(struct bContext *C, void *arg1);
void UI_popup_block_invoke(struct bContext *C, uiBlockCreateFunc func, void *arg);
void UI_popup_block_invoke_ex(struct bContext *C, uiBlockCreateFunc func, void *arg, const char *opname, int opcontext);
void UI_popup_block_ex(struct bContext *C, uiBlockCreateFunc func, uiBlockHandleFunc popup_func, uiBlockCancelFunc cancel_func, void *arg);
void UI_popup_block_ex(struct bContext *C, uiBlockCreateFunc func, uiBlockHandleFunc popup_func, uiBlockCancelFunc cancel_func, void *arg, struct wmOperator *op);
/* void uiPupBlockOperator(struct bContext *C, uiBlockCreateFunc func, struct wmOperator *op, int opcontext); */ /* UNUSED */
void UI_popup_block_close(struct bContext *C, struct wmWindow *win, uiBlock *block);

View File

@ -87,6 +87,7 @@
#include "WM_api.h"
#include "WM_types.h"
#include "wm_event_system.h"
#ifdef WITH_INPUT_IME
# include "wm_window.h"
@ -381,6 +382,7 @@ typedef struct uiAfterFunc {
void *butm_func_arg;
int a2;
wmOperator *popup_op;
wmOperatorType *optype;
int opcontext;
PointerRNA *opptr;
@ -636,13 +638,24 @@ PointerRNA *ui_handle_afterfunc_add_operator(wmOperatorType *ot, int opcontext,
return ptr;
}
static void popup_check(bContext *C, wmOperator *op)
{
if (op && op->type->check && op->type->check(C, op)) {
/* check for popup and re-layout buttons */
ARegion *ar_menu = CTX_wm_menu(C);
if (ar_menu)
ED_region_tag_refresh_ui(ar_menu);
}
}
/**
* Check if a #uiAfterFunc is needed for this button.
*/
static bool ui_afterfunc_check(const uiBlock *block, const uiBut *but)
{
return (but->func || but->funcN || but->rename_func || but->optype || but->rnaprop || block->handle_func ||
(but->type == UI_BTYPE_BUT_MENU && block->butm_func));
(but->type == UI_BTYPE_BUT_MENU && block->butm_func) ||
(block->handle && block->handle->popup_op));
}
static void ui_apply_but_func(bContext *C, uiBut *but)
@ -683,6 +696,9 @@ static void ui_apply_but_func(bContext *C, uiBut *but)
after->butm_func_arg = block->butm_func_arg;
after->a2 = but->a2;
}
if (block->handle)
after->popup_op = block->handle->popup_op;
after->optype = but->optype;
after->opcontext = but->opcontext;
@ -767,6 +783,9 @@ static void ui_apply_but_funcs_after(bContext *C)
if (after.context)
CTX_store_set(C, after.context);
if (after.popup_op)
popup_check(C, after.popup_op);
if (after.opptr) {
/* free in advance to avoid leak on exit */
opptr = *after.opptr;
@ -6660,7 +6679,7 @@ static void remove_shortcut_func(bContext *C, void *arg1, void *UNUSED(arg2))
static void popup_add_shortcut_func(bContext *C, void *arg1, void *UNUSED(arg2))
{
uiBut *but = (uiBut *)arg1;
UI_popup_block_ex(C, menu_add_shortcut, NULL, menu_add_shortcut_cancel, but);
UI_popup_block_ex(C, menu_add_shortcut, NULL, menu_add_shortcut_cancel, but, NULL);
}
/**
@ -10177,6 +10196,25 @@ void UI_popup_handlers_add(bContext *C, ListBase *handlers, uiPopupBlockHandle *
void UI_popup_handlers_remove(ListBase *handlers, uiPopupBlockHandle *popup)
{
wmEventHandler *handler;
for (handler = handlers->first; handler; handler = handler->next) {
if (handler->ui_handle == ui_popup_handler &&
handler->ui_remove == ui_popup_handler_remove &&
handler->ui_userdata == popup)
{
/* tag refresh parent popup */
if (handler->next &&
handler->next->ui_handle == ui_popup_handler &&
handler->next->ui_remove == ui_popup_handler_remove)
{
uiPopupBlockHandle *parent_popup = handler->next->ui_userdata;
ED_region_tag_refresh_ui(parent_popup->region);
}
break;
}
}
WM_event_remove_ui_handler(handlers, ui_popup_handler, ui_popup_handler_remove, popup, false);
}

View File

@ -557,6 +557,7 @@ struct uiPopupBlockHandle {
struct uiKeyNavLock keynav_state;
/* for operator popups */
struct wmOperator *popup_op;
struct wmOperatorType *optype;
ScrArea *ctx_area;
ARegion *ctx_region;

View File

@ -3317,7 +3317,7 @@ void UI_popup_block_invoke(bContext *C, uiBlockCreateFunc func, void *arg)
UI_popup_block_invoke_ex(C, func, arg, NULL, WM_OP_INVOKE_DEFAULT);
}
void UI_popup_block_ex(bContext *C, uiBlockCreateFunc func, uiBlockHandleFunc popup_func, uiBlockCancelFunc cancel_func, void *arg)
void UI_popup_block_ex(bContext *C, uiBlockCreateFunc func, uiBlockHandleFunc popup_func, uiBlockCancelFunc cancel_func, void *arg, wmOperator *op)
{
wmWindow *window = CTX_wm_window(C);
uiPopupBlockHandle *handle;
@ -3326,6 +3326,7 @@ void UI_popup_block_ex(bContext *C, uiBlockCreateFunc func, uiBlockHandleFunc po
handle->popup = true;
handle->retvalue = 1;
handle->popup_op = op;
handle->popup_arg = arg;
handle->popup_func = popup_func;
handle->cancel_func = cancel_func;

View File

@ -127,12 +127,10 @@ uiBut *uiDefAutoButR(uiBlock *block, PointerRNA *ptr, PropertyRNA *prop, int ind
break;
case PROP_POINTER:
{
PointerRNA pptr;
pptr = RNA_property_pointer_get(ptr, prop);
if (!pptr.type)
pptr.type = RNA_property_pointer_type(ptr, prop);
icon = RNA_struct_ui_icon(pptr.type);
if (icon == 0) {
PointerRNA pptr = RNA_property_pointer_get(ptr, prop);
icon = RNA_struct_ui_icon(pptr.type ? pptr.type : RNA_property_pointer_type(ptr, prop));
}
if (icon == ICON_DOT)
icon = 0;

View File

@ -1400,6 +1400,8 @@ static bool view3d_localview_init(
}
}
DAG_on_visible_update(bmain, false);
return ok;
}

View File

@ -277,6 +277,7 @@ typedef struct MirrorModifierData {
short axis DNA_DEPRECATED; /* deprecated, use flag instead */
short flag;
float tolerance;
float uv_offset[2];
struct Object *mirror_ob;
} MirrorModifierData;

View File

@ -1526,6 +1526,20 @@ static void rna_def_modifier_mirror(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Mirror V", "Mirror the V texture coordinate around the 0.5 point");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
prop = RNA_def_property(srna, "mirror_offset_u", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_float_sdna(prop, NULL, "uv_offset[0]");
RNA_def_property_range(prop, -1, 1);
RNA_def_property_ui_range(prop, -1, 1, 2, 4);
RNA_def_property_ui_text(prop, "U Offset", "Amount to offset mirrored UVs from the 0.5 point on the U axis");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
prop = RNA_def_property(srna, "mirror_offset_v", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_float_sdna(prop, NULL, "uv_offset[1]");
RNA_def_property_range(prop, -1, 1);
RNA_def_property_ui_range(prop, -1, 1, 2, 4);
RNA_def_property_ui_text(prop, "V Offset", "Amount to offset mirrored UVs from the 0.5 point on the V axis");
RNA_def_property_update(prop, 0, "rna_Modifier_update");
prop = RNA_def_property(srna, "merge_threshold", PROP_FLOAT, PROP_DISTANCE);
RNA_def_property_float_sdna(prop, NULL, "tolerance");
RNA_def_property_range(prop, 0, FLT_MAX);

View File

@ -259,8 +259,8 @@ static DerivedMesh *doMirrorOnAxis(MirrorModifierData *mmd,
int j = maxLoops;
dmloopuv += j; /* second set of loops only */
for (; j-- > 0; dmloopuv++) {
if (do_mirr_u) dmloopuv->uv[0] = 1.0f - dmloopuv->uv[0];
if (do_mirr_v) dmloopuv->uv[1] = 1.0f - dmloopuv->uv[1];
if (do_mirr_u) dmloopuv->uv[0] = 1.0f - dmloopuv->uv[0] + mmd->uv_offset[0];
if (do_mirr_v) dmloopuv->uv[1] = 1.0f - dmloopuv->uv[1] + mmd->uv_offset[1];
}
}
}

View File

@ -1562,6 +1562,11 @@ static int wm_homefile_read_exec(bContext *C, wmOperator *op)
RNA_property_string_get(op->ptr, prop_app_template, app_template_buf);
app_template = app_template_buf;
}
else if (!use_factory_settings) {
/* TODO: dont reset prefs on 'New File' */
BLI_strncpy(app_template_buf, U.app_template, sizeof(app_template_buf));
app_template = app_template_buf;
}
else {
app_template = NULL;
}

View File

@ -1432,20 +1432,6 @@ static void dialog_exec_cb(bContext *C, void *arg1, void *arg2)
}
}
static void popup_check_cb(bContext *C, void *op_ptr, void *UNUSED(arg))
{
wmOperator *op = op_ptr;
if (op->type->check) {
if (op->type->check(C, op)) {
/* check for popup and re-layout buttons */
ARegion *ar_menu = CTX_wm_menu(C);
if (ar_menu) {
ED_region_tag_refresh_ui(ar_menu);
}
}
}
}
/* Dialogs are popups that require user verification (click OK) before exec */
static uiBlock *wm_block_dialog_create(bContext *C, ARegion *ar, void *userData)
{
@ -1464,8 +1450,6 @@ static uiBlock *wm_block_dialog_create(bContext *C, ARegion *ar, void *userData)
layout = UI_block_layout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 0, 0, data->width, data->height, 0, style);
UI_block_func_set(block, popup_check_cb, op, NULL);
uiLayoutOperatorButs(C, layout, op, NULL, 'H', UI_LAYOUT_OP_SHOW_TITLE);
/* clear so the OK button is left alone */
@ -1504,8 +1488,6 @@ static uiBlock *wm_operator_ui_create(bContext *C, ARegion *ar, void *userData)
layout = UI_block_layout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 0, 0, data->width, data->height, 0, style);
UI_block_func_set(block, popup_check_cb, op, NULL);
/* since ui is defined the auto-layout args are not used */
uiLayoutOperatorButs(C, layout, op, NULL, 'V', 0);
@ -1552,7 +1534,7 @@ int WM_operator_ui_popup(bContext *C, wmOperator *op, int width, int height)
data->width = width;
data->height = height;
data->free_op = true; /* if this runs and gets registered we may want not to free it */
UI_popup_block_ex(C, wm_operator_ui_create, NULL, wm_operator_ui_popup_cancel, data);
UI_popup_block_ex(C, wm_operator_ui_create, NULL, wm_operator_ui_popup_cancel, data, op);
return OPERATOR_RUNNING_MODAL;
}
@ -1582,7 +1564,7 @@ static int wm_operator_props_popup_ex(bContext *C, wmOperator *op,
if (!do_redo || !(U.uiflag & USER_GLOBALUNDO))
return WM_operator_props_dialog_popup(C, op, 15 * UI_UNIT_X, UI_UNIT_Y);
UI_popup_block_ex(C, wm_block_create_redo, NULL, wm_block_redo_cancel_cb, op);
UI_popup_block_ex(C, wm_block_create_redo, NULL, wm_block_redo_cancel_cb, op, op);
if (do_call)
wm_block_redo_cb(C, op, 0);
@ -1624,7 +1606,7 @@ int WM_operator_props_dialog_popup(bContext *C, wmOperator *op, int width, int h
data->free_op = true; /* if this runs and gets registered we may want not to free it */
/* op is not executed until popup OK but is clicked */
UI_popup_block_ex(C, wm_block_dialog_create, wm_operator_ui_popup_ok, wm_operator_ui_popup_cancel, data);
UI_popup_block_ex(C, wm_block_dialog_create, wm_operator_ui_popup_ok, wm_operator_ui_popup_cancel, data, op);
return OPERATOR_RUNNING_MODAL;
}