WIP: Brush assets project #106303
|
@ -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()) {
|
||||
|
|
|
@ -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]);
|
||||
});
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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')
|
||||
|
|
|
@ -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>"""
|
||||
|
|
Loading…
Reference in New Issue