Merge branch 'master' into sculpt-dev

This commit is contained in:
Pablo Dobarro 2021-04-06 17:49:13 +02:00
commit 347c8255ed
17 changed files with 182 additions and 104 deletions

View File

@ -1,2 +1,2 @@
Sphinx==3.5.1
sphinx_rtd_theme==0.5.1
Sphinx==3.5.3
sphinx_rtd_theme==0.5.2

View File

@ -219,9 +219,12 @@ def do_versions(self):
if version <= (2, 93, 16):
cscene = scene.cycles
if scene.render.use_simplify and \
(cscene.ao_bounces or cscene.ao_bounces_render):
ao_bounces = cscene.get("ao_bounces", 0)
ao_bounces_render = cscene.get("ao_bounces_render", 0)
if scene.render.use_simplify and (ao_bounces or ao_bounces_render):
cscene.use_fast_gi = True
cscene.ao_bounces = ao_bounces
cscene.ao_bounces_render = ao_bounces_render
else:
cscene.ao_bounces = 1
cscene.ao_bounces_render = 1

View File

@ -222,7 +222,7 @@ void BKE_gpencil_blend_read_data(BlendDataReader *reader, bGPdata *gpd)
/* relink palettes (old palettes deprecated, only to convert old files) */
BLO_read_list(reader, &gpd->palettes);
if (gpd->palettes.first != NULL) {
LISTBASE_FOREACH (Palette *, palette, &gpd->palettes) {
LISTBASE_FOREACH (bGPDpalette *, palette, &gpd->palettes) {
BLO_read_list(reader, &palette->colors);
}
}

View File

@ -72,38 +72,46 @@ class ResourceScope : NonCopyable, NonMovable {
* Pass ownership of the resource to the ResourceScope. It will be destructed and freed when
* the collector is destructed.
*/
template<typename T> void add(std::unique_ptr<T> resource, const char *name)
template<typename T> T *add(std::unique_ptr<T> resource, const char *name)
{
BLI_assert(resource.get() != nullptr);
T *ptr = resource.release();
if (ptr == nullptr) {
return nullptr;
}
this->add(
resource.release(),
ptr,
[](void *data) {
T *typed_data = reinterpret_cast<T *>(data);
delete typed_data;
},
name);
return ptr;
}
/**
* Pass ownership of the resource to the ResourceScope. It will be destructed when the
* collector is destructed.
*/
template<typename T> void add(destruct_ptr<T> resource, const char *name)
template<typename T> T *add(destruct_ptr<T> resource, const char *name)
{
T *ptr = resource.release();
if (ptr == nullptr) {
return nullptr;
}
/* There is no need to keep track of such types. */
if (std::is_trivially_destructible_v<T>) {
resource.release();
return;
return ptr;
}
BLI_assert(resource.get() != nullptr);
this->add(
resource.release(),
ptr,
[](void *data) {
T *typed_data = reinterpret_cast<T *>(data);
typed_data->~T();
},
name);
return ptr;
}
/**

View File

@ -337,10 +337,10 @@ bool _bli_array_iter_spiral_square(const void *arr_v,
center[1] < arr_shape[1]);
const char *arr = arr_v;
const int stride[2] = {arr_shape[1] * (int)elem_size, (int)elem_size};
const int stride[2] = {arr_shape[0] * (int)elem_size, (int)elem_size};
/* Test center first. */
int ofs[2] = {center[0] * stride[0], center[1] * stride[1]};
int ofs[2] = {center[0] * stride[1], center[1] * stride[0]};
if (test_fn(arr + ofs[0] + ofs[1], user_data)) {
return true;
}

View File

@ -259,17 +259,18 @@ std::ostream &operator<<(std::ostream &os, const NodeOperation &node_operation)
{
NodeOperationFlags flags = node_operation.get_flags();
os << "NodeOperation(";
os << "id=" << node_operation.get_id();
if (!node_operation.get_name().empty()) {
os << "name=" << node_operation.get_name() << ",";
os << ",name=" << node_operation.get_name();
}
os << "flags={" << flags << "},";
os << ",flags={" << flags << "}";
if (flags.is_read_buffer_operation) {
const ReadBufferOperation *read_operation = (const ReadBufferOperation *)&node_operation;
const MemoryProxy *proxy = read_operation->getMemoryProxy();
if (proxy) {
const WriteBufferOperation *write_operation = proxy->getWriteBufferOperation();
if (write_operation) {
os << "write=" << (NodeOperation &)*write_operation << ",";
os << ",write=" << (NodeOperation &)*write_operation;
}
}
}

View File

@ -251,6 +251,7 @@ struct NodeOperationFlags {
*/
class NodeOperation {
private:
int m_id;
std::string m_name;
Vector<NodeOperationInput> m_inputs;
Vector<NodeOperationOutput> m_outputs;
@ -307,6 +308,16 @@ class NodeOperation {
return m_name;
}
void set_id(const int id)
{
m_id = id;
}
const int get_id() const
{
return m_id;
}
const NodeOperationFlags get_flags() const
{
return flags;

View File

@ -124,6 +124,7 @@ void NodeOperationBuilder::convertToOperations(ExecutionSystem *system)
void NodeOperationBuilder::addOperation(NodeOperation *operation)
{
operation->set_id(m_operations.size());
m_operations.append(operation);
if (m_current_node) {
operation->set_name(m_current_node->getbNode()->name);
@ -691,4 +692,41 @@ void NodeOperationBuilder::group_operations()
}
}
/** Create a graphviz representation of the NodeOperationBuilder. */
std::ostream &operator<<(std::ostream &os, const NodeOperationBuilder &builder)
{
os << "# Builder start\n";
os << "digraph G {\n";
os << " rankdir=LR;\n";
os << " node [shape=box];\n";
for (const NodeOperation *operation : builder.get_operations()) {
os << " op" << operation->get_id() << " [label=\"" << *operation << "\"];\n";
}
os << "\n";
for (const NodeOperationBuilder::Link &link : builder.get_links()) {
os << " op" << link.from()->getOperation().get_id() << " -> op"
<< link.to()->getOperation().get_id() << ";\n";
}
for (const NodeOperation *operation : builder.get_operations()) {
if (operation->get_flags().is_read_buffer_operation) {
const ReadBufferOperation &read_operation = static_cast<const ReadBufferOperation &>(
*operation);
const WriteBufferOperation &write_operation =
*read_operation.getMemoryProxy()->getWriteBufferOperation();
os << " op" << write_operation.get_id() << " -> op" << read_operation.get_id() << ";\n";
}
}
os << "}\n";
os << "# Builder end\n";
return os;
}
std::ostream &operator<<(std::ostream &os, const NodeOperationBuilder::Link &link)
{
os << link.from()->getOperation().get_id() << " -> " << link.to()->getOperation().get_id();
return os;
}
} // namespace blender::compositor

View File

@ -119,6 +119,16 @@ class NodeOperationBuilder {
return m_active_viewer;
}
const Vector<NodeOperation *> &get_operations() const
{
return m_operations;
}
const Vector<Link> &get_links() const
{
return m_links;
}
protected:
/** Add datatype conversion where needed */
void add_datatype_conversions();
@ -160,4 +170,7 @@ class NodeOperationBuilder {
#endif
};
std::ostream &operator<<(std::ostream &os, const NodeOperationBuilder &builder);
std::ostream &operator<<(std::ostream &os, const NodeOperationBuilder::Link &link);
} // namespace blender::compositor

View File

@ -55,6 +55,6 @@ struct WorkPackage {
#endif
};
std::ostream &operator<<(std::ostream &os, const WorkPackage &WorkPackage);
std::ostream &operator<<(std::ostream &os, const WorkPackage &work_package);
} // namespace blender::compositor

View File

@ -828,19 +828,18 @@ void DEG_editors_update(
Main *bmain, Depsgraph *depsgraph, Scene *scene, ViewLayer *view_layer, bool time)
{
deg::Depsgraph *graph = (deg::Depsgraph *)depsgraph;
if (!graph->use_editors_update) {
return;
if (graph->use_editors_update) {
bool updated = time || DEG_id_type_any_updated(depsgraph);
DEGEditorUpdateContext update_ctx = {nullptr};
update_ctx.bmain = bmain;
update_ctx.depsgraph = depsgraph;
update_ctx.scene = scene;
update_ctx.view_layer = view_layer;
deg::deg_editors_scene_update(&update_ctx, updated);
}
bool updated = time || DEG_id_type_any_updated(depsgraph);
DEGEditorUpdateContext update_ctx = {nullptr};
update_ctx.bmain = bmain;
update_ctx.depsgraph = depsgraph;
update_ctx.scene = scene;
update_ctx.view_layer = view_layer;
deg::deg_editors_scene_update(&update_ctx, updated);
DEG_ids_clear_recalc(depsgraph);
}

View File

@ -1990,7 +1990,7 @@ static int edcu_shortest_path_pick_invoke(bContext *C, wmOperator *op, const wmE
ED_object_base_activate(C, basact);
}
DEG_id_tag_update(obedit->data, ID_RECALC_SELECT);
DEG_id_tag_update(obedit->data, ID_RECALC_SELECT | ID_RECALC_COPY_ON_WRITE);
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data);
return OPERATOR_FINISHED;
}

View File

@ -4632,35 +4632,56 @@ static int edbm_select_random_exec(bContext *C, wmOperator *op)
seed_iter += BLI_ghashutil_strhash_p(obedit->id.name);
}
RNG *rng = BLI_rng_new_srandom(seed_iter);
if (em->selectmode & SCE_SELECT_VERTEX) {
int elem_map_len = 0;
BMVert **elem_map = MEM_mallocN(sizeof(*elem_map) * em->bm->totvert, __func__);
BMVert *eve;
BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) {
if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN) && BLI_rng_get_float(rng) < randfac) {
BM_vert_select_set(em->bm, eve, select);
if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) {
elem_map[elem_map_len++] = eve;
}
}
BLI_array_randomize(elem_map, sizeof(*elem_map), elem_map_len, seed);
const int count_select = elem_map_len * randfac;
for (int i = 0; i < count_select; i++) {
BM_vert_select_set(em->bm, elem_map[i], select);
}
MEM_freeN(elem_map);
}
else if (em->selectmode & SCE_SELECT_EDGE) {
int elem_map_len = 0;
BMEdge **elem_map = MEM_mallocN(sizeof(*elem_map) * em->bm->totedge, __func__);
BMEdge *eed;
BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) {
if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN) && BLI_rng_get_float(rng) < randfac) {
BM_edge_select_set(em->bm, eed, select);
if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) {
elem_map[elem_map_len++] = eed;
}
}
BLI_array_randomize(elem_map, sizeof(*elem_map), elem_map_len, seed);
const int count_select = elem_map_len * randfac;
for (int i = 0; i < count_select; i++) {
BM_edge_select_set(em->bm, elem_map[i], select);
}
MEM_freeN(elem_map);
}
else {
int elem_map_len = 0;
BMFace **elem_map = MEM_mallocN(sizeof(*elem_map) * em->bm->totface, __func__);
BMFace *efa;
BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN) && BLI_rng_get_float(rng) < randfac) {
BM_face_select_set(em->bm, efa, select);
if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) {
elem_map[elem_map_len++] = efa;
}
}
BLI_array_randomize(elem_map, sizeof(*elem_map), elem_map_len, seed);
const int count_select = elem_map_len * randfac;
for (int i = 0; i < count_select; i++) {
BM_face_select_set(em->bm, elem_map[i], select);
}
MEM_freeN(elem_map);
}
BLI_rng_free(rng);
if (select) {
/* was EDBM_select_flush, but it over select in edge/face mode */
EDBM_selectmode_flush(em);

View File

@ -186,58 +186,25 @@ struct InputAngle_Data {
static void InputAngle(TransInfo *UNUSED(t), MouseInput *mi, const double mval[2], float output[3])
{
struct InputAngle_Data *data = mi->data;
double dx2 = mval[0] - (double)mi->center[0];
double dy2 = mval[1] - (double)mi->center[1];
double B = sqrt(dx2 * dx2 + dy2 * dy2);
float dir_prev[2], dir_curr[2], mi_center[2];
copy_v2_v2(mi_center, mi->center);
double dx1 = data->mval_prev[0] - (double)mi->center[0];
double dy1 = data->mval_prev[1] - (double)mi->center[1];
double A = sqrt(dx1 * dx1 + dy1 * dy1);
sub_v2_v2v2(dir_prev, (const float[2]){UNPACK2(data->mval_prev)}, mi_center);
sub_v2_v2v2(dir_curr, (const float[2]){UNPACK2(mval)}, mi_center);
double dx3 = mval[0] - data->mval_prev[0];
double dy3 = mval[1] - data->mval_prev[1];
if (normalize_v2(dir_prev) && normalize_v2(dir_curr)) {
float dphi = angle_normalized_v2v2(dir_prev, dir_curr);
/* use doubles here, to make sure a "1.0" (no rotation)
* doesn't become 9.999999e-01, which gives 0.02 for acos */
double deler = (((dx1 * dx1 + dy1 * dy1) + (dx2 * dx2 + dy2 * dy2) - (dx3 * dx3 + dy3 * dy3)) /
(2.0 * (((A * B) != 0.0) ? (A * B) : 1.0)));
/* ((A * B) ? (A * B) : 1.0) this takes care of potential divide by zero errors */
float dphi;
dphi = saacos((float)deler);
if ((dx1 * dy2 - dx2 * dy1) > 0.0) {
dphi = -dphi;
}
/* If the angle is zero, because of lack of precision close to the 1.0 value in acos
* approximate the angle with the opposite side of the normalized triangle
* This is a good approximation here since the smallest acos value seems to be around
* 0.02 degree and lower values don't even have a 0.01% error compared to the approximation
*/
if (dphi == 0) {
double dx, dy;
dx2 /= A;
dy2 /= A;
dx1 /= B;
dy1 /= B;
dx = dx1 - dx2;
dy = dy1 - dy2;
dphi = sqrt(dx * dx + dy * dy);
if ((dx1 * dy2 - dx2 * dy1) > 0.0) {
if (cross_v2v2(dir_prev, dir_curr) > 0.0f) {
dphi = -dphi;
}
data->angle += ((double)dphi) * (mi->precision ? (double)mi->precision_factor : 1.0);
data->mval_prev[0] = mval[0];
data->mval_prev[1] = mval[1];
}
data->angle += ((double)dphi) * (mi->precision ? (double)mi->precision_factor : 1.0);
data->mval_prev[0] = mval[0];
data->mval_prev[1] = mval[1];
output[0] = data->angle;
}

View File

@ -648,6 +648,13 @@ static void rna_FieldSettings_update(Main *UNUSED(bmain), Scene *UNUSED(scene),
ob->pd->tex = NULL;
}
/* In the case of specific forcefields that are using the EffectorData's normal, we need to
* rebuild mesh and bhvtree for SurfaceModifier to work correctly. */
if (ELEM(ob->pd->shape, PFIELD_SHAPE_SURFACE, PFIELD_SHAPE_POINTS) ||
ob->pd->forcefield == PFIELD_GUIDE) {
DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY);
}
DEG_id_tag_update(&ob->id, ID_RECALC_TRANSFORM);
WM_main_add_notifier(NC_OBJECT | ND_DRAW, ob);
}

View File

@ -112,18 +112,6 @@ static bool rna_Screen_fullscreen_get(PointerRNA *ptr)
return (screen->state == SCREENMAXIMIZED);
}
/* UI compatible list: should not be needed, but for now we need to keep EMPTY
* at least in the static version of this enum for python scripts. */
static const EnumPropertyItem *rna_Area_type_itemf(bContext *UNUSED(C),
PointerRNA *UNUSED(ptr),
PropertyRNA *UNUSED(prop),
bool *r_free)
{
/* +1 to skip SPACE_EMPTY */
*r_free = false;
return rna_enum_space_type_items + 1;
}
static int rna_Area_type_get(PointerRNA *ptr)
{
ScrArea *area = (ScrArea *)ptr->data;
@ -142,6 +130,11 @@ static void rna_Area_type_set(PointerRNA *ptr, int value)
}
ScrArea *area = (ScrArea *)ptr->data;
/* Empty areas are locked. */
if ((value == SPACE_EMPTY) || (area->spacetype == SPACE_EMPTY)) {
return;
}
area->butspacetype = value;
}
@ -188,16 +181,20 @@ static void rna_Area_type_update(bContext *C, PointerRNA *ptr)
}
static const EnumPropertyItem *rna_Area_ui_type_itemf(bContext *C,
PointerRNA *UNUSED(ptr),
PointerRNA *ptr,
PropertyRNA *UNUSED(prop),
bool *r_free)
{
EnumPropertyItem *item = NULL;
int totitem = 0;
/* +1 to skip SPACE_EMPTY */
for (const EnumPropertyItem *item_from = rna_enum_space_type_items + 1; item_from->identifier;
item_from++) {
ScrArea *area = (ScrArea *)ptr->data;
const EnumPropertyItem *item_from = rna_enum_space_type_items;
if (area->spacetype != SPACE_EMPTY) {
item_from += 1; /* +1 to skip SPACE_EMPTY */
}
for (; item_from->identifier; item_from++) {
if (ELEM(item_from->value, SPACE_TOPBAR, SPACE_STATUSBAR)) {
continue;
}
@ -224,6 +221,10 @@ static const EnumPropertyItem *rna_Area_ui_type_itemf(bContext *C,
static int rna_Area_ui_type_get(PointerRNA *ptr)
{
ScrArea *area = ptr->data;
/* This is for the Python API which may inspect empty areas. */
if (UNLIKELY(area->spacetype == SPACE_EMPTY)) {
return SPACE_EMPTY;
}
const int area_type = rna_Area_type_get(ptr);
const bool area_changing = area->butspacetype != SPACE_EMPTY;
int value = area_type << 16;
@ -252,6 +253,10 @@ static void rna_Area_ui_type_set(PointerRNA *ptr, int value)
{
ScrArea *area = ptr->data;
const int space_type = value >> 16;
/* Empty areas are locked. */
if ((space_type == SPACE_EMPTY) || (area->spacetype == SPACE_EMPTY)) {
return;
}
SpaceType *st = BKE_spacetype_from_id(space_type);
rna_Area_type_set(ptr, space_type);
@ -380,12 +385,17 @@ static void rna_def_area(BlenderRNA *brna)
RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", HEADER_NO_PULLDOWN);
RNA_def_property_ui_text(prop, "Show Menus", "Show menus in the header");
/* Note on space type use of #SPACE_EMPTY, this is not visible to the user,
* and script authors should be able to assign this value, however the value may be set
* and needs to be read back by script authors.
*
* This happens when an area is full-screen (when #ScrArea.full is set).
* in this case reading the empty value is needed, but it should never be set, see: T87187. */
prop = RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "spacetype");
RNA_def_property_enum_items(prop, rna_enum_space_type_items);
RNA_def_property_enum_default(prop, SPACE_VIEW3D);
RNA_def_property_enum_funcs(
prop, "rna_Area_type_get", "rna_Area_type_set", "rna_Area_type_itemf");
RNA_def_property_enum_funcs(prop, "rna_Area_type_get", "rna_Area_type_set", NULL);
RNA_def_property_ui_text(prop, "Editor Type", "Current editor type for this area");
RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);

View File

@ -4080,7 +4080,7 @@ static void rna_def_space_view3d_overlay(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "overlay.flag", V3D_OVERLAY_LOOK_DEV);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_ui_text(prop, "HDRI Preview", "Show HDRI preview spheres");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D | NS_VIEW3D_SHADING, NULL);
prop = RNA_def_property(srna, "show_wireframes", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "overlay.flag", V3D_OVERLAY_WIREFRAMES);