WIP: Brush assets project #106303

Draft
Julian Eisel wants to merge 351 commits from brush-assets-project into main

When changing the target branch, be careful to rebase the branch in your fork to match. See documentation.
10 changed files with 119 additions and 123 deletions
Showing only changes of commit 4e781aeda3 - Show all commits

View File

@ -445,8 +445,9 @@ static bool restore_coords(
MutableSpan<float3> positions = ss->vert_positions;
if (ss->shapekey_active) {
MutableSpan<float3> vertCos(static_cast<float3 *>(ss->shapekey_active->data),
ss->shapekey_active->totelem);
float(*vertCos)[3] = BKE_keyblock_convert_to_vertcos(ob, ss->shapekey_active);
const Span key_positions(reinterpret_cast<const float3 *>(vertCos),
ss->shapekey_active->totelem);
if (!unode.orig_position.is_empty()) {
if (ss->deform_modifiers_active) {
@ -467,11 +468,13 @@ static bool restore_coords(
}
/* Propagate new coords to keyblock. */
SCULPT_vertcos_to_key(ob, ss->shapekey_active, vertCos);
SCULPT_vertcos_to_key(ob, ss->shapekey_active, key_positions);
/* PBVH uses its own vertex array, so coords should be */
/* propagated to PBVH here. */
BKE_pbvh_vert_coords_apply(ss->pbvh, vertCos);
BKE_pbvh_vert_coords_apply(ss->pbvh, key_positions);
MEM_freeN(vertCos);
}
else {
if (!unode.orig_position.is_empty()) {

View File

@ -16,6 +16,7 @@
#include "BLI_color.hh"
#include "BLI_enumerable_thread_specific.hh"
#include "BLI_math_matrix.hh"
#include "BLI_path_util.h"
#include "BLI_task.hh"
@ -234,8 +235,8 @@ void obj_parallel_chunked_output(FormatHandler &fh, int tot_count, const Functio
return;
}
/* Give each chunk its own temporary output buffer, and process them in parallel. */
std::vector<FormatHandler> buffers(chunk_count);
blender::threading::parallel_for(IndexRange(chunk_count), 1, [&](IndexRange range) {
Array<FormatHandler> buffers(chunk_count);
threading::parallel_for(IndexRange(chunk_count), 1, [&](IndexRange range) {
for (const int r : range) {
int i_start = r * chunk_size;
int i_end = std::min(i_start + chunk_size, tot_count);
@ -259,6 +260,10 @@ void OBJWriter::write_vertex_coords(FormatHandler &fh,
const Mesh *mesh = obj_mesh_data.get_mesh();
const StringRef name = mesh->active_color_attribute;
const float4x4 transform = obj_mesh_data.get_world_axes_transform();
const Span<float3> positions = obj_mesh_data.get_mesh()->vert_positions();
if (write_colors && !name.is_empty()) {
const bke::AttributeAccessor attributes = mesh->attributes();
const VArray<ColorGeometry4f> attribute = *attributes.lookup_or_default<ColorGeometry4f>(
@ -266,7 +271,7 @@ void OBJWriter::write_vertex_coords(FormatHandler &fh,
BLI_assert(tot_count == attribute.size());
obj_parallel_chunked_output(fh, tot_count, [&](FormatHandler &buf, int i) {
float3 vertex = obj_mesh_data.calc_vertex_coords(i, export_params_.global_scale);
const float3 vertex = math::transform_point(transform, positions[i]);
ColorGeometry4f linear = attribute.get(i);
float srgb[3];
linearrgb_to_srgb_v3_v3(srgb, linear);
@ -275,7 +280,7 @@ void OBJWriter::write_vertex_coords(FormatHandler &fh,
}
else {
obj_parallel_chunked_output(fh, tot_count, [&](FormatHandler &buf, int i) {
float3 vertex = obj_mesh_data.calc_vertex_coords(i, export_params_.global_scale);
const float3 vertex = math::transform_point(transform, positions[i]);
buf.write_obj_vertex(vertex[0], vertex[1], vertex[2]);
});
}
@ -283,9 +288,8 @@ void OBJWriter::write_vertex_coords(FormatHandler &fh,
void OBJWriter::write_uv_coords(FormatHandler &fh, OBJMesh &r_obj_mesh_data) const
{
const Vector<float2> &uv_coords = r_obj_mesh_data.get_uv_coords();
const int tot_count = uv_coords.size();
obj_parallel_chunked_output(fh, tot_count, [&](FormatHandler &buf, int i) {
const Span<float2> uv_coords = r_obj_mesh_data.get_uv_coords();
obj_parallel_chunked_output(fh, uv_coords.size(), [&](FormatHandler &buf, int i) {
const float2 &uv_vertex = uv_coords[i];
buf.write_obj_uv(uv_vertex[0], uv_vertex[1]);
});
@ -294,9 +298,8 @@ void OBJWriter::write_uv_coords(FormatHandler &fh, OBJMesh &r_obj_mesh_data) con
void OBJWriter::write_poly_normals(FormatHandler &fh, OBJMesh &obj_mesh_data)
{
/* Poly normals should be calculated earlier via store_normal_coords_and_indices. */
const Vector<float3> &normal_coords = obj_mesh_data.get_normal_coords();
const int tot_count = normal_coords.size();
obj_parallel_chunked_output(fh, tot_count, [&](FormatHandler &buf, int i) {
const Span<float3> normal_coords = obj_mesh_data.get_normal_coords();
obj_parallel_chunked_output(fh, normal_coords.size(), [&](FormatHandler &buf, int i) {
const float3 &normal = normal_coords[i];
buf.write_obj_normal(normal[0], normal[1], normal[2]);
});

View File

@ -14,12 +14,12 @@
#include "BKE_mesh.hh"
#include "BKE_mesh_mapping.hh"
#include "BKE_object.hh"
#include "BLI_math_matrix.h"
#include "BLI_math_rotation.h"
#include "BLI_math_vector.h"
#include "BLI_listbase.h"
#include "BLI_map.hh"
#include "BLI_math_matrix.h"
#include "BLI_math_matrix.hh"
#include "BLI_math_rotation.h"
#include "BLI_sort.hh"
#include "DEG_depsgraph_query.hh"
@ -70,7 +70,8 @@ OBJMesh::OBJMesh(Depsgraph *depsgraph, const OBJExportParams &export_params, Obj
this->materials[i] = BKE_object_material_get_eval(obj_eval, i + 1);
}
set_world_axes_transform(*obj_eval, export_params.forward_axis, export_params.up_axis);
set_world_axes_transform(
*obj_eval, export_params.forward_axis, export_params.up_axis, export_params.global_scale);
}
/**
@ -103,11 +104,11 @@ void OBJMesh::clear()
owned_export_mesh_ = nullptr;
}
export_mesh_ = nullptr;
loop_to_uv_index_.clear_and_shrink();
loop_to_uv_index_ = {};
uv_coords_.clear_and_shrink();
loop_to_normal_index_.clear_and_shrink();
loop_to_normal_index_ = {};
normal_coords_.clear_and_shrink();
poly_order_.clear_and_shrink();
poly_order_ = {};
if (poly_smooth_groups_) {
MEM_freeN(poly_smooth_groups_);
poly_smooth_groups_ = nullptr;
@ -146,23 +147,27 @@ void OBJMesh::triangulate_mesh_eval()
void OBJMesh::set_world_axes_transform(const Object &obj_eval,
const eIOAxis forward,
const eIOAxis up)
const eIOAxis up,
const float global_scale)
{
float axes_transform[3][3];
unit_m3(axes_transform);
float3x3 axes_transform;
/* +Y-forward and +Z-up are the default Blender axis settings. */
mat3_from_axis_conversion(forward, up, IO_AXIS_Y, IO_AXIS_Z, axes_transform);
mul_m4_m3m4(world_and_axes_transform_, axes_transform, obj_eval.object_to_world);
/* mul_m4_m3m4 does not transform last row of obmat, i.e. location data. */
mul_v3_m3v3(world_and_axes_transform_[3], axes_transform, obj_eval.object_to_world[3]);
world_and_axes_transform_[3][3] = obj_eval.object_to_world[3][3];
mat3_from_axis_conversion(forward, up, IO_AXIS_Y, IO_AXIS_Z, axes_transform.ptr());
const float4x4 object_to_world(obj_eval.object_to_world);
const float3x3 transform = axes_transform * float3x3(object_to_world);
world_and_axes_transform_ = float4x4(transform);
world_and_axes_transform_.location() = axes_transform * object_to_world.location();
world_and_axes_transform_[3][3] = object_to_world[3][3];
world_and_axes_transform_ = math::from_scale<float4x4>(float3(global_scale)) *
world_and_axes_transform_;
/* Normals need inverse transpose of the regular matrix to handle non-uniform scale. */
float normal_matrix[3][3];
copy_m3_m4(normal_matrix, world_and_axes_transform_);
invert_m3_m3(world_and_axes_normal_transform_, normal_matrix);
transpose_m3(world_and_axes_normal_transform_);
mirrored_transform_ = is_negative_m3(world_and_axes_normal_transform_);
world_and_axes_normal_transform_ = math::transpose(math::invert(transform));
mirrored_transform_ = math::is_negative(world_and_axes_normal_transform_);
}
int OBJMesh::tot_vertices() const
@ -227,7 +232,7 @@ void OBJMesh::calc_poly_order()
}
const VArraySpan<int> material_indices_span(material_indices);
poly_order_.resize(material_indices_span.size());
poly_order_.reinitialize(material_indices_span.size());
for (const int i : material_indices_span.index_range()) {
poly_order_[i] = i;
}
@ -258,14 +263,6 @@ const char *OBJMesh::get_object_mesh_name() const
return export_mesh_->id.name + 2;
}
float3 OBJMesh::calc_vertex_coords(const int vert_index, const float global_scale) const
{
float3 r_coords = mesh_positions_[vert_index];
mul_m4_v3(world_and_axes_transform_, r_coords);
mul_v3_fl(r_coords, global_scale);
return r_coords;
}
Span<int> OBJMesh::calc_poly_vertex_indices(const int face_index) const
{
return mesh_corner_verts_.slice(mesh_faces_[face_index]);
@ -292,7 +289,7 @@ void OBJMesh::store_uv_coords_and_indices()
uv_to_index.reserve(export_mesh_->verts_num);
uv_coords_.reserve(export_mesh_->verts_num);
loop_to_uv_index_.resize(uv_map.size());
loop_to_uv_index_.reinitialize(uv_map.size());
for (int index = 0; index < int(uv_map.size()); index++) {
float2 uv = uv_map[index];
@ -317,11 +314,9 @@ Span<int> OBJMesh::calc_poly_uv_indices(const int face_index) const
float3 OBJMesh::calc_poly_normal(const int face_index) const
{
float3 r_poly_normal = bke::mesh::face_normal_calc(
mesh_positions_, mesh_corner_verts_.slice(mesh_faces_[face_index]));
mul_m3_v3(world_and_axes_normal_transform_, r_poly_normal);
normalize_v3(r_poly_normal);
return r_poly_normal;
const Span<int> face_verts = mesh_corner_verts_.slice(mesh_faces_[face_index]);
const float3 normal = bke::mesh::face_normal_calc(mesh_positions_, face_verts);
return math::normalize(world_and_axes_normal_transform_ * normal);
}
/** Round \a f to \a round_digits decimal digits. */
@ -352,7 +347,7 @@ void OBJMesh::store_normal_coords_and_indices()
Map<float3, int> normal_to_index;
/* We don't know how many unique normals there will be, but this is a guess. */
normal_to_index.reserve(export_mesh_->faces_num);
loop_to_normal_index_.resize(export_mesh_->corners_num);
loop_to_normal_index_.reinitialize(export_mesh_->corners_num);
loop_to_normal_index_.fill(-1);
Span<float3> corner_normals;
@ -368,17 +363,15 @@ void OBJMesh::store_normal_coords_and_indices()
bool need_per_loop_normals = !corner_normals.is_empty() || !(sharp_faces_[face_index]);
if (need_per_loop_normals) {
for (const int corner : face) {
float3 loop_normal;
BLI_assert(corner < export_mesh_->corners_num);
copy_v3_v3(loop_normal, corner_normals[corner]);
mul_m3_v3(world_and_axes_normal_transform_, loop_normal);
normalize_v3(loop_normal);
float3 rounded_loop_normal = round_float3_to_n_digits(loop_normal, round_digits);
int loop_norm_index = normal_to_index.lookup_default(rounded_loop_normal, -1);
const float3 normal = math::normalize(world_and_axes_normal_transform_ *
corner_normals[corner]);
const float3 rounded = round_float3_to_n_digits(normal, round_digits);
int loop_norm_index = normal_to_index.lookup_default(rounded, -1);
if (loop_norm_index == -1) {
loop_norm_index = cur_normal_index++;
normal_to_index.add(rounded_loop_normal, loop_norm_index);
normal_coords_.append(rounded_loop_normal);
normal_to_index.add(rounded, loop_norm_index);
normal_coords_.append(rounded);
}
loop_to_normal_index_[corner] = loop_norm_index;
}

View File

@ -10,6 +10,7 @@
#include <optional>
#include "BLI_math_matrix_types.hh"
#include "BLI_math_vector_types.hh"
#include "BLI_offset_indices.hh"
#include "BLI_utility_mixins.hh"
@ -44,14 +45,14 @@ class OBJMesh : NonCopyable {
* Final transform of an object obtained from export settings (up_axis, forward_axis) and the
* object's world transform matrix.
*/
float world_and_axes_transform_[4][4];
float world_and_axes_normal_transform_[3][3];
float4x4 world_and_axes_transform_;
float3x3 world_and_axes_normal_transform_;
bool mirrored_transform_;
/**
* Per-loop UV index.
*/
Vector<int> loop_to_uv_index_;
Array<int> loop_to_uv_index_;
/*
* UV vertices.
*/
@ -60,7 +61,7 @@ class OBJMesh : NonCopyable {
/**
* Per-loop normal index.
*/
Vector<int> loop_to_normal_index_;
Array<int> loop_to_normal_index_;
/*
* Normal coords.
*/
@ -81,7 +82,7 @@ class OBJMesh : NonCopyable {
/**
* Order in which the polygons should be written into the file (sorted by material index).
*/
Vector<int> poly_order_;
Array<int> poly_order_;
public:
Array<const Material *> materials;
@ -132,10 +133,11 @@ class OBJMesh : NonCopyable {
*/
const char *get_object_mesh_name() const;
/**
* Calculate coordinates of the vertex at the given index.
*/
float3 calc_vertex_coords(int vert_index, float global_scale) const;
const float4x4 &get_world_axes_transform() const
{
return world_and_axes_transform_;
}
/**
* Calculate vertex indices of all vertices of the polygon at the given index.
*/
@ -221,6 +223,9 @@ class OBJMesh : NonCopyable {
/**
* Set the final transform after applying axes settings and an Object's world transform.
*/
void set_world_axes_transform(const Object &obj_eval, eIOAxis forward, eIOAxis up);
void set_world_axes_transform(const Object &obj_eval,
eIOAxis forward,
eIOAxis up,
float global_scale);
};
} // namespace blender::io::obj

View File

@ -138,7 +138,7 @@ filter_supported_objects(Depsgraph *depsgraph, const OBJExportParams &export_par
return {std::move(r_exportable_meshes), std::move(r_exportable_nurbs)};
}
static void write_mesh_objects(Vector<std::unique_ptr<OBJMesh>> exportable_as_mesh,
static void write_mesh_objects(const Span<std::unique_ptr<OBJMesh>> exportable_as_mesh,
OBJWriter &obj_writer,
MTLWriter *mtl_writer,
const OBJExportParams &export_params)
@ -147,7 +147,7 @@ static void write_mesh_objects(Vector<std::unique_ptr<OBJMesh>> exportable_as_me
* we have to have the output text buffer for each object,
* and write them all into the file at the end. */
size_t count = exportable_as_mesh.size();
std::vector<FormatHandler> buffers(count);
Array<FormatHandler> buffers(count);
/* Serial: gather material indices, ensure normals & edges. */
Vector<Vector<int>> mtlindices;
@ -163,7 +163,7 @@ static void write_mesh_objects(Vector<std::unique_ptr<OBJMesh>> exportable_as_me
}
/* Parallel over meshes: store normal coords & indices, uv coords and indices. */
blender::threading::parallel_for(IndexRange(count), 1, [&](IndexRange range) {
threading::parallel_for(IndexRange(count), 1, [&](IndexRange range) {
for (const int i : range) {
OBJMesh &obj = *exportable_as_mesh[i];
if (export_params.export_normals) {
@ -189,7 +189,7 @@ static void write_mesh_objects(Vector<std::unique_ptr<OBJMesh>> exportable_as_me
}
/* Parallel over meshes: main result writing. */
blender::threading::parallel_for(IndexRange(count), 1, [&](IndexRange range) {
threading::parallel_for(IndexRange(count), 1, [&](IndexRange range) {
for (const int i : range) {
OBJMesh &obj = *exportable_as_mesh[i];
auto &fh = buffers[i];
@ -239,7 +239,7 @@ static void write_mesh_objects(Vector<std::unique_ptr<OBJMesh>> exportable_as_me
/**
* Export NURBS Curves in parameter form, not as vertices and edges.
*/
static void write_nurbs_curve_objects(const Vector<std::unique_ptr<OBJCurve>> &exportable_as_nurbs,
static void write_nurbs_curve_objects(const Span<std::unique_ptr<OBJCurve>> exportable_as_nurbs,
const OBJWriter &obj_writer)
{
FormatHandler fh;
@ -280,8 +280,7 @@ void export_frame(Depsgraph *depsgraph, const OBJExportParams &export_params, co
auto [exportable_as_mesh, exportable_as_nurbs] = filter_supported_objects(depsgraph,
export_params);
write_mesh_objects(
std::move(exportable_as_mesh), *frame_writer, mtl_writer.get(), export_params);
write_mesh_objects(exportable_as_mesh, *frame_writer, mtl_writer.get(), export_params);
if (mtl_writer) {
mtl_writer->write_header(export_params.blen_filepath);
char dest_dir[PATH_MAX];
@ -298,7 +297,7 @@ void export_frame(Depsgraph *depsgraph, const OBJExportParams &export_params, co
dest_dir,
export_params.export_pbr_extensions);
}
write_nurbs_curve_objects(std::move(exportable_as_nurbs), *frame_writer);
write_nurbs_curve_objects(exportable_as_nurbs, *frame_writer);
}
bool append_frame_to_filename(const char *filepath, const int frame, char *r_filepath_with_frames)

View File

@ -930,18 +930,15 @@ enum wmConfirmPosition {
};
struct wmConfirmDetails {
char title[1024];
char message[1024];
char message2[1024];
char confirm_button[256];
char cancel_button[256];
std::string title;
std::string message;
std::string message2;
std::string confirm_text;
int icon;
wmConfirmSize size;
wmConfirmPosition position;
bool confirm_default;
bool cancel_default;
bool mouse_move_quit;
bool red_alert;
};
/**

View File

@ -3629,8 +3629,8 @@ static void wm_clear_recent_files_confirm(bContext * /*C*/,
wmOperator * /*op*/,
wmConfirmDetails *confirm)
{
STRNCPY(confirm->message, IFACE_("Remove all items from the recent files list"));
STRNCPY(confirm->confirm_button, IFACE_("Remove All"));
confirm->message = IFACE_("Remove all items from the recent files list");
confirm->confirm_text = IFACE_("Remove All");
confirm->position = WM_WARNING_POSITION_CENTER;
confirm->size = WM_WARNING_SIZE_LARGE;
confirm->cancel_default = true;

View File

@ -1217,16 +1217,13 @@ static uiBlock *wm_block_confirm_create(bContext *C, ARegion *region, void *arg_
wmConfirmDetails confirm = {{0}};
STRNCPY(confirm.title, WM_operatortype_description(C, op->type, op->ptr).c_str());
STRNCPY(confirm.confirm_button, WM_operatortype_name(op->type, op->ptr).c_str());
STRNCPY(confirm.cancel_button, IFACE_("Cancel"));
confirm.title = WM_operatortype_description(C, op->type, op->ptr);
confirm.confirm_text = WM_operatortype_name(op->type, op->ptr);
confirm.icon = ALERT_ICON_WARNING;
confirm.size = WM_WARNING_SIZE_SMALL;
confirm.position = WM_WARNING_POSITION_MOUSE;
confirm.confirm_default = true;
confirm.cancel_default = false;
confirm.mouse_move_quit = false;
confirm.red_alert = false;
/* uiBlock.flag */
int block_flags = UI_BLOCK_KEEP_OPEN | UI_BLOCK_NO_WIN_CLIP | UI_BLOCK_NUMSELECT;
@ -1248,21 +1245,23 @@ static uiBlock *wm_block_confirm_create(bContext *C, ARegion *region, void *arg_
const uiStyle *style = UI_style_get_dpi();
int text_width = std::max(
120 * UI_SCALE_FAC,
BLF_width(style->widget.uifont_id, confirm.title, ARRAY_SIZE(confirm.title)));
if (confirm.message[0]) {
text_width = std::max(
text_width,
int(BLF_width(style->widget.uifont_id, confirm.message, ARRAY_SIZE(confirm.message))));
BLF_width(style->widget.uifont_id, confirm.title.c_str(), confirm.title.length()));
if (!confirm.message.empty()) {
text_width = std::max(text_width,
int(BLF_width(style->widget.uifont_id,
confirm.message.c_str(),
confirm.message.length())));
}
if (confirm.message2[0]) {
text_width = std::max(
text_width,
int(BLF_width(style->widget.uifont_id, confirm.message2, ARRAY_SIZE(confirm.message2))));
if (!confirm.message2.empty()) {
text_width = std::max(text_width,
int(BLF_width(style->widget.uifont_id,
confirm.message2.c_str(),
confirm.message2.length())));
}
const bool small = confirm.size == WM_WARNING_SIZE_SMALL;
const int padding = (small ? 7 : 14) * UI_SCALE_FAC;
const short icon_size = (small ? (confirm.message[0] ? 48 : 32) : 64) * UI_SCALE_FAC;
const short icon_size = (small ? (confirm.message.empty() ? 32 : 48) : 64) * UI_SCALE_FAC;
const int dialog_width = icon_size + text_width + (style->columnspace * 2.5);
const float split_factor = (float)icon_size / (float)(dialog_width - style->columnspace);
@ -1281,17 +1280,19 @@ static uiBlock *wm_block_confirm_create(bContext *C, ARegion *region, void *arg_
/* The rest of the content on the right. */
layout = uiLayoutColumn(split_block, true);
if (confirm.title[0]) {
if (!confirm.message[0]) {
if (!confirm.title.empty()) {
if (confirm.message.empty()) {
uiItemS(layout);
}
uiItemL_ex(layout, confirm.title, ICON_NONE, true, false);
uiItemL_ex(layout, confirm.title.c_str(), ICON_NONE, true, false);
}
if (confirm.message[0]) {
uiItemL(layout, confirm.message, ICON_NONE);
if (!confirm.message.empty()) {
uiItemL(layout, confirm.message.c_str(), ICON_NONE);
}
if (confirm.message2[0]) {
uiItemL(layout, confirm.message2, ICON_NONE);
if (!confirm.message2.empty()) {
uiItemL(layout, confirm.message2.c_str(), ICON_NONE);
}
uiItemS_ex(layout, small ? 0.5f : 4.0f);
@ -1315,7 +1316,7 @@ static uiBlock *wm_block_confirm_create(bContext *C, ARegion *region, void *arg_
UI_BTYPE_BUT,
0,
0,
confirm.confirm_button,
confirm.confirm_text.c_str(),
0,
0,
0,
@ -1333,7 +1334,7 @@ static uiBlock *wm_block_confirm_create(bContext *C, ARegion *region, void *arg_
UI_BTYPE_BUT,
0,
0,
confirm.cancel_button,
IFACE_("Cancel"),
0,
0,
0,
@ -1351,7 +1352,7 @@ static uiBlock *wm_block_confirm_create(bContext *C, ARegion *region, void *arg_
UI_BTYPE_BUT,
0,
0,
confirm.confirm_button,
confirm.confirm_text.c_str(),
0,
0,
0,
@ -1369,18 +1370,7 @@ static uiBlock *wm_block_confirm_create(bContext *C, ARegion *region, void *arg_
UI_but_func_set(cancel_but, wm_operator_block_cancel, op, block);
UI_but_drawflag_disable(confirm_but, UI_BUT_TEXT_LEFT);
UI_but_drawflag_disable(cancel_but, UI_BUT_TEXT_LEFT);
if (confirm.red_alert) {
UI_but_flag_enable(confirm_but, UI_BUT_REDALERT);
}
else {
if (confirm.cancel_default) {
UI_but_flag_enable(cancel_but, UI_BUT_ACTIVE_DEFAULT);
}
else if (confirm.confirm_default) {
UI_but_flag_enable(confirm_but, UI_BUT_ACTIVE_DEFAULT);
}
}
UI_but_flag_enable(confirm.cancel_default ? cancel_but : confirm_but, UI_BUT_ACTIVE_DEFAULT);
if (confirm.position == WM_WARNING_POSITION_MOUSE) {
int bounds_offset[2];

View File

@ -136,6 +136,7 @@ def main():
from modules import render_report
report = render_report.Report("Eevee Next", output_dir, oiiotool)
report.set_pixelated(True)
report.set_engine_name('eevee_next')
report.set_reference_dir("eevee_next_renders")
report.set_reference_override_dir(reference_override_dir)
report.set_compare_engine('cycles', 'CPU')

View File

@ -76,6 +76,7 @@ def test_get_images(output_dir, filepath, reference_dir, reference_override_dir)
class Report:
__slots__ = (
'title',
'engine_name',
'output_dir',
'global_dir',
'reference_dir',
@ -104,6 +105,7 @@ class Report:
self.compare_engine = None
self.fail_threshold = 0.016
self.fail_percent = 1
self.engine_name = self.title.lower().replace(" ", "_")
self.device = device
self.blacklist = blacklist
@ -142,6 +144,9 @@ class Report:
def set_compare_engine(self, other_engine, other_device=None):
self.compare_engine = (other_engine, other_device)
def set_engine_name(self, engine_name):
self.engine_name = engine_name
def run(self, dirpath, blender, arguments_cb, batch=False):
# Run tests and output report.
dirname = os.path.basename(dirpath)
@ -232,7 +237,7 @@ class Report:
if failed:
message = """<div class="alert alert-danger" role="alert">"""
message += """<p>Run this command to regenerate reference (ground truth) images:</p>"""
message += """<p><tt>BLENDER_TEST_UPDATE=1 ctest -R %s</tt></p>""" % self.title.lower()
message += """<p><tt>BLENDER_TEST_UPDATE=1 ctest -R %s</tt></p>""" % self.engine_name
message += """<p>This then happens for new and failing tests; reference images of """ \
"""passing test cases will not be updated. Be sure to commit the new reference """ \
"""images to the SVN repository afterwards.</p>"""